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