diff --git a/pkgs/stdenv/booter.nix b/pkgs/stdenv/booter.nix index 668dcabc0499..1df05099fbf5 100644 --- a/pkgs/stdenv/booter.nix +++ b/pkgs/stdenv/booter.nix @@ -95,13 +95,25 @@ stageFuns: let __hatPackages = nextStage; }; }; - in - if args.__raw or false - then args' - else allPackages ((builtins.removeAttrs args' ["selfBuild"]) // { - buildPackages = if args.selfBuild or true then null else prevStage; - targetPackages = if args.selfBuild or true then null else nextStage; - }); + thisStage = + if args.__raw or false + then args' + else allPackages ((builtins.removeAttrs args' ["selfBuild"]) // { + adjacentPackages = if args.selfBuild or true then null else rec { + pkgsBuildBuild = prevStage.buildPackages; + pkgsBuildHost = prevStage; + pkgsBuildTarget = + if args.stdenv.targetPlatform == args.stdenv.hostPlatform + then pkgsBuildHost + else assert args.stdenv.hostPlatform == args.stdenv.buildPlatform; thisStage; + pkgsHostHost = + if args.stdenv.hostPlatform == args.stdenv.targetPlatform + then thisStage + else assert args.stdenv.buildPlatform == args.stdenv.hostPlatform; pkgsBuildHost; + pkgsTargetTarget = nextStage; + }; + }); + in thisStage; # This is a hack for resolving cross-compiled compilers' run-time # deps. (That is, compilers that are themselves cross-compiled, as diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 6ace5f7c99cb..ab5265ac8857 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -25,9 +25,6 @@ let in { - # Allow callPackage to fill in the pkgs argument - inherit pkgs; - # A stdenv capable of building 32-bit binaries. On x86_64-linux, # it uses GCC compiled with multilib support; on i686-linux, it's # just the plain stdenv. diff --git a/pkgs/top-level/splice.nix b/pkgs/top-level/splice.nix index ec6ed357c688..a093442d3698 100644 --- a/pkgs/top-level/splice.nix +++ b/pkgs/top-level/splice.nix @@ -96,19 +96,20 @@ let } @ args: if actuallySplice then spliceReal args else pkgsHostTarget; - splicedPackages = splicePackages rec { - pkgsBuildBuild = pkgs.buildPackages.buildPackages; - pkgsBuildHost = pkgs.buildPackages; - pkgsBuildTarget = - if pkgs.stdenv.targetPlatform == pkgs.stdenv.hostPlatform - then pkgsBuildHost - else assert pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform; pkgsHostTarget; - pkgsHostHost = {}; # unimplemented - pkgsHostTarget = pkgs; - pkgsTargetTarget = pkgs.targetPackages; + splicedPackages = splicePackages { + inherit (pkgs) + pkgsBuildBuild pkgsBuildHost pkgsBuildTarget + pkgsHostHost pkgsHostTarget + pkgsTargetTarget + ; } // { # These should never be spliced under any circumstances - inherit (pkgs) pkgs buildPackages targetPackages; + inherit (pkgs) + pkgsBuildBuild pkgsBuildHost pkgsBuildTarget + pkgsHostHost pkgsHostTarget + pkgsTargetTarget + buildPackages pkgs targetPackages + ; inherit (pkgs.stdenv) buildPlatform targetPlatform hostPlatform; }; diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix index 0ee5c25b0101..f04cdf338e8f 100644 --- a/pkgs/top-level/stage.nix +++ b/pkgs/top-level/stage.nix @@ -21,18 +21,23 @@ ## Other parameters ## -, # The package set used at build-time. If null, `buildPackages` will - # be defined internally as the final produced package set itself. This allows - # us to avoid expensive splicing. - buildPackages - -, # The package set used in the next stage. If null, `targetPackages` will be - # defined internally as the final produced package set itself, just like with - # `buildPackages` and for the same reasons. +, # Either null or an object in the form: # - # THIS IS A HACK for compilers that don't think critically about cross- - # compilation. Please do *not* use unless you really know what you are doing. - targetPackages + # { + # pkgsBuildBuild = ...; + # pkgsBuildHost = ...; + # pkgsBuildTarget = ...; + # pkgsHostHost = ...; + # # pkgsHostTarget skipped on purpose. + # pkgsTargetTarget ...; + # } + # + # These are references to adjacent bootstrapping stages. The more familiar + # `buildPackages` and `targetPackages` are defined in terms of them. If null, + # they are instead defined internally as the current stage. This allows us to + # avoid expensive splicing. `pkgsHostTarget` is skipped because it is always + # defined as the current stage. + adjacentPackages , # The standard environment to use for building packages. stdenv @@ -70,11 +75,33 @@ let inherit (self) runtimeShell; }; - stdenvBootstappingAndPlatforms = self: super: { - buildPackages = (if buildPackages == null then self else buildPackages) - // { recurseForDerivations = false; }; - targetPackages = (if targetPackages == null then self else targetPackages) + stdenvBootstappingAndPlatforms = self: super: let + withFallback = thisPkgs: + (if adjacentPackages == null then self else thisPkgs) // { recurseForDerivations = false; }; + in { + # Here are package sets of from related stages. They are all in the form + # `pkgs{theirHost}{theirTarget}`. For example, `pkgsBuildHost` means their + # host platform is our build platform, and their target platform is our host + # platform. We only care about their host/target platforms, not their build + # platform, because the the former two alone affect the interface of the + # final package; the build platform is just an implementation detail that + # should not leak. + pkgsBuildBuild = withFallback adjacentPackages.pkgsBuildBuild; + pkgsBuildHost = withFallback adjacentPackages.pkgsBuildHost; + pkgsBuildTarget = withFallback adjacentPackages.pkgsBuildTarget; + pkgsHostHost = withFallback adjacentPackages.pkgsHostHost; + pkgsHostTarget = self // { recurseForDerivations = false; }; # always `self` + pkgsTargetTarget = withFallback adjacentPackages.pkgsTargetTarget; + + # Older names for package sets. Use these when only the host platform of the + # package set matter (i.e. use `buildPackages` where any of `pkgsBuild*` + # would do, and `targetPackages` when any of `pkgsTarget*` would do (if we + # had more than just `pkgsTargetTarget`).) + buildPackages = self.pkgsBuildHost; + pkgs = self.pkgsHostTarget; + targetPackages = self.pkgsTargetTarget; + inherit stdenv; }; @@ -87,7 +114,7 @@ let inherit (hostPlatform) system; }; - splice = self: super: import ./splice.nix lib self (buildPackages != null); + splice = self: super: import ./splice.nix lib self (adjacentPackages != null); allPackages = self: super: let res = import ./all-packages.nix