summary refs log tree commit diff
path: root/pkgs/stdenv/generic
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/stdenv/generic')
-rw-r--r--pkgs/stdenv/generic/check-meta.nix5
-rw-r--r--pkgs/stdenv/generic/default-builder.sh4
-rw-r--r--pkgs/stdenv/generic/make-derivation.nix232
-rw-r--r--pkgs/stdenv/generic/setup.sh89
4 files changed, 197 insertions, 133 deletions
diff --git a/pkgs/stdenv/generic/check-meta.nix b/pkgs/stdenv/generic/check-meta.nix
index 63fd00d266e..9a794531bc1 100644
--- a/pkgs/stdenv/generic/check-meta.nix
+++ b/pkgs/stdenv/generic/check-meta.nix
@@ -152,9 +152,8 @@ let
 
     # flakeNote will be printed in the remediation messages below.
     flakeNote = "
- Note: For `nix shell`, `nix build`, `nix develop` or any other Nix 2.4+
- (Flake) command, `--impure` must be passed in order to read this
- environment variable.
+   Note: When using `nix shell`, `nix build`, `nix develop`, etc with a flake,
+         then pass `--impure` in order to allow use of environment variables.
     ";
 
   remediate_allowlist = allow_attr: rebuild_amendment: attrs:
diff --git a/pkgs/stdenv/generic/default-builder.sh b/pkgs/stdenv/generic/default-builder.sh
index 8c6fec7873b..d49fb8aa57f 100644
--- a/pkgs/stdenv/generic/default-builder.sh
+++ b/pkgs/stdenv/generic/default-builder.sh
@@ -1,6 +1,4 @@
-if [ -f .attrs.sh ]; then
-    . .attrs.sh
-fi
+if [ -e "$NIX_ATTRS_SH_FILE" ]; then . "$NIX_ATTRS_SH_FILE"; elif [ -f .attrs.sh ]; then . .attrs.sh; fi
 
 source $stdenv/setup
 genericBuild
diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix
index 1412d224a84..63d02c8f085 100644
--- a/pkgs/stdenv/generic/make-derivation.nix
+++ b/pkgs/stdenv/generic/make-derivation.nix
@@ -3,6 +3,43 @@
 stdenv:
 
 let
+  # Lib attributes are inherited to the lexical scope for performance reasons.
+  inherit (lib)
+    any
+    assertMsg
+    attrNames
+    boolToString
+    chooseDevOutputs
+    concatLists
+    concatMap
+    concatMapStrings
+    concatStringsSep
+    elem
+    elemAt
+    extendDerivation
+    filter
+    findFirst
+    flip
+    head
+    imap1
+    isAttrs
+    isBool
+    isDerivation
+    isInt
+    isList
+    isString
+    mapAttrs
+    mapNullable
+    optional
+    optionalAttrs
+    optionalString
+    optionals
+    remove
+    splitString
+    subtractLists
+    unique
+  ;
+
   checkMeta = import ./check-meta.nix {
     inherit lib config;
     # Nix itself uses the `system` field of a derivation to decide where
@@ -115,7 +152,7 @@ let
   # Including it then would cause needless mass rebuilds.
   #
   # TODO(@Ericson2314): Make [ "build" "host" ] always the default / resolve #87909
-  configurePlatforms ? lib.optionals
+  configurePlatforms ? optionals
     (stdenv.hostPlatform != stdenv.buildPlatform || config.configurePlatformsByDefault)
     [ "build" "host" ]
 
@@ -165,6 +202,17 @@ let
 
 , ... } @ attrs:
 
+# Policy on acceptable hash types in nixpkgs
+assert attrs ? outputHash -> (
+  let algo =
+    attrs.outputHashAlgo or (head (splitString "-" attrs.outputHash));
+  in
+  if algo == "md5" then
+    throw "Rejected insecure ${algo} hash '${attrs.outputHash}'"
+  else
+    true
+);
+
 let
   # TODO(@oxij, @Ericson2314): This is here to keep the old semantics, remove when
   # no package has `doCheck = true`.
@@ -172,12 +220,12 @@ let
   doInstallCheck' = doInstallCheck && stdenv.buildPlatform.canExecute stdenv.hostPlatform;
 
   separateDebugInfo' = separateDebugInfo && stdenv.hostPlatform.isLinux;
-  outputs' = outputs ++ lib.optional separateDebugInfo' "debug";
+  outputs' = outputs ++ optional separateDebugInfo' "debug";
 
   # Turn a derivation into its outPath without a string context attached.
   # See the comment at the usage site.
   unsafeDerivationToUntrackedOutpath = drv:
-    if lib.isDerivation drv
+    if isDerivation drv
     then builtins.unsafeDiscardStringContext drv.outPath
     else drv;
 
@@ -187,9 +235,9 @@ let
                                   ++ depsTargetTarget ++ depsTargetTargetPropagated) == 0;
   dontAddHostSuffix = attrs ? outputHash && !noNonNativeDeps || !stdenv.hasCC;
 
-  hardeningDisable' = if lib.any (x: x == "fortify") hardeningDisable
+  hardeningDisable' = if any (x: x == "fortify") hardeningDisable
     # disabling fortify implies fortify3 should also be disabled
-    then lib.unique (hardeningDisable ++ [ "fortify3" ])
+    then unique (hardeningDisable ++ [ "fortify3" ])
     else hardeningDisable;
   supportedHardeningFlags = [ "fortify" "fortify3" "stackprotector" "pie" "pic" "strictoverflow" "format" "relro" "bindnow" ];
   # Musl-based platforms will keep "pie", other platforms will not.
@@ -201,19 +249,19 @@ let
       #    - static armv7l, where compilation fails.
       !(stdenv.hostPlatform.isAarch && stdenv.hostPlatform.isStatic)
     then supportedHardeningFlags
-    else lib.remove "pie" supportedHardeningFlags;
+    else remove "pie" supportedHardeningFlags;
   enabledHardeningOptions =
     if builtins.elem "all" hardeningDisable'
     then []
-    else lib.subtractLists hardeningDisable' (defaultHardeningFlags ++ hardeningEnable);
+    else subtractLists hardeningDisable' (defaultHardeningFlags ++ hardeningEnable);
   # hardeningDisable additionally supports "all".
-  erroneousHardeningFlags = lib.subtractLists supportedHardeningFlags (hardeningEnable ++ lib.remove "all" hardeningDisable);
+  erroneousHardeningFlags = subtractLists supportedHardeningFlags (hardeningEnable ++ remove "all" hardeningDisable);
 
   checkDependencyList = checkDependencyList' [];
