From ddeb0d2d6b2e71cf98ab50ab376f802cf29c7c22 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sun, 13 Nov 2016 10:38:41 -0800 Subject: [PATCH 1/9] top-level: Stop exposing all stdenvs --- pkgs/stdenv/cross/default.nix | 2 +- pkgs/stdenv/custom/default.nix | 4 ++-- pkgs/stdenv/default.nix | 7 +++---- pkgs/top-level/stdenv.nix | 6 ++---- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/pkgs/stdenv/cross/default.nix b/pkgs/stdenv/cross/default.nix index 0cde6a05943..4b7d81879b1 100644 --- a/pkgs/stdenv/cross/default.nix +++ b/pkgs/stdenv/cross/default.nix @@ -8,7 +8,7 @@ rec { }; vanillaStdenv = (import ../. (args // argClobber // { allPackages = args: allPackages (argClobber // args); - })).stdenv // { + })) // { # Needed elsewhere as a hacky way to pass the target cross = crossSystem; }; diff --git a/pkgs/stdenv/custom/default.nix b/pkgs/stdenv/custom/default.nix index 2f2f495b388..6d2aa8c59b3 100644 --- a/pkgs/stdenv/custom/default.nix +++ b/pkgs/stdenv/custom/default.nix @@ -1,10 +1,10 @@ { system, allPackages, platform, crossSystem, config, ... } @ args: rec { - vanillaStdenv = (import ../. (args // { + vanillaStdenv = import ../. (args // { # Remove config.replaceStdenv to ensure termination. config = builtins.removeAttrs config [ "replaceStdenv" ]; - })).stdenv; + }); buildPackages = allPackages { # It's OK to change the built-time dependencies diff --git a/pkgs/stdenv/default.nix b/pkgs/stdenv/default.nix index 4be34a35acb..ac84ea0f9a0 100644 --- a/pkgs/stdenv/default.nix +++ b/pkgs/stdenv/default.nix @@ -8,7 +8,7 @@ { system, allPackages ? import ../.., platform, config, crossSystem, lib }: -rec { +let # The native (i.e., impure) build environment. This one uses the @@ -43,7 +43,7 @@ rec { inherit (import ./custom { inherit system allPackages platform crossSystem config lib; }) stdenvCustom; # Select the appropriate stdenv for the platform `system'. - stdenv = +in if crossSystem != null then if crossSystem.useiOSCross or false then stdenvCrossiOS else stdenvCross else @@ -60,5 +60,4 @@ rec { if system == "i686-cygwin" then stdenvNative else if system == "x86_64-cygwin" then stdenvNative else if system == "x86_64-freebsd" then stdenvFreeBSD else - stdenvNative; -} + stdenvNative diff --git a/pkgs/top-level/stdenv.nix b/pkgs/top-level/stdenv.nix index 9f485b8c90e..adb8bdde6ad 100644 --- a/pkgs/top-level/stdenv.nix +++ b/pkgs/top-level/stdenv.nix @@ -1,12 +1,10 @@ { system, bootStdenv, crossSystem, config, platform, lib, nixpkgsFun }: rec { - allStdenvs = import ../stdenv { + defaultStdenv = import ../stdenv { inherit system platform config crossSystem lib; allPackages = nixpkgsFun; - }; - - defaultStdenv = allStdenvs.stdenv // { inherit platform; }; + } // { inherit platform; }; stdenv = if bootStdenv != null From 2df990967be3c21f074c56682f8fa47bdd7cba7b Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 30 Nov 2016 19:03:22 -0500 Subject: [PATCH 2/9] Move up `inherit` binding for consistency --- pkgs/stdenv/cross/default.nix | 2 +- pkgs/stdenv/custom/default.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/stdenv/cross/default.nix b/pkgs/stdenv/cross/default.nix index 4b7d81879b1..e48124f1c4d 100644 --- a/pkgs/stdenv/cross/default.nix +++ b/pkgs/stdenv/cross/default.nix @@ -17,10 +17,10 @@ rec { # be used to build compilers and other such tools targeting the cross # platform. Then, `forceNativeDrv` can be removed. buildPackages = allPackages { + inherit system platform crossSystem config; # It's OK to change the built-time dependencies allowCustomOverrides = true; bootStdenv = vanillaStdenv; - inherit system platform crossSystem config; }; stdenvCross = buildPackages.makeStdenvCross diff --git a/pkgs/stdenv/custom/default.nix b/pkgs/stdenv/custom/default.nix index 6d2aa8c59b3..4c14d6411f1 100644 --- a/pkgs/stdenv/custom/default.nix +++ b/pkgs/stdenv/custom/default.nix @@ -7,10 +7,10 @@ rec { }); buildPackages = allPackages { + inherit system platform crossSystem config; # It's OK to change the built-time dependencies allowCustomOverrides = true; bootStdenv = vanillaStdenv; - inherit system platform crossSystem config; }; stdenvCustom = config.replaceStdenv { pkgs = buildPackages; }; From 07a2b17cbf541c485e04f1a8ec98ffe8c24ac713 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sun, 27 Nov 2016 12:32:56 -0800 Subject: [PATCH 3/9] top-level: Split some of `pkgs/top-level/default.nix` to `pkgs/top-level/stage.nix` This is preparation for the latter just building a single stage, and the former building a package set with the bootstrapped stdenv. --- pkgs/top-level/default.nix | 98 +++------------------------------ pkgs/top-level/stage.nix | 107 +++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 90 deletions(-) create mode 100644 pkgs/top-level/stage.nix diff --git a/pkgs/top-level/default.nix b/pkgs/top-level/default.nix index 831b1db0cea..c5b8bbac31c 100644 --- a/pkgs/top-level/default.nix +++ b/pkgs/top-level/default.nix @@ -4,37 +4,22 @@ packages in the Nix Packages collection for some particular platform. */ - { # The system (e.g., `i686-linux') for which to build the packages. system -, # The standard environment to use. Only used for bootstrapping. If - # null, the default standard environment is used. - bootStdenv ? null - -, # This is used because stdenv replacement and the stdenvCross do benefit from - # the overridden configuration provided by the user, as opposed to the normal - # bootstrapping stdenvs. - allowCustomOverrides ? (bootStdenv == null) - -, # Non-GNU/Linux OSes are currently "impure" platforms, with their libc - # outside of the store. Thus, GCC, GFortran, & co. must always look for - # files in standard system directories (/usr/include, etc.) - noSysDirs ? (system != "x86_64-freebsd" && system != "i686-freebsd" - && system != "x86_64-solaris" - && system != "x86_64-kfreebsd-gnu") - , # Allow a configuration attribute set to be passed in as an argument. config ? {} , crossSystem ? null , platform ? null +, ... } @ args: +let # Rename the function arguments + configExpr = config; + platform_ = platform; -let configExpr = config; platform_ = platform; in # rename the function arguments - -let +in let lib = import ../../lib; # Allow both: @@ -72,75 +57,8 @@ let # deterministically inferred the same way. nixpkgsFun = newArgs: import ./. (args // newArgs); - stdenvAdapters = self: super: - let res = import ../stdenv/adapters.nix self; in res // { - stdenvAdapters = res; - }; + pkgs = import ./stage.nix ({ + inherit lib nixpkgsFun config platform; + } // args); - trivialBuilders = self: super: - import ../build-support/trivial-builders.nix { - inherit lib; inherit (self) stdenv stdenvNoCC; inherit (self.xorg) lndir; - }; - - stdenvDefault = self: super: - import ./stdenv.nix { - inherit system bootStdenv crossSystem config platform lib nixpkgsFun; - }; - - allPackages = self: super: - let res = import ./all-packages.nix - { inherit system noSysDirs config crossSystem platform lib nixpkgsFun; } - res self; - in res; - - aliases = self: super: import ./aliases.nix super; - - # stdenvOverrides is used to avoid circular dependencies for building - # the standard build environment. This mechanism uses the override - # mechanism to implement some staged compilation of the stdenv. - # - # We don't want stdenv overrides in the case of cross-building, or - # otherwise the basic overridden packages will not be built with the - # crossStdenv adapter. - stdenvOverrides = self: super: - lib.optionalAttrs (crossSystem == null && super.stdenv ? overrides) - (super.stdenv.overrides super); - - # Allow packages to be overridden globally via the `packageOverrides' - # configuration option, which must be a function that takes `pkgs' - # as an argument and returns a set of new or overridden packages. - # The `packageOverrides' function is called with the *original* - # (un-overridden) set of packages, allowing packageOverrides - # attributes to refer to the original attributes (e.g. "foo = - # ... pkgs.foo ..."). - configOverrides = self: super: - lib.optionalAttrs allowCustomOverrides - ((config.packageOverrides or (super: {})) super); - - # The complete chain of package set builders, applied from top to bottom - toFix = lib.foldl' (lib.flip lib.extends) (self: {}) [ - stdenvAdapters - trivialBuilders - stdenvDefault - allPackages - aliases - stdenvOverrides - configOverrides - ]; - - # Use `overridePackages` to easily override this package set. - # Warning: this function is very expensive and must not be used - # from within the nixpkgs repository. - # - # Example: - # pkgs.overridePackages (self: super: { - # foo = super.foo.override { ... }; - # } - # - # The result is `pkgs' where all the derivations depending on `foo' - # will use the new version. - - # Return the complete set of packages. Warning: this function is very - # expensive! - pkgs = lib.makeExtensibleWithCustomName "overridePackages" toFix; in pkgs diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix new file mode 100644 index 00000000000..9ab9d22e54f --- /dev/null +++ b/pkgs/top-level/stage.nix @@ -0,0 +1,107 @@ +/* This file composes the Nix Packages collection. That is, it + imports the functions that build the various packages, and calls + them with appropriate arguments. The result is a set of all the + packages in the Nix Packages collection for some particular + platform. */ + + +{ # The system (e.g., `i686-linux') for which to build the packages. + system + +, # The standard environment to use. Only used for bootstrapping. If + # null, the default standard environment is used. + bootStdenv ? null + +, # This is used because stdenv replacement and the stdenvCross do benefit from + # the overridden configuration provided by the user, as opposed to the normal + # bootstrapping stdenvs. + allowCustomOverrides ? (bootStdenv == null) + +, # Non-GNU/Linux OSes are currently "impure" platforms, with their libc + # outside of the store. Thus, GCC, GFortran, & co. must always look for + # files in standard system directories (/usr/include, etc.) + noSysDirs ? (system != "x86_64-freebsd" && system != "i686-freebsd" + && system != "x86_64-solaris" + && system != "x86_64-kfreebsd-gnu") + +, # The configuration attribute set + config + +, crossSystem ? null +, platform +, lib +, nixpkgsFun +}: + +let + stdenvAdapters = self: super: + let res = import ../stdenv/adapters.nix self; in res // { + stdenvAdapters = res; + }; + + trivialBuilders = self: super: + import ../build-support/trivial-builders.nix { + inherit lib; inherit (self) stdenv stdenvNoCC; inherit (self.xorg) lndir; + }; + + stdenvDefault = self: super: + import ./stdenv.nix { + inherit system bootStdenv crossSystem config platform lib nixpkgsFun; + }; + + allPackages = self: super: + let res = import ./all-packages.nix + { inherit system noSysDirs config crossSystem platform lib nixpkgsFun; } + res self; + in res; + + aliases = self: super: import ./aliases.nix super; + + # stdenvOverrides is used to avoid circular dependencies for building + # the standard build environment. This mechanism uses the override + # mechanism to implement some staged compilation of the stdenv. + # + # We don't want stdenv overrides in the case of cross-building, or + # otherwise the basic overridden packages will not be built with the + # crossStdenv adapter. + stdenvOverrides = self: super: + lib.optionalAttrs (crossSystem == null && super.stdenv ? overrides) + (super.stdenv.overrides super); + + # Allow packages to be overridden globally via the `packageOverrides' + # configuration option, which must be a function that takes `pkgs' + # as an argument and returns a set of new or overridden packages. + # The `packageOverrides' function is called with the *original* + # (un-overridden) set of packages, allowing packageOverrides + # attributes to refer to the original attributes (e.g. "foo = + # ... pkgs.foo ..."). + configOverrides = self: super: + lib.optionalAttrs allowCustomOverrides + ((config.packageOverrides or (super: {})) super); + + # The complete chain of package set builders, applied from top to bottom + toFix = lib.foldl' (lib.flip lib.extends) (self: {}) [ + stdenvAdapters + trivialBuilders + stdenvDefault + allPackages + aliases + stdenvOverrides + configOverrides + ]; + + # Use `overridePackages` to easily override this package set. + # Warning: this function is very expensive and must not be used + # from within the nixpkgs repository. + # + # Example: + # pkgs.overridePackages (self: super: { + # foo = super.foo.override { ... }; + # } + # + # The result is `pkgs' where all the derivations depending on `foo' + # will use the new version. + + # Return the complete set of packages. Warning: this function is very + # expensive! +in lib.makeExtensibleWithCustomName "overridePackages" toFix From d240a0da1ab03ef8838553229b72b9b37a0ef3e7 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sun, 27 Nov 2016 12:35:58 -0800 Subject: [PATCH 4/9] top-level: Remove cycles: stdenv calls in top-level but not vice versa This commit changes the dependencies of stdenv, and clean-up the stdenv story by removing the `defaultStdenv` attribute as well as the `bootStdenv` parameter. Before, the final bootstrapping stage's stdenv was provided by all-packages, which was iterating multiple times over the top-level/default.nix expression, and non-final bootstrapping stages' stdenvs were explicitly specified with the `bootStdenv` parameter. Now, all stages' stdenvs are specified with the `stdenv` parameter. For non-final bootstrapping stages, this is a small change---basically just rename the parameter. For the final stage, top-level/default.nix takes the chosen stdenv and makes the final stage with it. `allPackages` is used to make all bootstrapping stages, final and non-final alike. It's basically the expression of `stage.nix` (along with a few partially-applied default arguments) Note, the make-bootstrap-tools scripts are temporarily broken --- pkgs/stdenv/cross/default.nix | 2 +- pkgs/stdenv/custom/default.nix | 2 +- pkgs/stdenv/darwin/default.nix | 5 +++-- pkgs/stdenv/default.nix | 5 +++-- pkgs/stdenv/freebsd/default.nix | 2 +- pkgs/stdenv/linux/default.nix | 3 ++- pkgs/stdenv/native/default.nix | 3 ++- pkgs/top-level/default.nix | 37 +++++++++++++++++++++++++-------- pkgs/top-level/stage.nix | 27 ++++++++++++------------ pkgs/top-level/stdenv.nix | 13 ------------ 10 files changed, 55 insertions(+), 44 deletions(-) delete mode 100644 pkgs/top-level/stdenv.nix diff --git a/pkgs/stdenv/cross/default.nix b/pkgs/stdenv/cross/default.nix index e48124f1c4d..fcf06bcf1da 100644 --- a/pkgs/stdenv/cross/default.nix +++ b/pkgs/stdenv/cross/default.nix @@ -20,7 +20,7 @@ rec { inherit system platform crossSystem config; # It's OK to change the built-time dependencies allowCustomOverrides = true; - bootStdenv = vanillaStdenv; + stdenv = vanillaStdenv; }; stdenvCross = buildPackages.makeStdenvCross diff --git a/pkgs/stdenv/custom/default.nix b/pkgs/stdenv/custom/default.nix index 4c14d6411f1..e8f203d69cf 100644 --- a/pkgs/stdenv/custom/default.nix +++ b/pkgs/stdenv/custom/default.nix @@ -10,7 +10,7 @@ rec { inherit system platform crossSystem config; # It's OK to change the built-time dependencies allowCustomOverrides = true; - bootStdenv = vanillaStdenv; + stdenv = vanillaStdenv; }; stdenvCustom = config.replaceStdenv { pkgs = buildPackages; }; diff --git a/pkgs/stdenv/darwin/default.nix b/pkgs/stdenv/darwin/default.nix index 1bc983d6312..49c4d9b8b2b 100644 --- a/pkgs/stdenv/darwin/default.nix +++ b/pkgs/stdenv/darwin/default.nix @@ -22,7 +22,7 @@ let (import "${./standard-sandbox.sb}") ''; in rec { - allPackages = import ../../..; + inherit allPackages; commonPreHook = '' export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}" @@ -101,7 +101,8 @@ in rec { thisPkgs = allPackages { inherit system platform; - bootStdenv = thisStdenv; + allowCustomOverrides = false; + stdenv = thisStdenv; }; in { stdenv = thisStdenv; pkgs = thisPkgs; }; diff --git a/pkgs/stdenv/default.nix b/pkgs/stdenv/default.nix index ac84ea0f9a0..bd515181fc6 100644 --- a/pkgs/stdenv/default.nix +++ b/pkgs/stdenv/default.nix @@ -5,7 +5,7 @@ # Posix utilities, the GNU C compiler, and so on. On other systems, # we use the native C library. -{ system, allPackages ? import ../.., platform, config, crossSystem, lib }: +{ system, allPackages ? import ../top-level, platform, config, crossSystem, lib }: let @@ -19,7 +19,8 @@ let inherit (import ./native { inherit system allPackages config; }) stdenvNative; stdenvNativePkgs = allPackages { - bootStdenv = stdenvNative; + allowCustomOverrides = false; + stdenv = stdenvNative; noSysDirs = false; }; diff --git a/pkgs/stdenv/freebsd/default.nix b/pkgs/stdenv/freebsd/default.nix index 4c7ebc16239..13cb21fe1d8 100644 --- a/pkgs/stdenv/freebsd/default.nix +++ b/pkgs/stdenv/freebsd/default.nix @@ -5,7 +5,7 @@ }: rec { - allPackages = import ../../..; + inherit allPackages; bootstrapTools = derivation { inherit system; diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix index e3aeafe178d..e0a68bdca2f 100644 --- a/pkgs/stdenv/linux/default.nix +++ b/pkgs/stdenv/linux/default.nix @@ -107,7 +107,8 @@ rec { thisPkgs = allPackages { inherit system platform; - bootStdenv = thisStdenv; + allowCustomOverrides = false; + stdenv = thisStdenv; }; in { stdenv = thisStdenv; pkgs = thisPkgs; }; diff --git a/pkgs/stdenv/native/default.nix b/pkgs/stdenv/native/default.nix index fcd0805275b..22b4dc1400f 100644 --- a/pkgs/stdenv/native/default.nix +++ b/pkgs/stdenv/native/default.nix @@ -127,7 +127,8 @@ rec { stdenvBoot1Pkgs = allPackages { inherit system; - bootStdenv = stdenvBoot1; + allowCustomOverrides = false; + stdenv = stdenvBoot1; }; diff --git a/pkgs/top-level/default.nix b/pkgs/top-level/default.nix index c5b8bbac31c..d1e824a8070 100644 --- a/pkgs/top-level/default.nix +++ b/pkgs/top-level/default.nix @@ -1,8 +1,21 @@ -/* This file composes the Nix Packages collection. That is, it - imports the functions that build the various packages, and calls - them with appropriate arguments. The result is a set of all the - packages in the Nix Packages collection for some particular - platform. */ +/* This function composes the Nix Packages collection. It: + + 1. Applies the final stage to the given `config` if it is a function + + 2. Infers an appropriate `platform` based on the `system` if none is + provided + + 3. Defaults to no non-standard config and no cross-compilation target + + 4. Uses the above to infer the default standard environment (stdenv) if + none is provided + + 5. Builds the final stage --- a fully booted package set with the chosen + stdenv + + Use `impure.nix` to also infer the `system` based on the one on which + evaluation is taking place, and the configuration from environment variables + or dot-files. */ { # The system (e.g., `i686-linux') for which to build the packages. system @@ -12,7 +25,6 @@ , crossSystem ? null , platform ? null -, ... } @ args: let # Rename the function arguments @@ -57,8 +69,15 @@ in let # deterministically inferred the same way. nixpkgsFun = newArgs: import ./. (args // newArgs); - pkgs = import ./stage.nix ({ - inherit lib nixpkgsFun config platform; - } // args); + # Partially apply some args for building bootstraping stage pkgs sets + allPackages = newArgs: import ./stage.nix ({ + inherit lib nixpkgsFun config; + } // newArgs); + + stdenv = import ../stdenv { + inherit lib allPackages system platform crossSystem config; + }; + + pkgs = allPackages { inherit system stdenv config crossSystem platform; }; in pkgs diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix index 9ab9d22e54f..0c621b81c7e 100644 --- a/pkgs/top-level/stage.nix +++ b/pkgs/top-level/stage.nix @@ -1,21 +1,24 @@ -/* This file composes the Nix Packages collection. That is, it - imports the functions that build the various packages, and calls - them with appropriate arguments. The result is a set of all the - packages in the Nix Packages collection for some particular - platform. */ +/* This file composes a single bootstrapping stage of the Nix Packages + collection. That is, it imports the functions that build the various + packages, and calls them with appropriate arguments. The result is a set of + all the packages in the Nix Packages collection for some particular platform + for some particular stage. + + Default arguments are only provided for bootstrapping + arguments. Normal users should not import this directly but instead + import `pkgs/default.nix` or `default.nix`. */ { # The system (e.g., `i686-linux') for which to build the packages. system -, # The standard environment to use. Only used for bootstrapping. If - # null, the default standard environment is used. - bootStdenv ? null +, # The standard environment to use for building packages. + stdenv , # This is used because stdenv replacement and the stdenvCross do benefit from # the overridden configuration provided by the user, as opposed to the normal # bootstrapping stdenvs. - allowCustomOverrides ? (bootStdenv == null) + allowCustomOverrides ? true , # Non-GNU/Linux OSes are currently "impure" platforms, with their libc # outside of the store. Thus, GCC, GFortran, & co. must always look for @@ -45,9 +48,7 @@ let }; stdenvDefault = self: super: - import ./stdenv.nix { - inherit system bootStdenv crossSystem config platform lib nixpkgsFun; - }; + { stdenv = stdenv // { inherit platform; }; }; allPackages = self: super: let res = import ./all-packages.nix @@ -81,9 +82,9 @@ let # The complete chain of package set builders, applied from top to bottom toFix = lib.foldl' (lib.flip lib.extends) (self: {}) [ + stdenvDefault stdenvAdapters trivialBuilders - stdenvDefault allPackages aliases stdenvOverrides diff --git a/pkgs/top-level/stdenv.nix b/pkgs/top-level/stdenv.nix deleted file mode 100644 index adb8bdde6ad..00000000000 --- a/pkgs/top-level/stdenv.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ system, bootStdenv, crossSystem, config, platform, lib, nixpkgsFun }: - -rec { - defaultStdenv = import ../stdenv { - inherit system platform config crossSystem lib; - allPackages = nixpkgsFun; - } // { inherit platform; }; - - stdenv = - if bootStdenv != null - then (bootStdenv // { inherit platform; }) - else defaultStdenv; -} From 39753f5360134f1aab1a949260374a876c0983eb Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sun, 27 Nov 2016 12:37:45 -0800 Subject: [PATCH 5/9] top-level: Close over fewer arguments for stdenv stages This makes the flow of data easier to understand. There's little downside because the args in question are already inspected by the stdenvs. cross-compiling in particular is simpler because we don't need to worry about overriding the config closed over by `allPackages`. --- pkgs/stdenv/cross/default.nix | 12 ++++++------ pkgs/stdenv/custom/default.nix | 9 ++++++--- pkgs/stdenv/darwin/default.nix | 2 +- pkgs/stdenv/default.nix | 10 ++++++---- pkgs/stdenv/linux/default.nix | 2 +- pkgs/stdenv/native/default.nix | 2 +- pkgs/top-level/default.nix | 5 +++-- 7 files changed, 24 insertions(+), 18 deletions(-) diff --git a/pkgs/stdenv/cross/default.nix b/pkgs/stdenv/cross/default.nix index fcf06bcf1da..10e2a766356 100644 --- a/pkgs/stdenv/cross/default.nix +++ b/pkgs/stdenv/cross/default.nix @@ -1,14 +1,14 @@ -{ system, allPackages, platform, crossSystem, config, ... } @ args: +{ lib, allPackages +, system, platform, crossSystem, config +}: rec { - argClobber = { + vanillaStdenv = (import ../. { + inherit lib allPackages system platform; crossSystem = null; # Ignore custom stdenvs when cross compiling for compatability config = builtins.removeAttrs config [ "replaceStdenv" ]; - }; - vanillaStdenv = (import ../. (args // argClobber // { - allPackages = args: allPackages (argClobber // args); - })) // { + }) // { # Needed elsewhere as a hacky way to pass the target cross = crossSystem; }; diff --git a/pkgs/stdenv/custom/default.nix b/pkgs/stdenv/custom/default.nix index e8f203d69cf..174b8593c0a 100644 --- a/pkgs/stdenv/custom/default.nix +++ b/pkgs/stdenv/custom/default.nix @@ -1,10 +1,13 @@ -{ system, allPackages, platform, crossSystem, config, ... } @ args: +{ lib, allPackages +, system, platform, crossSystem, config +}: rec { - vanillaStdenv = import ../. (args // { + vanillaStdenv = import ../. { + inherit lib allPackages system platform crossSystem; # Remove config.replaceStdenv to ensure termination. config = builtins.removeAttrs config [ "replaceStdenv" ]; - }); + }; buildPackages = allPackages { inherit system platform crossSystem config; diff --git a/pkgs/stdenv/darwin/default.nix b/pkgs/stdenv/darwin/default.nix index 49c4d9b8b2b..6182c8cc0c7 100644 --- a/pkgs/stdenv/darwin/default.nix +++ b/pkgs/stdenv/darwin/default.nix @@ -100,7 +100,7 @@ in rec { }; thisPkgs = allPackages { - inherit system platform; + inherit system platform config; allowCustomOverrides = false; stdenv = thisStdenv; }; diff --git a/pkgs/stdenv/default.nix b/pkgs/stdenv/default.nix index bd515181fc6..246e656f33b 100644 --- a/pkgs/stdenv/default.nix +++ b/pkgs/stdenv/default.nix @@ -5,12 +5,13 @@ # Posix utilities, the GNU C compiler, and so on. On other systems, # we use the native C library. -{ system, allPackages ? import ../top-level, platform, config, crossSystem, lib }: - +{ # Args just for stdenvs' usage + lib, allPackages + # Args to pass on to `allPacakges` too +, system, platform, crossSystem, config +}: let - - # The native (i.e., impure) build environment. This one uses the # tools installed on the system outside of the Nix environment, # i.e., the stuff in /bin, /usr/bin, etc. This environment should @@ -19,6 +20,7 @@ let inherit (import ./native { inherit system allPackages config; }) stdenvNative; stdenvNativePkgs = allPackages { + inherit system platform crossSystem config; allowCustomOverrides = false; stdenv = stdenvNative; noSysDirs = false; diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix index e0a68bdca2f..e4bf87c5202 100644 --- a/pkgs/stdenv/linux/default.nix +++ b/pkgs/stdenv/linux/default.nix @@ -106,7 +106,7 @@ rec { }; thisPkgs = allPackages { - inherit system platform; + inherit system platform config; allowCustomOverrides = false; stdenv = thisStdenv; }; diff --git a/pkgs/stdenv/native/default.nix b/pkgs/stdenv/native/default.nix index 22b4dc1400f..0f9aee214b3 100644 --- a/pkgs/stdenv/native/default.nix +++ b/pkgs/stdenv/native/default.nix @@ -126,7 +126,7 @@ rec { } // {inherit fetchurl;}; stdenvBoot1Pkgs = allPackages { - inherit system; + inherit system platform config; allowCustomOverrides = false; stdenv = stdenvBoot1; }; diff --git a/pkgs/top-level/default.nix b/pkgs/top-level/default.nix index d1e824a8070..9464a8012b3 100644 --- a/pkgs/top-level/default.nix +++ b/pkgs/top-level/default.nix @@ -69,9 +69,10 @@ in let # deterministically inferred the same way. nixpkgsFun = newArgs: import ./. (args // newArgs); - # Partially apply some args for building bootstraping stage pkgs sets + # Partially apply some arguments for building bootstraping stage pkgs + # sets. Only apply arguments which no stdenv would want to override. allPackages = newArgs: import ./stage.nix ({ - inherit lib nixpkgsFun config; + inherit lib nixpkgsFun; } // newArgs); stdenv = import ../stdenv { From 05c12f147e932c990f4b026b9efe0b7a1985461e Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 26 Nov 2016 15:13:43 -0800 Subject: [PATCH 6/9] top-level: Move default-choosing logic to top-level/platforms.nix This mirrors stdenv/default.nix --- pkgs/top-level/default.nix | 24 +++++++----------------- pkgs/top-level/platforms.nix | 8 ++++++++ 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/pkgs/top-level/default.nix b/pkgs/top-level/default.nix index 9464a8012b3..6b61110f1e7 100644 --- a/pkgs/top-level/default.nix +++ b/pkgs/top-level/default.nix @@ -24,12 +24,11 @@ config ? {} , crossSystem ? null -, platform ? null +, platform ? assert false; null } @ args: let # Rename the function arguments configExpr = config; - platform_ = platform; in let lib = import ../../lib; @@ -42,21 +41,12 @@ in let then configExpr { inherit pkgs; } else configExpr; - # Allow setting the platform in the config file. Otherwise, let's use a reasonable default (pc) - - platformAuto = let - platforms = (import ./platforms.nix); - in - if system == "armv6l-linux" then platforms.raspberrypi - else if system == "armv7l-linux" then platforms.armv7l-hf-multiplatform - else if system == "armv5tel-linux" then platforms.sheevaplug - else if system == "mips64el-linux" then platforms.fuloong2f_n32 - else if system == "x86_64-linux" then platforms.pc64 - else if system == "i686-linux" then platforms.pc32 - else platforms.pcBase; - - platform = if platform_ != null then platform_ - else config.platform or platformAuto; + # Allow setting the platform in the config file. Otherwise, let's use a + # reasonable default. + platform = + args.platform + or (config.platform + or (import ./platforms.nix).selectPlatformBySystem system); # A few packages make a new package set to draw their dependencies from. # (Currently to get a cross tool chain, or forced-i686 package.) Rather than diff --git a/pkgs/top-level/platforms.nix b/pkgs/top-level/platforms.nix index efeae9a9d20..671aaea4491 100644 --- a/pkgs/top-level/platforms.nix +++ b/pkgs/top-level/platforms.nix @@ -443,4 +443,12 @@ rec { }; }; + selectPlatformBySystem = system: + if system == "armv6l-linux" then raspberrypi + else if system == "armv7l-linux" then armv7l-hf-multiplatform + else if system == "armv5tel-linux" then sheevaplug + else if system == "mips64el-linux" then fuloong2f_n32 + else if system == "x86_64-linux" then pc64 + else if system == "i686-linux" then pc32 + else pcBase; } From a55d1ecc9050a50904a13e3a34535990b9e61ae3 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 26 Nov 2016 15:34:13 -0800 Subject: [PATCH 7/9] top-level: Document why `nixpkgsFun` doesn't close over inferred default arguments --- pkgs/top-level/default.nix | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/pkgs/top-level/default.nix b/pkgs/top-level/default.nix index 6b61110f1e7..a1f3a1c38c5 100644 --- a/pkgs/top-level/default.nix +++ b/pkgs/top-level/default.nix @@ -55,8 +55,15 @@ in let # whatever arguments it doesn't explicitly provide. This way, # `all-packages.nix` doesn't know more than it needs too. # - # It's OK that `args` doesn't include the defaults: they'll be - # deterministically inferred the same way. + # It's OK that `args` doesn't include default arguemtns from this file: + # they'll be deterministically inferred. In fact we must *not* include them, + # because it's important that if some parameter which affects the default is + # substituted with a different argument, the default is re-inferred. + # + # To put this in concrete terms, this function is basically just used today to + # use package for a different platform for the current platform (namely cross + # compiling toolchains and 32-bit packages on x86_64). In both those cases we + # want the provided non-native `system` argument to affect the stdenv chosen. nixpkgsFun = newArgs: import ./. (args // newArgs); # Partially apply some arguments for building bootstraping stage pkgs From 4751d9e5ad124284dbd719d3a58f42d56f1b9514 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 30 Nov 2016 18:51:13 -0500 Subject: [PATCH 8/9] top-level: turn the screw - Non-cross stdenvs are honest and assert that `crossSystem` is null - `crossSystem` is a mandatory argument to top-level/stage.nix, just like `system` and `platform` - Broken default arguments on stdenvs for testing are gone. - All stdenvs (but little-used stdenvNix) take the same arguments for easy testing. --- pkgs/stdenv/custom/default.nix | 2 ++ pkgs/stdenv/darwin/default.nix | 10 +++++----- pkgs/stdenv/default.nix | 16 ++++++++-------- pkgs/stdenv/freebsd/default.nix | 8 ++++---- pkgs/stdenv/linux/default.nix | 10 +++++----- pkgs/stdenv/native/default.nix | 8 ++++++-- pkgs/top-level/stage.nix | 2 +- 7 files changed, 31 insertions(+), 25 deletions(-) diff --git a/pkgs/stdenv/custom/default.nix b/pkgs/stdenv/custom/default.nix index 174b8593c0a..188d0027773 100644 --- a/pkgs/stdenv/custom/default.nix +++ b/pkgs/stdenv/custom/default.nix @@ -2,6 +2,8 @@ , system, platform, crossSystem, config }: +assert crossSystem == null; + rec { vanillaStdenv = import ../. { inherit lib allPackages system platform crossSystem; diff --git a/pkgs/stdenv/darwin/default.nix b/pkgs/stdenv/darwin/default.nix index 6182c8cc0c7..b9044f25cd7 100644 --- a/pkgs/stdenv/darwin/default.nix +++ b/pkgs/stdenv/darwin/default.nix @@ -1,7 +1,5 @@ -{ system ? builtins.currentSystem -, allPackages ? import ../../.. -, platform ? null -, config ? {} +{ lib, allPackages +, system, platform, crossSystem, config # Allow passing in bootstrap files directly so we can test the stdenv bootstrap process when changing the bootstrap tools , bootstrapFiles ? let @@ -17,6 +15,8 @@ } }: +assert crossSystem == null; + let libSystemProfile = '' (import "${./standard-sandbox.sb}") @@ -100,7 +100,7 @@ in rec { }; thisPkgs = allPackages { - inherit system platform config; + inherit system platform crossSystem config; allowCustomOverrides = false; stdenv = thisStdenv; }; diff --git a/pkgs/stdenv/default.nix b/pkgs/stdenv/default.nix index 246e656f33b..3b49d0de830 100644 --- a/pkgs/stdenv/default.nix +++ b/pkgs/stdenv/default.nix @@ -9,7 +9,7 @@ lib, allPackages # Args to pass on to `allPacakges` too , system, platform, crossSystem, config -}: +} @ args: let # The native (i.e., impure) build environment. This one uses the @@ -17,7 +17,7 @@ let # i.e., the stuff in /bin, /usr/bin, etc. This environment should # be used with care, since many Nix packages will not build properly # with it (e.g., because they require GNU Make). - inherit (import ./native { inherit system allPackages config; }) stdenvNative; + inherit (import ./native args) stdenvNative; stdenvNativePkgs = allPackages { inherit system platform crossSystem config; @@ -28,22 +28,22 @@ let # The Nix build environment. - stdenvNix = import ./nix { + stdenvNix = assert crossSystem == null; import ./nix { inherit config lib; stdenv = stdenvNative; pkgs = stdenvNativePkgs; }; - inherit (import ./freebsd { inherit system allPackages platform config; }) stdenvFreeBSD; + inherit (import ./freebsd args) stdenvFreeBSD; # Linux standard environment. - inherit (import ./linux { inherit system allPackages platform config lib; }) stdenvLinux; + inherit (import ./linux args) stdenvLinux; - inherit (import ./darwin { inherit system allPackages platform config; }) stdenvDarwin; + inherit (import ./darwin args) stdenvDarwin; - inherit (import ./cross { inherit system allPackages platform crossSystem config lib; }) stdenvCross stdenvCrossiOS; + inherit (import ./cross args) stdenvCross stdenvCrossiOS; - inherit (import ./custom { inherit system allPackages platform crossSystem config lib; }) stdenvCustom; + inherit (import ./custom args) stdenvCustom; # Select the appropriate stdenv for the platform `system'. in diff --git a/pkgs/stdenv/freebsd/default.nix b/pkgs/stdenv/freebsd/default.nix index 13cb21fe1d8..ea2ebcc7917 100644 --- a/pkgs/stdenv/freebsd/default.nix +++ b/pkgs/stdenv/freebsd/default.nix @@ -1,9 +1,9 @@ -{ system ? builtins.currentSystem -, allPackages ? import ../../.. -, platform ? null -, config ? {} +{ lib, allPackages +, system, platform, crossSystem, config }: +assert crossSystem == null; + rec { inherit allPackages; diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix index e4bf87c5202..34196359f52 100644 --- a/pkgs/stdenv/linux/default.nix +++ b/pkgs/stdenv/linux/default.nix @@ -3,11 +3,9 @@ # external (non-Nix) tools, such as /usr/bin/gcc, and it contains a C # compiler and linker that do not search in default locations, # ensuring purity of components produced by it. +{ lib, allPackages +, system, platform, crossSystem, config -# The function defaults are for easy testing. -{ system ? builtins.currentSystem -, allPackages ? import ../../.. -, platform ? null, config ? {}, lib ? (import ../../../lib) , bootstrapFiles ? if system == "i686-linux" then import ./bootstrap/i686.nix else if system == "x86_64-linux" then import ./bootstrap/x86_64.nix @@ -18,6 +16,8 @@ else abort "unsupported platform for the pure Linux stdenv" }: +assert crossSystem == null; + rec { commonPreHook = @@ -106,7 +106,7 @@ rec { }; thisPkgs = allPackages { - inherit system platform config; + inherit system platform crossSystem config; allowCustomOverrides = false; stdenv = thisStdenv; }; diff --git a/pkgs/stdenv/native/default.nix b/pkgs/stdenv/native/default.nix index 0f9aee214b3..8396bd0cb01 100644 --- a/pkgs/stdenv/native/default.nix +++ b/pkgs/stdenv/native/default.nix @@ -1,4 +1,8 @@ -{ system, allPackages ? import ../../.., config }: +{ lib, allPackages +, system, platform, crossSystem, config +}: + +assert crossSystem == null; rec { @@ -126,7 +130,7 @@ rec { } // {inherit fetchurl;}; stdenvBoot1Pkgs = allPackages { - inherit system platform config; + inherit system platform crossSystem config; allowCustomOverrides = false; stdenv = stdenvBoot1; }; diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix index 0c621b81c7e..1d6305151ca 100644 --- a/pkgs/top-level/stage.nix +++ b/pkgs/top-level/stage.nix @@ -30,7 +30,7 @@ , # The configuration attribute set config -, crossSystem ? null +, crossSystem , platform , lib , nixpkgsFun From 5c6234a7d3f0b430d7dc941dc1ab059c42729611 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 3 Dec 2016 17:21:07 -0800 Subject: [PATCH 9/9] top-level: Allow manually specifying a stdenv, and fix stdenv tests - The darwin test can now force the use of the freshly-booted darwin stdenv - The linux test now passes enough dummy arguments This may make debugging harder, if so, check out #20889 --- pkgs/stdenv/darwin/make-bootstrap-tools.nix | 8 ++++---- pkgs/stdenv/linux/make-bootstrap-tools.nix | 7 +++++++ pkgs/top-level/default.nix | 6 +++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/pkgs/stdenv/darwin/make-bootstrap-tools.nix b/pkgs/stdenv/darwin/make-bootstrap-tools.nix index 10d2b4decdd..bd581f71a43 100644 --- a/pkgs/stdenv/darwin/make-bootstrap-tools.nix +++ b/pkgs/stdenv/darwin/make-bootstrap-tools.nix @@ -332,10 +332,10 @@ in rec { }; # The ultimate test: bootstrap a whole stdenv from the tools specified above and get a package set out of it - test-pkgs = let - stdenv = import (test-pkgspath + "/pkgs/stdenv/darwin") { inherit system bootstrapFiles; }; - in import test-pkgspath { + test-pkgs = import test-pkgspath { inherit system; - bootStdenv = stdenv.stdenvDarwin; + stdenv = args: let + args' = args // { inherit bootstrapFiles; }; + in (import (test-pkgspath + "/pkgs/stdenv/darwin") args').stdenvDarwin; }; } diff --git a/pkgs/stdenv/linux/make-bootstrap-tools.nix b/pkgs/stdenv/linux/make-bootstrap-tools.nix index 1ecb222af3e..7063d7bfcb6 100644 --- a/pkgs/stdenv/linux/make-bootstrap-tools.nix +++ b/pkgs/stdenv/linux/make-bootstrap-tools.nix @@ -175,6 +175,13 @@ rec { bootstrapTools = (import ./default.nix { inherit system bootstrapFiles; + + lib = assert false; null; + allPackages = assert false; null; + + platform = assert false; null; + crossSystem = assert false; null; + config = assert false; null; }).bootstrapTools; test = derivation { diff --git a/pkgs/top-level/default.nix b/pkgs/top-level/default.nix index a1f3a1c38c5..31c51215676 100644 --- a/pkgs/top-level/default.nix +++ b/pkgs/top-level/default.nix @@ -23,6 +23,10 @@ , # Allow a configuration attribute set to be passed in as an argument. config ? {} +, # The standard environment for building packages, or rather a function + # providing it. See below for the arguments given to that function. + stdenv ? assert false; null + , crossSystem ? null , platform ? assert false; null } @ args: @@ -72,7 +76,7 @@ in let inherit lib nixpkgsFun; } // newArgs); - stdenv = import ../stdenv { + stdenv = (args.stdenv or (import ../stdenv)) { inherit lib allPackages system platform crossSystem config; };