| ... | @@ -150,6 +150,7 @@ no_implicit_dylibs: bool = false, | ... | @@ -150,6 +150,7 @@ no_implicit_dylibs: bool = false, |
| 150 | /// Whether the linker should parse and always force load objects containing ObjC in archives. | 150 | /// Whether the linker should parse and always force load objects containing ObjC in archives. |
| 151 | // TODO: in Zig we currently take -ObjC as always on | 151 | // TODO: in Zig we currently take -ObjC as always on |
| 152 | force_load_objc: bool = true, | 152 | force_load_objc: bool = true, |
| | 153 | rpaths: std.ArrayListUnmanaged([]const u8) = .{}, |
| 153 | | 154 | |
| 154 | /// Hot-code swapping state. | 155 | /// Hot-code swapping state. |
| 155 | hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{}, | 156 | hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{}, |
| ... | @@ -192,7 +193,7 @@ pub fn createEmpty( | ... | @@ -192,7 +193,7 @@ pub fn createEmpty( |
| 192 | null | 193 | null |
| 193 | else | 194 | else |
| 194 | try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path}); | 195 | try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path}); |
| 195 | const allow_shlib_undefined = options.allow_shlib_undefined orelse comp.config.any_sanitize_thread; | 196 | const allow_shlib_undefined = options.allow_shlib_undefined orelse false; |
| 196 | | 197 | |
| 197 | const self = try arena.create(MachO); | 198 | const self = try arena.create(MachO); |
| 198 | self.* = .{ | 199 | self.* = .{ |
| ... | @@ -358,6 +359,8 @@ pub fn deinit(self: *MachO) void { | ... | @@ -358,6 +359,8 @@ pub fn deinit(self: *MachO) void { |
| 358 | } | 359 | } |
| 359 | self.thunks.deinit(gpa); | 360 | self.thunks.deinit(gpa); |
| 360 | self.unwind_records.deinit(gpa); | 361 | self.unwind_records.deinit(gpa); |
| | 362 | |
| | 363 | self.rpaths.deinit(gpa); |
| 361 | } | 364 | } |
| 362 | | 365 | |
| 363 | pub fn flush(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 366 | pub fn flush(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { |
| ... | @@ -395,6 +398,9 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -395,6 +398,9 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) |
| 395 | if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path); | 398 | if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path); |
| 396 | if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path); | 399 | if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path); |
| 397 | | 400 | |
| | 401 | try self.rpaths.ensureUnusedCapacity(gpa, self.base.rpath_list.len); |
| | 402 | self.rpaths.appendSliceAssumeCapacity(self.base.rpath_list); |
| | 403 | |
| 398 | var positionals = std.ArrayList(Compilation.LinkObject).init(gpa); | 404 | var positionals = std.ArrayList(Compilation.LinkObject).init(gpa); |
| 399 | defer positionals.deinit(); | 405 | defer positionals.deinit(); |
| 400 | | 406 | |
| ... | @@ -413,7 +419,10 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -413,7 +419,10 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) |
| 413 | | 419 | |
| 414 | // TSAN | 420 | // TSAN |
| 415 | if (comp.config.any_sanitize_thread) { | 421 | if (comp.config.any_sanitize_thread) { |
| 416 | try positionals.append(.{ .path = comp.tsan_static_lib.?.full_object_path }); | 422 | const path = comp.tsan_dynamic_lib.?.full_object_path; |
| | 423 | try positionals.append(.{ .path = path }); |
| | 424 | const basename = std.fs.path.dirname(path) orelse "."; |
| | 425 | try self.rpaths.append(gpa, basename); |
| 417 | } | 426 | } |
| 418 | | 427 | |
| 419 | for (positionals.items) |obj| { | 428 | for (positionals.items) |obj| { |
| ... | @@ -771,7 +780,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void { | ... | @@ -771,7 +780,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void { |
| 771 | try argv.append(syslibroot); | 780 | try argv.append(syslibroot); |
| 772 | } | 781 | } |
| 773 | | 782 | |
| 774 | for (self.base.rpath_list) |rpath| { | 783 | for (self.rpaths.items) |rpath| { |
| 775 | try argv.append("-rpath"); | 784 | try argv.append("-rpath"); |
| 776 | try argv.append(rpath); | 785 | try argv.append(rpath); |
| 777 | } | 786 | } |
| ... | @@ -831,7 +840,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void { | ... | @@ -831,7 +840,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void { |
| 831 | } | 840 | } |
| 832 | | 841 | |
| 833 | if (comp.config.any_sanitize_thread) { | 842 | if (comp.config.any_sanitize_thread) { |
| 834 | try argv.append(comp.tsan_static_lib.?.full_object_path); | 843 | try argv.append(comp.tsan_dynamic_lib.?.full_object_path); |
| 835 | } | 844 | } |
| 836 | | 845 | |
| 837 | for (self.lib_dirs) |lib_dir| { | 846 | for (self.lib_dirs) |lib_dir| { |
| ... | @@ -3015,8 +3024,8 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { | ... | @@ -3015,8 +3024,8 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { |
| 3015 | ncmds += 1; | 3024 | ncmds += 1; |
| 3016 | } | 3025 | } |
| 3017 | | 3026 | |
| 3018 | try load_commands.writeRpathLCs(self.base.rpath_list, writer); | 3027 | try load_commands.writeRpathLCs(self.rpaths.items, writer); |
| 3019 | ncmds += self.base.rpath_list.len; | 3028 | ncmds += self.rpaths.items.len; |
| 3020 | | 3029 | |
| 3021 | try writer.writeStruct(macho.source_version_command{ .version = 0 }); | 3030 | try writer.writeStruct(macho.source_version_command{ .version = 0 }); |
| 3022 | ncmds += 1; | 3031 | ncmds += 1; |