-  checkDependencyList' = positions: name: deps: lib.flip lib.imap1 deps (index: dep:
-    if lib.isDerivation dep || dep == null || builtins.isString dep || builtins.isPath dep then dep
-    else if lib.isList dep then checkDependencyList' ([index] ++ positions) name dep
-    else throw "Dependency is not of a valid type: ${lib.concatMapStrings (ix: "element ${toString ix} of ") ([index] ++ positions)}${name} for ${attrs.name or attrs.pname}");
+  checkDependencyList' = positions: name: deps: flip imap1 deps (index: dep:
+    if isDerivation dep || dep == null || builtins.isString dep || builtins.isPath dep then dep
+    else if isList dep then checkDependencyList' ([index] ++ positions) name dep
+    else throw "Dependency is not of a valid type: ${concatMapStrings (ix: "element ${toString ix} of ") ([index] ++ positions)}${name} for ${attrs.name or attrs.pname}");
 in if builtins.length erroneousHardeningFlags != 0
 then abort ("mkDerivation was called with unsupported hardening flags: " + lib.generators.toPretty {} {
   inherit erroneousHardeningFlags hardeningDisable hardeningEnable supportedHardeningFlags;
@@ -222,20 +270,20 @@ else let
   doCheck = doCheck';
   doInstallCheck = doInstallCheck';
   buildInputs' = buildInputs
-         ++ lib.optionals doCheck checkInputs
-         ++ lib.optionals doInstallCheck installCheckInputs;
+         ++ optionals doCheck checkInputs
+         ++ optionals doInstallCheck installCheckInputs;
   nativeBuildInputs' = nativeBuildInputs
-         ++ lib.optional separateDebugInfo' ../../build-support/setup-hooks/separate-debug-info.sh
-         ++ lib.optional stdenv.hostPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh
-         ++ lib.optionals doCheck nativeCheckInputs
-         ++ lib.optionals doInstallCheck nativeInstallCheckInputs;
+         ++ optional separateDebugInfo' ../../build-support/setup-hooks/separate-debug-info.sh
+         ++ optional stdenv.hostPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh
+         ++ optionals doCheck nativeCheckInputs
+         ++ optionals doInstallCheck nativeInstallCheckInputs;
 
   outputs = outputs';
 
   references = nativeBuildInputs ++ buildInputs
             ++ propagatedNativeBuildInputs ++ propagatedBuildInputs;
 
-  dependencies = map (map lib.chooseDevOutputs) [
+  dependencies = map (map chooseDevOutputs) [
     [
       (map (drv: drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuild" depsBuildBuild))
       (map (drv: drv.__spliced.buildHost or drv) (checkDependencyList "nativeBuildInputs" nativeBuildInputs'))
@@ -249,7 +297,7 @@ else let
       (map (drv: drv.__spliced.targetTarget or drv) (checkDependencyList "depsTargetTarget" depsTargetTarget))
     ]
   ];
-  propagatedDependencies = map (map lib.chooseDevOutputs) [
+  propagatedDependencies = map (map chooseDevOutputs) [
     [
       (map (drv: drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuildPropagated" depsBuildBuildPropagated))
       (map (drv: drv.__spliced.buildHost or drv) (checkDependencyList "propagatedNativeBuildInputs" propagatedNativeBuildInputs))
@@ -265,26 +313,26 @@ else let
   ];
 
   computedSandboxProfile =
-    lib.concatMap (input: input.__propagatedSandboxProfile or [])
+    concatMap (input: input.__propagatedSandboxProfile or [])
       (stdenv.extraNativeBuildInputs
        ++ stdenv.extraBuildInputs
-       ++ lib.concatLists dependencies);
+       ++ concatLists dependencies);
 
   computedPropagatedSandboxProfile =
-    lib.concatMap (input: input.__propagatedSandboxProfile or [])
-      (lib.concatLists propagatedDependencies);
+    concatMap (input: input.__propagatedSandboxProfile or [])
+      (concatLists propagatedDependencies);
 
   computedImpureHostDeps =
-    lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or [])
+    unique (concatMap (input: input.__propagatedImpureHostDeps or [])
       (stdenv.extraNativeBuildInputs
        ++ stdenv.extraBuildInputs
-       ++ lib.concatLists dependencies));
+       ++ concatLists dependencies));
 
   computedPropagatedImpureHostDeps =
-    lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or [])
-      (lib.concatLists propagatedDependencies));
+    unique (concatMap (input: input.__propagatedImpureHostDeps or [])
+      (concatLists propagatedDependencies));
 
-  envIsExportable = lib.isAttrs env && !lib.isDerivation env;
+  envIsExportable = isAttrs env && !isDerivation env;
 
   derivationArg =
     (removeAttrs attrs
@@ -295,8 +343,8 @@ else let
        "__darwinAllowLocalNetworking"
        "__impureHostDeps" "__propagatedImpureHostDeps"
        "sandboxProfile" "propagatedSandboxProfile"]
-       ++ lib.optional (__structuredAttrs || envIsExportable) "env"))
-    // (lib.optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) {
+       ++ optional (__structuredAttrs || envIsExportable) "env"))
+    // (optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) {
       name =
         let
           # Indicate the host platform of the derivation if cross compiling.
@@ -304,7 +352,7 @@ else let
           # suffix. But we have some weird ones with run-time deps that are
           # just used for their side-affects. Those might as well since the
           # hash can't be the same. See #32986.
-          hostSuffix = lib.optionalString
+          hostSuffix = optionalString
             (stdenv.hostPlatform != stdenv.buildPlatform && !dontAddHostSuffix)
             "-${stdenv.hostPlatform.config}";
 
@@ -313,17 +361,17 @@ else let
           # nix and nixStatic. This should be also achieved by moving the
           # hostSuffix before the version, so we could contemplate removing
           # it again.
-          staticMarker = lib.optionalString stdenv.hostPlatform.isStatic "-static";
+          staticMarker = optionalString stdenv.hostPlatform.isStatic "-static";
         in
         lib.strings.sanitizeDerivationName (
           if attrs ? name
           then attrs.name + hostSuffix
           else
             # we cannot coerce null to a string below
-            assert lib.assertMsg (attrs ? version && attrs.version != null) "The ‘version’ attribute cannot be null.";
+            assert assertMsg (attrs ? version && attrs.version != null) "The ‘version’ attribute cannot be null.";
             "${attrs.pname}${staticMarker}${hostSuffix}-${attrs.version}"
         );
-    }) // lib.optionalAttrs __structuredAttrs { env = checkedEnv; } // {
+    }) // optionalAttrs __structuredAttrs { env = checkedEnv; } // {
       builder = attrs.realBuilder or stdenv.shell;
       args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)];
       inherit stdenv;
