summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2019-03-13 13:34:38 -0400
committerJohn Ericson <git@JohnEricson.me>2019-03-24 22:12:15 -0400
commit70d71bbbe46eecfefc920bb1a919960d5feb9fc4 (patch)
tree5b65648837c13163f04829c492c1d3f08b898c35
parentceb27efde0532bb663e3d8c4fe20f82ee4dc22e3 (diff)
downloadnixpkgs-70d71bbbe46eecfefc920bb1a919960d5feb9fc4.tar
nixpkgs-70d71bbbe46eecfefc920bb1a919960d5feb9fc4.tar.gz
nixpkgs-70d71bbbe46eecfefc920bb1a919960d5feb9fc4.tar.bz2
nixpkgs-70d71bbbe46eecfefc920bb1a919960d5feb9fc4.tar.lz
nixpkgs-70d71bbbe46eecfefc920bb1a919960d5feb9fc4.tar.xz
nixpkgs-70d71bbbe46eecfefc920bb1a919960d5feb9fc4.tar.zst
nixpkgs-70d71bbbe46eecfefc920bb1a919960d5feb9fc4.zip
top-level: Create `pkgs{Build,Host,Target}{Build,Host,Target}`
This is needed to avoid confusing and repeated boilerplate for
`fooForTarget`.  The vast majority of use-cases can still use
`buildPackages or `targetPackages`, which are now defined in terms of
these.
-rw-r--r--pkgs/stdenv/booter.nix26
-rw-r--r--pkgs/top-level/all-packages.nix3
-rw-r--r--pkgs/top-level/splice.nix23
-rw-r--r--pkgs/top-level/stage.nix59
4 files changed, 74 insertions, 37 deletions
diff --git a/pkgs/stdenv/booter.nix b/pkgs/stdenv/booter.nix
index 668dcabc049..1df05099fbf 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 6ace5f7c99c..ab5265ac885 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 ec6ed357c68..a093442d369 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 0ee5c25b010..f04cdf338e8 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