5 # For cmd | while read; do ...; done
9 if [ -n "@coreutils_bin@" ]; then
10 PATH
="@coreutils_bin@/bin"
13 declare -ri recurThreshold
=200
14 declare -i overflowCount
=0
16 declare -ar origArgs
=("$@")
18 # Throw away what we won't need
19 declare -a parentArgs
=()
24 echo "cctools LD does not support '-l foo'" >&2
27 -lazy_library |
-reexport_library |
-upward_library |
-weak_library)
31 -l* |
*.so.
* |
*.dylib |
-lazy-l* |
-reexport-l* |
-upward-l* |
-weak-l*)
39 # Evidentally ld doesn't like using the child's RPATH, so it still
41 parentArgs
+=("$1" "$2")
50 parentArgs
+=("$1" "$2")
53 -install_name |
-dylib_install_name |
-dynamic-linker |
-plugin)
54 parentArgs
+=("$1" "$2")
58 # Only an rpath to the child is needed, which we will add
62 if [[ -f "$1" ]]; then
63 # Propabably a non-standard object file like Haskell's
64 # `.dyn_o`. Skip it like other inputs
76 if (( "$overflowCount" <= "$recurThreshold" )); then
77 if [ -n "${NIX_DEBUG:-}" ]; then
78 echo "ld-wrapper: Only ${overflowCount} inputs counted while ${recurThreshold} is the ceiling, linking normally. " >&2
81 exec @prog@
"${origArgs[@]}"
86 if [ -n "${NIX_DEBUG:-}" ]; then
87 echo "ld-wrapper: ${overflowCount} inputs counted when ${recurThreshold} is the ceiling, inspecting further. " >&2
90 # Collect the normalized linker input
93 # Arguments are null-separated
94 @prog@
--dump-normalized-lib-args "${origArgs[@]}" |
95 while IFS
= read -r -d '' input
; do
99 declare -i leafCount
=0
101 declare -a childrenInputs
=() trailingInputs
=()
102 while (( "${#norm[@]}" )); do
104 -lazy_library |
-upward_library)
105 # TODO(@Ericson2314): Don't do that, but intersperse children
107 echo "ld-wrapper: Warning: Potentially changing link order" >&2
108 trailingInputs
+=("${norm[0]}" "${norm[1]}")
109 norm
=("${norm[@]:2}")
111 -reexport_library |
-weak_library)
112 childrenInputs
+=("${norm[0]}" "${norm[1]}")
113 if [[ "${norm[1]}" != "$lastLeaf" ]]; then
115 lastLeaf
="${norm[1]}"
117 norm
=("${norm[@]:2}")
120 childrenInputs
+=(-reexport_library "${norm[0]}")
121 if [[ "${norm[0]}" != "$lastLeaf" ]]; then
123 lastLeaf
="${norm[0]}"
125 norm
=("${norm[@]:1}")
128 # Don't delegate object files or static libs
129 parentArgs
+=("${norm[0]}")
130 norm
=("${norm[@]:1}")
133 if [[ -f "${norm[0]}" ]]; then
134 # Propabably a non-standard object file. We'll let it by.
135 parentArgs
+=("${norm[0]}")
136 norm
=("${norm[@]:1}")
138 echo "ld-wrapper: Internal Error: Invalid normalized argument" >&2
147 if (( "$leafCount" <= "$recurThreshold" )); then
148 if [ -n "${NIX_DEBUG:-}" ]; then
149 echo "ld-wrapper: Only ${leafCount} *dynamic* inputs counted while ${recurThreshold} is the ceiling, linking normally. " >&2
152 exec @prog@
"${origArgs[@]}"
157 if [ -n "${NIX_DEBUG:-}" ]; then
158 echo "ld-wrapper: ${leafCount} *dynamic* inputs counted when ${recurThreshold} is the ceiling, delegating to children. " >&2
161 declare -r outputNameLibless
=$
( \
162 if [[ -z "${outputName:+isUndefined}" ]]; then
166 baseName
=$
(basename ${outputName})
167 if [[ "$baseName" = lib
* ]]; then
168 baseName
="${baseName:3}"
172 declare -ra children
=(
173 "$outputNameLibless-reexport-delegate-0"
174 "$outputNameLibless-reexport-delegate-1"
179 symbolBloatObject
=$outputNameLibless-symbol-hack.o
180 if [[ ! -f $symbolBloatObject ]]; then
181 # `-Q` means use GNU Assembler rather than Clang, avoiding an awkward
183 printf '.private_extern _______child_hack_foo\nchild_hack_foo:\n' |
184 PATH
="$PATH:@out@/bin" @targetPrefix@as
-Q -- -o $symbolBloatObject
187 # Split inputs between children
188 declare -a child0Inputs
=() child1Inputs
=("${childrenInputs[@]}")
189 let "countFirstChild = $leafCount / 2" || true
191 while (( "$countFirstChild" )); do
192 case "${child1Inputs[0]}" in
193 -reexport_library |
-weak_library)
194 child0Inputs
+=("${child1Inputs[0]}" "${child1Inputs[1]}")
195 if [[ "${child1Inputs[1]}" != "$lastLeaf" ]]; then
196 let countFirstChild-
=1 || true
197 lastLeaf
="${child1Inputs[1]}"
199 child1Inputs
=("${child1Inputs[@]:2}")
202 child0Inputs
+=(-reexport_library "${child1Inputs[0]}")
203 if [[ "${child1Inputs[0]}" != "$lastLeaf" ]]; then
204 let countFirstChild-
=1 || true
205 lastLeaf
="${child1Inputs[1]}"
207 child1Inputs
=("${child1Inputs[@]:2}")
210 echo "ld-wrapper: Internal Error: Invalid delegated input" >&2
218 @out@
/bin
/@targetPrefix@ld \
219 -macosx_version_min $MACOSX_DEPLOYMENT_TARGET -arch x86_64
-dylib \
220 -o "$out/lib/lib${children[0]}.dylib" \
221 -install_name "$out/lib/lib${children[0]}.dylib" \
222 "$symbolBloatObject" "${child0Inputs[@]}" "${trailingInputs[@]}"
224 # Second half of libs
225 @out@
/bin
/@targetPrefix@ld \
226 -macosx_version_min $MACOSX_DEPLOYMENT_TARGET -arch x86_64
-dylib \
227 -o "$out/lib/lib${children[1]}.dylib" \
228 -install_name "$out/lib/lib${children[1]}.dylib" \
229 "$symbolBloatObject" "${child1Inputs[@]}" "${trailingInputs[@]}"
231 parentArgs
+=("-L$out/lib" -rpath "$out/lib")
232 if [[ $outputName != *reexport-delegate
* ]]; then
233 parentArgs
+=("-l${children[0]}" "-l${children[1]}")
235 parentArgs
+=("-reexport-l${children[0]}" "-reexport-l${children[1]}")
238 parentArgs
+=("${trailingInputs[@]}")
240 if [ -n "${NIX_DEBUG:-}" ]; then
241 echo "flags using delegated children to @prog@:" >&2
242 printf " %q\n" "${parentArgs[@]}" >&2
246 exec @prog@
"${parentArgs[@]}"