authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-21 08:07:42+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-21 08:07:44+02:00
logb73ef342895f00bdb31ea5f947ee83764f235d43
tree1aed709d194cdcfd203c2df5b88a1ac02a31d04c
parent4793dafa0433d758b126f2f97d1de031b99e0fa1

frontend: directly pass resolved frameworks container to the linker

We can infer the framework name from the included resolved framework path. Fix hash implementation, and bump linker hash value from 9 to 10.

7 files changed, 33 insertions(+), 55 deletions(-)

src/Compilation.zig+6-14
...@@ -507,8 +507,7 @@ pub const InitOptions = struct {...@@ -507,8 +507,7 @@ pub const InitOptions = struct {
507 c_source_files: []const CSourceFile = &[0]CSourceFile{},507 c_source_files: []const CSourceFile = &[0]CSourceFile{},
508 link_objects: []LinkObject = &[0]LinkObject{},508 link_objects: []LinkObject = &[0]LinkObject{},
509 framework_dirs: []const []const u8 = &[0][]const u8{},509 framework_dirs: []const []const u8 = &[0][]const u8{},
510 framework_names: []const []const u8 = &.{},510 frameworks: []const Framework = &.{},
511 framework_infos: []const Framework = &.{},
512 system_lib_names: []const []const u8 = &.{},511 system_lib_names: []const []const u8 = &.{},
513 system_lib_infos: []const SystemLib = &.{},512 system_lib_infos: []const SystemLib = &.{},
514 /// These correspond to the WASI libc emulated subcomponents including:513 /// These correspond to the WASI libc emulated subcomponents including:
...@@ -831,7 +830,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -831,7 +830,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
831 // Our linker can't handle objects or most advanced options yet.830 // Our linker can't handle objects or most advanced options yet.
832 if (options.link_objects.len != 0 or831 if (options.link_objects.len != 0 or
833 options.c_source_files.len != 0 or832 options.c_source_files.len != 0 or
834 options.framework_names.len != 0 or833 options.frameworks.len != 0 or
835 options.system_lib_names.len != 0 or834 options.system_lib_names.len != 0 or
836 options.link_libc or options.link_libcpp or835 options.link_libc or options.link_libcpp or
837 link_eh_frame_hdr or836 link_eh_frame_hdr or
...@@ -1447,13 +1446,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1447,13 +1446,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1447 system_libs.putAssumeCapacity(lib_name, options.system_lib_infos[i]);1446 system_libs.putAssumeCapacity(lib_name, options.system_lib_infos[i]);
1448 }1447 }
14491448
1450 var frameworks: std.StringArrayHashMapUnmanaged(Framework) = .{};
1451 errdefer frameworks.deinit(gpa);
1452 try frameworks.ensureTotalCapacity(gpa, options.framework_names.len);
1453 for (options.framework_names, options.framework_infos) |framework_name, info| {
1454 frameworks.putAssumeCapacity(framework_name, info);
1455 }
1456
1457 const bin_file = try link.File.openPath(gpa, .{1449 const bin_file = try link.File.openPath(gpa, .{
1458 .emit = bin_file_emit,1450 .emit = bin_file_emit,
1459 .implib_emit = implib_emit,1451 .implib_emit = implib_emit,
...@@ -1473,7 +1465,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1473,7 +1465,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1473 .link_libcpp = link_libcpp,1465 .link_libcpp = link_libcpp,
1474 .link_libunwind = link_libunwind,1466 .link_libunwind = link_libunwind,
1475 .objects = options.link_objects,1467 .objects = options.link_objects,
1476 .frameworks = frameworks,1468 .frameworks = options.frameworks,
1477 .framework_dirs = options.framework_dirs,1469 .framework_dirs = options.framework_dirs,
1478 .system_libs = system_libs,1470 .system_libs = system_libs,
1479 .wasi_emulated_libs = options.wasi_emulated_libs,1471 .wasi_emulated_libs = options.wasi_emulated_libs,
...@@ -2275,7 +2267,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo...@@ -2275,7 +2267,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo
2275/// to remind the programmer to update multiple related pieces of code that2267/// to remind the programmer to update multiple related pieces of code that
2276/// are in different locations. Bump this number when adding or deleting2268/// are in different locations. Bump this number when adding or deleting
2277/// anything from the link cache manifest.2269/// anything from the link cache manifest.
2278pub const link_hash_implementation_version = 9;2270pub const link_hash_implementation_version = 10;
22792271
2280fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifest) !void {2272fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifest) !void {
2281 const gpa = comp.gpa;2273 const gpa = comp.gpa;
...@@ -2285,7 +2277,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes...@@ -2285,7 +2277,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
2285 defer arena_allocator.deinit();2277 defer arena_allocator.deinit();
2286 const arena = arena_allocator.allocator();2278 const arena = arena_allocator.allocator();
22872279
2288 comptime assert(link_hash_implementation_version == 9);2280 comptime assert(link_hash_implementation_version == 10);
22892281
2290 if (comp.bin_file.options.module) |mod| {2282 if (comp.bin_file.options.module) |mod| {
2291 const main_zig_file = try mod.main_pkg.root_src_directory.join(arena, &[_][]const u8{2283 const main_zig_file = try mod.main_pkg.root_src_directory.join(arena, &[_][]const u8{
...@@ -2394,7 +2386,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes...@@ -2394,7 +2386,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
23942386
2395 // Mach-O specific stuff2387 // Mach-O specific stuff
2396 man.hash.addListOfBytes(comp.bin_file.options.framework_dirs);2388 man.hash.addListOfBytes(comp.bin_file.options.framework_dirs);
2397 link.hashAddFrameworks(&man.hash, comp.bin_file.options.frameworks);2389 try link.hashAddFrameworks(man, comp.bin_file.options.frameworks);
2398 try man.addOptionalFile(comp.bin_file.options.entitlements);2390 try man.addOptionalFile(comp.bin_file.options.entitlements);
2399 man.hash.addOptional(comp.bin_file.options.pagezero_size);2391 man.hash.addOptional(comp.bin_file.options.pagezero_size);
2400 man.hash.addOptional(comp.bin_file.options.headerpad_size);2392 man.hash.addOptional(comp.bin_file.options.headerpad_size);
src/link.zig+6-12
...@@ -57,15 +57,11 @@ pub fn hashAddSystemLibs(...@@ -57,15 +57,11 @@ pub fn hashAddSystemLibs(
57 }57 }
58}58}
5959
60pub fn hashAddFrameworks(60pub fn hashAddFrameworks(man: *Cache.Manifest, hm: []const Framework) !void {
61 hh: *Cache.HashHelper,61 for (hm) |value| {
62 hm: std.StringArrayHashMapUnmanaged(Framework),62 man.hash.add(value.needed);
63) void {63 man.hash.add(value.weak);
64 const keys = hm.keys();64 _ = try man.addFile(value.path, null);
65 hh.addListOfBytes(keys);
66 for (hm.values()) |value| {
67 hh.add(value.needed);
68 hh.add(value.weak);
69 }65 }
70}66}
7167
...@@ -209,7 +205,7 @@ pub const Options = struct {...@@ -209,7 +205,7 @@ pub const Options = struct {
209205
210 objects: []Compilation.LinkObject,206 objects: []Compilation.LinkObject,
211 framework_dirs: []const []const u8,207 framework_dirs: []const []const u8,
212 frameworks: std.StringArrayHashMapUnmanaged(Framework),208 frameworks: []const Framework,
213 /// These are *always* dynamically linked. Static libraries will be209 /// These are *always* dynamically linked. Static libraries will be
214 /// provided as positional arguments.210 /// provided as positional arguments.
215 system_libs: std.StringArrayHashMapUnmanaged(SystemLib),211 system_libs: std.StringArrayHashMapUnmanaged(SystemLib),
...@@ -277,7 +273,6 @@ pub const Options = struct {...@@ -277,7 +273,6 @@ pub const Options = struct {
277273
278 pub fn move(self: *Options) Options {274 pub fn move(self: *Options) Options {
279 const copied_state = self.*;275 const copied_state = self.*;
280 self.frameworks = .{};
281 self.system_libs = .{};276 self.system_libs = .{};
282 self.force_undefined_symbols = .{};277 self.force_undefined_symbols = .{};
283 return copied_state;278 return copied_state;
...@@ -643,7 +638,6 @@ pub const File = struct {...@@ -643,7 +638,6 @@ pub const File = struct {
643 base.releaseLock();638 base.releaseLock();
644 if (base.file) |f| f.close();639 if (base.file) |f| f.close();
645 if (base.intermediary_basename) |sub_path| base.allocator.free(sub_path);640 if (base.intermediary_basename) |sub_path| base.allocator.free(sub_path);
646 base.options.frameworks.deinit(base.allocator);
647 base.options.system_libs.deinit(base.allocator);641 base.options.system_libs.deinit(base.allocator);
648 base.options.force_undefined_symbols.deinit(base.allocator);642 base.options.force_undefined_symbols.deinit(base.allocator);
649 switch (base.tag) {643 switch (base.tag) {
src/link/Coff/lld.zig+1-1
...@@ -63,7 +63,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -63,7 +63,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
63 man = comp.cache_parent.obtain();63 man = comp.cache_parent.obtain();
64 self.base.releaseLock();64 self.base.releaseLock();
6565
66 comptime assert(Compilation.link_hash_implementation_version == 9);66 comptime assert(Compilation.link_hash_implementation_version == 10);
6767
68 for (self.base.options.objects) |obj| {68 for (self.base.options.objects) |obj| {
69 _ = try man.addFile(obj.path, null);69 _ = try man.addFile(obj.path, null);
src/link/Elf.zig+1-1
...@@ -1367,7 +1367,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v...@@ -1367,7 +1367,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
1367 // We are about to obtain this lock, so here we give other processes a chance first.1367 // We are about to obtain this lock, so here we give other processes a chance first.
1368 self.base.releaseLock();1368 self.base.releaseLock();
13691369
1370 comptime assert(Compilation.link_hash_implementation_version == 9);1370 comptime assert(Compilation.link_hash_implementation_version == 10);
13711371
1372 try man.addOptionalFile(self.base.options.linker_script);1372 try man.addOptionalFile(self.base.options.linker_script);
1373 try man.addOptionalFile(self.base.options.version_script);1373 try man.addOptionalFile(self.base.options.version_script);
src/link/MachO/zld.zig+11-12
...@@ -3396,7 +3396,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr...@@ -3396,7 +3396,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
3396 // We are about to obtain this lock, so here we give other processes a chance first.3396 // We are about to obtain this lock, so here we give other processes a chance first.
3397 macho_file.base.releaseLock();3397 macho_file.base.releaseLock();
33983398
3399 comptime assert(Compilation.link_hash_implementation_version == 9);3399 comptime assert(Compilation.link_hash_implementation_version == 10);
34003400
3401 for (options.objects) |obj| {3401 for (options.objects) |obj| {
3402 _ = try man.addFile(obj.path, null);3402 _ = try man.addFile(obj.path, null);
...@@ -3417,7 +3417,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr...@@ -3417,7 +3417,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
3417 man.hash.add(options.strip);3417 man.hash.add(options.strip);
3418 man.hash.addListOfBytes(options.lib_dirs);3418 man.hash.addListOfBytes(options.lib_dirs);
3419 man.hash.addListOfBytes(options.framework_dirs);3419 man.hash.addListOfBytes(options.framework_dirs);
3420 link.hashAddFrameworks(&man.hash, options.frameworks);3420 try link.hashAddFrameworks(&man, options.frameworks);
3421 man.hash.addListOfBytes(options.rpath_list);3421 man.hash.addListOfBytes(options.rpath_list);
3422 if (is_dyn_lib) {3422 if (is_dyn_lib) {
3423 man.hash.addOptionalBytes(options.install_name);3423 man.hash.addOptionalBytes(options.install_name);
...@@ -3555,9 +3555,8 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr...@@ -3555,9 +3555,8 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
3555 }3555 }
35563556
3557 {3557 {
3558 const vals = options.frameworks.values();3558 try libs.ensureUnusedCapacity(options.frameworks.len);
3559 try libs.ensureUnusedCapacity(vals.len);3559 for (options.frameworks) |v| libs.putAssumeCapacity(v.path, .{
3560 for (vals) |v| libs.putAssumeCapacity(v.path, .{
3561 .needed = v.needed,3560 .needed = v.needed,
3562 .weak = v.weak,3561 .weak = v.weak,
3563 .path = v.path,3562 .path = v.path,
...@@ -3664,14 +3663,14 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr...@@ -3664,14 +3663,14 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
3664 try argv.append(try std.fmt.allocPrint(arena, "-L{s}", .{lib_dir}));3663 try argv.append(try std.fmt.allocPrint(arena, "-L{s}", .{lib_dir}));
3665 }3664 }
36663665
3667 for (options.frameworks.keys()) |framework| {3666 for (options.frameworks) |framework| {
3668 const info = options.frameworks.get(framework).?;3667 const name = std.fs.path.stem(framework.path);
3669 const arg = if (info.needed)3668 const arg = if (framework.needed)
3670 try std.fmt.allocPrint(arena, "-needed_framework {s}", .{framework})3669 try std.fmt.allocPrint(arena, "-needed_framework {s}", .{name})
3671 else if (info.weak)3670 else if (framework.weak)
3672 try std.fmt.allocPrint(arena, "-weak_framework {s}", .{framework})3671 try std.fmt.allocPrint(arena, "-weak_framework {s}", .{name})
3673 else3672 else
3674 try std.fmt.allocPrint(arena, "-framework {s}", .{framework});3673 try std.fmt.allocPrint(arena, "-framework {s}", .{name});
3675 try argv.append(arg);3674 try argv.append(arg);
3676 }3675 }
36773676
src/link/Wasm.zig+2-2
...@@ -3193,7 +3193,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l...@@ -3193,7 +3193,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
3193 // We are about to obtain this lock, so here we give other processes a chance first.3193 // We are about to obtain this lock, so here we give other processes a chance first.
3194 wasm.base.releaseLock();3194 wasm.base.releaseLock();
31953195
3196 comptime assert(Compilation.link_hash_implementation_version == 9);3196 comptime assert(Compilation.link_hash_implementation_version == 10);
31973197
3198 for (options.objects) |obj| {3198 for (options.objects) |obj| {
3199 _ = try man.addFile(obj.path, null);3199 _ = try man.addFile(obj.path, null);
...@@ -4254,7 +4254,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !...@@ -4254,7 +4254,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
4254 // We are about to obtain this lock, so here we give other processes a chance first.4254 // We are about to obtain this lock, so here we give other processes a chance first.
4255 wasm.base.releaseLock();4255 wasm.base.releaseLock();
42564256
4257 comptime assert(Compilation.link_hash_implementation_version == 9);4257 comptime assert(Compilation.link_hash_implementation_version == 10);
42584258
4259 for (wasm.base.options.objects) |obj| {4259 for (wasm.base.options.objects) |obj| {
4260 _ = try man.addFile(obj.path, null);4260 _ = try man.addFile(obj.path, null);
src/main.zig+6-13
...@@ -2876,10 +2876,7 @@ fn buildOutputType(...@@ -2876,10 +2876,7 @@ fn buildOutputType(
2876 // After this point, resolved_system_libs is used instead of external_system_libs.2876 // After this point, resolved_system_libs is used instead of external_system_libs.
28772877
2878 // We now repeat part of the process for frameworks.2878 // We now repeat part of the process for frameworks.
2879 var resolved_frameworks: std.MultiArrayList(struct {2879 var resolved_frameworks = std.ArrayList(Compilation.Framework).init(arena);
2880 name: []const u8,
2881 framework: Compilation.Framework,
2882 }) = .{};
28832880
2884 if (frameworks.keys().len > 0) {2881 if (frameworks.keys().len > 0) {
2885 var test_path = std.ArrayList(u8).init(gpa);2882 var test_path = std.ArrayList(u8).init(gpa);
...@@ -2904,13 +2901,10 @@ fn buildOutputType(...@@ -2904,13 +2901,10 @@ fn buildOutputType(
2904 framework_name,2901 framework_name,
2905 )) {2902 )) {
2906 const path = try arena.dupe(u8, test_path.items);2903 const path = try arena.dupe(u8, test_path.items);
2907 try resolved_frameworks.append(arena, .{2904 try resolved_frameworks.append(.{
2908 .name = framework_name,2905 .needed = info.needed,
2909 .framework = .{2906 .weak = info.weak,
2910 .needed = info.needed,2907 .path = path,
2911 .weak = info.weak,
2912 .path = path,
2913 },
2914 });2908 });
2915 continue :framework;2909 continue :framework;
2916 }2910 }
...@@ -3327,8 +3321,7 @@ fn buildOutputType(...@@ -3327,8 +3321,7 @@ fn buildOutputType(
3327 .c_source_files = c_source_files.items,3321 .c_source_files = c_source_files.items,
3328 .link_objects = link_objects.items,3322 .link_objects = link_objects.items,
3329 .framework_dirs = framework_dirs.items,3323 .framework_dirs = framework_dirs.items,
3330 .framework_names = resolved_frameworks.items(.name),3324 .frameworks = resolved_frameworks.items,
3331 .framework_infos = resolved_frameworks.items(.framework),
3332 .system_lib_names = resolved_system_libs.items(.name),3325 .system_lib_names = resolved_system_libs.items(.name),
3333 .system_lib_infos = resolved_system_libs.items(.lib),3326 .system_lib_infos = resolved_system_libs.items(.lib),
3334 .wasi_emulated_libs = wasi_emulated_libs.items,3327 .wasi_emulated_libs = wasi_emulated_libs.items,