aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-11-06 13:22:03 -0500
committerGitHub <noreply@github.com>2020-11-06 13:22:03 -0500
commita9e09a8be4ff6a15dabb1362a6833e6b0af66b22 (patch)
tree67236efd6bbb875d2eef2c7068826dcc2e1abed1
parenta1a16a941e6e04c0f6f0d17c4c9f13d2ba32a9a1 (diff)
parentab69b89d528c828e949bb2d2f3632401a2d382fe (diff)
downloadzig-a9e09a8be4ff6a15dabb1362a6833e6b0af66b22.tar.gz
zig-a9e09a8be4ff6a15dabb1362a6833e6b0af66b22.zip
Merge pull request #6990 from kubkon/system-linker-hack
Re-enable system linker hack
-rw-r--r--build.zig2
-rw-r--r--lib/std/build.zig9
-rw-r--r--src/Compilation.zig26
-rw-r--r--src/link.zig3
-rw-r--r--src/link/MachO.zig109
5 files changed, 92 insertions, 57 deletions
diff --git a/build.zig b/build.zig
index b4d8b71f79..ae6073f8be 100644
--- a/build.zig
+++ b/build.zig
@@ -396,8 +396,8 @@ fn configureStage2(b: *Builder, exe: anytype, ctx: Context, need_cpp_includes: b
try addCxxKnownPath(b, ctx, exe, "libstdc++.a", null, need_cpp_includes);
exe.linkSystemLibrary("pthread");
// TODO LLD cannot perform this link.
+ // Set ZIG_SYSTEM_LINKER_HACK env var to use system linker ld instead.
// See https://github.com/ziglang/zig/issues/1535
- exe.enableSystemLinkerHack();
} else |err| switch (err) {
error.RequiredLibraryNotFound => {
// System compiler, not gcc.
diff --git a/lib/std/build.zig b/lib/std/build.zig
index a1ac3f88f2..5666005fa4 100644
--- a/lib/std/build.zig
+++ b/lib/std/build.zig
@@ -1237,7 +1237,6 @@ pub const LibExeObjStep = struct {
packages: ArrayList(Pkg),
build_options_contents: std.ArrayList(u8),
build_options_artifact_args: std.ArrayList(BuildOptionArtifactArg),
- system_linker_hack: bool = false,
object_src: []const u8,
@@ -1898,10 +1897,6 @@ pub const LibExeObjStep = struct {
self.exec_cmd_args = args;
}
- pub fn enableSystemLinkerHack(self: *LibExeObjStep) void {
- self.system_linker_hack = true;
- }
-
fn linkLibraryOrObject(self: *LibExeObjStep, other: *LibExeObjStep) void {
self.step.dependOn(&other.step);
self.link_objects.append(LinkObject{ .OtherStep = other }) catch unreachable;
@@ -2283,10 +2278,6 @@ pub const LibExeObjStep = struct {
}
}
- if (self.system_linker_hack) {
- try zig_args.append("--system-linker-hack");
- }
-
if (self.valgrind_support) |valgrind_support| {
if (valgrind_support) {
try zig_args.append("-fvalgrind");
diff --git a/src/Compilation.zig b/src/Compilation.zig
index d4289fad34..36847f0437 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -472,13 +472,22 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
break :blk false;
};
- const syslibroot = if (build_options.have_llvm and comptime std.Target.current.isDarwin()) outer: {
- const path = if (use_lld and options.is_native_os and options.target.isDarwin()) inner: {
- const syslibroot_path = try std.zig.system.getSDKPath(arena);
- break :inner syslibroot_path;
- } else null;
- break :outer path;
- } else null;
+ const DarwinOptions = struct {
+ syslibroot: ?[]const u8 = null,
+ system_linker_hack: bool = false,
+ };
+
+ const darwin_options: DarwinOptions = if (build_options.have_llvm and comptime std.Target.current.isDarwin()) outer: {
+ const opts: DarwinOptions = if (use_lld and options.is_native_os and options.target.isDarwin()) inner: {
+ const syslibroot = try std.zig.system.getSDKPath(arena);
+ const system_linker_hack = std.os.getenv("ZIG_SYSTEM_LINKER_HACK") != null;
+ break :inner .{
+ .syslibroot = syslibroot,
+ .system_linker_hack = system_linker_hack,
+ };
+ } else .{};
+ break :outer opts;
+ } else .{};
const link_libc = options.link_libc or target_util.osRequiresLibC(options.target);
@@ -775,13 +784,14 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
.optimize_mode = options.optimize_mode,
.use_lld = use_lld,
.use_llvm = use_llvm,
+ .system_linker_hack = darwin_options.system_linker_hack,
.link_libc = link_libc,
.link_libcpp = options.link_libcpp,
.objects = options.link_objects,
.frameworks = options.frameworks,
.framework_dirs = options.framework_dirs,
.system_libs = system_libs,
- .syslibroot = syslibroot,
+ .syslibroot = darwin_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 02433ecde7..7b0271f978 100644
--- a/src/link.zig
+++ b/src/link.zig
@@ -57,6 +57,9 @@ pub const Options = struct {
/// other objects.
/// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary.
use_llvm: bool,
+ /// Darwin-only. If this is true, `use_llvm` is true, and `is_native_os` is true, this link code will
+ /// use system linker `ld` instead of the LLD.
+ system_linker_hack: bool,
link_libc: bool,
link_libcpp: bool,
function_sections: bool,
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 01830c1561..6fbd1265d5 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -532,11 +532,19 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
// Create an LLD command line and invoke it.
var argv = std.ArrayList([]const u8).init(self.base.allocator);
defer argv.deinit();
- // Even though we're calling LLD as a library it thinks the first argument is its own exe name.
- try argv.append("lld");
- try argv.append("-error-limit");
- try argv.append("0");
+ // TODO https://github.com/ziglang/zig/issues/6971
+ // Note that there is no need to check if running natively since we do that already
+ // when setting `system_linker_hack` in Compilation struct.
+ if (self.base.options.system_linker_hack) {
+ try argv.append("ld");
+ } else {
+ // Even though we're calling LLD as a library it thinks the first argument is its own exe name.
+ try argv.append("lld");
+
+ try argv.append("-error-limit");
+ try argv.append("0");
+ }
try argv.append("-demangle");
@@ -703,42 +711,65 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
Compilation.dump_argv(argv.items);
}
- const new_argv = try arena.allocSentinel(?[*:0]const u8, argv.items.len, null);
- for (argv.items) |arg, i| {
- new_argv[i] = try arena.dupeZ(u8, arg);
- }
+ // TODO https://github.com/ziglang/zig/issues/6971
+ // Note that there is no need to check if running natively since we do that already
+ // when setting `system_linker_hack` in Compilation struct.
+ if (self.base.options.system_linker_hack) {
+ const result = try std.ChildProcess.exec(.{ .allocator = self.base.allocator, .argv = argv.items });
+ defer {
+ self.base.allocator.free(result.stdout);
+ self.base.allocator.free(result.stderr);
+ }
+ if (result.stdout.len != 0) {
+ std.log.warn("unexpected LD stdout: {}", .{result.stdout});
+ }
+ if (result.stderr.len != 0) {
+ std.log.warn("unexpected LD stderr: {}", .{result.stderr});
+ }
+ if (result.term != .Exited or result.term.Exited != 0) {
+ // TODO parse this output and surface with the Compilation API rather than
+ // directly outputting to stderr here.
+ std.debug.print("{}", .{result.stderr});
+ return error.LDReportedFailure;
+ }
+ } else {
+ const new_argv = try arena.allocSentinel(?[*:0]const u8, argv.items.len, null);
+ for (argv.items) |arg, i| {
+ new_argv[i] = try arena.dupeZ(u8, arg);
+ }
- var stderr_context: LLDContext = .{
- .macho = self,
- .data = std.ArrayList(u8).init(self.base.allocator),
- };
- defer stderr_context.data.deinit();
- var stdout_context: LLDContext = .{
- .macho = self,
- .data = std.ArrayList(u8).init(self.base.allocator),
- };
- defer stdout_context.data.deinit();
- const llvm = @import("../llvm.zig");
- const ok = llvm.Link(
- .MachO,
- new_argv.ptr,
- new_argv.len,
- append_diagnostic,
- @ptrToInt(&stdout_context),
- @ptrToInt(&stderr_context),
- );
- if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory;
- if (stdout_context.data.items.len != 0) {
- std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items});
- }
- if (!ok) {
- // TODO parse this output and surface with the Compilation API rather than
- // directly outputting to stderr here.
- std.debug.print("{}", .{stderr_context.data.items});
- return error.LLDReportedFailure;
- }
- if (stderr_context.data.items.len != 0) {
- std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});
+ var stderr_context: LLDContext = .{
+ .macho = self,
+ .data = std.ArrayList(u8).init(self.base.allocator),
+ };
+ defer stderr_context.data.deinit();
+ var stdout_context: LLDContext = .{
+ .macho = self,
+ .data = std.ArrayList(u8).init(self.base.allocator),
+ };
+ defer stdout_context.data.deinit();
+ const llvm = @import("../llvm.zig");
+ const ok = llvm.Link(
+ .MachO,
+ new_argv.ptr,
+ new_argv.len,
+ append_diagnostic,
+ @ptrToInt(&stdout_context),
+ @ptrToInt(&stderr_context),
+ );
+ if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory;
+ if (stdout_context.data.items.len != 0) {
+ std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items});
+ }
+ if (!ok) {
+ // TODO parse this output and surface with the Compilation API rather than
+ // directly outputting to stderr here.
+ std.debug.print("{}", .{stderr_context.data.items});
+ return error.LLDReportedFailure;
+ }
+ if (stderr_context.data.items.len != 0) {
+ std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});
+ }
}
}