Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
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 local found=
72
73 if [ -d "$1/include" ]; then
74 export NIX_CFLAGS_COMPILE${role_post}+=" -isystem $1/include"
75 found=1
76 fi
77
78 if [ -d "$1/Library/Frameworks" ]; then
79 export NIX_CFLAGS_COMPILE${role_post}+=" -iframework $1/Library/Frameworks"
80 found=1
81 fi
82
83 if [[ -n "@useMacroPrefixMap@" && -n ${NIX_STORE:-} && -n $found ]]; then
84 local scrubbed="$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${1#"$NIX_STORE"/*-}"
85 export NIX_CFLAGS_COMPILE${role_post}+=" -fmacro-prefix-map=$1=$scrubbed"
86 fi
87}
88
89# See ../setup-hooks/role.bash
90getTargetRole
91getTargetRoleWrapper
92
93# We use the `targetOffset` to choose the right env hook to accumulate the right
94# sort of deps (those with that offset).
95addEnvHooks "$targetOffset" ccWrapper_addCVars
96
97# Note 1: these come *after* $out in the PATH (see setup.sh).
98# Note 2: phase separation makes this look useless to shellcheck.
99
100# shellcheck disable=SC2157
101if [ -n "@cc@" ]; then
102 addToSearchPath _PATH @cc@/bin
103fi
104
105# shellcheck disable=SC2157
106if [ -n "@libc_bin@" ]; then
107 addToSearchPath _PATH @libc_bin@/bin
108fi
109
110# shellcheck disable=SC2157
111if [ -n "@coreutils_bin@" ]; then
112 addToSearchPath _PATH @coreutils_bin@/bin
113fi
114
115# Export tool environment variables so various build systems use the right ones.
116
117export NIX_CC${role_post}=@out@
118
119export CC${role_post}=@named_cc@
120export CXX${role_post}=@named_cxx@
121
122# If unset, assume the default hardening flags.
123: ${NIX_HARDENING_ENABLE="@default_hardening_flags_str@"}
124export NIX_HARDENING_ENABLE
125
126# No local scope in sourced file
127unset -v role_post