| ... | @@ -92,6 +92,9 @@ headerpad_size: ?u32, | ... | @@ -92,6 +92,9 @@ headerpad_size: ?u32, |
| 92 | headerpad_max_install_names: bool, | 92 | headerpad_max_install_names: bool, |
| 93 | /// Remove dylibs that are unreachable by the entry point or exported symbols. | 93 | /// Remove dylibs that are unreachable by the entry point or exported symbols. |
| 94 | dead_strip_dylibs: bool, | 94 | dead_strip_dylibs: bool, |
| | 95 | /// Treatment of undefined symbols |
| | 96 | undefined_treatment: UndefinedTreatment, |
| | 97 | /// List of input frameworks |
| 95 | frameworks: []const Framework, | 98 | frameworks: []const Framework, |
| 96 | /// Install name for the dylib. | 99 | /// Install name for the dylib. |
| 97 | /// TODO: unify with soname | 100 | /// TODO: unify with soname |
| ... | @@ -122,14 +125,6 @@ pub fn hashAddFrameworks(man: *Cache.Manifest, hm: []const Framework) !void { | ... | @@ -122,14 +125,6 @@ pub fn hashAddFrameworks(man: *Cache.Manifest, hm: []const Framework) !void { |
| 122 | } | 125 | } |
| 123 | } | 126 | } |
| 124 | | 127 | |
| 125 | /// The filesystem layout of darwin SDK elements. | | |
| 126 | pub const SdkLayout = enum { | | |
| 127 | /// macOS SDK layout: TOP { /usr/include, /usr/lib, /System/Library/Frameworks }. | | |
| 128 | sdk, | | |
| 129 | /// Shipped libc layout: TOP { /lib/libc/include, /lib/libc/darwin, <NONE> }. | | |
| 130 | vendored, | | |
| 131 | }; | | |
| 132 | | | |
| 133 | pub fn createEmpty( | 128 | pub fn createEmpty( |
| 134 | arena: Allocator, | 129 | arena: Allocator, |
| 135 | comp: *Compilation, | 130 | comp: *Compilation, |
| ... | @@ -153,6 +148,7 @@ pub fn createEmpty( | ... | @@ -153,6 +148,7 @@ pub fn createEmpty( |
| 153 | null | 148 | null |
| 154 | else | 149 | else |
| 155 | try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path}); | 150 | try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path}); |
| | 151 | const allow_shlib_undefined = options.allow_shlib_undefined orelse false; |
| 156 | | 152 | |
| 157 | const self = try arena.create(MachO); | 153 | const self = try arena.create(MachO); |
| 158 | self.* = .{ | 154 | self.* = .{ |
| ... | @@ -164,7 +160,7 @@ pub fn createEmpty( | ... | @@ -164,7 +160,7 @@ pub fn createEmpty( |
| 164 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug), | 160 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug), |
| 165 | .print_gc_sections = options.print_gc_sections, | 161 | .print_gc_sections = options.print_gc_sections, |
| 166 | .stack_size = options.stack_size orelse 16777216, | 162 | .stack_size = options.stack_size orelse 16777216, |
| 167 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, | 163 | .allow_shlib_undefined = allow_shlib_undefined, |
| 168 | .file = null, | 164 | .file = null, |
| 169 | .disable_lld_caching = options.disable_lld_caching, | 165 | .disable_lld_caching = options.disable_lld_caching, |
| 170 | .build_id = options.build_id, | 166 | .build_id = options.build_id, |
| ... | @@ -187,6 +183,7 @@ pub fn createEmpty( | ... | @@ -187,6 +183,7 @@ pub fn createEmpty( |
| 187 | }, | 183 | }, |
| 188 | .platform = Platform.fromTarget(target), | 184 | .platform = Platform.fromTarget(target), |
| 189 | .sdk_version = if (options.darwin_sdk_layout) |layout| inferSdkVersion(comp, layout) else null, | 185 | .sdk_version = if (options.darwin_sdk_layout) |layout| inferSdkVersion(comp, layout) else null, |
| | 186 | .undefined_treatment = if (allow_shlib_undefined) .dynamic_lookup else .@"error", |
| 190 | }; | 187 | }; |
| 191 | if (use_llvm and comp.config.have_zcu) { | 188 | if (use_llvm and comp.config.have_zcu) { |
| 192 | self.llvm_object = try LlvmObject.create(arena, comp); | 189 | self.llvm_object = try LlvmObject.create(arena, comp); |
| ... | @@ -502,6 +499,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node | ... | @@ -502,6 +499,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node |
| 502 | | 499 | |
| 503 | try self.convertTentativeDefinitions(); | 500 | try self.convertTentativeDefinitions(); |
| 504 | try self.createObjcSections(); | 501 | try self.createObjcSections(); |
| | 502 | try self.claimUnresolved(); |
| 505 | | 503 | |
| 506 | state_log.debug("{}", .{self.dumpState()}); | 504 | state_log.debug("{}", .{self.dumpState()}); |
| 507 | | 505 | |
| ... | @@ -1310,6 +1308,39 @@ fn createObjcSections(self: *MachO) !void { | ... | @@ -1310,6 +1308,39 @@ fn createObjcSections(self: *MachO) !void { |
| 1310 | } | 1308 | } |
| 1311 | } | 1309 | } |
| 1312 | | 1310 | |
| | 1311 | fn claimUnresolved(self: *MachO) error{OutOfMemory}!void { |
| | 1312 | for (self.objects.items) |index| { |
| | 1313 | const object = self.getFile(index).?.object; |
| | 1314 | |
| | 1315 | for (object.symbols.items, 0..) |sym_index, i| { |
| | 1316 | const nlist_idx = @as(Symbol.Index, @intCast(i)); |
| | 1317 | const nlist = object.symtab.items(.nlist)[nlist_idx]; |
| | 1318 | if (!nlist.ext()) continue; |
| | 1319 | if (!nlist.undf()) continue; |
| | 1320 | |
| | 1321 | const sym = self.getSymbol(sym_index); |
| | 1322 | if (sym.getFile(self) != null) continue; |
| | 1323 | |
| | 1324 | const is_import = switch (self.undefined_treatment) { |
| | 1325 | .@"error" => false, |
| | 1326 | .warn, .suppress => nlist.weakRef(), |
| | 1327 | .dynamic_lookup => true, |
| | 1328 | }; |
| | 1329 | if (is_import) { |
| | 1330 | sym.value = 0; |
| | 1331 | sym.atom = 0; |
| | 1332 | sym.nlist_idx = 0; |
| | 1333 | sym.file = self.internal_object.?; |
| | 1334 | sym.flags.weak = false; |
| | 1335 | sym.flags.weak_ref = nlist.weakRef(); |
| | 1336 | sym.flags.import = is_import; |
| | 1337 | sym.visibility = .global; |
| | 1338 | try self.getInternalObject().?.symbols.append(self.base.comp.gpa, sym_index); |
| | 1339 | } |
| | 1340 | } |
| | 1341 | } |
| | 1342 | } |
| | 1343 | |
| 1313 | fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void { | 1344 | fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void { |
| 1314 | _ = self; | 1345 | _ = self; |
| 1315 | _ = atom_index; | 1346 | _ = atom_index; |
| ... | @@ -2350,6 +2381,21 @@ const SystemLib = struct { | ... | @@ -2350,6 +2381,21 @@ const SystemLib = struct { |
| 2350 | must_link: bool = false, | 2381 | must_link: bool = false, |
| 2351 | }; | 2382 | }; |
| 2352 | | 2383 | |
| | 2384 | /// The filesystem layout of darwin SDK elements. |
| | 2385 | pub const SdkLayout = enum { |
| | 2386 | /// macOS SDK layout: TOP { /usr/include, /usr/lib, /System/Library/Frameworks }. |
| | 2387 | sdk, |
| | 2388 | /// Shipped libc layout: TOP { /lib/libc/include, /lib/libc/darwin, <NONE> }. |
| | 2389 | vendored, |
| | 2390 | }; |
| | 2391 | |
| | 2392 | const UndefinedTreatment = enum { |
| | 2393 | @"error", |
| | 2394 | warn, |
| | 2395 | suppress, |
| | 2396 | dynamic_lookup, |
| | 2397 | }; |
| | 2398 | |
| 2353 | const MachO = @This(); | 2399 | const MachO = @This(); |
| 2354 | | 2400 | |
| 2355 | const std = @import("std"); | 2401 | const std = @import("std"); |