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, # 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, perl ? null # optional, for texi2pod (then pod2man)
21, gmp, mpfr, libmpc, gettext, which, patchelf
22, libelf # optional, for link-time optimizations (LTO)
23, isl ? null # optional, for the Graphite optimization framework.
24, zlib ? null
25, gnatboot ? null
26, enableMultilib ? false
27, enablePlugin ? stdenv.hostPlatform == stdenv.buildPlatform # Whether to support user-supplied plug-ins
28, name ? "gcc"
29, libcCross ? null
30, threadsCross ? null # for MinGW
31, crossStageStatic ? false
32, # Strip kills static libs of other archs (hence no cross)
33 stripped ? stdenv.hostPlatform.system == stdenv.buildPlatform.system
34 && stdenv.targetPlatform.system == stdenv.hostPlatform.system
35, gnused ? null
36, cloog # unused; just for compat with gcc4, as we override the parameter on some places
37, buildPackages
38}:
39
40# Note: this package is used for bootstrapping fetchurl, and thus
41# cannot use fetchpatch! All mutable patches (generated by GitHub or
42# cgit) that are needed here should be included directly in Nixpkgs as
43# files.
44
45# LTO needs libelf and zlib.
46assert libelf != null -> zlib != null;
47
48# Make sure we get GNU sed.
49assert stdenv.hostPlatform.isDarwin -> gnused != null;
50
51# The go frontend is written in c++
52assert langGo -> langCC;
53assert langAda -> gnatboot != null;
54
55# threadsCross is just for MinGW
56assert threadsCross != null -> stdenv.targetPlatform.isWindows;
57
58# profiledCompiler builds inject non-determinism in one of the compilation stages.
59# If turned on, we can't provide reproducible builds anymore
60assert reproducibleBuild -> profiledCompiler == false;
61
62with lib;
63with builtins;
64
65let majorVersion = "9";
66 version = "${majorVersion}.3.0";
67
68 inherit (stdenv) buildPlatform hostPlatform targetPlatform;
69
70 patches =
71 # Fix ICE: Max. number of generated reload insns per insn is achieved (90)
72 #
73 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96796
74 #
75 # This patch can most likely be removed by a post 9.3.0-release.
76 [ ./avoid-cycling-subreg-reloads.patch ]
77 ++ optional (targetPlatform != hostPlatform) ../libstdc++-target.patch
78 ++ optional targetPlatform.isNetBSD ../libstdc++-netbsd-ctypes.patch
79 ++ optional noSysDirs ../no-sys-dirs.patch
80 /* ++ optional (hostPlatform != buildPlatform) (fetchpatch { # XXX: Refine when this should be applied
81 url = "https://git.busybox.net/buildroot/plain/package/gcc/${version}/0900-remove-selftests.patch?id=11271540bfe6adafbc133caf6b5b902a816f5f02";
82 sha256 = ""; # TODO: uncomment and check hash when available.
83 }) */
84 ++ optional langAda ../gnat-cflags.patch
85 ++ optional langD ../libphobos.patch
86 ++ optional langFortran ../gfortran-driving.patch
87 ++ optional (targetPlatform.libc == "musl" && targetPlatform.isPower) ../ppc-musl.patch
88
89 # Obtain latest patch with ../update-mcfgthread-patches.sh
90 ++ optional (!crossStageStatic && targetPlatform.isMinGW) ./Added-mcf-thread-model-support-from-mcfgthread.patch
91
92 ++ [ ../libsanitizer-no-cyclades-9.patch ];
93
94 /* Cross-gcc settings (build == host != target) */
95 crossMingw = targetPlatform != hostPlatform && targetPlatform.libc == "msvcrt";
96 stageNameAddon = if crossStageStatic then "stage-static" else "stage-final";
97 crossNameAddon = optionalString (targetPlatform != hostPlatform) "${targetPlatform.config}-${stageNameAddon}-";
98
99in
100
101stdenv.mkDerivation ({
102 pname = "${crossNameAddon}${name}${if stripped then "" else "-debug"}";
103 inherit version;
104
105 builder = ../builder.sh;
106
107 src = fetchurl {
108 url = "mirror://gcc/releases/gcc-${version}/gcc-${version}.tar.xz";
109 sha256 = "1la2yy27ziasyf0jvzk58y1i5b5bq2h176qil550bxhifs39gqbi";
110 };
111
112 inherit patches;
113
114 outputs = [ "out" "man" "info" ] ++ lib.optional (!langJit) "lib";
115 setOutputFlags = false;
116 NIX_NO_SELF_RPATH = true;
117
118 libc_dev = stdenv.cc.libc_dev;
119
120 hardeningDisable = [ "format" "pie" ];
121
122 postPatch = ''
123 configureScripts=$(find . -name configure)
124 for configureScript in $configureScripts; do
125 patchShebangs $configureScript
126 done
127 ''
128 # This should kill all the stdinc frameworks that gcc and friends like to
129 # insert into default search paths.
130 + lib.optionalString hostPlatform.isDarwin ''
131 substituteInPlace gcc/config/darwin-c.c \
132 --replace 'if (stdinc)' 'if (0)'
133
134 substituteInPlace libgcc/config/t-slibgcc-darwin \
135 --replace "-install_name @shlib_slibdir@/\$(SHLIB_INSTALL_NAME)" "-install_name ''${!outputLib}/lib/\$(SHLIB_INSTALL_NAME)"
136
137 substituteInPlace libgfortran/configure \
138 --replace "-install_name \\\$rpath/\\\$soname" "-install_name ''${!outputLib}/lib/\\\$soname"
139 ''
140 + (
141 if targetPlatform != hostPlatform || stdenv.cc.libc != null then
142 # On NixOS, use the right path to the dynamic linker instead of
143 # `/lib/ld*.so'.
144 let
145 libc = if libcCross != null then libcCross else stdenv.cc.libc;
146 in
147 (
148 '' echo "fixing the \`GLIBC_DYNAMIC_LINKER', \`UCLIBC_DYNAMIC_LINKER', and \`MUSL_DYNAMIC_LINKER' macros..."
149 for header in "gcc/config/"*-gnu.h "gcc/config/"*"/"*.h
150 do
151 grep -q _DYNAMIC_LINKER "$header" || continue
152 echo " fixing \`$header'..."
153 sed -i "$header" \
154 -e 's|define[[:blank:]]*\([UCG]\+\)LIBC_DYNAMIC_LINKER\([0-9]*\)[[:blank:]]"\([^\"]\+\)"$|define \1LIBC_DYNAMIC_LINKER\2 "${libc.out}\3"|g' \
155 -e 's|define[[:blank:]]*MUSL_DYNAMIC_LINKER\([0-9]*\)[[:blank:]]"\([^\"]\+\)"$|define MUSL_DYNAMIC_LINKER\1 "${libc.out}\2"|g'
156 done
157 ''
158 + lib.optionalString (targetPlatform.libc == "musl")
159 ''
160 sed -i gcc/config/linux.h -e '1i#undef LOCAL_INCLUDE_DIR'
161 ''
162 )
163 else "")
164 + lib.optionalString targetPlatform.isAvr ''
165 makeFlagsArray+=(
166 'LIMITS_H_TEST=false'
167 )
168 '';
169
170 inherit noSysDirs staticCompiler crossStageStatic
171 libcCross crossMingw;
172
173 depsBuildBuild = [ buildPackages.stdenv.cc ];
174 nativeBuildInputs = [ texinfo which gettext ]
175 ++ (optional (perl != null) perl)
176 ++ (optional langAda gnatboot)
177 ;
178
179 # For building runtime libs
180 depsBuildTarget =
181 (
182 if hostPlatform == buildPlatform then [
183 targetPackages.stdenv.cc.bintools # newly-built gcc will be used
184 ] else assert targetPlatform == hostPlatform; [ # build != host == target
185 stdenv.cc
186 ]
187 )
188 ++ optional targetPlatform.isLinux patchelf;
189
190 buildInputs = [
191 gmp mpfr libmpc libelf
192 targetPackages.stdenv.cc.bintools # For linking code at run-time
193 ] ++ (optional (isl != null) isl)
194 ++ (optional (zlib != null) zlib)
195 # The builder relies on GNU sed (for instance, Darwin's `sed' fails with
196 # "-i may not be used with stdin"), and `stdenvNative' doesn't provide it.
197 ++ (optional hostPlatform.isDarwin gnused)
198 ;
199
200 depsTargetTarget = optional (!crossStageStatic && threadsCross != null) threadsCross;
201
202 NIX_LDFLAGS = lib.optionalString hostPlatform.isSunOS "-lm -ldl";
203
204 preConfigure = import ../common/pre-configure.nix {
205 inherit lib;
206 inherit version targetPlatform hostPlatform gnatboot langAda langGo langJit;
207 };
208
209 dontDisableStatic = true;
210
211 configurePlatforms = [ "build" "host" "target" ];
212
213 configureFlags = import ../common/configure-flags.nix {
214 inherit
215 lib
216 stdenv
217 targetPackages
218 crossStageStatic libcCross
219 version
220
221 gmp mpfr libmpc libelf isl
222
223 enableLTO
224 enableMultilib
225 enablePlugin
226 enableShared
227
228 langC
229 langD
230 langCC
231 langFortran
232 langAda
233 langGo
234 langObjC
235 langObjCpp
236 langJit
237 ;
238 };
239
240 targetConfig = if targetPlatform != hostPlatform then targetPlatform.config else null;
241
242 buildFlags = optional
243 (targetPlatform == hostPlatform && hostPlatform == buildPlatform)
244 (if profiledCompiler then "profiledbootstrap" else "bootstrap");
245
246 dontStrip = !stripped;
247
248 installTargets = optional stripped "install-strip";
249
250 # https://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
251 ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
252
253 # Setting $CPATH and $LIBRARY_PATH to make sure both `gcc' and `xgcc' find the
254 # library headers and binaries, regarless of the language being compiled.
255 #
256 # Likewise, the LTO code doesn't find zlib.
257 #
258 # Cross-compiling, we need gcc not to read ./specs in order to build the g++
259 # compiler (after the specs for the cross-gcc are created). Having
260 # LIBRARY_PATH= makes gcc read the specs from ., and the build breaks.
261
262 CPATH = optionals (targetPlatform == hostPlatform) (makeSearchPathOutput "dev" "include" ([]
263 ++ optional (zlib != null) zlib
264 ));
265
266 LIBRARY_PATH = optionals (targetPlatform == hostPlatform) (makeLibraryPath (optional (zlib != null) zlib));
267
268 inherit
269 (import ../common/extra-target-flags.nix {
270 inherit lib stdenv crossStageStatic langD libcCross threadsCross;
271 })
272 EXTRA_FLAGS_FOR_TARGET
273 EXTRA_LDFLAGS_FOR_TARGET
274 ;
275
276 passthru = {
277 inherit langC langCC langObjC langObjCpp langAda langFortran langGo langD version;
278 isGNU = true;
279 };
280
281 enableParallelBuilding = true;
282 inherit enableMultilib;
283
284 inherit (stdenv) is64bit;
285
286 meta = {
287 homepage = "https://gcc.gnu.org/";
288 license = lib.licenses.gpl3Plus; # runtime support libraries are typically LGPLv3+
289 description = "GNU Compiler Collection, version ${version}"
290 + (if stripped then "" else " (with debugging info)");
291
292 longDescription = ''
293 The GNU Compiler Collection includes compiler front ends for C, C++,
294 Objective-C, Fortran, OpenMP for C/C++/Fortran, and Ada, as well as
295 libraries for these languages (libstdc++, libgomp,...).
296
297 GCC development is a part of the GNU Project, aiming to improve the
298 compiler used in the GNU system including the GNU/Linux variant.
299 '';
300
301 maintainers = lib.teams.gcc.members;
302
303 platforms = lib.platforms.unix;
304 };
305}
306
307// optionalAttrs (targetPlatform != hostPlatform && targetPlatform.libc == "msvcrt" && crossStageStatic) {
308 makeFlags = [ "all-gcc" "all-target-libgcc" ];
309 installTargets = "install-gcc install-target-libgcc";
310}
311
312// optionalAttrs (enableMultilib) { dontMoveLib64 = true; }
313)