lol
1{ stdenv, fetchurl, noSysDirs
2, langC ? true, langCC ? true, langFortran ? false
3, langObjC ? stdenv.isDarwin
4, langObjCpp ? stdenv.isDarwin
5, langJava ? false
6, langAda ? false
7, langVhdl ? false
8, langGo ? false
9, profiledCompiler ? false
10, staticCompiler ? false
11, enableShared ? true
12, texinfo ? null
13, perl ? null # optional, for texi2pod (then pod2man); required for Java
14, gmp, mpfr, libmpc, gettext, which
15, libelf # optional, for link-time optimizations (LTO)
16, isl ? null # optional, for the Graphite optimization framework.
17, zlib ? null, boehmgc ? null
18, zip ? null, unzip ? null, pkgconfig ? null
19, gtk ? null, libart_lgpl ? null
20, libX11 ? null, libXt ? null, libSM ? null, libICE ? null, libXtst ? null
21, libXrender ? null, xproto ? null, renderproto ? null, xextproto ? null
22, libXrandr ? null, libXi ? null, inputproto ? null, randrproto ? null
23, x11Support ? langJava
24, gnatboot ? null
25, enableMultilib ? false
26, enablePlugin ? true # whether to support user-supplied plug-ins
27, name ? "gcc"
28, cross ? null
29, binutilsCross ? null
30, libcCross ? null
31, crossStageStatic ? true
32, gnat ? null
33, libpthread ? null, libpthreadCross ? null # required for GNU/Hurd
34, stripped ? true
35, gnused ? null
36, binutils ? null
37}:
38
39assert langJava -> zip != null && unzip != null
40 && zlib != null && boehmgc != null
41 && perl != null; # for `--enable-java-home'
42assert langAda -> gnatboot != null;
43assert langVhdl -> gnat != null;
44
45# LTO needs libelf and zlib.
46assert libelf != null -> zlib != null;
47
48# Make sure we get GNU sed.
49assert stdenv.isDarwin -> gnused != null;
50
51# Need c++filt on darwin
52assert stdenv.isDarwin -> binutils != null;
53
54# The go frontend is written in c++
55assert langGo -> langCC;
56
57with stdenv.lib;
58with builtins;
59
60let version = "5.2.0";
61
62 # Whether building a cross-compiler for GNU/Hurd.
63 crossGNU = cross != null && cross.config == "i586-pc-gnu";
64
65 enableParallelBuilding = true;
66
67 patches = [ ]
68 ++ optional (cross != null) ../libstdc++-target.patch
69 ++ optional noSysDirs ../no-sys-dirs.patch
70 # The GNAT Makefiles did not pay attention to CFLAGS_FOR_TARGET for its
71 # target libraries and tools.
72 ++ optional langAda ../gnat-cflags.patch
73 ++ optional langFortran ../gfortran-driving.patch;
74
75 javaEcj = fetchurl {
76 # The `$(top_srcdir)/ecj.jar' file is automatically picked up at
77 # `configure' time.
78
79 # XXX: Eventually we might want to take it from upstream.
80 url = "ftp://sourceware.org/pub/java/ecj-4.3.jar";
81 sha256 = "0jz7hvc0s6iydmhgh5h2m15yza7p2rlss2vkif30vm9y77m97qcx";
82 };
83
84 # Antlr (optional) allows the Java `gjdoc' tool to be built. We want a
85 # binary distribution here to allow the whole chain to be bootstrapped.
86 javaAntlr = fetchurl {
87 url = http://www.antlr.org/download/antlr-4.4-complete.jar;
88 sha256 = "02lda2imivsvsis8rnzmbrbp8rh1kb8vmq4i67pqhkwz7lf8y6dz";
89 };
90
91 xlibs = [
92 libX11 libXt libSM libICE libXtst libXrender libXrandr libXi
93 xproto renderproto xextproto inputproto randrproto
94 ];
95
96 javaAwtGtk = langJava && x11Support;
97
98 /* Platform flags */
99 platformFlags = let
100 gccArch = stdenv.platform.gcc.arch or null;
101 gccCpu = stdenv.platform.gcc.cpu or null;
102 gccAbi = stdenv.platform.gcc.abi or null;
103 gccFpu = stdenv.platform.gcc.fpu or null;
104 gccFloat = stdenv.platform.gcc.float or null;
105 gccMode = stdenv.platform.gcc.mode or null;
106 withArch = if gccArch != null then " --with-arch=${gccArch}" else "";
107 withCpu = if gccCpu != null then " --with-cpu=${gccCpu}" else "";
108 withAbi = if gccAbi != null then " --with-abi=${gccAbi}" else "";
109 withFpu = if gccFpu != null then " --with-fpu=${gccFpu}" else "";
110 withFloat = if gccFloat != null then " --with-float=${gccFloat}" else "";
111 withMode = if gccMode != null then " --with-mode=${gccMode}" else "";
112 in
113 withArch +
114 withCpu +
115 withAbi +
116 withFpu +
117 withFloat +
118 withMode;
119
120 /* Cross-gcc settings */
121 crossMingw = cross != null && cross.libc == "msvcrt";
122 crossDarwin = cross != null && cross.libc == "libSystem";
123 crossConfigureFlags = let
124 gccArch = stdenv.cross.gcc.arch or null;
125 gccCpu = stdenv.cross.gcc.cpu or null;
126 gccAbi = stdenv.cross.gcc.abi or null;
127 gccFpu = stdenv.cross.gcc.fpu or null;
128 gccFloat = stdenv.cross.gcc.float or null;
129 gccMode = stdenv.cross.gcc.mode or null;
130 withArch = if gccArch != null then " --with-arch=${gccArch}" else "";
131 withCpu = if gccCpu != null then " --with-cpu=${gccCpu}" else "";
132 withAbi = if gccAbi != null then " --with-abi=${gccAbi}" else "";
133 withFpu = if gccFpu != null then " --with-fpu=${gccFpu}" else "";
134 withFloat = if gccFloat != null then " --with-float=${gccFloat}" else "";
135 withMode = if gccMode != null then " --with-mode=${gccMode}" else "";
136 in
137 "--target=${cross.config}" +
138 withArch +
139 withCpu +
140 withAbi +
141 withFpu +
142 withFloat +
143 withMode +
144 (if crossMingw && crossStageStatic then
145 " --with-headers=${libcCross}/include" +
146 " --with-gcc" +
147 " --with-gnu-as" +
148 " --with-gnu-ld" +
149 " --with-gnu-ld" +
150 " --disable-shared" +
151 " --disable-nls" +
152 " --disable-debug" +
153 " --enable-sjlj-exceptions" +
154 " --enable-threads=win32" +
155 " --disable-win32-registry"
156 else if crossStageStatic then
157 " --disable-libssp --disable-nls" +
158 " --without-headers" +
159 " --disable-threads " +
160 " --disable-libgomp " +
161 " --disable-libquadmath" +
162 " --disable-shared" +
163 " --disable-libatomic " + # libatomic requires libc
164 " --disable-decimal-float" # libdecnumber requires libc
165 else
166 (if crossDarwin then " --with-sysroot=${libcCross}/share/sysroot"
167 else " --with-headers=${libcCross}/include") +
168 # Ensure that -print-prog-name is able to find the correct programs.
169 (stdenv.lib.optionalString (crossMingw || crossDarwin) (
170 " --with-as=${binutilsCross}/bin/${cross.config}-as" +
171 " --with-ld=${binutilsCross}/bin/${cross.config}-ld"
172 )) +
173 " --enable-__cxa_atexit" +
174 " --enable-long-long" +
175 (if crossMingw then
176 " --enable-threads=win32" +
177 " --enable-sjlj-exceptions" +
178 " --enable-hash-synchronization" +
179 " --disable-libssp" +
180 " --disable-nls" +
181 " --with-dwarf2" +
182 # I think noone uses shared gcc libs in mingw, so we better do the same.
183 # In any case, mingw32 g++ linking is broken by default with shared libs,
184 # unless adding "-lsupc++" to any linking command. I don't know why.
185 " --disable-shared" +
186 # To keep ABI compatibility with upstream mingw-w64
187 " --enable-fully-dynamic-string"
188 else (if cross.libc == "uclibc" then
189 # In uclibc cases, libgomp needs an additional '-ldl'
190 # and as I don't know how to pass it, I disable libgomp.
191 " --disable-libgomp" else "") +
192 " --enable-threads=posix" +
193 " --enable-nls" +
194 " --disable-decimal-float") # No final libdecnumber (it may work only in 386)
195 );
196 stageNameAddon = if crossStageStatic then "-stage-static" else "-stage-final";
197 crossNameAddon = if cross != null then "-${cross.config}" + stageNameAddon else "";
198
199 bootstrap = cross == null && !stdenv.isArm && !stdenv.isMips;
200
201in
202
203# We need all these X libraries when building AWT with GTK+.
204assert x11Support -> (filter (x: x == null) ([ gtk libart_lgpl ] ++ xlibs)) == [];
205
206stdenv.mkDerivation ({
207 name = "${name}${if stripped then "" else "-debug"}-${version}" + crossNameAddon;
208
209 builder = ../builder.sh;
210
211 outputs = [ "out" "info" ];
212
213 src = fetchurl {
214 url = "mirror://gnu/gcc/gcc-${version}/gcc-${version}.tar.bz2";
215 sha256 = "1bccp8a106xwz3wkixn65ngxif112vn90qf95m6lzpgpnl25p0sz";
216 };
217
218 inherit patches;
219
220 postPatch =
221 if (stdenv.isGNU
222 || (libcCross != null # e.g., building `gcc.crossDrv'
223 && libcCross ? crossConfig
224 && libcCross.crossConfig == "i586-pc-gnu")
225 || (crossGNU && libcCross != null))
226 then
227 # On GNU/Hurd glibc refers to Hurd & Mach headers and libpthread is not
228 # in glibc, so add the right `-I' flags to the default spec string.
229 assert libcCross != null -> libpthreadCross != null;
230 let
231 libc = if libcCross != null then libcCross else stdenv.glibc;
232 gnu_h = "gcc/config/gnu.h";
233 extraCPPDeps =
234 libc.propagatedBuildInputs
235 ++ stdenv.lib.optional (libpthreadCross != null) libpthreadCross
236 ++ stdenv.lib.optional (libpthread != null) libpthread;
237 extraCPPSpec =
238 concatStrings (intersperse " "
239 (map (x: "-I${x}/include") extraCPPDeps));
240 extraLibSpec =
241 if libpthreadCross != null
242 then "-L${libpthreadCross}/lib ${libpthreadCross.TARGET_LDFLAGS}"
243 else "-L${libpthread}/lib";
244 in
245 '' echo "augmenting \`CPP_SPEC' in \`${gnu_h}' with \`${extraCPPSpec}'..."
246 sed -i "${gnu_h}" \
247 -es'|CPP_SPEC *"\(.*\)$|CPP_SPEC "${extraCPPSpec} \1|g'
248
249 echo "augmenting \`LIB_SPEC' in \`${gnu_h}' with \`${extraLibSpec}'..."
250 sed -i "${gnu_h}" \
251 -es'|LIB_SPEC *"\(.*\)$|LIB_SPEC "${extraLibSpec} \1|g'
252
253 echo "setting \`NATIVE_SYSTEM_HEADER_DIR' and \`STANDARD_INCLUDE_DIR' to \`${libc}/include'..."
254 sed -i "${gnu_h}" \
255 -es'|#define STANDARD_INCLUDE_DIR.*$|#define STANDARD_INCLUDE_DIR "${libc}/include"|g'
256 ''
257 else if cross != null || stdenv.cc.libc != null then
258 # On NixOS, use the right path to the dynamic linker instead of
259 # `/lib/ld*.so'.
260 let
261 libc = if libcCross != null then libcCross else stdenv.cc.libc;
262 in
263 '' echo "fixing the \`GLIBC_DYNAMIC_LINKER' and \`UCLIBC_DYNAMIC_LINKER' macros..."
264 for header in "gcc/config/"*-gnu.h "gcc/config/"*"/"*.h
265 do
266 grep -q LIBC_DYNAMIC_LINKER "$header" || continue
267 echo " fixing \`$header'..."
268 sed -i "$header" \
269 -e 's|define[[:blank:]]*\([UCG]\+\)LIBC_DYNAMIC_LINKER\([0-9]*\)[[:blank:]]"\([^\"]\+\)"$|define \1LIBC_DYNAMIC_LINKER\2 "${libc}\3"|g'
270 done
271 ''
272 else null;
273
274 inherit noSysDirs staticCompiler langJava crossStageStatic
275 libcCross crossMingw;
276
277 nativeBuildInputs = [ texinfo which gettext ]
278 ++ (optional (perl != null) perl)
279 ++ (optional javaAwtGtk pkgconfig);
280
281 buildInputs = [ gmp mpfr libmpc libelf ]
282 ++ (optional (isl != null) isl)
283 ++ (optional (zlib != null) zlib)
284 ++ (optionals langJava [ boehmgc zip unzip ])
285 ++ (optionals javaAwtGtk ([ gtk libart_lgpl ] ++ xlibs))
286 ++ (optionals (cross != null) [binutilsCross])
287 ++ (optionals langAda [gnatboot])
288 ++ (optionals langVhdl [gnat])
289
290 # The builder relies on GNU sed (for instance, Darwin's `sed' fails with
291 # "-i may not be used with stdin"), and `stdenvNative' doesn't provide it.
292 ++ (optional stdenv.isDarwin gnused)
293 ++ (optional stdenv.isDarwin binutils)
294 ;
295
296 NIX_LDFLAGS = stdenv.lib.optionalString stdenv.isSunOS "-lm -ldl";
297
298 preConfigure = stdenv.lib.optionalString (stdenv.isSunOS && stdenv.is64bit) ''
299 export NIX_LDFLAGS=`echo $NIX_LDFLAGS | sed -e s~$prefix/lib~$prefix/lib/amd64~g`
300 export LDFLAGS_FOR_TARGET="-Wl,-rpath,$prefix/lib/amd64 $LDFLAGS_FOR_TARGET"
301 export CXXFLAGS_FOR_TARGET="-Wl,-rpath,$prefix/lib/amd64 $CXXFLAGS_FOR_TARGET"
302 export CFLAGS_FOR_TARGET="-Wl,-rpath,$prefix/lib/amd64 $CFLAGS_FOR_TARGET"
303 '' + stdenv.lib.optionalString stdenv.isDarwin ''
304 if SDKROOT=$(/usr/bin/xcrun --show-sdk-path); then
305 configureFlagsArray+=(--with-native-system-header-dir=$SDKROOT/usr/include)
306 makeFlagsArray+=( \
307 CFLAGS_FOR_BUILD=-F$SDKROOT/System/Library/Frameworks \
308 CFLAGS_FOR_TARGET=-F$SDKROOT/System/Library/Frameworks \
309 FLAGS_FOR_TARGET=-F$SDKROOT/System/Library/Frameworks \
310 )
311 fi
312 '';
313
314 dontDisableStatic = true;
315
316 configureFlags = "
317 ${if stdenv.isSunOS then
318 " --enable-long-long --enable-libssp --enable-threads=posix --disable-nls --enable-__cxa_atexit " +
319 # On Illumos/Solaris GNU as is preferred
320 " --with-gnu-as --without-gnu-ld "
321 else ""}
322 --enable-lto
323 ${if enableMultilib then "--enable-multilib --disable-libquadmath" else "--disable-multilib"}
324 ${if enableShared then "" else "--disable-shared"}
325 ${if enablePlugin then "--enable-plugin" else "--disable-plugin"}
326 ${optionalString (isl != null) "--with-isl=${isl}"}
327 ${if langJava then
328 "--with-ecj-jar=${javaEcj} " +
329
330 # Follow Sun's layout for the convenience of IcedTea/OpenJDK. See
331 # <http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2010-April/008888.html>.
332 "--enable-java-home --with-java-home=\${prefix}/lib/jvm/jre "
333 else ""}
334 ${if javaAwtGtk then "--enable-java-awt=gtk" else ""}
335 ${if langJava && javaAntlr != null then "--with-antlr-jar=${javaAntlr}" else ""}
336 --with-gmp=${gmp}
337 --with-mpfr=${mpfr}
338 --with-mpc=${libmpc}
339 ${if libelf != null then "--with-libelf=${libelf}" else ""}
340 --disable-libstdcxx-pch
341 --without-included-gettext
342 --with-system-zlib
343 --enable-static
344 --enable-languages=${
345 concatStrings (intersperse ","
346 ( optional langC "c"
347 ++ optional langCC "c++"
348 ++ optional langFortran "fortran"
349 ++ optional langJava "java"
350 ++ optional langAda "ada"
351 ++ optional langVhdl "vhdl"
352 ++ optional langGo "go"
353 ++ optional langObjC "objc"
354 ++ optional langObjCpp "obj-c++"
355 ++ optionals crossDarwin [ "objc" "obj-c++" ]
356 )
357 )
358 }
359 ${if (stdenv ? glibc && cross == null)
360 then " --with-native-system-header-dir=${stdenv.glibc}/include"
361 else ""}
362 ${if langAda then " --enable-libada" else ""}
363 ${if cross == null && stdenv.isi686 then "--with-arch=i686" else ""}
364 ${if cross != null then crossConfigureFlags else ""}
365 ${if !bootstrap then "--disable-bootstrap" else ""}
366 ${if cross == null then platformFlags else ""}
367 ";
368
369 targetConfig = if cross != null then cross.config else null;
370
371 buildFlags = if bootstrap then
372 (if profiledCompiler then "profiledbootstrap" else "bootstrap")
373 else "";
374
375 installTargets =
376 if stripped
377 then "install-strip"
378 else "install";
379
380 crossAttrs = let
381 xgccArch = stdenv.cross.gcc.arch or null;
382 xgccCpu = stdenv.cross.gcc.cpu or null;
383 xgccAbi = stdenv.cross.gcc.abi or null;
384 xgccFpu = stdenv.cross.gcc.fpu or null;
385 xgccFloat = stdenv.cross.gcc.float or null;
386 xwithArch = if xgccArch != null then " --with-arch=${xgccArch}" else "";
387 xwithCpu = if xgccCpu != null then " --with-cpu=${xgccCpu}" else "";
388 xwithAbi = if xgccAbi != null then " --with-abi=${xgccAbi}" else "";
389 xwithFpu = if xgccFpu != null then " --with-fpu=${xgccFpu}" else "";
390 xwithFloat = if xgccFloat != null then " --with-float=${xgccFloat}" else "";
391 in {
392 AR = "${stdenv.cross.config}-ar";
393 LD = "${stdenv.cross.config}-ld";
394 CC = "${stdenv.cross.config}-gcc";
395 CXX = "${stdenv.cross.config}-gcc";
396 AR_FOR_TARGET = "${stdenv.cross.config}-ar";
397 LD_FOR_TARGET = "${stdenv.cross.config}-ld";
398 CC_FOR_TARGET = "${stdenv.cross.config}-gcc";
399 NM_FOR_TARGET = "${stdenv.cross.config}-nm";
400 CXX_FOR_TARGET = "${stdenv.cross.config}-g++";
401 # If we are making a cross compiler, cross != null
402 NIX_CC_CROSS = if cross == null then "${stdenv.ccCross}" else "";
403 dontStrip = true;
404 configureFlags = ''
405 ${if enableMultilib then "" else "--disable-multilib"}
406 ${if enableShared then "" else "--disable-shared"}
407 ${if langJava then "--with-ecj-jar=${javaEcj.crossDrv}" else ""}
408 ${if javaAwtGtk then "--enable-java-awt=gtk" else ""}
409 ${if langJava && javaAntlr != null then "--with-antlr-jar=${javaAntlr.crossDrv}" else ""}
410 --with-gmp=${gmp.crossDrv}
411 --with-mpfr=${mpfr.crossDrv}
412 --disable-libstdcxx-pch
413 --without-included-gettext
414 --with-system-zlib
415 --enable-languages=${
416 concatStrings (intersperse ","
417 ( optional langC "c"
418 ++ optional langCC "c++"
419 ++ optional langFortran "fortran"
420 ++ optional langJava "java"
421 ++ optional langAda "ada"
422 ++ optional langVhdl "vhdl"
423 ++ optional langGo "go"
424 )
425 )
426 }
427 ${if langAda then " --enable-libada" else ""}
428 --target=${stdenv.cross.config}
429 ${xwithArch}
430 ${xwithCpu}
431 ${xwithAbi}
432 ${xwithFpu}
433 ${xwithFloat}
434 '';
435 buildFlags = "";
436 };
437
438
439 # Needed for the cross compilation to work
440 AR = "ar";
441 LD = "ld";
442 # http://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
443 CC = if stdenv.system == "x86_64-solaris" then "gcc -m64" else "gcc";
444
445 # Setting $CPATH and $LIBRARY_PATH to make sure both `gcc' and `xgcc' find
446 # the library headers and binaries, regarless of the language being
447 # compiled.
448
449 # Note: When building the Java AWT GTK+ peer, the build system doesn't
450 # honor `--with-gmp' et al., e.g., when building
451 # `libjava/classpath/native/jni/java-math/gnu_java_math_GMP.c', so we just
452 # add them to $CPATH and $LIBRARY_PATH in this case.
453 #
454 # Likewise, the LTO code doesn't find zlib.
455
456 CPATH = concatStrings
457 (intersperse ":" (map (x: x + "/include")
458 (optionals (zlib != null) [ zlib ]
459 ++ optionals langJava [ boehmgc ]
460 ++ optionals javaAwtGtk xlibs
461 ++ optionals javaAwtGtk [ gmp mpfr ]
462 ++ optional (libpthread != null) libpthread
463 ++ optional (libpthreadCross != null) libpthreadCross
464
465 # On GNU/Hurd glibc refers to Mach & Hurd
466 # headers.
467 ++ optionals (libcCross != null && libcCross ? "propagatedBuildInputs" )
468 libcCross.propagatedBuildInputs)));
469
470 LIBRARY_PATH = concatStrings
471 (intersperse ":" (map (x: x + "/lib")
472 (optionals (zlib != null) [ zlib ]
473 ++ optionals langJava [ boehmgc ]
474 ++ optionals javaAwtGtk xlibs
475 ++ optionals javaAwtGtk [ gmp mpfr ]
476 ++ optional (libpthread != null) libpthread)));
477
478 EXTRA_TARGET_CFLAGS =
479 if cross != null && libcCross != null
480 then "-idirafter ${libcCross}/include"
481 else null;
482
483 EXTRA_TARGET_LDFLAGS =
484 if cross != null && libcCross != null
485 then "-B${libcCross}/lib -Wl,-L${libcCross}/lib" +
486 (optionalString (libpthreadCross != null)
487 " -L${libpthreadCross}/lib -Wl,${libpthreadCross.TARGET_LDFLAGS}")
488 else null;
489
490 passthru =
491 { inherit langC langCC langObjC langObjCpp langAda langFortran langVhdl langGo version; isGNU = true; };
492
493 inherit enableParallelBuilding enableMultilib;
494
495 inherit (stdenv) is64bit;
496
497 meta = {
498 homepage = http://gcc.gnu.org/;
499 license = stdenv.lib.licenses.gpl3Plus; # runtime support libraries are typically LGPLv3+
500 description = "GNU Compiler Collection, version ${version}"
501 + (if stripped then "" else " (with debugging info)");
502
503 longDescription = ''
504 The GNU Compiler Collection includes compiler front ends for C, C++,
505 Objective-C, Fortran, OpenMP for C/C++/Fortran, Java, and Ada, as well
506 as libraries for these languages (libstdc++, libgcj, libgomp,...).
507
508 GCC development is a part of the GNU Project, aiming to improve the
509 compiler used in the GNU system including the GNU/Linux variant.
510 '';
511
512 maintainers = with stdenv.lib.maintainers; [ viric simons ];
513
514 # gnatboot is not available out of linux platforms, so we disable the darwin build
515 # for the gnat (ada compiler).
516 platforms =
517 stdenv.lib.platforms.linux ++
518 stdenv.lib.platforms.freebsd ++
519 optionals (langAda == false) stdenv.lib.platforms.darwin;
520 };
521}
522
523// optionalAttrs (cross != null && cross.libc == "msvcrt" && crossStageStatic) {
524 makeFlags = [ "all-gcc" "all-target-libgcc" ];
525 installTargets = "install-gcc install-target-libgcc";
526}
527
528# Strip kills static libs of other archs (hence cross != null)
529// optionalAttrs (!stripped || cross != null) { dontStrip = true; NIX_STRIP_DEBUG = 0; }
530
531// optionalAttrs (enableMultilib) { dontMoveLib64 = true; }
532)