nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{ lib, stdenv, targetPackages, fetchurl, fetchpatch, noSysDirs
2, langC ? true, langCC ? true, langFortran ? false
3, langAda ? false
4, langObjC ? stdenv.targetPlatform.isDarwin
5, langObjCpp ? stdenv.targetPlatform.isDarwin
6, langD ? false
7, langGo ? false
8, reproducibleBuild ? true
9, profiledCompiler ? false
10, langJit ? false
11, staticCompiler ? false
12, enableShared ? !stdenv.targetPlatform.isStatic
13, enableLTO ? !stdenv.hostPlatform.isStatic
14, texinfo ? null
15, perl ? null # optional, for texi2pod (then pod2man)
16, gmp, mpfr, libmpc, gettext, which, patchelf, binutils
17, isl ? null # optional, for the Graphite optimization framework.
18, zlib ? null
19, libucontext ? null
20, gnat-bootstrap ? null
21, enableMultilib ? false
22, enablePlugin ? stdenv.hostPlatform == stdenv.buildPlatform # Whether to support user-supplied plug-ins
23, name ? "gcc"
24, libcCross ? null
25, threadsCross ? null # for MinGW
26, crossStageStatic ? false
27, gnused ? null
28, cloog # unused; just for compat with gcc4, as we override the parameter on some places
29, buildPackages
30, libxcrypt
31, disableGdbPlugin ? !enablePlugin
32, nukeReferences
33, callPackage
34}:
35
36# Make sure we get GNU sed.
37assert stdenv.buildPlatform.isDarwin -> gnused != null;
38
39# The go frontend is written in c++
40assert langGo -> langCC;
41assert langAda -> gnat-bootstrap != null;
42
43# TODO: fixup D bootstapping, probably by using gdc11 (and maybe other changes).
44# error: GDC is required to build d
45assert !langD;
46
47# threadsCross is just for MinGW
48assert threadsCross != {} -> stdenv.targetPlatform.isWindows;
49
50# profiledCompiler builds inject non-determinism in one of the compilation stages.
51# If turned on, we can't provide reproducible builds anymore
52assert reproducibleBuild -> profiledCompiler == false;
53
54with lib;
55with builtins;
56
57let majorVersion = "12";
58 version = "${majorVersion}.2.0";
59 disableBootstrap = !stdenv.hostPlatform.isDarwin && !profiledCompiler;
60
61 inherit (stdenv) buildPlatform hostPlatform targetPlatform;
62
63 patches =
64 optional (targetPlatform != hostPlatform) ../libstdc++-target.patch
65 ++ optional noSysDirs ../gcc-12-no-sys-dirs.patch
66 ++ optional noSysDirs ../no-sys-dirs-riscv.patch
67 ++ [
68 ../gnat-cflags-11.patch
69 ../gcc-12-gfortran-driving.patch
70 ../ppc-musl.patch
71 ../install-info-files-serially.patch
72 ]
73 # We only apply this patch when building a native toolchain for aarch64-darwin, as it breaks building
74 # a foreign one: https://github.com/iains/gcc-12-branch/issues/18
75 ++ optional (stdenv.isDarwin && stdenv.isAarch64 && buildPlatform == hostPlatform && hostPlatform == targetPlatform) (fetchpatch {
76 name = "gcc-12-darwin-aarch64-support.patch";
77 url = "https://github.com/Homebrew/formula-patches/raw/1d184289/gcc/gcc-12.2.0-arm.diff";
78 sha256 = "sha256-omclLslGi/2yCV4pNBMaIpPDMW3tcz/RXdupbNbeOHA=";
79 })
80 ++ optional langD ../libphobos.patch
81
82 # backport fixes to build gccgo with musl libc
83 ++ optionals (langGo && stdenv.hostPlatform.isMusl) [
84 (fetchpatch {
85 excludes = [ "gcc/go/gofrontend/MERGE" ];
86 url = "https://github.com/gcc-mirror/gcc/commit/cf79b1117bd177d3d4c6ed24b6fa243c3628ac2d.diff";
87 hash = "sha256-mS5ZiYi5D8CpGXrWg3tXlbhp4o86ew1imCTwaHLfl+I=";
88 })
89 (fetchpatch {
90 excludes = [ "gcc/go/gofrontend/MERGE" ];
91 url = "https://github.com/gcc-mirror/gcc/commit/7f195a2270910a6ed08bd76e3a16b0a6503f9faf.diff";
92 hash = "sha256-Ze/cFM0dQofKH00PWPDoklXUlwWhwA1nyTuiDAZ6FKo=";
93 })
94 (fetchpatch {
95 excludes = [ "gcc/go/gofrontend/MERGE" ];
96 url = "https://github.com/gcc-mirror/gcc/commit/762fd5e5547e464e25b4bee435db6df4eda0de90.diff";
97 hash = "sha256-o28upwTcHAnHG2Iq0OewzwSBEhHs+XpBGdIfZdT81pk=";
98 })
99 (fetchpatch {
100 excludes = [ "gcc/go/gofrontend/MERGE" ];
101 url = "https://github.com/gcc-mirror/gcc/commit/e73d9fcafbd07bc3714fbaf8a82db71d50015c92.diff";
102 hash = "sha256-1SjYCVHLEUihdON2TOC3Z2ufM+jf2vH0LvYtZL+c1Fo=";
103 })
104 (fetchpatch {
105 excludes = [ "gcc/go/gofrontend/MERGE" ];
106 url = "https://github.com/gcc-mirror/gcc/commit/b6c6a3d64f2e4e9347733290aca3c75898c44b2e.diff";
107 hash = "sha256-RycJ3YCHd3MXtYFjxP0zY2Wuw7/C4bWoBAQtTKJZPOQ=";
108 })
109 (fetchpatch {
110 excludes = [ "gcc/go/gofrontend/MERGE" ];
111 url = "https://github.com/gcc-mirror/gcc/commit/2b1a604a9b28fbf4f382060bebd04adb83acc2f9.diff";
112 hash = "sha256-WiBQG0Xbk75rHk+AMDvsbrm+dc7lDH0EONJXSdEeMGE=";
113 })
114 (fetchpatch {
115 url = "https://github.com/gcc-mirror/gcc/commit/c86b726c048eddc1be320c0bf64a897658bee13d.diff";
116 hash = "sha256-QSIlqDB6JRQhbj/c3ejlmbfWz9l9FurdSWxpwDebnlI=";
117 })
118 ]
119
120 # Fix detection of bootstrap compiler Ada support (cctools as) on Nix Darwin
121 ++ optional (stdenv.isDarwin && langAda) ../ada-cctools-as-detection-configure.patch
122
123 # Use absolute path in GNAT dylib install names on Darwin
124 ++ optional (stdenv.isDarwin && langAda) ../gnat-darwin-dylib-install-name.patch
125
126 # Obtain latest patch with ../update-mcfgthread-patches.sh
127 ++ optional (!crossStageStatic && targetPlatform.isMinGW && threadsCross.model == "mcf") ./Added-mcf-thread-model-support-from-mcfgthread.patch;
128
129 /* Cross-gcc settings (build == host != target) */
130 crossMingw = targetPlatform != hostPlatform && targetPlatform.libc == "msvcrt";
131 stageNameAddon = if crossStageStatic then "stage-static" else "stage-final";
132 crossNameAddon = optionalString (targetPlatform != hostPlatform) "${targetPlatform.config}-${stageNameAddon}-";
133
134 callFile = lib.callPackageWith {
135 # lets
136 inherit
137 majorVersion
138 version
139 buildPlatform
140 hostPlatform
141 targetPlatform
142 patches
143 crossMingw
144 stageNameAddon
145 crossNameAddon
146 ;
147 # inherit generated with 'nix eval --json --impure --expr "with import ./. {}; lib.attrNames (lib.functionArgs gcc12.cc.override)" | jq '.[]' --raw-output'
148 inherit
149 binutils
150 buildPackages
151 cloog
152 crossStageStatic
153 disableBootstrap
154 disableGdbPlugin
155 enableLTO
156 enableMultilib
157 enablePlugin
158 enableShared
159 fetchpatch
160 fetchurl
161 gettext
162 gmp
163 gnat-bootstrap
164 gnused
165 isl
166 langAda
167 langC
168 langCC
169 langD
170 langFortran
171 langGo
172 langJit
173 langObjC
174 langObjCpp
175 lib
176 libcCross
177 libmpc
178 libucontext
179 libxcrypt
180 mpfr
181 name
182 noSysDirs
183 nukeReferences
184 patchelf
185 perl
186 profiledCompiler
187 reproducibleBuild
188 staticCompiler
189 stdenv
190 targetPackages
191 texinfo
192 threadsCross
193 which
194 zip
195 zlib
196 ;
197 };
198
199in
200
201lib.pipe (stdenv.mkDerivation ({
202 pname = "${crossNameAddon}${name}";
203 inherit version;
204
205 builder = ../builder.sh;
206
207 src = fetchurl {
208 url = "mirror://gcc/releases/gcc-${version}/gcc-${version}.tar.xz";
209 sha256 = "sha256-5UnPnPNZSgDie2WJ1DItcOByDN0hPzm+tBgeBpJiMP8=";
210 };
211
212 inherit patches;
213
214 outputs = [ "out" "man" "info" ] ++ lib.optional (!langJit) "lib";
215 setOutputFlags = false;
216 NIX_NO_SELF_RPATH = true;
217
218 libc_dev = stdenv.cc.libc_dev;
219
220 hardeningDisable = [ "format" "pie" ];
221
222 postPatch = ''
223 configureScripts=$(find . -name configure)
224 for configureScript in $configureScripts; do
225 patchShebangs $configureScript
226 done
227 ''
228 # This should kill all the stdinc frameworks that gcc and friends like to
229 # insert into default search paths.
230 + lib.optionalString hostPlatform.isDarwin ''
231 substituteInPlace gcc/config/darwin-c.cc \
232 --replace 'if (stdinc)' 'if (0)'
233
234 substituteInPlace libgcc/config/t-slibgcc-darwin \
235 --replace "-install_name @shlib_slibdir@/\$(SHLIB_INSTALL_NAME)" "-install_name ''${!outputLib}/lib/\$(SHLIB_INSTALL_NAME)"
236
237 substituteInPlace libgfortran/configure \
238 --replace "-install_name \\\$rpath/\\\$soname" "-install_name ''${!outputLib}/lib/\\\$soname"
239 ''
240 + (
241 lib.optionalString (targetPlatform != hostPlatform || stdenv.cc.libc != null)
242 # On NixOS, use the right path to the dynamic linker instead of
243 # `/lib/ld*.so'.
244 (let
245 libc = if libcCross != null then libcCross else stdenv.cc.libc;
246 in
247 (
248 '' echo "fixing the \`GLIBC_DYNAMIC_LINKER', \`UCLIBC_DYNAMIC_LINKER', and \`MUSL_DYNAMIC_LINKER' macros..."
249 for header in "gcc/config/"*-gnu.h "gcc/config/"*"/"*.h
250 do
251 grep -q _DYNAMIC_LINKER "$header" || continue
252 echo " fixing \`$header'..."
253 sed -i "$header" \
254 -e 's|define[[:blank:]]*\([UCG]\+\)LIBC_DYNAMIC_LINKER\([0-9]*\)[[:blank:]]"\([^\"]\+\)"$|define \1LIBC_DYNAMIC_LINKER\2 "${libc.out}\3"|g' \
255 -e 's|define[[:blank:]]*MUSL_DYNAMIC_LINKER\([0-9]*\)[[:blank:]]"\([^\"]\+\)"$|define MUSL_DYNAMIC_LINKER\1 "${libc.out}\2"|g'
256 done
257 ''
258 + lib.optionalString (targetPlatform.libc == "musl")
259 ''
260 sed -i gcc/config/linux.h -e '1i#undef LOCAL_INCLUDE_DIR'
261 ''
262 )
263 ))
264 + lib.optionalString targetPlatform.isAvr ''
265 makeFlagsArray+=(
266 '-s' # workaround for hitting hydra log limit
267 'LIMITS_H_TEST=false'
268 )
269 '';
270
271 inherit noSysDirs staticCompiler crossStageStatic
272 libcCross crossMingw;
273
274 inherit (callFile ../common/dependencies.nix { }) depsBuildBuild nativeBuildInputs depsBuildTarget buildInputs depsTargetTarget;
275
276 NIX_LDFLAGS = lib.optionalString hostPlatform.isSunOS "-lm";
277
278
279 preConfigure = (callFile ../common/pre-configure.nix { }) + ''
280 ln -sf ${libxcrypt}/include/crypt.h libsanitizer/sanitizer_common/crypt.h
281 '';
282
283 dontDisableStatic = true;
284
285 configurePlatforms = [ "build" "host" "target" ];
286
287 configureFlags = callFile ../common/configure-flags.nix { };
288
289 targetConfig = if targetPlatform != hostPlatform then targetPlatform.config else null;
290
291 buildFlags =
292 # we do not yet have Nix-driven profiling
293 assert profiledCompiler -> !disableBootstrap;
294 let target =
295 lib.optionalString (profiledCompiler) "profiled" +
296 lib.optionalString (targetPlatform == hostPlatform && hostPlatform == buildPlatform && !disableBootstrap) "bootstrap";
297 in lib.optional (target != "") target;
298
299 inherit (callFile ../common/strip-attributes.nix { })
300 stripDebugList
301 stripDebugListTarget
302 preFixup;
303
304 # https://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
305 ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
306
307 # Setting $CPATH and $LIBRARY_PATH to make sure both `gcc' and `xgcc' find the
308 # library headers and binaries, regarless of the language being compiled.
309 #
310 # Likewise, the LTO code doesn't find zlib.
311 #
312 # Cross-compiling, we need gcc not to read ./specs in order to build the g++
313 # compiler (after the specs for the cross-gcc are created). Having
314 # LIBRARY_PATH= makes gcc read the specs from ., and the build breaks.
315
316 CPATH = optionals (targetPlatform == hostPlatform) (makeSearchPathOutput "dev" "include" ([]
317 ++ optional (zlib != null) zlib
318 ));
319
320 LIBRARY_PATH = optionals (targetPlatform == hostPlatform) (makeLibraryPath (optional (zlib != null) zlib));
321
322 inherit (callFile ../common/extra-target-flags.nix { })
323 EXTRA_FLAGS_FOR_TARGET
324 EXTRA_LDFLAGS_FOR_TARGET
325 ;
326
327 passthru = {
328 inherit langC langCC langObjC langObjCpp langAda langFortran langGo langD version;
329 isGNU = true;
330 };
331
332 enableParallelBuilding = true;
333 inherit enableShared enableMultilib;
334
335 meta = {
336 inherit (callFile ../common/meta.nix { })
337 homepage
338 license
339 description
340 longDescription
341 platforms
342 maintainers
343 ;
344 };
345}
346
347// optionalAttrs (targetPlatform != hostPlatform && targetPlatform.libc == "msvcrt" && crossStageStatic) {
348 makeFlags = [ "all-gcc" "all-target-libgcc" ];
349 installTargets = "install-gcc install-target-libgcc";
350}
351
352// optionalAttrs (enableMultilib) { dontMoveLib64 = true; }
353))
354[
355 (callPackage ../common/libgcc.nix { inherit langC langCC langJit; })
356 (callPackage ../common/checksum.nix { inherit langC langCC; })
357]
358