| author | |
| committer | |
| log | 8e96be0088d4ae007589651066d426f815aaab4f |
| tree | 398f48e05e365436a16f170b3075e596f135decb |
| parent | 283afb50b56fb8a2c288d2452bdf6e595a1bbb06 |
| parent | b73ef342895f00bdb31ea5f947ee83764f235d43 |
| signature |
compiler: resolve framework paths in the frontend8 files changed, 125 insertions(+), 139 deletions(-)
src/Compilation.zig+5-5| ... | @@ -507,7 +507,7 @@ pub const InitOptions = struct { | ... | @@ -507,7 +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 | frameworks: std.StringArrayHashMapUnmanaged(Framework) = .{}, | 510 | frameworks: []const Framework = &.{}, |
| 511 | system_lib_names: []const []const u8 = &.{}, | 511 | system_lib_names: []const []const u8 = &.{}, |
| 512 | system_lib_infos: []const SystemLib = &.{}, | 512 | system_lib_infos: []const SystemLib = &.{}, |
| 513 | /// These correspond to the WASI libc emulated subcomponents including: | 513 | /// These correspond to the WASI libc emulated subcomponents including: |
| ... | @@ -830,7 +830,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -830,7 +830,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 830 | // Our linker can't handle objects or most advanced options yet. | 830 | // Our linker can't handle objects or most advanced options yet. |
| 831 | if (options.link_objects.len != 0 or | 831 | if (options.link_objects.len != 0 or |
| 832 | options.c_source_files.len != 0 or | 832 | options.c_source_files.len != 0 or |
| 833 | options.frameworks.count() != 0 or | 833 | options.frameworks.len != 0 or |
| 834 | options.system_lib_names.len != 0 or | 834 | options.system_lib_names.len != 0 or |
| 835 | options.link_libc or options.link_libcpp or | 835 | options.link_libc or options.link_libcpp or |
| 836 | link_eh_frame_hdr or | 836 | link_eh_frame_hdr or |
| ... | @@ -2267,7 +2267,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo | ... | @@ -2267,7 +2267,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo |
| 2267 | /// to remind the programmer to update multiple related pieces of code that | 2267 | /// to remind the programmer to update multiple related pieces of code that |
| 2268 | /// are in different locations. Bump this number when adding or deleting | 2268 | /// are in different locations. Bump this number when adding or deleting |
| 2269 | /// anything from the link cache manifest. | 2269 | /// anything from the link cache manifest. |
| 2270 | pub const link_hash_implementation_version = 9; | 2270 | pub const link_hash_implementation_version = 10; |
| 2271 | 2271 | ||
| 2272 | fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifest) !void { | 2272 | fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifest) !void { |
| 2273 | const gpa = comp.gpa; | 2273 | const gpa = comp.gpa; |
| ... | @@ -2277,7 +2277,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes | ... | @@ -2277,7 +2277,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2277 | defer arena_allocator.deinit(); | 2277 | defer arena_allocator.deinit(); |
| 2278 | const arena = arena_allocator.allocator(); | 2278 | const arena = arena_allocator.allocator(); |
| 2279 | 2279 | ||
| 2280 | comptime assert(link_hash_implementation_version == 9); | 2280 | comptime assert(link_hash_implementation_version == 10); |
| 2281 | 2281 | ||
| 2282 | if (comp.bin_file.options.module) |mod| { | 2282 | if (comp.bin_file.options.module) |mod| { |
| 2283 | 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{ |
| ... | @@ -2386,7 +2386,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes | ... | @@ -2386,7 +2386,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2386 | 2386 | ||
| 2387 | // Mach-O specific stuff | 2387 | // Mach-O specific stuff |
| 2388 | man.hash.addListOfBytes(comp.bin_file.options.framework_dirs); | 2388 | man.hash.addListOfBytes(comp.bin_file.options.framework_dirs); |
| 2389 | link.hashAddFrameworks(&man.hash, comp.bin_file.options.frameworks); | 2389 | try link.hashAddFrameworks(man, comp.bin_file.options.frameworks); |
| 2390 | try man.addOptionalFile(comp.bin_file.options.entitlements); | 2390 | try man.addOptionalFile(comp.bin_file.options.entitlements); |
| 2391 | man.hash.addOptional(comp.bin_file.options.pagezero_size); | 2391 | man.hash.addOptional(comp.bin_file.options.pagezero_size); |
| 2392 | man.hash.addOptional(comp.bin_file.options.headerpad_size); | 2392 | man.hash.addOptional(comp.bin_file.options.headerpad_size); |
src/link.zig+7-12| ... | @@ -37,6 +37,7 @@ pub const SystemLib = struct { | ... | @@ -37,6 +37,7 @@ pub const SystemLib = struct { |
| 37 | pub const Framework = struct { | 37 | pub const Framework = struct { |
| 38 | needed: bool = false, | 38 | needed: bool = false, |
| 39 | weak: bool = false, | 39 | weak: bool = false, |
| 40 | path: []const u8, | ||
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| 42 | pub const SortSection = enum { name, alignment }; | 43 | pub const SortSection = enum { name, alignment }; |
| ... | @@ -56,15 +57,11 @@ pub fn hashAddSystemLibs( | ... | @@ -56,15 +57,11 @@ pub fn hashAddSystemLibs( |
| 56 | } | 57 | } |
| 57 | } | 58 | } |
| 58 | 59 | ||
| 59 | pub fn hashAddFrameworks( | 60 | pub fn hashAddFrameworks(man: *Cache.Manifest, hm: []const Framework) !void { |
| 60 | hh: *Cache.HashHelper, | 61 | for (hm) |value| { |
| 61 | hm: std.StringArrayHashMapUnmanaged(Framework), | 62 | man.hash.add(value.needed); |
| 62 | ) void { | 63 | man.hash.add(value.weak); |
| 63 | const keys = hm.keys(); | 64 | _ = try man.addFile(value.path, null); |
| 64 | hh.addListOfBytes(keys); | ||
| 65 | for (hm.values()) |value| { | ||
| 66 | hh.add(value.needed); | ||
| 67 | hh.add(value.weak); | ||
| 68 | } | 65 | } |
| 69 | } | 66 | } |
| 70 | 67 | ||
| ... | @@ -208,7 +205,7 @@ pub const Options = struct { | ... | @@ -208,7 +205,7 @@ pub const Options = struct { |
| 208 | 205 | ||
| 209 | objects: []Compilation.LinkObject, | 206 | objects: []Compilation.LinkObject, |
| 210 | framework_dirs: []const []const u8, | 207 | framework_dirs: []const []const u8, |
| 211 | frameworks: std.StringArrayHashMapUnmanaged(Framework), | 208 | frameworks: []const Framework, |
| 212 | /// These are *always* dynamically linked. Static libraries will be | 209 | /// These are *always* dynamically linked. Static libraries will be |
| 213 | /// provided as positional arguments. | 210 | /// provided as positional arguments. |
| 214 | system_libs: std.StringArrayHashMapUnmanaged(SystemLib), | 211 | system_libs: std.StringArrayHashMapUnmanaged(SystemLib), |
| ... | @@ -276,7 +273,6 @@ pub const Options = struct { | ... | @@ -276,7 +273,6 @@ pub const Options = struct { |
| 276 | 273 | ||
| 277 | pub fn move(self: *Options) Options { | 274 | pub fn move(self: *Options) Options { |
| 278 | const copied_state = self.*; | 275 | const copied_state = self.*; |
| 279 | self.frameworks = .{}; | ||
| 280 | self.system_libs = .{}; | 276 | self.system_libs = .{}; |
| 281 | self.force_undefined_symbols = .{}; | 277 | self.force_undefined_symbols = .{}; |
| 282 | return copied_state; | 278 | return copied_state; |
| ... | @@ -642,7 +638,6 @@ pub const File = struct { | ... | @@ -642,7 +638,6 @@ pub const File = struct { |
| 642 | base.releaseLock(); | 638 | base.releaseLock(); |
| 643 | if (base.file) |f| f.close(); | 639 | if (base.file) |f| f.close(); |
| 644 | if (base.intermediary_basename) |sub_path| base.allocator.free(sub_path); | 640 | if (base.intermediary_basename) |sub_path| base.allocator.free(sub_path); |
| 645 | base.options.frameworks.deinit(base.allocator); | ||
| 646 | base.options.system_libs.deinit(base.allocator); | 641 | base.options.system_libs.deinit(base.allocator); |
| 647 | base.options.force_undefined_symbols.deinit(base.allocator); | 642 | base.options.force_undefined_symbols.deinit(base.allocator); |
| 648 | 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(); |
| 65 | 65 | ||
| 66 | comptime assert(Compilation.link_hash_implementation_version == 9); | 66 | comptime assert(Compilation.link_hash_implementation_version == 10); |
| 67 | 67 | ||
| 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(); |
| 1369 | 1369 | ||
| 1370 | comptime assert(Compilation.link_hash_implementation_version == 9); | 1370 | comptime assert(Compilation.link_hash_implementation_version == 10); |
| 1371 | 1371 | ||
| 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.zig+1-63| ... | @@ -870,49 +870,7 @@ fn resolveLibSystemInDirs(arena: Allocator, dirs: []const []const u8, out_libs: | ... | @@ -870,49 +870,7 @@ fn resolveLibSystemInDirs(arena: Allocator, dirs: []const []const u8, out_libs: |
| 870 | return false; | 870 | return false; |
| 871 | } | 871 | } |
| 872 | 872 | ||
| 873 | pub fn resolveSearchDir( | 873 | fn resolveLib( |
| 874 | arena: Allocator, | ||
| 875 | dir: []const u8, | ||
| 876 | syslibroot: ?[]const u8, | ||
| 877 | ) !?[]const u8 { | ||
| 878 | var candidates = std.ArrayList([]const u8).init(arena); | ||
| 879 | |||
| 880 | if (fs.path.isAbsolute(dir)) { | ||
| 881 | if (syslibroot) |root| { | ||
| 882 | const common_dir = if (builtin.os.tag == .windows) blk: { | ||
| 883 | // We need to check for disk designator and strip it out from dir path so | ||
| 884 | // that we can concat dir with syslibroot. | ||
| 885 | // TODO we should backport this mechanism to 'MachO.Dylib.parseDependentLibs()' | ||
| 886 | const disk_designator = fs.path.diskDesignatorWindows(dir); | ||
| 887 | |||
| 888 | if (mem.indexOf(u8, dir, disk_designator)) |where| { | ||
| 889 | break :blk dir[where + disk_designator.len ..]; | ||
| 890 | } | ||
| 891 | |||
| 892 | break :blk dir; | ||
| 893 | } else dir; | ||
| 894 | const full_path = try fs.path.join(arena, &[_][]const u8{ root, common_dir }); | ||
| 895 | try candidates.append(full_path); | ||
| 896 | } | ||
| 897 | } | ||
| 898 | |||
| 899 | try candidates.append(dir); | ||
| 900 | |||
| 901 | for (candidates.items) |candidate| { | ||
| 902 | // Verify that search path actually exists | ||
| 903 | var tmp = fs.cwd().openDir(candidate, .{}) catch |err| switch (err) { | ||
| 904 | error.FileNotFound => continue, | ||
| 905 | else => |e| return e, | ||
| 906 | }; | ||
| 907 | defer tmp.close(); | ||
| 908 | |||
| 909 | return candidate; | ||
| 910 | } | ||
| 911 | |||
| 912 | return null; | ||
| 913 | } | ||
| 914 | |||
| 915 | pub fn resolveLib( | ||
| 916 | arena: Allocator, | 874 | arena: Allocator, |
| 917 | search_dir: []const u8, | 875 | search_dir: []const u8, |
| 918 | name: []const u8, | 876 | name: []const u8, |
| ... | @@ -931,26 +889,6 @@ pub fn resolveLib( | ... | @@ -931,26 +889,6 @@ pub fn resolveLib( |
| 931 | return full_path; | 889 | return full_path; |
| 932 | } | 890 | } |
| 933 | 891 | ||
| 934 | pub fn resolveFramework( | ||
| 935 | arena: Allocator, | ||
| 936 | search_dir: []const u8, | ||
| 937 | name: []const u8, | ||
| 938 | ext: []const u8, | ||
| 939 | ) !?[]const u8 { | ||
| 940 | const search_name = try std.fmt.allocPrint(arena, "{s}{s}", .{ name, ext }); | ||
| 941 | const prefix_path = try std.fmt.allocPrint(arena, "{s}.framework", .{name}); | ||
| 942 | const full_path = try fs.path.join(arena, &[_][]const u8{ search_dir, prefix_path, search_name }); | ||
| 943 | |||
| 944 | // Check if the file exists. | ||
| 945 | const tmp = fs.cwd().openFile(full_path, .{}) catch |err| switch (err) { | ||
| 946 | error.FileNotFound => return null, | ||
| 947 | else => |e| return e, | ||
| 948 | }; | ||
| 949 | defer tmp.close(); | ||
| 950 | |||
| 951 | return full_path; | ||
| 952 | } | ||
| 953 | |||
| 954 | const ParseDylibError = error{ | 892 | const ParseDylibError = error{ |
| 955 | OutOfMemory, | 893 | OutOfMemory, |
| 956 | EmptyStubFile, | 894 | EmptyStubFile, |
src/link/MachO/zld.zig+17-53| ... | @@ -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(); |
| 3398 | 3398 | ||
| 3399 | comptime assert(Compilation.link_hash_implementation_version == 9); | 3399 | comptime assert(Compilation.link_hash_implementation_version == 10); |
| 3400 | 3400 | ||
| 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); |
| ... | @@ -3512,9 +3512,6 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr | ... | @@ -3512,9 +3512,6 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3512 | try zld.atoms.append(gpa, Atom.empty); // AtomIndex at 0 is reserved as null atom | 3512 | try zld.atoms.append(gpa, Atom.empty); // AtomIndex at 0 is reserved as null atom |
| 3513 | try zld.strtab.buffer.append(gpa, 0); | 3513 | try zld.strtab.buffer.append(gpa, 0); |
| 3514 | 3514 | ||
| 3515 | var lib_not_found = false; | ||
| 3516 | var framework_not_found = false; | ||
| 3517 | |||
| 3518 | // Positional arguments to the linker such as object files and static archives. | 3515 | // Positional arguments to the linker such as object files and static archives. |
| 3519 | var positionals = std.ArrayList([]const u8).init(arena); | 3516 | var positionals = std.ArrayList([]const u8).init(arena); |
| 3520 | try positionals.ensureUnusedCapacity(options.objects.len); | 3517 | try positionals.ensureUnusedCapacity(options.objects.len); |
| ... | @@ -3557,43 +3554,16 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr | ... | @@ -3557,43 +3554,16 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3557 | for (vals) |v| libs.putAssumeCapacity(v.path.?, v); | 3554 | for (vals) |v| libs.putAssumeCapacity(v.path.?, v); |
| 3558 | } | 3555 | } |
| 3559 | 3556 | ||
| 3560 | try MachO.resolveLibSystem(arena, comp, options.sysroot, target, options.lib_dirs, &libs); | 3557 | { |
| 3561 | 3558 | try libs.ensureUnusedCapacity(options.frameworks.len); | |
| 3562 | // frameworks | 3559 | for (options.frameworks) |v| libs.putAssumeCapacity(v.path, .{ |
| 3563 | var framework_dirs = std.ArrayList([]const u8).init(arena); | 3560 | .needed = v.needed, |
| 3564 | for (options.framework_dirs) |dir| { | 3561 | .weak = v.weak, |
| 3565 | if (try MachO.resolveSearchDir(arena, dir, options.sysroot)) |search_dir| { | 3562 | .path = v.path, |
| 3566 | try framework_dirs.append(search_dir); | 3563 | }); |
| 3567 | } else { | ||
| 3568 | log.warn("directory not found for '-F{s}'", .{dir}); | ||
| 3569 | } | ||
| 3570 | } | ||
| 3571 | |||
| 3572 | outer: for (options.frameworks.keys()) |f_name| { | ||
| 3573 | for (framework_dirs.items) |dir| { | ||
| 3574 | for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| { | ||
| 3575 | if (try MachO.resolveFramework(arena, dir, f_name, ext)) |full_path| { | ||
| 3576 | const info = options.frameworks.get(f_name).?; | ||
| 3577 | try libs.put(full_path, .{ | ||
| 3578 | .needed = info.needed, | ||
| 3579 | .weak = info.weak, | ||
| 3580 | .path = full_path, | ||
| 3581 | }); | ||
| 3582 | continue :outer; | ||
| 3583 | } | ||
| 3584 | } | ||
| 3585 | } else { | ||
| 3586 | log.warn("framework not found for '-framework {s}'", .{f_name}); | ||
| 3587 | framework_not_found = true; | ||
| 3588 | } | ||
| 3589 | } | 3564 | } |
| 3590 | 3565 | ||
| 3591 | if (framework_not_found) { | 3566 | try MachO.resolveLibSystem(arena, comp, options.sysroot, target, options.lib_dirs, &libs); |
| 3592 | log.warn("Framework search paths:", .{}); | ||
| 3593 | for (framework_dirs.items) |dir| { | ||
| 3594 | log.warn(" {s}", .{dir}); | ||
| 3595 | } | ||
| 3596 | } | ||
| 3597 | 3567 | ||
| 3598 | if (options.verbose_link) { | 3568 | if (options.verbose_link) { |
| 3599 | var argv = std.ArrayList([]const u8).init(arena); | 3569 | var argv = std.ArrayList([]const u8).init(arena); |
| ... | @@ -3693,14 +3663,14 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr | ... | @@ -3693,14 +3663,14 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3693 | 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})); |
| 3694 | } | 3664 | } |
| 3695 | 3665 | ||
| 3696 | for (options.frameworks.keys()) |framework| { | 3666 | for (options.frameworks) |framework| { |
| 3697 | const info = options.frameworks.get(framework).?; | 3667 | const name = std.fs.path.stem(framework.path); |
| 3698 | const arg = if (info.needed) | 3668 | const arg = if (framework.needed) |
| 3699 | try std.fmt.allocPrint(arena, "-needed_framework {s}", .{framework}) | 3669 | try std.fmt.allocPrint(arena, "-needed_framework {s}", .{name}) |
| 3700 | else if (info.weak) | 3670 | else if (framework.weak) |
| 3701 | try std.fmt.allocPrint(arena, "-weak_framework {s}", .{framework}) | 3671 | try std.fmt.allocPrint(arena, "-weak_framework {s}", .{name}) |
| 3702 | else | 3672 | else |
| 3703 | try std.fmt.allocPrint(arena, "-framework {s}", .{framework}); | 3673 | try std.fmt.allocPrint(arena, "-framework {s}", .{name}); |
| 3704 | try argv.append(arg); | 3674 | try argv.append(arg); |
| 3705 | } | 3675 | } |
| 3706 | 3676 | ||
| ... | @@ -3740,12 +3710,6 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr | ... | @@ -3740,12 +3710,6 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3740 | if (resolver.unresolved.count() > 0) { | 3710 | if (resolver.unresolved.count() > 0) { |
| 3741 | return error.UndefinedSymbolReference; | 3711 | return error.UndefinedSymbolReference; |
| 3742 | } | 3712 | } |
| 3743 | if (lib_not_found) { | ||
| 3744 | return error.LibraryNotFound; | ||
| 3745 | } | ||
| 3746 | if (framework_not_found) { | ||
| 3747 | return error.FrameworkNotFound; | ||
| 3748 | } | ||
| 3749 | 3713 | ||
| 3750 | if (options.output_mode == .Exe) { | 3714 | if (options.output_mode == .Exe) { |
| 3751 | const entry_name = options.entry orelse load_commands.default_entry_point; | 3715 | const entry_name = options.entry orelse load_commands.default_entry_point; |
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(); |
| 3195 | 3195 | ||
| 3196 | comptime assert(Compilation.link_hash_implementation_version == 9); | 3196 | comptime assert(Compilation.link_hash_implementation_version == 10); |
| 3197 | 3197 | ||
| 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(); |
| 4256 | 4256 | ||
| 4257 | comptime assert(Compilation.link_hash_implementation_version == 9); | 4257 | comptime assert(Compilation.link_hash_implementation_version == 10); |
| 4258 | 4258 | ||
| 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+91-2| ... | @@ -746,6 +746,13 @@ const SystemLib = struct { | ... | @@ -746,6 +746,13 @@ const SystemLib = struct { |
| 746 | } | 746 | } |
| 747 | }; | 747 | }; |
| 748 | 748 | ||
| 749 | /// Similar to `link.Framework` except it doesn't store yet unresolved | ||
| 750 | /// path to the framework. | ||
| 751 | const Framework = struct { | ||
| 752 | needed: bool = false, | ||
| 753 | weak: bool = false, | ||
| 754 | }; | ||
| 755 | |||
| 749 | const CliModule = struct { | 756 | const CliModule = struct { |
| 750 | mod: *Package, | 757 | mod: *Package, |
| 751 | /// still in CLI arg format | 758 | /// still in CLI arg format |
| ... | @@ -919,7 +926,7 @@ fn buildOutputType( | ... | @@ -919,7 +926,7 @@ fn buildOutputType( |
| 919 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena); | 926 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena); |
| 920 | var link_objects = std.ArrayList(Compilation.LinkObject).init(arena); | 927 | var link_objects = std.ArrayList(Compilation.LinkObject).init(arena); |
| 921 | var framework_dirs = std.ArrayList([]const u8).init(arena); | 928 | var framework_dirs = std.ArrayList([]const u8).init(arena); |
| 922 | var frameworks: std.StringArrayHashMapUnmanaged(Compilation.Framework) = .{}; | 929 | var frameworks: std.StringArrayHashMapUnmanaged(Framework) = .{}; |
| 923 | // null means replace with the test executable binary | 930 | // null means replace with the test executable binary |
| 924 | var test_exec_args = std.ArrayList(?[]const u8).init(arena); | 931 | var test_exec_args = std.ArrayList(?[]const u8).init(arena); |
| 925 | var linker_export_symbol_names = std.ArrayList([]const u8).init(arena); | 932 | var linker_export_symbol_names = std.ArrayList([]const u8).init(arena); |
| ... | @@ -2868,6 +2875,59 @@ fn buildOutputType( | ... | @@ -2868,6 +2875,59 @@ fn buildOutputType( |
| 2868 | } | 2875 | } |
| 2869 | // 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. |
| 2870 | 2877 | ||
| 2878 | // We now repeat part of the process for frameworks. | ||
| 2879 | var resolved_frameworks = std.ArrayList(Compilation.Framework).init(arena); | ||
| 2880 | |||
| 2881 | if (frameworks.keys().len > 0) { | ||
| 2882 | var test_path = std.ArrayList(u8).init(gpa); | ||
| 2883 | defer test_path.deinit(); | ||
| 2884 | |||
| 2885 | var checked_paths = std.ArrayList(u8).init(gpa); | ||
| 2886 | defer checked_paths.deinit(); | ||
| 2887 | |||
| 2888 | var failed_frameworks = std.ArrayList(struct { | ||
| 2889 | name: []const u8, | ||
| 2890 | checked_paths: []const u8, | ||
| 2891 | }).init(arena); | ||
| 2892 | |||
| 2893 | framework: for (frameworks.keys(), frameworks.values()) |framework_name, info| { | ||
| 2894 | checked_paths.clearRetainingCapacity(); | ||
| 2895 | |||
| 2896 | for (framework_dirs.items) |framework_dir_path| { | ||
| 2897 | if (try accessFrameworkPath( | ||
| 2898 | &test_path, | ||
| 2899 | &checked_paths, | ||
| 2900 | framework_dir_path, | ||
| 2901 | framework_name, | ||
| 2902 | )) { | ||
| 2903 | const path = try arena.dupe(u8, test_path.items); | ||
| 2904 | try resolved_frameworks.append(.{ | ||
| 2905 | .needed = info.needed, | ||
| 2906 | .weak = info.weak, | ||
| 2907 | .path = path, | ||
| 2908 | }); | ||
| 2909 | continue :framework; | ||
| 2910 | } | ||
| 2911 | } | ||
| 2912 | |||
| 2913 | try failed_frameworks.append(.{ | ||
| 2914 | .name = framework_name, | ||
| 2915 | .checked_paths = try arena.dupe(u8, checked_paths.items), | ||
| 2916 | }); | ||
| 2917 | } | ||
| 2918 | |||
| 2919 | if (failed_frameworks.items.len > 0) { | ||
| 2920 | for (failed_frameworks.items) |f| { | ||
| 2921 | const searched_paths = if (f.checked_paths.len == 0) " none" else f.checked_paths; | ||
| 2922 | std.log.err("unable to find framework '{s}'. searched paths: {s}", .{ | ||
| 2923 | f.name, searched_paths, | ||
| 2924 | }); | ||
| 2925 | } | ||
| 2926 | process.exit(1); | ||
| 2927 | } | ||
| 2928 | } | ||
| 2929 | // After this point, resolved_frameworks is used instead of frameworks. | ||
| 2930 | |||
| 2871 | const object_format = target_info.target.ofmt; | 2931 | const object_format = target_info.target.ofmt; |
| 2872 | 2932 | ||
| 2873 | if (output_mode == .Obj and (object_format == .coff or object_format == .macho)) { | 2933 | if (output_mode == .Obj and (object_format == .coff or object_format == .macho)) { |
| ... | @@ -3261,7 +3321,7 @@ fn buildOutputType( | ... | @@ -3261,7 +3321,7 @@ fn buildOutputType( |
| 3261 | .c_source_files = c_source_files.items, | 3321 | .c_source_files = c_source_files.items, |
| 3262 | .link_objects = link_objects.items, | 3322 | .link_objects = link_objects.items, |
| 3263 | .framework_dirs = framework_dirs.items, | 3323 | .framework_dirs = framework_dirs.items, |
| 3264 | .frameworks = frameworks, | 3324 | .frameworks = resolved_frameworks.items, |
| 3265 | .system_lib_names = resolved_system_libs.items(.name), | 3325 | .system_lib_names = resolved_system_libs.items(.name), |
| 3266 | .system_lib_infos = resolved_system_libs.items(.lib), | 3326 | .system_lib_infos = resolved_system_libs.items(.lib), |
| 3267 | .wasi_emulated_libs = wasi_emulated_libs.items, | 3327 | .wasi_emulated_libs = wasi_emulated_libs.items, |
| ... | @@ -6336,3 +6396,32 @@ fn accessLibPath( | ... | @@ -6336,3 +6396,32 @@ fn accessLibPath( |
| 6336 | 6396 | ||
| 6337 | return false; | 6397 | return false; |
| 6338 | } | 6398 | } |
| 6399 | |||
| 6400 | fn accessFrameworkPath( | ||
| 6401 | test_path: *std.ArrayList(u8), | ||
| 6402 | checked_paths: *std.ArrayList(u8), | ||
| 6403 | framework_dir_path: []const u8, | ||
| 6404 | framework_name: []const u8, | ||
| 6405 | ) !bool { | ||
| 6406 | const sep = fs.path.sep_str; | ||
| 6407 | |||
| 6408 | for (&[_][]const u8{ "tbd", "dylib" }) |ext| { | ||
| 6409 | test_path.clearRetainingCapacity(); | ||
| 6410 | try test_path.writer().print("{s}" ++ sep ++ "{s}.framework" ++ sep ++ "{s}.{s}", .{ | ||
| 6411 | framework_dir_path, | ||
| 6412 | framework_name, | ||
| 6413 | framework_name, | ||
| 6414 | ext, | ||
| 6415 | }); | ||
| 6416 | try checked_paths.writer().print("\n {s}", .{test_path.items}); | ||
| 6417 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { | ||
| 6418 | error.FileNotFound => continue, | ||
| 6419 | else => |e| fatal("unable to search for {s} framework '{s}': {s}", .{ | ||
| 6420 | ext, test_path.items, @errorName(e), | ||
| 6421 | }), | ||
| 6422 | }; | ||
| 6423 | return true; | ||
| 6424 | } | ||
| 6425 | |||
| 6426 | return false; | ||
| 6427 | } |