| 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,7 +1,10 @@ |
| 1 | * libunwind | 1 | * make sure zig cc works |
| 2 | * stage1 C++ code integration | 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 | * support rpaths in ELF linker code | 5 | * support rpaths in ELF linker code |
| 4 | * build & link against compiler-rt | 6 | * build & link against compiler-rt |
| 7 | - stage1 C++ code integration | ||
| 5 | * build & link againstn freestanding libc | 8 | * build & link againstn freestanding libc |
| 6 | * add CLI support for a way to pass extra flags to c source files | 9 | * 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 features | 10 | * 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 limit | 15 | * port the stage1 os.cpp code that raises the open fd limit |
| 13 | * use global zig-cache dir for crt files | 16 | * 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 linking | 18 | * MachO LLD linking |
| 20 | * COFF LLD linking | 19 | * COFF LLD linking |
| 21 | * WASM LLD linking | 20 | * 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; |
| 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 | 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); |
| 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 | 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 | } |
| 157 | 160 | ||
| ... | @@ -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 | } |
| 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 | 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 { |
| 386 | 389 | ||
| 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/1535 | 400 | // 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 | } |
| 436 | 450 | ||
| 437 | const Context = struct { | 451 | const 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"); |
| 15 | const build_options = @import("build_options"); | 15 | const build_options = @import("build_options"); |
| 16 | const LibCInstallation = @import("libc_installation.zig").LibCInstallation; | 16 | const LibCInstallation = @import("libc_installation.zig").LibCInstallation; |
| 17 | const glibc = @import("glibc.zig"); | 17 | const glibc = @import("glibc.zig"); |
| 18 | const libunwind = @import("libunwind.zig"); | ||
| 18 | const fatal = @import("main.zig").fatal; | 19 | const fatal = @import("main.zig").fatal; |
| 19 | const Module = @import("Module.zig"); | 20 | const Module = @import("Module.zig"); |
| 20 | const Cache = @import("Cache.zig"); | 21 | const Cache = @import("Cache.zig"); |
| ... | @@ -63,7 +64,7 @@ libcxx_static_lib: ?[]const u8 = null, | ... | @@ -63,7 +64,7 @@ libcxx_static_lib: ?[]const u8 = null, |
| 63 | libcxxabi_static_lib: ?[]const u8 = null, | 64 | libcxxabi_static_lib: ?[]const u8 = null, |
| 64 | /// Populated when we build libunwind.a. A WorkItem to build this is placed in the queue | 65 | /// 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(). |
| 66 | libunwind_static_lib: ?[]const u8 = null, | 67 | libunwind_static_lib: ?CRTFile = null, |
| 67 | /// Populated when we build c.a. A WorkItem to build this is placed in the queue | 68 | /// 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(). |
| 69 | libc_static_lib: ?[]const u8 = null, | 70 | libc_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 objects | 117 | /// all of the glibc shared objects |
| 117 | glibc_shared_objects, | 118 | glibc_shared_objects, |
| 119 | |||
| 120 | libunwind: void, | ||
| 118 | }; | 121 | }; |
| 119 | 122 | ||
| 120 | pub const CObject = struct { | 123 | pub 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 | }; |
| 210 | 224 | ||
| 211 | pub const EmitLoc = struct { | 225 | pub 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 | }; |
| 281 | 292 | ||
| 282 | pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | 293 | pub 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 | } | ||
| 639 | 653 | ||
| 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 | } |
| 658 | 672 | ||
| 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 | } |
| 941 | 965 | ||
| ... | @@ -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 and | 1621 | 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 | |||
| 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,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(); |
| 753 | 753 | ||
| 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 @@ | ||
| 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,26 +1,28 @@ |
| 1 | const Elf = @This(); | ||
| 2 | |||
| 1 | const std = @import("std"); | 3 | const std = @import("std"); |
| 2 | const mem = std.mem; | 4 | const mem = std.mem; |
| 3 | const assert = std.debug.assert; | 5 | const assert = std.debug.assert; |
| 4 | const Allocator = std.mem.Allocator; | 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 | const fs = std.fs; | 7 | const fs = std.fs; |
| 9 | const elf = std.elf; | 8 | const elf = std.elf; |
| 10 | const codegen = @import("../codegen.zig"); | ||
| 11 | const log = std.log.scoped(.link); | 9 | const log = std.log.scoped(.link); |
| 12 | const DW = std.dwarf; | 10 | const DW = std.dwarf; |
| 13 | const trace = @import("../tracy.zig").trace; | ||
| 14 | const leb128 = std.debug.leb; | 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 | const Package = @import("../Package.zig"); | 18 | const Package = @import("../Package.zig"); |
| 16 | const Value = @import("../value.zig").Value; | 19 | const Value = @import("../value.zig").Value; |
| 17 | const Type = @import("../type.zig").Type; | 20 | const Type = @import("../type.zig").Type; |
| 18 | const link = @import("../link.zig"); | 21 | const link = @import("../link.zig"); |
| 19 | const File = link.File; | 22 | const File = link.File; |
| 20 | const Elf = @This(); | ||
| 21 | const build_options = @import("build_options"); | 23 | const build_options = @import("build_options"); |
| 22 | const target_util = @import("../target.zig"); | 24 | const target_util = @import("../target.zig"); |
| 23 | const fatal = @import("main.zig").fatal; | 25 | const glibc = @import("../glibc.zig"); |
| 24 | 26 | ||
| 25 | const default_entry_addr = 0x8000000; | 27 | const default_entry_addr = 0x8000000; |
| 26 | 28 | ||
| ... | @@ -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 | } |