authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-09 00:05:37+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-10 13:41:10+02:00
log509fe33d10e4e89a351678f4d466f30a7870ebcf
tree586178dc0f24bf9875e58a830af1e2fdde51af2f
parent9ab8d065b6ebc2db40f680d0de4a558297327ee3

macho: when targeting simulator, match host dylibs too

otherwise, linking may fail as some libc functions are provided by the host when simulating a different OS such iPhoneOS.

1 files changed, 43 insertions(+), 7 deletions(-)

src/link/MachO/Dylib.zig+43-7
...@@ -352,6 +352,42 @@ fn targetToAppleString(allocator: *Allocator, target: std.Target) ![]const u8 {...@@ -352,6 +352,42 @@ fn targetToAppleString(allocator: *Allocator, target: std.Target) ![]const u8 {
352 return std.fmt.allocPrint(allocator, "{s}-{s}", .{ arch, os });352 return std.fmt.allocPrint(allocator, "{s}-{s}", .{ arch, os });
353}353}
354354
355const TargetMatcher = struct {
356 allocator: *Allocator,
357 target_strings: std.ArrayListUnmanaged([]const u8) = .{},
358
359 fn init(allocator: *Allocator, target: std.Target) !TargetMatcher {
360 var self = TargetMatcher{ .allocator = allocator };
361 try self.target_strings.append(allocator, try targetToAppleString(allocator, target));
362
363 if (target.abi == .simulator) {
364 // For Apple simulator targets, linking gets tricky as we need to link against the simulator
365 // hosts dylibs too.
366 const host_target = try targetToAppleString(allocator, (std.zig.CrossTarget{
367 .cpu_arch = target.cpu.arch,
368 .os_tag = .macos,
369 }).toTarget());
370 try self.target_strings.append(allocator, host_target);
371 }
372
373 return self;
374 }
375
376 fn deinit(self: *TargetMatcher) void {
377 for (self.target_strings.items) |t| {
378 self.allocator.free(t);
379 }
380 self.target_strings.deinit(self.allocator);
381 }
382
383 fn matches(self: TargetMatcher, targets: []const []const u8) bool {
384 for (self.target_strings.items) |t| {
385 if (hasTarget(targets, t)) return true;
386 }
387 return false;
388 }
389};
390
355pub fn parseFromStub(self: *Dylib, allocator: *Allocator, target: std.Target, lib_stub: LibStub) !void {391pub fn parseFromStub(self: *Dylib, allocator: *Allocator, target: std.Target, lib_stub: LibStub) !void {
356 if (lib_stub.inner.len == 0) return error.EmptyStubFile;392 if (lib_stub.inner.len == 0) return error.EmptyStubFile;
357393
...@@ -368,14 +404,14 @@ pub fn parseFromStub(self: *Dylib, allocator: *Allocator, target: std.Target, li...@@ -368,14 +404,14 @@ pub fn parseFromStub(self: *Dylib, allocator: *Allocator, target: std.Target, li
368 }404 }
369 self.id = id;405 self.id = id;
370406
371 const target_string = try targetToAppleString(allocator, target);407 var matcher = try TargetMatcher.init(allocator, target);
372 defer allocator.free(target_string);408 defer matcher.deinit();
373409
374 var umbrella_libs = std.StringHashMap(void).init(allocator);410 var umbrella_libs = std.StringHashMap(void).init(allocator);
375 defer umbrella_libs.deinit();411 defer umbrella_libs.deinit();
376412
377 for (lib_stub.inner) |stub, stub_index| {413 for (lib_stub.inner) |stub, stub_index| {
378 if (!hasTarget(stub.targets, target_string)) continue;414 if (!matcher.matches(stub.targets)) continue;
379415
380 if (stub_index > 0) {416 if (stub_index > 0) {
381 // TODO I thought that we could switch on presence of `parent-umbrella` map;417 // TODO I thought that we could switch on presence of `parent-umbrella` map;
...@@ -386,7 +422,7 @@ pub fn parseFromStub(self: *Dylib, allocator: *Allocator, target: std.Target, li...@@ -386,7 +422,7 @@ pub fn parseFromStub(self: *Dylib, allocator: *Allocator, target: std.Target, li
386422
387 if (stub.exports) |exports| {423 if (stub.exports) |exports| {
388 for (exports) |exp| {424 for (exports) |exp| {
389 if (!hasTarget(exp.targets, target_string)) continue;425 if (!matcher.matches(exp.targets)) continue;
390426
391 if (exp.symbols) |symbols| {427 if (exp.symbols) |symbols| {
392 for (symbols) |sym_name| {428 for (symbols) |sym_name| {
...@@ -405,7 +441,7 @@ pub fn parseFromStub(self: *Dylib, allocator: *Allocator, target: std.Target, li...@@ -405,7 +441,7 @@ pub fn parseFromStub(self: *Dylib, allocator: *Allocator, target: std.Target, li
405441
406 if (stub.reexports) |reexports| {442 if (stub.reexports) |reexports| {
407 for (reexports) |reexp| {443 for (reexports) |reexp| {
408 if (!hasTarget(reexp.targets, target_string)) continue;444 if (!matcher.matches(reexp.targets)) continue;
409445
410 if (reexp.symbols) |symbols| {446 if (reexp.symbols) |symbols| {
411 for (symbols) |sym_name| {447 for (symbols) |sym_name| {
...@@ -433,11 +469,11 @@ pub fn parseFromStub(self: *Dylib, allocator: *Allocator, target: std.Target, li...@@ -433,11 +469,11 @@ pub fn parseFromStub(self: *Dylib, allocator: *Allocator, target: std.Target, li
433469
434 // TODO track which libs were already parsed in different steps470 // TODO track which libs were already parsed in different steps
435 for (lib_stub.inner) |stub| {471 for (lib_stub.inner) |stub| {
436 if (!hasTarget(stub.targets, target_string)) continue;472 if (!matcher.matches(stub.targets)) continue;
437473
438 if (stub.reexported_libraries) |reexports| {474 if (stub.reexported_libraries) |reexports| {
439 for (reexports) |reexp| {475 for (reexports) |reexp| {
440 if (!hasTarget(reexp.targets, target_string)) continue;476 if (!matcher.matches(reexp.targets)) continue;
441477
442 for (reexp.libraries) |lib| {478 for (reexp.libraries) |lib| {
443 if (umbrella_libs.contains(lib)) {479 if (umbrella_libs.contains(lib)) {