commit
a9e09a8be4
|
@ -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);
|
try addCxxKnownPath(b, ctx, exe, "libstdc++.a", null, need_cpp_includes);
|
||||||
exe.linkSystemLibrary("pthread");
|
exe.linkSystemLibrary("pthread");
|
||||||
// TODO LLD cannot perform this link.
|
// 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
|
// See https://github.com/ziglang/zig/issues/1535
|
||||||
exe.enableSystemLinkerHack();
|
|
||||||
} else |err| switch (err) {
|
} else |err| switch (err) {
|
||||||
error.RequiredLibraryNotFound => {
|
error.RequiredLibraryNotFound => {
|
||||||
// System compiler, not gcc.
|
// System compiler, not gcc.
|
||||||
|
|
|
@ -1237,7 +1237,6 @@ pub const LibExeObjStep = struct {
|
||||||
packages: ArrayList(Pkg),
|
packages: ArrayList(Pkg),
|
||||||
build_options_contents: std.ArrayList(u8),
|
build_options_contents: std.ArrayList(u8),
|
||||||
build_options_artifact_args: std.ArrayList(BuildOptionArtifactArg),
|
build_options_artifact_args: std.ArrayList(BuildOptionArtifactArg),
|
||||||
system_linker_hack: bool = false,
|
|
||||||
|
|
||||||
object_src: []const u8,
|
object_src: []const u8,
|
||||||
|
|
||||||
|
@ -1898,10 +1897,6 @@ pub const LibExeObjStep = struct {
|
||||||
self.exec_cmd_args = args;
|
self.exec_cmd_args = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enableSystemLinkerHack(self: *LibExeObjStep) void {
|
|
||||||
self.system_linker_hack = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn linkLibraryOrObject(self: *LibExeObjStep, other: *LibExeObjStep) void {
|
fn linkLibraryOrObject(self: *LibExeObjStep, other: *LibExeObjStep) void {
|
||||||
self.step.dependOn(&other.step);
|
self.step.dependOn(&other.step);
|
||||||
self.link_objects.append(LinkObject{ .OtherStep = other }) catch unreachable;
|
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 (self.valgrind_support) |valgrind_support| {
|
||||||
if (valgrind_support) {
|
if (valgrind_support) {
|
||||||
try zig_args.append("-fvalgrind");
|
try zig_args.append("-fvalgrind");
|
||||||
|
|
|
@ -472,13 +472,22 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||||
break :blk false;
|
break :blk false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const syslibroot = if (build_options.have_llvm and comptime std.Target.current.isDarwin()) outer: {
|
const DarwinOptions = struct {
|
||||||
const path = if (use_lld and options.is_native_os and options.target.isDarwin()) inner: {
|
syslibroot: ?[]const u8 = null,
|
||||||
const syslibroot_path = try std.zig.system.getSDKPath(arena);
|
system_linker_hack: bool = false,
|
||||||
break :inner syslibroot_path;
|
};
|
||||||
} else null;
|
|
||||||
break :outer path;
|
const darwin_options: DarwinOptions = if (build_options.have_llvm and comptime std.Target.current.isDarwin()) outer: {
|
||||||
} else null;
|
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);
|
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,
|
.optimize_mode = options.optimize_mode,
|
||||||
.use_lld = use_lld,
|
.use_lld = use_lld,
|
||||||
.use_llvm = use_llvm,
|
.use_llvm = use_llvm,
|
||||||
|
.system_linker_hack = darwin_options.system_linker_hack,
|
||||||
.link_libc = link_libc,
|
.link_libc = link_libc,
|
||||||
.link_libcpp = options.link_libcpp,
|
.link_libcpp = options.link_libcpp,
|
||||||
.objects = options.link_objects,
|
.objects = options.link_objects,
|
||||||
.frameworks = options.frameworks,
|
.frameworks = options.frameworks,
|
||||||
.framework_dirs = options.framework_dirs,
|
.framework_dirs = options.framework_dirs,
|
||||||
.system_libs = system_libs,
|
.system_libs = system_libs,
|
||||||
.syslibroot = syslibroot,
|
.syslibroot = darwin_options.syslibroot,
|
||||||
.lib_dirs = options.lib_dirs,
|
.lib_dirs = options.lib_dirs,
|
||||||
.rpath_list = options.rpath_list,
|
.rpath_list = options.rpath_list,
|
||||||
.strip = strip,
|
.strip = strip,
|
||||||
|
|
|
@ -57,6 +57,9 @@ pub const Options = struct {
|
||||||
/// other objects.
|
/// other objects.
|
||||||
/// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary.
|
/// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary.
|
||||||
use_llvm: bool,
|
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_libc: bool,
|
||||||
link_libcpp: bool,
|
link_libcpp: bool,
|
||||||
function_sections: bool,
|
function_sections: bool,
|
||||||
|
|
|
@ -532,11 +532,19 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
|
||||||
// Create an LLD command line and invoke it.
|
// Create an LLD command line and invoke it.
|
||||||
var argv = std.ArrayList([]const u8).init(self.base.allocator);
|
var argv = std.ArrayList([]const u8).init(self.base.allocator);
|
||||||
defer argv.deinit();
|
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");
|
// TODO https://github.com/ziglang/zig/issues/6971
|
||||||
try argv.append("0");
|
// 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");
|
try argv.append("-demangle");
|
||||||
|
|
||||||
|
@ -703,42 +711,65 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
|
||||||
Compilation.dump_argv(argv.items);
|
Compilation.dump_argv(argv.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
const new_argv = try arena.allocSentinel(?[*:0]const u8, argv.items.len, null);
|
// TODO https://github.com/ziglang/zig/issues/6971
|
||||||
for (argv.items) |arg, i| {
|
// Note that there is no need to check if running natively since we do that already
|
||||||
new_argv[i] = try arena.dupeZ(u8, arg);
|
// 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 = .{
|
var stderr_context: LLDContext = .{
|
||||||
.macho = self,
|
.macho = self,
|
||||||
.data = std.ArrayList(u8).init(self.base.allocator),
|
.data = std.ArrayList(u8).init(self.base.allocator),
|
||||||
};
|
};
|
||||||
defer stderr_context.data.deinit();
|
defer stderr_context.data.deinit();
|
||||||
var stdout_context: LLDContext = .{
|
var stdout_context: LLDContext = .{
|
||||||
.macho = self,
|
.macho = self,
|
||||||
.data = std.ArrayList(u8).init(self.base.allocator),
|
.data = std.ArrayList(u8).init(self.base.allocator),
|
||||||
};
|
};
|
||||||
defer stdout_context.data.deinit();
|
defer stdout_context.data.deinit();
|
||||||
const llvm = @import("../llvm.zig");
|
const llvm = @import("../llvm.zig");
|
||||||
const ok = llvm.Link(
|
const ok = llvm.Link(
|
||||||
.MachO,
|
.MachO,
|
||||||
new_argv.ptr,
|
new_argv.ptr,
|
||||||
new_argv.len,
|
new_argv.len,
|
||||||
append_diagnostic,
|
append_diagnostic,
|
||||||
@ptrToInt(&stdout_context),
|
@ptrToInt(&stdout_context),
|
||||||
@ptrToInt(&stderr_context),
|
@ptrToInt(&stderr_context),
|
||||||
);
|
);
|
||||||
if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory;
|
if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory;
|
||||||
if (stdout_context.data.items.len != 0) {
|
if (stdout_context.data.items.len != 0) {
|
||||||
std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items});
|
std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items});
|
||||||
}
|
}
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
// TODO parse this output and surface with the Compilation API rather than
|
// TODO parse this output and surface with the Compilation API rather than
|
||||||
// directly outputting to stderr here.
|
// directly outputting to stderr here.
|
||||||
std.debug.print("{}", .{stderr_context.data.items});
|
std.debug.print("{}", .{stderr_context.data.items});
|
||||||
return error.LLDReportedFailure;
|
return error.LLDReportedFailure;
|
||||||
}
|
}
|
||||||
if (stderr_context.data.items.len != 0) {
|
if (stderr_context.data.items.len != 0) {
|
||||||
std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});
|
std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue