at 24.11-pre 118 lines 4.6 kB view raw
1# CC Wrapper hygiene 2# 3# For at least cross compilation, we need to depend on multiple cc-wrappers at 4# once---specifically up to one per sort of dependency. This follows from having 5# different tools targeting different platforms, and different flags for those 6# tools. For example: 7# 8# # Flags for compiling (whether or not linking) C code for the... 9# NIX_CFLAGS_COMPILE_FOR_BUILD # ...build platform 10# NIX_CFLAGS_COMPILE # ...host platform 11# NIX_CFLAGS_COMPILE_FOR_TARGET # ...target platform 12# 13# Notice that these platforms are the 3 *relative* to the package using 14# cc-wrapper, not absolute like `x86_64-pc-linux-gnu`. 15# 16# The simplest solution would be to have separate cc-wrappers per (3 intended 17# use-cases * n absolute concrete platforms). For the use-case axis, we would 18# @-splice in 'BUILD_' '' 'TARGET_' to use the write environment variables when 19# building the cc-wrapper, and likewise prefix the binaries' names so they didn't 20# clobber each other on the PATH. But the need for 3x cc-wrappers, along with 21# non-standard name prefixes, is annoying and liable to break packages' build 22# systems. 23# 24# Instead, we opt to have just one cc-wrapper per absolute platform. Matching 25# convention, the binaries' names can just be prefixed with their target 26# platform. On the other hand, that means packages will depend on not just 27# multiple cc-wrappers, but the exact same cc-wrapper derivation multiple ways. 28# That means the exact same cc-wrapper derivation must be able to avoid 29# conflicting with itself, despite the fact that `setup-hook.sh`, the `addCvars` 30# function, and `add-flags.sh` are all communicating with each other with 31# environment variables. Yuck. 32# 33# The basic strategy is: 34# 35# - Everyone exclusively *adds information* to relative-platform-specific 36# environment variables, like `NIX_CFLAGS_COMPILE_FOR_TARGET`, to communicate 37# with the wrapped binaries. 38# 39# - The wrapped binaries will exclusively *read* cc-wrapper-derivation-specific 40# environment variables distinguished with with `suffixSalt`, like 41# `NIX_CFLAGS_COMPILE_@suffixSalt@`. 42# 43# - `add-flags`, beyond its old task of reading extra flags stuck inside the 44# cc-wrapper derivation, will convert the relative-platform-specific 45# variables to cc-wrapper-derivation-specific variables. This conversion is 46# the only time all but one of the cc-wrapper-derivation-specific variables 47# are set. 48# 49# This ensures the flow of information is exclusive from 50# relative-platform-specific variables to cc-wrapper-derivation-specific 51# variables. This allows us to support the general case of a many--many relation 52# between relative platforms and cc-wrapper derivations. 53# 54# For more details, read the individual files where the mechanisms used to 55# accomplish this will be individually documented. 56 57# Skip setup hook if we're neither a build-time dep, nor, temporarily, doing a 58# native compile. 59# 60# TODO(@Ericson2314): No native exception 61[[ -z ${strictDeps-} ]] || (( "$hostOffset" < 0 )) || return 0 62 63# It's fine that any other cc-wrapper will redefine this. Bash functions close 64# over no state, and there's no @-substitutions within, so any redefined 65# function is guaranteed to be exactly the same. 66ccWrapper_addCVars () { 67 # See ../setup-hooks/role.bash 68 local role_post 69 getHostRoleEnvHook 70 71 if [ -d "$1/include" ]; then 72 export NIX_CFLAGS_COMPILE${role_post}+=" -isystem $1/include" 73 fi 74 75 if [ -d "$1/Library/Frameworks" ]; then 76 export NIX_CFLAGS_COMPILE${role_post}+=" -iframework $1/Library/Frameworks" 77 fi 78} 79 80# See ../setup-hooks/role.bash 81getTargetRole 82getTargetRoleWrapper 83 84# We use the `targetOffset` to choose the right env hook to accumulate the right 85# sort of deps (those with that offset). 86addEnvHooks "$targetOffset" ccWrapper_addCVars 87 88# Note 1: these come *after* $out in the PATH (see setup.sh). 89# Note 2: phase separation makes this look useless to shellcheck. 90 91# shellcheck disable=SC2157 92if [ -n "@cc@" ]; then 93 addToSearchPath _PATH @cc@/bin 94fi 95 96# shellcheck disable=SC2157 97if [ -n "@libc_bin@" ]; then 98 addToSearchPath _PATH @libc_bin@/bin 99fi 100 101# shellcheck disable=SC2157 102if [ -n "@coreutils_bin@" ]; then 103 addToSearchPath _PATH @coreutils_bin@/bin 104fi 105 106# Export tool environment variables so various build systems use the right ones. 107 108export NIX_CC${role_post}=@out@ 109 110export CC${role_post}=@named_cc@ 111export CXX${role_post}=@named_cxx@ 112 113# If unset, assume the default hardening flags. 114: ${NIX_HARDENING_ENABLE="@default_hardening_flags_str@"} 115export NIX_HARDENING_ENABLE 116 117# No local scope in sourced file 118unset -v role_post