diff options
author | Vladimír Čunát <vcunat@gmail.com> | 2017-07-09 18:07:00 +0200 |
---|---|---|
committer | Vladimír Čunát <vcunat@gmail.com> | 2017-07-09 18:07:52 +0200 |
commit | bfb7ef86f3f2417b6866c704b7423c33bc33286c (patch) | |
tree | c466dc1a8c5e41bc2be1b349ac93ed4fd5a5a0d2 /pkgs/stdenv | |
parent | d10c3cc5eedf58e80e270d7c912cf68ea1a822e4 (diff) | |
parent | 466e7e23c6f71ebed7050802d377102002fc2a0d (diff) | |
download | nixlib-bfb7ef86f3f2417b6866c704b7423c33bc33286c.tar nixlib-bfb7ef86f3f2417b6866c704b7423c33bc33286c.tar.gz nixlib-bfb7ef86f3f2417b6866c704b7423c33bc33286c.tar.bz2 nixlib-bfb7ef86f3f2417b6866c704b7423c33bc33286c.tar.lz nixlib-bfb7ef86f3f2417b6866c704b7423c33bc33286c.tar.xz nixlib-bfb7ef86f3f2417b6866c704b7423c33bc33286c.tar.zst nixlib-bfb7ef86f3f2417b6866c704b7423c33bc33286c.zip |
Merge branch 'master' into staging
Mass rebuilds incoming. The mass-rebuild situation got really messy this weekend.
Diffstat (limited to 'pkgs/stdenv')
-rw-r--r-- | pkgs/stdenv/adapters.nix | 8 | ||||
-rw-r--r-- | pkgs/stdenv/cross/default.nix | 11 | ||||
-rw-r--r-- | pkgs/stdenv/custom/default.nix | 8 | ||||
-rw-r--r-- | pkgs/stdenv/darwin/default.nix | 20 | ||||
-rw-r--r-- | pkgs/stdenv/freebsd/default.nix | 14 | ||||
-rw-r--r-- | pkgs/stdenv/generic/check-meta.nix | 197 | ||||
-rw-r--r-- | pkgs/stdenv/generic/default.nix | 385 | ||||
-rw-r--r-- | pkgs/stdenv/generic/make-derivation.nix | 150 | ||||
-rw-r--r-- | pkgs/stdenv/linux/default.nix | 20 | ||||
-rw-r--r-- | pkgs/stdenv/native/default.nix | 9 | ||||
-rw-r--r-- | pkgs/stdenv/nix/default.nix | 7 |
11 files changed, 426 insertions, 403 deletions
diff --git a/pkgs/stdenv/adapters.nix b/pkgs/stdenv/adapters.nix index 7515a72fcfdf..5848ee87b1b0 100644 --- a/pkgs/stdenv/adapters.nix +++ b/pkgs/stdenv/adapters.nix @@ -61,11 +61,9 @@ rec { , buildPlatform, hostPlatform, targetPlatform } @ overrideArgs: let stdenv = overrideArgs.stdenv.override { - # TODO(@Ericson2314): Cannot do this for now because then Nix thinks the - # resulting derivation should be built on the host platform. - #hostPlatform = buildPlatform; - #targetPlatform = hostPlatform; - inherit cc; + inherit + buildPlatform hostPlatform targetPlatform + cc; allowedRequisites = null; diff --git a/pkgs/stdenv/cross/default.nix b/pkgs/stdenv/cross/default.nix index 125c4300975a..c83714d01f2c 100644 --- a/pkgs/stdenv/cross/default.nix +++ b/pkgs/stdenv/cross/default.nix @@ -14,21 +14,18 @@ in bootStages ++ [ # Build Packages (vanillaPackages: { - buildPlatform = localSystem; - hostPlatform = localSystem; - targetPlatform = crossSystem; inherit config overlays; selfBuild = false; + stdenv = + assert vanillaPackages.hostPlatform == localSystem; + assert vanillaPackages.targetPlatform == localSystem; + vanillaPackages.stdenv.override { targetPlatform = crossSystem; }; # It's OK to change the built-time dependencies allowCustomOverrides = true; - inherit (vanillaPackages) stdenv; }) # Run Packages (buildPackages: { - buildPlatform = localSystem; - hostPlatform = crossSystem; - targetPlatform = crossSystem; inherit config overlays; selfBuild = false; stdenv = buildPackages.makeStdenvCross { diff --git a/pkgs/stdenv/custom/default.nix b/pkgs/stdenv/custom/default.nix index d5dc977b37a7..b6ea8685f8e6 100644 --- a/pkgs/stdenv/custom/default.nix +++ b/pkgs/stdenv/custom/default.nix @@ -15,11 +15,11 @@ in bootStages ++ [ # Additional stage, built using custom stdenv (vanillaPackages: { - buildPlatform = localSystem; - hostPlatform = localSystem; - targetPlatform = localSystem; inherit config overlays; - stdenv = config.replaceStdenv { pkgs = vanillaPackages; }; + stdenv = + assert vanillaPackages.hostPlatform == localSystem; + assert vanillaPackages.targetPlatform == localSystem; + config.replaceStdenv { pkgs = vanillaPackages; }; }) ] diff --git a/pkgs/stdenv/darwin/default.nix b/pkgs/stdenv/darwin/default.nix index 1c0b42886ca3..f6d9bcac5104 100644 --- a/pkgs/stdenv/darwin/default.nix +++ b/pkgs/stdenv/darwin/default.nix @@ -68,6 +68,10 @@ in rec { name = "stdenv-darwin-boot-${toString step}"; + buildPlatform = localSystem; + hostPlatform = localSystem; + targetPlatform = localSystem; + cc = if isNull last then "/dev/null" else import ../../build-support/cc-wrapper { inherit shell; inherit (last) stdenv; @@ -96,9 +100,6 @@ in rec { ''; initialPath = [ bootstrapTools ]; - hostPlatform = localSystem; - targetPlatform = localSystem; - fetchurlBoot = import ../../build-support/fetchurl { stdenv = stage0.stdenv; curl = bootstrapTools; @@ -113,9 +114,6 @@ in rec { }; in { - buildPlatform = localSystem; - hostPlatform = localSystem; - targetPlatform = localSystem; inherit config overlays; stdenv = thisStdenv; }; @@ -285,6 +283,10 @@ in rec { name = "stdenv-darwin"; + buildPlatform = localSystem; + hostPlatform = localSystem; + targetPlatform = localSystem; + preHook = commonPreHook + '' export PATH_LOCALE=${pkgs.darwin.locale}/share/locale ''; @@ -292,9 +294,6 @@ in rec { stdenvSandboxProfile = binShClosure + libSystemProfile; extraSandboxProfile = binShClosure + libSystemProfile; - hostPlatform = localSystem; - targetPlatform = localSystem; - initialPath = import ../common-path.nix { inherit pkgs; }; shell = "${pkgs.bash}/bin/bash"; @@ -348,9 +347,6 @@ in rec { stage3 stage4 (prevStage: { - buildPlatform = localSystem; - hostPlatform = localSystem; - targetPlatform = localSystem; inherit config overlays; stdenv = stdenvDarwin prevStage; }) diff --git a/pkgs/stdenv/freebsd/default.nix b/pkgs/stdenv/freebsd/default.nix index 389a5b9985fe..d15afe761894 100644 --- a/pkgs/stdenv/freebsd/default.nix +++ b/pkgs/stdenv/freebsd/default.nix @@ -35,6 +35,9 @@ let inherit (localSystem) system; in stdenv = import ../generic { name = "stdenv-freebsd-boot-1"; + buildPlatform = localSystem; + hostPlatform = localSystem; + targetPlatform = localSystem; inherit config; initialPath = [ "/" "/usr" ]; hostPlatform = localSystem; @@ -52,6 +55,9 @@ let inherit (localSystem) system; in stdenv = import ../generic { name = "stdenv-freebsd-boot-0"; + buildPlatform = localSystem; + hostPlatform = localSystem; + targetPlatform = localSystem; inherit config; initialPath = [ prevStage.bootstrapTools ]; inherit (prevStage.stdenv) @@ -62,12 +68,12 @@ let inherit (localSystem) system; in }) (prevStage: { - buildPlatform = localSystem; - hostPlatform = localSystem; - targetPlatform = localSystem; inherit config overlays; stdenv = import ../generic { name = "stdenv-freebsd-boot-3"; + buildPlatform = localSystem; + hostPlatform = localSystem; + targetPlatform = localSystem; inherit config; inherit (prevStage.stdenv) @@ -77,8 +83,6 @@ let inherit (localSystem) system; in nativeTools = true; nativePrefix = "/usr"; nativeLibc = true; - hostPlatform = localSystem; - targetPlatform = localSystem; inherit (prevStage) stdenv; cc = { name = "clang-9.9.9"; diff --git a/pkgs/stdenv/generic/check-meta.nix b/pkgs/stdenv/generic/check-meta.nix new file mode 100644 index 000000000000..8b2cf01f169b --- /dev/null +++ b/pkgs/stdenv/generic/check-meta.nix @@ -0,0 +1,197 @@ +# Extend a derivation with checks for brokenness, license, etc. Throw a +# descriptive error when the check fails; return `derivationArg` otherwise. +# Note: no dependencies are checked in this step. + +{ lib, config, system, meta, derivationArg, mkDerivationArg }: + +let + attrs = mkDerivationArg; # TODO: probably get rid of passing this one + + # See discussion at https://github.com/NixOS/nixpkgs/pull/25304#issuecomment-298385426 + # for why this defaults to false, but I (@copumpkin) want to default it to true soon. + shouldCheckMeta = config.checkMeta or false; + + 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 ''‘${showLicense license}’ is not an attribute of lib.licenses'' + ) list; + + areLicenseListsValid = + if lib.mutuallyExclusive whitelist blacklist then + assert onlyLicenses whitelist; assert onlyLicenses blacklist; true + else + throw "whitelistedLicenses and blacklistedLicenses are not mutually exclusive."; + + hasLicense = attrs: + attrs ? meta.license; + + 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, ...}: + # { + # allowUnfree = false; + # allowUnfreePredicate = (x: pkgs.lib.hasPrefix "flashplayer-" x.name); + # } + allowUnfreePredicate = config.allowUnfreePredicate or (x: false); + + # 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; + + allowInsecureDefaultPredicate = x: builtins.elem x.name (config.permittedInsecurePackages or []); + allowInsecurePredicate = x: (config.allowUnfreePredicate or allowInsecureDefaultPredicate) x; + + hasAllowedInsecure = attrs: + (attrs.meta.knownVulnerabilities or []) == [] || + allowInsecurePredicate attrs || + builtins.getEnv "NIXPKGS_ALLOW_INSECURE" == "1"; + + showLicense = license: license.shortName or "unknown"; + + pos_str = meta.position or "«unknown-file»"; + + remediation = { + unfree = remediate_whitelist "Unfree"; + broken = remediate_whitelist "Broken"; + blacklisted = x: ""; + insecure = remediate_insecure; + unknown-meta = x: ""; + }; + remediate_whitelist = allow_attr: attrs: + '' + a) For `nixos-rebuild` you can set + { nixpkgs.config.allow${allow_attr} = true; } + in configuration.nix to override this. + + b) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add + { allow${allow_attr} = true; } + to ~/.config/nixpkgs/config.nix. + ''; + + remediate_insecure = attrs: + '' + + Known issues: + + '' + (lib.fold (issue: default: "${default} - ${issue}\n") "" attrs.meta.knownVulnerabilities) + '' + + You can install it anyway by whitelisting this package, using the + following methods: + + a) for `nixos-rebuild` you can add ‘${attrs.name or "«name-missing»"}’ to + `nixpkgs.config.permittedInsecurePackages` in the configuration.nix, + like so: + + { + nixpkgs.config.permittedInsecurePackages = [ + "${attrs.name or "«name-missing»"}" + ]; + } + + b) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add + ‘${attrs.name or "«name-missing»"}’ to `permittedInsecurePackages` in + ~/.config/nixpkgs/config.nix, like so: + + { + permittedInsecurePackages = [ + "${attrs.name or "«name-missing»"}" + ]; + } + + ''; + + throwEvalHelp = { reason , errormsg ? "" }: + throw ('' + Package ‘${attrs.name or "«name-missing»"}’ in ${pos_str} ${errormsg}, refusing to evaluate. + + '' + ((builtins.getAttr reason remediation) attrs)); + + metaTypes = with lib.types; rec { + # These keys are documented + description = str; + longDescription = str; + branch = str; + homepage = str; + downloadPage = str; + license = either (listOf lib.types.attrs) (either lib.types.attrs str); + maintainers = listOf str; + priority = int; + platforms = listOf str; + hydraPlatforms = listOf str; + broken = bool; + + # Weirder stuff that doesn't appear in the documentation? + version = str; + tag = str; + updateWalker = bool; + executables = listOf str; + outputsToInstall = listOf str; + position = str; + repositories = attrsOf str; + isBuildPythonPackage = platforms; + schedulingPriority = str; + downloadURLRegexp = str; + isFcitxEngine = bool; + isIbusEngine = bool; + }; + + checkMetaAttr = k: v: + if metaTypes?${k} then + if metaTypes.${k}.check v then null else "key '${k}' has a value ${v} of an invalid type ${builtins.typeOf v}; expected ${metaTypes.${k}.description}" + else "key '${k}' is unrecognized; expected one of: \n\t [${lib.concatMapStringsSep ", " (x: "'${x}'") (lib.attrNames metaTypes)}]"; + checkMeta = meta: if shouldCheckMeta then lib.remove null (lib.mapAttrsToList checkMetaAttr meta) else []; + + # Check if a derivation is valid, that is whether it passes checks for + # e.g brokenness or license. + # + # Return { valid: Bool } and additionally + # { reason: String; errormsg: String } if it is not valid, where + # reason is one of "unfree", "blacklisted" or "broken". + checkValidity = attrs: + if hasDeniedUnfreeLicense attrs && !(hasWhitelistedLicense attrs) then + { valid = false; reason = "unfree"; errormsg = "has an unfree license (‘${showLicense attrs.meta.license}’)"; } + else if hasBlacklistedLicense attrs then + { valid = false; reason = "blacklisted"; errormsg = "has a blacklisted license (‘${showLicense attrs.meta.license}’)"; } + else if !allowBroken && attrs.meta.broken or false then + { valid = false; reason = "broken"; errormsg = "is marked as broken"; } + else if !allowBroken && attrs.meta.platforms or null != null && !lib.lists.elem system attrs.meta.platforms then + { valid = false; reason = "broken"; errormsg = "is not supported on ‘${system}’"; } + else if !(hasAllowedInsecure attrs) then + { valid = false; reason = "insecure"; errormsg = "is marked as insecure"; } + else let res = checkMeta (attrs.meta or {}); in if res != [] then + { valid = false; reason = "unknown-meta"; errormsg = "has an invalid meta attrset:${lib.concatMapStrings (x: "\n\t - " + x) res}"; } + else { valid = true; }; + + # Throw an error if trying to evaluate an non-valid derivation + validityCondition = + let v = checkValidity attrs; + in if !v.valid + then throwEvalHelp (removeAttrs v ["valid"]) + else true; + +in + assert validityCondition; + derivationArg diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix index ce9beb2bbc62..a5d3c5a8ff5c 100644 --- a/pkgs/stdenv/generic/default.nix +++ b/pkgs/stdenv/generic/default.nix @@ -15,89 +15,32 @@ let lib = import ../../../lib; in lib.makeOverridable ( , stdenvSandboxProfile ? "" , extraSandboxProfile ? "" -, # The platforms here do *not* correspond to the stage the stdenv is - # used in, but rather the previous one, in which it was built. We - # use the latter two platforms, like a cross compiler, because the - # stand environment is a build tool if you squint at it, and because - # neither of these are used when building stdenv so we know the - # build platform is irrelevant. - hostPlatform, targetPlatform + ## Platform parameters + ## + ## The "build" "host" "target" terminology below comes from GNU Autotools. See + ## its documentation for more information on what those words mean. Note that + ## each should always be defined, even when not cross compiling. + ## + ## For purposes of bootstrapping, think of each stage as a "sliding window" + ## over a list of platforms. Specifically, the host platform of the previous + ## stage becomes the build platform of the current one, and likewise the + ## target platform of the previous stage becomes the host platform of the + ## current one. + ## + +, # The platform on which packages are built. Consists of `system`, a + # string (e.g.,`i686-linux') identifying the most import attributes of the + # build platform, and `platform` a set of other details. + buildPlatform + +, # The platform on which packages run. + hostPlatform + +, # The platform which build tools (especially compilers) build for in this stage, + targetPlatform }: let - inherit (targetPlatform) system; - - # See discussion at https://github.com/NixOS/nixpkgs/pull/25304#issuecomment-298385426 - # for why this defaults to false, but I (@copumpkin) want to default it to true soon. - shouldCheckMeta = config.checkMeta or false; - - allowUnfree = config.allowUnfree or false || builtins.getEnv "NIXPKGS_ALLOW_UNFREE" == "1"; - - whitelist = config.whitelistedLicenses or []; - blacklist = config.blacklistedLicenses or []; - - ifDarwin = attrs: if system == "x86_64-darwin" then attrs else {}; - - onlyLicenses = list: - lib.lists.all (license: - let l = lib.licenses.${license.shortName or "BROKEN"} or false; in - if license == l then true else - throw ''‘${showLicense 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: - attrs ? meta.license; - - 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, ...}: - # { - # allowUnfree = false; - # allowUnfreePredicate = (x: pkgs.lib.hasPrefix "flashplayer-" x.name); - # } - allowUnfreePredicate = config.allowUnfreePredicate or (x: false); - - # 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; - - allowInsecureDefaultPredicate = x: builtins.elem x.name (config.permittedInsecurePackages or []); - allowInsecurePredicate = x: (config.allowUnfreePredicate or allowInsecureDefaultPredicate) x; - - hasAllowedInsecure = attrs: - (attrs.meta.knownVulnerabilities or []) == [] || - allowInsecurePredicate attrs || - builtins.getEnv "NIXPKGS_ALLOW_INSECURE" == "1"; - - showLicense = license: license.shortName or "unknown"; - defaultNativeBuildInputs = extraBuildInputs ++ [ ../../build-support/setup-hooks/move-docs.sh ../../build-support/setup-hooks/compress-man-pages.sh @@ -106,7 +49,7 @@ let ] # FIXME this on Darwin; see # https://github.com/NixOS/nixpkgs/commit/94d164dd7#commitcomment-22030369 - ++ lib.optional result.isLinux ../../build-support/setup-hooks/audit-tmpdir.sh + ++ lib.optional hostPlatform.isLinux ../../build-support/setup-hooks/audit-tmpdir.sh ++ [ ../../build-support/setup-hooks/multiple-outputs.sh ../../build-support/setup-hooks/move-sbin.sh @@ -115,272 +58,16 @@ let cc ]; - # `mkDerivation` wraps the builtin `derivation` function to - # produce derivations that use this stdenv and its shell. - # - # See also: - # - # * https://nixos.org/nixpkgs/manual/#sec-using-stdenv - # Details on how to use this mkDerivation function - # - # * https://nixos.org/nix/manual/#ssec-derivation - # Explanation about derivations in general - mkDerivation = - { nativeBuildInputs ? [] - , buildInputs ? [] - - , propagatedNativeBuildInputs ? [] - , propagatedBuildInputs ? [] - - , crossConfig ? null - , meta ? {} - , passthru ? {} - , pos ? null # position used in error messages and for meta.position - , separateDebugInfo ? false - , outputs ? [ "out" ] - , __impureHostDeps ? [] - , __propagatedImpureHostDeps ? [] - , sandboxProfile ? "" - , propagatedSandboxProfile ? "" - , ... } @ attrs: - let - dependencies = [ - (map (drv: drv.nativeDrv or drv) nativeBuildInputs) - (map (drv: drv.crossDrv or drv) buildInputs) - ]; - propagatedDependencies = [ - (map (drv: drv.nativeDrv or drv) propagatedNativeBuildInputs) - (map (drv: drv.crossDrv or drv) propagatedBuildInputs) - ]; - in let - pos' = - if pos != null then - pos - else if attrs.meta.description or null != null then - builtins.unsafeGetAttrPos "description" attrs.meta - else - builtins.unsafeGetAttrPos "name" attrs; - pos'' = if pos' != null then "‘" + pos'.file + ":" + toString pos'.line + "’" else "«unknown-file»"; - - - remediation = { - unfree = remediate_whitelist "Unfree"; - broken = remediate_whitelist "Broken"; - blacklisted = x: ""; - insecure = remediate_insecure; - unknown-meta = x: ""; - }; - remediate_whitelist = allow_attr: attrs: - '' - a) For `nixos-rebuild` you can set - { nixpkgs.config.allow${allow_attr} = true; } - in configuration.nix to override this. - - b) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add - { allow${allow_attr} = true; } - to ~/.config/nixpkgs/config.nix. - ''; - - remediate_insecure = attrs: - '' - - Known issues: - - '' + (lib.fold (issue: default: "${default} - ${issue}\n") "" attrs.meta.knownVulnerabilities) + '' - - You can install it anyway by whitelisting this package, using the - following methods: - - a) for `nixos-rebuild` you can add ‘${attrs.name or "«name-missing»"}’ to - `nixpkgs.config.permittedInsecurePackages` in the configuration.nix, - like so: - - { - nixpkgs.config.permittedInsecurePackages = [ - "${attrs.name or "«name-missing»"}" - ]; - } - - b) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add - ‘${attrs.name or "«name-missing»"}’ to `permittedInsecurePackages` in - ~/.config/nixpkgs/config.nix, like so: - - { - permittedInsecurePackages = [ - "${attrs.name or "«name-missing»"}" - ]; - } - - ''; - - - throwEvalHelp = { reason , errormsg ? "" }: - throw ('' - Package ‘${attrs.name or "«name-missing»"}’ in ${pos''} ${errormsg}, refusing to evaluate. - - '' + ((builtins.getAttr reason remediation) attrs)); - - metaTypes = with lib.types; rec { - # These keys are documented - description = str; - longDescription = str; - branch = str; - homepage = str; - downloadPage = str; - license = either (listOf lib.types.attrs) (either lib.types.attrs str); - maintainers = listOf str; - priority = int; - platforms = listOf str; - hydraPlatforms = listOf str; - broken = bool; - - # Weirder stuff that doesn't appear in the documentation? - version = str; - tag = str; - updateWalker = bool; - executables = listOf str; - outputsToInstall = listOf str; - position = str; - repositories = attrsOf str; - isBuildPythonPackage = platforms; - schedulingPriority = str; - downloadURLRegexp = str; - isFcitxEngine = bool; - isIbusEngine = bool; - }; - - checkMetaAttr = k: v: - if metaTypes?${k} then - if metaTypes.${k}.check v then null else "key '${k}' has a value ${v} of an invalid type ${builtins.typeOf v}; expected ${metaTypes.${k}.description}" - else "key '${k}' is unrecognized; expected one of: \n\t [${lib.concatMapStringsSep ", " (x: "'${x}'") (lib.attrNames metaTypes)}]"; - checkMeta = meta: if shouldCheckMeta then lib.remove null (lib.mapAttrsToList checkMetaAttr meta) else []; - - # Check if a derivation is valid, that is whether it passes checks for - # e.g brokenness or license. - # - # Return { valid: Bool } and additionally - # { reason: String; errormsg: String } if it is not valid, where - # reason is one of "unfree", "blacklisted" or "broken". - checkValidity = attrs: - if hasDeniedUnfreeLicense attrs && !(hasWhitelistedLicense attrs) then - { valid = false; reason = "unfree"; errormsg = "has an unfree license (‘${showLicense attrs.meta.license}’)"; } - else if hasBlacklistedLicense attrs then - { valid = false; reason = "blacklisted"; errormsg = "has a blacklisted license (‘${showLicense attrs.meta.license}’)"; } - else if !allowBroken && attrs.meta.broken or false then - { valid = false; reason = "broken"; errormsg = "is marked as broken"; } - else if !allowBroken && attrs.meta.platforms or null != null && !lib.lists.elem result.system attrs.meta.platforms then - { valid = false; reason = "broken"; errormsg = "is not supported on ‘${result.system}’"; } - else if !(hasAllowedInsecure attrs) then - { valid = false; reason = "insecure"; errormsg = "is marked as insecure"; } - else let res = checkMeta (attrs.meta or {}); in if res != [] then - { valid = false; reason = "unknown-meta"; errormsg = "has an invalid meta attrset:${lib.concatMapStrings (x: "\n\t - " + x) res}"; } - else { valid = true; }; - - outputs' = - outputs ++ - (if separateDebugInfo then assert targetPlatform.isLinux; [ "debug" ] else []); - - dependencies' = let - justMap = map lib.chooseDevOutputs dependencies; - nativeBuildInputs = lib.elemAt justMap 0 - ++ lib.optional targetPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh; - buildInputs = lib.elemAt justMap 1 - # TODO(@Ericson2314): Should instead also be appended to `nativeBuildInputs`. - ++ lib.optional separateDebugInfo ../../build-support/setup-hooks/separate-debug-info.sh; - in [ nativeBuildInputs buildInputs ]; - - propagatedDependencies' = map lib.chooseDevOutputs propagatedDependencies; - in - - # Throw an error if trying to evaluate an non-valid derivation - assert let v = checkValidity attrs; - in if !v.valid - then throwEvalHelp (removeAttrs v ["valid"]) - else true; - - lib.addPassthru (derivation ( - (removeAttrs attrs - ["meta" "passthru" "crossAttrs" "pos" - "__impureHostDeps" "__propagatedImpureHostDeps" - "sandboxProfile" "propagatedSandboxProfile"]) - // (let - # TODO(@Ericson2314): Reversing of dep lists is just temporary to avoid Darwin mass rebuild. - computedSandboxProfile = - lib.concatMap (input: input.__propagatedSandboxProfile or []) (extraBuildInputs ++ lib.concatLists (lib.reverseList dependencies')); - computedPropagatedSandboxProfile = - lib.concatMap (input: input.__propagatedSandboxProfile or []) (lib.concatLists (lib.reverseList propagatedDependencies')); - computedImpureHostDeps = - lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (extraBuildInputs ++ lib.concatLists (lib.reverseList dependencies'))); - computedPropagatedImpureHostDeps = - lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (lib.concatLists (lib.reverseList propagatedDependencies'))); - in - { - builder = attrs.realBuilder or shell; - args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)]; - stdenv = result; - system = result.system; - userHook = config.stdenv.userHook or null; - __ignoreNulls = true; - - nativeBuildInputs = lib.elemAt dependencies' 0; - buildInputs = lib.elemAt dependencies' 1; - - propagatedNativeBuildInputs = lib.elemAt propagatedDependencies' 0; - propagatedBuildInputs = lib.elemAt propagatedDependencies' 1; - } // ifDarwin { - # TODO: remove lib.unique once nix has a list canonicalization primitive - __sandboxProfile = - let profiles = [ extraSandboxProfile ] ++ computedSandboxProfile ++ computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile sandboxProfile ]; - final = lib.concatStringsSep "\n" (lib.filter (x: x != "") (lib.unique profiles)); - in final; - __propagatedSandboxProfile = lib.unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]); - __impureHostDeps = computedImpureHostDeps ++ computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ++ __impureHostDeps ++ __extraImpureHostDeps ++ [ - "/dev/zero" - "/dev/random" - "/dev/urandom" - "/bin/sh" - ]; - __propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps; - } // (if outputs' != [ "out" ] then { - outputs = outputs'; - } else { })))) ( - { - overrideAttrs = f: mkDerivation (attrs // (f attrs)); - # The meta attribute is passed in the resulting attribute set, - # but it's not part of the actual derivation, i.e., it's not - # passed to the builder and is not a dependency. But since we - # include it in the result, it *is* available to nix-env for queries. - meta = { } - # If the packager hasn't specified `outputsToInstall`, choose a default, - # which is the name of `p.bin or p.out or p`; - # if he has specified it, it will be overridden below in `// meta`. - # Note: This default probably shouldn't be globally configurable. - # Services and users should specify outputs explicitly, - # unless they are comfortable with this default. - // { outputsToInstall = - let - outs = outputs'; # the value passed to derivation primitive - hasOutput = out: builtins.elem out outs; - in [( lib.findFirst hasOutput null (["bin" "out"] ++ outs) )]; - } - // meta - # Fill `meta.position` to identify the source location of the package. - // lib.optionalAttrs (pos' != null) - { position = pos'.file + ":" + toString pos'.line; } - ; - 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). - passthru); - # The stdenv that we are producing. - result = + stdenv = derivation ( (if isNull allowedRequisites then {} else { allowedRequisites = allowedRequisites ++ defaultNativeBuildInputs; }) // { - inherit system name; + inherit name; + + # Nix itself uses the `system` field of a derivation to decide where to + # build it. This is a bit confusing for cross compilation. + inherit (buildPlatform) system; builder = shell; @@ -390,7 +77,7 @@ let inherit preHook initialPath shell defaultNativeBuildInputs; } - // ifDarwin { + // lib.optionalAttrs buildPlatform.isDarwin { __sandboxProfile = stdenvSandboxProfile; __impureHostDeps = __stdenvImpureHostDeps; }) @@ -402,6 +89,10 @@ let platforms = lib.platforms.all; }; + inherit buildPlatform hostPlatform targetPlatform; + + inherit extraBuildInputs __extraImpureHostDeps extraSandboxProfile; + # Utility flags to test the type of platform. inherit (hostPlatform) isDarwin isLinux isSunOS isHurd isCygwin isFreeBSD isOpenBSD @@ -412,7 +103,9 @@ let # Whether we should run paxctl to pax-mark binaries. needsPax = isLinux; - inherit mkDerivation; + inherit (import ./make-derivation.nix { + inherit lib config stdenv; + }) mkDerivation; # For convenience, bring in the library functions in lib/ so # packages don't have to do that themselves. @@ -431,4 +124,4 @@ let # like curl = if stdenv ? curl then stdenv.curl else ...). // extraAttrs; -in result) +in stdenv) diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix new file mode 100644 index 000000000000..31b0428eeb2b --- /dev/null +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -0,0 +1,150 @@ +{ lib, config, stdenv }: + +rec { + # `mkDerivation` wraps the builtin `derivation` function to + # produce derivations that use this stdenv and its shell. + # + # See also: + # + # * https://nixos.org/nixpkgs/manual/#sec-using-stdenv + # Details on how to use this mkDerivation function + # + # * https://nixos.org/nix/manual/#ssec-derivation + # Explanation about derivations in general + mkDerivation = + { nativeBuildInputs ? [] + , buildInputs ? [] + + , propagatedNativeBuildInputs ? [] + , propagatedBuildInputs ? [] + + , crossConfig ? null + , meta ? {} + , passthru ? {} + , pos ? # position used in error messages and for meta.position + (if attrs.meta.description or null != null + then builtins.unsafeGetAttrPos "description" attrs.meta + else builtins.unsafeGetAttrPos "name" attrs) + , separateDebugInfo ? false + , outputs ? [ "out" ] + , __impureHostDeps ? [] + , __propagatedImpureHostDeps ? [] + , sandboxProfile ? "" + , propagatedSandboxProfile ? "" + , ... } @ attrs: + let + dependencies = [ + (map (drv: drv.nativeDrv or drv) nativeBuildInputs) + (map (drv: drv.crossDrv or drv) buildInputs) + ]; + propagatedDependencies = [ + (map (drv: drv.nativeDrv or drv) propagatedNativeBuildInputs) + (map (drv: drv.crossDrv or drv) propagatedBuildInputs) + ]; + in let + + outputs' = + outputs ++ + (if separateDebugInfo then assert stdenv.hostPlatform.isLinux; [ "debug" ] else []); + + dependencies' = let + justMap = map lib.chooseDevOutputs dependencies; + nativeBuildInputs = lib.elemAt justMap 0 + ++ lib.optional stdenv.hostPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh; + buildInputs = lib.elemAt justMap 1 + # TODO(@Ericson2314): Should instead also be appended to `nativeBuildInputs`. + ++ lib.optional separateDebugInfo ../../build-support/setup-hooks/separate-debug-info.sh; + in [ nativeBuildInputs buildInputs ]; + + propagatedDependencies' = map lib.chooseDevOutputs propagatedDependencies; + + derivationArg = + (removeAttrs attrs + ["meta" "passthru" "crossAttrs" "pos" + "__impureHostDeps" "__propagatedImpureHostDeps" + "sandboxProfile" "propagatedSandboxProfile"]) + // (let + # TODO(@Ericson2314): Reversing of dep lists is just temporary to avoid Darwin mass rebuild. + computedSandboxProfile = + lib.concatMap (input: input.__propagatedSandboxProfile or []) (stdenv.extraBuildInputs ++ lib.concatLists (lib.reverseList dependencies')); + computedPropagatedSandboxProfile = + lib.concatMap (input: input.__propagatedSandboxProfile or []) (lib.concatLists (lib.reverseList propagatedDependencies')); + computedImpureHostDeps = + lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (stdenv.extraBuildInputs ++ lib.concatLists (lib.reverseList dependencies'))); + computedPropagatedImpureHostDeps = + lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (lib.concatLists (lib.reverseList propagatedDependencies'))); + in + { + builder = attrs.realBuilder or stdenv.shell; + args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)]; + inherit stdenv; + inherit (stdenv) system; + userHook = config.stdenv.userHook or null; + __ignoreNulls = true; + + nativeBuildInputs = lib.elemAt dependencies' 0; + buildInputs = lib.elemAt dependencies' 1; + + propagatedNativeBuildInputs = lib.elemAt propagatedDependencies' 0; + propagatedBuildInputs = lib.elemAt propagatedDependencies' 1; + } // lib.optionalAttrs (stdenv.buildPlatform.isDarwin) { + # TODO: remove lib.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)); + in final; + __propagatedSandboxProfile = lib.unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]); + __impureHostDeps = computedImpureHostDeps ++ computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ++ __impureHostDeps ++ stdenv.__extraImpureHostDeps ++ [ + "/dev/zero" + "/dev/random" + "/dev/urandom" + "/bin/sh" + ]; + __propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps; + } // (if outputs' != [ "out" ] then { + outputs = outputs'; + } 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 + # passed to the builder and is not a dependency. But since we + # include it in the result, it *is* available to nix-env for queries. + meta = { } + # If the packager hasn't specified `outputsToInstall`, choose a default, + # which is the name of `p.bin or p.out or p`; + # if he has specified it, it will be overridden below in `// meta`. + # Note: This default probably shouldn't be globally configurable. + # Services and users should specify outputs explicitly, + # unless they are comfortable with this default. + // { outputsToInstall = + let + outs = outputs'; # the value passed to derivation primitive + hasOutput = out: builtins.elem out outs; + in [( lib.findFirst hasOutput null (["bin" "out"] ++ outs) )]; + } + // attrs.meta or {} + # Fill `meta.position` to identify the source location of the package. + // lib.optionalAttrs (pos != null) + { position = pos.file + ":" + toString pos.line; } + ; + + in + + lib.addPassthru + (derivation (import ./check-meta.nix + { + inherit lib config meta derivationArg; + mkDerivationArg = attrs; + # Nix itself uses the `system` field of a derivation to decide where + # to build it. This is a bit confusing for cross compilation. + inherit (stdenv) system; + })) + ( { + overrideAttrs = f: mkDerivation (attrs // (f attrs)); + inherit meta passthru; + } // + # Pass through extra attributes that are not inputs, but + # should be made available to Nix expressions using the + # derivation (e.g., in assertions). + passthru); +} diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix index c2879d93e17c..c475d2d1e927 100644 --- a/pkgs/stdenv/linux/default.nix +++ b/pkgs/stdenv/linux/default.nix @@ -52,8 +52,11 @@ let let thisStdenv = import ../generic { - inherit config extraBuildInputs; name = "stdenv-linux-boot"; + buildPlatform = localSystem; + hostPlatform = localSystem; + targetPlatform = localSystem; + inherit config extraBuildInputs; preHook = '' # Don't patch #!/interpreter because it leads to retained @@ -64,9 +67,6 @@ let shell = "${bootstrapTools}/bin/bash"; initialPath = [bootstrapTools]; - hostPlatform = localSystem; - targetPlatform = localSystem; - fetchurlBoot = import ../../build-support/fetchurl/boot.nix { inherit system; }; @@ -102,9 +102,6 @@ let }; in { - buildPlatform = localSystem; - hostPlatform = localSystem; - targetPlatform = localSystem; inherit config overlays; stdenv = thisStdenv; }; @@ -269,11 +266,11 @@ in # dependency (`nix-store -qR') on bootstrapTools or the first # binutils built. (prevStage: { - buildPlatform = localSystem; - hostPlatform = localSystem; - targetPlatform = localSystem; inherit config overlays; stdenv = import ../generic rec { + buildPlatform = localSystem; + hostPlatform = localSystem; + targetPlatform = localSystem; inherit config; preHook = '' @@ -286,9 +283,6 @@ in initialPath = ((import ../common-path.nix) {pkgs = prevStage;}); - hostPlatform = localSystem; - targetPlatform = localSystem; - extraBuildInputs = [ prevStage.patchelf prevStage.paxctl ] ++ # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64. lib.optional (system == "aarch64-linux") prevStage.updateAutotoolsGnuConfigScriptsHook; diff --git a/pkgs/stdenv/native/default.nix b/pkgs/stdenv/native/default.nix index 31973c2cdc50..02734f2f3e59 100644 --- a/pkgs/stdenv/native/default.nix +++ b/pkgs/stdenv/native/default.nix @@ -81,6 +81,7 @@ let { cc, fetchurl, extraPath ? [], overrides ? (self: super: { }) }: import ../generic { + buildPlatform = localSystem; hostPlatform = localSystem; targetPlatform = localSystem; @@ -125,8 +126,6 @@ in "i686-solaris" = "/usr/gnu"; "x86_64-solaris" = "/opt/local/gcc47"; }.${system} or "/usr"; - hostPlatform = localSystem; - targetPlatform = localSystem; inherit stdenv; }; @@ -140,9 +139,6 @@ in # First build a stdenv based only on tools outside the store. (prevStage: { - buildPlatform = localSystem; - hostPlatform = localSystem; - targetPlatform = localSystem; inherit config overlays; stdenv = makeStdenv { inherit (prevStage) cc fetchurl; @@ -152,9 +148,6 @@ in # Using that, build a stdenv that adds the ‘xz’ command (which most systems # don't have, so we mustn't rely on the native environment providing it). (prevStage: { - buildPlatform = localSystem; - hostPlatform = localSystem; - targetPlatform = localSystem; inherit config overlays; stdenv = makeStdenv { inherit (prevStage.stdenv) cc fetchurl; diff --git a/pkgs/stdenv/nix/default.nix b/pkgs/stdenv/nix/default.nix index 7ab797ce91ba..aaf6c523ea4a 100644 --- a/pkgs/stdenv/nix/default.nix +++ b/pkgs/stdenv/nix/default.nix @@ -10,10 +10,13 @@ bootStages ++ [ (prevStage: let inherit (prevStage) stdenv; in { - inherit (prevStage) buildPlatform hostPlatform targetPlatform; inherit config overlays; stdenv = import ../generic rec { + buildPlatform = localSystem; + hostPlatform = localSystem; + targetPlatform = localSystem; + inherit config; preHook = '' @@ -30,8 +33,6 @@ bootStages ++ [ nativeTools = false; nativePrefix = stdenv.lib.optionalString hostPlatform.isSunOS "/usr"; nativeLibc = true; - hostPlatform = localSystem; - targetPlatform = localSystem; inherit stdenv; inherit (prevStage) binutils coreutils gnugrep; cc = prevStage.gcc.cc; |