···11+# N.B. It may be a surprise that the derivation-specific variables are exported,
22+# since this is just sourced by the wrapped binaries---the end consumers. This
33+# is because one wrapper binary may invoke another (e.g. cc invoking ld). In
44+# that case, it is cheaper/better to not repeat this step and let the forked
55+# wrapped binary just inherit the work of the forker's wrapper script.
66+77+# Accumulate prefixes for taking in the right input parameters. See setup-hook
88+# for details.
99+declare -a role_prefixes=()
1010+if [[ -n "${NIX_CC_WRAPPER_@infixSalt@_TARGET_BUILD:-}" ]]; then
1111+ role_prefixes+=(_BUILD)
1212+fi
1313+if [[ -n "${NIX_CC_WRAPPER_@infixSalt@_TARGET_HOST:-}" ]]; then
1414+ role_prefixes+=('')
1515+fi
1616+if [[ -n "${NIX_CC_WRAPPER_@infixSalt@_TARGET_TARGET:-}" ]]; then
1717+ role_prefixes+=(_TARGET)
1818+fi
1919+2020+# For each role we serve, we accumulate the input parameters into our own
2121+# cc-wrapper-derivation-specific environment variables.
2222+for pre in "${role_prefixes[@]}"; do
2323+ # We need to mangle names for hygiene, but also take parameters/overrides
2424+ # from the environment.
2525+ slurpUnsalted () {
2626+ case "$1" in
2727+ CC_WRAPPER_*)
2828+ local firstPre=NIX_CC_WRAPPER_
2929+ local varname="${1#CC_WRAPPER_}"
3030+ ;;
3131+ LD_WRAPPER_*)
3232+ local firstPre=NIX_LD_WRAPPER_
3333+ local varname="${1#LD_WRAPPER_}"
3434+ ;;
3535+ *)
3636+ local firstPre=NIX_
3737+ local varname="$1"
3838+ ;;
3939+ esac
4040+ local inputVar="${firstPre}${pre}${varname}"
4141+ local outputVar="${firstPre}@infixSalt@_${varname}"
4242+ local delimiter=''
4343+ if [[ -n "${!outputVar:-}" && -n "${!inputVar:-}" ]]; then
4444+ delimiter=' '
4545+ fi
4646+ # Easiest to just do this to deal with either the input or (old) output.
4747+ set +u
4848+ export ${outputVar}+="${delimiter}${!inputVar}"
4949+ set -u
5050+ }
5151+5252+ slurpUnsalted CC_WRAPPER_START_HOOK
5353+ slurpUnsalted CC_WRAPPER_EXEC_HOOK
5454+ slurpUnsalted LD_WRAPPER_START_HOOK
5555+ slurpUnsalted LD_WRAPPER_EXEC_HOOK
5656+5757+ slurpUnsalted CFLAGS_COMPILE
5858+ slurpUnsalted CFLAGS_LINK
5959+ slurpUnsalted CXXSTDLIB_COMPILE
6060+ slurpUnsalted CXXSTDLIB_LINK
6161+ slurpUnsalted DONT_SET_RPATH
6262+ slurpUnsalted GNATFLAGS_COMPILE
6363+ slurpUnsalted IGNORE_LD_THROUGH_GCC
6464+ slurpUnsalted LDFLAGS
6565+ slurpUnsalted LDFLAGS_BEFORE
6666+ slurpUnsalted LDFLAGS_AFTER
6767+ slurpUnsalted LDFLAGS_HARDEN
6868+6969+ slurpUnsalted SET_BUILD_ID
7070+ slurpUnsalted DONT_SET_RPATH
7171+ slurpUnsalted ENFORCE_NO_NATIVE
7272+done
7373+unset -f slurpUnsalted
7474+175# `-B@out@/bin' forces cc to use ld-wrapper.sh when calling ld.
276export NIX_@infixSalt@_CFLAGS_COMPILE="-B@out@/bin/ $NIX_@infixSalt@_CFLAGS_COMPILE"
377···34108 NIX_@infixSalt@_LDFLAGS_BEFORE="$(< @out@/nix-support/libc-ldflags-before) $NIX_@infixSalt@_LDFLAGS_BEFORE"
35109fi
36110111111+# That way forked processes don't againt extend these environment variables
37112export NIX_CC_WRAPPER_@infixSalt@_FLAGS_SET=1
+101-15
pkgs/build-support/cc-wrapper/setup-hook.sh
···11+# CC Wrapper hygiene
22+#
33+# For at least cross compilation, we need to depend on multiple cc-wrappers at
44+# once---specifically up to one per sort of dependency. This follows from having
55+# different tools targeting different platforms, and different flags for those
66+# tools. For example:
77+#
88+# # Flags for compiling (whether or not linking) C code for the...
99+# NIX_BUILD_CFLAGS_COMPILE # ...build platform
1010+# NIX_CFLAGS_COMPILE # ...host platform
1111+# NIX_TARGET_CFLAGS_COMPILE # ...target platform
1212+#
1313+# Notice that these platforms are the 3 *relative* to the package using
1414+# cc-wrapper, not absolute like `x86_64-pc-linux-gnu`.
1515+#
1616+# The simplest solution would be to have separate cc-wrappers per (3 intended
1717+# use-cases * n absolute concrete platforms). For the use-case axis, we would
1818+# @-splice in 'BUILD_' '' 'TARGET_' to use the write environment variables when
1919+# building the cc-wrapper, and likewise prefix the binaries' names so they didn't
2020+# clobber each other on the PATH. But the need for 3x cc-wrappers, along with
2121+# non-standard name prefixes, is annoying and liable to break packages' build
2222+# systems.
2323+#
2424+# Instead, we opt to have just one cc-wrapper per absolute platform. Matching
2525+# convention, the binaries' names can just be prefixed with their target
2626+# platform. On the other hand, that means packages will depend on not just
2727+# multiple cc-wrappers, but the exact same cc-wrapper derivation multiple ways.
2828+# That means the exact same cc-wrapper derivation must be able to avoid
2929+# conflicting with itself, despite the fact that `setup-hook.sh`, the `addCvars`
3030+# function, and `add-flags.sh` are all communicating with each other with
3131+# environment variables. Yuck.
3232+#
3333+# The basic strategy is:
3434+#
3535+# - Everyone exclusively *adds information* to relative-platform-specific
3636+# environment variables, like `NIX_TARGET_CFLAGS_COMPILE`, to communicate
3737+# with the wrapped binaries.
3838+#
3939+# - The wrapped binaries will exclusively *read* cc-wrapper-derivation-specific
4040+# environment variables distinguished with with `infixSalt`, like
4141+# `NIX_@infixSalt@_CFLAGS_COMPILE`.
4242+#
4343+# - `add-flags`, beyond its old task of reading extra flags stuck inside the
4444+# cc-wrapper derivation, will convert the relative-platform-specific
4545+# variables to cc-wrapper-derivation-specific variables. This conversion is
4646+# the only time all but one of the cc-wrapper-derivation-specific variables
4747+# are set.
4848+#
4949+# This ensures the flow of information is exclusive from
5050+# relative-platform-specific variables to cc-wrapper-derivation-specific
5151+# variables. This allows us to support the general case of a many--many relation
5252+# between relative platforms and cc-wrapper derivations.
5353+#
5454+# For more details, read the individual files where the mechanisms used to
5555+# accomplish this will be individually documented.
5656+5757+5858+# It's fine that any other cc-wrapper will redefine this. Bash functions close
5959+# over no state, and there's no @-substitutions within, so any redefined
6060+# function is guaranteed to be exactly the same.
161ccWrapper_addCVars () {
6262+ # The `depOffset` describes how the platforms of the dependencies are slid
6363+ # relative to the depending package. It is brought into scope of the
6464+ # environment hook defined as the role of the dependency being applied.
6565+ case $depOffset in
6666+ -1) local role='BUILD_' ;;
6767+ 0) local role='' ;;
6868+ 1) local role='TARGET_' ;;
6969+ *) echo "cc-wrapper: Error: Cannot be used with $depOffset-offset deps, " >2;
7070+ return 1 ;;
7171+ esac
7272+273 if [[ -d "$1/include" ]]; then
33- export NIX_CFLAGS_COMPILE+=" ${ccIncludeFlag:--isystem} $1/include"
7474+ export NIX_${role}CFLAGS_COMPILE+=" ${ccIncludeFlag:--isystem} $1/include"
475 fi
576677 if [[ -d "$1/lib64" && ! -L "$1/lib64" ]]; then
77- export NIX_LDFLAGS+=" -L$1/lib64"
7878+ export NIX_${role}LDFLAGS+=" -L$1/lib64"
879 fi
9801081 if [[ -d "$1/lib" ]]; then
1111- export NIX_LDFLAGS+=" -L$1/lib"
8282+ export NIX_${role}LDFLAGS+=" -L$1/lib"
1283 fi
13841485 if [[ -d "$1/Library/Frameworks" ]]; then
1515- export NIX_CFLAGS_COMPILE+=" -F$1/Library/Frameworks"
8686+ export NIX_${role}CFLAGS_COMPILE+=" -F$1/Library/Frameworks"
1687 fi
1788}
18899090+# Since the same cc-wrapper derivation can be depend on in multiple ways, we
9191+# need to accumulate *each* role (i.e. target platform relative the depending
9292+# derivation) in which the cc-wrapper derivation is used.
9393+# `NIX_CC_WRAPPER_@infixSalt@_TARGET_*` tracks this (needs to be an exported env
9494+# var so can't use fancier data structures).
9595+#
9696+# We also need to worry about what role is being added on *this* invocation of
9797+# setup-hook, which `role` tracks.
9898+if [ -n "${crossConfig:-}" ]; then
9999+ export NIX_CC_WRAPPER_@infixSalt@_TARGET_BUILD=1
100100+ role="BUILD_"
101101+else
102102+ export NIX_CC_WRAPPER_@infixSalt@_TARGET_HOST=1
103103+ role=""
104104+fi
105105+106106+# Eventually the exact sort of env-hook we create will depend on the role. This
107107+# is because based on what relative platform we are targeting, we use different
108108+# dependencies.
19109envHooks+=(ccWrapper_addCVars)
2011021111# Note 1: these come *after* $out in the PATH (see setup.sh).
···41131 addToSearchPath _PATH @coreutils_bin@/bin
42132fi
431334444-if [ -z "${crossConfig:-}" ]; then
4545- ENV_PREFIX=""
4646-else
4747- ENV_PREFIX="BUILD_"
4848-fi
134134+# Export tool environment variables so various build systems use the right ones.
491355050-export NIX_${ENV_PREFIX}CC=@out@
136136+export NIX_${role}CC=@out@
511375252-export ${ENV_PREFIX}CC=@named_cc@
5353-export ${ENV_PREFIX}CXX=@named_cxx@
138138+export ${role}CC=@named_cc@
139139+export ${role}CXX=@named_cxx@
5414055141for CMD in \
56142 cpp \
···59145 if
60146 PATH=$_PATH type -p "@binPrefix@$CMD" > /dev/null
61147 then
6262- export "${ENV_PREFIX}$(echo "$CMD" | tr "[:lower:]" "[:upper:]")=@binPrefix@${CMD}";
148148+ export "${role}$(echo "$CMD" | tr "[:lower:]" "[:upper:]")=@binPrefix@${CMD}";
63149 fi
64150done
651516666-# No local scope available for sourced files
6767-unset ENV_PREFIX
152152+# No local scope in sourced file
153153+unset role
+13
pkgs/stdenv/generic/setup.sh
···336336337337# Set the relevant environment variables to point to the build inputs
338338# found above.
339339+#
340340+# These `depOffset`s tell the env hook what sort of dependency
341341+# (ignoring propagatedness) is being passed to the env hook. In a real
342342+# language, we'd append a closure with this information to the
343343+# relevant env hook array, but bash doesn't have closures, so it's
344344+# easier to just pass this in.
345345+339346_addToNativeEnv() {
340347 local pkg="$1"
348348+ if [[ -n "${crossConfig:-}" ]]; then
349349+ local -i depOffset=-1
350350+ else
351351+ local -i depOffset=0
352352+ fi
341353342354 # Run the package-specific hooks set by the setup-hook scripts.
343355 runHook envHook "$pkg"
···349361350362_addToCrossEnv() {
351363 local pkg="$1"
364364+ local -i depOffset=0
352365353366 # Run the package-specific hooks set by the setup-hook scripts.
354367 runHook crossEnvHook "$pkg"