authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-16 17:17:37-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-16 17:18:13-07:00
log17d40ecb4964dbba0f3b1482f2c68253cfc69edf
tree346e786cfed2a85c19d092ba67657df21a09a561
parent17f094ec5bce9737f733de08ce0ca049f6d2a186

stage2: building libunwind.a

and put glibc shared objects on the elf linker line

6 files changed, 234 insertions(+), 32 deletions(-)

BRANCH_TODO+7-6
...@@ -1,7 +1,10 @@...@@ -1,7 +1,10 @@
1 * libunwind1 * make sure zig cc works
2 * stage1 C++ code integration2 - using it as a preprocessor (-E)
3 - @breakpoint(); // TODO the first arg is empty string right? skip past that.
4 - try building some software
3 * support rpaths in ELF linker code5 * support rpaths in ELF linker code
4 * build & link against compiler-rt6 * build & link against compiler-rt
7 - stage1 C++ code integration
5 * build & link againstn freestanding libc8 * build & link againstn freestanding libc
6 * add CLI support for a way to pass extra flags to c source files9 * add CLI support for a way to pass extra flags to c source files
7 * implement the workaround for using LLVM to detect native CPU features10 * implement the workaround for using LLVM to detect native CPU features
...@@ -12,10 +15,6 @@...@@ -12,10 +15,6 @@
12 * port the stage1 os.cpp code that raises the open fd limit15 * port the stage1 os.cpp code that raises the open fd limit
13 * use global zig-cache dir for crt files16 * use global zig-cache dir for crt files
14 * `zig translate-c`17 * `zig translate-c`
15 * make sure zig cc works
16 - using it as a preprocessor (-E)
17 - @breakpoint(); // TODO the first arg is empty string right? skip past that.
18 - try building some software
19 * MachO LLD linking18 * MachO LLD linking
20 * COFF LLD linking19 * COFF LLD linking
21 * WASM LLD linking20 * WASM LLD linking
...@@ -54,3 +53,5 @@...@@ -54,3 +53,5 @@
54 - make it possible for Package to not openDir and reference already existing resources.53 - make it possible for Package to not openDir and reference already existing resources.
55 * rename src/ to src/stage1/54 * rename src/ to src/stage1/
56 * rename src-self-hosted/ to src/55 * rename src-self-hosted/ to src/
56 * improve Directory.join to only use 1 allocation in a clean way.
57 * tracy builds with lc++
build.zig+23-9
...@@ -73,6 +73,9 @@ pub fn build(b: *Builder) !void {...@@ -73,6 +73,9 @@ pub fn build(b: *Builder) !void {
73 if (only_install_lib_files)73 if (only_install_lib_files)
74 return;74 return;
7575
76 const tracy = b.option([]const u8, "tracy", "Enable Tracy integration. Supply path to Tracy source");
77 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;
78
76 var exe = b.addExecutable("zig", "src-self-hosted/main.zig");79 var exe = b.addExecutable("zig", "src-self-hosted/main.zig");
77 exe.install();80 exe.install();
78 exe.setBuildMode(mode);81 exe.setBuildMode(mode);
...@@ -90,10 +93,8 @@ pub fn build(b: *Builder) !void {...@@ -90,10 +93,8 @@ pub fn build(b: *Builder) !void {
90 var ctx = parseConfigH(b, config_h_text);93 var ctx = parseConfigH(b, config_h_text);
91 ctx.llvm = try findLLVM(b, ctx.llvm_config_exe);94 ctx.llvm = try findLLVM(b, ctx.llvm_config_exe);
9295
93 try configureStage2(b, exe, ctx);96 try configureStage2(b, exe, ctx, tracy != null);
94 }97 }
95 const tracy = b.option([]const u8, "tracy", "Enable Tracy integration. Supply path to Tracy source");
96 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;
97 if (link_libc) {98 if (link_libc) {
98 exe.linkLibC();99 exe.linkLibC();
99 test_stage2.linkLibC();100 test_stage2.linkLibC();
...@@ -151,7 +152,9 @@ pub fn build(b: *Builder) !void {...@@ -151,7 +152,9 @@ pub fn build(b: *Builder) !void {
151 ) catch unreachable;152 ) catch unreachable;
152 exe.addIncludeDir(tracy_path);153 exe.addIncludeDir(tracy_path);
153 exe.addCSourceFile(client_cpp, &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" });154 exe.addCSourceFile(client_cpp, &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" });
154 exe.linkSystemLibraryName("c++");155 if (!enable_llvm) {
156 exe.linkSystemLibraryName("c++");
157 }
155 exe.linkLibC();158 exe.linkLibC();
156 }159 }
157160
...@@ -344,7 +347,7 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {...@@ -344,7 +347,7 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
344 return result;347 return result;
345}348}
346349
347fn configureStage2(b: *Builder, exe: anytype, ctx: Context) !void {350fn configureStage2(b: *Builder, exe: anytype, ctx: Context, need_cpp_includes: bool) !void {
348 exe.addIncludeDir("src");351 exe.addIncludeDir("src");
349 exe.addIncludeDir(ctx.cmake_binary_dir);352 exe.addIncludeDir(ctx.cmake_binary_dir);
350 addCppLib(b, exe, ctx.cmake_binary_dir, "zig_cpp");353 addCppLib(b, exe, ctx.cmake_binary_dir, "zig_cpp");
...@@ -377,7 +380,7 @@ fn configureStage2(b: *Builder, exe: anytype, ctx: Context) !void {...@@ -377,7 +380,7 @@ fn configureStage2(b: *Builder, exe: anytype, ctx: Context) !void {
377 if (exe.target.getOsTag() == .linux) {380 if (exe.target.getOsTag() == .linux) {
378 // First we try to static link against gcc libstdc++. If that doesn't work,381 // First we try to static link against gcc libstdc++. If that doesn't work,
379 // we fall back to -lc++ and cross our fingers.382 // we fall back to -lc++ and cross our fingers.
380 addCxxKnownPath(b, ctx, exe, "libstdc++.a", "") catch |err| switch (err) {383 addCxxKnownPath(b, ctx, exe, "libstdc++.a", "", need_cpp_includes) catch |err| switch (err) {
381 error.RequiredLibraryNotFound => {384 error.RequiredLibraryNotFound => {
382 exe.linkSystemLibrary("c++");385 exe.linkSystemLibrary("c++");
383 },386 },
...@@ -386,12 +389,12 @@ fn configureStage2(b: *Builder, exe: anytype, ctx: Context) !void {...@@ -386,12 +389,12 @@ fn configureStage2(b: *Builder, exe: anytype, ctx: Context) !void {
386389
387 exe.linkSystemLibrary("pthread");390 exe.linkSystemLibrary("pthread");
388 } else if (exe.target.isFreeBSD()) {391 } else if (exe.target.isFreeBSD()) {
389 try addCxxKnownPath(b, ctx, exe, "libc++.a", null);392 try addCxxKnownPath(b, ctx, exe, "libc++.a", null, need_cpp_includes);
390 exe.linkSystemLibrary("pthread");393 exe.linkSystemLibrary("pthread");
391 } else if (exe.target.isDarwin()) {394 } else if (exe.target.isDarwin()) {
392 if (addCxxKnownPath(b, ctx, exe, "libgcc_eh.a", "")) {395 if (addCxxKnownPath(b, ctx, exe, "libgcc_eh.a", "", need_cpp_includes)) {
393 // Compiler is GCC.396 // Compiler is GCC.
394 try addCxxKnownPath(b, ctx, exe, "libstdc++.a", null);397 try addCxxKnownPath(b, ctx, exe, "libstdc++.a", null, need_cpp_includes);
395 exe.linkSystemLibrary("pthread");398 exe.linkSystemLibrary("pthread");
396 // TODO LLD cannot perform this link.399 // TODO LLD cannot perform this link.
397 // See https://github.com/ziglang/zig/issues/1535400 // See https://github.com/ziglang/zig/issues/1535
...@@ -417,6 +420,7 @@ fn addCxxKnownPath(...@@ -417,6 +420,7 @@ fn addCxxKnownPath(
417 exe: anytype,420 exe: anytype,
418 objname: []const u8,421 objname: []const u8,
419 errtxt: ?[]const u8,422 errtxt: ?[]const u8,
423 need_cpp_includes: bool,
420) !void {424) !void {
421 const path_padded = try b.exec(&[_][]const u8{425 const path_padded = try b.exec(&[_][]const u8{
422 ctx.cxx_compiler,426 ctx.cxx_compiler,
...@@ -432,6 +436,16 @@ fn addCxxKnownPath(...@@ -432,6 +436,16 @@ fn addCxxKnownPath(
432 return error.RequiredLibraryNotFound;436 return error.RequiredLibraryNotFound;
433 }437 }
434 exe.addObjectFile(path_unpadded);438 exe.addObjectFile(path_unpadded);
439
440 // TODO a way to integrate with system c++ include files here
441 // cc -E -Wp,-v -xc++ /dev/null
442 if (need_cpp_includes) {
443 // I used these temporarily for testing something but we obviously need a
444 // more general purpose solution here.
445 //exe.addIncludeDir("/nix/store/b3zsk4ihlpiimv3vff86bb5bxghgdzb9-gcc-9.2.0/lib/gcc/x86_64-unknown-linux-gnu/9.2.0/../../../../include/c++/9.2.0");
446 //exe.addIncludeDir("/nix/store/b3zsk4ihlpiimv3vff86bb5bxghgdzb9-gcc-9.2.0/lib/gcc/x86_64-unknown-linux-gnu/9.2.0/../../../../include/c++/9.2.0/x86_64-unknown-linux-gnu");
447 //exe.addIncludeDir("/nix/store/b3zsk4ihlpiimv3vff86bb5bxghgdzb9-gcc-9.2.0/lib/gcc/x86_64-unknown-linux-gnu/9.2.0/../../../../include/c++/9.2.0/backward");
448 }
435}449}
436450
437const Context = struct {451const Context = struct {
src-self-hosted/Compilation.zig+38-4
...@@ -15,6 +15,7 @@ const liveness = @import("liveness.zig");...@@ -15,6 +15,7 @@ const liveness = @import("liveness.zig");
15const build_options = @import("build_options");15const build_options = @import("build_options");
16const LibCInstallation = @import("libc_installation.zig").LibCInstallation;16const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
17const glibc = @import("glibc.zig");17const glibc = @import("glibc.zig");
18const libunwind = @import("libunwind.zig");
18const fatal = @import("main.zig").fatal;19const fatal = @import("main.zig").fatal;
19const Module = @import("Module.zig");20const Module = @import("Module.zig");
20const Cache = @import("Cache.zig");21const Cache = @import("Cache.zig");
...@@ -63,7 +64,7 @@ libcxx_static_lib: ?[]const u8 = null,...@@ -63,7 +64,7 @@ libcxx_static_lib: ?[]const u8 = null,
63libcxxabi_static_lib: ?[]const u8 = null,64libcxxabi_static_lib: ?[]const u8 = null,
64/// Populated when we build libunwind.a. A WorkItem to build this is placed in the queue65/// Populated when we build libunwind.a. A WorkItem to build this is placed in the queue
65/// and resolved before calling linker.flush().66/// and resolved before calling linker.flush().
66libunwind_static_lib: ?[]const u8 = null,67libunwind_static_lib: ?CRTFile = null,
67/// Populated when we build c.a. A WorkItem to build this is placed in the queue68/// Populated when we build c.a. A WorkItem to build this is placed in the queue
68/// and resolved before calling linker.flush().69/// and resolved before calling linker.flush().
69libc_static_lib: ?[]const u8 = null,70libc_static_lib: ?[]const u8 = null,
...@@ -115,6 +116,8 @@ const WorkItem = union(enum) {...@@ -115,6 +116,8 @@ const WorkItem = union(enum) {
115 glibc_crt_file: glibc.CRTFile,116 glibc_crt_file: glibc.CRTFile,
116 /// all of the glibc shared objects117 /// all of the glibc shared objects
117 glibc_shared_objects,118 glibc_shared_objects,
119
120 libunwind: void,
118};121};
119122
120pub const CObject = struct {123pub const CObject = struct {
...@@ -206,6 +209,17 @@ pub const Directory = struct {...@@ -206,6 +209,17 @@ pub const Directory = struct {
206 /// `null` means cwd.209 /// `null` means cwd.
207 path: ?[]const u8,210 path: ?[]const u8,
208 handle: std.fs.Dir,211 handle: std.fs.Dir,
212
213 pub fn join(self: Directory, allocator: *Allocator, paths: []const []const u8) ![]u8 {
214 if (self.path) |p| {
215 // TODO clean way to do this with only 1 allocation
216 const part2 = try std.fs.path.join(allocator, paths);
217 defer allocator.free(part2);
218 return std.fs.path.join(allocator, &[_][]const u8{ p, part2 });
219 } else {
220 return std.fs.path.join(allocator, paths);
221 }
222 }
209};223};
210224
211pub const EmitLoc = struct {225pub const EmitLoc = struct {
...@@ -274,9 +288,6 @@ pub const InitOptions = struct {...@@ -274,9 +288,6 @@ pub const InitOptions = struct {
274 version: ?std.builtin.Version = null,288 version: ?std.builtin.Version = null,
275 libc_installation: ?*const LibCInstallation = null,289 libc_installation: ?*const LibCInstallation = null,
276 machine_code_model: std.builtin.CodeModel = .default,290 machine_code_model: std.builtin.CodeModel = .default,
277 /// TODO Once self-hosted Zig is capable enough, we can remove this special-case
278 /// hack in favor of more general compilation options.
279 stage1_is_dummy_so: bool = false,
280};291};
281292
282pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {293pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
...@@ -636,6 +647,9 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -636,6 +647,9 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
636 if (comp.wantBuildGLibCFromSource()) {647 if (comp.wantBuildGLibCFromSource()) {
637 try comp.addBuildingGLibCWorkItems();648 try comp.addBuildingGLibCWorkItems();
638 }649 }
650 if (comp.wantBuildLibUnwindFromSource()) {
651 try comp.work_queue.writeItem(.{ .libunwind = {} });
652 }
639653
640 return comp;654 return comp;
641}655}
...@@ -656,6 +670,10 @@ pub fn destroy(self: *Compilation) void {...@@ -656,6 +670,10 @@ pub fn destroy(self: *Compilation) void {
656 self.crt_files.deinit(gpa);670 self.crt_files.deinit(gpa);
657 }671 }
658672
673 if (self.libunwind_static_lib) |*unwind_crt_file| {
674 unwind_crt_file.deinit(gpa);
675 }
676
659 for (self.c_object_table.items()) |entry| {677 for (self.c_object_table.items()) |entry| {
660 entry.key.destroy(gpa);678 entry.key.destroy(gpa);
661 }679 }
...@@ -936,6 +954,12 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void {...@@ -936,6 +954,12 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void {
936 fatal("unable to build glibc shared objects: {}", .{@errorName(err)});954 fatal("unable to build glibc shared objects: {}", .{@errorName(err)});
937 };955 };
938 },956 },
957 .libunwind => {
958 libunwind.buildStaticLib(self) catch |err| {
959 // TODO Expose this as a normal compile error rather than crashing here.
960 fatal("unable to build libunwind: {}", .{@errorName(err)});
961 };
962 },
939 };963 };
940}964}
941965
...@@ -1597,3 +1621,13 @@ fn wantBuildGLibCFromSource(comp: *Compilation) bool {...@@ -1597,3 +1621,13 @@ fn wantBuildGLibCFromSource(comp: *Compilation) bool {
1597 comp.bin_file.options.libc_installation == null and1621 comp.bin_file.options.libc_installation == null and
1598 comp.bin_file.options.target.isGnuLibC();1622 comp.bin_file.options.target.isGnuLibC();
1599}1623}
1624
1625fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
1626 const is_exe_or_dyn_lib = switch (comp.bin_file.options.output_mode) {
1627 .Obj => false,
1628 .Lib => comp.bin_file.options.link_mode == .Dynamic,
1629 .Exe => true,
1630 };
1631 return comp.bin_file.options.link_libc and is_exe_or_dyn_lib and
1632 comp.bin_file.options.libc_installation == null;
1633}
src-self-hosted/glibc.zig+4-1
...@@ -751,6 +751,10 @@ pub fn buildSharedObjects(comp: *Compilation) !void {...@@ -751,6 +751,10 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
751 const tracy = trace(@src());751 const tracy = trace(@src());
752 defer tracy.end();752 defer tracy.end();
753753
754 if (!build_options.have_llvm) {
755 return error.ZigCompilerNotBuiltWithLLVMExtensions;
756 }
757
754 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);758 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
755 defer arena_allocator.deinit();759 defer arena_allocator.deinit();
756 const arena = &arena_allocator.allocator;760 const arena = &arena_allocator.allocator;
...@@ -987,7 +991,6 @@ fn buildSharedLib(...@@ -987,7 +991,6 @@ fn buildSharedLib(
987 .debug_link = comp.bin_file.options.debug_link,991 .debug_link = comp.bin_file.options.debug_link,
988 .clang_passthrough_mode = comp.clang_passthrough_mode,992 .clang_passthrough_mode = comp.clang_passthrough_mode,
989 .version = version,993 .version = version,
990 .stage1_is_dummy_so = true,
991 .version_script = map_file_path,994 .version_script = map_file_path,
992 .override_soname = override_soname,995 .override_soname = override_soname,
993 .c_source_files = &c_source_files,996 .c_source_files = &c_source_files,
src-self-hosted/libunwind.zig created+144
...@@ -0,0 +1,144 @@
1const std = @import("std");
2const path = std.fs.path;
3const assert = std.debug.assert;
4
5const target_util = @import("target.zig");
6const Compilation = @import("Compilation.zig");
7const build_options = @import("build_options");
8const trace = @import("tracy.zig").trace;
9
10pub fn buildStaticLib(comp: *Compilation) !void {
11 const tracy = trace(@src());
12 defer tracy.end();
13
14 if (!build_options.have_llvm) {
15 return error.ZigCompilerNotBuiltWithLLVMExtensions;
16 }
17
18 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
19 defer arena_allocator.deinit();
20 const arena = &arena_allocator.allocator;
21
22 const root_name = "unwind";
23 const output_mode = .Lib;
24 const link_mode = .Static;
25 const target = comp.getTarget();
26 const basename = try std.zig.binNameAlloc(arena, root_name, target, output_mode, link_mode, null);
27
28 const emit_bin = Compilation.EmitLoc{
29 .directory = null, // Put it in the cache directory.
30 .basename = basename,
31 };
32
33 const unwind_src_list = [_][]const u8{
34 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "libunwind.cpp",
35 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-EHABI.cpp",
36 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-seh.cpp",
37 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1.c",
38 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1-gcc-ext.c",
39 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-sjlj.c",
40 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersRestore.S",
41 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersSave.S",
42 };
43
44 var c_source_files: [unwind_src_list.len]Compilation.CSourceFile = undefined;
45 for (unwind_src_list) |unwind_src, i| {
46 var cflags = std.ArrayList([]const u8).init(arena);
47
48 switch (Compilation.classifyFileExt(unwind_src)) {
49 .c => {
50 try cflags.append("-std=c99");
51 },
52 .cpp => {
53 try cflags.appendSlice(&[_][]const u8{
54 "-fno-rtti",
55 "-I",
56 try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "include" }),
57 });
58 },
59 .assembly => {},
60 else => unreachable, // You can see the entire list of files just above.
61 }
62 try cflags.append("-I");
63 try cflags.append(try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libunwind", "include" }));
64 if (target_util.supports_fpic(target)) {
65 try cflags.append("-fPIC");
66 }
67 try cflags.append("-D_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS");
68 try cflags.append("-Wa,--noexecstack");
69
70 // This is intentionally always defined because the macro definition means, should it only
71 // build for the target specified by compiler defines. Since we pass -target the compiler
72 // defines will be correct.
73 try cflags.append("-D_LIBUNWIND_IS_NATIVE_ONLY");
74
75 if (comp.bin_file.options.optimize_mode == .Debug) {
76 try cflags.append("-D_DEBUG");
77 }
78 if (comp.bin_file.options.single_threaded) {
79 try cflags.append("-D_LIBUNWIND_HAS_NO_THREADS");
80 }
81 try cflags.append("-Wno-bitwise-conditional-parentheses");
82
83 c_source_files[i] = .{
84 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{unwind_src}),
85 .extra_flags = cflags.items,
86 };
87 }
88 const sub_compilation = try Compilation.create(comp.gpa, .{
89 // TODO use the global cache directory here
90 .zig_cache_directory = comp.zig_cache_directory,
91 .zig_lib_directory = comp.zig_lib_directory,
92 .target = target,
93 .root_name = root_name,
94 .root_pkg = null,
95 .output_mode = output_mode,
96 .rand = comp.rand,
97 .libc_installation = comp.bin_file.options.libc_installation,
98 .emit_bin = emit_bin,
99 .optimize_mode = comp.bin_file.options.optimize_mode,
100 .link_mode = link_mode,
101 .want_sanitize_c = false,
102 .want_stack_check = false,
103 .want_valgrind = false,
104 .want_pic = comp.bin_file.options.pic,
105 .emit_h = null,
106 .strip = comp.bin_file.options.strip,
107 .is_native_os = comp.bin_file.options.is_native_os,
108 .self_exe_path = comp.self_exe_path,
109 .c_source_files = &c_source_files,
110 .debug_cc = comp.debug_cc,
111 .debug_link = comp.bin_file.options.debug_link,
112 .clang_passthrough_mode = comp.clang_passthrough_mode,
113 .link_libc = true,
114 });
115 defer sub_compilation.destroy();
116
117 try updateSubCompilation(sub_compilation);
118
119 assert(comp.libunwind_static_lib == null);
120 comp.libunwind_static_lib = Compilation.CRTFile{
121 .full_object_path = try sub_compilation.bin_file.options.directory.join(comp.gpa, &[_][]const u8{basename}),
122 .lock = sub_compilation.bin_file.toOwnedLock(),
123 };
124}
125
126fn updateSubCompilation(sub_compilation: *Compilation) !void {
127 try sub_compilation.update();
128
129 // Look for compilation errors in this sub_compilation
130 var errors = try sub_compilation.getAllErrorsAlloc();
131 defer errors.deinit(sub_compilation.gpa);
132
133 if (errors.list.len != 0) {
134 for (errors.list) |full_err_msg| {
135 std.log.err("{}:{}:{}: {}\n", .{
136 full_err_msg.src_path,
137 full_err_msg.line + 1,
138 full_err_msg.column + 1,
139 full_err_msg.msg,
140 });
141 }
142 return error.BuildingLibCObjectFailed;
143 }
144}
src-self-hosted/link/Elf.zig+18-12
...@@ -1,26 +1,28 @@...@@ -1,26 +1,28 @@
1const Elf = @This();
2
1const std = @import("std");3const std = @import("std");
2const mem = std.mem;4const mem = std.mem;
3const assert = std.debug.assert;5const assert = std.debug.assert;
4const Allocator = std.mem.Allocator;6const Allocator = std.mem.Allocator;
5const ir = @import("../ir.zig");
6const Module = @import("../Module.zig");
7const Compilation = @import("../Compilation.zig");
8const fs = std.fs;7const fs = std.fs;
9const elf = std.elf;8const elf = std.elf;
10const codegen = @import("../codegen.zig");
11const log = std.log.scoped(.link);9const log = std.log.scoped(.link);
12const DW = std.dwarf;10const DW = std.dwarf;
13const trace = @import("../tracy.zig").trace;
14const leb128 = std.debug.leb;11const leb128 = std.debug.leb;
12
13const ir = @import("../ir.zig");
14const Module = @import("../Module.zig");
15const Compilation = @import("../Compilation.zig");
16const codegen = @import("../codegen.zig");
17const trace = @import("../tracy.zig").trace;
15const Package = @import("../Package.zig");18const Package = @import("../Package.zig");
16const Value = @import("../value.zig").Value;19const Value = @import("../value.zig").Value;
17const Type = @import("../type.zig").Type;20const Type = @import("../type.zig").Type;
18const link = @import("../link.zig");21const link = @import("../link.zig");
19const File = link.File;22const File = link.File;
20const Elf = @This();
21const build_options = @import("build_options");23const build_options = @import("build_options");
22const target_util = @import("../target.zig");24const target_util = @import("../target.zig");
23const fatal = @import("main.zig").fatal;25const glibc = @import("../glibc.zig");
2426
25const default_entry_addr = 0x8000000;27const default_entry_addr = 0x8000000;
2628
...@@ -1530,15 +1532,19 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1530,15 +1532,19 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1530 try argv.append("-lpthread");1532 try argv.append("-lpthread");
1531 }1533 }
1532 } else if (target.isGnuLibC()) {1534 } else if (target.isGnuLibC()) {
1533 try argv.append(comp.libunwind_static_lib.?);1535 try argv.append(comp.libunwind_static_lib.?.full_object_path);
1534 // TODO here we need to iterate over the glibc libs and add the .so files to the linker line.1536 for (glibc.libs) |lib| {
1535 std.log.warn("TODO port add_glibc_libs to stage2", .{});1537 const lib_path = try std.fmt.allocPrint(arena, "{s}{c}lib{s}.so.{d}", .{
1538 comp.glibc_so_files.?.dir_path, fs.path.sep, lib.name, lib.sover,
1539 });
1540 try argv.append(lib_path);
1541 }
1536 try argv.append(try comp.get_libc_crt_file(arena, "libc_nonshared.a"));1542 try argv.append(try comp.get_libc_crt_file(arena, "libc_nonshared.a"));
1537 } else if (target.isMusl()) {1543 } else if (target.isMusl()) {
1538 try argv.append(comp.libunwind_static_lib.?);1544 try argv.append(comp.libunwind_static_lib.?.full_object_path);
1539 try argv.append(comp.libc_static_lib.?);1545 try argv.append(comp.libc_static_lib.?);
1540 } else if (self.base.options.link_libcpp) {1546 } else if (self.base.options.link_libcpp) {
1541 try argv.append(comp.libunwind_static_lib.?);1547 try argv.append(comp.libunwind_static_lib.?.full_object_path);
1542 } else {1548 } else {
1543 unreachable; // Compiler was supposed to emit an error for not being able to provide libc.1549 unreachable; // Compiler was supposed to emit an error for not being able to provide libc.
1544 }1550 }