@@ -340,22 +388,22 @@ else let
       __ignoreNulls = true;
       inherit __structuredAttrs strictDeps;
 
-      depsBuildBuild              = lib.elemAt (lib.elemAt dependencies 0) 0;
-      nativeBuildInputs           = lib.elemAt (lib.elemAt dependencies 0) 1;
-      depsBuildTarget             = lib.elemAt (lib.elemAt dependencies 0) 2;
-      depsHostHost                = lib.elemAt (lib.elemAt dependencies 1) 0;
-      buildInputs                 = lib.elemAt (lib.elemAt dependencies 1) 1;
-      depsTargetTarget            = lib.elemAt (lib.elemAt dependencies 2) 0;
+      depsBuildBuild              = elemAt (elemAt dependencies 0) 0;
+      nativeBuildInputs           = elemAt (elemAt dependencies 0) 1;
+      depsBuildTarget             = elemAt (elemAt dependencies 0) 2;
+      depsHostHost                = elemAt (elemAt dependencies 1) 0;
+      buildInputs                 = elemAt (elemAt dependencies 1) 1;
+      depsTargetTarget            = elemAt (elemAt dependencies 2) 0;
 
-      depsBuildBuildPropagated    = lib.elemAt (lib.elemAt propagatedDependencies 0) 0;
-      propagatedNativeBuildInputs = lib.elemAt (lib.elemAt propagatedDependencies 0) 1;
-      depsBuildTargetPropagated   = lib.elemAt (lib.elemAt propagatedDependencies 0) 2;
-      depsHostHostPropagated      = lib.elemAt (lib.elemAt propagatedDependencies 1) 0;
-      propagatedBuildInputs       = lib.elemAt (lib.elemAt propagatedDependencies 1) 1;
-      depsTargetTargetPropagated  = lib.elemAt (lib.elemAt propagatedDependencies 2) 0;
+      depsBuildBuildPropagated    = elemAt (elemAt propagatedDependencies 0) 0;
+      propagatedNativeBuildInputs = elemAt (elemAt propagatedDependencies 0) 1;
+      depsBuildTargetPropagated   = elemAt (elemAt propagatedDependencies 0) 2;
+      depsHostHostPropagated      = elemAt (elemAt propagatedDependencies 1) 0;
+      propagatedBuildInputs       = elemAt (elemAt propagatedDependencies 1) 1;
+      depsTargetTargetPropagated  = elemAt (elemAt propagatedDependencies 2) 0;
 
       # This parameter is sometimes a string, sometimes null, and sometimes a list, yuck
