about summary refs log tree commit diff
path: root/pkgs/stdenv/generic
diff options
context:
space:
mode:
authorVladimír Čunát <vcunat@gmail.com>2015-04-18 11:00:58 +0200
committerVladimír Čunát <vcunat@gmail.com>2015-04-18 11:22:20 +0200
commitbf414c9d4f892fd4e392a5f42016b57e84402a8b (patch)
tree08c000d609ed8e608ca542fa78360e4217f3fc36 /pkgs/stdenv/generic
parent29901451700a7382f3f9d5a0a23cd55b187e5585 (diff)
parent9de9669496a05f64ea436c01f9b66c057cd74f90 (diff)
downloadnixlib-bf414c9d4f892fd4e392a5f42016b57e84402a8b.tar
nixlib-bf414c9d4f892fd4e392a5f42016b57e84402a8b.tar.gz
nixlib-bf414c9d4f892fd4e392a5f42016b57e84402a8b.tar.bz2
nixlib-bf414c9d4f892fd4e392a5f42016b57e84402a8b.tar.lz
nixlib-bf414c9d4f892fd4e392a5f42016b57e84402a8b.tar.xz
nixlib-bf414c9d4f892fd4e392a5f42016b57e84402a8b.tar.zst
nixlib-bf414c9d4f892fd4e392a5f42016b57e84402a8b.zip
Merge 'staging' into closure-size
- there were many easy merge conflicts
- cc-wrapper needed nontrivial changes

Many other problems might've been created by interaction of the branches,
but stdenv and a few other packages build fine now.
Diffstat (limited to 'pkgs/stdenv/generic')
-rw-r--r--pkgs/stdenv/generic/builder.sh1
-rw-r--r--pkgs/stdenv/generic/default.nix183
-rw-r--r--pkgs/stdenv/generic/setup.sh29
3 files changed, 131 insertions, 82 deletions
diff --git a/pkgs/stdenv/generic/builder.sh b/pkgs/stdenv/generic/builder.sh
index 4fa722a73dd2..a46c46c2db50 100644
--- a/pkgs/stdenv/generic/builder.sh
+++ b/pkgs/stdenv/generic/builder.sh
@@ -8,6 +8,7 @@ mkdir $out
 
 echo "export SHELL=$shell" > $out/setup
 echo "initialPath=\"$initialPath\"" >> $out/setup
+echo "defaultNativeBuildInputs=\"$defaultNativeBuildInputs\"" >> $out/setup
 echo "$preHook" >> $out/setup
 cat "$setup" >> $out/setup
 
diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix
index a27485e144d7..e7a828355e7d 100644
--- a/pkgs/stdenv/generic/default.nix
+++ b/pkgs/stdenv/generic/default.nix
@@ -1,7 +1,7 @@
 let lib = import ../../../lib; in lib.makeOverridable (
 
-{ system, name ? "stdenv", preHook ? "", initialPath, gcc, shell
-, extraAttrs ? {}, overrides ? (pkgs: {}), config
+{ system, name ? "stdenv", preHook ? "", initialPath, cc, shell
+, allowedRequisites ? null, extraAttrs ? {}, overrides ? (pkgs: {}), config
 
 , # The `fetchurl' to use for downloading curl and its dependencies
   # (see all-packages.nix).
@@ -16,6 +16,41 @@ let
 
   allowUnfree = config.allowUnfree or false || builtins.getEnv "NIXPKGS_ALLOW_UNFREE" == "1";
 
+  whitelist = config.whitelistedLicenses or [];
+  blacklist = config.blacklistedLicenses or [];
+
+  onlyLicenses = list:
+    lib.lists.all (license:
+      let l = lib.licenses.${license.shortName or "BROKEN"} or false; in
+      if license == l then true else
+        throw ''‘${builtins.toJSON license}’ is not an attribute of lib.licenses''
+    ) list;
+
+  mutuallyExclusive = a: b:
+    (builtins.length a) == 0 ||
+    (!(builtins.elem (builtins.head a) b) &&
+     mutuallyExclusive (builtins.tail a) b);
+
+  areLicenseListsValid =
+    if mutuallyExclusive whitelist blacklist then
+      assert onlyLicenses whitelist; assert onlyLicenses blacklist; true
+    else
+      throw "whitelistedLicenses and blacklistedLicenses are not mutually exclusive.";
+
+  hasLicense = attrs:
+    builtins.hasAttr "meta" attrs && builtins.hasAttr "license" attrs.meta;
+
+  hasWhitelistedLicense = assert areLicenseListsValid; attrs:
+    hasLicense attrs && builtins.elem attrs.meta.license whitelist;
+
+  hasBlacklistedLicense = assert areLicenseListsValid; attrs:
+    hasLicense attrs && builtins.elem attrs.meta.license blacklist;
+
+  allowBroken = config.allowBroken or false || builtins.getEnv "NIXPKGS_ALLOW_BROKEN" == "1";
+
+  isUnfree = licenses: lib.lists.any (l:
+    !l.free or true || l == "unfree" || l == "unfree-redistributable") licenses;
+
   # Alow granular checks to allow only some unfree packages
   # Example:
   # {pkgs, ...}:
@@ -25,64 +60,79 @@ let
   # }
   allowUnfreePredicate = config.allowUnfreePredicate or (x: false);
 
-  allowBroken = config.allowBroken or false || builtins.getEnv "NIXPKGS_ALLOW_BROKEN" == "1";
-
-  forceEvalHelp = unfreeOrBroken:
-    assert (unfreeOrBroken == "Unfree" || unfreeOrBroken == "Broken");
-    ''
-      You can set
-        { nixpkgs.config.allow${unfreeOrBroken} = true; }
-      in configuration.nix to override this. If you use Nix standalone, you can add
-        { allow${unfreeOrBroken} = true; }
-      to ~/.nixpkgs/config.nix.
-    '';
+  # Check whether unfree packages are allowed and if not, whether the
+  # package has an unfree license and is not explicitely allowed by the
+  # `allowUNfreePredicate` function.
+  hasDeniedUnfreeLicense = attrs:
+    !allowUnfree &&
+    hasLicense attrs &&
+    isUnfree (lib.lists.toList attrs.meta.license) &&
+    !allowUnfreePredicate attrs;
 
-  unsafeGetAttrPos = builtins.unsafeGetAttrPos or (n: as: null);
-
-  extraBuildInputs' = extraBuildInputs ++
+  defaultNativeBuildInputs = extraBuildInputs ++
     [ ../../build-support/setup-hooks/move-docs.sh
       ../../build-support/setup-hooks/compress-man-pages.sh
       ../../build-support/setup-hooks/strip.sh
       ../../build-support/setup-hooks/patch-shebangs.sh
       ../../build-support/setup-hooks/multiple-outputs.sh
-      gcc
+      ../../build-support/setup-hooks/move-sbin.sh
+      ../../build-support/setup-hooks/move-lib64.sh
+      cc
     ];
 
   # Add a utility function to produce derivations that use this
   # stdenv and its shell.
-  mkDerivation = attrs:
+  mkDerivation =
+    { buildInputs ? []
+    , nativeBuildInputs ? []
+    , propagatedBuildInputs ? []
+    , propagatedNativeBuildInputs ? []
+    , crossConfig ? null
+    , meta ? {}
+    , passthru ? {}
+    , pos ? null # position used in error messages and for meta.position
+    , ... } @ attrs:
     let
-      pos =
-        if attrs.meta.description or null != null then
-          unsafeGetAttrPos "description" attrs.meta
+      pos' =
+        if pos != null then
+          pos
+        else if attrs.meta.description or null != null then
+          builtins.unsafeGetAttrPos "description" attrs.meta
         else
-          unsafeGetAttrPos "name" attrs;
-      pos' = if pos != null then "‘" + pos.file + ":" + toString pos.line + "’" else "«unknown-file»";
+          builtins.unsafeGetAttrPos "name" attrs;
+      pos'' = if pos' != null then "‘" + pos'.file + ":" + toString pos'.line + "’" else "«unknown-file»";
+
+      throwEvalHelp = unfreeOrBroken: whatIsWrong:
+        assert builtins.elem unfreeOrBroken ["Unfree" "Broken" "blacklisted"];
+
+        throw ("Package ‘${attrs.name or "«name-missing»"}’ in ${pos''} ${whatIsWrong}, refusing to evaluate."
+        + (lib.strings.optionalString (unfreeOrBroken != "blacklisted") ''
+
+          For `nixos-rebuild` you can set
+            { nixpkgs.config.allow${unfreeOrBroken} = true; }
+          in configuration.nix to override this.
+          For `nix-env` you can add
+            { allow${unfreeOrBroken} = true; }
+          to ~/.nixpkgs/config.nix.
+        ''));
+
+      licenseAllowed = attrs:
+        if hasDeniedUnfreeLicense attrs && !(hasWhitelistedLicense attrs) then
+          throwEvalHelp "Unfree" "has an unfree license ‘${builtins.toJSON attrs.meta.license}’ which is not whitelisted"
+        else if hasBlacklistedLicense attrs then
+          throwEvalHelp "blacklisted" "has the ‘${builtins.toJSON attrs.meta.license}’ license which is blacklisted"
+        else if !allowBroken && attrs.meta.broken or false then
+          throwEvalHelp "Broken" "is marked as broken"
+        else if !allowBroken && attrs.meta.platforms or null != null && !lib.lists.elem result.system attrs.meta.platforms then
+          throwEvalHelp "Broken" "is not supported on ‘${result.system}’"
+        else true;
+
     in
-    if !allowUnfree
-       && (let l = lib.lists.toList attrs.meta.license or []; in lib.lists.elem "unfree" l || lib.lists.elem "unfree-redistributable" l)
-       && !allowUnfreePredicate attrs then
-      throw ''
-            Package ‘${attrs.name}’ in ${pos'} has an unfree license, refusing to evaluate.
-            ${forceEvalHelp "Unfree"}''
-    else if !allowBroken && attrs.meta.broken or false then
-          throw ''
-            Package ‘${attrs.name}’ in ${pos'} is marked as broken, refusing to evaluate.
-            ${forceEvalHelp "Broken"}''
-    else if !allowBroken && attrs.meta.platforms or null != null && !lib.lists.elem result.system attrs.meta.platforms then
-          throw ''
-            Package ‘${attrs.name}’ in ${pos'} is not supported on ‘${result.system}’, refusing to evaluate.
-            ${forceEvalHelp "Broken"}''
-    else
+      assert licenseAllowed attrs;
+
       lib.addPassthru (derivation (
-        (removeAttrs attrs ["meta" "passthru" "crossAttrs"])
-        // (let
-          buildInputs = attrs.buildInputs or [];
-          nativeBuildInputs = attrs.nativeBuildInputs or [];
-          propagatedBuildInputs = attrs.propagatedBuildInputs or [];
-          propagatedNativeBuildInputs = attrs.propagatedNativeBuildInputs or [];
-          crossConfig = attrs.crossConfig or null;
-        in
+        (removeAttrs attrs ["meta" "passthru" "crossAttrs" "pos"])
+        //
         {
           builder = attrs.realBuilder or shell;
           args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)];
@@ -92,13 +142,13 @@ let
           __ignoreNulls = true;
 
           # Inputs built by the cross compiler.
-          buildInputs = lib.optionals (crossConfig != null) (buildInputs ++ extraBuildInputs');
-          propagatedBuildInputs = lib.optionals (crossConfig != null) propagatedBuildInputs;
+          buildInputs = if crossConfig != null then buildInputs else [];
+          propagatedBuildInputs = if crossConfig != null then propagatedBuildInputs else [];
           # Inputs built by the usual native compiler.
-          nativeBuildInputs = nativeBuildInputs ++ lib.optionals (crossConfig == null) (buildInputs ++ extraBuildInputs');
+          nativeBuildInputs = nativeBuildInputs ++ (if crossConfig == null then buildInputs else []);
           propagatedNativeBuildInputs = propagatedNativeBuildInputs ++
-            lib.optionals (crossConfig == null) propagatedBuildInputs;
-      }))) (
+            (if crossConfig == null then propagatedBuildInputs else []);
+        })) (
       {
         # The meta attribute is passed in the resulting attribute set,
         # but it's not part of the actual derivation, i.e., it's not
@@ -106,20 +156,21 @@ let
         # include it in the result, it *is* available to nix-env for
         # queries.  We also a meta.position attribute here to
         # identify the source location of the package.
-        meta = attrs.meta or {} // (if pos != null then {
-          position = pos.file + ":" + (toString pos.line);
+        meta = meta // (if pos' != null then {
+          position = pos'.file + ":" + toString pos'.line;
         } else {});
-        passthru = attrs.passthru or {};
+        inherit passthru;
       } //
       # Pass through extra attributes that are not inputs, but
       # should be made available to Nix expressions using the
       # derivation (e.g., in assertions).
-      (attrs.passthru or {}));
+      passthru);
 
   # The stdenv that we are producing.
   result =
