lol
1{ stdenv, targetPackages, fetchurl, noSysDirs
2, langC ? true, langCC ? true, langFortran ? false
3, langJava ? false
4, langAda ? false
5, langVhdl ? false
6, profiledCompiler ? false
7, staticCompiler ? false
8, enableShared ? true
9, texinfo ? null
10, perl ? null # optional, for texi2pod (then pod2man); required for Java
11, gmp, mpfr, libmpc, gettext, which
12, libelf # optional, for link-time optimizations (LTO)
13, ppl ? null, cloogppl ? null # optional, for the Graphite optimization framework
14, zlib ? null, boehmgc ? null
15, zip ? null, unzip ? null, pkgconfig ? null, gtk2 ? null, libart_lgpl ? null
16, libX11 ? null, libXt ? null, libSM ? null, libICE ? null, libXtst ? null
17, libXrender ? null, xproto ? null, renderproto ? null, xextproto ? null
18, libXrandr ? null, libXi ? null, inputproto ? null, randrproto ? null
19, gnatboot ? null
20, enableMultilib ? false
21, name ? "gcc"
22, libcCross ? null
23, crossStageStatic ? false
24, gnat ? null
25, libpthread ? null, libpthreadCross ? null # required for GNU/Hurd
26, stripped ? true
27, buildPlatform, hostPlatform, targetPlatform
28, buildPackages
29}:
30
31assert langJava -> zip != null && unzip != null
32 && zlib != null && boehmgc != null
33 && perl != null; # for `--enable-java-home'
34assert langAda -> gnatboot != null;
35assert langVhdl -> gnat != null;
36
37# LTO needs libelf and zlib.
38assert libelf != null -> zlib != null;
39
40with stdenv.lib;
41with builtins;
42
43let version = "4.5.4";
44 javaEcj = fetchurl {
45 # The `$(top_srcdir)/ecj.jar' file is automatically picked up at
46 # `configure' time.
47
48 # XXX: Eventually we might want to take it from upstream.
49 url = "ftp://sourceware.org/pub/java/ecj-4.3.jar";
50 sha256 = "0jz7hvc0s6iydmhgh5h2m15yza7p2rlss2vkif30vm9y77m97qcx";
51 };
52
53 # Antlr (optional) allows the Java `gjdoc' tool to be built. We want a
54 # binary distribution here to allow the whole chain to be bootstrapped.
55 javaAntlr = fetchurl {
56 url = http://www.antlr.org/download/antlr-3.1.3.jar;
57 sha256 = "1f41j0y4kjydl71lqlvr73yagrs2jsg1fjymzjz66mjy7al5lh09";
58 };
59
60 xlibs = [
61 libX11 libXt libSM libICE libXtst libXrender libXrandr libXi
62 xproto renderproto xextproto inputproto randrproto
63 ];
64
65 javaAwtGtk = langJava && gtk2 != null;
66
67 /* Platform flags */
68 platformFlags = let
69 gccArch = targetPlatform.platform.gcc.arch or null;
70 gccCpu = targetPlatform.platform.gcc.cpu or null;
71 gccAbi = targetPlatform.platform.gcc.abi or null;
72 gccFpu = targetPlatform.platform.gcc.fpu or null;
73 gccFloat = targetPlatform.platform.gcc.float or null;
74 gccMode = targetPlatform.platform.gcc.mode or null;
75 in
76 optional (gccArch != null) "--with-arch=${gccArch}" ++
77 optional (gccCpu != null) "--with-cpu=${gccCpu}" ++
78 optional (gccAbi != null) "--with-abi=${gccAbi}" ++
79 optional (gccFpu != null) "--with-fpu=${gccFpu}" ++
80 optional (gccFloat != null) "--with-float=${gccFloat}" ++
81 optional (gccMode != null) "--with-mode=${gccMode}";
82
83 /* Cross-gcc settings */
84 crossMingw = (targetPlatform != hostPlatform && targetPlatform.libc == "msvcrt");
85
86 crossConfigureFlags =
87 # Ensure that -print-prog-name is able to find the correct programs.
88 [ "--with-as=${targetPackages.stdenv.cc.bintools}/bin/${targetPlatform.config}-as"
89 "--with-ld=${targetPackages.stdenv.cc.bintools}/bin/${targetPlatform.config}-ld" ] ++
90 (if crossMingw && crossStageStatic then [
91 "--with-headers=${libcCross}/include"
92 "--with-gcc"
93 "--with-gnu-as"
94 "--with-gnu-ld"
95 "--with-gnu-ld"
96 "--disable-shared"
97 "--disable-nls"
98 "--disable-debug"
99 "--enable-sjlj-exceptions"
100 "--enable-threads=win32"
101 "--disable-win32-registry"
102 ] else if crossStageStatic then [
103 "--disable-libssp"
104 "--disable-nls"
105 "--without-headers"
106 "--disable-threads"
107 "--disable-libmudflap"
108 "--disable-libgomp"
109 "--disable-shared"
110 "--disable-decimal-float" # libdecnumber requires libc
111 ] else [
112 "--with-headers=${libcCross}/include"
113 "--enable-__cxa_atexit"
114 "--enable-long-long"
115 ] ++
116 (if crossMingw then [
117 "--enable-threads=win32"
118 "--enable-sjlj-exceptions"
119 "--enable-hash-synchronization"
120 "--enable-version-specific-runtime-libs"
121 "--enable-libssp"
122 "--disable-nls"
123 "--with-dwarf2"
124 ] else [
125 "--enable-threads=posix"
126 "--enable-nls"
127 "--disable-decimal-float" # No final libdecnumber (it may work only in 386)
128 ]));
129 stageNameAddon = if crossStageStatic then "-stage-static" else
130 "-stage-final";
131 crossNameAddon = if targetPlatform != hostPlatform then "-${targetPlatform.config}" + stageNameAddon else "";
132
133in
134
135# We need all these X libraries when building AWT with GTK+.
136assert gtk2 != null -> (filter (x: x == null) xlibs) == [];
137
138stdenv.mkDerivation ({
139 name = "${name}-${version}" + crossNameAddon;
140
141 builder = ../builder.sh;
142
143 src = (import ./sources.nix) {
144 inherit fetchurl optional version;
145 inherit langC langCC langFortran langJava langAda;
146 };
147
148 hardeningDisable = [ "format" ] ++ optional (name != "gnat") "all";
149
150 outputs = [ "out" "man" "info" ]
151 ++ optional (!(hostPlatform.is64bit && langAda)) "lib";
152
153 setOutputFlags = false;
154 NIX_NO_SELF_RPATH = true;
155
156 libc_dev = stdenv.cc.libc_dev;
157
158 patches =
159 [ ]
160 ++ optional (targetPlatform != hostPlatform) ../libstdc++-target.patch
161 ++ optional noSysDirs ./no-sys-dirs.patch
162 # The GNAT Makefiles did not pay attention to CFLAGS_FOR_TARGET for its
163 # target libraries and tools.
164 ++ optional langAda ../gnat-cflags.patch
165 ++ optional langVhdl ./ghdl-ortho-cflags.patch
166 ++ [ ../struct-ucontext-4.5.patch ] # glibc-2.26
167 ;
168
169 postPatch =
170 if (stdenv.system == "i586-pc-gnu"
171 || (libcCross != null # e.g., building `gcc.crossDrv'
172 && libcCross ? crossConfig
173 && libcCross.crossConfig == "i586-pc-gnu")
174 || (targetPlatform != hostPlatform && targetPlatform.config == "i586-pc-gnu"
175 && libcCross != null))
176 then
177 # On GNU/Hurd glibc refers to Hurd & Mach headers and libpthread is not
178 # in glibc, so add the right `-I' flags to the default spec string.
179 assert libcCross != null -> libpthreadCross != null;
180 let
181 libc = if libcCross != null then libcCross else stdenv.glibc;
182 gnu_h = "gcc/config/gnu.h";
183 i386_gnu_h = "gcc/config/i386/gnu.h";
184 extraCPPDeps =
185 libc.propagatedBuildInputs
186 ++ stdenv.lib.optional (libpthreadCross != null) libpthreadCross
187 ++ stdenv.lib.optional (libpthread != null) libpthread;
188 extraCPPSpec =
189 concatStrings (intersperse " "
190 (map (x: "-I${x.dev or x}/include") extraCPPDeps));
191 extraLibSpec =
192 if libpthreadCross != null
193 then "-L${libpthreadCross}/lib ${libpthreadCross.TARGET_LDFLAGS}"
194 else "-L${libpthread}/lib";
195 in
196 '' echo "augmenting \`CPP_SPEC' in \`${i386_gnu_h}' with \`${extraCPPSpec}'..."
197 sed -i "${i386_gnu_h}" \
198 -es'|CPP_SPEC *"\(.*\)$|CPP_SPEC "${extraCPPSpec} \1|g'
199
200 echo "augmenting \`LIB_SPEC' in \`${gnu_h}' with \`${extraLibSpec}'..."
201 sed -i "${gnu_h}" \
202 -es'|LIB_SPEC *"\(.*\)$|LIB_SPEC "${extraLibSpec} \1|g'
203
204 echo "setting \`NATIVE_SYSTEM_HEADER_DIR' and \`STANDARD_INCLUDE_DIR' to \`${libc.dev}/include'..."
205 sed -i "${gnu_h}" \
206 -es'|#define STANDARD_INCLUDE_DIR.*$|#define STANDARD_INCLUDE_DIR "${libc.dev}/include"|g'
207 sed -i gcc/config/t-gnu \
208 -es'|NATIVE_SYSTEM_HEADER_DIR.*$|NATIVE_SYSTEM_HEADER_DIR = ${libc.dev}/include|g'
209 ''
210 else if targetPlatform != hostPlatform || stdenv.cc.libc != null then
211 # On NixOS, use the right path to the dynamic linker instead of
212 # `/lib/ld*.so'.
213 let
214 libc = if libcCross != null then libcCross else stdenv.cc.libc;
215 in
216 '' echo "fixing the \`GLIBC_DYNAMIC_LINKER' and \`UCLIBC_DYNAMIC_LINKER' macros..."
217 for header in "gcc/config/"*-gnu.h "gcc/config/"*"/"*.h
218 do
219 grep -q LIBC_DYNAMIC_LINKER "$header" || continue
220 echo " fixing \`$header'..."
221 sed -i "$header" \
222 -e 's|define[[:blank:]]*\([UCG]\+\)LIBC_DYNAMIC_LINKER\([0-9]*\)[[:blank:]]"\([^\"]\+\)"$|define \1LIBC_DYNAMIC_LINKER\2 "${libc.out}\3"|g'
223 done
224 ''
225 else null;
226
227 # TODO(@Ericson2314): Make passthru instead. Weird to avoid mass rebuild,
228 crossStageStatic = targetPlatform == hostPlatform || crossStageStatic;
229 inherit noSysDirs profiledCompiler staticCompiler langJava
230 libcCross crossMingw;
231
232 depsBuildBuild = [ buildPackages.stdenv.cc ];
233 nativeBuildInputs = [ texinfo which gettext ]
234 ++ optional (perl != null) perl;
235
236 # For building runtime libs
237 depsBuildTarget =
238 if hostPlatform == buildPlatform then [
239 targetPackages.stdenv.cc.bintools # newly-built gcc will be used
240 ] else assert targetPlatform == hostPlatform; [ # build != host == target
241 stdenv.cc
242 ];
243
244 buildInputs = [
245 gmp mpfr libmpc libelf
246 targetPackages.stdenv.cc.bintools # For linking code at run-time
247 ] ++ (optional (ppl != null) ppl)
248 ++ (optional (cloogppl != null) cloogppl)
249 ++ (optional (zlib != null) zlib)
250 ++ (optional langJava boehmgc)
251 ++ (optionals langJava [zip unzip])
252 ++ (optionals javaAwtGtk ([gtk2 pkgconfig libart_lgpl] ++ xlibs))
253 ++ (optionals (targetPlatform != hostPlatform) [targetPackages.stdenv.cc.bintools])
254 ++ (optionals langAda [gnatboot])
255 ++ (optionals langVhdl [gnat])
256 ;
257
258 # TODO(@Ericson2314): Always pass "--target" and always prefix.
259 configurePlatforms =
260 # TODO(@Ericson2314): Figure out what's going wrong with Arm
261 if buildPlatform == hostPlatform && hostPlatform == targetPlatform && targetPlatform.isArm
262 then []
263 else [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
264
265 configureFlags =
266 # Basic dependencies
267 [
268 "--with-gmp=${gmp.dev}"
269 "--with-mpfr=${mpfr.dev}"
270 "--with-mpc=${libmpc}"
271 ] ++
272 optional (libelf != null) "--with-libelf=${libelf}" ++
273 optional (!(crossMingw && crossStageStatic))
274 "--with-native-system-header-dir=${getDev stdenv.cc.libc}/include" ++
275
276 # Basic configuration
277 [
278 "--disable-libstdcxx-pch"
279 "--without-included-gettext"
280 "--with-system-zlib"
281 "--enable-languages=${
282 concatStrings (intersperse ","
283 ( optional langC "c"
284 ++ optional langCC "c++"
285 ++ optional langFortran "fortran"
286 ++ optional langJava "java"
287 ++ optional langAda "ada"
288 ++ optional langVhdl "vhdl"
289 )
290 )
291 }"
292 ] ++
293 optional (!enableMultilib) "--disable-multilib" ++
294 optional (!enableShared) "--disable-shared" ++
295
296 # Optional features
297 optional (cloogppl != null) "--with-cloog=${cloogppl}" ++
298 optional (ppl != null) "--with-ppl=${ppl}" ++
299
300 # Java options
301 optionals langJava [
302 "--with-ecj-jar=${javaEcj}"
303
304 # Follow Sun's layout for the convenience of IcedTea/OpenJDK. See
305 # <http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2010-April/008888.html>.
306 "--enable-java-home"
307 "--with-java-home=\${prefix}/lib/jvm/jre"
308 ] ++
309 optional javaAwtGtk "--enable-java-awt=gtk" ++
310 optional (langJava && javaAntlr != null) "--with-antlr-jar=${javaAntlr}" ++
311
312 # Ada
313 optional langAda "--enable-libada" ++
314
315 platformFlags ++
316 optional (targetPlatform != hostPlatform) crossConfigureFlags ++
317
318 # Platform-specific flags
319 optional (targetPlatform == hostPlatform && targetPlatform.isi686) "--with-arch=i686" ++
320 # Trick that should be taken out once we have a mipsel-linux not loongson2f
321 optional (targetPlatform == hostPlatform && stdenv.system == "mipsel-linux") "--with-arch=loongson2f"
322 ;
323
324 targetConfig = if targetPlatform != hostPlatform then targetPlatform.config else null;
325
326 /* For cross-built gcc (build != host == target) */
327 crossAttrs = {
328 dontStrip = true;
329 };
330
331 # Setting $CPATH and $LIBRARY_PATH to make sure both `gcc' and `xgcc' find the
332 # library headers and binaries, regarless of the language being compiled.
333 #
334 # Note: When building the Java AWT GTK+ peer, the build system doesn't honor
335 # `--with-gmp' et al., e.g., when building
336 # `libjava/classpath/native/jni/java-math/gnu_java_math_GMP.c', so we just add
337 # them to $CPATH and $LIBRARY_PATH in this case.
338 #
339 # Likewise, the LTO code doesn't find zlib.
340 #
341 # Cross-compiling, we need gcc not to read ./specs in order to build the g++
342 # compiler (after the specs for the cross-gcc are created). Having
343 # LIBRARY_PATH= makes gcc read the specs from ., and the build breaks.
344
345 CPATH = optionals (targetPlatform == hostPlatform) (makeSearchPathOutput "dev" "include" ([]
346 ++ optional (zlib != null) zlib
347 ++ optional langJava boehmgc
348 ++ optionals javaAwtGtk xlibs
349 ++ optionals javaAwtGtk [ gmp mpfr ]
350 ++ optional (libpthread != null) libpthread
351 ++ optional (libpthreadCross != null) libpthreadCross
352
353 # On GNU/Hurd glibc refers to Mach & Hurd
354 # headers.
355 ++ optionals (libcCross != null && libcCross ? propagatedBuildInputs)
356 libcCross.propagatedBuildInputs
357 ));
358
359 LIBRARY_PATH = optionals (targetPlatform == hostPlatform) (makeLibraryPath ([]
360 ++ optional (zlib != null) zlib
361 ++ optional langJava boehmgc
362 ++ optionals javaAwtGtk xlibs
363 ++ optionals javaAwtGtk [ gmp mpfr ]
364 ++ optional (libpthread != null) libpthread)
365 );
366
367 EXTRA_TARGET_FLAGS = optionals
368 (targetPlatform != hostPlatform && libcCross != null)
369 ([
370 "-idirafter ${libcCross.dev}/include"
371 ] ++ optionals (! crossStageStatic) [
372 "-B${libcCross.out}/lib"
373 ]);
374
375 EXTRA_TARGET_LDFLAGS = optionals
376 (targetPlatform != hostPlatform && libcCross != null)
377 ([
378 "-Wl,-L${libcCross.out}/lib"
379 ] ++ (if crossStageStatic then [
380 "-B${libcCross.out}/lib"
381 ] else [
382 "-Wl,-rpath,${libcCross.out}/lib"
383 "-Wl,-rpath-link,${libcCross.out}/lib"
384 ]) ++ optionals (libpthreadCross != null) [
385 "-L${libpthreadCross}/lib"
386 "-Wl,${libpthreadCross.TARGET_LDFLAGS}"
387 ]);
388
389 passthru = {
390 inherit langC langCC langAda langFortran langVhdl enableMultilib version;
391 isGNU = true;
392 hardeningUnsupportedFlags = [ "stackprotector" ];
393 };
394
395 enableParallelBuilding = !langAda;
396
397 meta = {
398 homepage = http://gcc.gnu.org/;
399 license = stdenv.lib.licenses.gpl3Plus; # runtime support libraries are typically LGPLv3+
400 description = "GNU Compiler Collection, version ${version}"
401 + (if stripped then "" else " (with debugging info)");
402
403 longDescription = ''
404 The GNU Compiler Collection includes compiler front ends for C, C++,
405 Objective-C, Fortran, OpenMP for C/C++/Fortran, Java, and Ada, as well
406 as libraries for these languages (libstdc++, libgcj, libgomp,...).
407
408 GCC development is a part of the GNU Project, aiming to improve the
409 compiler used in the GNU system including the GNU/Linux variant.
410 '';
411
412 maintainers = [
413 stdenv.lib.maintainers.viric
414 ];
415
416 # Volunteers needed for the {Cyg,Dar}win ports of *PPL.
417 # gnatboot is not available out of linux platforms, so we disable the darwin build
418 # for the gnat (ada compiler).
419 platforms = stdenv.lib.platforms.linux ++ optionals (langAda == false) [ "i686-darwin" ];
420 };
421}
422
423// optionalAttrs (targetPlatform != hostPlatform || libcCross != null) {
424 # `builder.sh' sets $CPP, which leads configure to use "gcc -E" instead of,
425 # say, "i586-pc-gnu-gcc -E" when building `gcc.crossDrv'.
426 # FIXME: Fix `builder.sh' directly in the next stdenv-update.
427 postUnpack = "unset CPP";
428}
429
430// optionalAttrs (targetPlatform != hostPlatform && targetPlatform.libc == "msvcrt" && crossStageStatic) {
431 makeFlags = [ "all-gcc" "all-target-libgcc" ];
432 installTargets = "install-gcc install-target-libgcc";
433}
434
435# GCC 4.5.2 doesn't support the `install-strip' target, so let `stdenv' do
436# the stripping by default.
437// optionalAttrs (!stripped) { dontStrip = true; }
438
439// optionalAttrs langVhdl rec {
440 name = "ghdl-0.29";
441
442 ghdlSrc = fetchurl {
443 url = "http://ghdl.free.fr/ghdl-0.29.tar.bz2";
444 sha256 = "15mlinr1lwljwll9ampzcfcrk9bk0qpdks1kxlvb70xf9zhh2jva";
445 };
446
447 # Ghdl has some timestamps checks, storing file timestamps in '.cf' files.
448 # As we will change the timestamps to 1970-01-01 00:00:01, we also set the
449 # content of that .cf to that value. This way ghdl does not complain on
450 # the installed object files from the basic libraries (ieee, ...)
451 postInstallGhdl = ''
452 pushd $out
453 find . -name "*.cf" -exec \
454 sed 's/[0-9]*\.000" /19700101000001.000" /g' -i {} \;
455 popd
456 '';
457
458 postUnpack = ''
459 tar xvf ${ghdlSrc}
460 mv ghdl-*/vhdl gcc*/gcc
461 rm -Rf ghdl-*
462 '';
463
464 meta = {
465 homepage = http://ghdl.free.fr/;
466 license = stdenv.lib.licenses.gpl2Plus;
467 description = "Complete VHDL simulator, using the GCC technology (gcc ${version})";
468 maintainers = with stdenv.lib.maintainers; [viric];
469 platforms = with stdenv.lib.platforms; linux;
470 };
471
472})