nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 targetPackages,
5
6 withoutTargetLibc,
7 libcCross,
8 threadsCross,
9 version,
10
11 apple-sdk,
12 binutils,
13 gmp,
14 mpfr,
15 libmpc,
16 isl,
17
18 enableLTO,
19 enableMultilib,
20 enablePlugin,
21 disableGdbPlugin ? !enablePlugin,
22 enableShared,
23 enableDefaultPie,
24 targetPrefix,
25
26 langC,
27 langCC,
28 langFortran,
29 langAda ? false,
30 langGo,
31 langObjC,
32 langObjCpp,
33 langJit,
34 langRust ? false,
35 disableBootstrap ? (!lib.systems.equals stdenv.targetPlatform stdenv.hostPlatform),
36}:
37
38assert !enablePlugin -> disableGdbPlugin;
39
40# Note [Windows Exception Handling]
41# sjlj (short jump long jump) exception handling makes no sense on x86_64,
42# it's forcibly slowing programs down as it produces a constant overhead.
43# On x86_64 we have SEH (Structured Exception Handling) and we should use
44# that. On i686, we do not have SEH, and have to use sjlj with dwarf2.
45# Hence it's now conditional on x86_32 (i686 is 32bit).
46#
47# ref: https://stackoverflow.com/questions/15670169/what-is-difference-between-sjlj-vs-dwarf-vs-seh
48
49let
50 inherit (stdenv)
51 buildPlatform
52 hostPlatform
53 targetPlatform
54 ;
55
56 # See https://github.com/NixOS/nixpkgs/pull/209870#issuecomment-1500550903
57 disableBootstrap' = disableBootstrap && !langFortran && !langGo;
58
59 crossMingw = (!lib.systems.equals targetPlatform hostPlatform) && targetPlatform.isMinGW;
60 crossDarwin =
61 (!lib.systems.equals targetPlatform hostPlatform) && targetPlatform.libc == "libSystem";
62
63 crossConfigureFlags =
64 # Ensure that -print-prog-name is able to find the correct programs.
65 [
66 "--with-as=${
67 if targetPackages.stdenv.cc.bintools.isLLVM then binutils else targetPackages.stdenv.cc.bintools
68 }/bin/${targetPlatform.config}-as"
69 ]
70 ++ (
71 if withoutTargetLibc then
72 [
73 "--disable-libssp"
74 "--disable-nls"
75 "--without-headers"
76 "--disable-threads"
77 "--disable-libgomp"
78 "--disable-libquadmath"
79 (lib.enableFeature enableShared "shared")
80 "--disable-libatomic" # requires libc
81 "--disable-decimal-float" # requires libc
82 "--disable-libmpx" # requires libc
83 "--disable-hosted-libstdcxx" # requires libc
84 "--disable-libstdcxx-backtrace"
85 "--disable-linux-futex"
86 "--disable-libvtv"
87 "--disable-libitm"
88 ]
89 ++ lib.optionals crossMingw [
90 "--with-headers=${lib.getDev libcCross}/include"
91 "--with-gcc"
92 "--with-gnu-as"
93 "--with-gnu-ld"
94 "--disable-debug"
95 "--disable-win32-registry"
96 "--enable-hash-synchronization"
97 "--enable-libssp"
98 "--disable-nls"
99 # To keep ABI compatibility with upstream mingw-w64
100 "--enable-fully-dynamic-string"
101 ]
102 ++ lib.optionals (crossMingw && targetPlatform.isx86_32) [
103 # See Note [Windows Exception Handling]
104 "--enable-sjlj-exceptions"
105 "--with-dwarf2"
106 ]
107 else
108 [
109 (
110 if crossDarwin then
111 "--with-sysroot=${lib.getLib libcCross}/share/sysroot"
112 else
113 "--with-headers=${lib.getDev libcCross}${libcCross.incdir or "/include"}"
114 )
115 "--enable-__cxa_atexit"
116 "--enable-long-long"
117 "--enable-threads=${
118 if targetPlatform.isUnix then
119 "posix"
120 else if targetPlatform.isWindows then
121 (threadsCross.model or "win32")
122 else
123 "single"
124 }"
125 "--enable-nls"
126 ]
127 ++ lib.optionals (targetPlatform.libc == "uclibc" || targetPlatform.libc == "musl") [
128 # libsanitizer requires netrom/netrom.h which is not
129 # available in uclibc.
130 "--disable-libsanitizer"
131 ]
132 ++ lib.optional (
133 targetPlatform.libc == "newlib" || targetPlatform.libc == "newlib-nano"
134 ) "--with-newlib"
135 ++ lib.optional (targetPlatform.libc == "avrlibc") "--with-avrlibc"
136 );
137
138 configureFlags =
139 # Basic dependencies
140 [
141 "--with-gmp-include=${gmp.dev}/include"
142 "--with-gmp-lib=${gmp.out}/lib"
143 "--with-mpfr-include=${mpfr.dev}/include"
144 "--with-mpfr-lib=${mpfr.out}/lib"
145 "--with-mpc=${libmpc}"
146 ]
147 ++ lib.optionals (!withoutTargetLibc) [
148 (
149 if libcCross == null then
150 (
151 # GCC will search for the headers relative to SDKROOT on Darwin, so it will find them in the store.
152 if targetPlatform.isDarwin then
153 "--with-native-system-header-dir=/usr/include"
154 else
155 "--with-native-system-header-dir=${lib.getDev stdenv.cc.libc}/include"
156 )
157 else
158 "--with-native-system-header-dir=${lib.getDev libcCross}${libcCross.incdir or "/include"}"
159 )
160 # gcc builds for cross-compilers (build != host) or cross-built
161 # gcc (host != target) always apply the offset prefix to disentangle
162 # target headers from build or host headers:
163 # ${with_build_sysroot}${native_system_header_dir}
164 # or ${test_exec_prefix}/${target_noncanonical}/sys-include
165 # or ${with_sysroot}${native_system_header_dir}
166 # While native build (build == host == target) uses passed headers
167 # path as is:
168 # ${with_build_sysroot}${native_system_header_dir}
169 #
170 # Nixpkgs uses flat directory structure for both native and cross
171 # cases. As a result libc headers don't get found for cross case
172 # and many modern features get disabled (libssp is used instead of
173 # target-specific implementations and similar). More details at:
174 # https://github.com/NixOS/nixpkgs/pull/181802#issuecomment-1186822355
175 #
176 # We pick "/" path to effectively avoid sysroot offset and make it work
177 # as a native case.
178 # Darwin requires using the SDK as the sysroot for `SDKROOT` to work correctly.
179 "--with-build-sysroot=${if targetPlatform.isDarwin then apple-sdk.sdkroot else "/"}"
180 # Same with the stdlibc++ headers embedded in the gcc output
181 "--with-gxx-include-dir=${placeholder "out"}/include/c++/${version}/"
182 ]
183
184 # Basic configuration
185 ++ [
186 # Force target prefix. The behavior if `--target` and `--host`
187 # are specified is inconsistent: Sometimes specifying `--target`
188 # always causes a prefix to be generated, sometimes it's only
189 # added if the `--host` and `--target` differ. This means that
190 # sometimes there may be a prefix even though nixpkgs doesn't
191 # expect one and sometimes there may be none even though nixpkgs
192 # expects one (since not all information is serialized into the
193 # config attribute). The easiest way out of these problems is to
194 # always set the program prefix, so gcc will conform to our
195 # expectations.
196 "--program-prefix=${targetPrefix}"
197
198 (lib.enableFeature enableLTO "lto")
199 "--disable-libstdcxx-pch"
200 "--without-included-gettext"
201 "--with-system-zlib"
202 "--enable-static"
203 "--enable-languages=${
204 lib.concatStringsSep "," (
205 lib.optional langC "c"
206 ++ lib.optional langCC "c++"
207 ++ lib.optional langFortran "fortran"
208 ++ lib.optional langAda "ada"
209 ++ lib.optional langGo "go"
210 ++ lib.optional langObjC "objc"
211 ++ lib.optional langObjCpp "obj-c++"
212 ++ lib.optionals crossDarwin [
213 "objc"
214 "obj-c++"
215 ]
216 ++ lib.optional langJit "jit"
217 ++ lib.optional langRust "rust"
218 )
219 }"
220 ]
221
222 ++ (
223 if (enableMultilib || targetPlatform.isAvr) then
224 [
225 "--enable-multilib"
226 "--disable-libquadmath"
227 ]
228 else
229 [ "--disable-multilib" ]
230 )
231 ++ lib.optional (!enableShared) "--disable-shared"
232 ++ lib.singleton (lib.enableFeature enablePlugin "plugin")
233 # Libcc1 is the GCC cc1 plugin for the GDB debugger which is only used by gdb
234 ++ lib.optional disableGdbPlugin "--disable-libcc1"
235
236 # Support -m32 on powerpc64le/be
237 ++ lib.optional (targetPlatform.system == "powerpc64le-linux") "--enable-targets=powerpcle-linux"
238 ++ lib.optional (targetPlatform.system == "powerpc64-linux") "--enable-targets=powerpc-linux"
239
240 # Fix "unknown long double size, cannot define BFP_FMT"
241 ++ lib.optional (targetPlatform.isPower && targetPlatform.isMusl) "--disable-decimal-float"
242
243 # Optional features
244 ++ lib.optional (isl != null) "--with-isl=${isl}"
245
246 # Ada options, gcc can't build the runtime library for a cross compiler
247 ++ lib.optional langAda (
248 if lib.systems.equals hostPlatform targetPlatform then "--enable-libada" else "--disable-libada"
249 )
250
251 ++ import ../common/platform-flags.nix {
252 inherit (stdenv) targetPlatform;
253 inherit lib;
254 }
255 ++ lib.optionals (!lib.systems.equals targetPlatform hostPlatform) crossConfigureFlags
256 ++ lib.optional disableBootstrap' "--disable-bootstrap"
257
258 # Platform-specific flags
259 ++ lib.optional (
260 lib.systems.equals targetPlatform hostPlatform && targetPlatform.isx86_32
261 ) "--with-arch=${stdenv.hostPlatform.parsed.cpu.name}"
262 ++ lib.optional (targetPlatform.isNetBSD || targetPlatform.isCygwin) "--disable-libssp" # Provided by libc.
263 ++ lib.optionals hostPlatform.isSunOS [
264 "--enable-long-long"
265 "--enable-libssp"
266 "--enable-threads=posix"
267 "--disable-nls"
268 "--enable-__cxa_atexit"
269 # On Illumos/Solaris GNU as is preferred
270 "--with-gnu-as"
271 "--without-gnu-ld"
272 ]
273 ++
274 lib.optional (targetPlatform.libc == "musl")
275 # musl at least, disable: https://git.buildroot.net/buildroot/commit/?id=873d4019f7fb00f6a80592224236b3ba7d657865
276 "--disable-libmpx"
277 ++ lib.optionals (lib.systems.equals targetPlatform hostPlatform && targetPlatform.libc == "musl") [
278 "--disable-libsanitizer"
279 "--disable-symvers"
280 "libat_cv_have_ifunc=no"
281 "--disable-gnu-indirect-function"
282 ]
283 ++ lib.optionals enableDefaultPie [
284 "--enable-default-pie"
285 ]
286 ++ lib.optionals langJit [
287 "--enable-host-shared"
288 ]
289 ++ lib.optionals targetPlatform.isAlpha [
290 # Workaround build failures like:
291 # cc1: error: fp software completion requires '-mtrap-precision=i' [-Werror]
292 "--disable-werror"
293 ];
294
295in
296configureFlags