authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-06 13:22:03-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-11-06 13:22:03-05:00
loga9e09a8be4ff6a15dabb1362a6833e6b0af66b22
tree67236efd6bbb875d2eef2c7068826dcc2e1abed1
parenta1a16a941e6e04c0f6f0d17c4c9f13d2ba32a9a1
parentab69b89d528c828e949bb2d2f3632401a2d382fe
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

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

Re-enable system linker hack

5 files changed, 92 insertions(+), 57 deletions(-)

build.zig+1-1
...@@ -396,8 +396,8 @@ fn configureStage2(b: *Builder, exe: anytype, ctx: Context, need_cpp_includes: b...@@ -396,8 +396,8 @@ fn configureStage2(b: *Builder, exe: anytype, ctx: Context, need_cpp_includes: b
396 try addCxxKnownPath(b, ctx, exe, "libstdc++.a", null, need_cpp_includes);396 try addCxxKnownPath(b, ctx, exe, "libstdc++.a", null, need_cpp_includes);
397 exe.linkSystemLibrary("pthread");397 exe.linkSystemLibrary("pthread");
398 // TODO LLD cannot perform this link.398 // TODO LLD cannot perform this link.
399 // Set ZIG_SYSTEM_LINKER_HACK env var to use system linker ld instead.
399 // See https://github.com/ziglang/zig/issues/1535400 // See https://github.com/ziglang/zig/issues/1535
400 exe.enableSystemLinkerHack();
401 } else |err| switch (err) {401 } else |err| switch (err) {
402 error.RequiredLibraryNotFound => {402 error.RequiredLibraryNotFound => {
403 // System compiler, not gcc.403 // System compiler, not gcc.
lib/std/build.zig-9
...@@ -1237,7 +1237,6 @@ pub const LibExeObjStep = struct {...@@ -1237,7 +1237,6 @@ pub const LibExeObjStep = struct {
1237 packages: ArrayList(Pkg),1237 packages: ArrayList(Pkg),
1238 build_options_contents: std.ArrayList(u8),1238 build_options_contents: std.ArrayList(u8),
1239 build_options_artifact_args: std.ArrayList(BuildOptionArtifactArg),1239 build_options_artifact_args: std.ArrayList(BuildOptionArtifactArg),
1240 system_linker_hack: bool = false,
12411240
1242 object_src: []const u8,1241 object_src: []const u8,
12431242
...@@ -1898,10 +1897,6 @@ pub const LibExeObjStep = struct {...@@ -1898,10 +1897,6 @@ pub const LibExeObjStep = struct {
1898 self.exec_cmd_args = args;1897 self.exec_cmd_args = args;
1899 }1898 }
19001899
1901 pub fn enableSystemLinkerHack(self: *LibExeObjStep) void {
1902 self.system_linker_hack = true;
1903 }
1904
1905 fn linkLibraryOrObject(self: *LibExeObjStep, other: *LibExeObjStep) void {1900 fn linkLibraryOrObject(self: *LibExeObjStep, other: *LibExeObjStep) void {
1906 self.step.dependOn(&other.step);1901 self.step.dependOn(&other.step);
1907 self.link_objects.append(LinkObject{ .OtherStep = other }) catch unreachable;1902 self.link_objects.append(LinkObject{ .OtherStep = other }) catch unreachable;
...@@ -2283,10 +2278,6 @@ pub const LibExeObjStep = struct {...@@ -2283,10 +2278,6 @@ pub const LibExeObjStep = struct {
2283 }2278 }
2284 }2279 }
22852280
2286 if (self.system_linker_hack) {
2287 try zig_args.append("--system-linker-hack");
2288 }
2289
2290 if (self.valgrind_support) |valgrind_support| {2281 if (self.valgrind_support) |valgrind_support| {
2291 if (valgrind_support) {2282 if (valgrind_support) {
2292 try zig_args.append("-fvalgrind");2283 try zig_args.append("-fvalgrind");
src/Compilation.zig+18-8
...@@ -472,13 +472,22 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -472,13 +472,22 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
472 break :blk false;472 break :blk false;
473 };473 };
474474
475 const syslibroot = if (build_options.have_llvm and comptime std.Target.current.isDarwin()) outer: {475 const DarwinOptions = struct {
476 const path = if (use_lld and options.is_native_os and options.target.isDarwin()) inner: {476 syslibroot: ?[]const u8 = null,
477 const syslibroot_path = try std.zig.system.getSDKPath(arena);477 system_linker_hack: bool = false,
478 break :inner syslibroot_path;478 };
479 } else null;479
480 break :outer path;480 const darwin_options: DarwinOptions = if (build_options.have_llvm and comptime std.Target.current.isDarwin()) outer: {
481 } else null;481 const opts: DarwinOptions = if (use_lld and options.is_native_os and options.target.isDarwin()) inner: {
482 const syslibroot = try std.zig.system.getSDKPath(arena);
483 const system_linker_hack = std.os.getenv("ZIG_SYSTEM_LINKER_HACK") != null;
484 break :inner .{
485 .syslibroot = syslibroot,
486 .system_linker_hack = system_linker_hack,
487 };
488 } else .{};
489 break :outer opts;
490 } else .{};
482491
483 const link_libc = options.link_libc or target_util.osRequiresLibC(options.target);492 const link_libc = options.link_libc or target_util.osRequiresLibC(options.target);
484493
...@@ -775,13 +784,14 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -775,13 +784,14 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
775 .optimize_mode = options.optimize_mode,784 .optimize_mode = options.optimize_mode,
776 .use_lld = use_lld,785 .use_lld = use_lld,
777 .use_llvm = use_llvm,786 .use_llvm = use_llvm,
787 .system_linker_hack = darwin_options.system_linker_hack,
778 .link_libc = link_libc,788 .link_libc = link_libc,
779 .link_libcpp = options.link_libcpp,789 .link_libcpp = options.link_libcpp,
780 .objects = options.link_objects,790 .objects = options.link_objects,
781 .frameworks = options.frameworks,791 .frameworks = options.frameworks,
782 .framework_dirs = options.framework_dirs,792 .framework_dirs = options.framework_dirs,
783 .system_libs = system_libs,793 .system_libs = system_libs,
784 .syslibroot = syslibroot,794 .syslibroot = darwin_options.syslibroot,
785 .lib_dirs = options.lib_dirs,795 .lib_dirs = options.lib_dirs,
786 .rpath_list = options.rpath_list,796 .rpath_list = options.rpath_list,
787 .strip = strip,797 .strip = strip,
src/link.zig+3
...@@ -57,6 +57,9 @@ pub const Options = struct {...@@ -57,6 +57,9 @@ pub const Options = struct {
57 /// other objects.57 /// other objects.
58 /// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary.58 /// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary.
59 use_llvm: bool,59 use_llvm: bool,
60 /// Darwin-only. If this is true, `use_llvm` is true, and `is_native_os` is true, this link code will
61 /// use system linker `ld` instead of the LLD.
62 system_linker_hack: bool,
60 link_libc: bool,63 link_libc: bool,
61 link_libcpp: bool,64 link_libcpp: bool,
62 function_sections: bool,65 function_sections: bool,
src/link/MachO.zig+70-39
...@@ -532,11 +532,19 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {...@@ -532,11 +532,19 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
532 // Create an LLD command line and invoke it.532 // Create an LLD command line and invoke it.
533 var argv = std.ArrayList([]const u8).init(self.base.allocator);533 var argv = std.ArrayList([]const u8).init(self.base.allocator);
534 defer argv.deinit();534 defer argv.deinit();
535 // Even though we're calling LLD as a library it thinks the first argument is its own exe name.
536 try argv.append("lld");
537535
538 try argv.append("-error-limit");536 // TODO https://github.com/ziglang/zig/issues/6971
539 try argv.append("0");537 // Note that there is no need to check if running natively since we do that already
538 // when setting `system_linker_hack` in Compilation struct.
539 if (self.base.options.system_linker_hack) {
540 try argv.append("ld");
541 } else {
542 // Even though we're calling LLD as a library it thinks the first argument is its own exe name.
543 try argv.append("lld");
544
545 try argv.append("-error-limit");
546 try argv.append("0");
547 }
540548
541 try argv.append("-demangle");549 try argv.append("-demangle");
542550
...@@ -703,42 +711,65 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {...@@ -703,42 +711,65 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
703 Compilation.dump_argv(argv.items);711 Compilation.dump_argv(argv.items);
704 }712 }
705713
706 const new_argv = try arena.allocSentinel(?[*:0]const u8, argv.items.len, null);714 // TODO https://github.com/ziglang/zig/issues/6971
707 for (argv.items) |arg, i| {715 // Note that there is no need to check if running natively since we do that already
708 new_argv[i] = try arena.dupeZ(u8, arg);716 // when setting `system_linker_hack` in Compilation struct.
709 }717 if (self.base.options.system_linker_hack) {
718 const result = try std.ChildProcess.exec(.{ .allocator = self.base.allocator, .argv = argv.items });
719 defer {
720 self.base.allocator.free(result.stdout);
721 self.base.allocator.free(result.stderr);
722 }
723 if (result.stdout.len != 0) {
724 std.log.warn("unexpected LD stdout: {}", .{result.stdout});
725 }
726 if (result.stderr.len != 0) {
727 std.log.warn("unexpected LD stderr: {}", .{result.stderr});
728 }
729 if (result.term != .Exited or result.term.Exited != 0) {
730 // TODO parse this output and surface with the Compilation API rather than
731 // directly outputting to stderr here.
732 std.debug.print("{}", .{result.stderr});
733 return error.LDReportedFailure;
734 }
735 } else {
736 const new_argv = try arena.allocSentinel(?[*:0]const u8, argv.items.len, null);
737 for (argv.items) |arg, i| {
738 new_argv[i] = try arena.dupeZ(u8, arg);
739 }
710740
711 var stderr_context: LLDContext = .{741 var stderr_context: LLDContext = .{
712 .macho = self,742 .macho = self,
713 .data = std.ArrayList(u8).init(self.base.allocator),743 .data = std.ArrayList(u8).init(self.base.allocator),
714 };744 };
715 defer stderr_context.data.deinit();745 defer stderr_context.data.deinit();
716 var stdout_context: LLDContext = .{746 var stdout_context: LLDContext = .{
717 .macho = self,747 .macho = self,
718 .data = std.ArrayList(u8).init(self.base.allocator),748 .data = std.ArrayList(u8).init(self.base.allocator),
719 };749 };
720 defer stdout_context.data.deinit();750 defer stdout_context.data.deinit();
721 const llvm = @import("../llvm.zig");751 const llvm = @import("../llvm.zig");
722 const ok = llvm.Link(752 const ok = llvm.Link(
723 .MachO,753 .MachO,
724 new_argv.ptr,754 new_argv.ptr,
725 new_argv.len,755 new_argv.len,
726 append_diagnostic,756 append_diagnostic,
727 @ptrToInt(&stdout_context),757 @ptrToInt(&stdout_context),
728 @ptrToInt(&stderr_context),758 @ptrToInt(&stderr_context),
729 );759 );
730 if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory;760 if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory;
731 if (stdout_context.data.items.len != 0) {761 if (stdout_context.data.items.len != 0) {
732 std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items});762 std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items});
733 }763 }
734 if (!ok) {764 if (!ok) {
735 // TODO parse this output and surface with the Compilation API rather than765 // TODO parse this output and surface with the Compilation API rather than
736 // directly outputting to stderr here.766 // directly outputting to stderr here.
737 std.debug.print("{}", .{stderr_context.data.items});767 std.debug.print("{}", .{stderr_context.data.items});
738 return error.LLDReportedFailure;768 return error.LLDReportedFailure;
739 }769 }
740 if (stderr_context.data.items.len != 0) {770 if (stderr_context.data.items.len != 0) {
741 std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});771 std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});
772 }
742 }773 }
743 }774 }
744775