diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix index c790093ee4e2..1d4425f9c789 100644 --- a/pkgs/stdenv/generic/default.nix +++ b/pkgs/stdenv/generic/default.nix @@ -27,8 +27,6 @@ let lib = import ../../../lib; in lib.makeOverridable ( let inherit (targetPlatform) system; - ifDarwin = attrs: if system == "x86_64-darwin" then attrs else {}; - defaultNativeBuildInputs = extraBuildInputs ++ [ ../../build-support/setup-hooks/move-docs.sh ../../build-support/setup-hooks/compress-man-pages.sh @@ -37,7 +35,7 @@ let ] # FIXME this on Darwin; see # https://github.com/NixOS/nixpkgs/commit/94d164dd7#commitcomment-22030369 - ++ lib.optional result.isLinux ../../build-support/setup-hooks/audit-tmpdir.sh + ++ lib.optional hostPlatform.isLinux ../../build-support/setup-hooks/audit-tmpdir.sh ++ [ ../../build-support/setup-hooks/multiple-outputs.sh ../../build-support/setup-hooks/move-sbin.sh @@ -46,153 +44,8 @@ let cc ]; - # `mkDerivation` wraps the builtin `derivation` function to - # produce derivations that use this stdenv and its shell. - # - # See also: - # - # * https://nixos.org/nixpkgs/manual/#sec-using-stdenv - # Details on how to use this mkDerivation function - # - # * https://nixos.org/nix/manual/#ssec-derivation - # Explanation about derivations in general - mkDerivation = - { nativeBuildInputs ? [] - , buildInputs ? [] - - , propagatedNativeBuildInputs ? [] - , propagatedBuildInputs ? [] - - , crossConfig ? null - , meta ? {} - , passthru ? {} - , pos ? # position used in error messages and for meta.position - (if attrs.meta.description or null != null - then builtins.unsafeGetAttrPos "description" attrs.meta - else builtins.unsafeGetAttrPos "name" attrs) - , separateDebugInfo ? false - , outputs ? [ "out" ] - , __impureHostDeps ? [] - , __propagatedImpureHostDeps ? [] - , sandboxProfile ? "" - , propagatedSandboxProfile ? "" - , ... } @ attrs: - let - dependencies = [ - (map (drv: drv.nativeDrv or drv) nativeBuildInputs) - (map (drv: drv.crossDrv or drv) buildInputs) - ]; - propagatedDependencies = [ - (map (drv: drv.nativeDrv or drv) propagatedNativeBuildInputs) - (map (drv: drv.crossDrv or drv) propagatedBuildInputs) - ]; - in let - - outputs' = - outputs ++ - (if separateDebugInfo then assert targetPlatform.isLinux; [ "debug" ] else []); - - dependencies' = let - justMap = map lib.chooseDevOutputs dependencies; - nativeBuildInputs = lib.elemAt justMap 0 - ++ lib.optional targetPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh; - buildInputs = lib.elemAt justMap 1 - # TODO(@Ericson2314): Should instead also be appended to `nativeBuildInputs`. - ++ lib.optional separateDebugInfo ../../build-support/setup-hooks/separate-debug-info.sh; - in [ nativeBuildInputs buildInputs ]; - - propagatedDependencies' = map lib.chooseDevOutputs propagatedDependencies; - - derivationArg = - (removeAttrs attrs - ["meta" "passthru" "crossAttrs" "pos" - "__impureHostDeps" "__propagatedImpureHostDeps" - "sandboxProfile" "propagatedSandboxProfile"]) - // (let - # TODO(@Ericson2314): Reversing of dep lists is just temporary to avoid Darwin mass rebuild. - computedSandboxProfile = - lib.concatMap (input: input.__propagatedSandboxProfile or []) (extraBuildInputs ++ lib.concatLists (lib.reverseList dependencies')); - computedPropagatedSandboxProfile = - lib.concatMap (input: input.__propagatedSandboxProfile or []) (lib.concatLists (lib.reverseList propagatedDependencies')); - computedImpureHostDeps = - lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (extraBuildInputs ++ lib.concatLists (lib.reverseList dependencies'))); - computedPropagatedImpureHostDeps = - lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (lib.concatLists (lib.reverseList propagatedDependencies'))); - in - { - builder = attrs.realBuilder or shell; - args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)]; - stdenv = result; - system = result.system; - userHook = config.stdenv.userHook or null; - __ignoreNulls = true; - - nativeBuildInputs = lib.elemAt dependencies' 0; - buildInputs = lib.elemAt dependencies' 1; - - propagatedNativeBuildInputs = lib.elemAt propagatedDependencies' 0; - propagatedBuildInputs = lib.elemAt propagatedDependencies' 1; - } // ifDarwin { - # TODO: remove lib.unique once nix has a list canonicalization primitive - __sandboxProfile = - let profiles = [ extraSandboxProfile ] ++ computedSandboxProfile ++ computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile sandboxProfile ]; - final = lib.concatStringsSep "\n" (lib.filter (x: x != "") (lib.unique profiles)); - in final; - __propagatedSandboxProfile = lib.unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]); - __impureHostDeps = computedImpureHostDeps ++ computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ++ __impureHostDeps ++ __extraImpureHostDeps ++ [ - "/dev/zero" - "/dev/random" - "/dev/urandom" - "/bin/sh" - ]; - __propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps; - } // (if outputs' != [ "out" ] then { - outputs = outputs'; - } else { })); - - # The meta attribute is passed in the resulting attribute set, - # but it's not part of the actual derivation, i.e., it's not - # passed to the builder and is not a dependency. But since we - # include it in the result, it *is* available to nix-env for queries. - meta = { } - # If the packager hasn't specified `outputsToInstall`, choose a default, - # which is the name of `p.bin or p.out or p`; - # if he has specified it, it will be overridden below in `// meta`. - # Note: This default probably shouldn't be globally configurable. - # Services and users should specify outputs explicitly, - # unless they are comfortable with this default. - // { outputsToInstall = - let - outs = outputs'; # the value passed to derivation primitive - hasOutput = out: builtins.elem out outs; - in [( lib.findFirst hasOutput null (["bin" "out"] ++ outs) )]; - } - // attrs.meta or {} - # Fill `meta.position` to identify the source location of the package. - // lib.optionalAttrs (pos != null) - { position = pos.file + ":" + toString pos.line; } - ; - - in - - lib.addPassthru - (derivation (import ./check-meta.nix - { - inherit lib config meta derivationArg; - mkDerivationArg = attrs; - inherit system; # TODO: cross-compilation? - })) - ( { - overrideAttrs = f: mkDerivation (attrs // (f attrs)); - inherit meta passthru; - } // - # Pass through extra attributes that are not inputs, but - # should be made available to Nix expressions using the - # derivation (e.g., in assertions). - passthru); - # The stdenv that we are producing. - result = + stdenv = derivation ( (if isNull allowedRequisites then {} else { allowedRequisites = allowedRequisites ++ defaultNativeBuildInputs; }) // { @@ -206,7 +59,7 @@ let inherit preHook initialPath shell defaultNativeBuildInputs; } - // ifDarwin { + // lib.optionalAttrs hostPlatform.isDarwin { __sandboxProfile = stdenvSandboxProfile; __impureHostDeps = __stdenvImpureHostDeps; }) @@ -228,7 +81,15 @@ let # Whether we should run paxctl to pax-mark binaries. needsPax = isLinux; - inherit mkDerivation; + inherit (import ./make-derivation.nix { + inherit lib config stdenv; + # TODO(@Ericson2314): Remove + inherit + extraBuildInputs + __extraImpureHostDeps + extraSandboxProfile + hostPlatform targetPlatform; + }) mkDerivation; # For convenience, bring in the library functions in lib/ so # packages don't have to do that themselves. @@ -247,4 +108,4 @@ let # like curl = if stdenv ? curl then stdenv.curl else ...). // extraAttrs; -in result) +in stdenv) diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix new file mode 100644 index 000000000000..92d5d2a3d9d3 --- /dev/null +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -0,0 +1,155 @@ +{ lib, config, stdenv + +# TODO(@Ericson2314): get off stdenv +, extraBuildInputs +, __extraImpureHostDeps +, extraSandboxProfile +, hostPlatform, targetPlatform +}: + +rec { + # `mkDerivation` wraps the builtin `derivation` function to + # produce derivations that use this stdenv and its shell. + # + # See also: + # + # * https://nixos.org/nixpkgs/manual/#sec-using-stdenv + # Details on how to use this mkDerivation function + # + # * https://nixos.org/nix/manual/#ssec-derivation + # Explanation about derivations in general + mkDerivation = + { nativeBuildInputs ? [] + , buildInputs ? [] + + , propagatedNativeBuildInputs ? [] + , propagatedBuildInputs ? [] + + , crossConfig ? null + , meta ? {} + , passthru ? {} + , pos ? # position used in error messages and for meta.position + (if attrs.meta.description or null != null + then builtins.unsafeGetAttrPos "description" attrs.meta + else builtins.unsafeGetAttrPos "name" attrs) + , separateDebugInfo ? false + , outputs ? [ "out" ] + , __impureHostDeps ? [] + , __propagatedImpureHostDeps ? [] + , sandboxProfile ? "" + , propagatedSandboxProfile ? "" + , ... } @ attrs: + let + dependencies = [ + (map (drv: drv.nativeDrv or drv) nativeBuildInputs) + (map (drv: drv.crossDrv or drv) buildInputs) + ]; + propagatedDependencies = [ + (map (drv: drv.nativeDrv or drv) propagatedNativeBuildInputs) + (map (drv: drv.crossDrv or drv) propagatedBuildInputs) + ]; + in let + + outputs' = + outputs ++ + (if separateDebugInfo then assert targetPlatform.isLinux; [ "debug" ] else []); + + dependencies' = let + justMap = map lib.chooseDevOutputs dependencies; + nativeBuildInputs = lib.elemAt justMap 0 + ++ lib.optional targetPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh; + buildInputs = lib.elemAt justMap 1 + # TODO(@Ericson2314): Should instead also be appended to `nativeBuildInputs`. + ++ lib.optional separateDebugInfo ../../build-support/setup-hooks/separate-debug-info.sh; + in [ nativeBuildInputs buildInputs ]; + + propagatedDependencies' = map lib.chooseDevOutputs propagatedDependencies; + + derivationArg = + (removeAttrs attrs + ["meta" "passthru" "crossAttrs" "pos" + "__impureHostDeps" "__propagatedImpureHostDeps" + "sandboxProfile" "propagatedSandboxProfile"]) + // (let + # TODO(@Ericson2314): Reversing of dep lists is just temporary to avoid Darwin mass rebuild. + computedSandboxProfile = + lib.concatMap (input: input.__propagatedSandboxProfile or []) (extraBuildInputs ++ lib.concatLists (lib.reverseList dependencies')); + computedPropagatedSandboxProfile = + lib.concatMap (input: input.__propagatedSandboxProfile or []) (lib.concatLists (lib.reverseList propagatedDependencies')); + computedImpureHostDeps = + lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (extraBuildInputs ++ lib.concatLists (lib.reverseList dependencies'))); + computedPropagatedImpureHostDeps = + lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (lib.concatLists (lib.reverseList propagatedDependencies'))); + in + { + builder = attrs.realBuilder or stdenv.shell; + args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)]; + inherit stdenv; + system = stdenv.system; # TODO(@Ericson2314): be correct about cross compilation + userHook = config.stdenv.userHook or null; + __ignoreNulls = true; + + nativeBuildInputs = lib.elemAt dependencies' 0; + buildInputs = lib.elemAt dependencies' 1; + + propagatedNativeBuildInputs = lib.elemAt propagatedDependencies' 0; + propagatedBuildInputs = lib.elemAt propagatedDependencies' 1; + } // lib.optionalAttrs (hostPlatform.isDarwin) { + # TODO: remove lib.unique once nix has a list canonicalization primitive + __sandboxProfile = + let profiles = [ extraSandboxProfile ] ++ computedSandboxProfile ++ computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile sandboxProfile ]; + final = lib.concatStringsSep "\n" (lib.filter (x: x != "") (lib.unique profiles)); + in final; + __propagatedSandboxProfile = lib.unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]); + __impureHostDeps = computedImpureHostDeps ++ computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ++ __impureHostDeps ++ __extraImpureHostDeps ++ [ + "/dev/zero" + "/dev/random" + "/dev/urandom" + "/bin/sh" + ]; + __propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps; + } // (if outputs' != [ "out" ] then { + outputs = outputs'; + } else { })); + + # The meta attribute is passed in the resulting attribute set, + # but it's not part of the actual derivation, i.e., it's not + # passed to the builder and is not a dependency. But since we + # include it in the result, it *is* available to nix-env for queries. + meta = { } + # If the packager hasn't specified `outputsToInstall`, choose a default, + # which is the name of `p.bin or p.out or p`; + # if he has specified it, it will be overridden below in `// meta`. + # Note: This default probably shouldn't be globally configurable. + # Services and users should specify outputs explicitly, + # unless they are comfortable with this default. + // { outputsToInstall = + let + outs = outputs'; # the value passed to derivation primitive + hasOutput = out: builtins.elem out outs; + in [( lib.findFirst hasOutput null (["bin" "out"] ++ outs) )]; + } + // attrs.meta or {} + # Fill `meta.position` to identify the source location of the package. + // lib.optionalAttrs (pos != null) + { position = pos.file + ":" + toString pos.line; } + ; + + in + + lib.addPassthru + (derivation (import ./check-meta.nix + { + inherit lib config meta derivationArg; + mkDerivationArg = attrs; + inherit (stdenv) system; # TODO: cross-compilation? + })) + ( { + overrideAttrs = f: mkDerivation (attrs // (f attrs)); + inherit meta passthru; + } // + # Pass through extra attributes that are not inputs, but + # should be made available to Nix expressions using the + # derivation (e.g., in assertions). + passthru); +}