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
396396 try addCxxKnownPath(b, ctx, exe, "libstdc++.a", null, need_cpp_includes);
397397 exe.linkSystemLibrary("pthread");
398398 // TODO LLD cannot perform this link.
399 // Set ZIG_SYSTEM_LINKER_HACK env var to use system linker ld instead.
399400 // See https://github.com/ziglang/zig/issues/1535
400 exe.enableSystemLinkerHack();
401401 } else |err| switch (err) {
402402 error.RequiredLibraryNotFound => {
403403 // System compiler, not gcc.
lib/std/build.zig-9
......@@ -1237,7 +1237,6 @@ pub const LibExeObjStep = struct {
12371237 packages: ArrayList(Pkg),
12381238 build_options_contents: std.ArrayList(u8),
12391239 build_options_artifact_args: std.ArrayList(BuildOptionArtifactArg),
1240 system_linker_hack: bool = false,
12411240
12421241 object_src: []const u8,
12431242
......@@ -1898,10 +1897,6 @@ pub const LibExeObjStep = struct {
18981897 self.exec_cmd_args = args;
18991898 }
19001899
1901 pub fn enableSystemLinkerHack(self: *LibExeObjStep) void {
1902 self.system_linker_hack = true;
1903 }
1904
19051900 fn linkLibraryOrObject(self: *LibExeObjStep, other: *LibExeObjStep) void {
19061901 self.step.dependOn(&other.step);
19071902 self.link_objects.append(LinkObject{ .OtherStep = other }) catch unreachable;
......@@ -2283,10 +2278,6 @@ pub const LibExeObjStep = struct {
22832278 }
22842279 }
22852280
2286 if (self.system_linker_hack) {
2287 try zig_args.append("--system-linker-hack");
2288 }
2289
22902281 if (self.valgrind_support) |valgrind_support| {
22912282 if (valgrind_support) {
22922283 try zig_args.append("-fvalgrind");
src/Compilation.zig+18-8
......@@ -472,13 +472,22 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
472472 break :blk false;
473473 };
474474
475 const syslibroot = if (build_options.have_llvm and comptime std.Target.current.isDarwin()) outer: {
476 const path = if (use_lld and options.is_native_os and options.target.isDarwin()) inner: {
477 const syslibroot_path = try std.zig.system.getSDKPath(arena);
478 break :inner syslibroot_path;
479 } else null;
480 break :outer path;
481 } else null;
475 const DarwinOptions = struct {
476 syslibroot: ?[]const u8 = null,
477 system_linker_hack: bool = false,
478 };
479
480 const darwin_options: DarwinOptions = if (build_options.have_llvm and comptime std.Target.current.isDarwin()) outer: {
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
483492 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 {
775784 .optimize_mode = options.optimize_mode,
776785 .use_lld = use_lld,
777786 .use_llvm = use_llvm,
787 .system_linker_hack = darwin_options.system_linker_hack,
778788 .link_libc = link_libc,
779789 .link_libcpp = options.link_libcpp,
780790 .objects = options.link_objects,
781791 .frameworks = options.frameworks,
782792 .framework_dirs = options.framework_dirs,
783793 .system_libs = system_libs,
784 .syslibroot = syslibroot,
794 .syslibroot = darwin_options.syslibroot,
785795 .lib_dirs = options.lib_dirs,
786796 .rpath_list = options.rpath_list,
787797 .strip = strip,
src/link.zig+3
......@@ -57,6 +57,9 @@ pub const Options = struct {
5757 /// other objects.
5858 /// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary.
5959 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,
6063 link_libc: bool,
6164 link_libcpp: bool,
6265 function_sections: bool,
src/link/MachO.zig+70-39
......@@ -532,11 +532,19 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
532532 // Create an LLD command line and invoke it.
533533 var argv = std.ArrayList([]const u8).init(self.base.allocator);
534534 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");
539 try argv.append("0");
536 // TODO https://github.com/ziglang/zig/issues/6971
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
541549 try argv.append("-demangle");
542550
......@@ -703,42 +711,65 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
703711 Compilation.dump_argv(argv.items);
704712 }
705713
706 const new_argv = try arena.allocSentinel(?[*:0]const u8, argv.items.len, null);
707 for (argv.items) |arg, i| {
708 new_argv[i] = try arena.dupeZ(u8, arg);
709 }
714 // TODO https://github.com/ziglang/zig/issues/6971
715 // Note that there is no need to check if running natively since we do that already
716 // when setting `system_linker_hack` in Compilation struct.
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 = .{
712 .macho = self,
713 .data = std.ArrayList(u8).init(self.base.allocator),
714 };
715 defer stderr_context.data.deinit();
716 var stdout_context: LLDContext = .{
717 .macho = self,
718 .data = std.ArrayList(u8).init(self.base.allocator),
719 };
720 defer stdout_context.data.deinit();
721 const llvm = @import("../llvm.zig");
722 const ok = llvm.Link(
723 .MachO,
724 new_argv.ptr,
725 new_argv.len,
726 append_diagnostic,
727 @ptrToInt(&stdout_context),
728 @ptrToInt(&stderr_context),
729 );
730 if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory;
731 if (stdout_context.data.items.len != 0) {
732 std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items});
733 }
734 if (!ok) {
735 // TODO parse this output and surface with the Compilation API rather than
736 // directly outputting to stderr here.
737 std.debug.print("{}", .{stderr_context.data.items});
738 return error.LLDReportedFailure;
739 }
740 if (stderr_context.data.items.len != 0) {
741 std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});
741 var stderr_context: LLDContext = .{
742 .macho = self,
743 .data = std.ArrayList(u8).init(self.base.allocator),
744 };
745 defer stderr_context.data.deinit();
746 var stdout_context: LLDContext = .{
747 .macho = self,
748 .data = std.ArrayList(u8).init(self.base.allocator),
749 };
750 defer stdout_context.data.deinit();
751 const llvm = @import("../llvm.zig");
752 const ok = llvm.Link(
753 .MachO,
754 new_argv.ptr,
755 new_argv.len,
756 append_diagnostic,
757 @ptrToInt(&stdout_context),
758 @ptrToInt(&stderr_context),
759 );
760 if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory;
761 if (stdout_context.data.items.len != 0) {
762 std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items});
763 }
764 if (!ok) {
765 // TODO parse this output and surface with the Compilation API rather than
766 // directly outputting to stderr here.
767 std.debug.print("{}", .{stderr_context.data.items});
768 return error.LLDReportedFailure;
769 }
770 if (stderr_context.data.items.len != 0) {
771 std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items});
772 }
742773 }
743774 }
744775