summaryrefslogtreecommitdiffstats
path: root/pkgs/stdenv/generic/make-derivation.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/stdenv/generic/make-derivation.nix')
-rw-r--r--pkgs/stdenv/generic/make-derivation.nix163
1 files changed, 111 insertions, 52 deletions
diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix
index 432a7e338944..96f8e91412cd 100644
--- a/pkgs/stdenv/generic/make-derivation.nix
+++ b/pkgs/stdenv/generic/make-derivation.nix
@@ -36,8 +36,12 @@ rec {
, depsTargetTarget ? [] # 1 -> 1
, depsTargetTargetPropagated ? [] # 1 -> 1
+ , checkInputs ? []
+ , installCheckInputs ? []
+
# Configure Phase
, configureFlags ? []
+ , cmakeFlags ? []
, # Target is not included by default because most programs don't care.
# Including it then would cause needless mass rebuilds.
#
@@ -46,18 +50,23 @@ rec {
(stdenv.hostPlatform != stdenv.buildPlatform)
[ "build" "host" ]
+ # TODO(@Ericson2314): Make unconditional / resolve #33599
# Check phase
- , doCheck ? false
+ , doCheck ? config.doCheckByDefault or false
+ # TODO(@Ericson2314): Make unconditional / resolve #33599
# InstallCheck phase
- , doInstallCheck ? false
+ , doInstallCheck ? config.doCheckByDefault or false
- , crossConfig ? null
+ , # TODO(@Ericson2314): Make always true and remove
+ strictDeps ? stdenv.hostPlatform != stdenv.buildPlatform
, 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 if attrs.version or null != null
+ then builtins.unsafeGetAttrPos "version" attrs
else builtins.unsafeGetAttrPos "name" attrs)
, separateDebugInfo ? false
, outputs ? [ "out" ]
@@ -71,9 +80,31 @@ rec {
, ... } @ attrs:
- # TODO(@Ericson2314): Make this more modular, and not O(n^2).
let
+ computedName = if name != "" then name else "${attrs.pname}-${attrs.version}";
+
+ # TODO(@oxij, @Ericson2314): This is here to keep the old semantics, remove when
+ # no package has `doCheck = true`.
+ doCheck' = doCheck && stdenv.hostPlatform == stdenv.buildPlatform;
+ doInstallCheck' = doInstallCheck && stdenv.hostPlatform == stdenv.buildPlatform;
+
+ separateDebugInfo' = separateDebugInfo && stdenv.hostPlatform.isLinux;
+ outputs' = outputs ++ lib.optional separateDebugInfo' "debug";
+
+ fixedOutputDrv = attrs ? outputHash;
+ noNonNativeDeps = builtins.length (depsBuildTarget ++ depsBuildTargetPropagated
+ ++ depsHostHost ++ depsHostHostPropagated
+ ++ buildInputs ++ propagatedBuildInputs
+ ++ depsTargetTarget ++ depsTargetTargetPropagated) == 0;
+ dontAddHostSuffix = attrs ? outputHash && !noNonNativeDeps || stdenv.cc == null;
supportedHardeningFlags = [ "fortify" "stackprotector" "pie" "pic" "strictoverflow" "format" "relro" "bindnow" ];
+ defaultHardeningFlags = if stdenv.hostPlatform.isMusl
+ then supportedHardeningFlags
+ else lib.remove "pie" supportedHardeningFlags;
+ enabledHardeningOptions =
+ if builtins.elem "all" hardeningDisable
+ then []
+ else lib.subtractLists hardeningDisable (defaultHardeningFlags ++ hardeningEnable);
# hardeningDisable additionally supports "all".
erroneousHardeningFlags = lib.subtractLists supportedHardeningFlags (hardeningEnable ++ lib.remove "all" hardeningDisable);
in if builtins.length erroneousHardeningFlags != 0
@@ -81,6 +112,11 @@ rec {
inherit erroneousHardeningFlags hardeningDisable hardeningEnable supportedHardeningFlags;
})
else let
+ doCheck = doCheck';
+ doInstallCheck = doInstallCheck';
+
+ outputs = outputs';
+
references = nativeBuildInputs ++ buildInputs
++ propagatedNativeBuildInputs ++ propagatedBuildInputs;
@@ -88,13 +124,15 @@ rec {
[
(map (drv: drv.__spliced.buildBuild or drv) depsBuildBuild)
(map (drv: drv.nativeDrv or drv) nativeBuildInputs
- ++ lib.optional separateDebugInfo ../../build-support/setup-hooks/separate-debug-info.sh
+ ++ lib.optional separateDebugInfo' ../../build-support/setup-hooks/separate-debug-info.sh
++ lib.optional stdenv.hostPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh)
(map (drv: drv.__spliced.buildTarget or drv) depsBuildTarget)
]
[
(map (drv: drv.__spliced.hostHost or drv) depsHostHost)
- (map (drv: drv.crossDrv or drv) buildInputs)
+ (map (drv: drv.crossDrv or drv) (buildInputs
+ ++ lib.optionals doCheck checkInputs
+ ++ lib.optionals doInstallCheck' installCheckInputs))
]
[
(map (drv: drv.__spliced.targetTarget or drv) depsTargetTarget)
@@ -115,58 +153,71 @@ rec {
]
];
- outputs' =
- outputs ++
- (if separateDebugInfo then assert stdenv.hostPlatform.isLinux; [ "debug" ] else []);
+ computedSandboxProfile =
+ lib.concatMap (input: input.__propagatedSandboxProfile or [])
+ (stdenv.extraNativeBuildInputs
+ ++ stdenv.extraBuildInputs
+ ++ lib.concatLists dependencies);
+
+ computedPropagatedSandboxProfile =
+ lib.concatMap (input: input.__propagatedSandboxProfile or [])
+ (lib.concatLists propagatedDependencies);
+
+ computedImpureHostDeps =
+ lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or [])
+ (stdenv.extraNativeBuildInputs
+ ++ stdenv.extraBuildInputs
+ ++ lib.concatLists dependencies));
+
+ computedPropagatedImpureHostDeps =
+ lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or [])
+ (lib.concatLists propagatedDependencies));
derivationArg =
(removeAttrs attrs
- ["meta" "passthru" "crossAttrs" "pos"
+ ["meta" "passthru" "pos"
+ "checkInputs" "installCheckInputs"
"__impureHostDeps" "__propagatedImpureHostDeps"
"sandboxProfile" "propagatedSandboxProfile"])
- // (let
- computedSandboxProfile =
- lib.concatMap (input: input.__propagatedSandboxProfile or [])
- (stdenv.extraNativeBuildInputs
- ++ stdenv.extraBuildInputs
- ++ lib.concatLists dependencies);
- computedPropagatedSandboxProfile =
- lib.concatMap (input: input.__propagatedSandboxProfile or [])
- (lib.concatLists propagatedDependencies);
- computedImpureHostDeps =
- lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or [])
- (stdenv.extraNativeBuildInputs
- ++ stdenv.extraBuildInputs
- ++ lib.concatLists dependencies));
- computedPropagatedImpureHostDeps =
- lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or [])
- (lib.concatLists propagatedDependencies));
- in
- {
+ // {
# A hack to make `nix-env -qa` and `nix search` ignore broken packages.
# TODO(@oxij): remove this assert when something like NixOS/nix#1771 gets merged into nix.
- name = assert validity.handled; name + lib.optionalString
- (stdenv.hostPlatform != stdenv.buildPlatform)
+ name = assert validity.handled; computedName + lib.optionalString
+ # Fixed-output derivations like source tarballs shouldn't get a host
+ # 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.
+ (stdenv.hostPlatform != stdenv.buildPlatform && !dontAddHostSuffix)
("-" + stdenv.hostPlatform.config);
builder = attrs.realBuilder or stdenv.shell;
args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)];
inherit stdenv;
- inherit (stdenv) system;
+
+ # The `system` attribute of a derivation has special meaning to Nix.
+ # Derivations set it to choose what sort of machine could be used to
+ # execute the build, The build platform entirely determines this,
+ # indeed more finely than Nix knows or cares about. The `system`
+ # attribute of `buildPlatfom` matches Nix's degree of specificity.
+ # exactly.
+ inherit (stdenv.buildPlatform) system;
+
userHook = config.stdenv.userHook or null;
__ignoreNulls = true;
+ inherit 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;
- depsHostBuild = lib.elemAt (lib.elemAt dependencies 1) 0;
+ depsHostHost = lib.elemAt (lib.elemAt dependencies 1) 0;
buildInputs = lib.elemAt (lib.elemAt dependencies 1) 1;
depsTargetTarget = lib.elemAt (lib.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;
- depsHostBuildPropagated = lib.elemAt (lib.elemAt propagatedDependencies 1) 0;
+ depsHostHostPropagated = lib.elemAt (lib.elemAt propagatedDependencies 1) 0;
propagatedBuildInputs = lib.elemAt (lib.elemAt propagatedDependencies 1) 1;
depsTargetTargetPropagated = lib.elemAt (lib.elemAt propagatedDependencies 2) 0;
@@ -179,6 +230,24 @@ rec {
++ optional (elem "host" configurePlatforms) "--host=${stdenv.hostPlatform.config}"
++ optional (elem "target" configurePlatforms) "--target=${stdenv.targetPlatform.config}";
+ inherit doCheck doInstallCheck;
+
+ inherit outputs;
+ } // lib.optionalAttrs (stdenv.hostPlatform != stdenv.buildPlatform) {
+ cmakeFlags =
+ (/**/ if lib.isString cmakeFlags then [cmakeFlags]
+ else if cmakeFlags == null then []
+ else cmakeFlags)
+ ++ lib.optional (stdenv.hostPlatform.uname.system != null) "-DCMAKE_SYSTEM_NAME=${stdenv.hostPlatform.uname.system}"
+ ++ lib.optional (stdenv.hostPlatform.uname.processor != null) "-DCMAKE_SYSTEM_PROCESSOR=${stdenv.hostPlatform.uname.processor}"
+ ++ lib.optional (stdenv.hostPlatform.uname.release != null) "-DCMAKE_SYSTEM_VERSION=${stdenv.hostPlatform.release}"
+ ++ lib.optional (stdenv.buildPlatform.uname.system != null) "-DCMAKE_HOST_SYSTEM_NAME=${stdenv.buildPlatform.uname.system}"
+ ++ lib.optional (stdenv.buildPlatform.uname.processor != null) "-DCMAKE_HOST_SYSTEM_PROCESSOR=${stdenv.buildPlatform.uname.processor}"
+ ++ lib.optional (stdenv.buildPlatform.uname.release != null) "-DCMAKE_HOST_SYSTEM_VERSION=${stdenv.buildPlatform.uname.release}";
+ } // lib.optionalAttrs (attrs.enableParallelBuilding or false) {
+ enableParallelChecking = attrs.enableParallelChecking or true;
+ } // lib.optionalAttrs (hardeningDisable != [] || hardeningEnable != []) {
+ NIX_HARDENING_ENABLE = enabledHardeningOptions;
} // lib.optionalAttrs (stdenv.buildPlatform.isDarwin) {
# TODO: remove lib.unique once nix has a list canonicalization primitive
__sandboxProfile =
@@ -193,23 +262,14 @@ rec {
"/bin/sh"
];
__propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps;
- } // lib.optionalAttrs (outputs' != [ "out" ]) {
- outputs = outputs';
- } // lib.optionalAttrs (attrs ? doCheck) {
- # TODO(@Ericson2314): Make unconditional / resolve #33599
- doCheck = doCheck && (stdenv.hostPlatform == stdenv.buildPlatform);
- } // lib.optionalAttrs (attrs ? doInstallCheck) {
- # TODO(@Ericson2314): Make unconditional / resolve #33599
- doInstallCheck = doInstallCheck && (stdenv.hostPlatform == stdenv.buildPlatform);
- });
+ };
validity = import ./check-meta.nix {
- inherit lib config meta derivationArg;
- mkDerivationArg = attrs;
+ inherit lib config meta;
# 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;
- };
+ inherit (stdenv) hostPlatform;
+ } 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
@@ -218,7 +278,7 @@ rec {
meta = {
# `name` above includes cross-compilation cruft (and is under assert),
# lets have a clean always accessible version here.
- inherit name;
+ name = computedName;
# If the packager hasn't specified `outputsToInstall`, choose a default,
# which is the name of `p.bin or p.out or p`;
@@ -228,10 +288,9 @@ rec {
# 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) )]
- ++ lib.optional (hasOutput "man") "man";
+ hasOutput = out: builtins.elem out outputs;
+ in [( lib.findFirst hasOutput null (["bin" "out"] ++ outputs) )]
+ ++ lib.optional (hasOutput "man") "man";
}
// attrs.meta or {}
# Fill `meta.position` to identify the source location of the package.