Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2015 Andrew Kelley
3 : : *
4 : : * This file is part of zig, which is MIT licensed.
5 : : * See http://opensource.org/licenses/MIT
6 : : */
7 : :
8 : : #include "os.hpp"
9 : : #include "config.h"
10 : : #include "codegen.hpp"
11 : : #include "analyze.hpp"
12 : : #include "compiler.hpp"
13 : : #include "install_files.h"
14 : : #include "glibc.hpp"
15 : :
16 : : static const char *msvcrt_common_src[] = {
17 : : "misc" OS_SEP "onexit_table.c",
18 : : "misc" OS_SEP "register_tls_atexit.c",
19 : : "stdio" OS_SEP "acrt_iob_func.c",
20 : : "misc" OS_SEP "_configthreadlocale.c",
21 : : "misc" OS_SEP "_get_current_locale.c",
22 : : "misc" OS_SEP "invalid_parameter_handler.c",
23 : : "misc" OS_SEP "output_format.c",
24 : : "misc" OS_SEP "purecall.c",
25 : : "secapi" OS_SEP "_access_s.c",
26 : : "secapi" OS_SEP "_cgets_s.c",
27 : : "secapi" OS_SEP "_cgetws_s.c",
28 : : "secapi" OS_SEP "_chsize_s.c",
29 : : "secapi" OS_SEP "_controlfp_s.c",
30 : : "secapi" OS_SEP "_cprintf_s.c",
31 : : "secapi" OS_SEP "_cprintf_s_l.c",
32 : : "secapi" OS_SEP "_ctime32_s.c",
33 : : "secapi" OS_SEP "_ctime64_s.c",
34 : : "secapi" OS_SEP "_cwprintf_s.c",
35 : : "secapi" OS_SEP "_cwprintf_s_l.c",
36 : : "secapi" OS_SEP "_gmtime32_s.c",
37 : : "secapi" OS_SEP "_gmtime64_s.c",
38 : : "secapi" OS_SEP "_localtime32_s.c",
39 : : "secapi" OS_SEP "_localtime64_s.c",
40 : : "secapi" OS_SEP "_mktemp_s.c",
41 : : "secapi" OS_SEP "_sopen_s.c",
42 : : "secapi" OS_SEP "_strdate_s.c",
43 : : "secapi" OS_SEP "_strtime_s.c",
44 : : "secapi" OS_SEP "_umask_s.c",
45 : : "secapi" OS_SEP "_vcprintf_s.c",
46 : : "secapi" OS_SEP "_vcprintf_s_l.c",
47 : : "secapi" OS_SEP "_vcwprintf_s.c",
48 : : "secapi" OS_SEP "_vcwprintf_s_l.c",
49 : : "secapi" OS_SEP "_vscprintf_p.c",
50 : : "secapi" OS_SEP "_vscwprintf_p.c",
51 : : "secapi" OS_SEP "_vswprintf_p.c",
52 : : "secapi" OS_SEP "_waccess_s.c",
53 : : "secapi" OS_SEP "_wasctime_s.c",
54 : : "secapi" OS_SEP "_wctime32_s.c",
55 : : "secapi" OS_SEP "_wctime64_s.c",
56 : : "secapi" OS_SEP "_wstrtime_s.c",
57 : : "secapi" OS_SEP "_wmktemp_s.c",
58 : : "secapi" OS_SEP "_wstrdate_s.c",
59 : : "secapi" OS_SEP "asctime_s.c",
60 : : "secapi" OS_SEP "memcpy_s.c",
61 : : "secapi" OS_SEP "memmove_s.c",
62 : : "secapi" OS_SEP "rand_s.c",
63 : : "secapi" OS_SEP "sprintf_s.c",
64 : : "secapi" OS_SEP "strerror_s.c",
65 : : "secapi" OS_SEP "vsprintf_s.c",
66 : : "secapi" OS_SEP "wmemcpy_s.c",
67 : : "secapi" OS_SEP "wmemmove_s.c",
68 : : "stdio" OS_SEP "mingw_lock.c",
69 : : };
70 : :
71 : : static const char *msvcrt_i386_src[] = {
72 : : "misc" OS_SEP "lc_locale_func.c",
73 : :
74 : : };
75 : :
76 : : static const char *msvcrt_other_src[] = {
77 : : "misc" OS_SEP "__p___argv.c",
78 : : "misc" OS_SEP "__p__acmdln.c",
79 : : "misc" OS_SEP "__p__fmode.c",
80 : : "misc" OS_SEP "__p__wcmdln.c",
81 : : };
82 : :
83 : : static const char *mingwex_generic_src[] = {
84 : : "complex" OS_SEP "_cabs.c",
85 : : "complex" OS_SEP "cabs.c",
86 : : "complex" OS_SEP "cabsf.c",
87 : : "complex" OS_SEP "cabsl.c",
88 : : "complex" OS_SEP "cacos.c",
89 : : "complex" OS_SEP "cacosf.c",
90 : : "complex" OS_SEP "cacosl.c",
91 : : "complex" OS_SEP "carg.c",
92 : : "complex" OS_SEP "cargf.c",
93 : : "complex" OS_SEP "cargl.c",
94 : : "complex" OS_SEP "casin.c",
95 : : "complex" OS_SEP "casinf.c",
96 : : "complex" OS_SEP "casinl.c",
97 : : "complex" OS_SEP "catan.c",
98 : : "complex" OS_SEP "catanf.c",
99 : : "complex" OS_SEP "catanl.c",
100 : : "complex" OS_SEP "ccos.c",
101 : : "complex" OS_SEP "ccosf.c",
102 : : "complex" OS_SEP "ccosl.c",
103 : : "complex" OS_SEP "cexp.c",
104 : : "complex" OS_SEP "cexpf.c",
105 : : "complex" OS_SEP "cexpl.c",
106 : : "complex" OS_SEP "cimag.c",
107 : : "complex" OS_SEP "cimagf.c",
108 : : "complex" OS_SEP "cimagl.c",
109 : : "complex" OS_SEP "clog.c",
110 : : "complex" OS_SEP "clog10.c",
111 : : "complex" OS_SEP "clog10f.c",
112 : : "complex" OS_SEP "clog10l.c",
113 : : "complex" OS_SEP "clogf.c",
114 : : "complex" OS_SEP "clogl.c",
115 : : "complex" OS_SEP "conj.c",
116 : : "complex" OS_SEP "conjf.c",
117 : : "complex" OS_SEP "conjl.c",
118 : : "complex" OS_SEP "cpow.c",
119 : : "complex" OS_SEP "cpowf.c",
120 : : "complex" OS_SEP "cpowl.c",
121 : : "complex" OS_SEP "cproj.c",
122 : : "complex" OS_SEP "cprojf.c",
123 : : "complex" OS_SEP "cprojl.c",
124 : : "complex" OS_SEP "creal.c",
125 : : "complex" OS_SEP "crealf.c",
126 : : "complex" OS_SEP "creall.c",
127 : : "complex" OS_SEP "csin.c",
128 : : "complex" OS_SEP "csinf.c",
129 : : "complex" OS_SEP "csinl.c",
130 : : "complex" OS_SEP "csqrt.c",
131 : : "complex" OS_SEP "csqrtf.c",
132 : : "complex" OS_SEP "csqrtl.c",
133 : : "complex" OS_SEP "ctan.c",
134 : : "complex" OS_SEP "ctanf.c",
135 : : "complex" OS_SEP "ctanl.c",
136 : : "crt" OS_SEP "dllentry.c",
137 : : "crt" OS_SEP "dllmain.c",
138 : : "gdtoa" OS_SEP "arithchk.c",
139 : : "gdtoa" OS_SEP "dmisc.c",
140 : : "gdtoa" OS_SEP "dtoa.c",
141 : : "gdtoa" OS_SEP "g__fmt.c",
142 : : "gdtoa" OS_SEP "g_dfmt.c",
143 : : "gdtoa" OS_SEP "g_ffmt.c",
144 : : "gdtoa" OS_SEP "g_xfmt.c",
145 : : "gdtoa" OS_SEP "gdtoa.c",
146 : : "gdtoa" OS_SEP "gethex.c",
147 : : "gdtoa" OS_SEP "gmisc.c",
148 : : "gdtoa" OS_SEP "hd_init.c",
149 : : "gdtoa" OS_SEP "hexnan.c",
150 : : "gdtoa" OS_SEP "misc.c",
151 : : "gdtoa" OS_SEP "qnan.c",
152 : : "gdtoa" OS_SEP "smisc.c",
153 : : "gdtoa" OS_SEP "strtodg.c",
154 : : "gdtoa" OS_SEP "strtodnrp.c",
155 : : "gdtoa" OS_SEP "strtof.c",
156 : : "gdtoa" OS_SEP "strtopx.c",
157 : : "gdtoa" OS_SEP "sum.c",
158 : : "gdtoa" OS_SEP "ulp.c",
159 : : "math" OS_SEP "abs64.c",
160 : : "math" OS_SEP "cbrt.c",
161 : : "math" OS_SEP "cbrtf.c",
162 : : "math" OS_SEP "cbrtl.c",
163 : : "math" OS_SEP "cephes_emath.c",
164 : : "math" OS_SEP "copysign.c",
165 : : "math" OS_SEP "copysignf.c",
166 : : "math" OS_SEP "coshf.c",
167 : : "math" OS_SEP "coshl.c",
168 : : "math" OS_SEP "erfl.c",
169 : : "math" OS_SEP "expf.c",
170 : : "math" OS_SEP "fabs.c",
171 : : "math" OS_SEP "fabsf.c",
172 : : "math" OS_SEP "fabsl.c",
173 : : "math" OS_SEP "fdim.c",
174 : : "math" OS_SEP "fdimf.c",
175 : : "math" OS_SEP "fdiml.c",
176 : : "math" OS_SEP "fma.c",
177 : : "math" OS_SEP "fmaf.c",
178 : : "math" OS_SEP "fmal.c",
179 : : "math" OS_SEP "fmax.c",
180 : : "math" OS_SEP "fmaxf.c",
181 : : "math" OS_SEP "fmaxl.c",
182 : : "math" OS_SEP "fmin.c",
183 : : "math" OS_SEP "fminf.c",
184 : : "math" OS_SEP "fminl.c",
185 : : "math" OS_SEP "fp_consts.c",
186 : : "math" OS_SEP "fp_constsf.c",
187 : : "math" OS_SEP "fp_constsl.c",
188 : : "math" OS_SEP "fpclassify.c",
189 : : "math" OS_SEP "fpclassifyf.c",
190 : : "math" OS_SEP "fpclassifyl.c",
191 : : "math" OS_SEP "frexpf.c",
192 : : "math" OS_SEP "hypot.c",
193 : : "math" OS_SEP "hypotf.c",
194 : : "math" OS_SEP "hypotl.c",
195 : : "math" OS_SEP "isnan.c",
196 : : "math" OS_SEP "isnanf.c",
197 : : "math" OS_SEP "isnanl.c",
198 : : "math" OS_SEP "ldexpf.c",
199 : : "math" OS_SEP "lgamma.c",
200 : : "math" OS_SEP "lgammaf.c",
201 : : "math" OS_SEP "lgammal.c",
202 : : "math" OS_SEP "llrint.c",
203 : : "math" OS_SEP "llrintf.c",
204 : : "math" OS_SEP "llrintl.c",
205 : : "math" OS_SEP "llround.c",
206 : : "math" OS_SEP "llroundf.c",
207 : : "math" OS_SEP "llroundl.c",
208 : : "math" OS_SEP "log10f.c",
209 : : "math" OS_SEP "logf.c",
210 : : "math" OS_SEP "lrint.c",
211 : : "math" OS_SEP "lrintf.c",
212 : : "math" OS_SEP "lrintl.c",
213 : : "math" OS_SEP "lround.c",
214 : : "math" OS_SEP "lroundf.c",
215 : : "math" OS_SEP "lroundl.c",
216 : : "math" OS_SEP "modf.c",
217 : : "math" OS_SEP "modff.c",
218 : : "math" OS_SEP "modfl.c",
219 : : "math" OS_SEP "nextafterf.c",
220 : : "math" OS_SEP "nextafterl.c",
221 : : "math" OS_SEP "nexttoward.c",
222 : : "math" OS_SEP "nexttowardf.c",
223 : : "math" OS_SEP "powf.c",
224 : : "math" OS_SEP "powi.c",
225 : : "math" OS_SEP "powif.c",
226 : : "math" OS_SEP "powil.c",
227 : : "math" OS_SEP "rint.c",
228 : : "math" OS_SEP "rintf.c",
229 : : "math" OS_SEP "rintl.c",
230 : : "math" OS_SEP "round.c",
231 : : "math" OS_SEP "roundf.c",
232 : : "math" OS_SEP "roundl.c",
233 : : "math" OS_SEP "s_erf.c",
234 : : "math" OS_SEP "sf_erf.c",
235 : : "math" OS_SEP "signbit.c",
236 : : "math" OS_SEP "signbitf.c",
237 : : "math" OS_SEP "signbitl.c",
238 : : "math" OS_SEP "signgam.c",
239 : : "math" OS_SEP "sinhf.c",
240 : : "math" OS_SEP "sinhl.c",
241 : : "math" OS_SEP "sqrt.c",
242 : : "math" OS_SEP "sqrtf.c",
243 : : "math" OS_SEP "sqrtl.c",
244 : : "math" OS_SEP "tanhf.c",
245 : : "math" OS_SEP "tanhl.c",
246 : : "math" OS_SEP "tgamma.c",
247 : : "math" OS_SEP "tgammaf.c",
248 : : "math" OS_SEP "tgammal.c",
249 : : "math" OS_SEP "truncl.c",
250 : : "misc" OS_SEP "alarm.c",
251 : : "misc" OS_SEP "assert.c",
252 : : "misc" OS_SEP "basename.c",
253 : : "misc" OS_SEP "btowc.c",
254 : : "misc" OS_SEP "delay-f.c",
255 : : "misc" OS_SEP "delay-n.c",
256 : : "misc" OS_SEP "delayimp.c",
257 : : "misc" OS_SEP "difftime.c",
258 : : "misc" OS_SEP "difftime32.c",
259 : : "misc" OS_SEP "difftime64.c",
260 : : "misc" OS_SEP "dirent.c",
261 : : "misc" OS_SEP "dirname.c",
262 : : "misc" OS_SEP "execv.c",
263 : : "misc" OS_SEP "execve.c",
264 : : "misc" OS_SEP "execvp.c",
265 : : "misc" OS_SEP "execvpe.c",
266 : : "misc" OS_SEP "feclearexcept.c",
267 : : "misc" OS_SEP "fegetenv.c",
268 : : "misc" OS_SEP "fegetexceptflag.c",
269 : : "misc" OS_SEP "fegetround.c",
270 : : "misc" OS_SEP "feholdexcept.c",
271 : : "misc" OS_SEP "feraiseexcept.c",
272 : : "misc" OS_SEP "fesetenv.c",
273 : : "misc" OS_SEP "fesetexceptflag.c",
274 : : "misc" OS_SEP "fesetround.c",
275 : : "misc" OS_SEP "fetestexcept.c",
276 : : "misc" OS_SEP "feupdateenv.c",
277 : : "misc" OS_SEP "ftruncate.c",
278 : : "misc" OS_SEP "ftw.c",
279 : : "misc" OS_SEP "ftw64.c",
280 : : "misc" OS_SEP "fwide.c",
281 : : "misc" OS_SEP "getlogin.c",
282 : : "misc" OS_SEP "getopt.c",
283 : : "misc" OS_SEP "gettimeofday.c",
284 : : "misc" OS_SEP "imaxabs.c",
285 : : "misc" OS_SEP "imaxdiv.c",
286 : : "misc" OS_SEP "isblank.c",
287 : : "misc" OS_SEP "iswblank.c",
288 : : "misc" OS_SEP "mbrtowc.c",
289 : : "misc" OS_SEP "mbsinit.c",
290 : : "misc" OS_SEP "mempcpy.c",
291 : : "misc" OS_SEP "mingw-aligned-malloc.c",
292 : : "misc" OS_SEP "mingw-fseek.c",
293 : : "misc" OS_SEP "mingw_getsp.S",
294 : : "misc" OS_SEP "mingw_matherr.c",
295 : : "misc" OS_SEP "mingw_mbwc_convert.c",
296 : : "misc" OS_SEP "mingw_usleep.c",
297 : : "misc" OS_SEP "mingw_wcstod.c",
298 : : "misc" OS_SEP "mingw_wcstof.c",
299 : : "misc" OS_SEP "mingw_wcstold.c",
300 : : "misc" OS_SEP "mkstemp.c",
301 : : "misc" OS_SEP "seterrno.c",
302 : : "misc" OS_SEP "sleep.c",
303 : : "misc" OS_SEP "spawnv.c",
304 : : "misc" OS_SEP "spawnve.c",
305 : : "misc" OS_SEP "spawnvp.c",
306 : : "misc" OS_SEP "spawnvpe.c",
307 : : "misc" OS_SEP "strnlen.c",
308 : : "misc" OS_SEP "strsafe.c",
309 : : "misc" OS_SEP "strtoimax.c",
310 : : "misc" OS_SEP "strtold.c",
311 : : "misc" OS_SEP "strtoumax.c",
312 : : "misc" OS_SEP "tdelete.c",
313 : : "misc" OS_SEP "tfind.c",
314 : : "misc" OS_SEP "tsearch.c",
315 : : "misc" OS_SEP "twalk.c",
316 : : "misc" OS_SEP "uchar_c16rtomb.c",
317 : : "misc" OS_SEP "uchar_c32rtomb.c",
318 : : "misc" OS_SEP "uchar_mbrtoc16.c",
319 : : "misc" OS_SEP "uchar_mbrtoc32.c",
320 : : "misc" OS_SEP "wassert.c",
321 : : "misc" OS_SEP "wcrtomb.c",
322 : : "misc" OS_SEP "wcsnlen.c",
323 : : "misc" OS_SEP "wcstof.c",
324 : : "misc" OS_SEP "wcstoimax.c",
325 : : "misc" OS_SEP "wcstold.c",
326 : : "misc" OS_SEP "wcstoumax.c",
327 : : "misc" OS_SEP "wctob.c",
328 : : "misc" OS_SEP "wctrans.c",
329 : : "misc" OS_SEP "wctype.c",
330 : : "misc" OS_SEP "wdirent.c",
331 : : "misc" OS_SEP "winbs_uint64.c",
332 : : "misc" OS_SEP "winbs_ulong.c",
333 : : "misc" OS_SEP "winbs_ushort.c",
334 : : "misc" OS_SEP "wmemchr.c",
335 : : "misc" OS_SEP "wmemcmp.c",
336 : : "misc" OS_SEP "wmemcpy.c",
337 : : "misc" OS_SEP "wmemmove.c",
338 : : "misc" OS_SEP "wmempcpy.c",
339 : : "misc" OS_SEP "wmemset.c",
340 : : "stdio" OS_SEP "_Exit.c",
341 : : "stdio" OS_SEP "_findfirst64i32.c",
342 : : "stdio" OS_SEP "_findnext64i32.c",
343 : : "stdio" OS_SEP "_fstat.c",
344 : : "stdio" OS_SEP "_fstat64i32.c",
345 : : "stdio" OS_SEP "_ftime.c",
346 : : "stdio" OS_SEP "_getc_nolock.c",
347 : : "stdio" OS_SEP "_getwc_nolock.c",
348 : : "stdio" OS_SEP "_putc_nolock.c",
349 : : "stdio" OS_SEP "_putwc_nolock.c",
350 : : "stdio" OS_SEP "_stat.c",
351 : : "stdio" OS_SEP "_stat64i32.c",
352 : : "stdio" OS_SEP "_wfindfirst64i32.c",
353 : : "stdio" OS_SEP "_wfindnext64i32.c",
354 : : "stdio" OS_SEP "_wstat.c",
355 : : "stdio" OS_SEP "_wstat64i32.c",
356 : : "stdio" OS_SEP "asprintf.c",
357 : : "stdio" OS_SEP "atoll.c",
358 : : "stdio" OS_SEP "fgetpos64.c",
359 : : "stdio" OS_SEP "fopen64.c",
360 : : "stdio" OS_SEP "fseeko32.c",
361 : : "stdio" OS_SEP "fseeko64.c",
362 : : "stdio" OS_SEP "fsetpos64.c",
363 : : "stdio" OS_SEP "ftello.c",
364 : : "stdio" OS_SEP "ftello64.c",
365 : : "stdio" OS_SEP "ftruncate64.c",
366 : : "stdio" OS_SEP "lltoa.c",
367 : : "stdio" OS_SEP "lltow.c",
368 : : "stdio" OS_SEP "lseek64.c",
369 : : "stdio" OS_SEP "mingw_asprintf.c",
370 : : "stdio" OS_SEP "mingw_fprintf.c",
371 : : "stdio" OS_SEP "mingw_fprintfw.c",
372 : : "stdio" OS_SEP "mingw_fscanf.c",
373 : : "stdio" OS_SEP "mingw_fwscanf.c",
374 : : "stdio" OS_SEP "mingw_pformat.c",
375 : : "stdio" OS_SEP "mingw_pformatw.c",
376 : : "stdio" OS_SEP "mingw_printf.c",
377 : : "stdio" OS_SEP "mingw_printfw.c",
378 : : "stdio" OS_SEP "mingw_scanf.c",
379 : : "stdio" OS_SEP "mingw_snprintf.c",
380 : : "stdio" OS_SEP "mingw_snprintfw.c",
381 : : "stdio" OS_SEP "mingw_sprintf.c",
382 : : "stdio" OS_SEP "mingw_sprintfw.c",
383 : : "stdio" OS_SEP "mingw_sscanf.c",
384 : : "stdio" OS_SEP "mingw_swscanf.c",
385 : : "stdio" OS_SEP "mingw_vasprintf.c",
386 : : "stdio" OS_SEP "mingw_vfprintf.c",
387 : : "stdio" OS_SEP "mingw_vfprintfw.c",
388 : : "stdio" OS_SEP "mingw_vfscanf.c",
389 : : "stdio" OS_SEP "mingw_vprintf.c",
390 : : "stdio" OS_SEP "mingw_vprintfw.c",
391 : : "stdio" OS_SEP "mingw_vsnprintf.c",
392 : : "stdio" OS_SEP "mingw_vsnprintfw.c",
393 : : "stdio" OS_SEP "mingw_vsprintf.c",
394 : : "stdio" OS_SEP "mingw_vsprintfw.c",
395 : : "stdio" OS_SEP "mingw_wscanf.c",
396 : : "stdio" OS_SEP "mingw_wvfscanf.c",
397 : : "stdio" OS_SEP "scanf.S",
398 : : "stdio" OS_SEP "snprintf.c",
399 : : "stdio" OS_SEP "snwprintf.c",
400 : : "stdio" OS_SEP "strtof.c",
401 : : "stdio" OS_SEP "strtok_r.c",
402 : : "stdio" OS_SEP "truncate.c",
403 : : "stdio" OS_SEP "ulltoa.c",
404 : : "stdio" OS_SEP "ulltow.c",
405 : : "stdio" OS_SEP "vasprintf.c",
406 : : "stdio" OS_SEP "vfscanf.c",
407 : : "stdio" OS_SEP "vfscanf2.S",
408 : : "stdio" OS_SEP "vfwscanf.c",
409 : : "stdio" OS_SEP "vfwscanf2.S",
410 : : "stdio" OS_SEP "vscanf.c",
411 : : "stdio" OS_SEP "vscanf2.S",
412 : : "stdio" OS_SEP "vsnprintf.c",
413 : : "stdio" OS_SEP "vsnwprintf.c",
414 : : "stdio" OS_SEP "vsscanf.c",
415 : : "stdio" OS_SEP "vsscanf2.S",
416 : : "stdio" OS_SEP "vswscanf.c",
417 : : "stdio" OS_SEP "vswscanf2.S",
418 : : "stdio" OS_SEP "vwscanf.c",
419 : : "stdio" OS_SEP "vwscanf2.S",
420 : : "stdio" OS_SEP "wtoll.c",
421 : : };
422 : :
423 : : static const char *mingwex_x86_src[] = {
424 : : "math" OS_SEP "x86" OS_SEP "acosf.c",
425 : : "math" OS_SEP "x86" OS_SEP "acosh.c",
426 : : "math" OS_SEP "x86" OS_SEP "acoshf.c",
427 : : "math" OS_SEP "x86" OS_SEP "acoshl.c",
428 : : "math" OS_SEP "x86" OS_SEP "acosl.c",
429 : : "math" OS_SEP "x86" OS_SEP "asinf.c",
430 : : "math" OS_SEP "x86" OS_SEP "asinh.c",
431 : : "math" OS_SEP "x86" OS_SEP "asinhf.c",
432 : : "math" OS_SEP "x86" OS_SEP "asinhl.c",
433 : : "math" OS_SEP "x86" OS_SEP "asinl.c",
434 : : "math" OS_SEP "x86" OS_SEP "atan2.c",
435 : : "math" OS_SEP "x86" OS_SEP "atan2f.c",
436 : : "math" OS_SEP "x86" OS_SEP "atan2l.c",
437 : : "math" OS_SEP "x86" OS_SEP "atanf.c",
438 : : "math" OS_SEP "x86" OS_SEP "atanh.c",
439 : : "math" OS_SEP "x86" OS_SEP "atanhf.c",
440 : : "math" OS_SEP "x86" OS_SEP "atanhl.c",
441 : : "math" OS_SEP "x86" OS_SEP "atanl.c",
442 : : "math" OS_SEP "x86" OS_SEP "ceilf.S",
443 : : "math" OS_SEP "x86" OS_SEP "ceill.S",
444 : : "math" OS_SEP "x86" OS_SEP "ceil.S",
445 : : "math" OS_SEP "x86" OS_SEP "_chgsignl.S",
446 : : "math" OS_SEP "x86" OS_SEP "copysignl.S",
447 : : "math" OS_SEP "x86" OS_SEP "cos.c",
448 : : "math" OS_SEP "x86" OS_SEP "cosf.c",
449 : : "math" OS_SEP "x86" OS_SEP "cosl.c",
450 : : "math" OS_SEP "x86" OS_SEP "cosl_internal.S",
451 : : "math" OS_SEP "x86" OS_SEP "cossin.c",
452 : : "math" OS_SEP "x86" OS_SEP "exp2f.S",
453 : : "math" OS_SEP "x86" OS_SEP "exp2l.S",
454 : : "math" OS_SEP "x86" OS_SEP "exp2.S",
455 : : "math" OS_SEP "x86" OS_SEP "exp.c",
456 : : "math" OS_SEP "x86" OS_SEP "expl.c",
457 : : "math" OS_SEP "x86" OS_SEP "expm1.c",
458 : : "math" OS_SEP "x86" OS_SEP "expm1f.c",
459 : : "math" OS_SEP "x86" OS_SEP "expm1l.c",
460 : : "math" OS_SEP "x86" OS_SEP "floorf.S",
461 : : "math" OS_SEP "x86" OS_SEP "floorl.S",
462 : : "math" OS_SEP "x86" OS_SEP "floor.S",
463 : : "math" OS_SEP "x86" OS_SEP "fmod.c",
464 : : "math" OS_SEP "x86" OS_SEP "fmodf.c",
465 : : "math" OS_SEP "x86" OS_SEP "fmodl.c",
466 : : "math" OS_SEP "x86" OS_SEP "frexpl.S",
467 : : "math" OS_SEP "x86" OS_SEP "fucom.c",
468 : : "math" OS_SEP "x86" OS_SEP "ilogbf.S",
469 : : "math" OS_SEP "x86" OS_SEP "ilogbl.S",
470 : : "math" OS_SEP "x86" OS_SEP "ilogb.S",
471 : : "math" OS_SEP "x86" OS_SEP "internal_logl.S",
472 : : "math" OS_SEP "x86" OS_SEP "ldexp.c",
473 : : "math" OS_SEP "x86" OS_SEP "ldexpl.c",
474 : : "math" OS_SEP "x86" OS_SEP "log10l.S",
475 : : "math" OS_SEP "x86" OS_SEP "log1pf.S",
476 : : "math" OS_SEP "x86" OS_SEP "log1pl.S",
477 : : "math" OS_SEP "x86" OS_SEP "log1p.S",
478 : : "math" OS_SEP "x86" OS_SEP "log2f.S",
479 : : "math" OS_SEP "x86" OS_SEP "log2l.S",
480 : : "math" OS_SEP "x86" OS_SEP "log2.S",
481 : : "math" OS_SEP "x86" OS_SEP "logb.c",
482 : : "math" OS_SEP "x86" OS_SEP "logbf.c",
483 : : "math" OS_SEP "x86" OS_SEP "logbl.c",
484 : : "math" OS_SEP "x86" OS_SEP "log.c",
485 : : "math" OS_SEP "x86" OS_SEP "logl.c",
486 : : "math" OS_SEP "x86" OS_SEP "nearbyintf.S",
487 : : "math" OS_SEP "x86" OS_SEP "nearbyintl.S",
488 : : "math" OS_SEP "x86" OS_SEP "nearbyint.S",
489 : : "math" OS_SEP "x86" OS_SEP "pow.c",
490 : : "math" OS_SEP "x86" OS_SEP "powl.c",
491 : : "math" OS_SEP "x86" OS_SEP "remainderf.S",
492 : : "math" OS_SEP "x86" OS_SEP "remainderl.S",
493 : : "math" OS_SEP "x86" OS_SEP "remainder.S",
494 : : "math" OS_SEP "x86" OS_SEP "remquof.S",
495 : : "math" OS_SEP "x86" OS_SEP "remquol.S",
496 : : "math" OS_SEP "x86" OS_SEP "remquo.S",
497 : : "math" OS_SEP "x86" OS_SEP "scalbnf.S",
498 : : "math" OS_SEP "x86" OS_SEP "scalbnl.S",
499 : : "math" OS_SEP "x86" OS_SEP "scalbn.S",
500 : : "math" OS_SEP "x86" OS_SEP "sin.c",
501 : : "math" OS_SEP "x86" OS_SEP "sinf.c",
502 : : "math" OS_SEP "x86" OS_SEP "sinl.c",
503 : : "math" OS_SEP "x86" OS_SEP "sinl_internal.S",
504 : : "math" OS_SEP "x86" OS_SEP "tanf.c",
505 : : "math" OS_SEP "x86" OS_SEP "tanl.S",
506 : : "math" OS_SEP "x86" OS_SEP "truncf.S",
507 : : "math" OS_SEP "x86" OS_SEP "trunc.S",
508 : : };
509 : :
510 : : static const char *mingwex_arm32_src[] = {
511 : : "math" OS_SEP "arm" OS_SEP "_chgsignl.S",
512 : : "math" OS_SEP "arm" OS_SEP "ceil.S",
513 : : "math" OS_SEP "arm" OS_SEP "ceilf.S",
514 : : "math" OS_SEP "arm" OS_SEP "ceill.S",
515 : : "math" OS_SEP "arm" OS_SEP "copysignl.c",
516 : : "math" OS_SEP "arm" OS_SEP "exp2.c",
517 : : "math" OS_SEP "arm" OS_SEP "floor.S",
518 : : "math" OS_SEP "arm" OS_SEP "floorf.S",
519 : : "math" OS_SEP "arm" OS_SEP "floorl.S",
520 : : "math" OS_SEP "arm" OS_SEP "ldexpl.c",
521 : : "math" OS_SEP "arm" OS_SEP "log2.c",
522 : : "math" OS_SEP "arm" OS_SEP "nearbyint.S",
523 : : "math" OS_SEP "arm" OS_SEP "nearbyintf.S",
524 : : "math" OS_SEP "arm" OS_SEP "nearbyintl.S",
525 : : "math" OS_SEP "arm" OS_SEP "scalbn.c",
526 : : "math" OS_SEP "arm" OS_SEP "sincos.c",
527 : : "math" OS_SEP "arm" OS_SEP "trunc.S",
528 : : "math" OS_SEP "arm" OS_SEP "truncf.S",
529 : : };
530 : :
531 : : static const char *mingwex_arm64_src[] = {
532 : : "math" OS_SEP "arm64" OS_SEP "ceilf.S",
533 : : "math" OS_SEP "arm64" OS_SEP "ceill.S",
534 : : "math" OS_SEP "arm64" OS_SEP "ceil.S",
535 : : "math" OS_SEP "arm64" OS_SEP "_chgsignl.S",
536 : : "math" OS_SEP "arm64" OS_SEP "copysignl.c",
537 : : "math" OS_SEP "arm64" OS_SEP "exp2f.S",
538 : : "math" OS_SEP "arm64" OS_SEP "exp2.S",
539 : : "math" OS_SEP "arm64" OS_SEP "floorf.S",
540 : : "math" OS_SEP "arm64" OS_SEP "floorl.S",
541 : : "math" OS_SEP "arm64" OS_SEP "floor.S",
542 : : "math" OS_SEP "arm64" OS_SEP "ldexpl.c",
543 : : "math" OS_SEP "arm64" OS_SEP "log2.c",
544 : : "math" OS_SEP "arm64" OS_SEP "nearbyintf.S",
545 : : "math" OS_SEP "arm64" OS_SEP "nearbyintl.S",
546 : : "math" OS_SEP "arm64" OS_SEP "nearbyint.S",
547 : : "math" OS_SEP "arm64" OS_SEP "scalbn.c",
548 : : "math" OS_SEP "arm64" OS_SEP "sincos.c",
549 : : "math" OS_SEP "arm64" OS_SEP "truncf.S",
550 : : "math" OS_SEP "arm64" OS_SEP "trunc.S",
551 : : };
552 : :
553 : : struct MinGWDef {
554 : : const char *name;
555 : : const char *path;
556 : : bool always_link;
557 : : };
558 : : static const MinGWDef mingw_def_list[] = {
559 : : {"msvcrt", "lib-common" OS_SEP "msvcrt.def.in", true},
560 : : {"setupapi", "libarm32" OS_SEP "setupapi.def", false},
561 : : {"setupapi", "libarm64" OS_SEP "setupapi.def", false},
562 : : {"setupapi", "lib32" OS_SEP "setupapi.def", false},
563 : : {"setupapi", "lib64" OS_SEP "setupapi.def", false},
564 : : {"winmm", "lib-common" OS_SEP "winmm.def", false},
565 : : {"gdi32", "lib-common" OS_SEP "gdi32.def", false},
566 : : {"imm32", "lib-common" OS_SEP "imm32.def", false},
567 : : {"version", "lib-common" OS_SEP "version.def", false},
568 : : {"advapi32", "lib-common" OS_SEP "advapi32.def.in", true},
569 : : {"oleaut32", "lib-common" OS_SEP "oleaut32.def.in", false},
570 : : {"ole32", "lib-common" OS_SEP "ole32.def.in", false},
571 : : {"shell32", "lib-common" OS_SEP "shell32.def", true},
572 : : {"user32", "lib-common" OS_SEP "user32.def.in", true},
573 : : {"kernel32", "lib-common" OS_SEP "kernel32.def.in", true},
574 : : {"ntdll", "libarm32" OS_SEP "ntdll.def", true},
575 : : {"ntdll", "lib32" OS_SEP "ntdll.def", true},
576 : : {"ntdll", "lib64" OS_SEP "ntdll.def", true},
577 : : };
578 : :
579 : : struct LinkJob {
580 : : CodeGen *codegen;
581 : : ZigList<const char *> args;
582 : : bool link_in_crt;
583 : : HashMap<Buf *, bool, buf_hash, buf_eql_buf> rpath_table;
584 : : };
585 : :
586 : 38 : static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFile *c_file) {
587 : 38 : CodeGen *child_gen = create_child_codegen(parent_gen, nullptr, OutTypeObj, nullptr);
588 : 38 : codegen_set_out_name(child_gen, buf_create_from_str(name));
589 : 38 : ZigList<CFile *> c_source_files = {0};
590 : 38 : c_source_files.append(c_file);
591 : 38 : child_gen->c_source_files = c_source_files;
592 : 38 : codegen_build_and_link(child_gen);
593 : 38 : return buf_ptr(&child_gen->output_file_path);
594 : : }
595 : :
596 : 674 : static const char *path_from_zig_lib(CodeGen *g, const char *dir, const char *subpath) {
597 : 674 : Buf *dir1 = buf_alloc();
598 : 674 : os_path_join(g->zig_lib_dir, buf_create_from_str(dir), dir1);
599 : 674 : Buf *result = buf_alloc();
600 : 674 : os_path_join(dir1, buf_create_from_str(subpath), result);
601 : 674 : return buf_ptr(result);
602 : : }
603 : :
604 : 636 : static const char *path_from_libc(CodeGen *g, const char *subpath) {
605 : 636 : return path_from_zig_lib(g, "libc", subpath);
606 : : }
607 : :
608 : 32 : static const char *path_from_libunwind(CodeGen *g, const char *subpath) {
609 : 32 : return path_from_zig_lib(g, "libunwind", subpath);
610 : : }
611 : :
612 : 2 : static const char *build_libunwind(CodeGen *parent) {
613 : 2 : CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
614 : 2 : codegen_set_out_name(child_gen, buf_create_from_str("unwind"));
615 : 2 : LinkLib *new_link_lib = codegen_add_link_lib(child_gen, buf_create_from_str("c"));
616 : 2 : new_link_lib->provided_explicitly = false;
617 : : enum SrcKind {
618 : : SrcCpp,
619 : : SrcC,
620 : : SrcAsm,
621 : : };
622 : : static const struct {
623 : : const char *path;
624 : : SrcKind kind;
625 : : } unwind_src[] = {
626 : : {"src" OS_SEP "libunwind.cpp", SrcCpp},
627 : : {"src" OS_SEP "Unwind-EHABI.cpp", SrcCpp},
628 : : {"src" OS_SEP "Unwind-seh.cpp", SrcCpp},
629 : :
630 : : {"src" OS_SEP "UnwindLevel1.c", SrcC},
631 : : {"src" OS_SEP "UnwindLevel1-gcc-ext.c", SrcC},
632 : : {"src" OS_SEP "Unwind-sjlj.c", SrcC},
633 : :
634 : : {"src" OS_SEP "UnwindRegistersRestore.S", SrcAsm},
635 : : {"src" OS_SEP "UnwindRegistersSave.S", SrcAsm},
636 : : };
637 : 2 : ZigList<CFile *> c_source_files = {0};
638 [ + + ]: 18 : for (size_t i = 0; i < array_length(unwind_src); i += 1) {
639 : 16 : CFile *c_file = allocate<CFile>(1);
640 : 16 : c_file->source_path = path_from_libunwind(parent, unwind_src[i].path);
641 [ + + + - ]: 16 : switch (unwind_src[i].kind) {
642 : 6 : case SrcC:
643 : 6 : c_file->args.append("-std=c99");
644 : 6 : break;
645 : 6 : case SrcCpp:
646 : 6 : c_file->args.append("-fno-rtti");
647 : 6 : c_file->args.append("-I");
648 : 6 : c_file->args.append(path_from_zig_lib(parent, "libcxx", "include"));
649 : 6 : break;
650 : 4 : case SrcAsm:
651 : 4 : break;
652 : : }
653 : 16 : c_file->args.append("-I");
654 : 16 : c_file->args.append(path_from_libunwind(parent, "include"));
655 : 16 : c_file->args.append("-fPIC");
656 : 16 : c_file->args.append("-D_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS");
657 : 16 : c_file->args.append("-Wa,--noexecstack");
658 [ + - ]: 16 : if (parent->zig_target->is_native) {
659 : 16 : c_file->args.append("-D_LIBUNWIND_IS_NATIVE_ONLY");
660 : : }
661 [ + - ]: 16 : if (parent->build_mode == BuildModeDebug) {
662 : 16 : c_file->args.append("-D_DEBUG");
663 : : }
664 [ + + ]: 16 : if (parent->is_single_threaded) {
665 : 8 : c_file->args.append("-D_LIBUNWIND_HAS_NO_THREADS");
666 : : }
667 : 16 : c_source_files.append(c_file);
668 : : }
669 : 2 : child_gen->c_source_files = c_source_files;
670 : 2 : codegen_build_and_link(child_gen);
671 : 2 : return buf_ptr(&child_gen->output_file_path);
672 : : }
673 : :
674 : 0 : static void mingw_add_cc_args(CodeGen *parent, CFile *c_file) {
675 : 0 : c_file->args.append("-DHAVE_CONFIG_H");
676 : :
677 : 0 : c_file->args.append("-I");
678 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "include",
679 : : buf_ptr(parent->zig_lib_dir))));
680 : :
681 : 0 : c_file->args.append("-isystem");
682 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "any-windows-any",
683 : : buf_ptr(parent->zig_lib_dir))));
684 : :
685 [ # # ]: 0 : if (target_is_arm(parent->zig_target) &&
[ # # # # ]
686 : 0 : target_arch_pointer_bit_width(parent->zig_target->arch) == 32)
687 : : {
688 : 0 : c_file->args.append("-mfpu=vfp");
689 : : }
690 : :
691 : 0 : c_file->args.append("-std=gnu11");
692 : 0 : c_file->args.append("-D_CRTBLD");
693 : 0 : c_file->args.append("-D_WIN32_WINNT=0x0f00");
694 : 0 : c_file->args.append("-D__MSVCRT_VERSION__=0x700");
695 : 0 : }
696 : :
697 : 152 : static void glibc_add_include_dirs_arch(CFile *c_file, ZigLLVM_ArchType arch, const char *nptl, const char *dir) {
698 [ + - ][ + - ]: 152 : bool is_x86 = arch == ZigLLVM_x86 || arch == ZigLLVM_x86_64;
699 [ + - ][ - + ]: 152 : bool is_aarch64 = arch == ZigLLVM_aarch64 || arch == ZigLLVM_aarch64_be;
700 [ + - ][ + - ]: 152 : bool is_mips = arch == ZigLLVM_mips || arch == ZigLLVM_mipsel ||
701 [ + - ][ - + ]: 304 : arch == ZigLLVM_mips64el || arch == ZigLLVM_mips64;
702 [ + - ][ - + ]: 152 : bool is_arm = arch == ZigLLVM_arm || arch == ZigLLVM_armeb;
703 [ + - ][ + - ]: 152 : bool is_ppc = arch == ZigLLVM_ppc || arch == ZigLLVM_ppc64 || arch == ZigLLVM_ppc64le;
[ - + ]
704 [ + - ][ - + ]: 152 : bool is_riscv = arch == ZigLLVM_riscv32 || arch == ZigLLVM_riscv64;
705 [ + - ][ + - ]: 152 : bool is_sparc = arch == ZigLLVM_sparc || arch == ZigLLVM_sparcel || arch == ZigLLVM_sparcv9;
[ - + ]
706 : 152 : bool is_64 = target_arch_pointer_bit_width(arch) == 64;
707 : :
708 [ + - ]: 152 : if (is_x86) {
709 [ + - ]: 152 : if (arch == ZigLLVM_x86_64) {
710 [ + + ]: 152 : if (nptl != nullptr) {
711 : 38 : c_file->args.append("-I");
712 : 38 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "x86_64" OS_SEP "%s", dir, nptl)));
713 : : } else {
714 : 114 : c_file->args.append("-I");
715 : 152 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "x86_64", dir)));
716 : : }
717 [ # # ]: 0 : } else if (arch == ZigLLVM_x86) {
718 [ # # ]: 0 : if (nptl != nullptr) {
719 : 0 : c_file->args.append("-I");
720 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "i386" OS_SEP "%s", dir, nptl)));
721 : : } else {
722 : 0 : c_file->args.append("-I");
723 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "i386", dir)));
724 : : }
725 : : }
726 [ + + ]: 152 : if (nptl != nullptr) {
727 : 38 : c_file->args.append("-I");
728 : 38 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "x86" OS_SEP "%s", dir, nptl)));
729 : : } else {
730 : 114 : c_file->args.append("-I");
731 : 152 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "x86", dir)));
732 : : }
733 [ # # ]: 0 : } else if (is_arm) {
734 [ # # ]: 0 : if (nptl != nullptr) {
735 : 0 : c_file->args.append("-I");
736 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "arm" OS_SEP "%s", dir, nptl)));
737 : : } else {
738 : 0 : c_file->args.append("-I");
739 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "arm", dir)));
740 : : }
741 [ # # ]: 0 : } else if (is_mips) {
742 [ # # ]: 0 : if (nptl != nullptr) {
743 : 0 : c_file->args.append("-I");
744 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "mips" OS_SEP "%s", dir, nptl)));
745 : : } else {
746 [ # # ]: 0 : if (is_64) {
747 : 0 : c_file->args.append("-I");
748 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "mips" OS_SEP "mips64", dir)));
749 : : } else {
750 : 0 : c_file->args.append("-I");
751 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "mips" OS_SEP "mips32", dir)));
752 : : }
753 : 0 : c_file->args.append("-I");
754 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "mips", dir)));
755 : : }
756 [ # # ]: 0 : } else if (is_sparc) {
757 [ # # ]: 0 : if (nptl != nullptr) {
758 : 0 : c_file->args.append("-I");
759 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sparc" OS_SEP "%s", dir, nptl)));
760 : : } else {
761 [ # # ]: 0 : if (is_64) {
762 : 0 : c_file->args.append("-I");
763 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sparc" OS_SEP "sparc64", dir)));
764 : : } else {
765 : 0 : c_file->args.append("-I");
766 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sparc" OS_SEP "sparc32", dir)));
767 : : }
768 : 0 : c_file->args.append("-I");
769 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sparc", dir)));
770 : : }
771 [ # # ]: 0 : } else if (is_aarch64) {
772 [ # # ]: 0 : if (nptl != nullptr) {
773 : 0 : c_file->args.append("-I");
774 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "aarch64" OS_SEP "%s", dir, nptl)));
775 : : } else {
776 : 0 : c_file->args.append("-I");
777 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "aarch64", dir)));
778 : : }
779 [ # # ]: 0 : } else if (is_ppc) {
780 [ # # ]: 0 : if (nptl != nullptr) {
781 : 0 : c_file->args.append("-I");
782 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "powerpc" OS_SEP "%s", dir, nptl)));
783 : : } else {
784 [ # # ]: 0 : if (is_64) {
785 : 0 : c_file->args.append("-I");
786 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "powerpc" OS_SEP "powerpc64", dir)));
787 : : } else {
788 : 0 : c_file->args.append("-I");
789 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "powerpc" OS_SEP "powerpc32", dir)));
790 : : }
791 : 0 : c_file->args.append("-I");
792 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "powerpc", dir)));
793 : : }
794 [ # # ]: 0 : } else if (is_riscv) {
795 [ # # ]: 0 : if (nptl != nullptr) {
796 : 0 : c_file->args.append("-I");
797 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "riscv" OS_SEP "%s", dir, nptl)));
798 : : } else {
799 : 0 : c_file->args.append("-I");
800 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "riscv", dir)));
801 : : }
802 : : }
803 : 152 : }
804 : :
805 : 38 : static void glibc_add_include_dirs(CodeGen *parent, CFile *c_file) {
806 : 38 : ZigLLVM_ArchType arch = parent->zig_target->arch;
807 [ + - ]: 38 : const char *nptl = (parent->zig_target->os == OsLinux) ? "nptl" : "htl";
808 : 38 : const char *glibc = path_from_libc(parent, "glibc");
809 : :
810 : 38 : c_file->args.append("-I");
811 : 38 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "include", glibc)));
812 : :
813 [ + - ]: 38 : if (parent->zig_target->os == OsLinux) {
814 : 38 : glibc_add_include_dirs_arch(c_file, arch, nullptr,
815 : : path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "unix" OS_SEP "sysv" OS_SEP "linux"));
816 : : }
817 : :
818 [ + - ]: 38 : if (nptl != nullptr) {
819 : 38 : glibc_add_include_dirs_arch(c_file, arch, nptl, path_from_libc(parent, "glibc" OS_SEP "sysdeps"));
820 : : }
821 : :
822 [ + - ]: 38 : if (parent->zig_target->os == OsLinux) {
823 : 38 : c_file->args.append("-I");
824 : 38 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP
825 : : "unix" OS_SEP "sysv" OS_SEP "linux" OS_SEP "include"));
826 : 38 : c_file->args.append("-I");
827 : 38 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP
828 : : "unix" OS_SEP "sysv" OS_SEP "linux"));
829 : : }
830 [ + - ]: 38 : if (nptl != nullptr) {
831 : 38 : c_file->args.append("-I");
832 : 38 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "sysdeps" OS_SEP "%s", glibc, nptl)));
833 : : }
834 : :
835 : 38 : c_file->args.append("-I");
836 : 38 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "pthread"));
837 : :
838 : 38 : c_file->args.append("-I");
839 : 38 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "unix" OS_SEP "sysv"));
840 : :
841 : 38 : glibc_add_include_dirs_arch(c_file, arch, nullptr,
842 : : path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "unix"));
843 : :
844 : 38 : c_file->args.append("-I");
845 : 38 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "unix"));
846 : :
847 : 38 : glibc_add_include_dirs_arch(c_file, arch, nullptr, path_from_libc(parent, "glibc" OS_SEP "sysdeps"));
848 : :
849 : 38 : c_file->args.append("-I");
850 : 38 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "sysdeps" OS_SEP "generic"));
851 : :
852 : 38 : c_file->args.append("-I");
853 : 38 : c_file->args.append(path_from_libc(parent, "glibc"));
854 : :
855 : 38 : c_file->args.append("-I");
856 : 38 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-%s-%s",
857 : 38 : buf_ptr(parent->zig_lib_dir), target_arch_name(parent->zig_target->arch),
858 : 76 : target_os_name(parent->zig_target->os), target_abi_name(parent->zig_target->abi))));
859 : :
860 : 38 : c_file->args.append("-I");
861 : 38 : c_file->args.append(path_from_libc(parent, "include" OS_SEP "generic-glibc"));
862 : :
863 : 38 : c_file->args.append("-I");
864 : 38 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-linux-any",
865 : 38 : buf_ptr(parent->zig_lib_dir), target_arch_name(parent->zig_target->arch))));
866 : :
867 : 38 : c_file->args.append("-I");
868 : 38 : c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-linux-any"));
869 : 38 : }
870 : :
871 : 6 : static const char *glibc_start_asm_path(CodeGen *parent, const char *file) {
872 : 6 : ZigLLVM_ArchType arch = parent->zig_target->arch;
873 [ + - ][ - + ]: 6 : bool is_aarch64 = arch == ZigLLVM_aarch64 || arch == ZigLLVM_aarch64_be;
874 [ + - ][ + - ]: 6 : bool is_mips = arch == ZigLLVM_mips || arch == ZigLLVM_mipsel ||
875 [ + - ][ - + ]: 12 : arch == ZigLLVM_mips64el || arch == ZigLLVM_mips64;
876 [ + - ][ - + ]: 6 : bool is_arm = arch == ZigLLVM_arm || arch == ZigLLVM_armeb;
877 [ + - ][ + - ]: 6 : bool is_ppc = arch == ZigLLVM_ppc || arch == ZigLLVM_ppc64 || arch == ZigLLVM_ppc64le;
[ - + ]
878 [ + - ][ - + ]: 6 : bool is_riscv = arch == ZigLLVM_riscv32 || arch == ZigLLVM_riscv64;
879 [ + - ][ + - ]: 6 : bool is_sparc = arch == ZigLLVM_sparc || arch == ZigLLVM_sparcel || arch == ZigLLVM_sparcv9;
[ - + ]
880 : 6 : bool is_64 = target_arch_pointer_bit_width(arch) == 64;
881 : :
882 : 6 : Buf result = BUF_INIT;
883 : 6 : buf_resize(&result, 0);
884 : 6 : buf_append_buf(&result, parent->zig_lib_dir);
885 : 6 : buf_append_str(&result, OS_SEP "libc" OS_SEP "glibc" OS_SEP "sysdeps" OS_SEP);
886 [ - + ]: 6 : if (is_sparc) {
887 [ # # ]: 0 : if (is_64) {
888 : 0 : buf_append_str(&result, "sparc" OS_SEP "sparc64");
889 : : } else {
890 : 0 : buf_append_str(&result, "sparc" OS_SEP "sparc32");
891 : : }
892 [ - + ]: 6 : } else if (is_arm) {
893 : 0 : buf_append_str(&result, "arm");
894 [ - + ]: 6 : } else if (is_mips) {
895 : 0 : buf_append_str(&result, "mips");
896 [ + - ]: 6 : } else if (arch == ZigLLVM_x86_64) {
897 : 6 : buf_append_str(&result, "x86_64");
898 [ # # ]: 0 : } else if (arch == ZigLLVM_x86) {
899 : 0 : buf_append_str(&result, "i386");
900 [ # # ]: 0 : } else if (is_aarch64) {
901 : 0 : buf_append_str(&result, "aarch64");
902 [ # # ]: 0 : } else if (is_riscv) {
903 : 0 : buf_append_str(&result, "riscv");
904 [ # # ]: 0 : } else if (is_ppc) {
905 [ # # ]: 0 : if (is_64) {
906 : 0 : buf_append_str(&result, "powerpc" OS_SEP "powerpc64");
907 : : } else {
908 : 0 : buf_append_str(&result, "powerpc" OS_SEP "powerpc32");
909 : : }
910 : : }
911 : :
912 : 6 : buf_append_str(&result, OS_SEP);
913 : 6 : buf_append_str(&result, file);
914 : 6 : return buf_ptr(&result);
915 : : }
916 : :
917 : 0 : static const char *musl_start_asm_path(CodeGen *parent, const char *file) {
918 : 0 : Buf *result = buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "crt" OS_SEP "%s" OS_SEP "%s",
919 : 0 : buf_ptr(parent->zig_lib_dir), target_arch_musl_name(parent->zig_target->arch), file);
920 : 0 : return buf_ptr(result);
921 : : }
922 : :
923 : 0 : static void musl_add_cc_args(CodeGen *parent, CFile *c_file, bool want_O3) {
924 : 0 : c_file->args.append("-std=c99");
925 : 0 : c_file->args.append("-ffreestanding");
926 : : // Musl adds these args to builds with gcc but clang does not support them.
927 : : //c_file->args.append("-fexcess-precision=standard");
928 : : //c_file->args.append("-frounding-math");
929 : 0 : c_file->args.append("-Wa,--noexecstack");
930 : 0 : c_file->args.append("-D_XOPEN_SOURCE=700");
931 : :
932 : 0 : c_file->args.append("-I");
933 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "arch" OS_SEP "%s",
934 : 0 : buf_ptr(parent->zig_lib_dir), target_arch_musl_name(parent->zig_target->arch))));
935 : :
936 : 0 : c_file->args.append("-I");
937 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "arch" OS_SEP "generic",
938 : : buf_ptr(parent->zig_lib_dir))));
939 : :
940 : 0 : c_file->args.append("-I");
941 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "src" OS_SEP "include",
942 : : buf_ptr(parent->zig_lib_dir))));
943 : :
944 : 0 : c_file->args.append("-I");
945 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "src" OS_SEP "internal",
946 : : buf_ptr(parent->zig_lib_dir))));
947 : :
948 : 0 : c_file->args.append("-I");
949 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "musl" OS_SEP "include",
950 : : buf_ptr(parent->zig_lib_dir))));
951 : :
952 : 0 : c_file->args.append("-I");
953 : 0 : c_file->args.append(buf_ptr(buf_sprintf(
954 : : "%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-%s-%s",
955 : : buf_ptr(parent->zig_lib_dir),
956 : 0 : target_arch_name(parent->zig_target->arch),
957 : 0 : target_os_name(parent->zig_target->os),
958 : 0 : target_abi_name(parent->zig_target->abi))));
959 : :
960 : 0 : c_file->args.append("-I");
961 : 0 : c_file->args.append(buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "generic-musl",
962 : : buf_ptr(parent->zig_lib_dir))));
963 : :
964 [ # # ]: 0 : if (want_O3)
965 : 0 : c_file->args.append("-O3");
966 : : else
967 : 0 : c_file->args.append("-Os");
968 : :
969 : 0 : c_file->args.append("-fomit-frame-pointer");
970 : 0 : c_file->args.append("-fno-unwind-tables");
971 : 0 : c_file->args.append("-fno-asynchronous-unwind-tables");
972 : 0 : c_file->args.append("-ffunction-sections");
973 : 0 : c_file->args.append("-fdata-sections");
974 : 0 : }
975 : :
976 : : static const char *musl_arch_names[] = {
977 : : "aarch64",
978 : : "arm",
979 : : "generic",
980 : : "i386",
981 : : "m68k",
982 : : "microblaze",
983 : : "mips",
984 : : "mips64",
985 : : "mipsn32",
986 : : "or1k",
987 : : "powerpc",
988 : : "powerpc64",
989 : : "riscv64",
990 : : "s390x",
991 : : "sh",
992 : : "x32",
993 : : "x86_64",
994 : : };
995 : :
996 : 0 : static bool is_musl_arch_name(const char *name) {
997 [ # # ]: 0 : for (size_t i = 0; i < array_length(musl_arch_names); i += 1) {
998 [ # # ]: 0 : if (strcmp(name, musl_arch_names[i]) == 0)
999 : 0 : return true;
1000 : : }
1001 : 0 : return false;
1002 : : }
1003 : :
1004 : 0 : static const char *build_musl(CodeGen *parent) {
1005 : 0 : CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
1006 : 0 : codegen_set_out_name(child_gen, buf_create_from_str("c"));
1007 : :
1008 : : // When there is a src/<arch>/foo.* then it should substitute for src/foo.*
1009 : : // Even a .s file can substitute for a .c file.
1010 : :
1011 : : enum MuslSrc {
1012 : : MuslSrcAsm,
1013 : : MuslSrcNormal,
1014 : : MuslSrcO3,
1015 : : };
1016 : :
1017 : 0 : const char *target_musl_arch_name = target_arch_musl_name(parent->zig_target->arch);
1018 : :
1019 : 0 : HashMap<Buf *, MuslSrc, buf_hash, buf_eql_buf> source_table = {};
1020 : 0 : source_table.init(1800);
1021 : :
1022 [ # # ]: 0 : for (size_t i = 0; i < array_length(ZIG_MUSL_SRC_FILES); i += 1) {
1023 : 0 : Buf *src_file = buf_create_from_str(ZIG_MUSL_SRC_FILES[i]);
1024 : :
1025 : : MuslSrc src_kind;
1026 [ # # ]: 0 : if (buf_ends_with_str(src_file, ".c")) {
1027 : 0 : assert(buf_starts_with_str(src_file, "musl/src/"));
1028 [ # # ]: 0 : bool want_O3 = buf_starts_with_str(src_file, "musl/src/malloc/") ||
1029 [ # # ][ # # ]: 0 : buf_starts_with_str(src_file, "musl/src/string/") ||
1030 : 0 : buf_starts_with_str(src_file, "musl/src/internal/");
1031 [ # # ]: 0 : src_kind = want_O3 ? MuslSrcO3 : MuslSrcNormal;
1032 [ # # ][ # # ]: 0 : } else if (buf_ends_with_str(src_file, ".s") || buf_ends_with_str(src_file, ".S")) {
[ # # ]
1033 : 0 : src_kind = MuslSrcAsm;
1034 : : } else {
1035 : 0 : continue;
1036 : : }
1037 : : if (ZIG_OS_SEP_CHAR != '/') {
1038 : : buf_replace(src_file, '/', ZIG_OS_SEP_CHAR);
1039 : : }
1040 : 0 : source_table.put_unique(src_file, src_kind);
1041 : : }
1042 : :
1043 : 0 : ZigList<CFile *> c_source_files = {0};
1044 : :
1045 : 0 : Buf dirname = BUF_INIT;
1046 : 0 : Buf basename = BUF_INIT;
1047 : 0 : Buf noextbasename = BUF_INIT;
1048 : 0 : Buf dirbasename = BUF_INIT;
1049 : 0 : Buf before_arch_dir = BUF_INIT;
1050 : :
1051 : 0 : auto source_it = source_table.entry_iterator();
1052 : : for (;;) {
1053 : 0 : auto *entry = source_it.next();
1054 [ # # ]: 0 : if (!entry) break;
1055 : :
1056 : 0 : Buf *src_file = entry->key;
1057 : 0 : MuslSrc src_kind = entry->value;
1058 : :
1059 : 0 : os_path_split(src_file, &dirname, &basename);
1060 : 0 : os_path_extname(&basename, &noextbasename, nullptr);
1061 : 0 : os_path_split(&dirname, &before_arch_dir, &dirbasename);
1062 : :
1063 : 0 : bool is_arch_specific = false;
1064 : : // Architecture-specific implementations are under a <arch>/ folder.
1065 [ # # ]: 0 : if (is_musl_arch_name(buf_ptr(&dirbasename))) {
1066 : : // Not the architecture we're compiling for.
1067 [ # # ]: 0 : if (strcmp(buf_ptr(&dirbasename), target_musl_arch_name) != 0)
1068 : 0 : continue;
1069 : 0 : is_arch_specific = true;
1070 : : }
1071 : :
1072 [ # # ]: 0 : if (!is_arch_specific) {
1073 : 0 : Buf override_path = BUF_INIT;
1074 : :
1075 : : // Look for an arch specific override.
1076 : 0 : buf_resize(&override_path, 0);
1077 : 0 : buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.s",
1078 : : buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
1079 [ # # ]: 0 : if (source_table.maybe_get(&override_path) != nullptr)
1080 : 0 : continue;
1081 : :
1082 : 0 : buf_resize(&override_path, 0);
1083 : 0 : buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.S",
1084 : : buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
1085 [ # # ]: 0 : if (source_table.maybe_get(&override_path) != nullptr)
1086 : 0 : continue;
1087 : :
1088 : 0 : buf_resize(&override_path, 0);
1089 : 0 : buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.c",
1090 : : buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
1091 [ # # ]: 0 : if (source_table.maybe_get(&override_path) != nullptr)
1092 : 0 : continue;
1093 : : }
1094 : :
1095 : 0 : Buf *full_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "%s",
1096 : 0 : buf_ptr(parent->zig_lib_dir), buf_ptr(src_file));
1097 : :
1098 : 0 : CFile *c_file = allocate<CFile>(1);
1099 : 0 : c_file->source_path = buf_ptr(full_path);
1100 : :
1101 : 0 : musl_add_cc_args(parent, c_file, src_kind == MuslSrcO3);
1102 : 0 : c_file->args.append("-Qunused-arguments");
1103 : 0 : c_file->args.append("-w"); // disable all warnings
1104 : :
1105 : 0 : c_source_files.append(c_file);
1106 : 0 : }
1107 : :
1108 : 0 : child_gen->c_source_files = c_source_files;
1109 : 0 : codegen_build_and_link(child_gen);
1110 : 0 : return buf_ptr(&child_gen->output_file_path);
1111 : : }
1112 : :
1113 : 0 : static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) {
1114 : 0 : CFile *c_file = allocate<CFile>(1);
1115 : 0 : c_file->source_path = buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s",
1116 : : buf_ptr(parent->zig_lib_dir), src_path));
1117 : 0 : c_file->args.append("-DHAVE_CONFIG_H");
1118 : 0 : c_file->args.append("-D__LIBMSVCRT__");
1119 : :
1120 : 0 : c_file->args.append("-I");
1121 : 0 : c_file->args.append(path_from_libc(parent, "mingw" OS_SEP "include"));
1122 : :
1123 : 0 : c_file->args.append("-std=gnu99");
1124 : 0 : c_file->args.append("-D_CRTBLD");
1125 : 0 : c_file->args.append("-D_WIN32_WINNT=0x0f00");
1126 : 0 : c_file->args.append("-D__MSVCRT_VERSION__=0x700");
1127 : :
1128 : 0 : c_file->args.append("-isystem");
1129 : 0 : c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-windows-any"));
1130 : :
1131 : 0 : c_file->args.append("-g");
1132 : 0 : c_file->args.append("-O2");
1133 : :
1134 : 0 : child_gen->c_source_files.append(c_file);
1135 : 0 : }
1136 : :
1137 : 0 : static void add_mingwex_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) {
1138 : 0 : CFile *c_file = allocate<CFile>(1);
1139 : 0 : c_file->source_path = buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s",
1140 : : buf_ptr(parent->zig_lib_dir), src_path));
1141 : 0 : c_file->args.append("-DHAVE_CONFIG_H");
1142 : :
1143 : 0 : c_file->args.append("-I");
1144 : 0 : c_file->args.append(path_from_libc(parent, "mingw"));
1145 : :
1146 : 0 : c_file->args.append("-I");
1147 : 0 : c_file->args.append(path_from_libc(parent, "mingw" OS_SEP "include"));
1148 : :
1149 : 0 : c_file->args.append("-std=gnu99");
1150 : 0 : c_file->args.append("-D_CRTBLD");
1151 : 0 : c_file->args.append("-D_WIN32_WINNT=0x0f00");
1152 : 0 : c_file->args.append("-D__MSVCRT_VERSION__=0x700");
1153 : 0 : c_file->args.append("-g");
1154 : 0 : c_file->args.append("-O2");
1155 : :
1156 : 0 : c_file->args.append("-isystem");
1157 : 0 : c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-windows-any"));
1158 : :
1159 : 0 : child_gen->c_source_files.append(c_file);
1160 : 0 : }
1161 : :
1162 : 12 : static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
1163 [ + - ][ - + ]: 12 : if (parent->libc == nullptr && parent->zig_target->os == OsWindows) {
1164 [ # # ]: 0 : if (strcmp(file, "crt2.o") == 0) {
1165 : 0 : CFile *c_file = allocate<CFile>(1);
1166 : 0 : c_file->source_path = buf_ptr(buf_sprintf(
1167 : : "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "crt" OS_SEP "crtexe.c", buf_ptr(parent->zig_lib_dir)));
1168 : 0 : mingw_add_cc_args(parent, c_file);
1169 : 0 : c_file->args.append("-U__CRTDLL__");
1170 : 0 : c_file->args.append("-D__MSVCRT__");
1171 : : // Uncomment these 3 things for crtu
1172 : : //c_file->args.append("-DUNICODE");
1173 : : //c_file->args.append("-D_UNICODE");
1174 : : //c_file->args.append("-DWPRFLAG=1");
1175 : 0 : return build_libc_object(parent, "crt2", c_file);
1176 [ # # ]: 0 : } else if (strcmp(file, "dllcrt2.o") == 0) {
1177 : 0 : CFile *c_file = allocate<CFile>(1);
1178 : 0 : c_file->source_path = buf_ptr(buf_sprintf(
1179 : : "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "crt" OS_SEP "crtdll.c", buf_ptr(parent->zig_lib_dir)));
1180 : 0 : mingw_add_cc_args(parent, c_file);
1181 : 0 : c_file->args.append("-U__CRTDLL__");
1182 : 0 : c_file->args.append("-D__MSVCRT__");
1183 : 0 : return build_libc_object(parent, "dllcrt2", c_file);
1184 [ # # ]: 0 : } else if (strcmp(file, "mingw32.lib") == 0) {
1185 : 0 : CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
1186 : 0 : codegen_set_out_name(child_gen, buf_create_from_str("mingw32"));
1187 : :
1188 : : static const char *deps[] = {
1189 : : "mingw" OS_SEP "crt" OS_SEP "crt0_c.c",
1190 : : "mingw" OS_SEP "crt" OS_SEP "dll_argv.c",
1191 : : "mingw" OS_SEP "crt" OS_SEP "gccmain.c",
1192 : : "mingw" OS_SEP "crt" OS_SEP "natstart.c",
1193 : : "mingw" OS_SEP "crt" OS_SEP "pseudo-reloc-list.c",
1194 : : "mingw" OS_SEP "crt" OS_SEP "wildcard.c",
1195 : : "mingw" OS_SEP "crt" OS_SEP "charmax.c",
1196 : : "mingw" OS_SEP "crt" OS_SEP "crt0_w.c",
1197 : : "mingw" OS_SEP "crt" OS_SEP "dllargv.c",
1198 : : "mingw" OS_SEP "crt" OS_SEP "gs_support.c",
1199 : : "mingw" OS_SEP "crt" OS_SEP "_newmode.c",
1200 : : "mingw" OS_SEP "crt" OS_SEP "tlssup.c",
1201 : : "mingw" OS_SEP "crt" OS_SEP "xncommod.c",
1202 : : "mingw" OS_SEP "crt" OS_SEP "cinitexe.c",
1203 : : "mingw" OS_SEP "crt" OS_SEP "merr.c",
1204 : : "mingw" OS_SEP "crt" OS_SEP "pesect.c",
1205 : : "mingw" OS_SEP "crt" OS_SEP "udllargc.c",
1206 : : "mingw" OS_SEP "crt" OS_SEP "xthdloc.c",
1207 : : "mingw" OS_SEP "crt" OS_SEP "CRT_fp10.c",
1208 : : "mingw" OS_SEP "crt" OS_SEP "mingw_helpers.c",
1209 : : "mingw" OS_SEP "crt" OS_SEP "pseudo-reloc.c",
1210 : : "mingw" OS_SEP "crt" OS_SEP "udll_argv.c",
1211 : : "mingw" OS_SEP "crt" OS_SEP "xtxtmode.c",
1212 : : "mingw" OS_SEP "crt" OS_SEP "crt_handler.c",
1213 : : "mingw" OS_SEP "crt" OS_SEP "tlsthrd.c",
1214 : : "mingw" OS_SEP "crt" OS_SEP "tlsmthread.c",
1215 : : "mingw" OS_SEP "crt" OS_SEP "tlsmcrt.c",
1216 : : "mingw" OS_SEP "crt" OS_SEP "cxa_atexit.c",
1217 : : };
1218 [ # # ]: 0 : for (size_t i = 0; i < array_length(deps); i += 1) {
1219 : 0 : CFile *c_file = allocate<CFile>(1);
1220 : 0 : c_file->source_path = path_from_libc(parent, deps[i]);
1221 : 0 : c_file->args.append("-DHAVE_CONFIG_H");
1222 : 0 : c_file->args.append("-D_SYSCRT=1");
1223 : 0 : c_file->args.append("-DCRTDLL=1");
1224 : :
1225 : 0 : c_file->args.append("-isystem");
1226 : 0 : c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-windows-any"));
1227 : :
1228 : 0 : c_file->args.append("-isystem");
1229 : 0 : c_file->args.append(path_from_libc(parent, "mingw" OS_SEP "include"));
1230 : :
1231 : 0 : c_file->args.append("-std=gnu99");
1232 : 0 : c_file->args.append("-D_CRTBLD");
1233 : 0 : c_file->args.append("-D_WIN32_WINNT=0x0f00");
1234 : 0 : c_file->args.append("-D__MSVCRT_VERSION__=0x700");
1235 : 0 : c_file->args.append("-g");
1236 : 0 : c_file->args.append("-O2");
1237 : :
1238 : 0 : child_gen->c_source_files.append(c_file);
1239 : : }
1240 : 0 : codegen_build_and_link(child_gen);
1241 : 0 : return buf_ptr(&child_gen->output_file_path);
1242 [ # # ]: 0 : } else if (strcmp(file, "msvcrt-os.lib") == 0) {
1243 : 0 : CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
1244 : 0 : codegen_set_out_name(child_gen, buf_create_from_str("msvcrt-os"));
1245 : :
1246 [ # # ]: 0 : for (size_t i = 0; i < array_length(msvcrt_common_src); i += 1) {
1247 : 0 : add_msvcrt_os_dep(parent, child_gen, msvcrt_common_src[i]);
1248 : : }
1249 [ # # ]: 0 : if (parent->zig_target->arch == ZigLLVM_x86) {
1250 [ # # ]: 0 : for (size_t i = 0; i < array_length(msvcrt_i386_src); i += 1) {
1251 : 0 : add_msvcrt_os_dep(parent, child_gen, msvcrt_i386_src[i]);
1252 : : }
1253 : : } else {
1254 [ # # ]: 0 : for (size_t i = 0; i < array_length(msvcrt_other_src); i += 1) {
1255 : 0 : add_msvcrt_os_dep(parent, child_gen, msvcrt_other_src[i]);
1256 : : }
1257 : : }
1258 : 0 : codegen_build_and_link(child_gen);
1259 : 0 : return buf_ptr(&child_gen->output_file_path);
1260 [ # # ]: 0 : } else if (strcmp(file, "mingwex.lib") == 0) {
1261 : 0 : CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
1262 : 0 : codegen_set_out_name(child_gen, buf_create_from_str("mingwex"));
1263 : :
1264 [ # # ]: 0 : for (size_t i = 0; i < array_length(mingwex_generic_src); i += 1) {
1265 : 0 : add_mingwex_os_dep(parent, child_gen, mingwex_generic_src[i]);
1266 : : }
1267 [ # # ][ # # ]: 0 : if (parent->zig_target->arch == ZigLLVM_x86 || parent->zig_target->arch == ZigLLVM_x86_64) {
1268 [ # # ]: 0 : for (size_t i = 0; i < array_length(mingwex_x86_src); i += 1) {
1269 : 0 : add_mingwex_os_dep(parent, child_gen, mingwex_x86_src[i]);
1270 : 0 : }
1271 [ # # ]: 0 : } else if (target_is_arm(parent->zig_target)) {
1272 [ # # ]: 0 : if (target_arch_pointer_bit_width(parent->zig_target->arch) == 32) {
1273 [ # # ]: 0 : for (size_t i = 0; i < array_length(mingwex_arm32_src); i += 1) {
1274 : 0 : add_mingwex_os_dep(parent, child_gen, mingwex_arm32_src[i]);
1275 : : }
1276 : : } else {
1277 [ # # ]: 0 : for (size_t i = 0; i < array_length(mingwex_arm64_src); i += 1) {
1278 : 0 : add_mingwex_os_dep(parent, child_gen, mingwex_arm64_src[i]);
1279 : : }
1280 : : }
1281 : : } else {
1282 : 0 : zig_unreachable();
1283 : : }
1284 : 0 : codegen_build_and_link(child_gen);
1285 : 0 : return buf_ptr(&child_gen->output_file_path);
1286 : : } else {
1287 : 0 : zig_unreachable();
1288 : : }
1289 [ + - ][ + - ]: 12 : } else if (parent->libc == nullptr && target_is_glibc(parent->zig_target)) {
[ + - ]
1290 [ + + ]: 12 : if (strcmp(file, "crti.o") == 0) {
1291 : 2 : CFile *c_file = allocate<CFile>(1);
1292 : 2 : c_file->source_path = glibc_start_asm_path(parent, "crti.S");
1293 : 2 : glibc_add_include_dirs(parent, c_file);
1294 : 2 : c_file->args.append("-D_LIBC_REENTRANT");
1295 : 2 : c_file->args.append("-include");
1296 : 2 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h"));
1297 : 2 : c_file->args.append("-DMODULE_NAME=libc");
1298 : 2 : c_file->args.append("-include");
1299 : 2 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h"));
1300 : 2 : c_file->args.append("-DTOP_NAMESPACE=glibc");
1301 : 2 : c_file->args.append("-DASSEMBLER");
1302 : 2 : c_file->args.append("-g");
1303 : 2 : c_file->args.append("-Wa,--noexecstack");
1304 : 2 : return build_libc_object(parent, "crti", c_file);
1305 [ + + ]: 10 : } else if (strcmp(file, "crtn.o") == 0) {
1306 : 2 : CFile *c_file = allocate<CFile>(1);
1307 : 2 : c_file->source_path = glibc_start_asm_path(parent, "crtn.S");
1308 : 2 : glibc_add_include_dirs(parent, c_file);
1309 : 2 : c_file->args.append("-D_LIBC_REENTRANT");
1310 : 2 : c_file->args.append("-DMODULE_NAME=libc");
1311 : 2 : c_file->args.append("-DTOP_NAMESPACE=glibc");
1312 : 2 : c_file->args.append("-DASSEMBLER");
1313 : 2 : c_file->args.append("-g");
1314 : 2 : c_file->args.append("-Wa,--noexecstack");
1315 : 2 : return build_libc_object(parent, "crtn", c_file);
1316 [ + + ]: 8 : } else if (strcmp(file, "start.os") == 0) {
1317 : 2 : CFile *c_file = allocate<CFile>(1);
1318 : 2 : c_file->source_path = glibc_start_asm_path(parent, "start.S");
1319 : 2 : glibc_add_include_dirs(parent, c_file);
1320 : 2 : c_file->args.append("-D_LIBC_REENTRANT");
1321 : 2 : c_file->args.append("-include");
1322 : 2 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h"));
1323 : 2 : c_file->args.append("-DMODULE_NAME=libc");
1324 : 2 : c_file->args.append("-include");
1325 : 2 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h"));
1326 : 2 : c_file->args.append("-DPIC");
1327 : 2 : c_file->args.append("-DSHARED");
1328 : 2 : c_file->args.append("-DTOP_NAMESPACE=glibc");
1329 : 2 : c_file->args.append("-DASSEMBLER");
1330 : 2 : c_file->args.append("-g");
1331 : 2 : c_file->args.append("-Wa,--noexecstack");
1332 : 2 : return build_libc_object(parent, "start", c_file);
1333 [ + + ]: 6 : } else if (strcmp(file, "abi-note.o") == 0) {
1334 : 2 : CFile *c_file = allocate<CFile>(1);
1335 : 2 : c_file->source_path = path_from_libc(parent, "glibc" OS_SEP "csu" OS_SEP "abi-note.S");
1336 : 2 : c_file->args.append("-I");
1337 : 2 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "csu"));
1338 : 2 : glibc_add_include_dirs(parent, c_file);
1339 : 2 : c_file->args.append("-D_LIBC_REENTRANT");
1340 : 2 : c_file->args.append("-DMODULE_NAME=libc");
1341 : 2 : c_file->args.append("-DTOP_NAMESPACE=glibc");
1342 : 2 : c_file->args.append("-DASSEMBLER");
1343 : 2 : c_file->args.append("-g");
1344 : 2 : c_file->args.append("-Wa,--noexecstack");
1345 : 2 : return build_libc_object(parent, "abi-note", c_file);
1346 [ + + ]: 4 : } else if (strcmp(file, "Scrt1.o") == 0) {
1347 : 2 : const char *start_os = get_libc_crt_file(parent, "start.os");
1348 : 2 : const char *abi_note_o = get_libc_crt_file(parent, "abi-note.o");
1349 : 2 : CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeObj, nullptr);
1350 : 2 : codegen_set_out_name(child_gen, buf_create_from_str("Scrt1"));
1351 : 2 : codegen_add_object(child_gen, buf_create_from_str(start_os));
1352 : 2 : codegen_add_object(child_gen, buf_create_from_str(abi_note_o));
1353 : 2 : codegen_build_and_link(child_gen);
1354 : 2 : return buf_ptr(&child_gen->output_file_path);
1355 [ + - ]: 2 : } else if (strcmp(file, "libc_nonshared.a") == 0) {
1356 : 2 : CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
1357 : 2 : codegen_set_out_name(child_gen, buf_create_from_str("c_nonshared"));
1358 : : {
1359 : 2 : CFile *c_file = allocate<CFile>(1);
1360 : 2 : c_file->source_path = path_from_libc(parent, "glibc" OS_SEP "csu" OS_SEP "elf-init.c");
1361 : 2 : c_file->args.append("-std=gnu11");
1362 : 2 : c_file->args.append("-fgnu89-inline");
1363 : 2 : c_file->args.append("-g");
1364 : 2 : c_file->args.append("-O2");
1365 : 2 : c_file->args.append("-fmerge-all-constants");
1366 : 2 : c_file->args.append("-fno-stack-protector");
1367 : 2 : c_file->args.append("-fmath-errno");
1368 : 2 : c_file->args.append("-fno-stack-protector");
1369 : 2 : c_file->args.append("-I");
1370 : 2 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "csu"));
1371 : 2 : glibc_add_include_dirs(parent, c_file);
1372 : 2 : c_file->args.append("-DSTACK_PROTECTOR_LEVEL=0");
1373 : 2 : c_file->args.append("-fPIC");
1374 : 2 : c_file->args.append("-fno-stack-protector");
1375 : 2 : c_file->args.append("-ftls-model=initial-exec");
1376 : 2 : c_file->args.append("-D_LIBC_REENTRANT");
1377 : 2 : c_file->args.append("-include");
1378 : 2 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h"));
1379 : 2 : c_file->args.append("-DMODULE_NAME=libc");
1380 : 2 : c_file->args.append("-include");
1381 : 2 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h"));
1382 : 2 : c_file->args.append("-DPIC");
1383 : 2 : c_file->args.append("-DLIBC_NONSHARED=1");
1384 : 2 : c_file->args.append("-DTOP_NAMESPACE=glibc");
1385 : 2 : codegen_add_object(child_gen, buf_create_from_str(build_libc_object(parent, "elf-init", c_file)));
1386 : : }
1387 : : static const struct {
1388 : : const char *name;
1389 : : const char *path;
1390 : : } deps[] = {
1391 : : {"atexit", "glibc" OS_SEP "stdlib" OS_SEP "atexit.c"},
1392 : : {"at_quick_exit", "glibc" OS_SEP "stdlib" OS_SEP "at_quick_exit.c"},
1393 : : {"stat", "glibc" OS_SEP "io" OS_SEP "stat.c"},
1394 : : {"fstat", "glibc" OS_SEP "io" OS_SEP "fstat.c"},
1395 : : {"lstat", "glibc" OS_SEP "io" OS_SEP "lstat.c"},
1396 : : {"stat64", "glibc" OS_SEP "io" OS_SEP "stat64.c"},
1397 : : {"fstat64", "glibc" OS_SEP "io" OS_SEP "fstat64.c"},
1398 : : {"lstat64", "glibc" OS_SEP "io" OS_SEP "lstat64.c"},
1399 : : {"fstatat", "glibc" OS_SEP "io" OS_SEP "fstatat.c"},
1400 : : {"fstatat64", "glibc" OS_SEP "io" OS_SEP "fstatat64.c"},
1401 : : {"mknod", "glibc" OS_SEP "io" OS_SEP "mknod.c"},
1402 : : {"mknodat", "glibc" OS_SEP "io" OS_SEP "mknodat.c"},
1403 : : {"pthread_atfork", "glibc" OS_SEP "nptl" OS_SEP "pthread_atfork.c"},
1404 : : {"stack_chk_fail_local", "glibc" OS_SEP "debug" OS_SEP "stack_chk_fail_local.c"},
1405 : : };
1406 [ + + ]: 30 : for (size_t i = 0; i < array_length(deps); i += 1) {
1407 : 28 : CFile *c_file = allocate<CFile>(1);
1408 : 28 : c_file->source_path = path_from_libc(parent, deps[i].path);
1409 : 28 : c_file->args.append("-std=gnu11");
1410 : 28 : c_file->args.append("-fgnu89-inline");
1411 : 28 : c_file->args.append("-g");
1412 : 28 : c_file->args.append("-O2");
1413 : 28 : c_file->args.append("-fmerge-all-constants");
1414 : 28 : c_file->args.append("-fno-stack-protector");
1415 : 28 : c_file->args.append("-fmath-errno");
1416 : 28 : c_file->args.append("-ftls-model=initial-exec");
1417 : 28 : c_file->args.append("-Wno-ignored-attributes");
1418 : 28 : glibc_add_include_dirs(parent, c_file);
1419 : 28 : c_file->args.append("-D_LIBC_REENTRANT");
1420 : 28 : c_file->args.append("-include");
1421 : 28 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h"));
1422 : 28 : c_file->args.append("-DMODULE_NAME=libc");
1423 : 28 : c_file->args.append("-include");
1424 : 28 : c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h"));
1425 : 28 : c_file->args.append("-DPIC");
1426 : 28 : c_file->args.append("-DLIBC_NONSHARED=1");
1427 : 28 : c_file->args.append("-DTOP_NAMESPACE=glibc");
1428 : 28 : codegen_add_object(child_gen, buf_create_from_str(build_libc_object(parent, deps[i].name, c_file)));
1429 : : }
1430 : 2 : codegen_build_and_link(child_gen);
1431 : 2 : return buf_ptr(&child_gen->output_file_path);
1432 : : } else {
1433 : 0 : zig_unreachable();
1434 : : }
1435 [ # # ][ # # ]: 0 : } else if (parent->libc == nullptr && target_is_musl(parent->zig_target)) {
[ # # ]
1436 [ # # ]: 0 : if (strcmp(file, "crti.o") == 0) {
1437 : 0 : CFile *c_file = allocate<CFile>(1);
1438 : 0 : c_file->source_path = musl_start_asm_path(parent, "crti.s");
1439 : 0 : musl_add_cc_args(parent, c_file, false);
1440 : 0 : c_file->args.append("-Qunused-arguments");
1441 : 0 : return build_libc_object(parent, "crti", c_file);
1442 [ # # ]: 0 : } else if (strcmp(file, "crtn.o") == 0) {
1443 : 0 : CFile *c_file = allocate<CFile>(1);
1444 : 0 : c_file->source_path = musl_start_asm_path(parent, "crtn.s");
1445 : 0 : c_file->args.append("-Qunused-arguments");
1446 : 0 : musl_add_cc_args(parent, c_file, false);
1447 : 0 : return build_libc_object(parent, "crtn", c_file);
1448 [ # # ]: 0 : } else if (strcmp(file, "crt1.o") == 0) {
1449 : 0 : CFile *c_file = allocate<CFile>(1);
1450 : 0 : c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "crt1.c");
1451 : 0 : musl_add_cc_args(parent, c_file, false);
1452 : 0 : c_file->args.append("-fno-stack-protector");
1453 : 0 : c_file->args.append("-DCRT");
1454 : 0 : return build_libc_object(parent, "crt1", c_file);
1455 [ # # ]: 0 : } else if (strcmp(file, "Scrt1.o") == 0) {
1456 : 0 : CFile *c_file = allocate<CFile>(1);
1457 : 0 : c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "Scrt1.c");
1458 : 0 : musl_add_cc_args(parent, c_file, false);
1459 : 0 : c_file->args.append("-fPIC");
1460 : 0 : c_file->args.append("-fno-stack-protector");
1461 : 0 : c_file->args.append("-DCRT");
1462 : 0 : return build_libc_object(parent, "Scrt1", c_file);
1463 : : } else {
1464 : 0 : zig_unreachable();
1465 : : }
1466 : : } else {
1467 : 0 : assert(parent->libc != nullptr);
1468 : 0 : Buf *out_buf = buf_alloc();
1469 : 0 : os_path_join(&parent->libc->crt_dir, buf_create_from_str(file), out_buf);
1470 : 0 : return buf_ptr(out_buf);
1471 : : }
1472 : : }
1473 : :
1474 : 14 : static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, OutType child_out_type) {
1475 : 14 : CodeGen *child_gen = create_child_codegen(parent_gen, full_path, child_out_type,
1476 : 14 : parent_gen->libc);
1477 : 14 : codegen_set_out_name(child_gen, buf_create_from_str(aname));
1478 : :
1479 : : // This is so that compiler_rt and libc.zig libraries know whether they
1480 : : // will eventually be linked with libc. They make different decisions
1481 : : // about what to export depending on whether libc is linked.
1482 [ + + ]: 14 : if (parent_gen->libc_link_lib != nullptr) {
1483 : 4 : LinkLib *new_link_lib = codegen_add_link_lib(child_gen, parent_gen->libc_link_lib->name);
1484 : 4 : new_link_lib->provided_explicitly = parent_gen->libc_link_lib->provided_explicitly;
1485 : : }
1486 : :
1487 : 14 : child_gen->function_sections = true;
1488 : 14 : child_gen->want_stack_check = WantStackCheckDisabled;
1489 : :
1490 : 14 : codegen_build_and_link(child_gen);
1491 : 14 : return &child_gen->output_file_path;
1492 : : }
1493 : :
1494 : 9 : static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type) {
1495 : 9 : Buf *full_path = buf_alloc();
1496 : 9 : os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("compiler_rt.zig"), full_path);
1497 : :
1498 : 9 : return build_a_raw(parent_gen, "compiler_rt", full_path, child_out_type);
1499 : : }
1500 : :
1501 : 5 : static Buf *build_c(CodeGen *parent_gen, OutType child_out_type) {
1502 : 5 : Buf *full_path = buf_alloc();
1503 : 5 : os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("c.zig"), full_path);
1504 : :
1505 : 5 : return build_a_raw(parent_gen, "c", full_path, child_out_type);
1506 : : }
1507 : :
1508 : 2 : static const char *get_darwin_arch_string(const ZigTarget *t) {
1509 [ - - - - : 2 : switch (t->arch) {
- + ]
1510 : 0 : case ZigLLVM_aarch64:
1511 : 0 : return "arm64";
1512 : 0 : case ZigLLVM_thumb:
1513 : : case ZigLLVM_arm:
1514 : 0 : return "arm";
1515 : 0 : case ZigLLVM_ppc:
1516 : 0 : return "ppc";
1517 : 0 : case ZigLLVM_ppc64:
1518 : 0 : return "ppc64";
1519 : 0 : case ZigLLVM_ppc64le:
1520 : 0 : return "ppc64le";
1521 : 2 : default:
1522 : 2 : return ZigLLVMGetArchTypeName(t->arch);
1523 : : }
1524 : : }
1525 : :
1526 : :
1527 : 11 : static const char *getLDMOption(const ZigTarget *t) {
1528 [ - - - - : 11 : switch (t->arch) {
- - - - -
- - - - -
+ - - - ]
1529 : 0 : case ZigLLVM_x86:
1530 : 0 : return "elf_i386";
1531 : 0 : case ZigLLVM_aarch64:
1532 : 0 : return "aarch64linux";
1533 : 0 : case ZigLLVM_aarch64_be:
1534 : 0 : return "aarch64_be_linux";
1535 : 0 : case ZigLLVM_arm:
1536 : : case ZigLLVM_thumb:
1537 : 0 : return "armelf_linux_eabi";
1538 : 0 : case ZigLLVM_armeb:
1539 : : case ZigLLVM_thumbeb:
1540 : 0 : return "armebelf_linux_eabi";
1541 : 0 : case ZigLLVM_ppc:
1542 : 0 : return "elf32ppclinux";
1543 : 0 : case ZigLLVM_ppc64:
1544 : 0 : return "elf64ppc";
1545 : 0 : case ZigLLVM_ppc64le:
1546 : 0 : return "elf64lppc";
1547 : 0 : case ZigLLVM_sparc:
1548 : : case ZigLLVM_sparcel:
1549 : 0 : return "elf32_sparc";
1550 : 0 : case ZigLLVM_sparcv9:
1551 : 0 : return "elf64_sparc";
1552 : 0 : case ZigLLVM_mips:
1553 : 0 : return "elf32btsmip";
1554 : 0 : case ZigLLVM_mipsel:
1555 : 0 : return "elf32ltsmip";
1556 : : return "elf64btsmip";
1557 : 0 : case ZigLLVM_mips64el:
1558 : 0 : return "elf64ltsmip";
1559 : 0 : case ZigLLVM_systemz:
1560 : 0 : return "elf64_s390";
1561 : 11 : case ZigLLVM_x86_64:
1562 [ - + ]: 11 : if (t->abi == ZigLLVM_GNUX32) {
1563 : 0 : return "elf32_x86_64";
1564 : : }
1565 : : // Any target elf will use the freebsd osabi if suffixed with "_fbsd".
1566 [ - + ]: 11 : if (t->os == OsFreeBSD) {
1567 : 0 : return "elf_x86_64_fbsd";
1568 : : }
1569 : 11 : return "elf_x86_64";
1570 : 0 : case ZigLLVM_riscv32:
1571 : 0 : return "elf32lriscv";
1572 : 0 : case ZigLLVM_riscv64:
1573 : 0 : return "elf64lriscv";
1574 : 0 : default:
1575 : 0 : zig_unreachable();
1576 : : }
1577 : : }
1578 : :
1579 : 0 : static void add_rpath(LinkJob *lj, Buf *rpath) {
1580 [ # # ]: 0 : if (lj->rpath_table.maybe_get(rpath) != nullptr)
1581 : 0 : return;
1582 : :
1583 : 0 : lj->args.append("-rpath");
1584 : 0 : lj->args.append(buf_ptr(rpath));
1585 : :
1586 : 0 : lj->rpath_table.put(rpath, true);
1587 : : }
1588 : :
1589 : 2 : static void add_glibc_libs(LinkJob *lj) {
1590 : : Error err;
1591 : : ZigGLibCAbi *glibc_abi;
1592 [ - + ]: 2 : if ((err = glibc_load_metadata(&glibc_abi, lj->codegen->zig_lib_dir, true))) {
1593 : 0 : fprintf(stderr, "%s\n", err_str(err));
1594 : 0 : exit(1);
1595 : : }
1596 : :
1597 : : Buf *artifact_dir;
1598 [ - + ]: 2 : if ((err = glibc_build_dummies_and_maps(lj->codegen, glibc_abi, lj->codegen->zig_target,
1599 : 2 : &artifact_dir, true)))
1600 : : {
1601 : 0 : fprintf(stderr, "%s\n", err_str(err));
1602 : 0 : exit(1);
1603 : : }
1604 : :
1605 : 2 : size_t lib_count = glibc_lib_count();
1606 [ + + ]: 12 : for (size_t i = 0; i < lib_count; i += 1) {
1607 : 10 : const ZigGLibCLib *lib = glibc_lib_enum(i);
1608 : 10 : Buf *so_path = buf_sprintf("%s" OS_SEP "lib%s.so.%d.0.0", buf_ptr(artifact_dir), lib->name, lib->sover);
1609 : 10 : lj->args.append(buf_ptr(so_path));
1610 : : }
1611 : 2 : }
1612 : :
1613 : 11 : static void construct_linker_job_elf(LinkJob *lj) {
1614 : 11 : CodeGen *g = lj->codegen;
1615 : :
1616 : 11 : lj->args.append("-error-limit=0");
1617 : :
1618 [ - + ]: 11 : if (g->linker_script) {
1619 : 0 : lj->args.append("-T");
1620 : 0 : lj->args.append(g->linker_script);
1621 : : }
1622 : :
1623 [ + + ]: 11 : if (g->out_type != OutTypeObj) {
1624 : 10 : lj->args.append("--gc-sections");
1625 : : }
1626 : :
1627 : 11 : lj->args.append("-m");
1628 : 11 : lj->args.append(getLDMOption(g->zig_target));
1629 : :
1630 : 11 : bool is_lib = g->out_type == OutTypeLib;
1631 [ + - ][ + + ]: 11 : bool is_dyn_lib = g->is_dynamic && is_lib;
1632 : 11 : Buf *soname = nullptr;
1633 [ + + ]: 11 : if (!g->have_dynamic_link) {
1634 [ + - ][ + - ]: 4 : if (g->zig_target->arch == ZigLLVM_arm || g->zig_target->arch == ZigLLVM_armeb ||
[ + - ]
1635 [ - + ]: 4 : g->zig_target->arch == ZigLLVM_thumb || g->zig_target->arch == ZigLLVM_thumbeb)
1636 : : {
1637 : 0 : lj->args.append("-Bstatic");
1638 : : } else {
1639 : 4 : lj->args.append("-static");
1640 : : }
1641 [ + + ]: 7 : } else if (is_dyn_lib) {
1642 : 5 : lj->args.append("-shared");
1643 : :
1644 : 5 : assert(buf_len(&g->output_file_path) != 0);
1645 : 5 : soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major);
1646 : : }
1647 : :
1648 : 11 : lj->args.append("-o");
1649 : 11 : lj->args.append(buf_ptr(&g->output_file_path));
1650 : :
1651 [ + + ]: 11 : if (lj->link_in_crt) {
1652 : : const char *crt1o;
1653 [ - + ]: 2 : if (g->zig_target->os == OsNetBSD) {
1654 : 0 : crt1o = "crt0.o";
1655 [ - + ]: 2 : } else if (!g->have_dynamic_link) {
1656 : 0 : crt1o = "crt1.o";
1657 : : } else {
1658 : 2 : crt1o = "Scrt1.o";
1659 : : }
1660 : 2 : lj->args.append(get_libc_crt_file(g, crt1o));
1661 : 2 : lj->args.append(get_libc_crt_file(g, "crti.o"));
1662 : : }
1663 : :
1664 [ - + ]: 11 : for (size_t i = 0; i < g->rpath_list.length; i += 1) {
1665 : 0 : Buf *rpath = g->rpath_list.at(i);
1666 : 0 : add_rpath(lj, rpath);
1667 : : }
1668 [ + - ]: 11 : if (g->each_lib_rpath) {
1669 [ - + ]: 11 : for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
1670 : 0 : const char *lib_dir = g->lib_dirs.at(i);
1671 [ # # ]: 0 : for (size_t i = 0; i < g->link_libs_list.length; i += 1) {
1672 : 0 : LinkLib *link_lib = g->link_libs_list.at(i);
1673 [ # # ]: 0 : if (buf_eql_str(link_lib->name, "c")) {
1674 : 0 : continue;
1675 : : }
1676 : : bool does_exist;
1677 : 0 : Buf *test_path = buf_sprintf("%s/lib%s.so", lib_dir, buf_ptr(link_lib->name));
1678 [ # # ]: 0 : if (os_file_exists(test_path, &does_exist) != ErrorNone) {
1679 : 0 : zig_panic("link: unable to check if file exists: %s", buf_ptr(test_path));
1680 : : }
1681 [ # # ]: 0 : if (does_exist) {
1682 : 0 : add_rpath(lj, buf_create_from_str(lib_dir));
1683 : 0 : break;
1684 : : }
1685 : : }
1686 : : }
1687 : : }
1688 : :
1689 [ - + ]: 11 : for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
1690 : 0 : const char *lib_dir = g->lib_dirs.at(i);
1691 : 0 : lj->args.append("-L");
1692 : 0 : lj->args.append(lib_dir);
1693 : : }
1694 : :
1695 [ + + ]: 11 : if (g->libc_link_lib != nullptr) {
1696 [ - + ]: 2 : if (g->libc != nullptr) {
1697 : 0 : lj->args.append("-L");
1698 : 0 : lj->args.append(buf_ptr(&g->libc->crt_dir));
1699 : : }
1700 : :
1701 [ + - ][ + - ]: 2 : if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) {
[ + - ]
1702 : 2 : assert(g->dynamic_linker_path != nullptr);
1703 : 2 : lj->args.append("-dynamic-linker");
1704 : 2 : lj->args.append(buf_ptr(g->dynamic_linker_path));
1705 : : }
1706 : : }
1707 : :
1708 [ + + ]: 11 : if (is_dyn_lib) {
1709 : 5 : lj->args.append("-soname");
1710 : 5 : lj->args.append(buf_ptr(soname));
1711 : :
1712 [ + - ]: 5 : if (g->version_script_path != nullptr) {
1713 : 5 : lj->args.append("-version-script");
1714 : 5 : lj->args.append(buf_ptr(g->version_script_path));
1715 : : }
1716 : : }
1717 : :
1718 : : // .o files
1719 [ + + ]: 23 : for (size_t i = 0; i < g->link_objects.length; i += 1) {
1720 : 12 : lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
1721 : : }
1722 : :
1723 [ + + ][ + + ]: 11 : if (!g->is_dummy_so && (g->out_type == OutTypeExe || is_dyn_lib)) {
[ - + ]
1724 [ + + ]: 5 : if (g->libc_link_lib == nullptr) {
1725 : 3 : Buf *libc_a_path = build_c(g, OutTypeLib);
1726 : 3 : lj->args.append(buf_ptr(libc_a_path));
1727 : : }
1728 : :
1729 : 5 : Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
1730 : 5 : lj->args.append(buf_ptr(compiler_rt_o_path));
1731 : : }
1732 : :
1733 [ + + ]: 13 : for (size_t i = 0; i < g->link_libs_list.length; i += 1) {
1734 : 2 : LinkLib *link_lib = g->link_libs_list.at(i);
1735 [ + - ]: 2 : if (buf_eql_str(link_lib->name, "c")) {
1736 : : // libc is linked specially
1737 : 2 : continue;
1738 : : }
1739 [ # # ][ # # ]: 0 : if (g->libc == nullptr && target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name))) {
[ # # ]
1740 : : // these libraries are always linked below when targeting glibc
1741 : 0 : continue;
1742 : : }
1743 : : Buf *arg;
1744 [ # # ]: 0 : if (buf_starts_with_str(link_lib->name, "/") || buf_ends_with_str(link_lib->name, ".a") ||
[ # # # # ]
[ # # ]
1745 : 0 : buf_ends_with_str(link_lib->name, ".so"))
1746 : : {
1747 : 0 : arg = link_lib->name;
1748 : : } else {
1749 : 0 : arg = buf_sprintf("-l%s", buf_ptr(link_lib->name));
1750 : : }
1751 : 0 : lj->args.append(buf_ptr(arg));
1752 : : }
1753 : :
1754 : :
1755 : : // libc dep
1756 [ + + ][ + - ]: 11 : if (g->libc_link_lib != nullptr && g->out_type != OutTypeObj) {
1757 [ - + ]: 2 : if (g->libc != nullptr) {
1758 [ # # ]: 0 : if (!g->have_dynamic_link) {
1759 : 0 : lj->args.append("--start-group");
1760 : 0 : lj->args.append("-lgcc");
1761 : 0 : lj->args.append("-lgcc_eh");
1762 : 0 : lj->args.append("-lc");
1763 : 0 : lj->args.append("-lm");
1764 : 0 : lj->args.append("--end-group");
1765 : : } else {
1766 : 0 : lj->args.append("-lgcc");
1767 : 0 : lj->args.append("--as-needed");
1768 : 0 : lj->args.append("-lgcc_s");
1769 : 0 : lj->args.append("--no-as-needed");
1770 : 0 : lj->args.append("-lc");
1771 : 0 : lj->args.append("-lm");
1772 : 0 : lj->args.append("-lgcc");
1773 : 0 : lj->args.append("--as-needed");
1774 : 0 : lj->args.append("-lgcc_s");
1775 : 0 : lj->args.append("--no-as-needed");
1776 : : }
1777 [ + - ]: 2 : } else if (target_is_glibc(g->zig_target)) {
1778 [ + - ]: 2 : if (target_supports_libunwind(g->zig_target)) {
1779 : 2 : lj->args.append(build_libunwind(g));
1780 : : }
1781 : 2 : add_glibc_libs(lj);
1782 : 2 : lj->args.append(get_libc_crt_file(g, "libc_nonshared.a"));
1783 [ # # ]: 0 : } else if (target_is_musl(g->zig_target)) {
1784 [ # # ]: 0 : if (target_supports_libunwind(g->zig_target)) {
1785 : 0 : lj->args.append(build_libunwind(g));
1786 : : }
1787 : 0 : lj->args.append(build_musl(g));
1788 : : } else {
1789 : 0 : zig_unreachable();
1790 : : }
1791 : : }
1792 : :
1793 : : // crt end
1794 [ + + ]: 11 : if (lj->link_in_crt) {
1795 : 2 : lj->args.append(get_libc_crt_file(g, "crtn.o"));
1796 : : }
1797 : :
1798 [ - + ]: 11 : if (!g->zig_target->is_native) {
1799 : 0 : lj->args.append("--allow-shlib-undefined");
1800 : : }
1801 : :
1802 [ - + ]: 11 : if (g->zig_target->os == OsZen) {
1803 : 0 : lj->args.append("-e");
1804 : 0 : lj->args.append("_start");
1805 : :
1806 : 0 : lj->args.append("--image-base=0x10000000");
1807 : : }
1808 : 11 : }
1809 : :
1810 : 0 : static void construct_linker_job_wasm(LinkJob *lj) {
1811 : 0 : CodeGen *g = lj->codegen;
1812 : :
1813 : 0 : lj->args.append("-error-limit=0");
1814 : :
1815 [ # # ]: 0 : if (g->out_type != OutTypeExe) {
1816 : 0 : lj->args.append("--no-entry"); // So lld doesn't look for _start.
1817 : :
1818 : : // If there are any C source files we cannot rely on individual exports.
1819 [ # # ]: 0 : if (g->c_source_files.length != 0) {
1820 : 0 : lj->args.append("--export-all");
1821 : : } else {
1822 : 0 : auto export_it = g->exported_symbol_names.entry_iterator();
1823 : 0 : decltype(g->exported_symbol_names)::Entry *curr_entry = nullptr;
1824 [ # # ]: 0 : while ((curr_entry = export_it.next()) != nullptr) {
1825 : 0 : Buf *arg = buf_sprintf("--export=%s", buf_ptr(curr_entry->key));
1826 : 0 : lj->args.append(buf_ptr(arg));
1827 : : }
1828 : : }
1829 : : }
1830 : 0 : lj->args.append("--allow-undefined");
1831 : 0 : lj->args.append("-o");
1832 : 0 : lj->args.append(buf_ptr(&g->output_file_path));
1833 : :
1834 : : // .o files
1835 [ # # ]: 0 : for (size_t i = 0; i < g->link_objects.length; i += 1) {
1836 : 0 : lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
1837 : : }
1838 : :
1839 [ # # ]: 0 : if (g->out_type != OutTypeObj) {
1840 : 0 : Buf *libc_o_path = build_c(g, OutTypeObj);
1841 : 0 : lj->args.append(buf_ptr(libc_o_path));
1842 : :
1843 : 0 : Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj);
1844 : 0 : lj->args.append(buf_ptr(compiler_rt_o_path));
1845 : : }
1846 : 0 : }
1847 : :
1848 : 6 : static void coff_append_machine_arg(CodeGen *g, ZigList<const char *> *list) {
1849 [ - + ]: 6 : if (g->zig_target->arch == ZigLLVM_x86) {
1850 : 0 : list->append("-MACHINE:X86");
1851 [ + - ]: 6 : } else if (g->zig_target->arch == ZigLLVM_x86_64) {
1852 : 6 : list->append("-MACHINE:X64");
1853 [ # # ]: 0 : } else if (target_is_arm(g->zig_target)) {
1854 [ # # ]: 0 : if (target_arch_pointer_bit_width(g->zig_target->arch) == 32) {
1855 : 0 : list->append("-MACHINE:ARM");
1856 : : } else {
1857 : 0 : list->append("-MACHINE:ARM64");
1858 : : }
1859 : : }
1860 : 6 : }
1861 : :
1862 : 0 : static void link_diag_callback(void *context, const char *ptr, size_t len) {
1863 : 0 : Buf *diag = reinterpret_cast<Buf *>(context);
1864 : 0 : buf_append_mem(diag, ptr, len);
1865 : 0 : }
1866 : :
1867 : 19 : static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag) {
1868 : 19 : buf_resize(diag, 0);
1869 : 19 : return ZigLLDLink(oformat, args, arg_count, link_diag_callback, diag);
1870 : : }
1871 : :
1872 : 0 : static void add_uefi_link_args(LinkJob *lj) {
1873 : 0 : lj->args.append("-BASE:0");
1874 : 0 : lj->args.append("-ENTRY:EfiMain");
1875 : 0 : lj->args.append("-OPT:REF");
1876 : 0 : lj->args.append("-SAFESEH:NO");
1877 : 0 : lj->args.append("-MERGE:.rdata=.data");
1878 : 0 : lj->args.append("-ALIGN:32");
1879 : 0 : lj->args.append("-NODEFAULTLIB");
1880 : 0 : lj->args.append("-SECTION:.xdata,D");
1881 : 0 : }
1882 : :
1883 : 0 : static void add_msvc_link_args(LinkJob *lj, bool is_library) {
1884 : 0 : CodeGen *g = lj->codegen;
1885 : :
1886 : 0 : bool is_dynamic = g->is_dynamic;
1887 [ # # ]: 0 : const char *lib_str = is_dynamic ? "" : "lib";
1888 [ # # ]: 0 : const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : "";
1889 : :
1890 [ # # ]: 0 : if (!is_dynamic) {
1891 : 0 : Buf *cmt_lib_name = buf_sprintf("libcmt%s.lib", d_str);
1892 : 0 : lj->args.append(buf_ptr(cmt_lib_name));
1893 : : } else {
1894 : 0 : Buf *msvcrt_lib_name = buf_sprintf("msvcrt%s.lib", d_str);
1895 : 0 : lj->args.append(buf_ptr(msvcrt_lib_name));
1896 : : }
1897 : :
1898 : 0 : Buf *vcruntime_lib_name = buf_sprintf("%svcruntime%s.lib", lib_str, d_str);
1899 : 0 : lj->args.append(buf_ptr(vcruntime_lib_name));
1900 : :
1901 : 0 : Buf *crt_lib_name = buf_sprintf("%sucrt%s.lib", lib_str, d_str);
1902 : 0 : lj->args.append(buf_ptr(crt_lib_name));
1903 : :
1904 : : //Visual C++ 2015 Conformance Changes
1905 : : //https://msdn.microsoft.com/en-us/library/bb531344.aspx
1906 : 0 : lj->args.append("legacy_stdio_definitions.lib");
1907 : :
1908 : : // msvcrt depends on kernel32 and ntdll
1909 : 0 : lj->args.append("kernel32.lib");
1910 : 0 : lj->args.append("ntdll.lib");
1911 : 0 : }
1912 : :
1913 : 0 : static void print_zig_cc_cmd(ZigList<const char *> *args) {
1914 [ # # ]: 0 : for (size_t arg_i = 0; arg_i < args->length; arg_i += 1) {
1915 [ # # ]: 0 : const char *space_str = (arg_i == 0) ? "" : " ";
1916 : 0 : fprintf(stderr, "%s%s", space_str, args->at(arg_i));
1917 : : }
1918 : 0 : fprintf(stderr, "\n");
1919 : 0 : }
1920 : :
1921 : 0 : static const char *get_def_lib(CodeGen *parent, const char *name, Buf *def_in_rel_path) {
1922 : : Error err;
1923 : :
1924 : 0 : Buf *self_exe_path = buf_alloc();
1925 [ # # ]: 0 : if ((err = os_self_exe_path(self_exe_path))) {
1926 : 0 : fprintf(stderr, "Unable to get self exe path: %s\n", err_str(err));
1927 : 0 : exit(1);
1928 : : }
1929 : : Buf *compiler_id;
1930 [ # # ]: 0 : if ((err = get_compiler_id(&compiler_id))) {
1931 : 0 : fprintf(stderr, "Unable to get compiler id: %s\n", err_str(err));
1932 : 0 : exit(1);
1933 : : }
1934 : :
1935 : 0 : Buf *cache_dir = get_stage1_cache_path();
1936 : 0 : Buf *o_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR, buf_ptr(cache_dir));
1937 : 0 : Buf *manifest_dir = buf_sprintf("%s" OS_SEP CACHE_HASH_SUBDIR, buf_ptr(cache_dir));
1938 : :
1939 : 0 : Buf *def_in_file = buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s",
1940 : 0 : buf_ptr(parent->zig_lib_dir), buf_ptr(def_in_rel_path));
1941 : 0 : Buf *def_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "def-include",
1942 : 0 : buf_ptr(parent->zig_lib_dir));
1943 : :
1944 : 0 : CacheHash *cache_hash = allocate<CacheHash>(1);
1945 : 0 : cache_init(cache_hash, manifest_dir);
1946 : :
1947 : 0 : cache_buf(cache_hash, compiler_id);
1948 : 0 : cache_file(cache_hash, def_in_file);
1949 : 0 : cache_buf(cache_hash, def_include_dir);
1950 : 0 : cache_int(cache_hash, parent->zig_target->arch);
1951 : :
1952 : 0 : Buf digest = BUF_INIT;
1953 : 0 : buf_resize(&digest, 0);
1954 [ # # ]: 0 : if ((err = cache_hit(cache_hash, &digest))) {
1955 [ # # ]: 0 : if (err != ErrorInvalidFormat) {
1956 [ # # ]: 0 : if (err == ErrorCacheUnavailable) {
1957 : : // already printed error
1958 : : } else {
1959 : 0 : fprintf(stderr, "unable to check cache when processing .def.in file: %s\n", err_str(err));
1960 : : }
1961 : 0 : exit(1);
1962 : : }
1963 : : }
1964 : :
1965 : : Buf *artifact_dir;
1966 : : Buf *lib_final_path;
1967 : 0 : Buf *final_lib_basename = buf_sprintf("%s.lib", name);
1968 : :
1969 : 0 : bool is_cache_miss = (buf_len(&digest) == 0);
1970 [ # # ]: 0 : if (is_cache_miss) {
1971 [ # # ]: 0 : if ((err = cache_final(cache_hash, &digest))) {
1972 : 0 : fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err));
1973 : 0 : exit(1);
1974 : : }
1975 : 0 : artifact_dir = buf_alloc();
1976 : 0 : os_path_join(o_dir, &digest, artifact_dir);
1977 [ # # ]: 0 : if ((err = os_make_path(artifact_dir))) {
1978 : 0 : fprintf(stderr, "Unable to create output directory '%s': %s",
1979 : : buf_ptr(artifact_dir), err_str(err));
1980 : 0 : exit(1);
1981 : : }
1982 : 0 : Buf *final_def_basename = buf_sprintf("%s.def", name);
1983 : 0 : Buf *def_final_path = buf_alloc();
1984 : 0 : os_path_join(artifact_dir, final_def_basename, def_final_path);
1985 : :
1986 : 0 : ZigList<const char *> args = {};
1987 : 0 : args.append(buf_ptr(self_exe_path));
1988 : 0 : args.append("cc");
1989 : 0 : args.append("-x");
1990 : 0 : args.append("c");
1991 : 0 : args.append(buf_ptr(def_in_file));
1992 : 0 : args.append("-Wp,-w");
1993 : 0 : args.append("-undef");
1994 : 0 : args.append("-P");
1995 : 0 : args.append("-I");
1996 : 0 : args.append(buf_ptr(def_include_dir));
1997 [ # # ]: 0 : if (target_is_arm(parent->zig_target)) {
1998 [ # # ]: 0 : if (target_arch_pointer_bit_width(parent->zig_target->arch) == 32) {
1999 : 0 : args.append("-DDEF_ARM32");
2000 : : } else {
2001 : 0 : args.append("-DDEF_ARM64");
2002 : : }
2003 [ # # ]: 0 : } else if (parent->zig_target->arch == ZigLLVM_x86) {
2004 : 0 : args.append("-DDEF_I386");
2005 [ # # ]: 0 : } else if (parent->zig_target->arch == ZigLLVM_x86_64) {
2006 : 0 : args.append("-DDEF_X64");
2007 : : } else {
2008 : 0 : zig_unreachable();
2009 : : }
2010 : 0 : args.append("-E");
2011 : 0 : args.append("-o");
2012 : 0 : args.append(buf_ptr(def_final_path));
2013 : :
2014 [ # # ]: 0 : if (parent->verbose_cc) {
2015 : 0 : print_zig_cc_cmd(&args);
2016 : : }
2017 : : Termination term;
2018 : 0 : os_spawn_process(args, &term);
2019 [ # # ][ # # ]: 0 : if (term.how != TerminationIdClean || term.code != 0) {
2020 : 0 : fprintf(stderr, "\nThe following command failed:\n");
2021 : 0 : print_zig_cc_cmd(&args);
2022 : 0 : exit(1);
2023 : : }
2024 : :
2025 : 0 : lib_final_path = buf_alloc();
2026 : 0 : os_path_join(artifact_dir, final_lib_basename, lib_final_path);
2027 : :
2028 : 0 : args.resize(0);
2029 : 0 : args.append("link");
2030 : 0 : coff_append_machine_arg(parent, &args);
2031 : :
2032 : 0 : args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_final_path))));
2033 : 0 : args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(lib_final_path))));
2034 : :
2035 : 0 : Buf diag = BUF_INIT;
2036 : 0 : ZigLLVM_ObjectFormatType target_ofmt = target_object_format(parent->zig_target);
2037 [ # # ]: 0 : if (!zig_lld_link(target_ofmt, args.items, args.length, &diag)) {
2038 : 0 : fprintf(stderr, "%s\n", buf_ptr(&diag));
2039 : 0 : exit(1);
2040 : : }
2041 : : } else {
2042 : : // cache hit
2043 : 0 : artifact_dir = buf_alloc();
2044 : 0 : os_path_join(o_dir, &digest, artifact_dir);
2045 : 0 : lib_final_path = buf_alloc();
2046 : 0 : os_path_join(artifact_dir, final_lib_basename, lib_final_path);
2047 : : }
2048 : 0 : parent->caches_to_release.append(cache_hash);
2049 : :
2050 : 0 : return buf_ptr(lib_final_path);
2051 : : }
2052 : :
2053 : 0 : static bool is_linking_system_lib(CodeGen *g, const char *name) {
2054 [ # # ]: 0 : for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) {
2055 : 0 : LinkLib *link_lib = g->link_libs_list.at(lib_i);
2056 [ # # ]: 0 : if (buf_eql_str(link_lib->name, name)) {
2057 : 0 : return true;
2058 : : }
2059 : : }
2060 : 0 : return false;
2061 : : }
2062 : :
2063 : 0 : static void add_mingw_link_args(LinkJob *lj, bool is_library) {
2064 : 0 : CodeGen *g = lj->codegen;
2065 : :
2066 : 0 : lj->args.append("-lldmingw");
2067 : :
2068 [ # # ][ # # ]: 0 : bool is_dll = g->out_type == OutTypeLib && g->is_dynamic;
2069 : :
2070 [ # # ]: 0 : if (g->zig_target->arch == ZigLLVM_x86) {
2071 : 0 : lj->args.append("-ALTERNATENAME:__image_base__=___ImageBase");
2072 : : } else {
2073 : 0 : lj->args.append("-ALTERNATENAME:__image_base__=__ImageBase");
2074 : : }
2075 : :
2076 [ # # ]: 0 : if (is_dll) {
2077 : 0 : lj->args.append(get_libc_crt_file(g, "dllcrt2.o"));
2078 : : } else {
2079 : 0 : lj->args.append(get_libc_crt_file(g, "crt2.o"));
2080 : : }
2081 : :
2082 : 0 : lj->args.append(get_libc_crt_file(g, "mingw32.lib"));
2083 : 0 : lj->args.append(get_libc_crt_file(g, "mingwex.lib"));
2084 : 0 : lj->args.append(get_libc_crt_file(g, "msvcrt-os.lib"));
2085 : :
2086 [ # # ]: 0 : for (size_t def_i = 0; def_i < array_length(mingw_def_list); def_i += 1) {
2087 : 0 : const char *name = mingw_def_list[def_i].name;
2088 : 0 : Buf *path = buf_create_from_str(mingw_def_list[def_i].path);
2089 : 0 : bool always_link = mingw_def_list[def_i].always_link;
2090 : 0 : bool is_this_arch = false;
2091 [ # # ]: 0 : if (buf_starts_with_str(path, "lib-common" OS_SEP)) {
2092 : 0 : is_this_arch = true;
2093 [ # # ]: 0 : } else if (target_is_arm(g->zig_target)) {
2094 [ # # ]: 0 : if (target_arch_pointer_bit_width(g->zig_target->arch) == 32) {
2095 : 0 : is_this_arch = buf_starts_with_str(path, "libarm32" OS_SEP);
2096 : : } else {
2097 : 0 : is_this_arch = buf_starts_with_str(path, "libarm64" OS_SEP);
2098 : : }
2099 [ # # ]: 0 : } else if (g->zig_target->arch == ZigLLVM_x86) {
2100 : 0 : is_this_arch = buf_starts_with_str(path, "lib32" OS_SEP);
2101 [ # # ]: 0 : } else if (g->zig_target->arch == ZigLLVM_x86_64) {
2102 : 0 : is_this_arch = buf_starts_with_str(path, "lib64" OS_SEP);
2103 : : }
2104 [ # # ][ # # ]: 0 : if (is_this_arch && (always_link || is_linking_system_lib(g, name))) {
[ # # ][ # # ]
2105 : 0 : lj->args.append(get_def_lib(g, name, path));
2106 : : }
2107 : : }
2108 : 0 : }
2109 : :
2110 : 2 : static void add_win_link_args(LinkJob *lj, bool is_library, bool *have_windows_dll_import_libs) {
2111 [ - + ]: 2 : if (lj->link_in_crt) {
2112 [ # # ]: 0 : if (target_abi_is_gnu(lj->codegen->zig_target->abi)) {
2113 : 0 : *have_windows_dll_import_libs = true;
2114 : 0 : add_mingw_link_args(lj, is_library);
2115 : : } else {
2116 : 0 : add_msvc_link_args(lj, is_library);
2117 : : }
2118 : : } else {
2119 : 2 : lj->args.append("-NODEFAULTLIB");
2120 [ + - ]: 2 : if (!is_library) {
2121 [ - + ]: 2 : if (lj->codegen->have_winmain) {
2122 : 0 : lj->args.append("-ENTRY:WinMain");
2123 : : } else {
2124 : 2 : lj->args.append("-ENTRY:WinMainCRTStartup");
2125 : : }
2126 : : }
2127 : : }
2128 : 2 : }
2129 : :
2130 : 4 : static bool is_mingw_link_lib(Buf *name) {
2131 [ + - ]: 62 : for (size_t def_i = 0; def_i < array_length(mingw_def_list); def_i += 1) {
2132 [ + + ]: 62 : if (buf_eql_str_ignore_case(name, mingw_def_list[def_i].name)) {
2133 : 4 : return true;
2134 : : }
2135 : : }
2136 : 0 : return false;
2137 : : }
2138 : 2 : static void construct_linker_job_coff(LinkJob *lj) {
2139 : : Error err;
2140 : 2 : CodeGen *g = lj->codegen;
2141 : :
2142 : 2 : lj->args.append("-ERRORLIMIT:0");
2143 : :
2144 : 2 : lj->args.append("-NOLOGO");
2145 : :
2146 [ + - ]: 2 : if (!g->strip_debug_symbols) {
2147 : 2 : lj->args.append("-DEBUG");
2148 : : }
2149 : :
2150 [ + - ]: 2 : if (g->out_type == OutTypeExe) {
2151 : : // TODO compile time stack upper bound detection
2152 : 2 : lj->args.append("-STACK:16777216");
2153 : : }
2154 : :
2155 : 2 : coff_append_machine_arg(g, &lj->args);
2156 : :
2157 : 2 : bool is_library = g->out_type == OutTypeLib;
2158 [ # # ][ - + ]: 2 : if (is_library && g->is_dynamic) {
2159 : 0 : lj->args.append("-DLL");
2160 : : }
2161 : :
2162 : 2 : lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path))));
2163 : :
2164 [ # # ][ - + ]: 2 : if (g->libc_link_lib != nullptr && g->libc != nullptr) {
2165 : 0 : lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->crt_dir))));
2166 : :
2167 [ # # ]: 0 : if (target_abi_is_gnu(g->zig_target->abi)) {
2168 : 0 : lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->sys_include_dir))));
2169 : 0 : lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->include_dir))));
2170 : : } else {
2171 : 0 : lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->msvc_lib_dir))));
2172 : 0 : lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->kernel32_lib_dir))));
2173 : : }
2174 : : }
2175 : :
2176 [ - + ]: 2 : for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
2177 : 0 : const char *lib_dir = g->lib_dirs.at(i);
2178 : 0 : lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir)));
2179 : : }
2180 : :
2181 [ + + ]: 4 : for (size_t i = 0; i < g->link_objects.length; i += 1) {
2182 : 2 : lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
2183 : : }
2184 : :
2185 : 2 : bool have_windows_dll_import_libs = false;
2186 [ - + - - : 2 : switch (detect_subsystem(g)) {
- - - - -
- ]
2187 : 0 : case TargetSubsystemAuto:
2188 [ # # ]: 0 : if (g->zig_target->os == OsUefi) {
2189 : 0 : add_uefi_link_args(lj);
2190 : : } else {
2191 : 0 : add_win_link_args(lj, is_library, &have_windows_dll_import_libs);
2192 : : }
2193 : 0 : break;
2194 : 2 : case TargetSubsystemConsole:
2195 : 2 : lj->args.append("-SUBSYSTEM:console");
2196 : 2 : add_win_link_args(lj, is_library, &have_windows_dll_import_libs);
2197 : 2 : break;
2198 : 0 : case TargetSubsystemEfiApplication:
2199 : 0 : lj->args.append("-SUBSYSTEM:efi_application");
2200 : 0 : add_uefi_link_args(lj);
2201 : 0 : break;
2202 : 0 : case TargetSubsystemEfiBootServiceDriver:
2203 : 0 : lj->args.append("-SUBSYSTEM:efi_boot_service_driver");
2204 : 0 : add_uefi_link_args(lj);
2205 : 0 : break;
2206 : 0 : case TargetSubsystemEfiRom:
2207 : 0 : lj->args.append("-SUBSYSTEM:efi_rom");
2208 : 0 : add_uefi_link_args(lj);
2209 : 0 : break;
2210 : 0 : case TargetSubsystemEfiRuntimeDriver:
2211 : 0 : lj->args.append("-SUBSYSTEM:efi_runtime_driver");
2212 : 0 : add_uefi_link_args(lj);
2213 : 0 : break;
2214 : 0 : case TargetSubsystemNative:
2215 : 0 : lj->args.append("-SUBSYSTEM:native");
2216 : 0 : add_win_link_args(lj, is_library, &have_windows_dll_import_libs);
2217 : 0 : break;
2218 : 0 : case TargetSubsystemPosix:
2219 : 0 : lj->args.append("-SUBSYSTEM:posix");
2220 : 0 : add_win_link_args(lj, is_library, &have_windows_dll_import_libs);
2221 : 0 : break;
2222 : 0 : case TargetSubsystemWindows:
2223 : 0 : lj->args.append("-SUBSYSTEM:windows");
2224 : 0 : add_win_link_args(lj, is_library, &have_windows_dll_import_libs);
2225 : 0 : break;
2226 : : }
2227 : :
2228 [ - + ][ # # ]: 2 : if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) {
[ # # ]
2229 [ + - ][ + - ]: 2 : if (g->libc_link_lib == nullptr && !g->is_dummy_so) {
2230 : 2 : Buf *libc_a_path = build_c(g, OutTypeLib);
2231 : 2 : lj->args.append(buf_ptr(libc_a_path));
2232 : : }
2233 : :
2234 : : // msvc compiler_rt is missing some stuff, so we still build it and rely on weak linkage
2235 : 2 : Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
2236 : 2 : lj->args.append(buf_ptr(compiler_rt_o_path));
2237 : : }
2238 : :
2239 : 2 : Buf *def_contents = buf_alloc();
2240 : 2 : ZigList<const char *> gen_lib_args = {0};
2241 [ + + ]: 6 : for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) {
2242 : 4 : LinkLib *link_lib = g->link_libs_list.at(lib_i);
2243 [ - + ]: 4 : if (buf_eql_str(link_lib->name, "c")) {
2244 : 0 : continue;
2245 : : }
2246 : 4 : bool is_sys_lib = is_mingw_link_lib(link_lib->name);
2247 [ # # ][ - + ]: 4 : if (have_windows_dll_import_libs && is_sys_lib) {
2248 : 0 : continue;
2249 : : }
2250 : : // If we're linking in the CRT or the libs are provided explictly we don't want to generate def/libs
2251 [ - + ][ # # ]: 4 : if ((lj->link_in_crt && is_sys_lib) || link_lib->provided_explicitly) {
[ - + ]
2252 [ # # ]: 0 : if (target_abi_is_gnu(lj->codegen->zig_target->abi)) {
2253 : 0 : Buf* lib_name = buf_sprintf("lib%s.a", buf_ptr(link_lib->name));
2254 : 0 : lj->args.append(buf_ptr(lib_name));
2255 : : }
2256 : : else {
2257 : 0 : Buf* lib_name = buf_sprintf("%s.lib", buf_ptr(link_lib->name));
2258 : 0 : lj->args.append(buf_ptr(lib_name));
2259 : : }
2260 : 0 : continue;
2261 : : }
2262 : :
2263 : 4 : buf_resize(def_contents, 0);
2264 : 4 : buf_appendf(def_contents, "LIBRARY %s\nEXPORTS\n", buf_ptr(link_lib->name));
2265 [ + + ]: 54 : for (size_t exp_i = 0; exp_i < link_lib->symbols.length; exp_i += 1) {
2266 : 50 : Buf *symbol_name = link_lib->symbols.at(exp_i);
2267 : 50 : buf_appendf(def_contents, "%s\n", buf_ptr(symbol_name));
2268 : : }
2269 : 4 : buf_appendf(def_contents, "\n");
2270 : :
2271 : 4 : Buf *def_path = buf_alloc();
2272 : 4 : os_path_join(g->output_dir, buf_sprintf("%s.def", buf_ptr(link_lib->name)), def_path);
2273 [ - + ]: 4 : if ((err = os_write_file(def_path, def_contents))) {
2274 : 0 : zig_panic("error writing def file: %s", err_str(err));
2275 : : }
2276 : :
2277 : 4 : Buf *generated_lib_path = buf_alloc();
2278 : 4 : os_path_join(g->output_dir, buf_sprintf("%s.lib", buf_ptr(link_lib->name)), generated_lib_path);
2279 : :
2280 : 4 : gen_lib_args.resize(0);
2281 : 4 : gen_lib_args.append("link");
2282 : :
2283 : 4 : coff_append_machine_arg(g, &gen_lib_args);
2284 : 4 : gen_lib_args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path))));
2285 : 4 : gen_lib_args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(generated_lib_path))));
2286 : 4 : Buf diag = BUF_INIT;
2287 : 4 : ZigLLVM_ObjectFormatType target_ofmt = target_object_format(g->zig_target);
2288 [ - + ]: 4 : if (!zig_lld_link(target_ofmt, gen_lib_args.items, gen_lib_args.length, &diag)) {
2289 : 0 : fprintf(stderr, "%s\n", buf_ptr(&diag));
2290 : 0 : exit(1);
2291 : : }
2292 : 4 : lj->args.append(buf_ptr(generated_lib_path));
2293 : : }
2294 : 2 : }
2295 : :
2296 : :
2297 : : // Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the
2298 : : // grouped values as integers. Numbers which are not provided are set to 0.
2299 : : // return true if the entire string was parsed (9.2), or all groups were
2300 : : // parsed (10.3.5extrastuff).
2301 : 2 : static bool darwin_get_release_version(const char *str, int *major, int *minor, int *micro, bool *had_extra) {
2302 : 2 : *had_extra = false;
2303 : :
2304 : 2 : *major = 0;
2305 : 2 : *minor = 0;
2306 : 2 : *micro = 0;
2307 : :
2308 [ - + ]: 2 : if (*str == '\0')
2309 : 0 : return false;
2310 : :
2311 : : char *end;
2312 : 2 : *major = (int)strtol(str, &end, 10);
2313 [ - + ][ + - ]: 2 : if (*str != '\0' && *end == '\0')
2314 : 0 : return true;
2315 [ - + ]: 2 : if (*end != '.')
2316 : 0 : return false;
2317 : :
2318 : 2 : str = end + 1;
2319 : 2 : *minor = (int)strtol(str, &end, 10);
2320 [ + - ][ + - ]: 2 : if (*str != '\0' && *end == '\0')
2321 : 2 : return true;
2322 [ # # ]: 0 : if (*end != '.')
2323 : 0 : return false;
2324 : :
2325 : 0 : str = end + 1;
2326 : 0 : *micro = (int)strtol(str, &end, 10);
2327 [ # # ][ # # ]: 0 : if (*str != '\0' && *end == '\0')
2328 : 0 : return true;
2329 [ # # ]: 0 : if (str == end)
2330 : 0 : return false;
2331 : 0 : *had_extra = true;
2332 : 2 : return true;
2333 : : }
2334 : :
2335 : : enum DarwinPlatformKind {
2336 : : MacOS,
2337 : : IPhoneOS,
2338 : : IPhoneOSSimulator,
2339 : : };
2340 : :
2341 : : struct DarwinPlatform {
2342 : : DarwinPlatformKind kind;
2343 : : int major;
2344 : : int minor;
2345 : : int micro;
2346 : : };
2347 : :
2348 : 2 : static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) {
2349 : 2 : CodeGen *g = lj->codegen;
2350 : :
2351 [ - + ]: 2 : if (g->mmacosx_version_min) {
2352 : 0 : platform->kind = MacOS;
2353 [ - + ]: 2 : } else if (g->mios_version_min) {
2354 : 0 : platform->kind = IPhoneOS;
2355 [ + - ]: 2 : } else if (g->zig_target->os == OsMacOSX) {
2356 : 2 : platform->kind = MacOS;
2357 : 2 : g->mmacosx_version_min = buf_create_from_str("10.14");
2358 : : } else {
2359 : 0 : zig_panic("unable to infer -mmacosx-version-min or -mios-version-min");
2360 : : }
2361 : :
2362 : : bool had_extra;
2363 [ + - ]: 2 : if (platform->kind == MacOS) {
2364 [ - + ]: 4 : if (!darwin_get_release_version(buf_ptr(g->mmacosx_version_min),
2365 [ + - ]: 2 : &platform->major, &platform->minor, &platform->micro, &had_extra) ||
2366 [ + - ][ + - ]: 4 : had_extra || platform->major != 10 || platform->minor >= 100 || platform->micro >= 100)
[ - + ][ + - ]
2367 : : {
2368 : 0 : zig_panic("invalid -mmacosx-version-min");
2369 : : }
2370 [ # # ]: 0 : } else if (platform->kind == IPhoneOS) {
2371 [ # # ]: 0 : if (!darwin_get_release_version(buf_ptr(g->mios_version_min),
2372 [ # # ]: 0 : &platform->major, &platform->minor, &platform->micro, &had_extra) ||
2373 [ # # ][ # # ]: 0 : had_extra || platform->major >= 10 || platform->minor >= 100 || platform->micro >= 100)
[ # # ][ # # ]
2374 : : {
2375 : 0 : zig_panic("invalid -mios-version-min");
2376 : : }
2377 : : } else {
2378 : 0 : zig_unreachable();
2379 : : }
2380 : :
2381 [ - + ][ # # ]: 2 : if (platform->kind == IPhoneOS &&
2382 [ # # ]: 0 : (g->zig_target->arch == ZigLLVM_x86 ||
2383 : 0 : g->zig_target->arch == ZigLLVM_x86_64))
2384 : : {
2385 : 0 : platform->kind = IPhoneOSSimulator;
2386 : : }
2387 : 2 : }
2388 : :
2389 : 2 : static void construct_linker_job_macho(LinkJob *lj) {
2390 : 2 : CodeGen *g = lj->codegen;
2391 : :
2392 : : // LLD MACH-O has no error limit option.
2393 : : //lj->args.append("-error-limit=0");
2394 : 2 : lj->args.append("-demangle");
2395 : :
2396 [ - + ]: 2 : if (g->linker_rdynamic) {
2397 : 0 : lj->args.append("-export_dynamic");
2398 : : }
2399 : :
2400 : 2 : bool is_lib = g->out_type == OutTypeLib;
2401 [ - + ][ # # ]: 2 : bool is_dyn_lib = g->is_dynamic && is_lib;
2402 [ - + ][ # # ]: 2 : if (is_lib && !g->is_dynamic) {
2403 : 0 : lj->args.append("-static");
2404 : : } else {
2405 : 2 : lj->args.append("-dynamic");
2406 : : }
2407 : :
2408 [ - + ]: 2 : if (is_dyn_lib) {
2409 : 0 : lj->args.append("-dylib");
2410 : :
2411 : 0 : Buf *compat_vers = buf_sprintf("%" ZIG_PRI_usize ".0.0", g->version_major);
2412 : 0 : lj->args.append("-compatibility_version");
2413 : 0 : lj->args.append(buf_ptr(compat_vers));
2414 : :
2415 : 0 : Buf *cur_vers = buf_sprintf("%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize,
2416 : 0 : g->version_major, g->version_minor, g->version_patch);
2417 : 0 : lj->args.append("-current_version");
2418 : 0 : lj->args.append(buf_ptr(cur_vers));
2419 : :
2420 : : // TODO getting an error when running an executable when doing this rpath thing
2421 : : //Buf *dylib_install_name = buf_sprintf("@rpath/lib%s.%" ZIG_PRI_usize ".dylib",
2422 : : // buf_ptr(g->root_out_name), g->version_major);
2423 : : //lj->args.append("-install_name");
2424 : : //lj->args.append(buf_ptr(dylib_install_name));
2425 : :
2426 : 0 : assert(buf_len(&g->output_file_path) != 0);
2427 : : }
2428 : :
2429 : 2 : lj->args.append("-arch");
2430 : 2 : lj->args.append(get_darwin_arch_string(g->zig_target));
2431 : :
2432 : : DarwinPlatform platform;
2433 : 2 : get_darwin_platform(lj, &platform);
2434 [ + - - - ]: 2 : switch (platform.kind) {
2435 : 2 : case MacOS:
2436 : 2 : lj->args.append("-macosx_version_min");
2437 : 2 : break;
2438 : 0 : case IPhoneOS:
2439 : 0 : lj->args.append("-iphoneos_version_min");
2440 : 0 : break;
2441 : 0 : case IPhoneOSSimulator:
2442 : 0 : lj->args.append("-ios_simulator_version_min");
2443 : 0 : break;
2444 : : }
2445 : 2 : Buf *version_string = buf_sprintf("%d.%d.%d", platform.major, platform.minor, platform.micro);
2446 : 2 : lj->args.append(buf_ptr(version_string));
2447 : :
2448 : 2 : lj->args.append("-sdk_version");
2449 : 2 : lj->args.append(buf_ptr(version_string));
2450 : :
2451 : :
2452 [ + - ]: 2 : if (g->out_type == OutTypeExe) {
2453 : 2 : lj->args.append("-pie");
2454 : : }
2455 : :
2456 : 2 : lj->args.append("-o");
2457 : 2 : lj->args.append(buf_ptr(&g->output_file_path));
2458 : :
2459 [ - + ]: 2 : for (size_t i = 0; i < g->rpath_list.length; i += 1) {
2460 : 0 : Buf *rpath = g->rpath_list.at(i);
2461 : 0 : add_rpath(lj, rpath);
2462 : : }
2463 [ - + ]: 2 : if (is_dyn_lib) {
2464 : 0 : add_rpath(lj, &g->output_file_path);
2465 : : }
2466 : :
2467 [ - + ]: 2 : if (is_dyn_lib) {
2468 [ # # ]: 0 : if (g->system_linker_hack) {
2469 : 0 : lj->args.append("-headerpad_max_install_names");
2470 : : }
2471 : : }
2472 : :
2473 [ - + ]: 2 : for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
2474 : 0 : const char *lib_dir = g->lib_dirs.at(i);
2475 : 0 : lj->args.append("-L");
2476 : 0 : lj->args.append(lib_dir);
2477 : : }
2478 : :
2479 [ + + ]: 4 : for (size_t i = 0; i < g->link_objects.length; i += 1) {
2480 : 2 : lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
2481 : : }
2482 : :
2483 : : // compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce
2484 [ - + ][ # # ]: 2 : if (g->out_type == OutTypeExe || is_dyn_lib) {
2485 : 2 : Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
2486 : 2 : lj->args.append(buf_ptr(compiler_rt_o_path));
2487 : : }
2488 : :
2489 [ - + ]: 2 : if (g->zig_target->is_native) {
2490 [ # # ]: 0 : for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) {
2491 : 0 : LinkLib *link_lib = g->link_libs_list.at(lib_i);
2492 [ # # ]: 0 : if (target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name))) {
2493 : : // handled by libSystem
2494 : 0 : continue;
2495 : : }
2496 [ # # ]: 0 : if (strchr(buf_ptr(link_lib->name), '/') == nullptr) {
2497 : 0 : Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name));
2498 : 0 : lj->args.append(buf_ptr(arg));
2499 : : } else {
2500 : 0 : lj->args.append(buf_ptr(link_lib->name));
2501 : : }
2502 : : }
2503 : : // on Darwin, libSystem has libc in it, but also you have to use it
2504 : : // to make syscalls because the syscall numbers are not documented
2505 : : // and change between versions.
2506 : : // so we always link against libSystem
2507 : 0 : lj->args.append("-lSystem");
2508 : : } else {
2509 : 2 : lj->args.append("-undefined");
2510 : 2 : lj->args.append("dynamic_lookup");
2511 : : }
2512 : :
2513 [ - + ]: 2 : for (size_t i = 0; i < g->framework_dirs.length; i += 1) {
2514 : 0 : const char *framework_dir = g->framework_dirs.at(i);
2515 : 0 : lj->args.append("-F");
2516 : 0 : lj->args.append(framework_dir);
2517 : : }
2518 : :
2519 [ - + ]: 2 : for (size_t i = 0; i < g->darwin_frameworks.length; i += 1) {
2520 : 0 : lj->args.append("-framework");
2521 : 0 : lj->args.append(buf_ptr(g->darwin_frameworks.at(i)));
2522 : : }
2523 : :
2524 : 2 : }
2525 : :
2526 : 15 : static void construct_linker_job(LinkJob *lj) {
2527 [ - + + + : 15 : switch (target_object_format(lj->codegen->zig_target)) {
- - ]
2528 : 0 : case ZigLLVM_UnknownObjectFormat:
2529 : 0 : zig_unreachable();
2530 : :
2531 : 2 : case ZigLLVM_COFF:
2532 : 2 : return construct_linker_job_coff(lj);
2533 : 11 : case ZigLLVM_ELF:
2534 : 11 : return construct_linker_job_elf(lj);
2535 : 2 : case ZigLLVM_MachO:
2536 : 2 : return construct_linker_job_macho(lj);
2537 : 0 : case ZigLLVM_Wasm:
2538 : 0 : return construct_linker_job_wasm(lj);
2539 : : }
2540 : : }
2541 : :
2542 : 0 : void zig_link_add_compiler_rt(CodeGen *g) {
2543 : 0 : Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj);
2544 : 0 : g->link_objects.append(compiler_rt_o_path);
2545 : 0 : }
2546 : :
2547 : 24 : void codegen_link(CodeGen *g) {
2548 : 24 : codegen_add_time_event(g, "Build Dependencies");
2549 : :
2550 : 24 : LinkJob lj = {0};
2551 : :
2552 : : // even though we're calling LLD as a library it thinks the first
2553 : : // argument is its own exe name
2554 : 24 : lj.args.append("lld");
2555 : :
2556 : 24 : lj.rpath_table.init(4);
2557 : 24 : lj.codegen = g;
2558 : :
2559 [ - + ]: 24 : if (g->verbose_llvm_ir) {
2560 : 0 : fprintf(stderr, "\nOptimization:\n");
2561 : 0 : fprintf(stderr, "---------------\n");
2562 : 0 : fflush(stderr);
2563 : 0 : LLVMDumpModule(g->module);
2564 : : }
2565 : :
2566 [ + + ]: 24 : if (g->out_type == OutTypeObj) {
2567 : 1 : lj.args.append("-r");
2568 : : }
2569 : :
2570 [ + + ][ + + ]: 24 : if (g->out_type == OutTypeLib && !g->is_dynamic && !target_is_wasm(g->zig_target)) {
[ + - ][ + + ]
2571 : 9 : ZigList<const char *> file_names = {};
2572 [ + + ]: 46 : for (size_t i = 0; i < g->link_objects.length; i += 1) {
2573 : 37 : file_names.append(buf_ptr(g->link_objects.at(i)));
2574 : : }
2575 : 9 : ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target->os);
2576 : 9 : codegen_add_time_event(g, "LLVM Link");
2577 [ - + ]: 9 : if (g->verbose_link) {
2578 : 0 : fprintf(stderr, "ar rcs %s", buf_ptr(&g->output_file_path));
2579 [ # # ]: 0 : for (size_t i = 0; i < file_names.length; i += 1) {
2580 : 0 : fprintf(stderr, " %s", file_names.at(i));
2581 : : }
2582 : 0 : fprintf(stderr, "\n");
2583 : : }
2584 [ - + ]: 9 : if (ZigLLVMWriteArchive(buf_ptr(&g->output_file_path), file_names.items, file_names.length, os_type)) {
2585 : 0 : fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->output_file_path));
2586 : 0 : exit(1);
2587 : : }
2588 : 9 : return;
2589 : : }
2590 : :
2591 [ + + ][ + - ]: 15 : lj.link_in_crt = (g->libc_link_lib != nullptr && g->out_type == OutTypeExe);
2592 : :
2593 : 15 : construct_linker_job(&lj);
2594 : :
2595 : :
2596 [ - + ]: 15 : if (g->verbose_link) {
2597 [ # # ]: 0 : for (size_t i = 0; i < lj.args.length; i += 1) {
2598 [ # # ]: 0 : const char *space = (i != 0) ? " " : "";
2599 : 0 : fprintf(stderr, "%s%s", space, lj.args.at(i));
2600 : : }
2601 : 0 : fprintf(stderr, "\n");
2602 : : }
2603 : :
2604 : 15 : Buf diag = BUF_INIT;
2605 : :
2606 : 15 : codegen_add_time_event(g, "LLVM Link");
2607 [ # # ][ - + ]: 15 : if (g->system_linker_hack && g->zig_target->os == OsMacOSX) {
2608 : : Termination term;
2609 : 0 : ZigList<const char *> args = {};
2610 : 0 : args.append("ld");
2611 [ # # ]: 0 : for (size_t i = 1; i < lj.args.length; i += 1) {
2612 : 0 : args.append(lj.args.at(i));
2613 : : }
2614 : 0 : os_spawn_process(args, &term);
2615 [ # # ][ # # ]: 0 : if (term.how != TerminationIdClean || term.code != 0) {
2616 : 0 : exit(1);
2617 : 0 : }
2618 [ - + ]: 15 : } else if (!zig_lld_link(target_object_format(g->zig_target), lj.args.items, lj.args.length, &diag)) {
2619 : 0 : fprintf(stderr, "%s\n", buf_ptr(&diag));
2620 : 15 : exit(1);
2621 : : }
2622 : : }
2623 : :
|