authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-24 18:43:38+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-24 20:27:23+02:00
log5e0e7b2cb4b568e244a4b0b4eb51d8faeb3fb226
treec4e49d6a466182267f81a09aa2b17c70eb70260d
parent8669e3d46b24fcd6b6aa1053a16cf5301ed0e87a

zld: exclude libs part of the umbrella

when parsing the umbrella lib

2 files changed, 34 insertions(+), 19 deletions(-)

src/link/MachO/Dylib.zig+34-16
...@@ -62,7 +62,6 @@ pub fn createAndParseFromPath(...@@ -62,7 +62,6 @@ pub fn createAndParseFromPath(
62 arch: Arch,62 arch: Arch,
63 path: []const u8,63 path: []const u8,
64 syslibroot: ?[]const u8,64 syslibroot: ?[]const u8,
65 recurse_libs: bool,
66) Error!?[]*Dylib {65) Error!?[]*Dylib {
67 const file = fs.cwd().openFile(path, .{}) catch |err| switch (err) {66 const file = fs.cwd().openFile(path, .{}) catch |err| switch (err) {
68 error.FileNotFound => return null,67 error.FileNotFound => return null,
...@@ -102,11 +101,9 @@ pub fn createAndParseFromPath(...@@ -102,11 +101,9 @@ pub fn createAndParseFromPath(
102101
103 var dylibs = std.ArrayList(*Dylib).init(allocator);102 var dylibs = std.ArrayList(*Dylib).init(allocator);
104 defer dylibs.deinit();103 defer dylibs.deinit();
105 try dylibs.append(dylib);
106104
107 if (recurse_libs) {105 try dylibs.append(dylib);
108 try dylib.parseDependentLibs(&dylibs);106 try dylib.parseDependentLibs(&dylibs);
109 }
110107
111 return dylibs.toOwnedSlice();108 return dylibs.toOwnedSlice();
112}109}
...@@ -283,18 +280,17 @@ pub fn parseFromStub(self: *Dylib, lib_stub: LibStub) !void {...@@ -283,18 +280,17 @@ pub fn parseFromStub(self: *Dylib, lib_stub: LibStub) !void {
283 else => unreachable,280 else => unreachable,
284 };281 };
285282
286 for (lib_stub.inner) |stub| {283 var umbrella_libs = std.StringHashMap(void).init(self.allocator);
287 if (!hasTarget(stub.targets, target_string)) continue;284 defer umbrella_libs.deinit();
288285
289 if (stub.reexported_libraries) |reexports| {286 for (lib_stub.inner) |stub, stub_index| {
290 for (reexports) |reexp| {287 if (!hasTarget(stub.targets, target_string)) continue;
291 if (!hasTarget(reexp.targets, target_string)) continue;
292288
293 try self.dependent_libs.ensureUnusedCapacity(self.allocator, reexp.libraries.len);289 if (stub_index > 0) {
294 for (reexp.libraries) |lib| {290 // TODO I thought that we could switch on presence of `parent-umbrella` map;
295 self.dependent_libs.putAssumeCapacity(try self.allocator.dupe(u8, lib), {});291 // however, turns out `libsystem_notify.dylib` is fully reexported by `libSystem.dylib`
296 }292 // BUT does not feature a `parent-umbrella` map as the only sublib. Apple's bug perhaps?
297 }293 try umbrella_libs.put(stub.install_name, .{});
298 }294 }
299295
300 if (stub.exports) |exports| {296 if (stub.exports) |exports| {
...@@ -341,6 +337,29 @@ pub fn parseFromStub(self: *Dylib, lib_stub: LibStub) !void {...@@ -341,6 +337,29 @@ pub fn parseFromStub(self: *Dylib, lib_stub: LibStub) !void {
341 }337 }
342 }338 }
343 }339 }
340
341 log.debug("{s}", .{umbrella_lib.install_name});
342
343 // TODO track which libs were already parsed in different steps
344 for (lib_stub.inner) |stub| {
345 if (!hasTarget(stub.targets, target_string)) continue;
346
347 if (stub.reexported_libraries) |reexports| {
348 for (reexports) |reexp| {
349 if (!hasTarget(reexp.targets, target_string)) continue;
350
351 for (reexp.libraries) |lib| {
352 if (umbrella_libs.contains(lib)) {
353 log.debug(" | {s} <= {s}", .{ lib, umbrella_lib.install_name });
354 continue;
355 }
356
357 log.debug(" | {s}", .{lib});
358 try self.dependent_libs.put(self.allocator, try self.allocator.dupe(u8, lib), {});
359 }
360 }
361 }
362 }
344}363}
345364
346pub fn parseDependentLibs(self: *Dylib, out: *std.ArrayList(*Dylib)) !void {365pub fn parseDependentLibs(self: *Dylib, out: *std.ArrayList(*Dylib)) !void {
...@@ -374,7 +393,6 @@ pub fn parseDependentLibs(self: *Dylib, out: *std.ArrayList(*Dylib)) !void {...@@ -374,7 +393,6 @@ pub fn parseDependentLibs(self: *Dylib, out: *std.ArrayList(*Dylib)) !void {
374 self.arch.?,393 self.arch.?,
375 lib_path,394 lib_path,
376 self.syslibroot,395 self.syslibroot,
377 true,
378 )) orelse {396 )) orelse {
379 continue;397 continue;
380 };398 };
src/link/MachO/Zld.zig-3
...@@ -279,7 +279,6 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void {...@@ -279,7 +279,6 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void {
279 self.arch.?,279 self.arch.?,
280 full_path,280 full_path,
281 self.syslibroot,281 self.syslibroot,
282 true,
283 )) |dylibs| {282 )) |dylibs| {
284 defer self.allocator.free(dylibs);283 defer self.allocator.free(dylibs);
285 try self.dylibs.appendSlice(self.allocator, dylibs);284 try self.dylibs.appendSlice(self.allocator, dylibs);
...@@ -297,7 +296,6 @@ fn parseLibs(self: *Zld, libs: []const []const u8) !void {...@@ -297,7 +296,6 @@ fn parseLibs(self: *Zld, libs: []const []const u8) !void {
297 self.arch.?,296 self.arch.?,
298 lib,297 lib,
299 self.syslibroot,298 self.syslibroot,
300 true,
301 )) |dylibs| {299 )) |dylibs| {
302 defer self.allocator.free(dylibs);300 defer self.allocator.free(dylibs);
303 try self.dylibs.appendSlice(self.allocator, dylibs);301 try self.dylibs.appendSlice(self.allocator, dylibs);
...@@ -319,7 +317,6 @@ fn parseLibSystem(self: *Zld, libc_stub_path: []const u8) !void {...@@ -319,7 +317,6 @@ fn parseLibSystem(self: *Zld, libc_stub_path: []const u8) !void {
319 self.arch.?,317 self.arch.?,
320 libc_stub_path,318 libc_stub_path,
321 self.syslibroot,319 self.syslibroot,
322 false,
323 )) orelse return error.FailedToParseLibSystem;320 )) orelse return error.FailedToParseLibSystem;
324 defer self.allocator.free(dylibs);321 defer self.allocator.free(dylibs);
325322