authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-23 20:48:47-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-23 20:48:47-07:00
logb08fd0e8fca5ff9ac5531437f5749e74dc009a14
treee2fcc2a3a28e1ce90631542745d779c92b9356c0
parent64deb46859a11588fb97e8464ec9dae53124b96b

stage2: building musl libc from source


6 files changed, 426 insertions(+), 76 deletions(-)

BRANCH_TODO+4-2
......@@ -1,7 +1,6 @@
1 * musl
1 * repair @cImport
22 * tests passing with -Dskip-non-native
33 * windows CUSTOMBUILD : error : unable to build compiler_rt: FileNotFound [D:\a\1\s\build\zig_install_lib_files.vcxproj]
4 * repair @cImport
54 * make sure zig cc works
65 - using it as a preprocessor (-E)
76 - try building some software
......@@ -20,6 +19,7 @@
2019 * WASM LLD linking
2120 * skip LLD caching when bin directory is not in the cache (so we don't put `id.txt` into the cwd)
2221 (maybe make it an explicit option and have main.zig disable it)
22 - make sure that `zig cc -o hello hello.c -target native-native-musl` and `zig build-exe hello.zig -lc -target native-native-musl` will share the same libc build.
2323 * audit the CLI options for stage2
2424 * audit the base cache hash
2525 * On operating systems that support it, do an execve for `zig test` and `zig run` rather than child process.
......@@ -58,3 +58,5 @@
5858 * rename std.builtin.Mode to std.builtin.OptimizeMode
5959 * implement `zig run` and `zig test` when combined with `--watch`
6060 * close the --pkg-begin --pkg-end Package directory handles
61 * make std.Progress support multithreaded
62 * update musl.zig static data to use native path separator in static data rather than replacing '/' at runtime
lib/std/zig/system.zig+6
......@@ -393,6 +393,12 @@ pub const NativeTargetInfo = struct {
393393 if (!native_target_has_ld or have_all_info or os_is_non_native) {
394394 return defaultAbiAndDynamicLinker(cpu, os, cross_target);
395395 }
396 if (cross_target.abi) |abi| {
397 if (abi.isMusl()) {
398 // musl implies static linking.
399 return defaultAbiAndDynamicLinker(cpu, os, cross_target);
400 }
401 }
396402 // The current target's ABI cannot be relied on for this. For example, we may build the zig
397403 // compiler for target riscv64-linux-musl and provide a tarball for users to download.
398404 // A user could then run that zig compiler on riscv64-linux-gnu. This use case is well-defined
src/Compilation.zig+106-4
......@@ -15,6 +15,7 @@ const liveness = @import("liveness.zig");
1515const build_options = @import("build_options");
1616const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
1717const glibc = @import("glibc.zig");
18const musl = @import("musl.zig");
1819const libunwind = @import("libunwind.zig");
1920const libcxx = @import("libcxx.zig");
2021const fatal = @import("main.zig").fatal;
......@@ -140,6 +141,8 @@ const Job = union(enum) {
140141 glibc_crt_file: glibc.CRTFile,
141142 /// all of the glibc shared objects
142143 glibc_shared_objects,
144 /// one of the glibc static objects
145 musl_crt_file: musl.CRTFile,
143146 /// libunwind.a, usually needed when linking libc
144147 libunwind: void,
145148 libcxx: void,
......@@ -778,6 +781,18 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
778781 if (comp.wantBuildGLibCFromSource()) {
779782 try comp.addBuildingGLibCJobs();
780783 }
784 if (comp.wantBuildMuslFromSource()) {
785 try comp.work_queue.write(&[_]Job{
786 .{ .musl_crt_file = .crti_o },
787 .{ .musl_crt_file = .crtn_o },
788 .{ .musl_crt_file = .crt1_o },
789 .{ .musl_crt_file = .scrt1_o },
790 .{ .musl_crt_file = .libc_a },
791 });
792 }
793 if (comp.wantBuildMinGWW64FromSource()) {
794 @panic("TODO");
795 }
781796 if (comp.wantBuildLibUnwindFromSource()) {
782797 try comp.work_queue.writeItem(.{ .libunwind = {} });
783798 }
......@@ -822,6 +837,7 @@ pub fn destroy(self: *Compilation) void {
822837 {
823838 var it = self.crt_files.iterator();
824839 while (it.next()) |entry| {
840 gpa.free(entry.key);
825841 entry.value.deinit(gpa);
826842 }
827843 self.crt_files.deinit(gpa);
......@@ -1128,6 +1144,12 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void {
11281144 fatal("unable to build glibc shared objects: {}", .{@errorName(err)});
11291145 };
11301146 },
1147 .musl_crt_file => |crt_file| {
1148 musl.buildCRTFile(self, crt_file) catch |err| {
1149 // TODO Expose this as a normal compile error rather than crashing here.
1150 fatal("unable to build musl CRT file: {}", .{@errorName(err)});
1151 };
1152 },
11311153 .libunwind => {
11321154 libunwind.buildStaticLib(self) catch |err| {
11331155 // TODO Expose this as a normal compile error rather than crashing here.
......@@ -1846,7 +1868,10 @@ fn detectLibCFromLibCInstallation(arena: *Allocator, target: Target, lci: *const
18461868}
18471869
18481870pub fn get_libc_crt_file(comp: *Compilation, arena: *Allocator, basename: []const u8) ![]const u8 {
1849 if (comp.wantBuildGLibCFromSource()) {
1871 if (comp.wantBuildGLibCFromSource() or
1872 comp.wantBuildMuslFromSource() or
1873 comp.wantBuildMinGWW64FromSource())
1874 {
18501875 return comp.crt_files.get(basename).?.full_object_path;
18511876 }
18521877 const lci = comp.bin_file.options.libc_installation orelse return error.LibCInstallationNotAvailable;
......@@ -1865,15 +1890,26 @@ fn addBuildingGLibCJobs(comp: *Compilation) !void {
18651890 });
18661891}
18671892
1868fn wantBuildGLibCFromSource(comp: *Compilation) bool {
1893fn wantBuildLibCFromSource(comp: Compilation) bool {
18691894 const is_exe_or_dyn_lib = switch (comp.bin_file.options.output_mode) {
18701895 .Obj => false,
18711896 .Lib => comp.bin_file.options.link_mode == .Dynamic,
18721897 .Exe => true,
18731898 };
18741899 return comp.bin_file.options.link_libc and is_exe_or_dyn_lib and
1875 comp.bin_file.options.libc_installation == null and
1876 comp.bin_file.options.target.isGnuLibC();
1900 comp.bin_file.options.libc_installation == null;
1901}
1902
1903fn wantBuildGLibCFromSource(comp: Compilation) bool {
1904 return comp.wantBuildLibCFromSource() and comp.getTarget().isGnuLibC();
1905}
1906
1907fn wantBuildMuslFromSource(comp: Compilation) bool {
1908 return comp.wantBuildLibCFromSource() and comp.getTarget().isMusl();
1909}
1910
1911fn wantBuildMinGWW64FromSource(comp: Compilation) bool {
1912 return comp.wantBuildLibCFromSource() and comp.getTarget().isMinGW();
18771913}
18781914
18791915fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
......@@ -2362,3 +2398,69 @@ fn createStage1Pkg(
23622398 };
23632399 return child_pkg;
23642400}
2401
2402pub fn build_crt_file(
2403 comp: *Compilation,
2404 root_name: []const u8,
2405 output_mode: std.builtin.OutputMode,
2406 c_source_files: []const Compilation.CSourceFile,
2407) !void {
2408 const tracy = trace(@src());
2409 defer tracy.end();
2410
2411 const target = comp.getTarget();
2412 const basename = try std.zig.binNameAlloc(comp.gpa, root_name, target, output_mode, null, null);
2413 errdefer comp.gpa.free(basename);
2414
2415 // TODO: This is extracted into a local variable to work around a stage1 miscompilation.
2416 const emit_bin = Compilation.EmitLoc{
2417 .directory = null, // Put it in the cache directory.
2418 .basename = basename,
2419 };
2420 const sub_compilation = try Compilation.create(comp.gpa, .{
2421 .local_cache_directory = comp.global_cache_directory,
2422 .global_cache_directory = comp.global_cache_directory,
2423 .zig_lib_directory = comp.zig_lib_directory,
2424 .target = target,
2425 .root_name = root_name,
2426 .root_pkg = null,
2427 .output_mode = output_mode,
2428 .rand = comp.rand,
2429 .libc_installation = comp.bin_file.options.libc_installation,
2430 .emit_bin = emit_bin,
2431 .optimize_mode = comp.bin_file.options.optimize_mode,
2432 .want_sanitize_c = false,
2433 .want_stack_check = false,
2434 .want_valgrind = false,
2435 .want_pic = comp.bin_file.options.pic,
2436 .emit_h = null,
2437 .strip = comp.bin_file.options.strip,
2438 .is_native_os = comp.bin_file.options.is_native_os,
2439 .self_exe_path = comp.self_exe_path,
2440 .c_source_files = c_source_files,
2441 .verbose_cc = comp.verbose_cc,
2442 .verbose_link = comp.bin_file.options.verbose_link,
2443 .verbose_tokenize = comp.verbose_tokenize,
2444 .verbose_ast = comp.verbose_ast,
2445 .verbose_ir = comp.verbose_ir,
2446 .verbose_llvm_ir = comp.verbose_llvm_ir,
2447 .verbose_cimport = comp.verbose_cimport,
2448 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
2449 .clang_passthrough_mode = comp.clang_passthrough_mode,
2450 .is_compiler_rt_or_libc = true,
2451 });
2452 defer sub_compilation.destroy();
2453
2454 try sub_compilation.updateSubCompilation();
2455
2456 try comp.crt_files.ensureCapacity(comp.gpa, comp.crt_files.count() + 1);
2457 const artifact_path = if (sub_compilation.bin_file.options.directory.path) |p|
2458 try std.fs.path.join(comp.gpa, &[_][]const u8{ p, basename })
2459 else
2460 try comp.gpa.dupe(u8, basename);
2461
2462 comp.crt_files.putAssumeCapacityNoClobber(basename, .{
2463 .full_object_path = artifact_path,
2464 .lock = sub_compilation.bin_file.toOwnedLock(),
2465 });
2466}
src/glibc.zig+4-66
......@@ -274,7 +274,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
274274 "-g",
275275 "-Wa,--noexecstack",
276276 });
277 return build_crt_file(comp, "crti.o", .Obj, &[1]Compilation.CSourceFile{
277 return comp.build_crt_file("crti", .Obj, &[1]Compilation.CSourceFile{
278278 .{
279279 .src_path = try start_asm_path(comp, arena, "crti.S"),
280280 .extra_flags = args.items,
......@@ -292,7 +292,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
292292 "-g",
293293 "-Wa,--noexecstack",
294294 });
295 return build_crt_file(comp, "crtn.o", .Obj, &[1]Compilation.CSourceFile{
295 return comp.build_crt_file("crtn", .Obj, &[1]Compilation.CSourceFile{
296296 .{
297297 .src_path = try start_asm_path(comp, arena, "crtn.S"),
298298 .extra_flags = args.items,
......@@ -343,7 +343,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
343343 .extra_flags = args.items,
344344 };
345345 };
346 return build_crt_file(comp, "Scrt1.o", .Obj, &[_]Compilation.CSourceFile{ start_os, abi_note_o });
346 return comp.build_crt_file("Scrt1", .Obj, &[_]Compilation.CSourceFile{ start_os, abi_note_o });
347347 },
348348 .libc_nonshared_a => {
349349 const deps = [_][]const u8{
......@@ -433,7 +433,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
433433 .extra_flags = args.items,
434434 };
435435 }
436 return build_crt_file(comp, "libc_nonshared.a", .Lib, &c_source_files);
436 return comp.build_crt_file("c_nonshared", .Lib, &c_source_files);
437437 },
438438 }
439439}
......@@ -676,68 +676,6 @@ fn lib_path(comp: *Compilation, arena: *Allocator, sub_path: []const u8) ![]cons
676676 return path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, sub_path });
677677}
678678
679fn build_crt_file(
680 comp: *Compilation,
681 basename: []const u8,
682 output_mode: std.builtin.OutputMode,
683 c_source_files: []const Compilation.CSourceFile,
684) !void {
685 const tracy = trace(@src());
686 defer tracy.end();
687
688 // TODO: This is extracted into a local variable to work around a stage1 miscompilation.
689 const emit_bin = Compilation.EmitLoc{
690 .directory = null, // Put it in the cache directory.
691 .basename = basename,
692 };
693 const sub_compilation = try Compilation.create(comp.gpa, .{
694 .local_cache_directory = comp.global_cache_directory,
695 .global_cache_directory = comp.global_cache_directory,
696 .zig_lib_directory = comp.zig_lib_directory,
697 .target = comp.getTarget(),
698 .root_name = mem.split(basename, ".").next().?,
699 .root_pkg = null,
700 .output_mode = output_mode,
701 .rand = comp.rand,
702 .libc_installation = comp.bin_file.options.libc_installation,
703 .emit_bin = emit_bin,
704 .optimize_mode = comp.bin_file.options.optimize_mode,
705 .want_sanitize_c = false,
706 .want_stack_check = false,
707 .want_valgrind = false,
708 .want_pic = comp.bin_file.options.pic,
709 .emit_h = null,
710 .strip = comp.bin_file.options.strip,
711 .is_native_os = comp.bin_file.options.is_native_os,
712 .self_exe_path = comp.self_exe_path,
713 .c_source_files = c_source_files,
714 .verbose_cc = comp.verbose_cc,
715 .verbose_link = comp.bin_file.options.verbose_link,
716 .verbose_tokenize = comp.verbose_tokenize,
717 .verbose_ast = comp.verbose_ast,
718 .verbose_ir = comp.verbose_ir,
719 .verbose_llvm_ir = comp.verbose_llvm_ir,
720 .verbose_cimport = comp.verbose_cimport,
721 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
722 .clang_passthrough_mode = comp.clang_passthrough_mode,
723 .is_compiler_rt_or_libc = true,
724 });
725 defer sub_compilation.destroy();
726
727 try sub_compilation.updateSubCompilation();
728
729 try comp.crt_files.ensureCapacity(comp.gpa, comp.crt_files.count() + 1);
730 const artifact_path = if (sub_compilation.bin_file.options.directory.path) |p|
731 try path.join(comp.gpa, &[_][]const u8{ p, basename })
732 else
733 try comp.gpa.dupe(u8, basename);
734
735 comp.crt_files.putAssumeCapacityNoClobber(basename, .{
736 .full_object_path = artifact_path,
737 .lock = sub_compilation.bin_file.toOwnedLock(),
738 });
739}
740
741679pub const BuiltSharedObjects = struct {
742680 lock: Cache.Lock,
743681 dir_path: []u8,
src/link/Elf.zig+1-1
......@@ -1548,7 +1548,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
15481548 try argv.append(try comp.get_libc_crt_file(arena, "libc_nonshared.a"));
15491549 } else if (target.isMusl()) {
15501550 try argv.append(comp.libunwind_static_lib.?.full_object_path);
1551 try argv.append(comp.libc_static_lib.?.full_object_path);
1551 try argv.append(try comp.get_libc_crt_file(arena, "libc.a"));
15521552 } else if (self.base.options.link_libcpp) {
15531553 try argv.append(comp.libunwind_static_lib.?.full_object_path);
15541554 } else {
src/musl.zig+305-3
......@@ -1,6 +1,308 @@
1//! TODO build musl libc from source
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3const mem = std.mem;
4const path = std.fs.path;
5const assert = std.debug.assert;
26
3pub const src_files = [_][]const u8{
7const target_util = @import("target.zig");
8const Compilation = @import("Compilation.zig");
9const build_options = @import("build_options");
10const trace = @import("tracy.zig").trace;
11const Cache = @import("Cache.zig");
12const Package = @import("Package.zig");
13
14pub const CRTFile = enum {
15 crti_o,
16 crtn_o,
17 crt1_o,
18 scrt1_o,
19 libc_a,
20};
21
22pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
23 if (!build_options.have_llvm) {
24 return error.ZigCompilerNotBuiltWithLLVMExtensions;
25 }
26 const gpa = comp.gpa;
27 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
28 defer arena_allocator.deinit();
29 const arena = &arena_allocator.allocator;
30
31 switch (crt_file) {
32 .crti_o => {
33 var args = std.ArrayList([]const u8).init(arena);
34 try add_cc_args(comp, arena, &args, false);
35 try args.appendSlice(&[_][]const u8{
36 "-Qunused-arguments",
37 });
38 return comp.build_crt_file("crti", .Obj, &[1]Compilation.CSourceFile{
39 .{
40 .src_path = try start_asm_path(comp, arena, "crti.s"),
41 .extra_flags = args.items,
42 },
43 });
44 },
45 .crtn_o => {
46 var args = std.ArrayList([]const u8).init(arena);
47 try add_cc_args(comp, arena, &args, false);
48 try args.appendSlice(&[_][]const u8{
49 "-Qunused-arguments",
50 });
51 return comp.build_crt_file("crtn", .Obj, &[1]Compilation.CSourceFile{
52 .{
53 .src_path = try start_asm_path(comp, arena, "crtn.s"),
54 .extra_flags = args.items,
55 },
56 });
57 },
58 .crt1_o => {
59 var args = std.ArrayList([]const u8).init(arena);
60 try add_cc_args(comp, arena, &args, false);
61 try args.appendSlice(&[_][]const u8{
62 "-fno-stack-protector",
63 "-DCRT",
64 });
65 return comp.build_crt_file("crt1", .Obj, &[1]Compilation.CSourceFile{
66 .{
67 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
68 "libc", "musl", "crt", "crt1.c",
69 }),
70 .extra_flags = args.items,
71 },
72 });
73 },
74 .scrt1_o => {
75 var args = std.ArrayList([]const u8).init(arena);
76 try add_cc_args(comp, arena, &args, false);
77 try args.appendSlice(&[_][]const u8{
78 "-fPIC",
79 "-fno-stack-protector",
80 "-DCRT",
81 });
82 return comp.build_crt_file("Scrt1", .Obj, &[1]Compilation.CSourceFile{
83 .{
84 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
85 "libc", "musl", "crt", "Scrt1.c",
86 }),
87 .extra_flags = args.items,
88 },
89 });
90 },
91 .libc_a => {
92 // When there is a src/<arch>/foo.* then it should substitute for src/foo.*
93 // Even a .s file can substitute for a .c file.
94 const target = comp.getTarget();
95 const arch_name = target_util.archMuslName(target.cpu.arch);
96 var source_table = std.StringArrayHashMap(Ext).init(comp.gpa);
97 defer source_table.deinit();
98
99 try source_table.ensureCapacity(compat_time32_files.len + src_files.len);
100
101 for (src_files) |src_file| {
102 try addSrcFile(arena, &source_table, src_file);
103 }
104
105 const time32_compat_arch_list = [_][]const u8{ "arm", "i386", "mips", "powerpc" };
106 for (time32_compat_arch_list) |time32_compat_arch| {
107 if (mem.eql(u8, arch_name, time32_compat_arch)) {
108 for (compat_time32_files) |compat_time32_file| {
109 try addSrcFile(arena, &source_table, compat_time32_file);
110 }
111 }
112 }
113
114 var c_source_files = std.ArrayList(Compilation.CSourceFile).init(comp.gpa);
115 defer c_source_files.deinit();
116
117 var override_path = std.ArrayList(u8).init(comp.gpa);
118 defer override_path.deinit();
119
120 const s = path.sep_str;
121
122 for (source_table.items()) |entry| {
123 const src_file = entry.key;
124 const ext = entry.value;
125
126 const dirname = path.dirname(src_file).?;
127 const basename = path.basename(src_file);
128 const noextbasename = mem.split(basename, ".").next().?;
129 const before_arch_dir = path.dirname(dirname).?;
130 const dirbasename = path.basename(dirname);
131
132 var is_arch_specific = false;
133 // Architecture-specific implementations are under a <arch>/ folder.
134 if (is_musl_arch_name(dirbasename)) {
135 if (!mem.eql(u8, dirbasename, arch_name))
136 continue; // Not the architecture we're compiling for.
137 is_arch_specific = true;
138 }
139 if (!is_arch_specific) {
140 // Look for an arch specific override.
141 override_path.shrinkRetainingCapacity(0);
142 try override_path.writer().print("{}" ++ s ++ "{}" ++ s ++ "{}.s", .{
143 dirname, arch_name, noextbasename,
144 });
145 if (source_table.contains(override_path.items))
146 continue;
147
148 override_path.shrinkRetainingCapacity(0);
149 try override_path.writer().print("{}" ++ s ++ "{}" ++ s ++ "{}.S", .{
150 dirname, arch_name, noextbasename,
151 });
152 if (source_table.contains(override_path.items))
153 continue;
154
155 override_path.shrinkRetainingCapacity(0);
156 try override_path.writer().print("{}" ++ s ++ "{}" ++ s ++ "{}.c", .{
157 dirname, arch_name, noextbasename,
158 });
159 if (source_table.contains(override_path.items))
160 continue;
161 }
162
163 var args = std.ArrayList([]const u8).init(arena);
164 try add_cc_args(comp, arena, &args, ext == .o3);
165 try args.appendSlice(&[_][]const u8{
166 "-Qunused-arguments",
167 "-w", // disable all warnings
168 });
169 const c_source_file = try c_source_files.addOne();
170 c_source_file.* = .{
171 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", src_file }),
172 .extra_flags = args.items,
173 };
174 }
175 return comp.build_crt_file("c", .Lib, c_source_files.items);
176 },
177 }
178}
179
180fn is_musl_arch_name(name: []const u8) bool {
181 const musl_arch_names = [_][]const u8{
182 "aarch64",
183 "arm",
184 "generic",
185 "i386",
186 "m68k",
187 "microblaze",
188 "mips",
189 "mips64",
190 "mipsn32",
191 "or1k",
192 "powerpc",
193 "powerpc64",
194 "riscv64",
195 "s390x",
196 "sh",
197 "x32",
198 "x86_64",
199 };
200 for (musl_arch_names) |musl_arch_name| {
201 if (mem.eql(u8, musl_arch_name, name)) {
202 return true;
203 }
204 }
205 return false;
206}
207
208const Ext = enum {
209 assembly,
210 normal,
211 o3,
212};
213
214fn addSrcFile(arena: *Allocator, source_table: *std.StringArrayHashMap(Ext), file_path: []const u8) !void {
215 const ext: Ext = ext: {
216 if (mem.endsWith(u8, file_path, ".c")) {
217 if (mem.startsWith(u8, file_path, "musl/src/malloc/") or
218 mem.startsWith(u8, file_path, "musl/src/string/") or
219 mem.startsWith(u8, file_path, "musl/src/internal/"))
220 {
221 break :ext .o3;
222 } else {
223 break :ext .assembly;
224 }
225 } else if (mem.endsWith(u8, file_path, ".s") or mem.endsWith(u8, file_path, ".S")) {
226 break :ext .assembly;
227 } else {
228 unreachable;
229 }
230 };
231 // TODO do this at comptime on the comptime data rather than at runtime
232 // probably best to wait until self-hosted is done and our comptime execution
233 // is faster and uses less memory.
234 const key = if (path.sep != '/') blk: {
235 const mutable_file_path = try arena.dupe(u8, file_path);
236 for (mutable_file_path) |*c| {
237 if (c.* == '/') {
238 c.* == path.sep;
239 }
240 }
241 break :blk mutable_file_path;
242 } else file_path;
243 source_table.putAssumeCapacityNoClobber(key, ext);
244}
245
246fn add_cc_args(
247 comp: *Compilation,
248 arena: *Allocator,
249 args: *std.ArrayList([]const u8),
250 want_O3: bool,
251) error{OutOfMemory}!void {
252 const target = comp.getTarget();
253 const arch_name = target_util.archMuslName(target.cpu.arch);
254 const os_name = @tagName(target.os.tag);
255 const triple = try std.fmt.allocPrint(arena, "{}-{}-musl", .{ arch_name, os_name });
256 const o_arg = if (want_O3) "-O3" else "-Os";
257
258 try args.appendSlice(&[_][]const u8{
259 "-std=c99",
260 "-ffreestanding",
261 // Musl adds these args to builds with gcc but clang does not support them.
262 //"-fexcess-precision=standard",
263 //"-frounding-math",
264 "-Wa,--noexecstack",
265 "-D_XOPEN_SOURCE=700",
266
267 "-I",
268 try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "arch", arch_name }),
269
270 "-I",
271 try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "arch", "generic" }),
272
273 "-I",
274 try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "src", "include" }),
275
276 "-I",
277 try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "src", "internal" }),
278
279 "-I",
280 try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "include" }),
281
282 "-I",
283 try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", triple }),
284
285 "-I",
286 try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", "generic-musl" }),
287
288 o_arg,
289
290 "-fomit-frame-pointer",
291 "-fno-unwind-tables",
292 "-fno-asynchronous-unwind-tables",
293 "-ffunction-sections",
294 "-fdata-sections",
295 });
296}
297
298fn start_asm_path(comp: *Compilation, arena: *Allocator, basename: []const u8) ![]const u8 {
299 const target = comp.getTarget();
300 return comp.zig_lib_directory.join(arena, &[_][]const u8{
301 "libc", "musl", "crt", target_util.archMuslName(target.cpu.arch), basename,
302 });
303}
304
305const src_files = [_][]const u8{
4306 "musl/src/aio/aio.c",
5307 "musl/src/aio/aio_suspend.c",
6308 "musl/src/aio/lio_listio.c",
......@@ -1776,7 +2078,7 @@ pub const src_files = [_][]const u8{
17762078 "musl/src/unistd/writev.c",
17772079 "musl/src/unistd/x32/lseek.c",
17782080};
1779pub const compat_time32_files = [_][]const u8{
2081const compat_time32_files = [_][]const u8{
17802082 "musl/compat/time32/__xstat.c",
17812083 "musl/compat/time32/adjtime32.c",
17822084 "musl/compat/time32/adjtimex_time32.c",