| ... | @@ -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 | } |
| 354 | | 354 | |
| | 355 | const 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 | |
| 355 | pub fn parseFromStub(self: *Dylib, allocator: *Allocator, target: std.Target, lib_stub: LibStub) !void { | 391 | pub 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; |
| 357 | | 393 | |
| ... | @@ -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; |
| 370 | | 406 | |
| 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(); |
| 373 | | 409 | |
| 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(); |
| 376 | | 412 | |
| 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; |
| 379 | | 415 | |
| 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 |
| 386 | | 422 | |
| 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; |
| 390 | | 426 | |
| 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 |
| 405 | | 441 | |
| 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; |
| 409 | | 445 | |
| 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 |
| 433 | | 469 | |
| 434 | // TODO track which libs were already parsed in different steps | 470 | // 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; |
| 437 | | 473 | |
| 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; |
| 441 | | 477 | |
| 442 | for (reexp.libraries) |lib| { | 478 | for (reexp.libraries) |lib| { |
| 443 | if (umbrella_libs.contains(lib)) { | 479 | if (umbrella_libs.contains(lib)) { |