-      configureFlags = let inherit (lib) optional elem; in
+      configureFlags =
         configureFlags
         ++ optional (elem "build"  configurePlatforms) "--build=${stdenv.buildPlatform.config}"
         ++ optional (elem "host"   configurePlatforms) "--host=${stdenv.hostPlatform.config}"
@@ -363,51 +411,77 @@ else let
 
       cmakeFlags =
         cmakeFlags
-        ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) ([
-          "-DCMAKE_SYSTEM_NAME=${lib.findFirst lib.isString "Generic" (lib.optional (!stdenv.hostPlatform.isRedox) stdenv.hostPlatform.uname.system)}"
-        ] ++ lib.optionals (stdenv.hostPlatform.uname.processor != null) [
+        ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) ([
+          "-DCMAKE_SYSTEM_NAME=${findFirst isString "Generic" (optional (!stdenv.hostPlatform.isRedox) stdenv.hostPlatform.uname.system)}"
+        ] ++ optionals (stdenv.hostPlatform.uname.processor != null) [
           "-DCMAKE_SYSTEM_PROCESSOR=${stdenv.hostPlatform.uname.processor}"
-        ] ++ lib.optionals (stdenv.hostPlatform.uname.release != null) [
+        ] ++ optionals (stdenv.hostPlatform.uname.release != null) [
           "-DCMAKE_SYSTEM_VERSION=${stdenv.hostPlatform.uname.release}"
-        ] ++ lib.optionals (stdenv.hostPlatform.isDarwin) [
+        ] ++ optionals (stdenv.hostPlatform.isDarwin) [
           "-DCMAKE_OSX_ARCHITECTURES=${stdenv.hostPlatform.darwinArch}"
-        ] ++ lib.optionals (stdenv.buildPlatform.uname.system != null) [
+        ] ++ optionals (stdenv.buildPlatform.uname.system != null) [
           "-DCMAKE_HOST_SYSTEM_NAME=${stdenv.buildPlatform.uname.system}"
-        ] ++ lib.optionals (stdenv.buildPlatform.uname.processor != null) [
+        ] ++ optionals (stdenv.buildPlatform.uname.processor != null) [
           "-DCMAKE_HOST_SYSTEM_PROCESSOR=${stdenv.buildPlatform.uname.processor}"
-        ] ++ lib.optionals (stdenv.buildPlatform.uname.release != null) [
+        ] ++ optionals (stdenv.buildPlatform.uname.release != null) [
           "-DCMAKE_HOST_SYSTEM_VERSION=${stdenv.buildPlatform.uname.release}"
-        ] ++ lib.optionals (stdenv.buildPlatform.canExecute stdenv.hostPlatform) [
+        ] ++ optionals (stdenv.buildPlatform.canExecute stdenv.hostPlatform) [
           "-DCMAKE_CROSSCOMPILING_EMULATOR=env"
         ]);
 
+      mesonFlags =
+        let
+          # See https://mesonbuild.com/Reference-tables.html#cpu-families
+          cpuFamily = platform: with platform;
+            /**/ if isAarch32 then "arm"
+            else if isx86_32  then "x86"
+            else platform.uname.processor;
+
+          crossFile = builtins.toFile "cross-file.conf" ''
+            [properties]
+            bindgen_clang_arguments = ['-target', '${stdenv.targetPlatform.config}']
+            needs_exe_wrapper = ${boolToString (!stdenv.buildPlatform.canExecute stdenv.hostPlatform)}
+
+            [host_machine]
+            system = '${stdenv.targetPlatform.parsed.kernel.name}'
+            cpu_family = '${cpuFamily stdenv.targetPlatform}'
+            cpu = '${stdenv.targetPlatform.parsed.cpu.name}'
+            endian = ${if stdenv.targetPlatform.isLittleEndian then "'little'" else "'big'"}
+
+            [binaries]
+            llvm-config = 'llvm-config-native'
+            rust = ['rustc', '--target', '${stdenv.targetPlatform.rust.rustcTargetSpec}']
+          '';
+          crossFlags = optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ "--cross-file=${crossFile}" ];
+        in crossFlags ++ mesonFlags;
+
       inherit patches;
 
       inherit doCheck doInstallCheck;
 
       inherit outputs;
-    } // lib.optionalAttrs (__contentAddressed) {
+    } // optionalAttrs (__contentAddressed) {
       inherit __contentAddressed;
       # Provide default values for outputHashMode and outputHashAlgo because
       # most people won't care about these anyways
       outputHashAlgo = attrs.outputHashAlgo or "sha256";
       outputHashMode = attrs.outputHashMode or "recursive";
-    } // lib.optionalAttrs (enableParallelBuilding) {
+    } // optionalAttrs (enableParallelBuilding) {
       inherit enableParallelBuilding;
       enableParallelChecking = attrs.enableParallelChecking or true;
       enableParallelInstalling = attrs.enableParallelInstalling or true;
-    } // lib.optionalAttrs (hardeningDisable != [] || hardeningEnable != [] || stdenv.hostPlatform.isMusl) {
+    } // optionalAttrs (hardeningDisable != [] || hardeningEnable != [] || stdenv.hostPlatform.isMusl) {
       NIX_HARDENING_ENABLE = enabledHardeningOptions;
-    } // lib.optionalAttrs (stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform ? gcc.arch) {
+    } // optionalAttrs (stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform ? gcc.arch) {
       requiredSystemFeatures = attrs.requiredSystemFeatures or [] ++ [ "gccarch-${stdenv.hostPlatform.gcc.arch}" ];
-    } // lib.optionalAttrs (stdenv.buildPlatform.isDarwin) {
+    } // optionalAttrs (stdenv.buildPlatform.isDarwin) {
       inherit __darwinAllowLocalNetworking;
-      # TODO: remove lib.unique once nix has a list canonicalization primitive
+      # TODO: remove `unique` once nix has a list canonicalization primitive
       __sandboxProfile =
       let profiles = [ stdenv.extraSandboxProfile ] ++ computedSandboxProfile ++ computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile sandboxProfile ];
-          final = lib.concatStringsSep "\n" (lib.filter (x: x != "") (lib.unique profiles));
+          final = concatStringsSep "\n" (filter (x: x != "") (unique profiles));
       in final;
