Merge pull request #6990 from kubkon/system-linker-hack

Re-enable system linker hack
master
Andrew Kelley 2020-11-06 13:22:03 -05:00 committed by GitHub
commit a9e09a8be4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 92 additions and 57 deletions

View File

@ -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.

View File

@ -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");

View File

@ -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,

View File

@ -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,

View File

@ -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();
// 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,6 +711,28 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
Compilation.dump_argv(argv.items);
}
// 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);
@ -741,6 +771,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});
}
}
}
if (!self.base.options.disable_lld_caching) {
// Update the file with the digest. If it fails we can continue; it only