coder: 2.16.1 -> 2.17.3 (#363393)
[NixPkgs.git] / pkgs / build-support / cc-wrapper / cc-wrapper.sh
blobda1a709684dac2e23d21ab94e0429dd3a5904fb7
1 #! @shell@
2 set -eu -o pipefail +o posix
3 shopt -s nullglob
5 if (( "${NIX_DEBUG:-0}" >= 7 )); then
6 set -x
7 fi
9 path_backup="$PATH"
11 # That @-vars are substituted separately from bash evaluation makes
12 # shellcheck think this, and others like it, are useless conditionals.
13 # shellcheck disable=SC2157
14 if [[ -n "@coreutils_bin@" && -n "@gnugrep_bin@" ]]; then
15 PATH="@coreutils_bin@/bin:@gnugrep_bin@/bin"
18 source @out@/nix-support/utils.bash
20 source @out@/nix-support/darwin-sdk-setup.bash
23 # Parse command line options and set several variables.
24 # For instance, figure out if linker flags should be passed.
25 # GCC prints annoying warnings when they are not needed.
26 dontLink=0
27 nonFlagArgs=0
28 cc1=0
29 # shellcheck disable=SC2193
30 [[ "@prog@" = *++ ]] && isCxx=1 || isCxx=0
31 cxxInclude=1
32 cxxLibrary=1
33 cInclude=1
35 expandResponseParams "$@"
37 declare -ag positionalArgs=()
38 declare -i n=0
39 nParams=${#params[@]}
40 while (( "$n" < "$nParams" )); do
41 p=${params[n]}
42 p2=${params[n+1]:-} # handle `p` being last one
43 n+=1
45 case "$p" in
46 -[cSEM] | -MM) dontLink=1 ;;
47 -cc1) cc1=1 ;;
48 -nostdinc) cInclude=0 cxxInclude=0 ;;
49 -nostdinc++) cxxInclude=0 ;;
50 -nostdlib) cxxLibrary=0 ;;
51 -x*-header) dontLink=1 ;; # both `-x c-header` and `-xc-header` are accepted by clang
52 -xc++*) isCxx=1 ;; # both `-xc++` and `-x c++` are accepted by clang
53 -x)
54 case "$p2" in
55 *-header) dontLink=1 ;;
56 c++*) isCxx=1 ;;
57 esac
59 --) # Everything else is positional args!
60 # See: https://github.com/llvm/llvm-project/commit/ed1d07282cc9d8e4c25d585e03e5c8a1b6f63a74
62 # Any positional arg (i.e. any argument after `--`) will be
63 # interpreted as a "non flag" arg:
64 if [[ -v "params[$n]" ]]; then nonFlagArgs=1; fi
66 positionalArgs=("${params[@]:$n}")
67 params=("${params[@]:0:$((n - 1))}")
68 break;
70 -?*) ;;
71 *) nonFlagArgs=1 ;; # Includes a solitary dash (`-`) which signifies standard input; it is not a flag
72 esac
73 done
75 # If we pass a flag like -Wl, then gcc will call the linker unless it
76 # can figure out that it has to do something else (e.g., because of a
77 # "-c" flag). So if no non-flag arguments are given, don't pass any
78 # linker flags. This catches cases like "gcc" (should just print
79 # "gcc: no input files") and "gcc -v" (should print the version).
80 if [ "$nonFlagArgs" = 0 ]; then
81 dontLink=1
84 # Arocc does not link
85 if [ "@isArocc@" = 1 ]; then
86 dontLink=1
89 # Optionally filter out paths not refering to the store.
90 if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "$NIX_STORE" ]]; then
91 kept=()
92 nParams=${#params[@]}
93 declare -i n=0
94 while (( "$n" < "$nParams" )); do
95 p=${params[n]}
96 p2=${params[n+1]:-} # handle `p` being last one
97 n+=1
99 skipNext=false
100 path=""
101 case "$p" in
102 -[IL]/*) path=${p:2} ;;
103 -[IL] | -isystem) path=$p2 skipNext=true ;;
104 esac
106 if [[ -n $path ]] && badPathWithDarwinSdk "$path"; then
107 skip "$path"
108 $skipNext && n+=1
109 continue
112 kept+=("$p")
113 done
114 # Old bash empty array hack
115 params=(${kept+"${kept[@]}"})
118 # Flirting with a layer violation here.
119 if [ -z "${NIX_BINTOOLS_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then
120 source @bintools@/nix-support/add-flags.sh
123 # Put this one second so libc ldflags take priority.
124 if [ -z "${NIX_CC_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then
125 source @out@/nix-support/add-flags.sh
128 # Clear march/mtune=native -- they bring impurity.
129 if [ "$NIX_ENFORCE_NO_NATIVE_@suffixSalt@" = 1 ]; then
130 kept=()
131 # Old bash empty array hack
132 for p in ${params+"${params[@]}"}; do
133 if [[ "$p" = -m*=native ]]; then
134 skip "$p"
135 else
136 kept+=("$p")
138 done
139 # Old bash empty array hack
140 params=(${kept+"${kept[@]}"})
143 if [[ "$isCxx" = 1 ]]; then
144 if [[ "$cxxInclude" = 1 ]]; then
146 # The motivation for this comment is to explain the reason for appending
147 # the C++ stdlib to NIX_CFLAGS_COMPILE, which I initially thought should
148 # change and later realized it shouldn't in:
150 # https://github.com/NixOS/nixpkgs/pull/185569#issuecomment-1234959249
152 # NIX_CFLAGS_COMPILE contains dependencies added using "-isystem", and
153 # NIX_CXXSTDLIB_COMPILE adds the C++ stdlib using "-isystem". Appending
154 # NIX_CXXSTDLIB_COMPILE to NIX_CLAGS_COMPILE emulates this part of the
155 # include lookup order from GCC/Clang:
157 # > 4. Directories specified with -isystem options are scanned in
158 # > left-to-right order.
159 # > 5. Standard system directories are scanned.
160 # > 6. Directories specified with -idirafter options are scanned
161 # > in left-to-right order.
163 # NIX_CXX_STDLIB_COMPILE acts as the "standard system directories" that
164 # are otherwise missing from CC in nixpkgs, so should be added last.
166 # This means that the C standard library should never be present inside
167 # NIX_CFLAGS_COMPILE, because it MUST come after the C++ stdlib. It is
168 # added automatically by cc-wrapper later using "-idirafter".
170 NIX_CFLAGS_COMPILE_@suffixSalt@+=" $NIX_CXXSTDLIB_COMPILE_@suffixSalt@"
172 if [[ "$cxxLibrary" = 1 ]]; then
173 NIX_CFLAGS_LINK_@suffixSalt@+=" $NIX_CXXSTDLIB_LINK_@suffixSalt@"
177 source @out@/nix-support/add-hardening.sh
179 # Add the flags for the C compiler proper.
180 extraAfter=(${hardeningCFlagsAfter[@]+"${hardeningCFlagsAfter[@]}"} $NIX_CFLAGS_COMPILE_@suffixSalt@)
181 extraBefore=(${hardeningCFlagsBefore[@]+"${hardeningCFlagsBefore[@]}"} $NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@)
183 if [ "$dontLink" != 1 ]; then
184 linkType=$(checkLinkType $NIX_LDFLAGS_BEFORE_@suffixSalt@ "${params[@]}" ${NIX_CFLAGS_LINK_@suffixSalt@:-} $NIX_LDFLAGS_@suffixSalt@)
186 # Add the flags that should only be passed to the compiler when
187 # linking.
188 extraAfter+=($(filterRpathFlags "$linkType" $NIX_CFLAGS_LINK_@suffixSalt@))
190 # Add the flags that should be passed to the linker (and prevent
191 # `ld-wrapper' from adding NIX_LDFLAGS_@suffixSalt@ again).
192 for i in $(filterRpathFlags "$linkType" $NIX_LDFLAGS_BEFORE_@suffixSalt@); do
193 extraBefore+=("-Wl,$i")
194 done
195 if [[ "$linkType" == dynamic && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; then
196 extraBefore+=("-Wl,-dynamic-linker=$NIX_DYNAMIC_LINKER_@suffixSalt@")
198 for i in $(filterRpathFlags "$linkType" $NIX_LDFLAGS_@suffixSalt@); do
199 if [ "${i:0:3}" = -L/ ]; then
200 extraAfter+=("$i")
201 else
202 extraAfter+=("-Wl,$i")
204 done
205 export NIX_LINK_TYPE_@suffixSalt@=$linkType
208 if [[ -e @out@/nix-support/add-local-cc-cflags-before.sh ]]; then
209 source @out@/nix-support/add-local-cc-cflags-before.sh
212 # As a very special hack, if the arguments are just `-v', then don't
213 # add anything. This is to prevent `gcc -v' (which normally prints
214 # out the version number and returns exit code 0) from printing out
215 # `No input files specified' and returning exit code 1.
216 if [ "$*" = -v ]; then
217 extraAfter=()
218 extraBefore=()
221 # clang's -cc1 mode is not compatible with most options
222 # that we would pass. Rather than trying to pass only
223 # options that would work, let's just remove all of them.
224 if [ "$cc1" = 1 ]; then
225 extraAfter=()
226 extraBefore=()
229 # Finally, if we got any positional args, append them to `extraAfter`
230 # now:
231 if [[ "${#positionalArgs[@]}" -gt 0 ]]; then
232 extraAfter+=(-- "${positionalArgs[@]}")
235 # Optionally print debug info.
236 if (( "${NIX_DEBUG:-0}" >= 1 )); then
237 # Old bash workaround, see ld-wrapper for explanation.
238 echo "extra flags before to @prog@:" >&2
239 printf " %q\n" ${extraBefore+"${extraBefore[@]}"} >&2
240 echo "original flags to @prog@:" >&2
241 printf " %q\n" ${params+"${params[@]}"} >&2
242 echo "extra flags after to @prog@:" >&2
243 printf " %q\n" ${extraAfter+"${extraAfter[@]}"} >&2
246 PATH="$path_backup"
247 # Old bash workaround, see above.
249 # if a cc-wrapper-hook exists, run it.
250 if [[ -e @out@/nix-support/cc-wrapper-hook ]]; then
251 compiler=@prog@
252 source @out@/nix-support/cc-wrapper-hook
255 if (( "${NIX_CC_USE_RESPONSE_FILE:-@use_response_file_by_default@}" >= 1 )); then
256 responseFile=$(@mktemp@ "${TMPDIR:-/tmp}/cc-params.XXXXXX")
257 trap '@rm@ -f -- "$responseFile"' EXIT
258 printf "%q\n" \
259 ${extraBefore+"${extraBefore[@]}"} \
260 ${params+"${params[@]}"} \
261 ${extraAfter+"${extraAfter[@]}"} > "$responseFile"
262 @prog@ "@$responseFile"
263 else
264 exec @prog@ \
265 ${extraBefore+"${extraBefore[@]}"} \
266 ${params+"${params[@]}"} \
267 ${extraAfter+"${extraAfter[@]}"}