| ... | ... | @@ -352,6 +352,42 @@ fn targetToAppleString(allocator: *Allocator, target: std.Target) ![]const u8 { |
| 352 | 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 | 391 | pub fn parseFromStub(self: *Dylib, allocator: *Allocator, target: std.Target, lib_stub: LibStub) !void { |
| 356 | 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 | 404 | } |
| 369 | 405 | self.id = id; |
| 370 | 406 | |
| 371 | | const target_string = try targetToAppleString(allocator, target); |
| 372 | | defer allocator.free(target_string); |
| 407 | var matcher = try TargetMatcher.init(allocator, target); |
| 408 | defer matcher.deinit(); |
| 373 | 409 | |
| 374 | 410 | var umbrella_libs = std.StringHashMap(void).init(allocator); |
| 375 | 411 | defer umbrella_libs.deinit(); |
| 376 | 412 | |
| 377 | 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 | 416 | if (stub_index > 0) { |
| 381 | 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 | 422 | |
| 387 | 423 | if (stub.exports) |exports| { |
| 388 | 424 | for (exports) |exp| { |
| 389 | | if (!hasTarget(exp.targets, target_string)) continue; |
| 425 | if (!matcher.matches(exp.targets)) continue; |
| 390 | 426 | |
| 391 | 427 | if (exp.symbols) |symbols| { |
| 392 | 428 | for (symbols) |sym_name| { |
| ... | ... | @@ -405,7 +441,7 @@ pub fn parseFromStub(self: *Dylib, allocator: *Allocator, target: std.Target, li |
| 405 | 441 | |
| 406 | 442 | if (stub.reexports) |reexports| { |
| 407 | 443 | for (reexports) |reexp| { |
| 408 | | if (!hasTarget(reexp.targets, target_string)) continue; |
| 444 | if (!matcher.matches(reexp.targets)) continue; |
| 409 | 445 | |
| 410 | 446 | if (reexp.symbols) |symbols| { |
| 411 | 447 | for (symbols) |sym_name| { |
| ... | ... | @@ -433,11 +469,11 @@ pub fn parseFromStub(self: *Dylib, allocator: *Allocator, target: std.Target, li |
| 433 | 469 | |
| 434 | 470 | // TODO track which libs were already parsed in different steps |
| 435 | 471 | for (lib_stub.inner) |stub| { |
| 436 | | if (!hasTarget(stub.targets, target_string)) continue; |
| 472 | if (!matcher.matches(stub.targets)) continue; |
| 437 | 473 | |
| 438 | 474 | if (stub.reexported_libraries) |reexports| { |
| 439 | 475 | for (reexports) |reexp| { |
| 440 | | if (!hasTarget(reexp.targets, target_string)) continue; |
| 476 | if (!matcher.matches(reexp.targets)) continue; |
| 441 | 477 | |
| 442 | 478 | for (reexp.libraries) |lib| { |
| 443 | 479 | if (umbrella_libs.contains(lib)) { |