aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Rønne Petersen <alex@alexrp.com>2025-05-04 01:53:51 +0200
committerGitHub <noreply@github.com>2025-05-04 01:53:51 +0200
commitdffd18f133972cb2e1b0695340f8104c3cd3b5f8 (patch)
tree34b2ed2832ae2f4f772fd12d07eb5500d557b6a5
parentf4e9846bca69e20f907384cdad43b86a3aae1fb2 (diff)
parentd2f92e1797cf30c2fb0993d7e09de73e496144f5 (diff)
downloadzig-dffd18f133972cb2e1b0695340f8104c3cd3b5f8.tar.gz
zig-dffd18f133972cb2e1b0695340f8104c3cd3b5f8.zip
Merge pull request #23752 from alexrp/static-native-glibc
compiler: Allow linking native glibc statically
-rw-r--r--src/Compilation/Config.zig20
-rw-r--r--src/main.zig1
-rw-r--r--src/target.zig6
3 files changed, 20 insertions, 7 deletions
diff --git a/src/Compilation/Config.zig b/src/Compilation/Config.zig
index a4c69454b3..71df1d9311 100644
--- a/src/Compilation/Config.zig
+++ b/src/Compilation/Config.zig
@@ -129,6 +129,7 @@ pub const ResolveError = error{
LldCannotIncrementallyLink,
LtoRequiresLld,
SanitizeThreadRequiresLibCpp,
+ LibCRequiresLibUnwind,
LibCppRequiresLibUnwind,
OsRequiresLibC,
LibCppRequiresLibC,
@@ -312,8 +313,8 @@ pub fn resolve(options: Options) ResolveError!Config {
break :b false;
};
- const link_libunwind = b: {
- if (link_libcpp and target_util.libcNeedsLibUnwind(target)) {
+ var link_libunwind = b: {
+ if (link_libcpp and target_util.libCxxNeedsLibUnwind(target)) {
if (options.link_libunwind == false) return error.LibCppRequiresLibUnwind;
break :b true;
}
@@ -352,7 +353,7 @@ pub fn resolve(options: Options) ResolveError!Config {
break :b .static;
}
if (explicitly_exe_or_dyn_lib and link_libc and
- (target.isGnuLibC() or target_util.osRequiresLibC(target)))
+ (target_util.osRequiresLibC(target) or (target.isGnuLibC() and !options.resolved_target.is_native_abi)))
{
if (options.link_mode == .static) return error.LibCRequiresDynamicLinking;
break :b .dynamic;
@@ -367,11 +368,11 @@ pub fn resolve(options: Options) ResolveError!Config {
if (options.link_mode) |link_mode| break :b link_mode;
- if (explicitly_exe_or_dyn_lib and link_libc and
- options.resolved_target.is_native_abi and target.abi.isMusl())
+ if (explicitly_exe_or_dyn_lib and link_libc and options.resolved_target.is_native_abi and
+ (target.isGnuLibC() or target.isMuslLibC()))
{
// If targeting the system's native ABI and the system's libc is
- // musl, link dynamically by default.
+ // glibc or musl, link dynamically by default.
break :b .dynamic;
}
@@ -379,6 +380,13 @@ pub fn resolve(options: Options) ResolveError!Config {
break :b .static;
};
+ // This is done here to avoid excessive duplicated logic due to the complex dependencies between these options.
+ if (options.output_mode == .Exe and link_libc and target_util.libCNeedsLibUnwind(target, link_mode)) {
+ if (options.link_libunwind == false) return error.LibCRequiresLibUnwind;
+
+ link_libunwind = true;
+ }
+
const import_memory = options.import_memory orelse (options.output_mode == .Obj);
const export_memory = b: {
if (link_mode == .dynamic) {
diff --git a/src/main.zig b/src/main.zig
index cac0c78163..7eb5436ee5 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -4206,6 +4206,7 @@ fn createModule(
error.LldCannotIncrementallyLink => fatal("self-hosted backends do not support linking with LLD", .{}),
error.LtoRequiresLld => fatal("LTO requires using LLD", .{}),
error.SanitizeThreadRequiresLibCpp => fatal("thread sanitization is (for now) implemented in C++, so it requires linking libc++", .{}),
+ error.LibCRequiresLibUnwind => fatal("libc of the specified target requires linking libunwind", .{}),
error.LibCppRequiresLibUnwind => fatal("libc++ requires linking libunwind", .{}),
error.OsRequiresLibC => fatal("the target OS requires using libc as the stable syscall interface", .{}),
error.LibCppRequiresLibC => fatal("libc++ requires linking libc", .{}),
diff --git a/src/target.zig b/src/target.zig
index c9a8a6ab07..6b67de4562 100644
--- a/src/target.zig
+++ b/src/target.zig
@@ -23,7 +23,11 @@ pub fn osRequiresLibC(target: std.Target) bool {
return target.os.requiresLibC();
}
-pub fn libcNeedsLibUnwind(target: std.Target) bool {
+pub fn libCNeedsLibUnwind(target: std.Target, link_mode: std.builtin.LinkMode) bool {
+ return target.isGnuLibC() and link_mode == .static;
+}
+
+pub fn libCxxNeedsLibUnwind(target: std.Target) bool {
return switch (target.os.tag) {
.macos,
.ios,