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