Commit e3575cdad4

Jakub Konka <kubkon@jakubkonka.com>
2021-07-13 22:58:25
zld: decommision use_lld for MachO
Invoke `linkAsArchive` directly in MachO backend when LLVM is available and we are asked to create a static lib.
1 parent 398672e
src/link/MachO.zig
@@ -341,7 +341,6 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
     assert(options.object_format == .macho);
 
     if (options.use_llvm) return error.LLVM_BackendIsTODO_ForMachO; // TODO
-    if (options.use_lld) return error.LLD_LinkingIsTODO_ForMachO; // TODO
 
     const file = try options.emit.?.directory.handle.createFile(sub_path, .{
         .truncate = false,
@@ -358,6 +357,10 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
 
     self.base.file = file;
 
+    if (options.output_mode == .Lib and options.link_mode == .Static) {
+        return self;
+    }
+
     if (!options.strip and options.module != null) {
         // Create dSYM bundle.
         const dir = options.module.?.zig_cache_artifact_directory;
@@ -393,12 +396,6 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
         .n_value = 0,
     });
 
-    switch (options.output_mode) {
-        .Exe => {},
-        .Obj => {},
-        .Lib => return error.TODOImplementWritingLibFiles,
-    }
-
     try self.populateMissingMetadata();
     try self.writeLocalSymbol(0);
 
@@ -428,6 +425,15 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*MachO {
 }
 
 pub fn flush(self: *MachO, comp: *Compilation) !void {
+    if (self.base.options.output_mode == .Lib and self.base.options.link_mode == .Static) {
+        if (build_options.have_llvm) {
+            return self.base.linkAsArchive(comp);
+        } else {
+            log.err("TODO: non-LLVM archiver for MachO object files", .{});
+            return error.TODOImplementWritingStaticLibFiles;
+        }
+    }
+
     if (build_options.have_llvm and self.base.options.use_lld) {
         return self.linkWithZld(comp);
     } else {
src/Compilation.zig
@@ -866,6 +866,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
 
         // Make a decision on whether to use LLD or our own linker.
         const use_lld = options.use_lld orelse blk: {
+            if (options.target.isDarwin()) {
+                break :blk false;
+            }
+
             if (!build_options.have_llvm)
                 break :blk false;
 
@@ -903,11 +907,9 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
             break :blk false;
         };
 
-        const darwin_can_use_system_sdk =
-            // comptime conditions
-            ((build_options.have_llvm and comptime std.Target.current.isDarwin()) and
-            // runtime conditions
-            (use_lld and std.builtin.os.tag == .macos and options.target.isDarwin()));
+        const darwin_can_use_system_sdk = comptime std.Target.current.isDarwin() and
+            std.builtin.os.tag == .macos and
+            options.target.isDarwin();
 
         const sysroot = blk: {
             if (options.sysroot) |sysroot| {
@@ -924,10 +926,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
 
         const lto = blk: {
             if (options.want_lto) |explicit| {
-                if (!use_lld)
+                if (!use_lld and !options.target.isDarwin())
                     return error.LtoUnavailableWithoutLld;
                 break :blk explicit;
-            } else if (!use_lld) {
+            } else if (!use_lld and !options.target.isDarwin()) {
                 break :blk false;
             } else if (options.c_source_files.len == 0) {
                 break :blk false;
src/link.zig
@@ -515,7 +515,7 @@ pub const File = struct {
         }
     }
 
-    fn linkAsArchive(base: *File, comp: *Compilation) !void {
+    pub fn linkAsArchive(base: *File, comp: *Compilation) !void {
         const tracy = trace(@src());
         defer tracy.end();
 
src/main.zig
@@ -1646,6 +1646,12 @@ fn buildOutputType(
         }
     }
 
+    if (use_lld) |opt| {
+        if (opt and cross_target.isDarwin()) {
+            fatal("-fLLD requested with Mach-O object format. Only the self-hosted linker is supported for this target.", .{});
+        }
+    }
+
     if (comptime std.Target.current.isDarwin()) {
         // If we want to link against frameworks, we need system headers.
         if (framework_dirs.items.len > 0 or frameworks.items.len > 0)