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