about summary refs log tree commit diff
path: root/nixpkgs/pkgs/stdenv/adapters.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/stdenv/adapters.nix')
-rw-r--r--nixpkgs/pkgs/stdenv/adapters.nix125
1 files changed, 76 insertions, 49 deletions
diff --git a/nixpkgs/pkgs/stdenv/adapters.nix b/nixpkgs/pkgs/stdenv/adapters.nix
index a8e984d61743..719f67998266 100644
--- a/nixpkgs/pkgs/stdenv/adapters.nix
+++ b/nixpkgs/pkgs/stdenv/adapters.nix
@@ -2,7 +2,31 @@
    a new stdenv with different behaviour, e.g. using a different C
    compiler. */
 
-pkgs:
+{ lib, pkgs, config }:
+
+let
+  # N.B. Keep in sync with default arg for stdenv/generic.
+  defaultMkDerivationFromStdenv = import ./generic/make-derivation.nix { inherit lib config; };
+
+  # Low level function to help with overriding `mkDerivationFromStdenv`. One
+  # gives it the old stdenv arguments and a "continuation" function, and
+  # underneath the final stdenv argument it yields to the continuation to do
+  # whatever it wants with old `mkDerivation` (old `mkDerivationFromStdenv`
+  # applied to the *new, final* stdenv) provided for convenience.
+  withOldMkDerivation = stdenvSuperArgs: k: stdenvSelf: let
+    mkDerivationFromStdenv-super = stdenvSuperArgs.mkDerivationFromStdenv or defaultMkDerivationFromStdenv;
+    mkDerivationSuper = mkDerivationFromStdenv-super stdenvSelf;
+  in
+    k stdenvSelf mkDerivationSuper;
+
+  # Wrap the original `mkDerivation` providing extra args to it.
+  extendMkDerivationArgs = old: f: withOldMkDerivation old (_: mkDerivationSuper: args:
+    mkDerivationSuper (args // f args));
+
+  # Wrap the original `mkDerivation` transforming the result.
+  overrideMkDerivationResult = old: f: withOldMkDerivation old (_: mkDerivationSuper: args:
+    f (mkDerivationSuper args));
+in
 
 rec {
 
@@ -31,33 +55,32 @@ rec {
 
   # Return a modified stdenv that tries to build statically linked
   # binaries.
-  makeStaticBinaries = stdenv:
-    let stdenv' = if stdenv.hostPlatform.libc != "glibc" then stdenv else
-      stdenv.override (prev: {
-          extraBuildInputs = (prev.extraBuildInputs or []) ++ [
-              stdenv.glibc.static
-            ];
-        });
-    in stdenv' //
-    { mkDerivation = args:
-      if stdenv'.hostPlatform.isDarwin
+  makeStaticBinaries = stdenv0:
+    stdenv0.override (old: {
+      mkDerivationFromStdenv = withOldMkDerivation old (stdenv: mkDerivationSuper: args:
+      if stdenv.hostPlatform.isDarwin
       then throw "Cannot build fully static binaries on Darwin/macOS"
-      else stdenv'.mkDerivation (args // {
+      else mkDerivationSuper (args // {
         NIX_CFLAGS_LINK = toString (args.NIX_CFLAGS_LINK or "") + " -static";
-      } // pkgs.lib.optionalAttrs (!(args.dontAddStaticConfigureFlags or false)) {
+      } // lib.optionalAttrs (!(args.dontAddStaticConfigureFlags or false)) {
         configureFlags = (args.configureFlags or []) ++ [
             "--disable-shared" # brrr...
           ];
-      });
-    };
+      }));
+    } // lib.optionalAttrs (stdenv0.hostPlatform.libc == "libc") {
+      extraBuildInputs = (old.extraBuildInputs or []) ++ [
+        stdenv0.glibc.static
+      ];
+    });
 
 
   # Return a modified stdenv that builds static libraries instead of
   # shared libraries.
