1{
2 lib,
3 stdenvNoLibs,
4 buildPackages,
5 gcc,
6 glibc,
7 libiberty,
8}:
9
10let
11 stdenv = stdenvNoLibs;
12 gccConfigureFlags = gcc.cc.configureFlags ++ [
13 "--disable-fixincludes"
14 "--disable-intl"
15 "--enable-threads=posix"
16 "--with-glibc-version=${glibc.version}"
17 "--disable-plugin"
18
19 # these are required in order to prevent inhibit_libc=true,
20 # which will cripple libgcc's unwinder; see:
21 # https://github.com/NixOS/nixpkgs/issues/213453#issuecomment-1616346163
22 "--with-headers=${lib.getDev glibc}/include"
23 "--with-native-system-header-dir=${lib.getDev glibc}${glibc.incdir or "/include"}"
24 "--with-build-sysroot=/"
25 ];
26
27in
28stdenv.mkDerivation (finalAttrs: {
29 pname = "libgcc";
30 inherit (gcc.cc) src version;
31
32 outputs = [
33 "out"
34 "dev"
35 ];
36
37 strictDeps = true;
38 depsBuildBuild = [ buildPackages.stdenv.cc ];
39 nativeBuildInputs = [ libiberty ];
40 buildInputs = [ glibc ];
41
42 postUnpack = ''
43 mkdir -p ./build
44 buildRoot=$(readlink -e "./build")
45 '';
46
47 postPatch = gcc.cc.passthru.forceLibgccToBuildCrtStuff + ''
48 sourceRoot=$(readlink -e "./libgcc")
49 '';
50
51 hardeningDisable = [ "pie" ];
52
53 preConfigure = ''
54 # Drop in libiberty, as external builds are not expected
55 cd "$buildRoot"
56 (
57 mkdir -p build-${stdenv.buildPlatform.config}/libiberty/
58 cd build-${stdenv.buildPlatform.config}/libiberty/
59 ln -s ${buildPackages.libiberty}/lib/libiberty.a ./
60 )
61 mkdir -p "$buildRoot/gcc"
62 cd "$buildRoot/gcc"
63 (
64 # We "shift" the tools over to fake platforms perspective from the previous stage.
65 export AS_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$AS_FOR_BUILD
66 export CC_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$CC_FOR_BUILD
67 export CPP_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$CPP_FOR_BUILD
68 export CXX_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$CXX_FOR_BUILD
69 export LD_FOR_BUILD=${buildPackages.stdenv.cc.bintools}/bin/$LD_FOR_BUILD
70
71 export AS=$AS_FOR_BUILD
72 export CC=$CC_FOR_BUILD
73 export CPP=$CPP_FOR_BUILD
74 export CXX=$CXX_FOR_BUILD
75 export LD=$LD_FOR_BUILD
76
77 export AS_FOR_TARGET=${stdenv.cc}/bin/$AS
78 export CC_FOR_TARGET=${stdenv.cc}/bin/$CC
79 export CPP_FOR_TARGET=${stdenv.cc}/bin/$CPP
80 export LD_FOR_TARGET=${stdenv.cc.bintools}/bin/$LD
81
82 # We define GENERATOR_FILE so nothing bothers looking for GNU GMP.
83 export NIX_CFLAGS_COMPILE_FOR_BUILD+=' -DGENERATOR_FILE=1'
84
85 "$sourceRoot/../gcc/configure" ${lib.concatStringsSep " " gccConfigureFlags}
86
87 # We remove the `libgcc.mvar` deps so that the bootstrap xgcc isn't built.
88 sed -e 's,libgcc.mvars:.*$,libgcc.mvars:,' -i Makefile
89
90 make \
91 config.h \
92 libgcc.mvars \
93 tconfig.h \
94 tm.h \
95 options.h \
96 insn-constants.h \
97 ''
98 + lib.optionalString stdenv.targetPlatform.isM68k ''
99 sysroot-suffix.h \
100 ''
101 + lib.optionalString stdenv.targetPlatform.isAarch32 ''
102 arm-isa.h \
103 arm-cpu.h \
104 ''
105 + lib.optionalString stdenv.targetPlatform.isLoongArch64 ''
106 loongarch-multilib.h \
107 ''
108 + ''
109 insn-modes.h
110 )
111 mkdir -p "$buildRoot/gcc/include"
112
113 # Preparing to configure + build libgcc itself
114 mkdir -p "$buildRoot/gcc/${stdenv.hostPlatform.config}/libgcc"
115 cd "$buildRoot/gcc/${stdenv.hostPlatform.config}/libgcc"
116 configureScript=$sourceRoot/configure
117 chmod +x "$configureScript"
118
119 export AS_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$AS_FOR_BUILD
120 export CC_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$CC_FOR_BUILD
121 export CPP_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$CPP_FOR_BUILD
122 export CXX_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$CXX_FOR_BUILD
123 export LD_FOR_BUILD=${buildPackages.stdenv.cc.bintools}/bin/$LD_FOR_BUILD
124
125 export AS=${stdenv.cc}/bin/$AS
126 export CC=${stdenv.cc}/bin/$CC
127 export CPP=${stdenv.cc}/bin/$CPP
128 export CXX=${stdenv.cc}/bin/$CXX
129 export LD=${stdenv.cc.bintools}/bin/$LD
130
131 export AS_FOR_TARGET=${stdenv.cc}/bin/$AS_FOR_TARGET
132 export CC_FOR_TARGET=${stdenv.cc}/bin/$CC_FOR_TARGET
133 export CPP_FOR_TARGET=${stdenv.cc}/bin/$CPP_FOR_TARGET
134 export LD_FOR_TARGET=${stdenv.cc.bintools}/bin/$LD_FOR_TARGET
135 '';
136
137 configurePlatforms = [
138 "build"
139 "host"
140 ];
141 configureFlags = [
142 "cross_compiling=true"
143 "--disable-gcov"
144 "--with-glibc-version=${glibc.version}"
145 ];
146
147 makeFlags = [ "MULTIBUILDTOP:=../" ];
148
149 postInstall = ''
150 moveToOutput "lib/gcc/${stdenv.hostPlatform.config}/${finalAttrs.version}/include" "$dev"
151 mkdir -p "$out/lib" "$dev/include"
152 ln -s "$out/lib/gcc/${stdenv.hostPlatform.config}/${finalAttrs.version}"/* "$out/lib"
153 ln -s "$dev/lib/gcc/${stdenv.hostPlatform.config}/${finalAttrs.version}/include"/* "$dev/include/"
154 '';
155})