From f8372d030e50b6eec50fd21a387b4d875f81a178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 6 Dec 2024 14:00:49 +0100 Subject: [PATCH 1/7] compiler: Classify libatomic as an alias for compiler-rt. This is a library that ships with GCC and provides fallback implementations of atomic intrinsics where necessary. Since we do the same in our compiler-rt implementation, and since some build systems insist on passing -latomic even for Clang (which zig cc masquerades as), just satisfy this dependency by way of compiler-rt. Closes #22165. --- src/target.zig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/target.zig b/src/target.zig index 6297d21bfc80..ae3a8e7ecc5f 100644 --- a/src/target.zig +++ b/src/target.zig @@ -267,7 +267,9 @@ pub fn classifyCompilerRtLibName(target: std.Target, name: []const u8) CompilerR // the linker unable to find `_Unwind_RaiseException` and other related symbols. return .both; } - if (std.mem.eql(u8, name, "compiler_rt")) { + if (std.mem.eql(u8, name, "compiler_rt") or + std.mem.eql(u8, name, "atomic")) + { return .only_compiler_rt; } if (std.mem.eql(u8, name, "unwind")) { From 37a34b54afee183f397cf708ac8d074fa7cc92d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 6 Dec 2024 14:07:15 +0100 Subject: [PATCH 2/7] compiler: Recognize libgcc_s regardless of target ABI. The real libgcc_s is a compiler-provided library; it works just fine with both glibc and musl. There's no reason that I can see for this check to be limited to glibc-based targets. --- src/main.zig | 2 +- src/target.zig | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.zig b/src/main.zig index 0d239f1f99f0..b946447cc680 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3832,7 +3832,7 @@ fn createModule( create_module.opts.link_libcpp = true; continue; } - switch (target_util.classifyCompilerRtLibName(target, lib_name)) { + switch (target_util.classifyCompilerRtLibName(lib_name)) { .none => {}, .only_libunwind, .both => { create_module.opts.link_libunwind = true; diff --git a/src/target.zig b/src/target.zig index ae3a8e7ecc5f..56069c26b20f 100644 --- a/src/target.zig +++ b/src/target.zig @@ -260,8 +260,8 @@ pub fn supportsReturnAddress(target: std.Target) bool { pub const CompilerRtClassification = enum { none, only_compiler_rt, only_libunwind, both }; -pub fn classifyCompilerRtLibName(target: std.Target, name: []const u8) CompilerRtClassification { - if (target.abi.isGnu() and std.mem.eql(u8, name, "gcc_s")) { +pub fn classifyCompilerRtLibName(name: []const u8) CompilerRtClassification { + if (std.mem.eql(u8, name, "gcc_s")) { // libgcc_s includes exception handling functions, so if linking this library // is requested, zig needs to instead link libunwind. Otherwise we end up with // the linker unable to find `_Unwind_RaiseException` and other related symbols. From e7169e9d4d6baa6d5f7db1852a3b7389e2688f46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 6 Dec 2024 14:12:18 +0100 Subject: [PATCH 3/7] compiler: Classify libgcc_eh as an alias for libunwind. This is GCC's take on libunwind. We can satisfy it by way of our bundled LLVM libunwind implementation. Closes #17268. --- src/target.zig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/target.zig b/src/target.zig index 56069c26b20f..b7f7da40e8f4 100644 --- a/src/target.zig +++ b/src/target.zig @@ -272,7 +272,9 @@ pub fn classifyCompilerRtLibName(name: []const u8) CompilerRtClassification { { return .only_compiler_rt; } - if (std.mem.eql(u8, name, "unwind")) { + if (std.mem.eql(u8, name, "unwind") or + std.mem.eql(u8, name, "gcc_eh")) + { return .only_libunwind; } return .none; From a879c3ea0b6cf46c879b0c92925fd6024c2d4ca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 6 Dec 2024 14:41:34 +0100 Subject: [PATCH 4/7] compiler: Classify libgcc as an alias for compiler-rt. This is GCC's equivalent to compiler-rt. The two libraries have a huge overlap in exported symbols, so we may as well satisfy it this way to increase compatibility with build systems in the wild. --- src/target.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/target.zig b/src/target.zig index b7f7da40e8f4..bfa65c0178ac 100644 --- a/src/target.zig +++ b/src/target.zig @@ -268,6 +268,7 @@ pub fn classifyCompilerRtLibName(name: []const u8) CompilerRtClassification { return .both; } if (std.mem.eql(u8, name, "compiler_rt") or + std.mem.eql(u8, name, "gcc") or std.mem.eql(u8, name, "atomic")) { return .only_compiler_rt; From da794ec7a3f6c0aab04561f1d5e0d248f9a806e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 6 Dec 2024 14:44:24 +0100 Subject: [PATCH 5/7] compiler: Remove warning about superfluous compiler-rt libraries. * This warning's wording is actually inaccurate when using the -fno-compiler-rt or -rtlib=none options. * It's not all that helpful; it's already understood that these libraries are part of the compiler, so printing a warning is just noise. In practice, this warning would always happen when building upstream musl, for example. * We don't warn when we satisfy -lunwind using our bundled libunwind either, or various libc libraries using our bundled libc, or when providing libc++, etc. So I really don't think we should be warning here either. --- src/main.zig | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main.zig b/src/main.zig index b946447cc680..cf2d37d08603 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3838,10 +3838,7 @@ fn createModule( create_module.opts.link_libunwind = true; continue; }, - .only_compiler_rt => { - warn("ignoring superfluous library '{s}': this dependency is fulfilled instead by compiler-rt which zig unconditionally provides", .{lib_name}); - continue; - }, + .only_compiler_rt => continue, } if (target.isMinGW()) { From 65cfc91836adfc4e9ef852b571b6a4f38b943284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 6 Dec 2024 15:08:43 +0100 Subject: [PATCH 6/7] std.zig.target: Consider libsupc++ to be a libc++ library name. This is, roughly, GCC's equivalent of libc++abi. --- lib/std/zig/target.zig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/std/zig/target.zig b/lib/std/zig/target.zig index b9116f557f41..1785eb94e66b 100644 --- a/lib/std/zig/target.zig +++ b/lib/std/zig/target.zig @@ -263,7 +263,8 @@ pub fn isLibCxxLibName(target: std.Target, name: []const u8) bool { return eqlIgnoreCase(ignore_case, name, "c++") or eqlIgnoreCase(ignore_case, name, "stdc++") or - eqlIgnoreCase(ignore_case, name, "c++abi"); + eqlIgnoreCase(ignore_case, name, "c++abi") or + eqlIgnoreCase(ignore_case, name, "supc++"); } fn eqlIgnoreCase(ignore_case: bool, a: []const u8, b: []const u8) bool { From 8f27fc6c072590f4e9047542ee56b85fd133633d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 6 Dec 2024 15:10:37 +0100 Subject: [PATCH 7/7] compiler: Classify libssp as an alias for compiler-rt. This is a GCC library providing symbols with stack smashing protection. We provide (most of) these symbols in our compiler-rt. --- src/target.zig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/target.zig b/src/target.zig index bfa65c0178ac..e796b8e27185 100644 --- a/src/target.zig +++ b/src/target.zig @@ -269,7 +269,8 @@ pub fn classifyCompilerRtLibName(name: []const u8) CompilerRtClassification { } if (std.mem.eql(u8, name, "compiler_rt") or std.mem.eql(u8, name, "gcc") or - std.mem.eql(u8, name, "atomic")) + std.mem.eql(u8, name, "atomic") or + std.mem.eql(u8, name, "ssp")) { return .only_compiler_rt; }