-
-    derivation {
+    derivation (
+    (if isNull allowedRequisites then {} else { allowedRequisites = allowedRequisites ++ defaultNativeBuildInputs; }) //
+    {
       inherit system name;
 
       builder = shell;
@@ -128,11 +179,8 @@ let
 
       setup = setupScript;
 
-      inherit preHook initialPath shell;
-
-      propagatedUserEnvPkgs = [gcc] ++
-        lib.filter lib.isDerivation initialPath;
-    }
+      inherit preHook initialPath shell defaultNativeBuildInputs;
+    })
 
     // rec {
 
@@ -156,13 +204,9 @@ let
       isCygwin = system == "i686-cygwin"
               || system == "x86_64-cygwin";
       isFreeBSD = system == "i686-freebsd"
-              || system == "x86_64-freebsd";
+               || system == "x86_64-freebsd";
       isOpenBSD = system == "i686-openbsd"
-              || system == "x86_64-openbsd";
-      isBSD = system == "i686-freebsd"
-           || system == "x86_64-freebsd"
-           || system == "i686-openbsd"
-           || system == "x86_64-openbsd";
+               || system == "x86_64-openbsd";
       isi686 = system == "i686-linux"
             || system == "i686-gnu"
             || system == "i686-freebsd"
@@ -183,6 +227,7 @@ let
       isArm = system == "armv5tel-linux"
            || system == "armv6l-linux"
            || system == "armv7l-linux";
