| author | |
| committer | |
| log | 88d1258e08e668e620d5f8f4681315e555acbcd2 |
| tree | 930e8dabe93e60af9fc4f0e54c17e07db2672aa1 |
| parent | acec06cfaf9a82ec8037a23993ff36fa72eb6e82 |
Previously, Zig ignored -lgcc_s with a warning that this dependency is
redundant because it is satisfied by compiler-rt. However, sfackler
pointed out that it also provides exception handling functions. So if
Zig sees -lgcc_s on the linker line, it needs to fulfill this dependency
with libunwind.
I also made link_libc inferred to be on if libunwind is linked since
libunwind depends on libc.3 files changed, 27 insertions(+), 14 deletions(-)
src/Compilation.zig+1-1| ... | @@ -962,7 +962,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -962,7 +962,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 962 | const tsan = options.want_tsan orelse false; | 962 | const tsan = options.want_tsan orelse false; |
| 963 | // TSAN is implemented in C++ so it requires linking libc++. | 963 | // TSAN is implemented in C++ so it requires linking libc++. |
| 964 | const link_libcpp = options.link_libcpp or tsan; | 964 | const link_libcpp = options.link_libcpp or tsan; |
| 965 | const link_libc = link_libcpp or options.link_libc or | 965 | const link_libc = link_libcpp or options.link_libc or options.link_libunwind or |
| 966 | target_util.osRequiresLibC(options.target); | 966 | target_util.osRequiresLibC(options.target); |
| 967 | 967 | ||
| 968 | const link_libunwind = options.link_libunwind or | 968 | const link_libunwind = options.link_libunwind or |
src/main.zig+14-9| ... | @@ -2048,19 +2048,24 @@ fn buildOutputType( | ... | @@ -2048,19 +2048,24 @@ fn buildOutputType( |
| 2048 | system_libs.orderedRemoveAt(i); | 2048 | system_libs.orderedRemoveAt(i); |
| 2049 | continue; | 2049 | continue; |
| 2050 | } | 2050 | } |
| 2051 | if (mem.eql(u8, lib_name, "unwind")) { | 2051 | switch (target_util.classifyCompilerRtLibName(target_info.target, lib_name)) { |
| 2052 | link_libunwind = true; | 2052 | .none => {}, |
| 2053 | system_libs.orderedRemoveAt(i); | 2053 | .only_libunwind, .both => { |
| 2054 | continue; | 2054 | link_libunwind = true; |
| 2055 | } | 2055 | system_libs.orderedRemoveAt(i); |
| 2056 | if (target_util.is_compiler_rt_lib_name(target_info.target, lib_name)) { | 2056 | continue; |
| 2057 | std.log.warn("ignoring superfluous library '{s}': this dependency is fulfilled instead by compiler-rt which zig unconditionally provides", .{lib_name}); | 2057 | }, |
| 2058 | system_libs.orderedRemoveAt(i); | 2058 | .only_compiler_rt => { |
| 2059 | continue; | 2059 | std.log.warn("ignoring superfluous library '{s}': this dependency is fulfilled instead by compiler-rt which zig unconditionally provides", .{lib_name}); |
| 2060 | system_libs.orderedRemoveAt(i); | ||
| 2061 | continue; | ||
| 2062 | }, | ||
| 2060 | } | 2063 | } |
| 2064 | |||
| 2061 | if (std.fs.path.isAbsolute(lib_name)) { | 2065 | if (std.fs.path.isAbsolute(lib_name)) { |
| 2062 | fatal("cannot use absolute path as a system library: {s}", .{lib_name}); | 2066 | fatal("cannot use absolute path as a system library: {s}", .{lib_name}); |
| 2063 | } | 2067 | } |
| 2068 | |||
| 2064 | if (target_info.target.os.tag == .wasi) { | 2069 | if (target_info.target.os.tag == .wasi) { |
| 2065 | if (wasi_libc.getEmulatedLibCRTFile(lib_name)) |crt_file| { | 2070 | if (wasi_libc.getEmulatedLibCRTFile(lib_name)) |crt_file| { |
| 2066 | try wasi_emulated_libs.append(crt_file); | 2071 | try wasi_emulated_libs.append(crt_file); |
src/target.zig+12-4| ... | @@ -427,14 +427,22 @@ pub fn is_libcpp_lib_name(target: std.Target, name: []const u8) bool { | ... | @@ -427,14 +427,22 @@ pub fn is_libcpp_lib_name(target: std.Target, name: []const u8) bool { |
| 427 | eqlIgnoreCase(ignore_case, name, "c++abi"); | 427 | eqlIgnoreCase(ignore_case, name, "c++abi"); |
| 428 | } | 428 | } |
| 429 | 429 | ||
| 430 | pub fn is_compiler_rt_lib_name(target: std.Target, name: []const u8) bool { | 430 | pub const CompilerRtClassification = enum { none, only_compiler_rt, only_libunwind, both }; |
| 431 | |||
| 432 | pub fn classifyCompilerRtLibName(target: std.Target, name: []const u8) CompilerRtClassification { | ||
| 431 | if (target.abi.isGnu() and std.mem.eql(u8, name, "gcc_s")) { | 433 | if (target.abi.isGnu() and std.mem.eql(u8, name, "gcc_s")) { |
| 432 | return true; | 434 | // libgcc_s includes exception handling functions, so if linking this library |
| 435 | // is requested, zig needs to instead link libunwind. Otherwise we end up with | ||
| 436 | // the linker unable to find `_Unwind_RaiseException` and other related symbols. | ||
| 437 | return .both; | ||
| 433 | } | 438 | } |
| 434 | if (std.mem.eql(u8, name, "compiler_rt")) { | 439 | if (std.mem.eql(u8, name, "compiler_rt")) { |
| 435 | return true; | 440 | return .only_compiler_rt; |
| 436 | } | 441 | } |
| 437 | return false; | 442 | if (std.mem.eql(u8, name, "unwind")) { |
| 443 | return .only_libunwind; | ||
| 444 | } | ||
| 445 | return .none; | ||
| 438 | } | 446 | } |
| 439 | 447 | ||
| 440 | pub fn hasDebugInfo(target: std.Target) bool { | 448 | pub fn hasDebugInfo(target: std.Target) bool { |