at v206 849 lines 22 kB view raw
1set -e 2set -o pipefail 3 4: ${outputs:=out} 5 6 7###################################################################### 8# Hook handling. 9 10 11# Run all hooks with the specified name in the order in which they 12# were added, stopping if any fails (returns a non-zero exit 13# code). The hooks for <hookName> are the shell function or variable 14# <hookName>, and the values of the shell array ‘<hookName>Hooks’. 15runHook() { 16 local hookName="$1" 17 shift 18 local var="$hookName" 19 if [[ "$hookName" =~ Hook$ ]]; then var+=s; else var+=Hooks; fi 20 eval "local -a dummy=(\"\${$var[@]}\")" 21 for hook in "_callImplicitHook 0 $hookName" "${dummy[@]}"; do 22 _eval "$hook" "$@" 23 done 24 return 0 25} 26 27 28# Run all hooks with the specified name, until one succeeds (returns a 29# zero exit code). If none succeed, return a non-zero exit code. 30runOneHook() { 31 local hookName="$1" 32 shift 33 local var="$hookName" 34 if [[ "$hookName" =~ Hook$ ]]; then var+=s; else var+=Hooks; fi 35 eval "local -a dummy=(\"\${$var[@]}\")" 36 for hook in "_callImplicitHook 1 $hookName" "${dummy[@]}"; do 37 if _eval "$hook" "$@"; then 38 return 0 39 fi 40 done 41 return 1 42} 43 44 45# Run the named hook, either by calling the function with that name or 46# by evaluating the variable with that name. This allows convenient 47# setting of hooks both from Nix expressions (as attributes / 48# environment variables) and from shell scripts (as functions). If you 49# want to allow multiple hooks, use runHook instead. 50_callImplicitHook() { 51 local def="$1" 52 local hookName="$2" 53 case "$(type -t $hookName)" in 54 (function|alias|builtin) $hookName;; 55 (file) source $hookName;; 56 (keyword) :;; 57 (*) if [ -z "${!hookName}" ]; then return "$def"; else eval "${!hookName}"; fi;; 58 esac 59} 60 61 62# A function wrapper around ‘eval’ that ensures that ‘return’ inside 63# hooks exits the hook, not the caller. 64_eval() { 65 local code="$1" 66 shift 67 if [ "$(type -t $code)" = function ]; then 68 eval "$code \"\$@\"" 69 else 70 eval "$code" 71 fi 72} 73 74 75###################################################################### 76# Logging. 77 78nestingLevel=0 79 80startNest() { 81 nestingLevel=$(($nestingLevel + 1)) 82 echo -en "\033[$1p" 83} 84 85stopNest() { 86 nestingLevel=$(($nestingLevel - 1)) 87 echo -en "\033[q" 88} 89 90header() { 91 startNest "$2" 92 echo "$1" 93} 94 95# Make sure that even when we exit abnormally, the original nesting 96# level is properly restored. 97closeNest() { 98 while [ $nestingLevel -gt 0 ]; do 99 stopNest 100 done 101} 102 103 104###################################################################### 105# Error handling. 106 107exitHandler() { 108 exitCode=$? 109 set +e 110 111 closeNest 112 113 if [ -n "$showBuildStats" ]; then 114 times > "$NIX_BUILD_TOP/.times" 115 local -a times=($(cat "$NIX_BUILD_TOP/.times")) 116 # Print the following statistics: 117 # - user time for the shell 118 # - system time for the shell 119 # - user time for all child processes 120 # - system time for all child processes 121 echo "build time elapsed: " ${times[*]} 122 fi 123 124 if [ $exitCode != 0 ]; then 125 runHook failureHook 126 127 # If the builder had a non-zero exit code and 128 # $succeedOnFailure is set, create the file 129 # ‘$out/nix-support/failed’ to signal failure, and exit 130 # normally. Otherwise, return the original exit code. 131 if [ -n "$succeedOnFailure" ]; then 132 echo "build failed with exit code $exitCode (ignored)" 133 mkdir -p "$out/nix-support" 134 printf "%s" $exitCode > "$out/nix-support/failed" 135 exit 0 136 fi 137 138 else 139 runHook exitHook 140 fi 141 142 exit $exitCode 143} 144 145trap "exitHandler" EXIT 146 147 148###################################################################### 149# Helper functions. 150 151 152addToSearchPathWithCustomDelimiter() { 153 local delimiter=$1 154 local varName=$2 155 local dir=$3 156 if [ -d "$dir" ]; then 157 eval export ${varName}=${!varName}${!varName:+$delimiter}${dir} 158 fi 159} 160 161PATH_DELIMITER=':' 162 163addToSearchPath() { 164 addToSearchPathWithCustomDelimiter "${PATH_DELIMITER}" "$@" 165} 166 167 168ensureDir() { 169 echo "warning: ‘ensureDir’ is deprecated; use ‘mkdir’ instead" >&2 170 local dir 171 for dir in "$@"; do 172 if ! [ -x "$dir" ]; then mkdir -p "$dir"; fi 173 done 174} 175 176 177installBin() { 178 mkdir -p $out/bin 179 cp "$@" $out/bin 180} 181 182 183###################################################################### 184# Initialisation. 185 186 187# Wildcard expansions that don't match should expand to an empty list. 188# This ensures that, for instance, "for i in *; do ...; done" does the 189# right thing. 190shopt -s nullglob 191 192 193# Set up the initial path. 194PATH= 195for i in $initialPath; do 196 if [ "$i" = / ]; then i=; fi 197 addToSearchPath PATH $i/bin 198 addToSearchPath PATH $i/sbin 199done 200 201if [ "$NIX_DEBUG" = 1 ]; then 202 echo "initial path: $PATH" 203fi 204 205 206# Check that the pre-hook initialised SHELL. 207if [ -z "$SHELL" ]; then echo "SHELL not set"; exit 1; fi 208BASH="$SHELL" 209export CONFIG_SHELL="$SHELL" 210 211 212# Execute the pre-hook. 213if [ -z "$shell" ]; then export shell=$SHELL; fi 214runHook preHook 215 216 217# Allow the caller to augment buildInputs (it's not always possible to 218# do this before the call to setup.sh, since the PATH is empty at that 219# point; here we have a basic Unix environment). 220runHook addInputsHook 221 222 223# Recursively find all build inputs. 224findInputs() { 225 local pkg="$1" 226 local var=$2 227 local propagatedBuildInputsFile=$3 228 229 case ${!var} in 230 *\ $pkg\ *) 231 return 0 232 ;; 233 esac 234 235 eval $var="'${!var} $pkg '" 236 237 if ! [ -e "$pkg" ]; then 238 echo "build input $pkg does not exist" >&2 239 exit 1 240 fi 241 242 if [ -f "$pkg" ]; then 243 source "$pkg" 244 fi 245 246 if [ -f "$pkg/nix-support/setup-hook" ]; then 247 source "$pkg/nix-support/setup-hook" 248 fi 249 250 if [ -f "$pkg/nix-support/$propagatedBuildInputsFile" ]; then 251 for i in $(cat "$pkg/nix-support/$propagatedBuildInputsFile"); do 252 findInputs "$i" $var $propagatedBuildInputsFile 253 done 254 fi 255} 256 257crossPkgs="" 258for i in $buildInputs $defaultBuildInputs $propagatedBuildInputs; do 259 findInputs $i crossPkgs propagated-build-inputs 260done 261 262nativePkgs="" 263for i in $nativeBuildInputs $defaultNativeBuildInputs $propagatedNativeBuildInputs; do 264 findInputs $i nativePkgs propagated-native-build-inputs 265done 266 267 268# Set the relevant environment variables to point to the build inputs 269# found above. 270_addToNativeEnv() { 271 local pkg=$1 272 273 if [ -d $1/bin ]; then 274 addToSearchPath _PATH $1/bin 275 fi 276 277 # Run the package-specific hooks set by the setup-hook scripts. 278 runHook envHook "$pkg" 279} 280 281for i in $nativePkgs; do 282 _addToNativeEnv $i 283done 284 285_addToCrossEnv() { 286 local pkg=$1 287 288 # Some programs put important build scripts (freetype-config and similar) 289 # into their crossDrv bin path. Intentionally these should go after 290 # the nativePkgs in PATH. 291 if [ -d $1/bin ]; then 292 addToSearchPath _PATH $1/bin 293 fi 294 295 # Run the package-specific hooks set by the setup-hook scripts. 296 runHook crossEnvHook "$pkg" 297} 298 299for i in $crossPkgs; do 300 _addToCrossEnv $i 301done 302 303 304# Add the output as an rpath. 305if [ "$NIX_NO_SELF_RPATH" != 1 ]; then 306 export NIX_LDFLAGS="-rpath $out/lib $NIX_LDFLAGS" 307 if [ -n "$NIX_LIB64_IN_SELF_RPATH" ]; then 308 export NIX_LDFLAGS="-rpath $out/lib64 $NIX_LDFLAGS" 309 fi 310 if [ -n "$NIX_LIB32_IN_SELF_RPATH" ]; then 311 export NIX_LDFLAGS="-rpath $out/lib32 $NIX_LDFLAGS" 312 fi 313fi 314 315 316# Set the TZ (timezone) environment variable, otherwise commands like 317# `date' will complain (e.g., `Tue Mar 9 10:01:47 Local time zone must 318# be set--see zic manual page 2004'). 319export TZ=UTC 320 321 322# Set the prefix. This is generally $out, but it can be overriden, 323# for instance if we just want to perform a test build/install to a 324# temporary location and write a build report to $out. 325if [ -z "$prefix" ]; then 326 prefix="$out"; 327fi 328 329if [ "$useTempPrefix" = 1 ]; then 330 prefix="$NIX_BUILD_TOP/tmp_prefix"; 331fi 332 333 334PATH=$_PATH${_PATH:+:}$PATH 335if [ "$NIX_DEBUG" = 1 ]; then 336 echo "final path: $PATH" 337fi 338 339 340# Make GNU Make produce nested output. 341export NIX_INDENT_MAKE=1 342 343 344# Normalize the NIX_BUILD_CORES variable. The value might be 0, which 345# means that we're supposed to try and auto-detect the number of 346# available CPU cores at run-time. 347 348if [ -z "${NIX_BUILD_CORES:-}" ]; then 349 NIX_BUILD_CORES="1" 350elif [ "$NIX_BUILD_CORES" -le 0 ]; then 351 NIX_BUILD_CORES=$(nproc 2>/dev/null || true) 352 if expr >/dev/null 2>&1 "$NIX_BUILD_CORES" : "^[0-9][0-9]*$"; then 353 : 354 else 355 NIX_BUILD_CORES="1" 356 fi 357fi 358export NIX_BUILD_CORES 359 360 361# Dummy implementation of the paxmark function. On Linux, this is 362# overwritten by paxctl's setup hook. 363paxmark() { true; } 364 365 366###################################################################### 367# Textual substitution functions. 368 369 370substitute() { 371 local input="$1" 372 local output="$2" 373 374 local -a params=("$@") 375 376 local n p pattern replacement varName content 377 378 # a slightly hacky way to keep newline at the end 379 content="$(cat "$input"; printf "%s" X)" 380 content="${content%X}" 381 382 for ((n = 2; n < ${#params[*]}; n += 1)); do 383 p=${params[$n]} 384 385 if [ "$p" = --replace ]; then 386 pattern="${params[$((n + 1))]}" 387 replacement="${params[$((n + 2))]}" 388 n=$((n + 2)) 389 fi 390 391 if [ "$p" = --subst-var ]; then 392 varName="${params[$((n + 1))]}" 393 pattern="@$varName@" 394 replacement="${!varName}" 395 n=$((n + 1)) 396 fi 397 398 if [ "$p" = --subst-var-by ]; then 399 pattern="@${params[$((n + 1))]}@" 400 replacement="${params[$((n + 2))]}" 401 n=$((n + 2)) 402 fi 403 404 content="${content//"$pattern"/$replacement}" 405 done 406 407 if [ -e "$output" ]; then chmod +w "$output"; fi 408 printf "%s" "$content" > "$output" 409} 410 411 412substituteInPlace() { 413 local fileName="$1" 414 shift 415 substitute "$fileName" "$fileName" "$@" 416} 417 418 419substituteAll() { 420 local input="$1" 421 local output="$2" 422 423 # Select all environment variables that start with a lowercase character. 424 for envVar in $(env | sed -e $'s/^\([a-z][^=]*\)=.*/\\1/; t \n d'); do 425 if [ "$NIX_DEBUG" = "1" ]; then 426 echo "$envVar -> ${!envVar}" 427 fi 428 args="$args --subst-var $envVar" 429 done 430 431 substitute "$input" "$output" $args 432} 433 434 435substituteAllInPlace() { 436 local fileName="$1" 437 shift 438 substituteAll "$fileName" "$fileName" "$@" 439} 440 441 442###################################################################### 443# What follows is the generic builder. 444 445 446# This function is useful for debugging broken Nix builds. It dumps 447# all environment variables to a file `env-vars' in the build 448# directory. If the build fails and the `-K' option is used, you can 449# then go to the build directory and source in `env-vars' to reproduce 450# the environment used for building. 451dumpVars() { 452 if [ "$noDumpEnvVars" != 1 ]; then 453 export > "$NIX_BUILD_TOP/env-vars" 454 fi 455} 456 457 458# Utility function: return the base name of the given path, with the 459# prefix `HASH-' removed, if present. 460stripHash() { 461 strippedName=$(basename $1); 462 if echo "$strippedName" | grep -q '^[a-z0-9]\{32\}-'; then 463 strippedName=$(echo "$strippedName" | cut -c34-) 464 fi 465} 466 467 468unpackCmdHooks+=(_defaultUnpack) 469_defaultUnpack() { 470 local fn="$1" 471 472 if [ -d "$fn" ]; then 473 474 stripHash "$fn" 475 # We can't preserve hardlinks because they may have been introduced by 476 # store optimization, which might break things in the build 477 cp -pr --reflink=auto --no-preserve=timestamps "$fn" $strippedName 478 479 else 480 481 case "$fn" in 482 *.tar.xz | *.tar.lzma) 483 # Don't rely on tar knowing about .xz. 484 xz -d < "$fn" | tar xf - 485 ;; 486 *.tar | *.tar.* | *.tgz | *.tbz2) 487 # GNU tar can automatically select the decompression method 488 # (info "(tar) gzip"). 489 tar xf "$fn" 490 ;; 491 *) 492 return 1 493 ;; 494 esac 495 496 fi 497} 498 499 500unpackFile() { 501 curSrc="$1" 502 header "unpacking source archive $curSrc" 3 503 if ! runOneHook unpackCmd "$curSrc"; then 504 echo "do not know how to unpack source archive $curSrc" 505 exit 1 506 fi 507 stopNest 508} 509 510 511unpackPhase() { 512 runHook preUnpack 513 514 if [ -z "$srcs" ]; then 515 if [ -z "$src" ]; then 516 echo 'variable $src or $srcs should point to the source' 517 exit 1 518 fi 519 srcs="$src" 520 fi 521 522 # To determine the source directory created by unpacking the 523 # source archives, we record the contents of the current 524 # directory, then look below which directory got added. Yeah, 525 # it's rather hacky. 526 local dirsBefore="" 527 for i in *; do 528 if [ -d "$i" ]; then 529 dirsBefore="$dirsBefore $i " 530 fi 531 done 532 533 # Unpack all source archives. 534 for i in $srcs; do 535 unpackFile $i 536 done 537 538 # Find the source directory. 539 if [ -n "$setSourceRoot" ]; then 540 runOneHook setSourceRoot 541 elif [ -z "$sourceRoot" ]; then 542 sourceRoot= 543 for i in *; do 544 if [ -d "$i" ]; then 545 case $dirsBefore in 546 *\ $i\ *) 547 ;; 548 *) 549 if [ -n "$sourceRoot" ]; then 550 echo "unpacker produced multiple directories" 551 exit 1 552 fi 553 sourceRoot="$i" 554 ;; 555 esac 556 fi 557 done 558 fi 559 560 if [ -z "$sourceRoot" ]; then 561 echo "unpacker appears to have produced no directories" 562 exit 1 563 fi 564 565 echo "source root is $sourceRoot" 566 567 # By default, add write permission to the sources. This is often 568 # necessary when sources have been copied from other store 569 # locations. 570 if [ "$dontMakeSourcesWritable" != 1 ]; then 571 chmod -R u+w "$sourceRoot" 572 fi 573 574 runHook postUnpack 575} 576 577 578patchPhase() { 579 runHook prePatch 580 581 for i in $patches; do 582 header "applying patch $i" 3 583 local uncompress=cat 584 case "$i" in 585 *.gz) 586 uncompress="gzip -d" 587 ;; 588 *.bz2) 589 uncompress="bzip2 -d" 590 ;; 591 *.xz) 592 uncompress="xz -d" 593 ;; 594 *.lzma) 595 uncompress="lzma -d" 596 ;; 597 esac 598 # "2>&1" is a hack to make patch fail if the decompressor fails (nonexistent patch, etc.) 599 $uncompress < "$i" 2>&1 | patch ${patchFlags:--p1} 600 stopNest 601 done 602 603 runHook postPatch 604} 605 606 607fixLibtool() { 608 sed -i -e 's^eval sys_lib_.*search_path=.*^^' "$1" 609} 610 611 612configurePhase() { 613 runHook preConfigure 614 615 if [ -z "$configureScript" ]; then 616 configureScript=./configure 617 if ! [ -x $configureScript ]; then 618 echo "no configure script, doing nothing" 619 return 620 fi 621 fi 622 623 if [ -z "$dontFixLibtool" ]; then 624 find . -iname "ltmain.sh" | while read i; do 625 echo "fixing libtool script $i" 626 fixLibtool $i 627 done 628 fi 629 630 if [ -z "$dontAddPrefix" ]; then 631 configureFlags="${prefixKey:---prefix=}$prefix $configureFlags" 632 fi 633 634 # Add --disable-dependency-tracking to speed up some builds. 635 if [ -z "$dontAddDisableDepTrack" ]; then 636 if grep -q dependency-tracking $configureScript; then 637 configureFlags="--disable-dependency-tracking $configureFlags" 638 fi 639 fi 640 641 # By default, disable static builds. 642 if [ -z "$dontDisableStatic" ]; then 643 if grep -q enable-static $configureScript; then 644 configureFlags="--disable-static $configureFlags" 645 fi 646 fi 647 648 echo "configure flags: $configureFlags ${configureFlagsArray[@]}" 649 $configureScript $configureFlags "${configureFlagsArray[@]}" 650 651 runHook postConfigure 652} 653 654 655buildPhase() { 656 runHook preBuild 657 658 if [ -z "$makeFlags" ] && ! [ -n "$makefile" -o -e "Makefile" -o -e "makefile" -o -e "GNUmakefile" ]; then 659 echo "no Makefile, doing nothing" 660 return 661 fi 662 663 # See https://github.com/NixOS/nixpkgs/pull/1354#issuecomment-31260409 664 makeFlags="SHELL=$SHELL $makeFlags" 665 666 echo "make flags: $makeFlags ${makeFlagsArray[@]} $buildFlags ${buildFlagsArray[@]}" 667 make ${makefile:+-f $makefile} \ 668 ${enableParallelBuilding:+-j${NIX_BUILD_CORES} -l${NIX_BUILD_CORES}} \ 669 $makeFlags "${makeFlagsArray[@]}" \ 670 $buildFlags "${buildFlagsArray[@]}" 671 672 runHook postBuild 673} 674 675 676checkPhase() { 677 runHook preCheck 678 679 echo "check flags: $makeFlags ${makeFlagsArray[@]} $checkFlags ${checkFlagsArray[@]}" 680 make ${makefile:+-f $makefile} \ 681 ${enableParallelBuilding:+-j${NIX_BUILD_CORES} -l${NIX_BUILD_CORES}} \ 682 $makeFlags "${makeFlagsArray[@]}" \ 683 ${checkFlags:-VERBOSE=y} "${checkFlagsArray[@]}" ${checkTarget:-check} 684 685 runHook postCheck 686} 687 688 689installPhase() { 690 runHook preInstall 691 692 mkdir -p "$prefix" 693 694 installTargets=${installTargets:-install} 695 echo "install flags: $installTargets $makeFlags ${makeFlagsArray[@]} $installFlags ${installFlagsArray[@]}" 696 make ${makefile:+-f $makefile} $installTargets \ 697 $makeFlags "${makeFlagsArray[@]}" \ 698 $installFlags "${installFlagsArray[@]}" 699 700 runHook postInstall 701} 702 703 704# The fixup phase performs generic, package-independent stuff, like 705# stripping binaries, running patchelf and setting 706# propagated-build-inputs. 707fixupPhase() { 708 # Make sure everything is writable so "strip" et al. work. 709 for output in $outputs; do 710 if [ -e "${!output}" ]; then chmod -R u+w "${!output}"; fi 711 done 712 713 runHook preFixup 714 715 # Apply fixup to each output. 716 local output 717 for output in $outputs; do 718 prefix=${!output} runHook fixupOutput 719 done 720 721 if [ -n "$propagatedBuildInputs" ]; then 722 mkdir -p "$out/nix-support" 723 echo "$propagatedBuildInputs" > "$out/nix-support/propagated-build-inputs" 724 fi 725 726 if [ -n "$propagatedNativeBuildInputs" ]; then 727 mkdir -p "$out/nix-support" 728 echo "$propagatedNativeBuildInputs" > "$out/nix-support/propagated-native-build-inputs" 729 fi 730 731 if [ -n "$propagatedUserEnvPkgs" ]; then 732 mkdir -p "$out/nix-support" 733 echo "$propagatedUserEnvPkgs" > "$out/nix-support/propagated-user-env-packages" 734 fi 735 736 if [ -n "$setupHook" ]; then 737 mkdir -p "$out/nix-support" 738 substituteAll "$setupHook" "$out/nix-support/setup-hook" 739 fi 740 741 runHook postFixup 742} 743 744 745installCheckPhase() { 746 runHook preInstallCheck 747 748 echo "installcheck flags: $makeFlags ${makeFlagsArray[@]} $installCheckFlags ${installCheckFlagsArray[@]}" 749 make ${makefile:+-f $makefile} \ 750 ${enableParallelBuilding:+-j${NIX_BUILD_CORES} -l${NIX_BUILD_CORES}} \ 751 $makeFlags "${makeFlagsArray[@]}" \ 752 $installCheckFlags "${installCheckFlagsArray[@]}" ${installCheckTarget:-installcheck} 753 754 runHook postInstallCheck 755} 756 757 758distPhase() { 759 runHook preDist 760 761 echo "dist flags: $distFlags ${distFlagsArray[@]}" 762 make ${makefile:+-f $makefile} $distFlags "${distFlagsArray[@]}" ${distTarget:-dist} 763 764 if [ "$dontCopyDist" != 1 ]; then 765 mkdir -p "$out/tarballs" 766 767 # Note: don't quote $tarballs, since we explicitly permit 768 # wildcards in there. 769 cp -pvd ${tarballs:-*.tar.gz} $out/tarballs 770 fi 771 772 runHook postDist 773} 774 775 776showPhaseHeader() { 777 local phase="$1" 778 case $phase in 779 unpackPhase) header "unpacking sources";; 780 patchPhase) header "patching sources";; 781 configurePhase) header "configuring";; 782 buildPhase) header "building";; 783 checkPhase) header "running tests";; 784 installPhase) header "installing";; 785 fixupPhase) header "post-installation fixup";; 786 installCheckPhase) header "running install tests";; 787 *) header "$phase";; 788 esac 789} 790 791 792genericBuild() { 793 if [ -n "$buildCommand" ]; then 794 eval "$buildCommand" 795 return 796 fi 797 798 if [ -z "$phases" ]; then 799 phases="$prePhases unpackPhase patchPhase $preConfigurePhases \ 800 configurePhase $preBuildPhases buildPhase checkPhase \ 801 $preInstallPhases installPhase $preFixupPhases fixupPhase installCheckPhase \ 802 $preDistPhases distPhase $postPhases"; 803 fi 804 805 for curPhase in $phases; do 806 if [ "$curPhase" = buildPhase -a -n "$dontBuild" ]; then continue; fi 807 if [ "$curPhase" = checkPhase -a -z "$doCheck" ]; then continue; fi 808 if [ "$curPhase" = installPhase -a -n "$dontInstall" ]; then continue; fi 809 if [ "$curPhase" = fixupPhase -a -n "$dontFixup" ]; then continue; fi 810 if [ "$curPhase" = installCheckPhase -a -z "$doInstallCheck" ]; then continue; fi 811 if [ "$curPhase" = distPhase -a -z "$doDist" ]; then continue; fi 812 813 if [ -n "$tracePhases" ]; then 814 echo 815 echo "@ phase-started $out $curPhase" 816 fi 817 818 showPhaseHeader "$curPhase" 819 dumpVars 820 821 # Evaluate the variable named $curPhase if it exists, otherwise the 822 # function named $curPhase. 823 eval "${!curPhase:-$curPhase}" 824 825 if [ "$curPhase" = unpackPhase ]; then 826 cd "${sourceRoot:-.}" 827 fi 828 829 if [ -n "$tracePhases" ]; then 830 echo 831 echo "@ phase-succeeded $out $curPhase" 832 fi 833 834 stopNest 835 done 836} 837 838 839# Execute the post-hooks. 840runHook postHook 841 842 843# Execute the global user hook (defined through the Nixpkgs 844# configuration option ‘stdenv.userHook’). This can be used to set 845# global compiler optimisation flags, for instance. 846runHook userHook 847 848 849dumpVars