Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions src/Compilation/Config.zig
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ pub const ResolveError = error{
LldCannotIncrementallyLink,
LtoRequiresLld,
SanitizeThreadRequiresLibCpp,
LibCRequiresLibUnwind,
LibCppRequiresLibUnwind,
OsRequiresLibC,
LibCppRequiresLibC,
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -367,18 +368,25 @@ 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;
}

// Static is generally a better default. Fight me.
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) {
Expand Down
1 change: 1 addition & 0 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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", .{}),
Expand Down
6 changes: 5 additions & 1 deletion src/target.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading