Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at python-updates 893 lines 36 kB view raw
1{ lib, config }: 2 3stdenv: 4 5let 6 # Lib attributes are inherited to the lexical scope for performance reasons. 7 inherit (lib) 8 any 9 assertMsg 10 attrNames 11 boolToString 12 concatLists 13 concatMap 14 concatMapStrings 15 concatStringsSep 16 elem 17 elemAt 18 extendDerivation 19 filter 20 findFirst 21 getDev 22 head 23 imap1 24 isAttrs 25 isBool 26 isDerivation 27 isInt 28 isList 29 isString 30 mapAttrs 31 mapNullable 32 optional 33 optionalAttrs 34 optionalString 35 optionals 36 pipe 37 remove 38 splitString 39 subtractLists 40 toFunction 41 unique 42 zipAttrsWith 43 ; 44 45 inherit (import ../../build-support/lib/cmake.nix { inherit lib stdenv; }) makeCMakeFlags; 46 inherit (import ../../build-support/lib/meson.nix { inherit lib stdenv; }) makeMesonFlags; 47 48 /** 49 This function creates a derivation, and returns it in the form of a [package attribute set](https://nix.dev/manual/nix/latest/glossary#package-attribute-set) 50 that refers to the derivation's outputs. 51 52 `mkDerivation` takes many argument attributes, most of which affect the derivation environment, 53 but [`meta`](#chap-meta) and [`passthru`](#var-stdenv-passthru) only directly affect package attributes. 54 55 The `mkDerivation` argument attributes can be made to refer to one another by passing a function to `mkDerivation`. 56 See [Fixed-point argument of `mkDerivation`](#mkderivation-recursive-attributes). 57 58 Reference documentation see: https://nixos.org/manual/nixpkgs/stable/#sec-using-stdenv 59 60 :::{.note} 61 This is used as the fundamental building block of most other functions in Nixpkgs for creating derivations. 62 63 Most arguments are also passed through to the underlying call of [`builtins.derivation`](https://nixos.org/manual/nix/stable/language/derivations). 64 ::: 65 */ 66 mkDerivation = fnOrAttrs: makeDerivationExtensible (toFunction fnOrAttrs); 67 68 checkMeta = import ./check-meta.nix { 69 inherit lib config; 70 # Nix itself uses the `system` field of a derivation to decide where 71 # to build it. This is a bit confusing for cross compilation. 72 inherit (stdenv) hostPlatform; 73 }; 74 75 # Based off lib.makeExtensible, with modifications: 76 makeDerivationExtensible = 77 rattrs: 78 let 79 # NOTE: The following is a hint that will be printed by the Nix cli when 80 # encountering an infinite recursion. It must not be formatted into 81 # separate lines, because Nix would only show the last line of the comment. 82 83 # An infinite recursion here can be caused by having the attribute names of expression `e` in `.overrideAttrs(finalAttrs: previousAttrs: e)` depend on `finalAttrs`. Only the attribute values of `e` can depend on `finalAttrs`. 84 args = rattrs (args // { inherit finalPackage overrideAttrs; }); 85 # ^^^^ 86 87 overrideAttrs = 88 f0: 89 let 90 extends' = 91 overlay: f: 92 ( 93 final: 94 let 95 prev = f final; 96 thisOverlay = overlay final prev; 97 warnForBadVersionOverride = ( 98 thisOverlay ? version 99 && prev ? version 100 # We could check that the version is actually distinct, but that 101 # would probably just delay the inevitable, or preserve tech debt. 102 # && prev.version != thisOverlay.version 103 && !(thisOverlay ? src) 104 && !(thisOverlay.__intentionallyOverridingVersion or false) 105 ); 106 pname = args.pname or "<unknown name>"; 107 version = args.version or "<unknown version>"; 108 pos = builtins.unsafeGetAttrPos "version" thisOverlay; 109 in 110 lib.warnIf warnForBadVersionOverride '' 111 ${ 112 args.name or "${pname}-${version}" 113 } was overridden with `version` but not `src` at ${pos.file or "<unknown file>"}:${ 114 builtins.toString pos.line or "<unknown line>" 115 }:${builtins.toString pos.column or "<unknown column>"}. 116 117 This is most likely not what you want. In order to properly change the version of a package, override 118 both the `version` and `src` attributes: 119 120 hello.overrideAttrs (oldAttrs: rec { 121 version = "1.0.0"; 122 src = pkgs.fetchurl { 123 url = "mirror://gnu/hello/hello-''${version}.tar.gz"; 124 hash = "..."; 125 }; 126 }) 127 128 (To silence this warning, set `__intentionallyOverridingVersion = true` in your `overrideAttrs` call.) 129 '' (prev // (builtins.removeAttrs thisOverlay [ "__intentionallyOverridingVersion" ])) 130 ); 131 in 132 makeDerivationExtensible (extends' (lib.toExtension f0) rattrs); 133 134 finalPackage = mkDerivationSimple overrideAttrs args; 135 136 in 137 finalPackage; 138 139 knownHardeningFlags = [ 140 "bindnow" 141 "format" 142 "fortify" 143 "fortify3" 144 "strictflexarrays1" 145 "strictflexarrays3" 146 "shadowstack" 147 "nostrictaliasing" 148 "pacret" 149 "pic" 150 "pie" 151 "relro" 152 "stackprotector" 153 "stackclashprotection" 154 "strictoverflow" 155 "trivialautovarinit" 156 "zerocallusedregs" 157 ]; 158 159 removedOrReplacedAttrNames = [ 160 "checkInputs" 161 "installCheckInputs" 162 "nativeCheckInputs" 163 "nativeInstallCheckInputs" 164 "__contentAddressed" 165 "__darwinAllowLocalNetworking" 166 "__impureHostDeps" 167 "__propagatedImpureHostDeps" 168 "sandboxProfile" 169 "propagatedSandboxProfile" 170 "disallowedReferences" 171 "disallowedRequisites" 172 "allowedReferences" 173 "allowedRequisites" 174 ]; 175 176 # Turn a derivation into its outPath without a string context attached. 177 # See the comment at the usage site. 178 unsafeDerivationToUntrackedOutpath = 179 drv: 180 if isDerivation drv && (!drv.__contentAddressed or false) then 181 builtins.unsafeDiscardStringContext drv.outPath 182 else 183 drv; 184 185 makeOutputChecks = 186 attrs: 187 # If we use derivations directly here, they end up as build-time dependencies. 188 # This is especially problematic in the case of disallowed*, since the disallowed 189 # derivations will be built by nix as build-time dependencies, while those 190 # derivations might take a very long time to build, or might not even build 191 # successfully on the platform used. 192 # We can improve on this situation by instead passing only the outPath, 193 # without an attached string context, to nix. The out path will be a placeholder 194 # which will be replaced by the actual out path if the derivation in question 195 # is part of the final closure (and thus needs to be built). If it is not 196 # part of the final closure, then the placeholder will be passed along, 197 # but in that case we know for a fact that the derivation is not part of the closure. 198 # This means that passing the out path to nix does the right thing in either 199 # case, both for disallowed and allowed references/requisites, and we won't 200 # build the derivation if it wouldn't be part of the closure, saving time and resources. 201 # While the problem is less severe for allowed*, since we want the derivation 202 # to be built eventually, we would still like to get the error early and without 203 # having to wait while nix builds a derivation that might not be used. 204 # See also https://github.com/NixOS/nix/issues/4629 205 { 206 ${if (attrs ? disallowedReferences) then "disallowedReferences" else null} = 207 map unsafeDerivationToUntrackedOutpath attrs.disallowedReferences; 208 ${if (attrs ? disallowedRequisites) then "disallowedRequisites" else null} = 209 map unsafeDerivationToUntrackedOutpath attrs.disallowedRequisites; 210 ${if (attrs ? allowedReferences) then "allowedReferences" else null} = 211 mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedReferences; 212 ${if (attrs ? allowedRequisites) then "allowedRequisites" else null} = 213 mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedRequisites; 214 }; 215 216 makeDerivationArgument = 217 218 # `makeDerivationArgument` is responsible for the `mkDerivation` arguments that 219 # affect the actual derivation, excluding a few behaviors that are not 220 # essential, and specific to `mkDerivation`: `env`, `cmakeFlags`, `mesonFlags`. 221 # 222 # See also: 223 # 224 # * https://nixos.org/nixpkgs/manual/#sec-using-stdenv 225 # Details on how to use this mkDerivation function 226 # 227 # * https://nixos.org/manual/nix/stable/expressions/derivations.html#derivations 228 # Explanation about derivations in general 229 { 230 231 # These types of dependencies are all exhaustively documented in 232 # the "Specifying Dependencies" section of the "Standard 233 # Environment" chapter of the Nixpkgs manual. 234 235 # TODO(@Ericson2314): Stop using legacy dep attribute names 236 237 # host offset -> target offset 238 depsBuildBuild ? [ ], # -1 -> -1 239 depsBuildBuildPropagated ? [ ], # -1 -> -1 240 nativeBuildInputs ? [ ], # -1 -> 0 N.B. Legacy name 241 propagatedNativeBuildInputs ? [ ], # -1 -> 0 N.B. Legacy name 242 depsBuildTarget ? [ ], # -1 -> 1 243 depsBuildTargetPropagated ? [ ], # -1 -> 1 244 245 depsHostHost ? [ ], # 0 -> 0 246 depsHostHostPropagated ? [ ], # 0 -> 0 247 buildInputs ? [ ], # 0 -> 1 N.B. Legacy name 248 propagatedBuildInputs ? [ ], # 0 -> 1 N.B. Legacy name 249 250 depsTargetTarget ? [ ], # 1 -> 1 251 depsTargetTargetPropagated ? [ ], # 1 -> 1 252 253 checkInputs ? [ ], 254 installCheckInputs ? [ ], 255 nativeCheckInputs ? [ ], 256 nativeInstallCheckInputs ? [ ], 257 258 # Configure Phase 259 configureFlags ? [ ], 260 # Target is not included by default because most programs don't care. 261 # Including it then would cause needless mass rebuilds. 262 # 263 # TODO(@Ericson2314): Make [ "build" "host" ] always the default / resolve #87909 264 configurePlatforms ? 265 optionals (stdenv.hostPlatform != stdenv.buildPlatform || config.configurePlatformsByDefault) 266 [ 267 "build" 268 "host" 269 ], 270 271 # TODO(@Ericson2314): Make unconditional / resolve #33599 272 # Check phase 273 doCheck ? config.doCheckByDefault or false, 274 275 # TODO(@Ericson2314): Make unconditional / resolve #33599 276 # InstallCheck phase 277 doInstallCheck ? config.doCheckByDefault or false, 278 279 # TODO(@Ericson2314): Make always true and remove / resolve #178468 280 strictDeps ? 281 if config.strictDepsByDefault then true else stdenv.hostPlatform != stdenv.buildPlatform, 282 283 enableParallelBuilding ? config.enableParallelBuildingByDefault, 284 285 separateDebugInfo ? false, 286 outputs ? [ "out" ], 287 __darwinAllowLocalNetworking ? false, 288 __impureHostDeps ? [ ], 289 __propagatedImpureHostDeps ? [ ], 290 sandboxProfile ? "", 291 propagatedSandboxProfile ? "", 292 293 hardeningEnable ? [ ], 294 hardeningDisable ? [ ], 295 296 patches ? [ ], 297 298 __contentAddressed ? 299 (!attrs ? outputHash) # Fixed-output drvs can't be content addressed too 300 && config.contentAddressedByDefault, 301 302 # Experimental. For simple packages mostly just works, 303 # but for anything complex, be prepared to debug if enabling. 304 __structuredAttrs ? config.structuredAttrsByDefault or false, 305 306 ... 307 }@attrs: 308 309 # Policy on acceptable hash types in nixpkgs 310 assert 311 attrs ? outputHash 312 -> ( 313 let 314 algo = attrs.outputHashAlgo or (head (splitString "-" attrs.outputHash)); 315 in 316 if algo == "md5" then throw "Rejected insecure ${algo} hash '${attrs.outputHash}'" else true 317 ); 318 319 let 320 # TODO(@oxij, @Ericson2314): This is here to keep the old semantics, remove when 321 # no package has `doCheck = true`. 322 doCheck' = doCheck && stdenv.buildPlatform.canExecute stdenv.hostPlatform; 323 doInstallCheck' = doInstallCheck && stdenv.buildPlatform.canExecute stdenv.hostPlatform; 324 325 separateDebugInfo' = 326 let 327 actualValue = separateDebugInfo && stdenv.hostPlatform.isLinux; 328 conflictingOption = 329 attrs ? "disallowedReferences" 330 || attrs ? "disallowedRequisites" 331 || attrs ? "allowedRequisites" 332 || attrs ? "allowedReferences"; 333 in 334 if actualValue && conflictingOption && !__structuredAttrs then 335 throw "separateDebugInfo = true in ${ 336 attrs.pname or "mkDerivation argument" 337 } requires __structuredAttrs if {dis,}allowedRequisites or {dis,}allowedReferences is set" 338 else 339 actualValue; 340 outputs' = outputs ++ optional separateDebugInfo' "debug"; 341 342 noNonNativeDeps = 343 builtins.length ( 344 depsBuildTarget 345 ++ depsBuildTargetPropagated 346 ++ depsHostHost 347 ++ depsHostHostPropagated 348 ++ buildInputs 349 ++ propagatedBuildInputs 350 ++ depsTargetTarget 351 ++ depsTargetTargetPropagated 352 ) == 0; 353 dontAddHostSuffix = attrs ? outputHash && !noNonNativeDeps || !stdenv.hasCC; 354 355 concretizeFlagImplications = 356 flag: impliesFlags: list: 357 if any (x: x == flag) list then (list ++ impliesFlags) else list; 358 359 hardeningDisable' = unique ( 360 pipe hardeningDisable [ 361 # disabling fortify implies fortify3 should also be disabled 362 (concretizeFlagImplications "fortify" [ "fortify3" ]) 363 # disabling strictflexarrays1 implies strictflexarrays3 should also be disabled 364 (concretizeFlagImplications "strictflexarrays1" [ "strictflexarrays3" ]) 365 ] 366 ); 367 defaultHardeningFlags = 368 (if stdenv.hasCC then stdenv.cc else { }).defaultHardeningFlags or 369 # fallback safe-ish set of flags 370 ( 371 if with stdenv.hostPlatform; isOpenBSD && isStatic then 372 knownHardeningFlags # Need pie, in fact 373 else 374 remove "pie" knownHardeningFlags 375 ); 376 enabledHardeningOptions = 377 if builtins.elem "all" hardeningDisable' then 378 [ ] 379 else 380 subtractLists hardeningDisable' (defaultHardeningFlags ++ hardeningEnable); 381 # hardeningDisable additionally supports "all". 382 erroneousHardeningFlags = subtractLists knownHardeningFlags ( 383 hardeningEnable ++ remove "all" hardeningDisable 384 ); 385 386 checkDependencyList = checkDependencyList' [ ]; 387 checkDependencyList' = 388 positions: name: deps: 389 imap1 ( 390 index: dep: 391 if dep == null || isDerivation dep || builtins.isString dep || builtins.isPath dep then 392 dep 393 else if isList dep then 394 checkDependencyList' ([ index ] ++ positions) name dep 395 else 396 throw "Dependency is not of a valid type: ${ 397 concatMapStrings (ix: "element ${toString ix} of ") ([ index ] ++ positions) 398 }${name} for ${attrs.name or attrs.pname}" 399 ) deps; 400 in 401 if builtins.length erroneousHardeningFlags != 0 then 402 abort ( 403 "mkDerivation was called with unsupported hardening flags: " 404 + lib.generators.toPretty { } { 405 inherit 406 erroneousHardeningFlags 407 hardeningDisable 408 hardeningEnable 409 knownHardeningFlags 410 ; 411 } 412 ) 413 else 414 let 415 doCheck = doCheck'; 416 doInstallCheck = doInstallCheck'; 417 buildInputs' = 418 buildInputs ++ optionals doCheck checkInputs ++ optionals doInstallCheck installCheckInputs; 419 nativeBuildInputs' = 420 nativeBuildInputs 421 ++ optional separateDebugInfo' ../../build-support/setup-hooks/separate-debug-info.sh 422 ++ optional stdenv.hostPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh 423 ++ optionals doCheck nativeCheckInputs 424 ++ optionals doInstallCheck nativeInstallCheckInputs; 425 426 outputs = outputs'; 427 428 dependencies = [ 429 [ 430 (map (drv: getDev drv.__spliced.buildBuild or drv) ( 431 checkDependencyList "depsBuildBuild" depsBuildBuild 432 )) 433 (map (drv: getDev drv.__spliced.buildHost or drv) ( 434 checkDependencyList "nativeBuildInputs" nativeBuildInputs' 435 )) 436 (map (drv: getDev drv.__spliced.buildTarget or drv) ( 437 checkDependencyList "depsBuildTarget" depsBuildTarget 438 )) 439 ] 440 [ 441 (map (drv: getDev drv.__spliced.hostHost or drv) (checkDependencyList "depsHostHost" depsHostHost)) 442 (map (drv: getDev drv.__spliced.hostTarget or drv) (checkDependencyList "buildInputs" buildInputs')) 443 ] 444 [ 445 (map (drv: getDev drv.__spliced.targetTarget or drv) ( 446 checkDependencyList "depsTargetTarget" depsTargetTarget 447 )) 448 ] 449 ]; 450 propagatedDependencies = [ 451 [ 452 (map (drv: getDev drv.__spliced.buildBuild or drv) ( 453 checkDependencyList "depsBuildBuildPropagated" depsBuildBuildPropagated 454 )) 455 (map (drv: getDev drv.__spliced.buildHost or drv) ( 456 checkDependencyList "propagatedNativeBuildInputs" propagatedNativeBuildInputs 457 )) 458 (map (drv: getDev drv.__spliced.buildTarget or drv) ( 459 checkDependencyList "depsBuildTargetPropagated" depsBuildTargetPropagated 460 )) 461 ] 462 [ 463 (map (drv: getDev drv.__spliced.hostHost or drv) ( 464 checkDependencyList "depsHostHostPropagated" depsHostHostPropagated 465 )) 466 (map (drv: getDev drv.__spliced.hostTarget or drv) ( 467 checkDependencyList "propagatedBuildInputs" propagatedBuildInputs 468 )) 469 ] 470 [ 471 (map (drv: getDev drv.__spliced.targetTarget or drv) ( 472 checkDependencyList "depsTargetTargetPropagated" depsTargetTargetPropagated 473 )) 474 ] 475 ]; 476 477 derivationArg = 478 removeAttrs attrs removedOrReplacedAttrNames 479 // { 480 ${if (attrs ? name || (attrs ? pname && attrs ? version)) then "name" else null} = 481 let 482 # Indicate the host platform of the derivation if cross compiling. 483 # Fixed-output derivations like source tarballs shouldn't get a host 484 # suffix. But we have some weird ones with run-time deps that are 485 # just used for their side-affects. Those might as well since the 486 # hash can't be the same. See #32986. 487 hostSuffix = optionalString ( 488 stdenv.hostPlatform != stdenv.buildPlatform && !dontAddHostSuffix 489 ) "-${stdenv.hostPlatform.config}"; 490 491 # Disambiguate statically built packages. This was originally 492 # introduce as a means to prevent nix-env to get confused between 493 # nix and nixStatic. This should be also achieved by moving the 494 # hostSuffix before the version, so we could contemplate removing 495 # it again. 496 staticMarker = optionalString stdenv.hostPlatform.isStatic "-static"; 497 in 498 lib.strings.sanitizeDerivationName ( 499 if attrs ? name then 500 attrs.name + hostSuffix 501 else 502 # we cannot coerce null to a string below 503 assert assertMsg ( 504 attrs ? version && attrs.version != null 505 ) "The `version` attribute cannot be null."; 506 "${attrs.pname}${staticMarker}${hostSuffix}-${attrs.version}" 507 ); 508 509 builder = attrs.realBuilder or stdenv.shell; 510 args = 511 attrs.args or [ 512 "-e" 513 ./source-stdenv.sh 514 (attrs.builder or ./default-builder.sh) 515 ]; 516 inherit stdenv; 517 518 # The `system` attribute of a derivation has special meaning to Nix. 519 # Derivations set it to choose what sort of machine could be used to 520 # execute the build, The build platform entirely determines this, 521 # indeed more finely than Nix knows or cares about. The `system` 522 # attribute of `buildPlatform` matches Nix's degree of specificity. 523 # exactly. 524 inherit (stdenv.buildPlatform) system; 525 526 userHook = config.stdenv.userHook or null; 527 __ignoreNulls = true; 528 inherit __structuredAttrs strictDeps; 529 530 depsBuildBuild = elemAt (elemAt dependencies 0) 0; 531 nativeBuildInputs = elemAt (elemAt dependencies 0) 1; 532 depsBuildTarget = elemAt (elemAt dependencies 0) 2; 533 depsHostHost = elemAt (elemAt dependencies 1) 0; 534 buildInputs = elemAt (elemAt dependencies 1) 1; 535 depsTargetTarget = elemAt (elemAt dependencies 2) 0; 536 537 depsBuildBuildPropagated = elemAt (elemAt propagatedDependencies 0) 0; 538 propagatedNativeBuildInputs = elemAt (elemAt propagatedDependencies 0) 1; 539 depsBuildTargetPropagated = elemAt (elemAt propagatedDependencies 0) 2; 540 depsHostHostPropagated = elemAt (elemAt propagatedDependencies 1) 0; 541 propagatedBuildInputs = elemAt (elemAt propagatedDependencies 1) 1; 542 depsTargetTargetPropagated = elemAt (elemAt propagatedDependencies 2) 0; 543 544 # This parameter is sometimes a string, sometimes null, and sometimes a list, yuck 545 configureFlags = 546 configureFlags 547 ++ optional (elem "build" configurePlatforms) "--build=${stdenv.buildPlatform.config}" 548 ++ optional (elem "host" configurePlatforms) "--host=${stdenv.hostPlatform.config}" 549 ++ optional (elem "target" configurePlatforms) "--target=${stdenv.targetPlatform.config}"; 550 551 inherit patches; 552 553 inherit doCheck doInstallCheck; 554 555 inherit outputs; 556 557 # When the derivations is content addressed provide default values 558 # for outputHashMode and outputHashAlgo because most people won't 559 # care about these anyways 560 ${if __contentAddressed then "__contentAddressed" else null} = __contentAddressed; 561 ${if __contentAddressed then "outputHashAlgo" else null} = attrs.outputHashAlgo or "sha256"; 562 ${if __contentAddressed then "outputHashMode" else null} = attrs.outputHashMode or "recursive"; 563 564 ${if enableParallelBuilding then "enableParallelBuilding" else null} = enableParallelBuilding; 565 ${if enableParallelBuilding then "enableParallelChecking" else null} = 566 attrs.enableParallelChecking or true; 567 ${if enableParallelBuilding then "enableParallelInstalling" else null} = 568 attrs.enableParallelInstalling or true; 569 570 ${ 571 if (hardeningDisable != [ ] || hardeningEnable != [ ] || stdenv.hostPlatform.isMusl) then 572 "NIX_HARDENING_ENABLE" 573 else 574 null 575 } = 576 builtins.concatStringsSep " " enabledHardeningOptions; 577 578 # TODO: remove platform condition 579 # Enabling this check could be a breaking change as it requires to edit nix.conf 580 # NixOS module already sets gccarch, unsure of nix installers and other distributions 581 ${ 582 if 583 stdenv.buildPlatform ? gcc.arch 584 && !( 585 stdenv.buildPlatform.isAarch64 586 && ( 587 # `aarch64-darwin` sets `{gcc.arch = "armv8.3-a+crypto+sha2+...";}` 588 stdenv.buildPlatform.isDarwin 589 || 590 # `aarch64-linux` has `{ gcc.arch = "armv8-a"; }` set by default 591 stdenv.buildPlatform.gcc.arch == "armv8-a" 592 ) 593 ) 594 then 595 "requiredSystemFeatures" 596 else 597 null 598 } = 599 attrs.requiredSystemFeatures or [ ] ++ [ 600 "gccarch-${stdenv.buildPlatform.gcc.arch}" 601 ]; 602 } 603 // optionalAttrs (stdenv.buildPlatform.isDarwin) ( 604 let 605 allDependencies = concatLists (concatLists dependencies); 606 allPropagatedDependencies = concatLists (concatLists propagatedDependencies); 607 608 computedSandboxProfile = concatMap (input: input.__propagatedSandboxProfile or [ ]) ( 609 stdenv.extraNativeBuildInputs ++ stdenv.extraBuildInputs ++ allDependencies 610 ); 611 612 computedPropagatedSandboxProfile = concatMap ( 613 input: input.__propagatedSandboxProfile or [ ] 614 ) allPropagatedDependencies; 615 616 computedImpureHostDeps = unique ( 617 concatMap (input: input.__propagatedImpureHostDeps or [ ]) ( 618 stdenv.extraNativeBuildInputs ++ stdenv.extraBuildInputs ++ allDependencies 619 ) 620 ); 621 622 computedPropagatedImpureHostDeps = unique ( 623 concatMap (input: input.__propagatedImpureHostDeps or [ ]) allPropagatedDependencies 624 ); 625 in 626 { 627 inherit __darwinAllowLocalNetworking; 628 # TODO: remove `unique` once nix has a list canonicalization primitive 629 __sandboxProfile = 630 let 631 profiles = [ 632 stdenv.extraSandboxProfile 633 ] 634 ++ computedSandboxProfile 635 ++ computedPropagatedSandboxProfile 636 ++ [ 637 propagatedSandboxProfile 638 sandboxProfile 639 ]; 640 final = concatStringsSep "\n" (filter (x: x != "") (unique profiles)); 641 in 642 final; 643 __propagatedSandboxProfile = unique ( 644 computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ] 645 ); 646 __impureHostDeps = 647 computedImpureHostDeps 648 ++ computedPropagatedImpureHostDeps 649 ++ __propagatedImpureHostDeps 650 ++ __impureHostDeps 651 ++ stdenv.__extraImpureHostDeps 652 ++ [ 653 "/dev/zero" 654 "/dev/random" 655 "/dev/urandom" 656 "/bin/sh" 657 ]; 658 __propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps; 659 } 660 ) 661 // ( 662 if !__structuredAttrs then 663 makeOutputChecks attrs 664 else 665 { 666 outputChecks = builtins.listToAttrs ( 667 map (name: { 668 inherit name; 669 value = 670 let 671 raw = zipAttrsWith (_: builtins.concatLists) [ 672 (makeOutputChecks attrs) 673 (makeOutputChecks attrs.outputChecks.${name} or { }) 674 ]; 675 in 676 # separateDebugInfo = true will put all sorts of files in 677 # the debug output which could carry references, but 678 # that's "normal". Notably it symlinks to the source. 679 # So disable reference checking for the debug output 680 if separateDebugInfo' && name == "debug" then 681 removeAttrs raw [ 682 "allowedReferences" 683 "allowedRequisites" 684 "disallowedReferences" 685 "disallowedRequisites" 686 ] 687 else 688 raw; 689 }) outputs 690 ); 691 } 692 ); 693 694 in 695 derivationArg; 696 697 mkDerivationSimple = 698 overrideAttrs: 699 700 # `mkDerivation` wraps the builtin `derivation` function to 701 # produce derivations that use this stdenv and its shell. 702 # 703 # Internally, it delegates most of its behavior to `makeDerivationArgument`, 704 # except for the `env`, `cmakeFlags`, and `mesonFlags` attributes, as well 705 # as the attributes `meta` and `passthru` that affect [package attributes], 706 # and not the derivation itself. 707 # 708 # See also: 709 # 710 # * https://nixos.org/nixpkgs/manual/#sec-using-stdenv 711 # Details on how to use this mkDerivation function 712 # 713 # * https://nixos.org/manual/nix/stable/expressions/derivations.html#derivations 714 # Explanation about derivations in general 715 # 716 # * [package attributes]: https://nixos.org/manual/nix/stable/glossary#package-attribute-set 717 { 718 719 # Configure Phase 720 cmakeFlags ? [ ], 721 mesonFlags ? [ ], 722 723 meta ? { }, 724 passthru ? { }, 725 pos ? # position used in error messages and for meta.position 726 ( 727 if attrs.meta.description or null != null then 728 builtins.unsafeGetAttrPos "description" attrs.meta 729 else if attrs.version or null != null then 730 builtins.unsafeGetAttrPos "version" attrs 731 else 732 builtins.unsafeGetAttrPos "name" attrs 733 ), 734 735 # Experimental. For simple packages mostly just works, 736 # but for anything complex, be prepared to debug if enabling. 737 __structuredAttrs ? config.structuredAttrsByDefault or false, 738 739 env ? { }, 740 741 ... 742 }@attrs: 743 744 # Policy on acceptable hash types in nixpkgs 745 assert 746 attrs ? outputHash 747 -> ( 748 let 749 algo = attrs.outputHashAlgo or (head (splitString "-" attrs.outputHash)); 750 in 751 if algo == "md5" then throw "Rejected insecure ${algo} hash '${attrs.outputHash}'" else true 752 ); 753 754 let 755 mainProgram = meta.mainProgram or null; 756 env' = env // lib.optionalAttrs (mainProgram != null) { NIX_MAIN_PROGRAM = mainProgram; }; 757 758 derivationArg = makeDerivationArgument ( 759 removeAttrs attrs ([ 760 "meta" 761 "passthru" 762 "pos" 763 "env" 764 ]) 765 // lib.optionalAttrs __structuredAttrs { env = checkedEnv; } 766 // { 767 cmakeFlags = makeCMakeFlags attrs; 768 mesonFlags = makeMesonFlags attrs; 769 } 770 ); 771 772 meta = checkMeta.commonMeta { 773 inherit validity attrs pos; 774 references = 775 attrs.nativeBuildInputs or [ ] 776 ++ attrs.buildInputs or [ ] 777 ++ attrs.propagatedNativeBuildInputs or [ ] 778 ++ attrs.propagatedBuildInputs or [ ]; 779 }; 780 validity = checkMeta.assertValidity { inherit meta attrs; }; 781 782 checkedEnv = 783 let 784 overlappingNames = attrNames (builtins.intersectAttrs env' derivationArg); 785 prettyPrint = lib.generators.toPretty { }; 786 makeError = 787 name: 788 " - ${name}: in `env`: ${prettyPrint env'.${name}}; in derivation arguments: ${ 789 prettyPrint derivationArg.${name} 790 }"; 791 errors = lib.concatMapStringsSep "\n" makeError overlappingNames; 792 in 793 assert assertMsg (isAttrs env && !isDerivation env) 794 "`env` must be an attribute set of environment variables. Set `env.env` or pick a more specific name."; 795 assert assertMsg (overlappingNames == [ ]) 796 "The `env` attribute set cannot contain any attributes passed to derivation. The following attributes are overlapping:\n${errors}"; 797 mapAttrs ( 798 n: v: 799 assert assertMsg (isString v || isBool v || isInt v || isDerivation v) 800 "The `env` attribute set can only contain derivation, string, boolean or integer attributes. The `${n}` attribute is of type ${builtins.typeOf v}."; 801 v 802 ) env'; 803 804 # Fixed-output derivations may not reference other paths, which means that 805 # for a fixed-output derivation, the corresponding inputDerivation should 806 # *not* be fixed-output. To achieve this we simply delete the attributes that 807 # would make it fixed-output. 808 deleteFixedOutputRelatedAttrs = lib.flip builtins.removeAttrs [ 809 "outputHashAlgo" 810 "outputHash" 811 "outputHashMode" 812 ]; 813 814 in 815 816 extendDerivation validity.handled ( 817 { 818 # A derivation that always builds successfully and whose runtime 819 # dependencies are the original derivations build time dependencies 820 # This allows easy building and distributing of all derivations 821 # needed to enter a nix-shell with 822 # nix-build shell.nix -A inputDerivation 823 inputDerivation = derivation ( 824 deleteFixedOutputRelatedAttrs derivationArg 825 // { 826 # Add a name in case the original drv didn't have one 827 name = derivationArg.name or "inputDerivation"; 828 # This always only has one output 829 outputs = [ "out" ]; 830 831 # Propagate the original builder and arguments, since we override 832 # them and they might contain references to build inputs 833 _derivation_original_builder = derivationArg.builder; 834 _derivation_original_args = derivationArg.args; 835 836 builder = stdenv.shell; 837 # The builtin `declare -p` dumps all bash and environment variables, 838 # which is where all build input references end up (e.g. $PATH for 839 # binaries). By writing this to $out, Nix can find and register 840 # them as runtime dependencies (since Nix greps for store paths 841 # through $out to find them). Using placeholder for $out works with 842 # and without structuredAttrs. 843 # This build script does not use setup.sh or stdenv, to keep 844 # the env most pristine. This gives us a very bare bones env, 845 # hence the extra/duplicated compatibility logic and "pure bash" style. 846 args = [ 847 "-c" 848 '' 849 out="${placeholder "out"}" 850 if [ -e "$NIX_ATTRS_SH_FILE" ]; then . "$NIX_ATTRS_SH_FILE"; elif [ -f .attrs.sh ]; then . .attrs.sh; fi 851 declare -p > $out 852 for var in $passAsFile; do 853 pathVar="''${var}Path" 854 printf "%s" "$(< "''${!pathVar}")" >> $out 855 done 856 '' 857 ]; 858 } 859 // ( 860 let 861 sharedOutputChecks = { 862 # inputDerivation produces the inputs; not the outputs, so any 863 # restrictions on what used to be the outputs don't serve a purpose 864 # anymore. 865 allowedReferences = null; 866 allowedRequisites = null; 867 disallowedReferences = [ ]; 868 disallowedRequisites = [ ]; 869 }; 870 in 871 if __structuredAttrs then 872 { 873 outputChecks.out = sharedOutputChecks; 874 } 875 else 876 sharedOutputChecks 877 ) 878 ); 879 880 inherit passthru overrideAttrs; 881 inherit meta; 882 } 883 // 884 # Pass through extra attributes that are not inputs, but 885 # should be made available to Nix expressions using the 886 # derivation (e.g., in assertions). 887 passthru 888 ) (derivation (derivationArg // checkedEnv)); 889 890in 891{ 892 inherit mkDerivation; 893}