+      isBigEndian = system == "powerpc-linux";
 
       # Whether we should run paxctl to pax-mark binaries.
       needsPax = isLinux;
@@ -197,7 +242,7 @@ let
 
       inherit overrides;
 
-      inherit gcc;
+      inherit cc;
     }
 
     # Propagate any extra attributes.  For instance, we use this to
diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh
index 74dad2c895b0..b5d31e09153a 100644
--- a/pkgs/stdenv/generic/setup.sh
+++ b/pkgs/stdenv/generic/setup.sh
@@ -1,4 +1,5 @@
 set -e
+set -o pipefail
 
 : ${outputs:=out}
 
@@ -101,7 +102,7 @@ exitHandler() {
         if [ -n "$succeedOnFailure" ]; then
             echo "build failed with exit code $exitCode (ignored)"
             mkdir -p "$out/nix-support"
-            echo -n $exitCode > "$out/nix-support/failed"
+            printf "%s" $exitCode > "$out/nix-support/failed"
             exit 0
         fi
 
@@ -184,11 +185,13 @@ fi
 
 # Check that the pre-hook initialised SHELL.
 if [ -z "$SHELL" ]; then echo "SHELL not set"; exit 1; fi
+BASH="$SHELL"
+export CONFIG_SHELL="$SHELL"
 
 
 # Execute the pre-hook.
-export CONFIG_SHELL="$SHELL"
 if [ -z "$shell" ]; then export shell=$SHELL; fi
+runHook preHook
 
 
 # Allow the caller to augment buildInputs (it's not always possible to
@@ -227,12 +230,12 @@ findInputs() {
 }
 
 crossPkgs=""
-for i in $buildInputs $propagatedBuildInputs; do
+for i in $buildInputs $defaultBuildInputs $propagatedBuildInputs; do
     findInputs $i crossPkgs propagated-build-inputs
 done
 
 nativePkgs=""
-for i in $nativeBuildInputs $propagatedNativeBuildInputs; do
+for i in $nativeBuildInputs $defaultNativeBuildInputs $propagatedNativeBuildInputs; do
     findInputs $i nativePkgs propagated-native-build-inputs
 done
 
@@ -339,7 +342,7 @@ substitute() {
     local n p pattern replacement varName content
 
     # a slightly hacky way to keep newline at the end
-    content="$(cat $input; echo -n X)"
+    content="$(cat "$input"; printf "%s" X)"
     content="${content%X}"
 
     for ((n = 2; n < ${#params[*]}; n += 1)); do
@@ -367,10 +370,8 @@ substitute() {
         content="${content//"$pattern"/$replacement}"
     done
 
-    # !!! This doesn't work properly if $content is "-n".
-    echo -n "$content" > "$output".tmp
-    if [ -x "$output" ]; then chmod +x "$output".tmp; fi
-    mv -f "$output".tmp "$output"
+    if [ -e "$output" ]; then chmod +w "$output"; fi
+    printf "%s" "$content" > "$output"
 }
 
 
@@ -386,7 +387,7 @@ substituteAll() {
     local output="$2"
 
     # Select all environment variables that start with a lowercase character.
-    for envVar in $(env | sed "s/^[^a-z].*//" | sed "s/^\([^=]*\)=.*/\1/"); do
+    for envVar in $(env | sed -e $'s/^\([a-z][^=]*\)=.*/\\1/; t \n d'); do
         if [ "$NIX_DEBUG" = "1" ]; then
             echo "$envVar -> ${!envVar}"
         fi
@@ -463,7 +464,9 @@ _defaultUnpack() {
     if [ -d "$fn" ]; then
 
         stripHash "$fn"
-        cp -prd --no-preserve=timestamps "$fn" $strippedName
+        # We can't preserve hardlinks because they may have been introduced by
+        # store optimization, which might break things in the build
+        cp -pr --reflink=auto --no-preserve=timestamps "$fn" $strippedName
 
     else
 
@@ -570,7 +573,7 @@ patchPhase() {
     for i in $patches; do
         header "applying patch $i" 3
         local uncompress=cat
-        case $i in
+        case "$i" in
             *.gz)
                 uncompress="gzip -d"
                 ;;
@@ -585,7 +588,7 @@ patchPhase() {
                 ;;
         esac
         # "2>&1" is a hack to make patch fail if the decompressor fails (nonexistent patch, etc.)
-        $uncompress < $i 2>&1 | patch ${patchFlags:--p1}
+        $uncompress < "$i" 2>&1 | patch ${patchFlags:--p1}
         stopNest
     done