-      __propagatedSandboxProfile = lib.unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]);
+      __propagatedSandboxProfile = unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]);
       __impureHostDeps = computedImpureHostDeps ++ computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ++ __impureHostDeps ++ stdenv.__extraImpureHostDeps ++ [
         "/dev/zero"
         "/dev/random"
@@ -434,21 +508,21 @@ else let
     # to be built eventually, we would still like to get the error early and without
     # having to wait while nix builds a derivation that might not be used.
     # See also https://github.com/NixOS/nix/issues/4629
-    lib.optionalAttrs (attrs ? disallowedReferences) {
+    optionalAttrs (attrs ? disallowedReferences) {
       disallowedReferences =
         map unsafeDerivationToUntrackedOutpath attrs.disallowedReferences;
     } //
-    lib.optionalAttrs (attrs ? disallowedRequisites) {
+    optionalAttrs (attrs ? disallowedRequisites) {
       disallowedRequisites =
         map unsafeDerivationToUntrackedOutpath attrs.disallowedRequisites;
     } //
-    lib.optionalAttrs (attrs ? allowedReferences) {
+    optionalAttrs (attrs ? allowedReferences) {
       allowedReferences =
-        lib.mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedReferences;
+        mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedReferences;
     } //
-    lib.optionalAttrs (attrs ? allowedRequisites) {
+    optionalAttrs (attrs ? allowedRequisites) {
       allowedRequisites =
-        lib.mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedRequisites;
+        mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedRequisites;
     };
 
   meta = checkMeta.commonMeta { inherit validity attrs pos references; };
@@ -456,20 +530,20 @@ else let
 
   checkedEnv =
     let
-      overlappingNames = lib.attrNames (builtins.intersectAttrs env derivationArg);
+      overlappingNames = attrNames (builtins.intersectAttrs env derivationArg);
     in
-    assert lib.assertMsg envIsExportable
+    assert assertMsg envIsExportable
       "When using structured attributes, `env` must be an attribute set of environment variables.";
-    assert lib.assertMsg (overlappingNames == [ ])
-      "The ‘env’ attribute set cannot contain any attributes passed to derivation. The following attributes are overlapping: ${lib.concatStringsSep ", " overlappingNames}";
-    lib.mapAttrs
-      (n: v: assert lib.assertMsg (lib.isString v || lib.isBool v || lib.isInt v || lib.isDerivation v)
+    assert assertMsg (overlappingNames == [ ])
+      "The ‘env’ attribute set cannot contain any attributes passed to derivation. The following attributes are overlapping: ${concatStringsSep ", " overlappingNames}";
+    mapAttrs
+      (n: v: assert assertMsg (isString v || isBool v || isInt v || isDerivation v)
         "The ‘env’ attribute set can only contain derivation, string, boolean or integer attributes. The ‘${n}’ attribute is of type ${builtins.typeOf v}."; v)
       env;
 
 in
 
-lib.extendDerivation
+extendDerivation
   validity.handled
   ({
      # A derivation that always builds successfully and whose runtime
@@ -518,7 +592,7 @@ lib.extendDerivation
    # should be made available to Nix expressions using the
    # derivation (e.g., in assertions).
    passthru)
-  (derivation (derivationArg // lib.optionalAttrs envIsExportable checkedEnv));
+  (derivation (derivationArg // optionalAttrs envIsExportable checkedEnv));
 
 in
   fnOrAttrs:
diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh
index ad9857fc9d6..37c10fb2957 100644
--- a/pkgs/stdenv/generic/setup.sh
+++ b/pkgs/stdenv/generic/setup.sh
@@ -16,29 +16,15 @@ if (( "${NIX_DEBUG:-0}" >= 6 )); then
     set -x
 fi
 
-if [ -f .attrs.sh ]; then
+if [ -f .attrs.sh ] || [[ -n "${NIX_ATTRS_JSON_FILE:-}" ]]; then
     __structuredAttrs=1
     echo "structuredAttrs is enabled"
-else
-    __structuredAttrs=
-fi
 
-if [ -n "$__structuredAttrs" ]; then
     for outputName in "${!outputs[@]}"; do
         # ex: out=/nix/store/...
         export "$outputName=${outputs[$outputName]}"
     done
 
-    # Before Nix 2.4, $NIX_ATTRS_*_FILE was named differently:
-    # https://github.com/NixOS/nix/commit/27ce722
-    if [[ -n "${ATTRS_JSON_FILE:-}" ]]; then
-        export NIX_ATTRS_JSON_FILE="$ATTRS_JSON_FILE"
-    fi
-
-    if [[ -n "${ATTRS_SH_FILE:-}" ]]; then
-        export NIX_ATTRS_SH_FILE="$ATTRS_SH_FILE"
-    fi
-
     # $NIX_ATTRS_JSON_FILE pointed to the wrong location in sandbox
     # https://github.com/NixOS/nix/issues/6736; please keep around until the
     # fix reaches *every patch version* that's >= lib/minver.nix
@@ -49,6 +35,7 @@ if [ -n "$__structuredAttrs" ]; then
         export NIX_ATTRS_SH_FILE="$NIX_BUILD_TOP/.attrs.sh"
     fi
 else
+    __structuredAttrs=
     : "${outputs:=out}"
 fi
 
@@ -1539,6 +1526,44 @@ showPhaseFooter() {
 }
 
 
+runPhase() {
+    local curPhase="$*"
+    if [[ "$curPhase" = unpackPhase && -n "${dontUnpack:-}" ]]; then return; fi
+    if [[ "$curPhase" = patchPhase && -n "${dontPatch:-}" ]]; then return; fi
+    if [[ "$curPhase" = configurePhase && -n "${dontConfigure:-}" ]]; then return; fi
+    if [[ "$curPhase" = buildPhase && -n "${dontBuild:-}" ]]; then return; fi
+    if [[ "$curPhase" = checkPhase && -z "${doCheck:-}" ]]; then return; fi
+    if [[ "$curPhase" = installPhase && -n "${dontInstall:-}" ]]; then return; fi
+    if [[ "$curPhase" = fixupPhase && -n "${dontFixup:-}" ]]; then return; fi
+    if [[ "$curPhase" = installCheckPhase && -z "${doInstallCheck:-}" ]]; then return; fi
+    if [[ "$curPhase" = distPhase && -z "${doDist:-}" ]]; then return; fi
+
+    if [[ -n $NIX_LOG_FD ]]; then
+        echo "@nix { \"action\": \"setPhase\", \"phase\": \"$curPhase\" }" >&"$NIX_LOG_FD"
+    fi
+
+    showPhaseHeader "$curPhase"
+    dumpVars
+
+    local startTime=$(date +"%s")
+
+    # Evaluate the variable named $curPhase if it exists, otherwise the
+    # function named $curPhase.
+    eval "${!curPhase:-$curPhase}"
+
+    local endTime=$(date +"%s")
+
+    showPhaseFooter "$curPhase" "$startTime" "$endTime"
+
+    if [ "$curPhase" = unpackPhase ]; then
+        # make sure we can cd into the directory
+        [ -n "${sourceRoot:-}" ] && chmod +x "${sourceRoot}"
+
+        cd "${sourceRoot:-.}"
+    fi
+}
+
+
 genericBuild() {
     # variable used by our gzip wrapper to add -n.
     # gzip is in common-path.nix and is added to nix-shell but we only want to change its behaviour in nix builds. do not move to a setupHook in gzip.
@@ -1565,39 +1590,7 @@ genericBuild() {
     # phase name is space-free, which it must be because it's the name
     # of either a shell variable or a shell function.
     for curPhase in ${phases[*]}; do
-        if [[ "$curPhase" = unpackPhase && -n "${dontUnpack:-}" ]]; then continue; fi
-        if [[ "$curPhase" = patchPhase && -n "${dontPatch:-}" ]]; then continue; fi
-        if [[ "$curPhase" = configurePhase && -n "${dontConfigure:-}" ]]; then continue; fi
-        if [[ "$curPhase" = buildPhase && -n "${dontBuild:-}" ]]; then continue; fi
-        if [[ "$curPhase" = checkPhase && -z "${doCheck:-}" ]]; then continue; fi
-        if [[ "$curPhase" = installPhase && -n "${dontInstall:-}" ]]; then continue; fi
-        if [[ "$curPhase" = fixupPhase && -n "${dontFixup:-}" ]]; then continue; fi
-        if [[ "$curPhase" = installCheckPhase && -z "${doInstallCheck:-}" ]]; then continue; fi
-        if [[ "$curPhase" = distPhase && -z "${doDist:-}" ]]; then continue; fi
-
-        if [[ -n $NIX_LOG_FD ]]; then
-            echo "@nix { \"action\": \"setPhase\", \"phase\": \"$curPhase\" }" >&"$NIX_LOG_FD"
-        fi
-
-        showPhaseHeader "$curPhase"
-        dumpVars
-
-        local startTime=$(date +"%s")
-
-        # Evaluate the variable named $curPhase if it exists, otherwise the
-        # function named $curPhase.
-        eval "${!curPhase:-$curPhase}"
-
-        local endTime=$(date +"%s")
-
-        showPhaseFooter "$curPhase" "$startTime" "$endTime"
-
-        if [ "$curPhase" = unpackPhase ]; then
-            # make sure we can cd into the directory
-            [ -n "${sourceRoot:-}" ] && chmod +x "${sourceRoot}"
-
-            cd "${sourceRoot:-.}"
-        fi
+        runPhase "$curPhase"
     done
 }