diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2021-08-16 21:16:29 -0400 |
---|---|---|
committer | John Ericson <John.Ericson@Obsidian.Systems> | 2021-08-18 17:22:50 +0000 |
commit | f110a182a66005782c0e58091bcda7243bf2a0ae (patch) | |
tree | 9dc114f30483a606958aea2685110a8382451539 /pkgs/stdenv/adapters.nix | |
parent | aa045621af26840816c7760f0e0f3d41e91dfaa8 (diff) | |
download | nixlib-f110a182a66005782c0e58091bcda7243bf2a0ae.tar nixlib-f110a182a66005782c0e58091bcda7243bf2a0ae.tar.gz nixlib-f110a182a66005782c0e58091bcda7243bf2a0ae.tar.bz2 nixlib-f110a182a66005782c0e58091bcda7243bf2a0ae.tar.lz nixlib-f110a182a66005782c0e58091bcda7243bf2a0ae.tar.xz nixlib-f110a182a66005782c0e58091bcda7243bf2a0ae.tar.zst nixlib-f110a182a66005782c0e58091bcda7243bf2a0ae.zip |
stdenv: Fix overriding + `overrideAttrs`
The old stdenv adapters were subtly wrong in two ways: - `overrideAttrs` leaked the original, unoverridden `mkDerivation`. - `stdenv.override` would throw away any manually-set `mkDerivation` from a stdenv reverting to the original. Now, `mkDerivation` is controlled (nearly directly) via an argument, and always correctly closes over the final ("self") stdenv. This means the adapters can work entirely via `.override` without any manual `stdenv // ...`, and both those issues are fixed. Note hashes are changed, because stdenvs no previously overridden like `stdenvNoCC` and `crossLibcStdenv` now are. I had to add some `dontDisableStatic = true` accordingly. The flip side however is that since the overrides compose, we no longer need to override anything but the default `stdenv` from which all the others are created.
Diffstat (limited to 'pkgs/stdenv/adapters.nix')
-rw-r--r-- | pkgs/stdenv/adapters.nix | 125 |
1 files changed, 76 insertions, 49 deletions
diff --git a/pkgs/stdenv/adapters.nix b/pkgs/stdenv/adapters.nix index a8e984d61743..719f67998266 100644 --- a/pkgs/stdenv/adapters.nix +++ b/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; }); - }; + }); } |