1{ lib, stdenv, targetPackages, fetchurl, fetchpatch, fetchFromGitHub, noSysDirs
2, langC ? true, langCC ? true, langFortran ? false
3, langAda ? false
4, langObjC ? stdenv.targetPlatform.isDarwin
5, langObjCpp ? stdenv.targetPlatform.isDarwin
6, langJava ? false
7, langGo ? false
8, reproducibleBuild ? true
9, profiledCompiler ? false
10, langJit ? false
11, staticCompiler ? false
12, # N.B. the defult is intentionally not from an `isStatic`. See
13 # https://gcc.gnu.org/install/configure.html - this is about target
14 # platform libraries not host platform ones unlike normal. But since
15 # we can't rebuild those without also rebuilding the compiler itself,
16 # we opt to always build everything unlike our usual policy.
17 enableShared ? true
18, enableLTO ? true
19, texinfo ? null
20, flex
21, perl ? null # optional, for texi2pod (then pod2man); required for Java
22, gmp, mpfr, libmpc, gettext, which, patchelf
23, libelf # optional, for link-time optimizations (LTO)
24, isl ? null # optional, for the Graphite optimization framework.
25, zlib ? null, boehmgc ? null
26, gnatboot ? null
27, zip ? null, unzip ? null, pkg-config ? null
28, gtk2 ? null, libart_lgpl ? null
29, libX11 ? null, libXt ? null, libSM ? null, libICE ? null, libXtst ? null
30, libXrender ? null, xorgproto ? null
31, libXrandr ? null, libXi ? null
32, x11Support ? langJava
33, enableMultilib ? false
34, enablePlugin ? stdenv.hostPlatform == stdenv.buildPlatform # Whether to support user-supplied plug-ins
35, name ? "gcc"
36, libcCross ? null
37, threadsCross ? null # for MinGW
38, crossStageStatic ? false
39, # Strip kills static libs of other archs (hence no cross)
40 stripped ? stdenv.hostPlatform.system == stdenv.buildPlatform.system
41 && stdenv.targetPlatform.system == stdenv.hostPlatform.system
42, gnused ? null
43, cloog # unused; just for compat with gcc4, as we override the parameter on some places
44, buildPackages
45}:
46
47assert langJava -> zip != null && unzip != null
48 && zlib != null && boehmgc != null
49 && perl != null; # for `--enable-java-home'
50
51# LTO needs libelf and zlib.
52assert libelf != null -> zlib != null;
53
54# Make sure we get GNU sed.
55assert stdenv.hostPlatform.isDarwin -> gnused != null;
56
57# The go frontend is written in c++
58assert langGo -> langCC;
59
60assert langAda -> gnatboot != null;
61
62# threadsCross is just for MinGW
63assert threadsCross != null -> stdenv.targetPlatform.isWindows;
64
65# profiledCompiler builds inject non-determinism in one of the compilation stages.
66# If turned on, we can't provide reproducible builds anymore
67assert reproducibleBuild -> profiledCompiler == false;
68
69with lib;
70with builtins;
71
72let majorVersion = "6";
73 version = "${majorVersion}.5.0";
74
75 inherit (stdenv) buildPlatform hostPlatform targetPlatform;
76
77 patches = optionals (!stdenv.targetPlatform.isRedox) [
78 ../use-source-date-epoch.patch ./0001-Fix-build-for-glibc-2.31.patch
79 ] ++ optional (targetPlatform != hostPlatform) ../libstdc++-target.patch
80 ++ optional noSysDirs ../no-sys-dirs.patch
81 ++ optional langAda ../gnat-cflags.patch
82 ++ optional langFortran ../gfortran-driving.patch
83 ++ optional (targetPlatform.libc == "musl") ../libgomp-dont-force-initial-exec.patch
84
85 # Obtain latest patch with ../update-mcfgthread-patches.sh
86 ++ optional (!crossStageStatic && targetPlatform.isMinGW) ./Added-mcf-thread-model-support-from-mcfgthread.patch
87 ++ optional (targetPlatform.libc == "musl" && targetPlatform.isx86_32) (fetchpatch {
88 url = "https://git.alpinelinux.org/aports/plain/main/gcc/gcc-6.1-musl-libssp.patch?id=5e4b96e23871ee28ef593b439f8c07ca7c7eb5bb";
89 sha256 = "1jf1ciz4gr49lwyh8knfhw6l5gvfkwzjy90m7qiwkcbsf4a3fqn2";
90 })
91
92 ++ [ ../libsanitizer-no-cyclades-9.patch ];
93
94 javaEcj = fetchurl {
95 # The `$(top_srcdir)/ecj.jar' file is automatically picked up at
96 # `configure' time.
97
98 # XXX: Eventually we might want to take it from upstream.
99 url = "ftp://sourceware.org/pub/java/ecj-4.3.jar";
100 sha256 = "0jz7hvc0s6iydmhgh5h2m15yza7p2rlss2vkif30vm9y77m97qcx";
101 };
102
103 # Antlr (optional) allows the Java `gjdoc' tool to be built. We want a
104 # binary distribution here to allow the whole chain to be bootstrapped.
105 javaAntlr = fetchurl {
106 url = "https://www.antlr.org/download/antlr-4.4-complete.jar";
107 sha256 = "02lda2imivsvsis8rnzmbrbp8rh1kb8vmq4i67pqhkwz7lf8y6dz";
108 };
109
110 xlibs = [
111 libX11 libXt libSM libICE libXtst libXrender libXrandr libXi
112 xorgproto
113 ];
114
115 javaAwtGtk = langJava && x11Support;
116
117 /* Cross-gcc settings (build == host != target) */
118 crossMingw = targetPlatform != hostPlatform && targetPlatform.libc == "msvcrt";
119 stageNameAddon = if crossStageStatic then "stage-static" else "stage-final";
120 crossNameAddon = optionalString (targetPlatform != hostPlatform) "${targetPlatform.config}-${stageNameAddon}-";
121
122in
123
124# We need all these X libraries when building AWT with GTK.
125assert x11Support -> (filter (x: x == null) ([ gtk2 libart_lgpl ] ++ xlibs)) == [];
126
127stdenv.mkDerivation ({
128 pname = "${crossNameAddon}${name}${if stripped then "" else "-debug"}";
129 inherit version;
130
131 builder = ../builder.sh;
132
133 src = if stdenv.targetPlatform.isVc4 then fetchFromGitHub {
134 owner = "itszor";
135 repo = "gcc-vc4";
136 rev = "e90ff43f9671c760cf0d1dd62f569a0fb9bf8918";
137 sha256 = "0gxf66hwqk26h8f853sybphqa5ca0cva2kmrw5jsiv6139g0qnp8";
138 } else if stdenv.targetPlatform.isRedox then fetchFromGitHub {
139 owner = "redox-os";
140 repo = "gcc";
141 rev = "f360ac095028d286fc6dde4d02daed48f59813fa"; # `redox` branch
142 sha256 = "1an96h8l58pppyh3qqv90g8hgcfd9hj7igvh2gigmkxbrx94khfl";
143 } else fetchurl {
144 url = "mirror://gnu/gcc/gcc-${version}/gcc-${version}.tar.xz";
145 sha256 = "0i89fksfp6wr1xg9l8296aslcymv2idn60ip31wr9s4pwin7kwby";
146 };
147
148 inherit patches;
149
150 outputs = if langJava || langGo || langJit then ["out" "man" "info"]
151 else [ "out" "lib" "man" "info" ];
152 setOutputFlags = false;
153 NIX_NO_SELF_RPATH = true;
154
155 libc_dev = stdenv.cc.libc_dev;
156
157 hardeningDisable = [ "format" "pie" ];
158
159 postPatch =
160 # This should kill all the stdinc frameworks that gcc and friends like to
161 # insert into default search paths.
162 lib.optionalString hostPlatform.isDarwin ''
163 substituteInPlace gcc/config/darwin-c.c \
164 --replace 'if (stdinc)' 'if (0)'
165
166 substituteInPlace libgcc/config/t-slibgcc-darwin \
167 --replace "-install_name @shlib_slibdir@/\$(SHLIB_INSTALL_NAME)" "-install_name ''${!outputLib}/lib/\$(SHLIB_INSTALL_NAME)"
168
169 substituteInPlace libgfortran/configure \
170 --replace "-install_name \\\$rpath/\\\$soname" "-install_name ''${!outputLib}/lib/\\\$soname"
171 ''
172 + (
173 if targetPlatform != hostPlatform || stdenv.cc.libc != null then
174 # On NixOS, use the right path to the dynamic linker instead of
175 # `/lib/ld*.so'.
176 let
177 libc = if libcCross != null then libcCross else stdenv.cc.libc;
178 in
179 (
180 '' echo "fixing the \`GLIBC_DYNAMIC_LINKER', \`UCLIBC_DYNAMIC_LINKER', and \`MUSL_DYNAMIC_LINKER' macros..."
181 for header in "gcc/config/"*-gnu.h "gcc/config/"*"/"*.h
182 do
183 grep -q _DYNAMIC_LINKER "$header" || continue
184 echo " fixing \`$header'..."
185 sed -i "$header" \
186 -e 's|define[[:blank:]]*\([UCG]\+\)LIBC_DYNAMIC_LINKER\([0-9]*\)[[:blank:]]"\([^\"]\+\)"$|define \1LIBC_DYNAMIC_LINKER\2 "${libc.out}\3"|g' \
187 -e 's|define[[:blank:]]*MUSL_DYNAMIC_LINKER\([0-9]*\)[[:blank:]]"\([^\"]\+\)"$|define MUSL_DYNAMIC_LINKER\1 "${libc.out}\2"|g'
188 done
189 ''
190 + lib.optionalString (targetPlatform.libc == "musl")
191 ''
192 sed -i gcc/config/linux.h -e '1i#undef LOCAL_INCLUDE_DIR'
193 ''
194 )
195 else "");
196
197 inherit noSysDirs staticCompiler langJava crossStageStatic
198 libcCross crossMingw;
199
200 depsBuildBuild = [ buildPackages.stdenv.cc ];
201 nativeBuildInputs = [ texinfo which gettext ]
202 ++ (optional (perl != null) perl)
203 ++ (optional javaAwtGtk pkg-config)
204 ++ (optional (with stdenv.targetPlatform; isVc4 || isRedox) flex)
205 ++ (optional langAda gnatboot)
206 ;
207
208 # For building runtime libs
209 depsBuildTarget =
210 (
211 if hostPlatform == buildPlatform then [
212 targetPackages.stdenv.cc.bintools # newly-built gcc will be used
213 ] else assert targetPlatform == hostPlatform; [ # build != host == target
214 stdenv.cc
215 ]
216 )
217 ++ optional targetPlatform.isLinux patchelf;
218
219 buildInputs = [
220 gmp mpfr libmpc libelf
221 targetPackages.stdenv.cc.bintools # For linking code at run-time
222 ] ++ (optional (isl != null) isl)
223 ++ (optional (zlib != null) zlib)
224 ++ (optionals langJava [ boehmgc zip unzip ])
225 ++ (optionals javaAwtGtk ([ gtk2 libart_lgpl ] ++ xlibs))
226 # The builder relies on GNU sed (for instance, Darwin's `sed' fails with
227 # "-i may not be used with stdin"), and `stdenvNative' doesn't provide it.
228 ++ (optional hostPlatform.isDarwin gnused)
229 ;
230
231 depsTargetTarget = optional (!crossStageStatic && threadsCross != null) threadsCross;
232
233 NIX_LDFLAGS = lib.optionalString hostPlatform.isSunOS "-lm -ldl";
234
235 preConfigure = import ../common/pre-configure.nix {
236 inherit lib;
237 inherit version targetPlatform hostPlatform gnatboot langJava langAda langGo;
238 };
239
240 dontDisableStatic = true;
241
242 configurePlatforms = [ "build" "host" "target" ];
243
244 configureFlags = import ../common/configure-flags.nix {
245 inherit
246 lib
247 stdenv
248 targetPackages
249 crossStageStatic libcCross
250 version
251
252 gmp mpfr libmpc libelf isl
253
254 enableLTO
255 enableMultilib
256 enablePlugin
257 enableShared
258
259 langC
260 langCC
261 langFortran
262 langJava javaAwtGtk javaAntlr javaEcj
263 langAda
264 langGo
265 langObjC
266 langObjCpp
267 langJit
268 ;
269 };
270
271 targetConfig = if targetPlatform != hostPlatform then targetPlatform.config else null;
272
273 buildFlags = optional
274 (targetPlatform == hostPlatform && hostPlatform == buildPlatform)
275 (if profiledCompiler then "profiledbootstrap" else "bootstrap");
276
277 dontStrip = !stripped;
278
279 doCheck = false; # requires a lot of tools, causes a dependency cycle for stdenv
280
281 installTargets = optional stripped "install-strip";
282
283 # https://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
284 ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
285
286 # Setting $CPATH and $LIBRARY_PATH to make sure both `gcc' and `xgcc' find the
287 # library headers and binaries, regarless of the language being compiled.
288 #
289 # Note: When building the Java AWT GTK peer, the build system doesn't honor
290 # `--with-gmp' et al., e.g., when building
291 # `libjava/classpath/native/jni/java-math/gnu_java_math_GMP.c', so we just add
292 # them to $CPATH and $LIBRARY_PATH in this case.
293 #
294 # Likewise, the LTO code doesn't find zlib.
295 #
296 # Cross-compiling, we need gcc not to read ./specs in order to build the g++
297 # compiler (after the specs for the cross-gcc are created). Having
298 # LIBRARY_PATH= makes gcc read the specs from ., and the build breaks.
299
300 CPATH = optionals (targetPlatform == hostPlatform) (makeSearchPathOutput "dev" "include" ([]
301 ++ optional (zlib != null) zlib
302 ++ optional langJava boehmgc
303 ++ optionals javaAwtGtk xlibs
304 ++ optionals javaAwtGtk [ gmp mpfr ]
305 ));
306
307 LIBRARY_PATH = optionals (targetPlatform == hostPlatform) (makeLibraryPath ([]
308 ++ optional (zlib != null) zlib
309 ++ optional langJava boehmgc
310 ++ optionals javaAwtGtk xlibs
311 ++ optionals javaAwtGtk [ gmp mpfr ]
312 ));
313
314 inherit
315 (import ../common/extra-target-flags.nix {
316 inherit lib stdenv crossStageStatic libcCross threadsCross;
317 })
318 EXTRA_FLAGS_FOR_TARGET
319 EXTRA_LDFLAGS_FOR_TARGET
320 ;
321
322 passthru = {
323 inherit langC langCC langObjC langObjCpp langFortran langAda langGo version;
324 isGNU = true;
325 };
326
327 enableParallelBuilding = true;
328 inherit enableMultilib;
329
330 inherit (stdenv) is64bit;
331
332 meta = {
333 homepage = "https://gcc.gnu.org/";
334 license = lib.licenses.gpl3Plus; # runtime support libraries are typically LGPLv3+
335 description = "GNU Compiler Collection, version ${version}"
336 + (if stripped then "" else " (with debugging info)");
337
338 longDescription = ''
339 The GNU Compiler Collection includes compiler front ends for C, C++,
340 Objective-C, Fortran, OpenMP for C/C++/Fortran, Java, and Ada, as well
341 as libraries for these languages (libstdc++, libgcj, libgomp,...).
342
343 GCC development is a part of the GNU Project, aiming to improve the
344 compiler used in the GNU system including the GNU/Linux variant.
345 '';
346
347 platforms = lib.platforms.unix;
348 };
349}
350
351// optionalAttrs (targetPlatform != hostPlatform && targetPlatform.libc == "msvcrt" && crossStageStatic) {
352 makeFlags = [ "all-gcc" "all-target-libgcc" ];
353 installTargets = "install-gcc install-target-libgcc";
354}
355
356// optionalAttrs (enableMultilib) { dontMoveLib64 = true; }
357
358// optionalAttrs (langJava && !stdenv.hostPlatform.isDarwin) {
359 postFixup = ''
360 target="$(echo "$out/libexec/gcc"/*/*/ecj*)"
361 patchelf --set-rpath "$(patchelf --print-rpath "$target"):$out/lib" "$target"
362 '';}
363)