-  makeStaticLibraries = stdenv: stdenv //
-    { mkDerivation = args: stdenv.mkDerivation (args // {
+  makeStaticLibraries = stdenv:
+    stdenv.override (old: {
+      mkDerivationFromStdenv = extendMkDerivationArgs old (args: {
         dontDisableStatic = true;
-      } // pkgs.lib.optionalAttrs (!(args.dontAddStaticConfigureFlags or false)) {
+      } // lib.optionalAttrs (!(args.dontAddStaticConfigureFlags or false)) {
         configureFlags = (args.configureFlags or []) ++ [
           "--enable-static"
           "--disable-shared"
@@ -65,18 +88,19 @@ rec {
         cmakeFlags = (args.cmakeFlags or []) ++ [ "-DBUILD_SHARED_LIBS:BOOL=OFF" ];
         mesonFlags = (args.mesonFlags or []) ++ [ "-Ddefault_library=static" ];
       });
-    };
+    });
 
 
   /* Modify a stdenv so that all buildInputs are implicitly propagated to
      consuming derivations
   */
-  propagateBuildInputs = stdenv: stdenv //
-    { mkDerivation = args: stdenv.mkDerivation (args // {
+  propagateBuildInputs = stdenv:
+    stdenv.override (old: {
+      mkDerivationFromStdenv = extendMkDerivationArgs old (args: {
         propagatedBuildInputs = (args.propagatedBuildInputs or []) ++ (args.buildInputs or []);
         buildInputs = [];
       });
-    };
+    });
 
 
   /* Modify a stdenv so that the specified attributes are added to
@@ -88,8 +112,9 @@ rec {
            { NIX_CFLAGS_COMPILE = "-O0"; }
            stdenv;
   */
-  addAttrsToDerivation = extraAttrs: stdenv: stdenv //
-    { mkDerivation = args: stdenv.mkDerivation (args // extraAttrs); };
+  addAttrsToDerivation = extraAttrs: stdenv: stdenv.override (old: {
+    mkDerivationFromStdenv = extendMkDerivationArgs old (_: extraAttrs);
+  });
 
 
   /* Return a modified stdenv that builds packages with GCC's coverage
@@ -110,21 +135,20 @@ rec {
      # remove all maintainers.
      defaultStdenv = replaceMaintainersField allStdenvs.stdenv pkgs [];
   */
-  replaceMaintainersField = stdenv: pkgs: maintainers: stdenv //
-    { mkDerivation = args:
-        pkgs.lib.recursiveUpdate
-          (stdenv.mkDerivation args)
-          { meta.maintainers = maintainers; };
-    };
+  replaceMaintainersField = stdenv: pkgs: maintainers:
+    stdenv.override (old: {
+      mkDerivationFromStdenv = overrideMkDerivationResult (pkg:
+        lib.recursiveUpdate pkg { meta.maintainers = maintainers; });
+    });
 
 
   /* Use the trace output to report all processed derivations with their
      license name.
   */
-  traceDrvLicenses = stdenv: stdenv //
-    { mkDerivation = args:
+  traceDrvLicenses = stdenv:
+    stdenv.override (old: {
+      mkDerivationFromStdenv = overrideMkDerivationResult (pkg:
         let
-          pkg = stdenv.mkDerivation args;
           printDrvPath = val: let
             drvPath = builtins.unsafeDiscardStringContext pkg.drvPath;
             license = pkg.meta.license or null;
@@ -133,8 +157,8 @@ rec {
         in pkg // {
           outPath = printDrvPath pkg.outPath;
           drvPath = printDrvPath pkg.drvPath;
-        };
-    };
+        });
+    });
 
 
   /* Abort if the license predicate is not verified for a derivation
@@ -152,10 +176,10 @@ rec {
      use it by patching the all-packages.nix file or by using the override
      feature of ~/.config/nixpkgs/config.nix .
   */
-  validateLicenses = licensePred: stdenv: stdenv //
-    { mkDerivation = args:
+  validateLicenses = licensePred: stdenv:
+    stdenv.override (old: {
+      mkDerivationFromStdenv = overrideMkDerivationResult (pkg:
         let
-          pkg = stdenv.mkDerivation args;
           drv = builtins.unsafeDiscardStringContext pkg.drvPath;
           license =
             pkg.meta.license or
@@ -175,40 +199,43 @@ rec {
         in pkg // {
           outPath = validate pkg.outPath;
           drvPath = validate pkg.drvPath;
-        };
-    };
+        });
+    });
 
 
   /* Modify a stdenv so that it produces debug builds; that is,
      binaries have debug info, and compiler optimisations are
      disabled. */
-  keepDebugInfo = stdenv: stdenv //
-    { mkDerivation = args: stdenv.mkDerivation (args // {
+  keepDebugInfo = stdenv:
+    stdenv.override (old: {
+      mkDerivationFromStdenv = extendMkDerivationArgs old (args: {
         dontStrip = true;
         NIX_CFLAGS_COMPILE = toString (args.NIX_CFLAGS_COMPILE or "") + " -ggdb -Og";
       });
-    };
+    });
 
 
   /* Modify a stdenv so that it uses the Gold linker. */
-  useGoldLinker = stdenv: stdenv //
-    { mkDerivation = args: stdenv.mkDerivation (args // {
+  useGoldLinker = stdenv:
+    stdenv.override (old: {
+      mkDerivationFromStdenv = extendMkDerivationArgs old (args: {
         NIX_CFLAGS_LINK = toString (args.NIX_CFLAGS_LINK or "") + " -fuse-ld=gold";
       });
-    };
+    });
 
 
   /* Modify a stdenv so that it builds binaries optimized specifically
      for the machine they are built on.
 
      WARNING: this breaks purity! */
-  impureUseNativeOptimizations = stdenv: stdenv //
-    { mkDerivation = args: stdenv.mkDerivation (args // {
+  impureUseNativeOptimizations = stdenv:
+    stdenv.override (old: {
+      mkDerivationFromStdenv = extendMkDerivationArgs old (args: {
         NIX_CFLAGS_COMPILE = toString (args.NIX_CFLAGS_COMPILE or "") + " -march=native";
         NIX_ENFORCE_NO_NATIVE = false;
 
         preferLocalBuild = true;
         allowSubstitutes = false;
       });
-    };
+    });
 }