Merge pull request #266886 from Artturin/testimpactofinherit

stdenv: Test the perf impact of inheriting from lib

authored by Artturi and committed by GitHub d9b120b3 fc5560f9

+119 -82
+119 -82
pkgs/stdenv/generic/make-derivation.nix
··· 3 stdenv: 4 5 let 6 checkMeta = import ./check-meta.nix { 7 inherit lib config; 8 # Nix itself uses the `system` field of a derivation to decide where ··· 115 # Including it then would cause needless mass rebuilds. 116 # 117 # TODO(@Ericson2314): Make [ "build" "host" ] always the default / resolve #87909 118 - configurePlatforms ? lib.optionals 119 (stdenv.hostPlatform != stdenv.buildPlatform || config.configurePlatformsByDefault) 120 [ "build" "host" ] 121 ··· 168 # Policy on acceptable hash types in nixpkgs 169 assert attrs ? outputHash -> ( 170 let algo = 171 - attrs.outputHashAlgo or (lib.head (lib.splitString "-" attrs.outputHash)); 172 in 173 if algo == "md5" then 174 throw "Rejected insecure ${algo} hash '${attrs.outputHash}'" ··· 183 doInstallCheck' = doInstallCheck && stdenv.buildPlatform.canExecute stdenv.hostPlatform; 184 185 separateDebugInfo' = separateDebugInfo && stdenv.hostPlatform.isLinux; 186 - outputs' = outputs ++ lib.optional separateDebugInfo' "debug"; 187 188 # Turn a derivation into its outPath without a string context attached. 189 # See the comment at the usage site. 190 unsafeDerivationToUntrackedOutpath = drv: 191 - if lib.isDerivation drv 192 then builtins.unsafeDiscardStringContext drv.outPath 193 else drv; 194 ··· 198 ++ depsTargetTarget ++ depsTargetTargetPropagated) == 0; 199 dontAddHostSuffix = attrs ? outputHash && !noNonNativeDeps || !stdenv.hasCC; 200 201 - hardeningDisable' = if lib.any (x: x == "fortify") hardeningDisable 202 # disabling fortify implies fortify3 should also be disabled 203 - then lib.unique (hardeningDisable ++ [ "fortify3" ]) 204 else hardeningDisable; 205 supportedHardeningFlags = [ "fortify" "fortify3" "stackprotector" "pie" "pic" "strictoverflow" "format" "relro" "bindnow" ]; 206 # Musl-based platforms will keep "pie", other platforms will not. ··· 212 # - static armv7l, where compilation fails. 213 !(stdenv.hostPlatform.isAarch && stdenv.hostPlatform.isStatic) 214 then supportedHardeningFlags 215 - else lib.remove "pie" supportedHardeningFlags; 216 enabledHardeningOptions = 217 if builtins.elem "all" hardeningDisable' 218 then [] 219 - else lib.subtractLists hardeningDisable' (defaultHardeningFlags ++ hardeningEnable); 220 # hardeningDisable additionally supports "all". 221 - erroneousHardeningFlags = lib.subtractLists supportedHardeningFlags (hardeningEnable ++ lib.remove "all" hardeningDisable); 222 223 checkDependencyList = checkDependencyList' []; 224 - checkDependencyList' = positions: name: deps: lib.flip lib.imap1 deps (index: dep: 225 - if lib.isDerivation dep || dep == null || builtins.isString dep || builtins.isPath dep then dep 226 - else if lib.isList dep then checkDependencyList' ([index] ++ positions) name dep 227 - 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}"); 228 in if builtins.length erroneousHardeningFlags != 0 229 then abort ("mkDerivation was called with unsupported hardening flags: " + lib.generators.toPretty {} { 230 inherit erroneousHardeningFlags hardeningDisable hardeningEnable supportedHardeningFlags; ··· 233 doCheck = doCheck'; 234 doInstallCheck = doInstallCheck'; 235 buildInputs' = buildInputs 236 - ++ lib.optionals doCheck checkInputs 237 - ++ lib.optionals doInstallCheck installCheckInputs; 238 nativeBuildInputs' = nativeBuildInputs 239 - ++ lib.optional separateDebugInfo' ../../build-support/setup-hooks/separate-debug-info.sh 240 - ++ lib.optional stdenv.hostPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh 241 - ++ lib.optionals doCheck nativeCheckInputs 242 - ++ lib.optionals doInstallCheck nativeInstallCheckInputs; 243 244 outputs = outputs'; 245 246 references = nativeBuildInputs ++ buildInputs 247 ++ propagatedNativeBuildInputs ++ propagatedBuildInputs; 248 249 - dependencies = map (map lib.chooseDevOutputs) [ 250 [ 251 (map (drv: drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuild" depsBuildBuild)) 252 (map (drv: drv.__spliced.buildHost or drv) (checkDependencyList "nativeBuildInputs" nativeBuildInputs')) ··· 260 (map (drv: drv.__spliced.targetTarget or drv) (checkDependencyList "depsTargetTarget" depsTargetTarget)) 261 ] 262 ]; 263 - propagatedDependencies = map (map lib.chooseDevOutputs) [ 264 [ 265 (map (drv: drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuildPropagated" depsBuildBuildPropagated)) 266 (map (drv: drv.__spliced.buildHost or drv) (checkDependencyList "propagatedNativeBuildInputs" propagatedNativeBuildInputs)) ··· 276 ]; 277 278 computedSandboxProfile = 279 - lib.concatMap (input: input.__propagatedSandboxProfile or []) 280 (stdenv.extraNativeBuildInputs 281 ++ stdenv.extraBuildInputs 282 - ++ lib.concatLists dependencies); 283 284 computedPropagatedSandboxProfile = 285 - lib.concatMap (input: input.__propagatedSandboxProfile or []) 286 - (lib.concatLists propagatedDependencies); 287 288 computedImpureHostDeps = 289 - lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) 290 (stdenv.extraNativeBuildInputs 291 ++ stdenv.extraBuildInputs 292 - ++ lib.concatLists dependencies)); 293 294 computedPropagatedImpureHostDeps = 295 - lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) 296 - (lib.concatLists propagatedDependencies)); 297 298 - envIsExportable = lib.isAttrs env && !lib.isDerivation env; 299 300 derivationArg = 301 (removeAttrs attrs ··· 306 "__darwinAllowLocalNetworking" 307 "__impureHostDeps" "__propagatedImpureHostDeps" 308 "sandboxProfile" "propagatedSandboxProfile"] 309 - ++ lib.optional (__structuredAttrs || envIsExportable) "env")) 310 - // (lib.optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) { 311 name = 312 let 313 # Indicate the host platform of the derivation if cross compiling. ··· 315 # suffix. But we have some weird ones with run-time deps that are 316 # just used for their side-affects. Those might as well since the 317 # hash can't be the same. See #32986. 318 - hostSuffix = lib.optionalString 319 (stdenv.hostPlatform != stdenv.buildPlatform && !dontAddHostSuffix) 320 "-${stdenv.hostPlatform.config}"; 321 ··· 324 # nix and nixStatic. This should be also achieved by moving the 325 # hostSuffix before the version, so we could contemplate removing 326 # it again. 327 - staticMarker = lib.optionalString stdenv.hostPlatform.isStatic "-static"; 328 in 329 lib.strings.sanitizeDerivationName ( 330 if attrs ? name 331 then attrs.name + hostSuffix 332 else 333 # we cannot coerce null to a string below 334 - assert lib.assertMsg (attrs ? version && attrs.version != null) "The ‘version’ attribute cannot be null."; 335 "${attrs.pname}${staticMarker}${hostSuffix}-${attrs.version}" 336 ); 337 - }) // lib.optionalAttrs __structuredAttrs { env = checkedEnv; } // { 338 builder = attrs.realBuilder or stdenv.shell; 339 args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)]; 340 inherit stdenv; ··· 351 __ignoreNulls = true; 352 inherit __structuredAttrs strictDeps; 353 354 - depsBuildBuild = lib.elemAt (lib.elemAt dependencies 0) 0; 355 - nativeBuildInputs = lib.elemAt (lib.elemAt dependencies 0) 1; 356 - depsBuildTarget = lib.elemAt (lib.elemAt dependencies 0) 2; 357 - depsHostHost = lib.elemAt (lib.elemAt dependencies 1) 0; 358 - buildInputs = lib.elemAt (lib.elemAt dependencies 1) 1; 359 - depsTargetTarget = lib.elemAt (lib.elemAt dependencies 2) 0; 360 361 - depsBuildBuildPropagated = lib.elemAt (lib.elemAt propagatedDependencies 0) 0; 362 - propagatedNativeBuildInputs = lib.elemAt (lib.elemAt propagatedDependencies 0) 1; 363 - depsBuildTargetPropagated = lib.elemAt (lib.elemAt propagatedDependencies 0) 2; 364 - depsHostHostPropagated = lib.elemAt (lib.elemAt propagatedDependencies 1) 0; 365 - propagatedBuildInputs = lib.elemAt (lib.elemAt propagatedDependencies 1) 1; 366 - depsTargetTargetPropagated = lib.elemAt (lib.elemAt propagatedDependencies 2) 0; 367 368 # This parameter is sometimes a string, sometimes null, and sometimes a list, yuck 369 - configureFlags = let inherit (lib) optional elem; in 370 configureFlags 371 ++ optional (elem "build" configurePlatforms) "--build=${stdenv.buildPlatform.config}" 372 ++ optional (elem "host" configurePlatforms) "--host=${stdenv.hostPlatform.config}" ··· 374 375 cmakeFlags = 376 cmakeFlags 377 - ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) ([ 378 - "-DCMAKE_SYSTEM_NAME=${lib.findFirst lib.isString "Generic" (lib.optional (!stdenv.hostPlatform.isRedox) stdenv.hostPlatform.uname.system)}" 379 - ] ++ lib.optionals (stdenv.hostPlatform.uname.processor != null) [ 380 "-DCMAKE_SYSTEM_PROCESSOR=${stdenv.hostPlatform.uname.processor}" 381 - ] ++ lib.optionals (stdenv.hostPlatform.uname.release != null) [ 382 "-DCMAKE_SYSTEM_VERSION=${stdenv.hostPlatform.uname.release}" 383 - ] ++ lib.optionals (stdenv.hostPlatform.isDarwin) [ 384 "-DCMAKE_OSX_ARCHITECTURES=${stdenv.hostPlatform.darwinArch}" 385 - ] ++ lib.optionals (stdenv.buildPlatform.uname.system != null) [ 386 "-DCMAKE_HOST_SYSTEM_NAME=${stdenv.buildPlatform.uname.system}" 387 - ] ++ lib.optionals (stdenv.buildPlatform.uname.processor != null) [ 388 "-DCMAKE_HOST_SYSTEM_PROCESSOR=${stdenv.buildPlatform.uname.processor}" 389 - ] ++ lib.optionals (stdenv.buildPlatform.uname.release != null) [ 390 "-DCMAKE_HOST_SYSTEM_VERSION=${stdenv.buildPlatform.uname.release}" 391 - ] ++ lib.optionals (stdenv.buildPlatform.canExecute stdenv.hostPlatform) [ 392 "-DCMAKE_CROSSCOMPILING_EMULATOR=env" 393 ]); 394 ··· 402 403 crossFile = builtins.toFile "cross-file.conf" '' 404 [properties] 405 - needs_exe_wrapper = ${lib.boolToString (!stdenv.buildPlatform.canExecute stdenv.hostPlatform)} 406 407 [host_machine] 408 system = '${stdenv.targetPlatform.parsed.kernel.name}' ··· 413 [binaries] 414 llvm-config = 'llvm-config-native' 415 ''; 416 - crossFlags = lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ "--cross-file=${crossFile}" ]; 417 in crossFlags ++ mesonFlags; 418 419 inherit patches; ··· 421 inherit doCheck doInstallCheck; 422 423 inherit outputs; 424 - } // lib.optionalAttrs (__contentAddressed) { 425 inherit __contentAddressed; 426 # Provide default values for outputHashMode and outputHashAlgo because 427 # most people won't care about these anyways 428 outputHashAlgo = attrs.outputHashAlgo or "sha256"; 429 outputHashMode = attrs.outputHashMode or "recursive"; 430 - } // lib.optionalAttrs (enableParallelBuilding) { 431 inherit enableParallelBuilding; 432 enableParallelChecking = attrs.enableParallelChecking or true; 433 enableParallelInstalling = attrs.enableParallelInstalling or true; 434 - } // lib.optionalAttrs (hardeningDisable != [] || hardeningEnable != [] || stdenv.hostPlatform.isMusl) { 435 NIX_HARDENING_ENABLE = enabledHardeningOptions; 436 - } // lib.optionalAttrs (stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform ? gcc.arch) { 437 requiredSystemFeatures = attrs.requiredSystemFeatures or [] ++ [ "gccarch-${stdenv.hostPlatform.gcc.arch}" ]; 438 - } // lib.optionalAttrs (stdenv.buildPlatform.isDarwin) { 439 inherit __darwinAllowLocalNetworking; 440 - # TODO: remove lib.unique once nix has a list canonicalization primitive 441 __sandboxProfile = 442 let profiles = [ stdenv.extraSandboxProfile ] ++ computedSandboxProfile ++ computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile sandboxProfile ]; 443 - final = lib.concatStringsSep "\n" (lib.filter (x: x != "") (lib.unique profiles)); 444 in final; 445 - __propagatedSandboxProfile = lib.unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]); 446 __impureHostDeps = computedImpureHostDeps ++ computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ++ __impureHostDeps ++ stdenv.__extraImpureHostDeps ++ [ 447 "/dev/zero" 448 "/dev/random" ··· 469 # to be built eventually, we would still like to get the error early and without 470 # having to wait while nix builds a derivation that might not be used. 471 # See also https://github.com/NixOS/nix/issues/4629 472 - lib.optionalAttrs (attrs ? disallowedReferences) { 473 disallowedReferences = 474 map unsafeDerivationToUntrackedOutpath attrs.disallowedReferences; 475 } // 476 - lib.optionalAttrs (attrs ? disallowedRequisites) { 477 disallowedRequisites = 478 map unsafeDerivationToUntrackedOutpath attrs.disallowedRequisites; 479 } // 480 - lib.optionalAttrs (attrs ? allowedReferences) { 481 allowedReferences = 482 - lib.mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedReferences; 483 } // 484 - lib.optionalAttrs (attrs ? allowedRequisites) { 485 allowedRequisites = 486 - lib.mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedRequisites; 487 }; 488 489 meta = checkMeta.commonMeta { inherit validity attrs pos references; }; ··· 491 492 checkedEnv = 493 let 494 - overlappingNames = lib.attrNames (builtins.intersectAttrs env derivationArg); 495 in 496 - assert lib.assertMsg envIsExportable 497 "When using structured attributes, `env` must be an attribute set of environment variables."; 498 - assert lib.assertMsg (overlappingNames == [ ]) 499 - "The ‘env’ attribute set cannot contain any attributes passed to derivation. The following attributes are overlapping: ${lib.concatStringsSep ", " overlappingNames}"; 500 - lib.mapAttrs 501 - (n: v: assert lib.assertMsg (lib.isString v || lib.isBool v || lib.isInt v || lib.isDerivation v) 502 "The ‘env’ attribute set can only contain derivation, string, boolean or integer attributes. The ‘${n}’ attribute is of type ${builtins.typeOf v}."; v) 503 env; 504 505 in 506 507 - lib.extendDerivation 508 validity.handled 509 ({ 510 # A derivation that always builds successfully and whose runtime ··· 553 # should be made available to Nix expressions using the 554 # derivation (e.g., in assertions). 555 passthru) 556 - (derivation (derivationArg // lib.optionalAttrs envIsExportable checkedEnv)); 557 558 in 559 fnOrAttrs:
··· 3 stdenv: 4 5 let 6 + # Lib attributes are inherited to the lexical scope for performance reasons. 7 + inherit (lib) 8 + any 9 + assertMsg 10 + attrNames 11 + boolToString 12 + chooseDevOutputs 13 + concatLists 14 + concatMap 15 + concatMapStrings 16 + concatStringsSep 17 + elem 18 + elemAt 19 + extendDerivation 20 + filter 21 + findFirst 22 + flip 23 + head 24 + imap1 25 + isAttrs 26 + isBool 27 + isDerivation 28 + isInt 29 + isList 30 + isString 31 + mapAttrs 32 + mapNullable 33 + optional 34 + optionalAttrs 35 + optionalString 36 + optionals 37 + remove 38 + splitString 39 + subtractLists 40 + unique 41 + ; 42 + 43 checkMeta = import ./check-meta.nix { 44 inherit lib config; 45 # Nix itself uses the `system` field of a derivation to decide where ··· 152 # Including it then would cause needless mass rebuilds. 153 # 154 # TODO(@Ericson2314): Make [ "build" "host" ] always the default / resolve #87909 155 + configurePlatforms ? optionals 156 (stdenv.hostPlatform != stdenv.buildPlatform || config.configurePlatformsByDefault) 157 [ "build" "host" ] 158 ··· 205 # Policy on acceptable hash types in nixpkgs 206 assert attrs ? outputHash -> ( 207 let algo = 208 + attrs.outputHashAlgo or (head (splitString "-" attrs.outputHash)); 209 in 210 if algo == "md5" then 211 throw "Rejected insecure ${algo} hash '${attrs.outputHash}'" ··· 220 doInstallCheck' = doInstallCheck && stdenv.buildPlatform.canExecute stdenv.hostPlatform; 221 222 separateDebugInfo' = separateDebugInfo && stdenv.hostPlatform.isLinux; 223 + outputs' = outputs ++ optional separateDebugInfo' "debug"; 224 225 # Turn a derivation into its outPath without a string context attached. 226 # See the comment at the usage site. 227 unsafeDerivationToUntrackedOutpath = drv: 228 + if isDerivation drv 229 then builtins.unsafeDiscardStringContext drv.outPath 230 else drv; 231 ··· 235 ++ depsTargetTarget ++ depsTargetTargetPropagated) == 0; 236 dontAddHostSuffix = attrs ? outputHash && !noNonNativeDeps || !stdenv.hasCC; 237 238 + hardeningDisable' = if any (x: x == "fortify") hardeningDisable 239 # disabling fortify implies fortify3 should also be disabled 240 + then unique (hardeningDisable ++ [ "fortify3" ]) 241 else hardeningDisable; 242 supportedHardeningFlags = [ "fortify" "fortify3" "stackprotector" "pie" "pic" "strictoverflow" "format" "relro" "bindnow" ]; 243 # Musl-based platforms will keep "pie", other platforms will not. ··· 249 # - static armv7l, where compilation fails. 250 !(stdenv.hostPlatform.isAarch && stdenv.hostPlatform.isStatic) 251 then supportedHardeningFlags 252 + else remove "pie" supportedHardeningFlags; 253 enabledHardeningOptions = 254 if builtins.elem "all" hardeningDisable' 255 then [] 256 + else subtractLists hardeningDisable' (defaultHardeningFlags ++ hardeningEnable); 257 # hardeningDisable additionally supports "all". 258 + erroneousHardeningFlags = subtractLists supportedHardeningFlags (hardeningEnable ++ remove "all" hardeningDisable); 259 260 checkDependencyList = checkDependencyList' []; 261 + checkDependencyList' = positions: name: deps: flip imap1 deps (index: dep: 262 + if isDerivation dep || dep == null || builtins.isString dep || builtins.isPath dep then dep 263 + else if isList dep then checkDependencyList' ([index] ++ positions) name dep 264 + else throw "Dependency is not of a valid type: ${concatMapStrings (ix: "element ${toString ix} of ") ([index] ++ positions)}${name} for ${attrs.name or attrs.pname}"); 265 in if builtins.length erroneousHardeningFlags != 0 266 then abort ("mkDerivation was called with unsupported hardening flags: " + lib.generators.toPretty {} { 267 inherit erroneousHardeningFlags hardeningDisable hardeningEnable supportedHardeningFlags; ··· 270 doCheck = doCheck'; 271 doInstallCheck = doInstallCheck'; 272 buildInputs' = buildInputs 273 + ++ optionals doCheck checkInputs 274 + ++ optionals doInstallCheck installCheckInputs; 275 nativeBuildInputs' = nativeBuildInputs 276 + ++ optional separateDebugInfo' ../../build-support/setup-hooks/separate-debug-info.sh 277 + ++ optional stdenv.hostPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh 278 + ++ optionals doCheck nativeCheckInputs 279 + ++ optionals doInstallCheck nativeInstallCheckInputs; 280 281 outputs = outputs'; 282 283 references = nativeBuildInputs ++ buildInputs 284 ++ propagatedNativeBuildInputs ++ propagatedBuildInputs; 285 286 + dependencies = map (map chooseDevOutputs) [ 287 [ 288 (map (drv: drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuild" depsBuildBuild)) 289 (map (drv: drv.__spliced.buildHost or drv) (checkDependencyList "nativeBuildInputs" nativeBuildInputs')) ··· 297 (map (drv: drv.__spliced.targetTarget or drv) (checkDependencyList "depsTargetTarget" depsTargetTarget)) 298 ] 299 ]; 300 + propagatedDependencies = map (map chooseDevOutputs) [ 301 [ 302 (map (drv: drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuildPropagated" depsBuildBuildPropagated)) 303 (map (drv: drv.__spliced.buildHost or drv) (checkDependencyList "propagatedNativeBuildInputs" propagatedNativeBuildInputs)) ··· 313 ]; 314 315 computedSandboxProfile = 316 + concatMap (input: input.__propagatedSandboxProfile or []) 317 (stdenv.extraNativeBuildInputs 318 ++ stdenv.extraBuildInputs 319 + ++ concatLists dependencies); 320 321 computedPropagatedSandboxProfile = 322 + concatMap (input: input.__propagatedSandboxProfile or []) 323 + (concatLists propagatedDependencies); 324 325 computedImpureHostDeps = 326 + unique (concatMap (input: input.__propagatedImpureHostDeps or []) 327 (stdenv.extraNativeBuildInputs 328 ++ stdenv.extraBuildInputs 329 + ++ concatLists dependencies)); 330 331 computedPropagatedImpureHostDeps = 332 + unique (concatMap (input: input.__propagatedImpureHostDeps or []) 333 + (concatLists propagatedDependencies)); 334 335 + envIsExportable = isAttrs env && !isDerivation env; 336 337 derivationArg = 338 (removeAttrs attrs ··· 343 "__darwinAllowLocalNetworking" 344 "__impureHostDeps" "__propagatedImpureHostDeps" 345 "sandboxProfile" "propagatedSandboxProfile"] 346 + ++ optional (__structuredAttrs || envIsExportable) "env")) 347 + // (optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) { 348 name = 349 let 350 # Indicate the host platform of the derivation if cross compiling. ··· 352 # suffix. But we have some weird ones with run-time deps that are 353 # just used for their side-affects. Those might as well since the 354 # hash can't be the same. See #32986. 355 + hostSuffix = optionalString 356 (stdenv.hostPlatform != stdenv.buildPlatform && !dontAddHostSuffix) 357 "-${stdenv.hostPlatform.config}"; 358 ··· 361 # nix and nixStatic. This should be also achieved by moving the 362 # hostSuffix before the version, so we could contemplate removing 363 # it again. 364 + staticMarker = optionalString stdenv.hostPlatform.isStatic "-static"; 365 in 366 lib.strings.sanitizeDerivationName ( 367 if attrs ? name 368 then attrs.name + hostSuffix 369 else 370 # we cannot coerce null to a string below 371 + assert assertMsg (attrs ? version && attrs.version != null) "The ‘version’ attribute cannot be null."; 372 "${attrs.pname}${staticMarker}${hostSuffix}-${attrs.version}" 373 ); 374 + }) // optionalAttrs __structuredAttrs { env = checkedEnv; } // { 375 builder = attrs.realBuilder or stdenv.shell; 376 args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)]; 377 inherit stdenv; ··· 388 __ignoreNulls = true; 389 inherit __structuredAttrs strictDeps; 390 391 + depsBuildBuild = elemAt (elemAt dependencies 0) 0; 392 + nativeBuildInputs = elemAt (elemAt dependencies 0) 1; 393 + depsBuildTarget = elemAt (elemAt dependencies 0) 2; 394 + depsHostHost = elemAt (elemAt dependencies 1) 0; 395 + buildInputs = elemAt (elemAt dependencies 1) 1; 396 + depsTargetTarget = elemAt (elemAt dependencies 2) 0; 397 398 + depsBuildBuildPropagated = elemAt (elemAt propagatedDependencies 0) 0; 399 + propagatedNativeBuildInputs = elemAt (elemAt propagatedDependencies 0) 1; 400 + depsBuildTargetPropagated = elemAt (elemAt propagatedDependencies 0) 2; 401 + depsHostHostPropagated = elemAt (elemAt propagatedDependencies 1) 0; 402 + propagatedBuildInputs = elemAt (elemAt propagatedDependencies 1) 1; 403 + depsTargetTargetPropagated = elemAt (elemAt propagatedDependencies 2) 0; 404 405 # This parameter is sometimes a string, sometimes null, and sometimes a list, yuck 406 + configureFlags = 407 configureFlags 408 ++ optional (elem "build" configurePlatforms) "--build=${stdenv.buildPlatform.config}" 409 ++ optional (elem "host" configurePlatforms) "--host=${stdenv.hostPlatform.config}" ··· 411 412 cmakeFlags = 413 cmakeFlags 414 + ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) ([ 415 + "-DCMAKE_SYSTEM_NAME=${findFirst isString "Generic" (optional (!stdenv.hostPlatform.isRedox) stdenv.hostPlatform.uname.system)}" 416 + ] ++ optionals (stdenv.hostPlatform.uname.processor != null) [ 417 "-DCMAKE_SYSTEM_PROCESSOR=${stdenv.hostPlatform.uname.processor}" 418 + ] ++ optionals (stdenv.hostPlatform.uname.release != null) [ 419 "-DCMAKE_SYSTEM_VERSION=${stdenv.hostPlatform.uname.release}" 420 + ] ++ optionals (stdenv.hostPlatform.isDarwin) [ 421 "-DCMAKE_OSX_ARCHITECTURES=${stdenv.hostPlatform.darwinArch}" 422 + ] ++ optionals (stdenv.buildPlatform.uname.system != null) [ 423 "-DCMAKE_HOST_SYSTEM_NAME=${stdenv.buildPlatform.uname.system}" 424 + ] ++ optionals (stdenv.buildPlatform.uname.processor != null) [ 425 "-DCMAKE_HOST_SYSTEM_PROCESSOR=${stdenv.buildPlatform.uname.processor}" 426 + ] ++ optionals (stdenv.buildPlatform.uname.release != null) [ 427 "-DCMAKE_HOST_SYSTEM_VERSION=${stdenv.buildPlatform.uname.release}" 428 + ] ++ optionals (stdenv.buildPlatform.canExecute stdenv.hostPlatform) [ 429 "-DCMAKE_CROSSCOMPILING_EMULATOR=env" 430 ]); 431 ··· 439 440 crossFile = builtins.toFile "cross-file.conf" '' 441 [properties] 442 + needs_exe_wrapper = ${boolToString (!stdenv.buildPlatform.canExecute stdenv.hostPlatform)} 443 444 [host_machine] 445 system = '${stdenv.targetPlatform.parsed.kernel.name}' ··· 450 [binaries] 451 llvm-config = 'llvm-config-native' 452 ''; 453 + crossFlags = optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ "--cross-file=${crossFile}" ]; 454 in crossFlags ++ mesonFlags; 455 456 inherit patches; ··· 458 inherit doCheck doInstallCheck; 459 460 inherit outputs; 461 + } // optionalAttrs (__contentAddressed) { 462 inherit __contentAddressed; 463 # Provide default values for outputHashMode and outputHashAlgo because 464 # most people won't care about these anyways 465 outputHashAlgo = attrs.outputHashAlgo or "sha256"; 466 outputHashMode = attrs.outputHashMode or "recursive"; 467 + } // optionalAttrs (enableParallelBuilding) { 468 inherit enableParallelBuilding; 469 enableParallelChecking = attrs.enableParallelChecking or true; 470 enableParallelInstalling = attrs.enableParallelInstalling or true; 471 + } // optionalAttrs (hardeningDisable != [] || hardeningEnable != [] || stdenv.hostPlatform.isMusl) { 472 NIX_HARDENING_ENABLE = enabledHardeningOptions; 473 + } // optionalAttrs (stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform ? gcc.arch) { 474 requiredSystemFeatures = attrs.requiredSystemFeatures or [] ++ [ "gccarch-${stdenv.hostPlatform.gcc.arch}" ]; 475 + } // optionalAttrs (stdenv.buildPlatform.isDarwin) { 476 inherit __darwinAllowLocalNetworking; 477 + # TODO: remove `unique` once nix has a list canonicalization primitive 478 __sandboxProfile = 479 let profiles = [ stdenv.extraSandboxProfile ] ++ computedSandboxProfile ++ computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile sandboxProfile ]; 480 + final = concatStringsSep "\n" (filter (x: x != "") (unique profiles)); 481 in final; 482 + __propagatedSandboxProfile = unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]); 483 __impureHostDeps = computedImpureHostDeps ++ computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ++ __impureHostDeps ++ stdenv.__extraImpureHostDeps ++ [ 484 "/dev/zero" 485 "/dev/random" ··· 506 # to be built eventually, we would still like to get the error early and without 507 # having to wait while nix builds a derivation that might not be used. 508 # See also https://github.com/NixOS/nix/issues/4629 509 + optionalAttrs (attrs ? disallowedReferences) { 510 disallowedReferences = 511 map unsafeDerivationToUntrackedOutpath attrs.disallowedReferences; 512 } // 513 + optionalAttrs (attrs ? disallowedRequisites) { 514 disallowedRequisites = 515 map unsafeDerivationToUntrackedOutpath attrs.disallowedRequisites; 516 } // 517 + optionalAttrs (attrs ? allowedReferences) { 518 allowedReferences = 519 + mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedReferences; 520 } // 521 + optionalAttrs (attrs ? allowedRequisites) { 522 allowedRequisites = 523 + mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedRequisites; 524 }; 525 526 meta = checkMeta.commonMeta { inherit validity attrs pos references; }; ··· 528 529 checkedEnv = 530 let 531 + overlappingNames = attrNames (builtins.intersectAttrs env derivationArg); 532 in 533 + assert assertMsg envIsExportable 534 "When using structured attributes, `env` must be an attribute set of environment variables."; 535 + assert assertMsg (overlappingNames == [ ]) 536 + "The ‘env’ attribute set cannot contain any attributes passed to derivation. The following attributes are overlapping: ${concatStringsSep ", " overlappingNames}"; 537 + mapAttrs 538 + (n: v: assert assertMsg (isString v || isBool v || isInt v || isDerivation v) 539 "The ‘env’ attribute set can only contain derivation, string, boolean or integer attributes. The ‘${n}’ attribute is of type ${builtins.typeOf v}."; v) 540 env; 541 542 in 543 544 + extendDerivation 545 validity.handled 546 ({ 547 # A derivation that always builds successfully and whose runtime ··· 590 # should be made available to Nix expressions using the 591 # derivation (e.g., in assertions). 592 passthru) 593 + (derivation (derivationArg // optionalAttrs envIsExportable checkedEnv)); 594 595 in 596 fnOrAttrs: