aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2020-11-02 09:04:18 +0100
committerJakub Konka <kubkon@jakubkonka.com>2020-11-02 17:06:09 +0100
commit317c555a5cdc52612e998d8b4bcbaf730be1a6f1 (patch)
tree0c414e11cfb2de91e0c7ee6485d784f61dc4330a /src
parent909aae8153e7ac71197bc9f864e4ceb2793317f2 (diff)
downloadzig-317c555a5cdc52612e998d8b4bcbaf730be1a6f1.tar.gz
zig-317c555a5cdc52612e998d8b4bcbaf730be1a6f1.zip
Fix linking issues on BigSur
This commit fixes linking issue on macOS 11 BigSur by appending a prefix path to all lib and framework search paths known as `-syslibroot`. The reason this is needed is that in macOS 11, the system libraries and frameworks are no longer readily available in the filesystem. Instead, the new macOS ships with a built-in dynamic linker cache of all system-provided libraries, and hence, when linking with either `lld.ld64` or `ld64`, it is required to pass in `-syslibroot [dir]`. The latter can usually be obtained by invoking `xcrun --show-sdk-path`. With this commit, Zig will do this automatically when compiling natively on macOS. However, it also provides a flag `-syslibroot` which can be used to overwrite the automtically populated value. To summarise, with this change, the user of Zig is not required to generate and append their own syslibroot path. Standard invocations such as `zig build-exe hello.zig` or `zig build` for projects will work out of the box. The only missing bit is `zig cc` and `zig c++` since the addition of the `-syslibroot` option would be a mismatch between the values provided by `clang` itself and Zig's wrapper.
Diffstat (limited to 'src')
-rw-r--r--src/Compilation.zig2
-rw-r--r--src/link.zig2
-rw-r--r--src/link/MachO.zig5
-rw-r--r--src/main.zig28
4 files changed, 36 insertions, 1 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 472f367b91..872eb1a78b 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -333,6 +333,7 @@ pub const InitOptions = struct {
keep_source_files_loaded: bool = false,
clang_argv: []const []const u8 = &[0][]const u8{},
lld_argv: []const []const u8 = &[0][]const u8{},
+ syslibroot: ?[]const u8 = null,
lib_dirs: []const []const u8 = &[0][]const u8{},
rpath_list: []const []const u8 = &[0][]const u8{},
c_source_files: []const CSourceFile = &[0]CSourceFile{},
@@ -773,6 +774,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
.frameworks = options.frameworks,
.framework_dirs = options.framework_dirs,
.system_libs = system_libs,
+ .syslibroot = options.syslibroot,
.lib_dirs = options.lib_dirs,
.rpath_list = options.rpath_list,
.strip = strip,
diff --git a/src/link.zig b/src/link.zig
index 3f6ceb7ac3..02433ecde7 100644
--- a/src/link.zig
+++ b/src/link.zig
@@ -88,6 +88,8 @@ pub const Options = struct {
llvm_cpu_features: ?[*:0]const u8,
/// Extra args passed directly to LLD. Ignored when not linking with LLD.
extra_lld_args: []const []const u8,
+ /// Darwin-only. Set the root path to the system libraries and frameworks.
+ syslibroot: ?[]const u8,
objects: []const []const u8,
framework_dirs: []const []const u8,
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 7344a698f9..01830c1561 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -628,6 +628,11 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
}
}
+ if (self.base.options.syslibroot) |dir| {
+ try argv.append("-syslibroot");
+ try argv.append(dir);
+ }
+
for (self.base.options.lib_dirs) |lib_dir| {
try argv.append("-L");
try argv.append(lib_dir);
diff --git a/src/main.zig b/src/main.zig
index 45fcb5ce61..87cd3e9dc7 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -315,8 +315,9 @@ const usage_build_generic =
\\ --subsystem [subsystem] (windows) /SUBSYSTEM:<subsystem> to the linker\n"
\\ --stack [size] Override default stack size
\\ --image-base [addr] Set base address for executable image
+ \\ -syslibroot [dir] (darwin) prepend a prefix to all search paths
\\ -framework [name] (darwin) link against framework
- \\ -F[dir] (darwin) add search path for frameworks
+ \\ -F [dir] (darwin) add search path for frameworks
\\
\\Test Options:
\\ --test-filter [text] Skip tests that do not match filter
@@ -492,6 +493,7 @@ fn buildOutputType(
var main_pkg_path: ?[]const u8 = null;
var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no;
var subsystem: ?std.Target.SubSystem = null;
+ var syslibroot: ?[]const u8 = null;
var system_libs = std.ArrayList([]const u8).init(gpa);
defer system_libs.deinit();
@@ -682,6 +684,10 @@ fn buildOutputType(
if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg});
i += 1;
try lib_dirs.append(args[i]);
+ } else if (mem.eql(u8, arg, "-syslibroot")) {
+ if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg});
+ i += 1;
+ syslibroot = args[i];
} else if (mem.eql(u8, arg, "-F")) {
if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg});
i += 1;
@@ -1380,6 +1386,12 @@ fn buildOutputType(
}
}
+ if (cross_target.isNativeOs() and std.Target.current.isDarwin()) {
+ if (syslibroot == null) {
+ syslibroot = try std.zig.system.getSDKPath(arena);
+ }
+ }
+
const object_format: std.Target.ObjectFormat = blk: {
const ofmt = target_ofmt orelse break :blk target_info.target.getObjectFormat();
if (mem.eql(u8, ofmt, "elf")) {
@@ -1628,6 +1640,7 @@ fn buildOutputType(
.rpath_list = rpath_list.items,
.c_source_files = c_source_files.items,
.link_objects = link_objects.items,
+ .syslibroot = syslibroot,
.framework_dirs = framework_dirs.items,
.frameworks = frameworks.items,
.system_libs = system_libs.items,
@@ -2159,6 +2172,7 @@ pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
var override_lib_dir: ?[]const u8 = null;
var override_global_cache_dir: ?[]const u8 = null;
var override_local_cache_dir: ?[]const u8 = null;
+ var syslibroot: ?[]const u8 = null;
var child_argv = std.ArrayList([]const u8).init(arena);
const argv_index_exe = child_argv.items.len;
@@ -2200,6 +2214,11 @@ pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
override_global_cache_dir = args[i];
try child_argv.appendSlice(&[_][]const u8{ arg, args[i] });
continue;
+ } else if (mem.eql(u8, arg, "--syslibroot")) {
+ if (i + 1 >= args.len) fatal("expected argument after '{}'", .{arg});
+ i += 1;
+ syslibroot = args[i];
+ continue;
}
}
try child_argv.append(arg);
@@ -2305,6 +2324,12 @@ pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
const cross_target: std.zig.CrossTarget = .{};
const target_info = try detectNativeTargetInfo(gpa, cross_target);
+ if (cross_target.isNativeOs() and target_info.target.isDarwin()) {
+ if (syslibroot == null) {
+ syslibroot = try std.zig.system.getSDKPath(arena);
+ }
+ }
+
const exe_basename = try std.zig.binNameAlloc(arena, .{
.root_name = "build",
.target = target_info.target,
@@ -2328,6 +2353,7 @@ pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
.target = target_info.target,
.is_native_os = cross_target.isNativeOs(),
.dynamic_linker = target_info.dynamic_linker.get(),
+ .syslibroot = syslibroot,
.output_mode = .Exe,
.root_pkg = &root_pkg,
.emit_bin = emit_bin,