| author | |
| committer | |
| log | 17d40ecb4964dbba0f3b1482f2c68253cfc69edf |
| tree | 346e786cfed2a85c19d092ba67657df21a09a561 |
| parent | 17f094ec5bce9737f733de08ce0ca049f6d2a186 |
and put glibc shared objects on the elf linker line6 files changed, 234 insertions(+), 32 deletions(-)
BRANCH_TODO+7-6| ... | ... | @@ -1,7 +1,10 @@ |
| 1 | * libunwind | |
| 2 | * stage1 C++ code integration | |
| 1 | * make sure zig cc works | |
| 2 | - 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 | 5 | * support rpaths in ELF linker code |
| 4 | 6 | * build & link against compiler-rt |
| 7 | - stage1 C++ code integration | |
| 5 | 8 | * build & link againstn freestanding libc |
| 6 | 9 | * add CLI support for a way to pass extra flags to c source files |
| 7 | 10 | * implement the workaround for using LLVM to detect native CPU features |
| ... | ... | @@ -12,10 +15,6 @@ |
| 12 | 15 | * port the stage1 os.cpp code that raises the open fd limit |
| 13 | 16 | * use global zig-cache dir for crt files |
| 14 | 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 | 18 | * MachO LLD linking |
| 20 | 19 | * COFF LLD linking |
| 21 | 20 | * WASM LLD linking |
| ... | ... | @@ -54,3 +53,5 @@ |
| 54 | 53 | - make it possible for Package to not openDir and reference already existing resources. |
| 55 | 54 | * rename src/ to src/stage1/ |
| 56 | 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 | 73 | if (only_install_lib_files) |
| 74 | 74 | return; |
| 75 | 75 | |
| 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 | 79 | var exe = b.addExecutable("zig", "src-self-hosted/main.zig"); |
| 77 | 80 | exe.install(); |
| 78 | 81 | exe.setBuildMode(mode); |
| ... | ... | @@ -90,10 +93,8 @@ pub fn build(b: *Builder) !void { |
| 90 | 93 | var ctx = parseConfigH(b, config_h_text); |
| 91 | 94 | ctx.llvm = try findLLVM(b, ctx.llvm_config_exe); |
| 92 | 95 | |
| 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 | 98 | if (link_libc) { |
| 98 | 99 | exe.linkLibC(); |
| 99 | 100 | test_stage2.linkLibC(); |
| ... | ... | @@ -151,7 +152,9 @@ pub fn build(b: *Builder) !void { |
| 151 | 152 | ) catch unreachable; |
| 152 | 153 | exe.addIncludeDir(tracy_path); |
| 153 | 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 | 158 | exe.linkLibC(); |
| 156 | 159 | } |
| 157 | 160 | |
| ... | ... | @@ -344,7 +347,7 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep { |
| 344 | 347 | return result; |
| 345 | 348 | } |
| 346 | 349 | |
| 347 | fn configureStage2(b: *Builder, exe: anytype, ctx: Context) !void { | |
| 350 | fn configureStage2(b: *Builder, exe: anytype, ctx: Context, need_cpp_includes: bool) !void { | |
| 348 | 351 | exe.addIncludeDir("src"); |
| 349 | 352 | exe.addIncludeDir(ctx.cmake_binary_dir); |
| 350 | 353 | addCppLib(b, exe, ctx.cmake_binary_dir, "zig_cpp"); |
| ... | ... | @@ -377,7 +380,7 @@ fn configureStage2(b: *Builder, exe: anytype, ctx: Context) !void { |
| 377 | 380 | if (exe.target.getOsTag() == .linux) { |
| 378 | 381 | // First we try to static link against gcc libstdc++. If that doesn't work, |
| 379 | 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 | 384 | error.RequiredLibraryNotFound => { |
| 382 | 385 | exe.linkSystemLibrary("c++"); |
| 383 | 386 | }, |
| ... | ... | @@ -386,12 +389,12 @@ fn configureStage2(b: *Builder, exe: anytype, ctx: Context) !void { |
| 386 | 389 | |
| 387 | 390 | exe.linkSystemLibrary("pthread"); |
| 388 | 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 | 393 | exe.linkSystemLibrary("pthread"); |
| 391 | 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 | 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 | 398 | exe.linkSystemLibrary("pthread"); |
| 396 | 399 | // TODO LLD cannot perform this link. |
| 397 | 400 | // See https://github.com/ziglang/zig/issues/1535 |
| ... | ... | @@ -417,6 +420,7 @@ fn addCxxKnownPath( |
| 417 | 420 | exe: anytype, |
| 418 | 421 | objname: []const u8, |
| 419 | 422 | errtxt: ?[]const u8, |
| 423 | need_cpp_includes: bool, | |
| 420 | 424 | ) !void { |
| 421 | 425 | const path_padded = try b.exec(&[_][]const u8{ |
| 422 | 426 | ctx.cxx_compiler, |
| ... | ... | @@ -432,6 +436,16 @@ fn addCxxKnownPath( |
| 432 | 436 | return error.RequiredLibraryNotFound; |
| 433 | 437 | } |
| 434 | 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 | } |
| 436 | 450 | |
| 437 | 451 | const Context = struct { |
src-self-hosted/Compilation.zig+38-4| ... | ... | @@ -15,6 +15,7 @@ const liveness = @import("liveness.zig"); |
| 15 | 15 | const build_options = @import("build_options"); |
| 16 | 16 | const LibCInstallation = @import("libc_installation.zig").LibCInstallation; |
| 17 | 17 | const glibc = @import("glibc.zig"); |
| 18 | const libunwind = @import("libunwind.zig"); | |
| 18 | 19 | const fatal = @import("main.zig").fatal; |
| 19 | 20 | const Module = @import("Module.zig"); |
| 20 | 21 | const Cache = @import("Cache.zig"); |
| ... | ... | @@ -63,7 +64,7 @@ libcxx_static_lib: ?[]const u8 = null, |
| 63 | 64 | libcxxabi_static_lib: ?[]const u8 = null, |
| 64 | 65 | /// Populated when we build libunwind.a. A WorkItem to build this is placed in the queue |
| 65 | 66 | /// and resolved before calling linker.flush(). |
| 66 | libunwind_static_lib: ?[]const u8 = null, | |
| 67 | libunwind_static_lib: ?CRTFile = null, | |
| 67 | 68 | /// Populated when we build c.a. A WorkItem to build this is placed in the queue |
| 68 | 69 | /// and resolved before calling linker.flush(). |
| 69 | 70 | libc_static_lib: ?[]const u8 = null, |
| ... | ... | @@ -115,6 +116,8 @@ const WorkItem = union(enum) { |
| 115 | 116 | glibc_crt_file: glibc.CRTFile, |
| 116 | 117 | /// all of the glibc shared objects |
| 117 | 118 | glibc_shared_objects, |
| 119 | ||
| 120 | libunwind: void, | |
| 118 | 121 | }; |
| 119 | 122 | |
| 120 | 123 | pub const CObject = struct { |
| ... | ... | @@ -206,6 +209,17 @@ pub const Directory = struct { |
| 206 | 209 | /// `null` means cwd. |
| 207 | 210 | path: ?[]const u8, |
| 208 | 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 | }; |
| 210 | 224 | |
| 211 | 225 | pub const EmitLoc = struct { |
| ... | ... | @@ -274,9 +288,6 @@ pub const InitOptions = struct { |
| 274 | 288 | version: ?std.builtin.Version = null, |
| 275 | 289 | libc_installation: ?*const LibCInstallation = null, |
| 276 | 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 | }; |
| 281 | 292 | |
| 282 | 293 | pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| ... | ... | @@ -636,6 +647,9 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 636 | 647 | if (comp.wantBuildGLibCFromSource()) { |
| 637 | 648 | try comp.addBuildingGLibCWorkItems(); |
| 638 | 649 | } |
| 650 | if (comp.wantBuildLibUnwindFromSource()) { | |
| 651 | try comp.work_queue.writeItem(.{ .libunwind = {} }); | |
| 652 | } | |
| 639 | 653 | |
| 640 | 654 | return comp; |
| 641 | 655 | } |
| ... | ... | @@ -656,6 +670,10 @@ pub fn destroy(self: *Compilation) void { |
| 656 | 670 | self.crt_files.deinit(gpa); |
| 657 | 671 | } |
| 658 | 672 | |
| 673 | if (self.libunwind_static_lib) |*unwind_crt_file| { | |
| 674 | unwind_crt_file.deinit(gpa); | |
| 675 | } | |
| 676 | ||
| 659 | 677 | for (self.c_object_table.items()) |entry| { |
| 660 | 678 | entry.key.destroy(gpa); |
| 661 | 679 | } |
| ... | ... | @@ -936,6 +954,12 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void { |
| 936 | 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 | } |
| 941 | 965 | |
| ... | ... | @@ -1597,3 +1621,13 @@ fn wantBuildGLibCFromSource(comp: *Compilation) bool { |
| 1597 | 1621 | comp.bin_file.options.libc_installation == null and |
| 1598 | 1622 | comp.bin_file.options.target.isGnuLibC(); |
| 1599 | 1623 | } |
| 1624 | ||
| 1625 | fn 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 | 751 | const tracy = trace(@src()); |
| 752 | 752 | defer tracy.end(); |
| 753 | 753 | |
| 754 | if (!build_options.have_llvm) { | |
| 755 | return error.ZigCompilerNotBuiltWithLLVMExtensions; | |
| 756 | } | |
| 757 | ||
| 754 | 758 | var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); |
| 755 | 759 | defer arena_allocator.deinit(); |
| 756 | 760 | const arena = &arena_allocator.allocator; |
| ... | ... | @@ -987,7 +991,6 @@ fn buildSharedLib( |
| 987 | 991 | .debug_link = comp.bin_file.options.debug_link, |
| 988 | 992 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| 989 | 993 | .version = version, |
| 990 | .stage1_is_dummy_so = true, | |
| 991 | 994 | .version_script = map_file_path, |
| 992 | 995 | .override_soname = override_soname, |
| 993 | 996 | .c_source_files = &c_source_files, |
src-self-hosted/libunwind.zig created+144| ... | ... | @@ -0,0 +1,144 @@ |
| 1 | const std = @import("std"); | |
| 2 | const path = std.fs.path; | |
| 3 | const assert = std.debug.assert; | |
| 4 | ||
| 5 | const target_util = @import("target.zig"); | |
| 6 | const Compilation = @import("Compilation.zig"); | |
| 7 | const build_options = @import("build_options"); | |
| 8 | const trace = @import("tracy.zig").trace; | |
| 9 | ||
| 10 | pub 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 | ||
| 126 | fn 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 | const Elf = @This(); | |
| 2 | ||
| 1 | 3 | const std = @import("std"); |
| 2 | 4 | const mem = std.mem; |
| 3 | 5 | const assert = std.debug.assert; |
| 4 | 6 | const Allocator = std.mem.Allocator; |
| 5 | const ir = @import("../ir.zig"); | |
| 6 | const Module = @import("../Module.zig"); | |
| 7 | const Compilation = @import("../Compilation.zig"); | |
| 8 | 7 | const fs = std.fs; |
| 9 | 8 | const elf = std.elf; |
| 10 | const codegen = @import("../codegen.zig"); | |
| 11 | 9 | const log = std.log.scoped(.link); |
| 12 | 10 | const DW = std.dwarf; |
| 13 | const trace = @import("../tracy.zig").trace; | |
| 14 | 11 | const leb128 = std.debug.leb; |
| 12 | ||
| 13 | const ir = @import("../ir.zig"); | |
| 14 | const Module = @import("../Module.zig"); | |
| 15 | const Compilation = @import("../Compilation.zig"); | |
| 16 | const codegen = @import("../codegen.zig"); | |
| 17 | const trace = @import("../tracy.zig").trace; | |
| 15 | 18 | const Package = @import("../Package.zig"); |
| 16 | 19 | const Value = @import("../value.zig").Value; |
| 17 | 20 | const Type = @import("../type.zig").Type; |
| 18 | 21 | const link = @import("../link.zig"); |
| 19 | 22 | const File = link.File; |
| 20 | const Elf = @This(); | |
| 21 | 23 | const build_options = @import("build_options"); |
| 22 | 24 | const target_util = @import("../target.zig"); |
| 23 | const fatal = @import("main.zig").fatal; | |
| 25 | const glibc = @import("../glibc.zig"); | |
| 24 | 26 | |
| 25 | 27 | const default_entry_addr = 0x8000000; |
| 26 | 28 | |
| ... | ... | @@ -1530,15 +1532,19 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1530 | 1532 | try argv.append("-lpthread"); |
| 1531 | 1533 | } |
| 1532 | 1534 | } else if (target.isGnuLibC()) { |
| 1533 | try argv.append(comp.libunwind_static_lib.?); | |
| 1534 | // TODO here we need to iterate over the glibc libs and add the .so files to the linker line. | |
| 1535 | std.log.warn("TODO port add_glibc_libs to stage2", .{}); | |
| 1535 | try argv.append(comp.libunwind_static_lib.?.full_object_path); | |
| 1536 | for (glibc.libs) |lib| { | |
| 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 | 1542 | try argv.append(try comp.get_libc_crt_file(arena, "libc_nonshared.a")); |
| 1537 | 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 | 1545 | try argv.append(comp.libc_static_lib.?); |
| 1540 | 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 | 1548 | } else { |
| 1543 | 1549 | unreachable; // Compiler was supposed to emit an error for not being able to provide libc. |
| 1544 | 1550 | } |