| 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 | 507 | c_source_files: []const CSourceFile = &[0]CSourceFile{}, |
| 508 | 508 | link_objects: []LinkObject = &[0]LinkObject{}, |
| 509 | 509 | framework_dirs: []const []const u8 = &[0][]const u8{}, |
| 510 | frameworks: std.StringArrayHashMapUnmanaged(Framework) = .{}, | |
| 510 | frameworks: []const Framework = &.{}, | |
| 511 | 511 | system_lib_names: []const []const u8 = &.{}, |
| 512 | 512 | system_lib_infos: []const SystemLib = &.{}, |
| 513 | 513 | /// These correspond to the WASI libc emulated subcomponents including: |
| ... | ... | @@ -830,7 +830,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 830 | 830 | // Our linker can't handle objects or most advanced options yet. |
| 831 | 831 | if (options.link_objects.len != 0 or |
| 832 | 832 | options.c_source_files.len != 0 or |
| 833 | options.frameworks.count() != 0 or | |
| 833 | options.frameworks.len != 0 or | |
| 834 | 834 | options.system_lib_names.len != 0 or |
| 835 | 835 | options.link_libc or options.link_libcpp or |
| 836 | 836 | link_eh_frame_hdr or |
| ... | ... | @@ -2267,7 +2267,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo |
| 2267 | 2267 | /// to remind the programmer to update multiple related pieces of code that |
| 2268 | 2268 | /// are in different locations. Bump this number when adding or deleting |
| 2269 | 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 | 2272 | fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifest) !void { |
| 2273 | 2273 | const gpa = comp.gpa; |
| ... | ... | @@ -2277,7 +2277,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2277 | 2277 | defer arena_allocator.deinit(); |
| 2278 | 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 | 2282 | if (comp.bin_file.options.module) |mod| { |
| 2283 | 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 | 2386 | |
| 2387 | 2387 | // Mach-O specific stuff |
| 2388 | 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 | 2390 | try man.addOptionalFile(comp.bin_file.options.entitlements); |
| 2391 | 2391 | man.hash.addOptional(comp.bin_file.options.pagezero_size); |
| 2392 | 2392 | man.hash.addOptional(comp.bin_file.options.headerpad_size); |
src/link.zig+7-12| ... | ... | @@ -37,6 +37,7 @@ pub const SystemLib = struct { |
| 37 | 37 | pub const Framework = struct { |
| 38 | 38 | needed: bool = false, |
| 39 | 39 | weak: bool = false, |
| 40 | path: []const u8, | |
| 40 | 41 | }; |
| 41 | 42 | |
| 42 | 43 | pub const SortSection = enum { name, alignment }; |
| ... | ... | @@ -56,15 +57,11 @@ pub fn hashAddSystemLibs( |
| 56 | 57 | } |
| 57 | 58 | } |
| 58 | 59 | |
| 59 | pub fn hashAddFrameworks( | |
| 60 | hh: *Cache.HashHelper, | |
| 61 | hm: std.StringArrayHashMapUnmanaged(Framework), | |
| 62 | ) void { | |
| 63 | const keys = hm.keys(); | |
| 64 | hh.addListOfBytes(keys); | |
| 65 | for (hm.values()) |value| { | |
| 66 | hh.add(value.needed); | |
| 67 | hh.add(value.weak); | |
| 60 | pub fn hashAddFrameworks(man: *Cache.Manifest, hm: []const Framework) !void { | |
| 61 | for (hm) |value| { | |
| 62 | man.hash.add(value.needed); | |
| 63 | man.hash.add(value.weak); | |
| 64 | _ = try man.addFile(value.path, null); | |
| 68 | 65 | } |
| 69 | 66 | } |
| 70 | 67 | |
| ... | ... | @@ -208,7 +205,7 @@ pub const Options = struct { |
| 208 | 205 | |
| 209 | 206 | objects: []Compilation.LinkObject, |
| 210 | 207 | framework_dirs: []const []const u8, |
| 211 | frameworks: std.StringArrayHashMapUnmanaged(Framework), | |
| 208 | frameworks: []const Framework, | |
| 212 | 209 | /// These are *always* dynamically linked. Static libraries will be |
| 213 | 210 | /// provided as positional arguments. |
| 214 | 211 | system_libs: std.StringArrayHashMapUnmanaged(SystemLib), |
| ... | ... | @@ -276,7 +273,6 @@ pub const Options = struct { |
| 276 | 273 | |
| 277 | 274 | pub fn move(self: *Options) Options { |
| 278 | 275 | const copied_state = self.*; |
| 279 | self.frameworks = .{}; | |
| 280 | 276 | self.system_libs = .{}; |
| 281 | 277 | self.force_undefined_symbols = .{}; |
| 282 | 278 | return copied_state; |
| ... | ... | @@ -642,7 +638,6 @@ pub const File = struct { |
| 642 | 638 | base.releaseLock(); |
| 643 | 639 | if (base.file) |f| f.close(); |
| 644 | 640 | if (base.intermediary_basename) |sub_path| base.allocator.free(sub_path); |
| 645 | base.options.frameworks.deinit(base.allocator); | |
| 646 | 641 | base.options.system_libs.deinit(base.allocator); |
| 647 | 642 | base.options.force_undefined_symbols.deinit(base.allocator); |
| 648 | 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 | 63 | man = comp.cache_parent.obtain(); |
| 64 | 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 | 68 | for (self.base.options.objects) |obj| { |
| 69 | 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 | 1367 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 1368 | 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 | 1372 | try man.addOptionalFile(self.base.options.linker_script); |
| 1373 | 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 | 870 | return false; |
| 871 | 871 | } |
| 872 | 872 | |
| 873 | pub fn resolveSearchDir( | |
| 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( | |
| 873 | fn resolveLib( | |
| 916 | 874 | arena: Allocator, |
| 917 | 875 | search_dir: []const u8, |
| 918 | 876 | name: []const u8, |
| ... | ... | @@ -931,26 +889,6 @@ pub fn resolveLib( |
| 931 | 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 | 892 | const ParseDylibError = error{ |
| 955 | 893 | OutOfMemory, |
| 956 | 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 | 3396 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 3397 | 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 | 3401 | for (options.objects) |obj| { |
| 3402 | 3402 | _ = try man.addFile(obj.path, null); |
| ... | ... | @@ -3417,7 +3417,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3417 | 3417 | man.hash.add(options.strip); |
| 3418 | 3418 | man.hash.addListOfBytes(options.lib_dirs); |
| 3419 | 3419 | man.hash.addListOfBytes(options.framework_dirs); |
| 3420 | link.hashAddFrameworks(&man.hash, options.frameworks); | |
| 3420 | try link.hashAddFrameworks(&man, options.frameworks); | |
| 3421 | 3421 | man.hash.addListOfBytes(options.rpath_list); |
| 3422 | 3422 | if (is_dyn_lib) { |
| 3423 | 3423 | man.hash.addOptionalBytes(options.install_name); |
| ... | ... | @@ -3512,9 +3512,6 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3512 | 3512 | try zld.atoms.append(gpa, Atom.empty); // AtomIndex at 0 is reserved as null atom |
| 3513 | 3513 | try zld.strtab.buffer.append(gpa, 0); |
| 3514 | 3514 | |
| 3515 | var lib_not_found = false; | |
| 3516 | var framework_not_found = false; | |
| 3517 | ||
| 3518 | 3515 | // Positional arguments to the linker such as object files and static archives. |
| 3519 | 3516 | var positionals = std.ArrayList([]const u8).init(arena); |
| 3520 | 3517 | try positionals.ensureUnusedCapacity(options.objects.len); |
| ... | ... | @@ -3557,43 +3554,16 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3557 | 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); | |
| 3561 | ||
| 3562 | // frameworks | |
| 3563 | var framework_dirs = std.ArrayList([]const u8).init(arena); | |
| 3564 | for (options.framework_dirs) |dir| { | |
| 3565 | if (try MachO.resolveSearchDir(arena, dir, options.sysroot)) |search_dir| { | |
| 3566 | try framework_dirs.append(search_dir); | |
| 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 | } | |
| 3557 | { | |
| 3558 | try libs.ensureUnusedCapacity(options.frameworks.len); | |
| 3559 | for (options.frameworks) |v| libs.putAssumeCapacity(v.path, .{ | |
| 3560 | .needed = v.needed, | |
| 3561 | .weak = v.weak, | |
| 3562 | .path = v.path, | |
| 3563 | }); | |
| 3589 | 3564 | } |
| 3590 | 3565 | |
| 3591 | if (framework_not_found) { | |
| 3592 | log.warn("Framework search paths:", .{}); | |
| 3593 | for (framework_dirs.items) |dir| { | |
| 3594 | log.warn(" {s}", .{dir}); | |
| 3595 | } | |
| 3596 | } | |
| 3566 | try MachO.resolveLibSystem(arena, comp, options.sysroot, target, options.lib_dirs, &libs); | |
| 3597 | 3567 | |
| 3598 | 3568 | if (options.verbose_link) { |
| 3599 | 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 | 3663 | try argv.append(try std.fmt.allocPrint(arena, "-L{s}", .{lib_dir})); |
| 3694 | 3664 | } |
| 3695 | 3665 | |
| 3696 | for (options.frameworks.keys()) |framework| { | |
| 3697 | const info = options.frameworks.get(framework).?; | |
| 3698 | const arg = if (info.needed) | |
| 3699 | try std.fmt.allocPrint(arena, "-needed_framework {s}", .{framework}) | |
| 3700 | else if (info.weak) | |
| 3701 | try std.fmt.allocPrint(arena, "-weak_framework {s}", .{framework}) | |
| 3666 | for (options.frameworks) |framework| { | |
| 3667 | const name = std.fs.path.stem(framework.path); | |
| 3668 | const arg = if (framework.needed) | |
| 3669 | try std.fmt.allocPrint(arena, "-needed_framework {s}", .{name}) | |
| 3670 | else if (framework.weak) | |
| 3671 | try std.fmt.allocPrint(arena, "-weak_framework {s}", .{name}) | |
| 3702 | 3672 | else |
| 3703 | try std.fmt.allocPrint(arena, "-framework {s}", .{framework}); | |
| 3673 | try std.fmt.allocPrint(arena, "-framework {s}", .{name}); | |
| 3704 | 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 | 3710 | if (resolver.unresolved.count() > 0) { |
| 3741 | 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 | 3714 | if (options.output_mode == .Exe) { |
| 3751 | 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 | 3193 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 3194 | 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 | 3198 | for (options.objects) |obj| { |
| 3199 | 3199 | _ = try man.addFile(obj.path, null); |
| ... | ... | @@ -4254,7 +4254,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4254 | 4254 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 4255 | 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 | 4259 | for (wasm.base.options.objects) |obj| { |
| 4260 | 4260 | _ = try man.addFile(obj.path, null); |
src/main.zig+91-2| ... | ... | @@ -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 | 756 | const CliModule = struct { |
| 750 | 757 | mod: *Package, |
| 751 | 758 | /// still in CLI arg format |
| ... | ... | @@ -919,7 +926,7 @@ fn buildOutputType( |
| 919 | 926 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena); |
| 920 | 927 | var link_objects = std.ArrayList(Compilation.LinkObject).init(arena); |
| 921 | 928 | var framework_dirs = std.ArrayList([]const u8).init(arena); |
| 922 | var frameworks: std.StringArrayHashMapUnmanaged(Compilation.Framework) = .{}; | |
| 929 | var frameworks: std.StringArrayHashMapUnmanaged(Framework) = .{}; | |
| 923 | 930 | // null means replace with the test executable binary |
| 924 | 931 | var test_exec_args = std.ArrayList(?[]const u8).init(arena); |
| 925 | 932 | var linker_export_symbol_names = std.ArrayList([]const u8).init(arena); |
| ... | ... | @@ -2868,6 +2875,59 @@ fn buildOutputType( |
| 2868 | 2875 | } |
| 2869 | 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 | 2931 | const object_format = target_info.target.ofmt; |
| 2872 | 2932 | |
| 2873 | 2933 | if (output_mode == .Obj and (object_format == .coff or object_format == .macho)) { |
| ... | ... | @@ -3261,7 +3321,7 @@ fn buildOutputType( |
| 3261 | 3321 | .c_source_files = c_source_files.items, |
| 3262 | 3322 | .link_objects = link_objects.items, |
| 3263 | 3323 | .framework_dirs = framework_dirs.items, |
| 3264 | .frameworks = frameworks, | |
| 3324 | .frameworks = resolved_frameworks.items, | |
| 3265 | 3325 | .system_lib_names = resolved_system_libs.items(.name), |
| 3266 | 3326 | .system_lib_infos = resolved_system_libs.items(.lib), |
| 3267 | 3327 | .wasi_emulated_libs = wasi_emulated_libs.items, |
| ... | ... | @@ -6336,3 +6396,32 @@ fn accessLibPath( |
| 6336 | 6396 | |
| 6337 | 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 | } |