···33 stdenv,
44 enableMultilib,
55 targetConfig,
66- withoutTargetLibc,
76}:
8798let
···210209 '';
211210212211 preInstall =
212212+ # What follows is a horribly cursed hack.
213213+ #
214214+ # GCC will install its libraries to $out/lib, $out/lib32, $out/lib64,
215215+ # $out/$targetConfig/lib, $out/$targetConfig/lib32 or $out/$targetConfig/lib64,
216216+ # depending on whether it's built as native or cross, and the exact target spec.
217217+ #
218218+ # We can't predict what it's actually going to do, and we also can't just tell it
219219+ # to always install to $out/lib, but we want everything to end up in $out/lib
220220+ # for consistency (multilib weirdness aside).
221221+ #
222222+ # So, we create a bunch of symlinks before we run GCC's install phase,
223223+ # redirecting every possible directory it may want to write to to the place
224224+ # we actually want things to be installed.
225225+ # We will then nuke the symlinks in postInstall.
226226+ #
227227+ # FIXME: there must be a better way to do this.
213228 ''
214214- mkdir -p "$out/''${targetConfig}/lib"
215215- mkdir -p "''${!outputLib}/''${targetConfig}/lib"
229229+ declare -ga compatibilitySymlinks=()
230230+231231+ makeCompatibilitySymlink() {
232232+ for output in "$out" "''${!outputLib}"; do
233233+ local linkTarget="$1"
234234+ local linkName="$output/$2"
235235+236236+ echo "Creating compatibility symlink: $linkTarget -> $linkName"
237237+238238+ mkdir -p "$(dirname "$linkName")"
239239+ ln -s "$linkTarget" "$linkName"
240240+ compatibilitySymlinks+=("$linkName")
241241+ done
242242+ }
216243 ''
217244 +
218218- # if cross-compiling, link from $lib/lib to $lib/${targetConfig}.
219219- # since native-compiles have $lib/lib as a directory (not a
220220- # symlink), this ensures that in every case we can assume that
221221- # $lib/lib contains the .so files
222222- lib.optionalString (with stdenv; targetPlatform.config != hostPlatform.config) ''
223223- ln -Ts "''${!outputLib}/''${targetConfig}/lib" $lib/lib
245245+ # This will redirect $output/lib{32,64} to $output/lib.
246246+ # Multilib is special, because it creates $out/lib (for 32-bit)
247247+ # and $out/lib64 (for 64-bit). No other targets can have both.
248248+ lib.optionalString (!enableMultilib) ''
249249+ makeCompatibilitySymlink lib lib32
250250+ makeCompatibilitySymlink lib lib64
224251 ''
225252 +
226226- # Make `lib64` symlinks to `lib`.
227227- lib.optionalString
228228- (!enableMultilib && stdenv.hostPlatform.is64bit && !stdenv.hostPlatform.isMips64n32)
229229- ''
230230- ln -s lib "$out/''${targetConfig}/lib64"
231231- ln -s lib "''${!outputLib}/''${targetConfig}/lib64"
232232- ''
233233- +
234234- # On mips platforms, gcc follows the IRIX naming convention:
235235- #
236236- # $PREFIX/lib = mips32
237237- # $PREFIX/lib32 = mips64n32
238238- # $PREFIX/lib64 = mips64
239239- #
240240- # Make `lib32` symlinks to `lib`.
241241- lib.optionalString (!enableMultilib && stdenv.targetPlatform.isMips64n32) ''
242242- ln -s lib "$out/''${targetConfig}/lib32"
243243- ln -s lib "''${!outputLib}/''${targetConfig}/lib32"
253253+ # This will redirect $output/$targetConfig/lib{,32,64} to $output/lib.
254254+ lib.optionalString (with stdenv; targetPlatform.config != hostPlatform.config) ''
255255+ makeCompatibilitySymlink lib $targetConfig/lib32
256256+ makeCompatibilitySymlink lib $targetConfig/lib64
257257+ makeCompatibilitySymlink ../lib $targetConfig/lib
244258 '';
245259246246- postInstall = ''
247247- # Move runtime libraries to lib output.
248248- moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.so*" "''${!outputLib}"
249249- moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.la" "''${!outputLib}"
250250- moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.dylib" "''${!outputLib}"
251251- moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.dll.a" "''${!outputLib}"
252252- moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.dll" "''${!outputLib}"
253253- moveToOutput "share/gcc-*/python" "''${!outputLib}"
260260+ postInstall =
261261+ ''
262262+ # Clean up our compatibility symlinks (see above)
263263+ for link in "''${compatibilitySymlinks[@]}"; do
264264+ echo "Removing compatibility symlink: $link"
265265+ rm -f "$link"
266266+ done
254267255255- if [ -z "$enableShared" ]; then
256256- moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.a" "''${!outputLib}"
257257- fi
268268+ # Move runtime libraries to lib output.
269269+ moveToOutput "lib/lib*.so*" "''${!outputLib}"
270270+ moveToOutput "lib/lib*.la" "''${!outputLib}"
271271+ moveToOutput "lib/lib*.dylib" "''${!outputLib}"
272272+ moveToOutput "lib/lib*.dll.a" "''${!outputLib}"
273273+ moveToOutput "lib/lib*.dll" "''${!outputLib}"
274274+ moveToOutput "share/gcc-*/python" "''${!outputLib}"
258275259259- for i in "''${!outputLib}/''${targetConfig}"/lib/*.{la,py}; do
260260- substituteInPlace "$i" --replace "$out" "''${!outputLib}"
261261- done
276276+ if [ -z "$enableShared" ]; then
277277+ moveToOutput "lib/lib*.a" "''${!outputLib}"
278278+ fi
262279263263- if [ -n "$enableMultilib" ]; then
264264- moveToOutput "''${targetConfig+$targetConfig/}lib64/lib*.so*" "''${!outputLib}"
265265- moveToOutput "''${targetConfig+$targetConfig/}lib64/lib*.la" "''${!outputLib}"
266266- moveToOutput "''${targetConfig+$targetConfig/}lib64/lib*.dylib" "''${!outputLib}"
267267- moveToOutput "''${targetConfig+$targetConfig/}lib64/lib*.dll.a" "''${!outputLib}"
268268- moveToOutput "''${targetConfig+$targetConfig/}lib64/lib*.dll" "''${!outputLib}"
280280+ for i in "''${!outputLib}"/lib/*.{la,py}; do
281281+ substituteInPlace "$i" --replace "$out" "''${!outputLib}"
282282+ done
269283270270- for i in "''${!outputLib}/''${targetConfig}"/lib64/*.{la,py}; do
271271- substituteInPlace "$i" --replace "$out" "''${!outputLib}"
272272- done
273273- fi
284284+ if [ -n "$enableMultilib" ]; then
285285+ moveToOutput "lib64/lib*.so*" "''${!outputLib}"
286286+ moveToOutput "lib64/lib*.la" "''${!outputLib}"
287287+ moveToOutput "lib64/lib*.dylib" "''${!outputLib}"
288288+ moveToOutput "lib64/lib*.dll.a" "''${!outputLib}"
289289+ moveToOutput "lib64/lib*.dll" "''${!outputLib}"
274290275275- # Remove `fixincl' to prevent a retained dependency on the
276276- # previous gcc.
277277- rm -rf $out/libexec/gcc/*/*/install-tools
278278- rm -rf $out/lib/gcc/*/*/install-tools
291291+ for i in "''${!outputLib}"/lib64/*.{la,py}; do
292292+ substituteInPlace "$i" --replace "$out" "''${!outputLib}"
293293+ done
294294+ fi
295295+296296+ # Remove `fixincl' to prevent a retained dependency on the
297297+ # previous gcc.
298298+ rm -rf $out/libexec/gcc/*/*/install-tools
299299+ rm -rf $out/lib/gcc/*/*/install-tools
279300280280- # More dependencies with the previous gcc or some libs (gccbug stores the build command line)
281281- rm -rf $out/bin/gccbug
301301+ # More dependencies with the previous gcc or some libs (gccbug stores the build command line)
302302+ rm -rf $out/bin/gccbug
282303283283- if type "install_name_tool"; then
284284- for i in "''${!outputLib}"/lib/*.*.dylib "''${!outputLib}"/lib/*.so.[0-9]; do
285285- install_name_tool -id "$i" "$i" || true
286286- for old_path in $(otool -L "$i" | grep "$out" | awk '{print $1}'); do
287287- new_path=`echo "$old_path" | sed "s,$out,''${!outputLib},"`
288288- install_name_tool -change "$old_path" "$new_path" "$i" || true
289289- done
290290- done
291291- fi
304304+ if type "install_name_tool"; then
305305+ for i in "''${!outputLib}"/lib/*.*.dylib "''${!outputLib}"/lib/*.so.[0-9]; do
306306+ install_name_tool -id "$i" "$i" || true
307307+ for old_path in $(otool -L "$i" | grep "$out" | awk '{print $1}'); do
308308+ new_path=`echo "$old_path" | sed "s,$out,''${!outputLib},"`
309309+ install_name_tool -change "$old_path" "$new_path" "$i" || true
310310+ done
311311+ done
312312+ fi
292313293293- # Get rid of some "fixed" header files
294294- rm -rfv $out/lib/gcc/*/*/include-fixed/{root,linux,sys/mount.h,bits/statx.h,pthread.h}
314314+ # Get rid of some "fixed" header files
315315+ rm -rfv $out/lib/gcc/*/*/include-fixed/{root,linux,sys/mount.h,bits/statx.h,pthread.h}
295316296296- # Replace hard links for i686-pc-linux-gnu-gcc etc. with symlinks.
297297- for i in $out/bin/*-gcc*; do
298298- if cmp -s $out/bin/gcc $i; then
299299- ln -sfn gcc $i
300300- fi
301301- done
317317+ # Replace hard links for i686-pc-linux-gnu-gcc etc. with symlinks.
318318+ for i in $out/bin/*-gcc*; do
319319+ if cmp -s $out/bin/gcc $i; then
320320+ ln -sfn gcc $i
321321+ fi
322322+ done
302323303303- for i in $out/bin/c++ $out/bin/*-c++* $out/bin/*-g++*; do
304304- if cmp -s $out/bin/g++ $i; then
305305- ln -sfn g++ $i
306306- fi
307307- done
324324+ for i in $out/bin/c++ $out/bin/*-c++* $out/bin/*-g++*; do
325325+ if cmp -s $out/bin/g++ $i; then
326326+ ln -sfn g++ $i
327327+ fi
328328+ done
308329309309- # Two identical man pages are shipped (moving and compressing is done later)
310310- for i in "$out"/share/man/man1/*g++.1; do
311311- if test -e "$i"; then
312312- man_prefix=`echo "$i" | sed "s,.*/\(.*\)g++.1,\1,"`
313313- ln -sf "$man_prefix"gcc.1 "$i"
314314- fi
315315- done
316316- '';
317317- }
318318- // lib.optionalAttrs ((stdenv.targetPlatform.config != stdenv.hostPlatform.config) && withoutTargetLibc) {
319319- dontCheckForBrokenSymlinks = true;
330330+ # Two identical man pages are shipped (moving and compressing is done later)
331331+ for i in "$out"/share/man/man1/*g++.1; do
332332+ if test -e "$i"; then
333333+ man_prefix=`echo "$i" | sed "s,.*/\(.*\)g++.1,\1,"`
334334+ ln -sf "$man_prefix"gcc.1 "$i"
335335+ fi
336336+ done
337337+ ''
338338+ +
339339+ # Recreate the target symlink so GCC can find libgcc_s on non-split builds.
340340+ lib.optionalString (with stdenv; targetPlatform.config != hostPlatform.config) ''
341341+ ln -s $lib/lib $lib/$targetConfig/lib
342342+ '';
320343 }
321344))