lol
1{ lib
2, stdenv
3}:
4
5# Trick to build a gcc that is capable of emitting shared libraries *without* having the
6# targetPlatform libc available beforehand. Taken from:
7# https://web.archive.org/web/20170222224855/http://frank.harvard.edu/~coldwell/toolchain/
8# https://web.archive.org/web/20170224235700/http://frank.harvard.edu/~coldwell/toolchain/t-linux.diff
9let
10 # crt{i,n}.o are the first and last (respectively) object file
11 # linked when producing an executable. Traditionally these
12 # files are delivered as part of the C library, but on GNU
13 # systems they are in fact built by GCC. Since libgcc needs to
14 # build before glibc, we can't wait for them to be copied by
15 # glibc. At this early pre-glibc stage these files sometimes
16 # have different names.
17 crtstuff-ofiles =
18 if stdenv.targetPlatform.isPower
19 then "ecrti.o ecrtn.o ncrti.o ncrtn.o"
20 else "crti.o crtn.o";
21
22 # Normally, `SHLIB_LC` is set to `-lc`, which means that
23 # `libgcc_s.so` cannot be built until `libc.so` is available.
24 # The assignment below clobbers this variable, removing the
25 # `-lc`.
26 #
27 # On PowerPC we add `-mnewlib`, which means "libc has not been
28 # built yet". This causes libgcc's Makefile to use the
29 # gcc-built `{e,n}crt{n,i}.o` instead of failing to find the
30 # versions which have been repackaged in libc as `crt{n,i}.o`
31 #
32 SHLIB_LC = lib.optionalString stdenv.targetPlatform.isPower "-mnewlib";
33
34in
35''
36 echo 'libgcc.a: ${crtstuff-ofiles}' >> libgcc/Makefile.in
37 echo 'SHLIB_LC=${SHLIB_LC}' >> libgcc/Makefile.in
38''
39
40 # Meanwhile, crt{i,n}.S are not present on certain platforms
41 # (e.g. LoongArch64), resulting in the following error:
42 #
43 # No rule to make target '../../../gcc-xx.x.x/libgcc/config/loongarch/crti.S', needed by 'crti.o'. Stop.
44 #
45 # For LoongArch64 and S390, a hacky workaround is to simply touch them,
46 # as the platform forces .init_array support.
47 #
48 # https://www.openwall.com/lists/musl/2022/11/09/3
49 #
50 # 'parsed.cpu.family' won't be correct for every platform.
51+ lib.optionalString (stdenv.targetPlatform.isLoongArch64 || stdenv.targetPlatform.isS390) ''
52 touch libgcc/config/${stdenv.targetPlatform.parsed.cpu.family}/crt{i,n}.S
53''