From 424952b7b4c515941fc6aaac597636ba56a348e2 Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Thu, 6 Jul 2023 03:24:33 -0700 Subject: [PATCH] gccWithoutTargetLibc: link libgcc_s.so using -mnewlib if isPower Closes #244405 Also adds considerably more commenting to document what is going on. --- .../compilers/gcc/common/pre-configure.nix | 33 ++++++++++++++++--- pkgs/test/cross/default.nix | 2 +- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/pkgs/development/compilers/gcc/common/pre-configure.nix b/pkgs/development/compilers/gcc/common/pre-configure.nix index 2561246a66f9..e386693b22c7 100644 --- a/pkgs/development/compilers/gcc/common/pre-configure.nix +++ b/pkgs/development/compilers/gcc/common/pre-configure.nix @@ -117,10 +117,35 @@ in lib.optionalString (hostPlatform.isSunOS && hostPlatform.is64bit) '' # https://web.archive.org/web/20170222224855/http://frank.harvard.edu/~coldwell/toolchain/ # https://web.archive.org/web/20170224235700/http://frank.harvard.edu/~coldwell/toolchain/t-linux.diff + lib.optionalString (targetPlatform != hostPlatform && withoutTargetLibc && enableShared) - (lib.optionalString (!stdenv.targetPlatform.isPower) '' - echo 'libgcc.a: crti.o crtn.o' >> libgcc/Makefile.in - '' + '' - echo 'SHLIB_LC=' >> libgcc/Makefile.in + (let + + # crt{i,n}.o are the first and last (respectively) object file + # linked when producing an executable. Traditionally these + # files are delivered as part of the C library, but on GNU + # systems they are in fact built by GCC. Since libgcc needs to + # build before glibc, we can't wait for them to be copied by + # glibc. At this early pre-glibc stage these files sometimes + # have different names. + crtstuff-ofiles = + if targetPlatform.isPower + then "ecrti.o ecrtn.o ncrti.o ncrtn.o" + else "crti.o crtn.o"; + + # Normally, `SHLIB_LC` is set to `-lc`, which means that + # `libgcc_s.so` cannot be built until `libc.so` is available. + # The assignment below clobbers this variable, removing the + # `-lc`. + # + # On PowerPC we add `-mnewlib`, which means "libc has not been + # built yet". This causes libgcc's Makefile to use the + # gcc-built `{e,n}crt{n,i}.o` instead of failing to find the + # versions which have been repackaged in libc as `crt{n,i}.o` + # + SHLIB_LC = lib.optionalString targetPlatform.isPower "-mnewlib"; + + in '' + echo 'libgcc.a: ${crtstuff-ofiles}' >> libgcc/Makefile.in + echo 'SHLIB_LC=${SHLIB_LC}' >> libgcc/Makefile.in '') + lib.optionalString (!enableMultilib && hostPlatform.is64bit && !hostPlatform.isMips64n32) '' diff --git a/pkgs/test/cross/default.nix b/pkgs/test/cross/default.nix index ad2689d5d217..46bb3c8d522d 100644 --- a/pkgs/test/cross/default.nix +++ b/pkgs/test/cross/default.nix @@ -136,7 +136,7 @@ let pkgs.pkgsCross.arm-embedded.stdenv pkgs.pkgsCross.m68k.stdenv pkgs.pkgsCross.aarch64-multiplatform.pkgsBuildTarget.gcc - #pkgs.pkgsCross.powernv.pkgsBuildTarget.gcc + pkgs.pkgsCross.powernv.pkgsBuildTarget.gcc pkgs.pkgsCross.mips64el-linux-gnuabi64.stdenv pkgs.pkgsCross.mips64el-linux-gnuabin32.stdenv pkgs.pkgsCross.mingwW64.stdenv