nixpkgs/pkgs/stdenv/generic/default.nix

343 lines
14 KiB
Nix
Raw Normal View History

let lib = import ../../../lib; in lib.makeOverridable (
{ 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).
fetchurlBoot
, setupScript ? ./setup.sh
, extraBuildInputs ? []
2015-06-12 02:58:26 +02:00
, __stdenvImpureHostDeps ? []
, __extraImpureHostDeps ? []
, stdenvSandboxProfile ? ""
, extraSandboxProfile ? ""
}:
let
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:
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, ...}:
# {
# allowUnfree = false;
2014-06-25 16:51:18 +02:00
# 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;
showLicense = license: license.shortName or "unknown";
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
2014-08-30 08:27:43 +02:00
../../build-support/setup-hooks/multiple-outputs.sh
../../build-support/setup-hooks/move-sbin.sh
../../build-support/setup-hooks/move-lib64.sh
../../build-support/setup-hooks/set-source-date-epoch-to-latest.sh
cc
];
2014-07-01 16:43:52 +02:00
# Add a utility function to produce derivations that use this
# stdenv and its shell.
2015-03-06 16:42:06 +01:00
mkDerivation =
{ buildInputs ? []
, nativeBuildInputs ? []
, propagatedBuildInputs ? []
, propagatedNativeBuildInputs ? []
, crossConfig ? null
, meta ? {}
, passthru ? {}
, pos ? null # position used in error messages and for meta.position
, separateDebugInfo ? false
, outputs ? [ "out" ]
, __impureHostDeps ? []
, __propagatedImpureHostDeps ? []
, sandboxProfile ? ""
, propagatedSandboxProfile ? ""
2015-03-06 16:42:06 +01:00
, ... } @ attrs:
2014-07-01 16:43:52 +02:00
let
pos' =
if pos != null then
pos
else if attrs.meta.description or null != null then
builtins.unsafeGetAttrPos "description" attrs.meta
2014-07-01 16:43:52 +02:00
else
builtins.unsafeGetAttrPos "name" attrs;
pos'' = if pos' != null then "" + pos'.file + ":" + toString pos'.line + "" else "«unknown-file»";
throwEvalHelp = { reason, errormsg }:
# uppercase the first character of string s
let up = s: with lib;
let cs = lib.stringToCharacters s;
in concatStrings (singleton (toUpper (head cs)) ++ tail cs);
in
assert builtins.elem reason ["unfree" "broken" "blacklisted"];
throw ("Package ${attrs.name or "«name-missing»"} in ${pos''} ${errormsg}, refusing to evaluate."
+ (lib.strings.optionalString (reason != "blacklisted") ''
a) For `nixos-rebuild` you can set
{ nixpkgs.config.allow${up reason} = true; }
in configuration.nix to override this.
b) For `nix-env`, `nix-build` or any other Nix command you can add
{ allow${up reason} = true; }
to ~/.nixpkgs/config.nix.
''));
# 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"; }
2015-01-29 10:46:35 +01:00
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 { valid = true; };
outputs' =
outputs ++
(if separateDebugInfo then assert result.isLinux; [ "debug" ] else []);
buildInputs' = buildInputs ++
(if separateDebugInfo then [ ../../build-support/setup-hooks/separate-debug-info.sh ] else []);
2014-07-01 16:43:52 +02:00
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;
2014-07-01 16:43:52 +02:00
lib.addPassthru (derivation (
(removeAttrs attrs
["meta" "passthru" "crossAttrs" "pos"
2015-11-07 02:44:02 +01:00
"__impureHostDeps" "__propagatedImpureHostDeps"
"sandboxProfile" "propagatedSandboxProfile"])
2015-06-12 02:58:26 +02:00
// (let
2015-11-07 02:44:02 +01:00
computedSandboxProfile =
lib.concatMap (input: input.__propagatedSandboxProfile or []) (extraBuildInputs ++ buildInputs ++ nativeBuildInputs);
2015-11-07 02:44:02 +01:00
computedPropagatedSandboxProfile =
lib.concatMap (input: input.__propagatedSandboxProfile or []) (propagatedBuildInputs ++ propagatedNativeBuildInputs);
computedImpureHostDeps =
lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (extraBuildInputs ++ buildInputs ++ nativeBuildInputs));
computedPropagatedImpureHostDeps =
lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (propagatedBuildInputs ++ propagatedNativeBuildInputs));
2015-06-12 02:58:26 +02:00
in
2014-07-01 16:43:52 +02:00
{
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;
# Inputs built by the cross compiler.
buildInputs = if crossConfig != null then buildInputs' else [];
propagatedBuildInputs = if crossConfig != null then propagatedBuildInputs else [];
2014-07-01 16:43:52 +02:00
# Inputs built by the usual native compiler.
nativeBuildInputs = nativeBuildInputs ++ (if crossConfig == null then buildInputs' else []);
2014-07-01 16:43:52 +02:00
propagatedNativeBuildInputs = propagatedNativeBuildInputs ++
(if crossConfig == null then propagatedBuildInputs else []);
} // ifDarwin {
2015-11-13 03:59:17 +01:00
# TODO: remove lib.unique once nix has a list canonicalization primitive
__sandboxProfile =
let profiles = [ extraSandboxProfile ] ++ computedSandboxProfile ++ computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile sandboxProfile ];
2015-11-13 03:59:17 +01:00
final = lib.concatStringsSep "\n" (lib.filter (x: x != "") (lib.unique profiles));
in final;
__propagatedSandboxProfile = lib.unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]);
2015-06-18 06:54:29 +02:00
__impureHostDeps = computedImpureHostDeps ++ computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ++ __impureHostDeps ++ __extraImpureHostDeps ++ [
2015-06-12 02:58:26 +02:00
"/dev/zero"
"/dev/random"
"/dev/urandom"
"/bin/sh"
2015-06-18 06:54:29 +02:00
];
__propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps;
} // (if outputs' != [ "out" ] then {
outputs = outputs';
} else { })))) (
2014-07-01 16:43:52 +02:00
{
# 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,
# namely `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; }
;
2015-03-06 16:42:06 +01:00
inherit passthru;
2014-07-01 16:43:52 +02:00
} //
# Pass through extra attributes that are not inputs, but
# should be made available to Nix expressions using the
# derivation (e.g., in assertions).
2015-03-06 16:42:06 +01:00
passthru);
2014-07-01 16:43:52 +02:00
# The stdenv that we are producing.
result =
derivation (
(if isNull allowedRequisites then {} else { allowedRequisites = allowedRequisites ++ defaultNativeBuildInputs; }) //
{
inherit system name;
builder = shell;
args = ["-e" ./builder.sh];
setup = setupScript;
inherit preHook initialPath shell defaultNativeBuildInputs;
}
// ifDarwin {
__sandboxProfile = stdenvSandboxProfile;
__impureHostDeps = __stdenvImpureHostDeps;
})
// rec {
2014-07-01 16:43:52 +02:00
meta.description = "The default build environment for Unix packages in Nixpkgs";
# Utility flags to test the type of platform.
2014-02-04 17:34:15 +01:00
isDarwin = system == "x86_64-darwin";
isLinux = system == "i686-linux"
|| system == "x86_64-linux"
|| system == "powerpc-linux"
|| system == "armv5tel-linux"
|| system == "armv6l-linux"
|| system == "armv7l-linux"
|| system == "mips64el-linux";
isGNU = system == "i686-gnu"; # GNU/Hurd
isGlibc = isGNU # useful for `stdenvNative'
|| isLinux
2014-02-04 17:34:15 +01:00
|| system == "x86_64-kfreebsd-gnu";
isSunOS = system == "i686-solaris"
|| system == "x86_64-solaris";
isCygwin = system == "i686-cygwin"
|| system == "x86_64-cygwin";
2014-02-04 17:34:15 +01:00
isFreeBSD = system == "i686-freebsd"
2015-02-25 04:15:51 +01:00
|| system == "x86_64-freebsd";
2014-02-04 17:34:15 +01:00
isOpenBSD = system == "i686-openbsd"
2015-02-25 04:15:51 +01:00
|| system == "x86_64-openbsd";
2014-02-04 17:34:15 +01:00
isi686 = system == "i686-linux"
|| system == "i686-gnu"
|| system == "i686-freebsd"
|| system == "i686-openbsd"
2015-05-26 15:18:49 +02:00
|| system == "i686-cygwin"
2014-02-04 17:34:15 +01:00
|| system == "i386-sunos";
isx86_64 = system == "x86_64-linux"
|| system == "x86_64-darwin"
|| system == "x86_64-freebsd"
|| system == "x86_64-openbsd"
2015-05-26 15:18:49 +02:00
|| system == "x86_64-cygwin"
2014-02-04 17:34:15 +01:00
|| system == "x86_64-solaris";
is64bit = system == "x86_64-linux"
|| system == "x86_64-darwin"
|| system == "x86_64-freebsd"
|| system == "x86_64-openbsd"
2015-05-26 15:18:49 +02:00
|| system == "x86_64-cygwin"
2015-04-26 00:08:05 +02:00
|| system == "x86_64-solaris"
|| system == "mips64el-linux";
2014-02-04 17:34:15 +01:00
isMips = system == "mips-linux"
|| system == "mips64el-linux";
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;
2014-07-01 16:43:52 +02:00
inherit mkDerivation;
# For convenience, bring in the library functions in lib/ so
# packages don't have to do that themselves.
inherit lib;
inherit fetchurlBoot;
inherit overrides;
inherit cc;
}
# Propagate any extra attributes. For instance, we use this to
# "lift" packages like curl from the final stdenv for Linux to
# all-packages.nix for that platform (meaning that it has a line
# like curl = if stdenv ? curl then stdenv.curl else ...).
// extraAttrs;
in result)