syndicate_utils: 20240509 -> 20250110
[NixPkgs.git] / pkgs / development / compilers / gcc / common / builder.nix
blobce6041c97409449638ce3e3aded8d3a65b22395f
2   lib,
3   stdenv,
4   enableMultilib,
5   targetConfig,
6 }:
8 let
9   forceLibgccToBuildCrtStuff = import ./libgcc-buildstuff.nix { inherit lib stdenv; };
12 originalAttrs:
13 (stdenv.mkDerivation (
14   finalAttrs:
15   originalAttrs
16   // {
17     passthru = (originalAttrs.passthru or { }) // {
18       inherit forceLibgccToBuildCrtStuff;
19     };
20     preUnpack = ''
21       oldOpts="$(shopt -po nounset)" || true
22       set -euo pipefail
24       export NIX_FIXINC_DUMMY="$NIX_BUILD_TOP/dummy"
25       mkdir "$NIX_FIXINC_DUMMY"
27       if test "$staticCompiler" = "1"; then
28           EXTRA_LDFLAGS="-static"
29       elif test "''${NIX_DONT_SET_RPATH-}" != "1"; then
30           EXTRA_LDFLAGS="-Wl,-rpath,''${!outputLib}/lib"
31       else
32           EXTRA_LDFLAGS=""
33       fi
35       # GCC interprets empty paths as ".", which we don't want.
36       if test -z "''${CPATH-}"; then unset CPATH; fi
37       if test -z "''${LIBRARY_PATH-}"; then unset LIBRARY_PATH; fi
38       echo "\$CPATH is \`''${CPATH-}'"
39       echo "\$LIBRARY_PATH is \`''${LIBRARY_PATH-}'"
41       if test "$noSysDirs" = "1"; then
43           declare -g \
44               EXTRA_FLAGS_FOR_BUILD EXTRA_FLAGS EXTRA_FLAGS_FOR_TARGET \
45               EXTRA_LDFLAGS_FOR_BUILD EXTRA_LDFLAGS_FOR_TARGET
47           # Extract flags from Bintools Wrappers
48           for post in '_FOR_BUILD' ""; do
49               curBintools="NIX_BINTOOLS''${post}"
51               declare -a extraLDFlags=()
52               if [[ -e "''${!curBintools}/nix-support/orig-libc" ]]; then
53                   # Figure out what extra flags when linking to pass to the gcc
54                   # compilers being generated to make sure that they use our libc.
55                   extraLDFlags=($(< "''${!curBintools}/nix-support/libc-ldflags") $(< "''${!curBintools}/nix-support/libc-ldflags-before" || true))
56                   if [ -e ''${!curBintools}/nix-support/ld-set-dynamic-linker ]; then
57                       extraLDFlags=-dynamic-linker=$(< ''${!curBintools}/nix-support/dynamic-linker)
58                   fi
60                   # The path to the Libc binaries such as `crti.o'.
61                   libc_libdir="$(< "''${!curBintools}/nix-support/orig-libc")/lib"
62               else
63                   # Hack: support impure environments.
64                   extraLDFlags=("-L/usr/lib64" "-L/usr/lib")
65                   libc_libdir="/usr/lib"
66               fi
67               declare -a prefixExtraLDFlags=()
68               prefixExtraLDFlags=("-L$libc_libdir")
69               nixDontSetRpathVar=NIX_DONT_SET_RPATH''${post}
70               if test "''${!nixDontSetRpathVar-}" != "1"; then
71                   prefixExtraLDFlags+=("-rpath" "$libc_libdir")
72               fi
73               extraLDFlags=("''${prefixExtraLDFlags[@]}" "''${extraLDFlags[@]}")
74               for i in "''${extraLDFlags[@]}"; do
75                   declare -g EXTRA_LDFLAGS''${post}+=" -Wl,$i"
76               done
77           done
79           # Extract flags from CC Wrappers
80           for post in '_FOR_BUILD' ""; do
81               curCC="NIX_CC''${post}"
82               curFIXINC="NIX_FIXINC_DUMMY''${post}"
84               declare -a extraFlags=()
85               if [[ -e "''${!curCC}/nix-support/orig-libc" ]]; then
86                   # Figure out what extra compiling flags to pass to the gcc compilers
87                   # being generated to make sure that they use our libc.
88                   extraFlags=($(< "''${!curCC}/nix-support/libc-crt1-cflags") $(< "''${!curCC}/nix-support/libc-cflags"))
90                   # The path to the Libc headers
91                   libc_devdir="$(< "''${!curCC}/nix-support/orig-libc-dev")"
93                   # Use *real* header files, otherwise a limits.h is generated that
94                   # does not include Libc's limits.h (notably missing SSIZE_MAX,
95                   # which breaks the build).
96                   declare -g NIX_FIXINC_DUMMY''${post}="$libc_devdir/include"
97               else
98                   # Hack: support impure environments.
99                   extraFlags=("-isystem" "/usr/include")
100                   declare -g NIX_FIXINC_DUMMY''${post}=/usr/include
101               fi
103               extraFlags=("-I''${!curFIXINC}" "''${extraFlags[@]}")
105               # BOOT_CFLAGS defaults to `-g -O2'; since we override it below, make
106               # sure to explictly add them so that files compiled with the bootstrap
107               # compiler are optimized and (optionally) contain debugging information
108               # (info "(gccinstall) Building").
109               if test -n "''${dontStrip-}"; then
110                   extraFlags=("-O2" "-g" "''${extraFlags[@]}")
111               else
112                   # Don't pass `-g' at all; this saves space while building.
113                   extraFlags=("-O2" "''${extraFlags[@]}")
114               fi
116               declare -g EXTRA_FLAGS''${post}="''${extraFlags[*]}"
117           done
119           if test -z "''${targetConfig-}"; then
120               # host = target, so the flags are the same
121               EXTRA_FLAGS_FOR_TARGET="$EXTRA_FLAGS"
122               EXTRA_LDFLAGS_FOR_TARGET="$EXTRA_LDFLAGS"
123           fi
125           # CFLAGS_FOR_TARGET are needed for the libstdc++ configure script to find
126           # the startfiles.
127           # FLAGS_FOR_TARGET are needed for the target libraries to receive the -Bxxx
128           # for the startfiles.
129           makeFlagsArray+=(
130               "BUILD_SYSTEM_HEADER_DIR=$NIX_FIXINC_DUMMY_FOR_BUILD"
131               "SYSTEM_HEADER_DIR=$NIX_FIXINC_DUMMY_FOR_BUILD"
132               "NATIVE_SYSTEM_HEADER_DIR=$NIX_FIXINC_DUMMY"
134               "LDFLAGS_FOR_BUILD=$EXTRA_LDFLAGS_FOR_BUILD"
135               #"LDFLAGS=$EXTRA_LDFLAGS"
136               "LDFLAGS_FOR_TARGET=$EXTRA_LDFLAGS_FOR_TARGET"
138               "CFLAGS_FOR_BUILD=$EXTRA_FLAGS_FOR_BUILD $EXTRA_LDFLAGS_FOR_BUILD"
139               "CXXFLAGS_FOR_BUILD=$EXTRA_FLAGS_FOR_BUILD $EXTRA_LDFLAGS_FOR_BUILD"
140               "FLAGS_FOR_BUILD=$EXTRA_FLAGS_FOR_BUILD $EXTRA_LDFLAGS_FOR_BUILD"
142               # It seems there is a bug in GCC 5
143               #"CFLAGS=$EXTRA_FLAGS $EXTRA_LDFLAGS"
144               #"CXXFLAGS=$EXTRA_FLAGS $EXTRA_LDFLAGS"
146               "CFLAGS_FOR_TARGET=$EXTRA_FLAGS_FOR_TARGET $EXTRA_LDFLAGS_FOR_TARGET"
147               "CXXFLAGS_FOR_TARGET=$EXTRA_FLAGS_FOR_TARGET $EXTRA_LDFLAGS_FOR_TARGET"
148               "FLAGS_FOR_TARGET=$EXTRA_FLAGS_FOR_TARGET $EXTRA_LDFLAGS_FOR_TARGET"
149           )
151           if test -z "''${targetConfig-}"; then
152               makeFlagsArray+=(
153                   "BOOT_CFLAGS=$EXTRA_FLAGS $EXTRA_LDFLAGS"
154                   "BOOT_LDFLAGS=$EXTRA_FLAGS_FOR_TARGET $EXTRA_LDFLAGS_FOR_TARGET"
155               )
156           fi
158           if test "$withoutTargetLibc" == 1; then
159               # We don't want the gcc build to assume there will be a libc providing
160               # limits.h in this stage
161               makeFlagsArray+=(
162                   'LIMITS_H_TEST=false'
163               )
164           else
165               makeFlagsArray+=(
166                   'LIMITS_H_TEST=true'
167               )
168           fi
169       fi
171       eval "$oldOpts"
172     '';
174     preConfigure =
175       (originalAttrs.preConfigure or "")
176       + ''
177         if test -n "$newlibSrc"; then
178             tar xvf "$newlibSrc" -C ..
179             ln -s ../newlib-*/newlib newlib
180             # Patch to get armvt5el working:
181             sed -i -e 's/ arm)/ arm*)/' newlib/configure.host
182         fi
184         # Bug - they packaged zlib
185         if test -d "zlib"; then
186             # This breaks the build without-headers, which should build only
187             # the target libgcc as target libraries.
188             # See 'configure:5370'
189             rm -Rf zlib
190         fi
192         if test -n "$crossMingw" -a -n "$withoutTargetLibc"; then
193             mkdir -p ../mingw
194             # --with-build-sysroot expects that:
195             cp -R $libcCross/include ../mingw
196             appendToVar configureFlags "--with-build-sysroot=`pwd`/.."
197         fi
199         # Perform the build in a different directory.
200         mkdir ../build
201         cd ../build
202         configureScript=../$sourceRoot/configure
203       '';
205     postConfigure = ''
206       # Avoid store paths when embedding ./configure flags into gcc.
207       # Mangled arguments are still useful when reporting bugs upstream.
208       sed -e "/TOPLEVEL_CONFIGURE_ARGUMENTS=/ s|$NIX_STORE/[a-z0-9]\{32\}-|$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-|g" -i Makefile
209     '';
211     preInstall =
212       ''
213         mkdir -p "$out/''${targetConfig}/lib"
214         mkdir -p "''${!outputLib}/''${targetConfig}/lib"
215       ''
216       +
217         # if cross-compiling, link from $lib/lib to $lib/${targetConfig}.
218         # since native-compiles have $lib/lib as a directory (not a
219         # symlink), this ensures that in every case we can assume that
220         # $lib/lib contains the .so files
221         lib.optionalString (with stdenv; targetPlatform.config != hostPlatform.config) ''
222           ln -Ts "''${!outputLib}/''${targetConfig}/lib" $lib/lib
223         ''
224       +
225         # Make `lib64` symlinks to `lib`.
226         lib.optionalString
227           (!enableMultilib && stdenv.hostPlatform.is64bit && !stdenv.hostPlatform.isMips64n32)
228           ''
229             ln -s lib "$out/''${targetConfig}/lib64"
230             ln -s lib "''${!outputLib}/''${targetConfig}/lib64"
231           ''
232       +
233         # On mips platforms, gcc follows the IRIX naming convention:
234         #
235         #  $PREFIX/lib   = mips32
236         #  $PREFIX/lib32 = mips64n32
237         #  $PREFIX/lib64 = mips64
238         #
239         # Make `lib32` symlinks to `lib`.
240         lib.optionalString (!enableMultilib && stdenv.targetPlatform.isMips64n32) ''
241           ln -s lib "$out/''${targetConfig}/lib32"
242           ln -s lib "''${!outputLib}/''${targetConfig}/lib32"
243         '';
245     postInstall = ''
246       # Move runtime libraries to lib output.
247       moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.so*" "''${!outputLib}"
248       moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.la"  "''${!outputLib}"
249       moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.dylib" "''${!outputLib}"
250       moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.dll.a" "''${!outputLib}"
251       moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.dll" "''${!outputLib}"
252       moveToOutput "share/gcc-*/python" "''${!outputLib}"
254       if [ -z "$enableShared" ]; then
255           moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.a" "''${!outputLib}"
256       fi
258       for i in "''${!outputLib}/''${targetConfig}"/lib/*.{la,py}; do
259           substituteInPlace "$i" --replace "$out" "''${!outputLib}"
260       done
262       if [ -n "$enableMultilib" ]; then
263           moveToOutput "''${targetConfig+$targetConfig/}lib64/lib*.so*" "''${!outputLib}"
264           moveToOutput "''${targetConfig+$targetConfig/}lib64/lib*.la"  "''${!outputLib}"
265           moveToOutput "''${targetConfig+$targetConfig/}lib64/lib*.dylib" "''${!outputLib}"
266           moveToOutput "''${targetConfig+$targetConfig/}lib64/lib*.dll.a" "''${!outputLib}"
267           moveToOutput "''${targetConfig+$targetConfig/}lib64/lib*.dll" "''${!outputLib}"
269           for i in "''${!outputLib}/''${targetConfig}"/lib64/*.{la,py}; do
270               substituteInPlace "$i" --replace "$out" "''${!outputLib}"
271           done
272       fi
274       # Remove `fixincl' to prevent a retained dependency on the
275       # previous gcc.
276       rm -rf $out/libexec/gcc/*/*/install-tools
277       rm -rf $out/lib/gcc/*/*/install-tools
279       # More dependencies with the previous gcc or some libs (gccbug stores the build command line)
280       rm -rf $out/bin/gccbug
282       if type "install_name_tool"; then
283           for i in "''${!outputLib}"/lib/*.*.dylib "''${!outputLib}"/lib/*.so.[0-9]; do
284               install_name_tool -id "$i" "$i" || true
285               for old_path in $(otool -L "$i" | grep "$out" | awk '{print $1}'); do
286                 new_path=`echo "$old_path" | sed "s,$out,''${!outputLib},"`
287                 install_name_tool -change "$old_path" "$new_path" "$i" || true
288               done
289           done
290       fi
292       # Get rid of some "fixed" header files
293       rm -rfv $out/lib/gcc/*/*/include-fixed/{root,linux,sys/mount.h,bits/statx.h,pthread.h}
295       # Replace hard links for i686-pc-linux-gnu-gcc etc. with symlinks.
296       for i in $out/bin/*-gcc*; do
297           if cmp -s $out/bin/gcc $i; then
298               ln -sfn gcc $i
299           fi
300       done
302       for i in $out/bin/c++ $out/bin/*-c++* $out/bin/*-g++*; do
303           if cmp -s $out/bin/g++ $i; then
304               ln -sfn g++ $i
305           fi
306       done
308       # Two identical man pages are shipped (moving and compressing is done later)
309       for i in "$out"/share/man/man1/*g++.1; do
310           if test -e "$i"; then
311               man_prefix=`echo "$i" | sed "s,.*/\(.*\)g++.1,\1,"`
312               ln -sf "$man_prefix"gcc.1 "$i"
313           fi
314       done
315     '';
316   }