| ... | ... | @@ -190,6 +190,7 @@ compiler_rt_lib: ?CRTFile = null, |
| 190 | 190 | compiler_rt_obj: ?CRTFile = null, |
| 191 | 191 | |
| 192 | 192 | glibc_so_files: ?glibc.BuiltSharedObjects = null, |
| 193 | wasi_emulated_libs: []const wasi_libc.CRTFile, |
| 193 | 194 | |
| 194 | 195 | /// For example `Scrt1.o` and `libc_nonshared.a`. These are populated after building libc from source, |
| 195 | 196 | /// The set of needed CRT (C runtime) files differs depending on the target and compilation settings. |
| ... | ... | @@ -707,6 +708,8 @@ pub const Win32Resource = struct { |
| 707 | 708 | |
| 708 | 709 | pub const MiscTask = enum { |
| 709 | 710 | write_builtin_zig, |
| 711 | rename_results, |
| 712 | check_whole_cache, |
| 710 | 713 | glibc_crt_file, |
| 711 | 714 | glibc_shared_objects, |
| 712 | 715 | musl_crt_file, |
| ... | ... | @@ -1500,6 +1503,7 @@ pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { |
| 1500 | 1503 | .function_sections = options.function_sections, |
| 1501 | 1504 | .data_sections = options.data_sections, |
| 1502 | 1505 | .native_system_include_paths = options.native_system_include_paths, |
| 1506 | .wasi_emulated_libs = options.wasi_emulated_libs, |
| 1503 | 1507 | }; |
| 1504 | 1508 | |
| 1505 | 1509 | // Prevent some footguns by making the "any" fields of config reflect |
| ... | ... | @@ -1521,7 +1525,6 @@ pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { |
| 1521 | 1525 | .z_max_page_size = options.linker_z_max_page_size, |
| 1522 | 1526 | .darwin_sdk_layout = libc_dirs.darwin_sdk_layout, |
| 1523 | 1527 | .frameworks = options.frameworks, |
| 1524 | | .wasi_emulated_libs = options.wasi_emulated_libs, |
| 1525 | 1528 | .lib_dirs = options.lib_dirs, |
| 1526 | 1529 | .rpath_list = options.rpath_list, |
| 1527 | 1530 | .symbol_wrap_set = options.symbol_wrap_set, |
| ... | ... | @@ -1672,10 +1675,10 @@ pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { |
| 1672 | 1675 | }; |
| 1673 | 1676 | errdefer comp.destroy(); |
| 1674 | 1677 | |
| 1675 | | const target = options.root_mod.resolved_target.result; |
| 1678 | const target = comp.root_mod.resolved_target.result; |
| 1676 | 1679 | |
| 1677 | | const capable_of_building_compiler_rt = canBuildLibCompilerRt(target, options.config.use_llvm); |
| 1678 | | const capable_of_building_zig_libc = canBuildZigLibC(target, options.config.use_llvm); |
| 1680 | const capable_of_building_compiler_rt = canBuildLibCompilerRt(target, comp.config.use_llvm); |
| 1681 | const capable_of_building_zig_libc = canBuildZigLibC(target, comp.config.use_llvm); |
| 1679 | 1682 | |
| 1680 | 1683 | // Add a `CObject` for each `c_source_files`. |
| 1681 | 1684 | try comp.c_object_table.ensureTotalCapacity(gpa, options.c_source_files.len); |
| ... | ... | @@ -1768,25 +1771,21 @@ pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { |
| 1768 | 1771 | }); |
| 1769 | 1772 | } |
| 1770 | 1773 | |
| 1771 | | if (comp.bin_file) |lf| { |
| 1772 | | if (lf.cast(link.File.Wasm)) |wasm| { |
| 1773 | | if (comp.wantBuildWasiLibcFromSource()) { |
| 1774 | | if (!target_util.canBuildLibC(target)) return error.LibCUnavailable; |
| 1774 | if (comp.wantBuildWasiLibcFromSource()) { |
| 1775 | if (!target_util.canBuildLibC(target)) return error.LibCUnavailable; |
| 1775 | 1776 | |
| 1776 | | // worst-case we need all components |
| 1777 | | try comp.work_queue.ensureUnusedCapacity(wasm.wasi_emulated_libs.len + 2); |
| 1777 | // worst-case we need all components |
| 1778 | try comp.work_queue.ensureUnusedCapacity(comp.wasi_emulated_libs.len + 2); |
| 1778 | 1779 | |
| 1779 | | for (wasm.wasi_emulated_libs) |crt_file| { |
| 1780 | | comp.work_queue.writeItemAssumeCapacity(.{ |
| 1781 | | .wasi_libc_crt_file = crt_file, |
| 1782 | | }); |
| 1783 | | } |
| 1784 | | comp.work_queue.writeAssumeCapacity(&[_]Job{ |
| 1785 | | .{ .wasi_libc_crt_file = wasi_libc.execModelCrtFile(options.config.wasi_exec_model) }, |
| 1786 | | .{ .wasi_libc_crt_file = .libc_a }, |
| 1787 | | }); |
| 1788 | | } |
| 1780 | for (comp.wasi_emulated_libs) |crt_file| { |
| 1781 | comp.work_queue.writeItemAssumeCapacity(.{ |
| 1782 | .wasi_libc_crt_file = crt_file, |
| 1783 | }); |
| 1789 | 1784 | } |
| 1785 | comp.work_queue.writeAssumeCapacity(&[_]Job{ |
| 1786 | .{ .wasi_libc_crt_file = wasi_libc.execModelCrtFile(comp.config.wasi_exec_model) }, |
| 1787 | .{ .wasi_libc_crt_file = .libc_a }, |
| 1788 | }); |
| 1790 | 1789 | } |
| 1791 | 1790 | |
| 1792 | 1791 | if (comp.wantBuildMinGWFromSource()) { |
| ... | ... | @@ -1832,11 +1831,11 @@ pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { |
| 1832 | 1831 | } |
| 1833 | 1832 | |
| 1834 | 1833 | if (comp.bin_file) |lf| { |
| 1835 | | if (comp.getTarget().isMinGW() and comp.config.any_non_single_threaded) { |
| 1834 | if (target.isMinGW() and comp.config.any_non_single_threaded) { |
| 1836 | 1835 | // LLD might drop some symbols as unused during LTO and GCing, therefore, |
| 1837 | 1836 | // we force mark them for resolution here. |
| 1838 | 1837 | |
| 1839 | | const tls_index_sym = switch (comp.getTarget().cpu.arch) { |
| 1838 | const tls_index_sym = switch (target.cpu.arch) { |
| 1840 | 1839 | .x86 => "__tls_index", |
| 1841 | 1840 | else => "_tls_index", |
| 1842 | 1841 | }; |
| ... | ... | @@ -2024,12 +2023,14 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void |
| 2024 | 2023 | try comp.addNonIncrementalStuffToCacheManifest(&man); |
| 2025 | 2024 | |
| 2026 | 2025 | const is_hit = man.hit() catch |err| { |
| 2027 | | // TODO properly bubble these up instead of emitting a warning |
| 2028 | 2026 | const i = man.failed_file_index orelse return err; |
| 2029 | 2027 | const pp = man.files.items[i].prefixed_path orelse return err; |
| 2030 | 2028 | const prefix = man.cache.prefixes()[pp.prefix].path orelse ""; |
| 2031 | | std.log.warn("{s}: {s}{s}", .{ @errorName(err), prefix, pp.sub_path }); |
| 2032 | | return err; |
| 2029 | return comp.setMiscFailure( |
| 2030 | .check_whole_cache, |
| 2031 | "unable to check cache: stat file '{}{s}{s}' failed: {s}", |
| 2032 | .{ comp.local_cache_directory, prefix, pp.sub_path, @errorName(err) }, |
| 2033 | ); |
| 2033 | 2034 | }; |
| 2034 | 2035 | if (is_hit) { |
| 2035 | 2036 | comp.last_update_was_cache_hit = true; |
| ... | ... | @@ -2221,7 +2222,17 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void |
| 2221 | 2222 | const tmp_dir_sub_path = "tmp" ++ s ++ Package.Manifest.hex64(tmp_dir_rand_int); |
| 2222 | 2223 | const o_sub_path = "o" ++ s ++ digest; |
| 2223 | 2224 | |
| 2224 | | try renameTmpIntoCache(comp.local_cache_directory, tmp_dir_sub_path, o_sub_path); |
| 2225 | renameTmpIntoCache(comp.local_cache_directory, tmp_dir_sub_path, o_sub_path) catch |err| { |
| 2226 | return comp.setMiscFailure( |
| 2227 | .rename_results, |
| 2228 | "failed to rename compilation results ('{}{s}') into local cache ('{}{s}'): {s}", |
| 2229 | .{ |
| 2230 | comp.local_cache_directory, tmp_dir_sub_path, |
| 2231 | comp.local_cache_directory, o_sub_path, |
| 2232 | @errorName(err), |
| 2233 | }, |
| 2234 | ); |
| 2235 | }; |
| 2225 | 2236 | comp.wholeCacheModeSetBinFilePath(whole, &digest); |
| 2226 | 2237 | |
| 2227 | 2238 | // Failure here only means an unnecessary cache miss. |
| ... | ... | @@ -2251,42 +2262,36 @@ fn renameTmpIntoCache( |
| 2251 | 2262 | tmp_dir_sub_path: []const u8, |
| 2252 | 2263 | o_sub_path: []const u8, |
| 2253 | 2264 | ) !void { |
| 2265 | var seen_eaccess = false; |
| 2254 | 2266 | while (true) { |
| 2255 | | if (builtin.os.tag == .windows) { |
| 2256 | | // Work around windows `renameW` can't fail with `PathAlreadyExists` |
| 2267 | std.fs.rename( |
| 2268 | cache_directory.handle, |
| 2269 | tmp_dir_sub_path, |
| 2270 | cache_directory.handle, |
| 2271 | o_sub_path, |
| 2272 | ) catch |err| switch (err) { |
| 2273 | // On Windows, rename fails with `AccessDenied` rather than `PathAlreadyExists`. |
| 2257 | 2274 | // See https://github.com/ziglang/zig/issues/8362 |
| 2258 | | if (cache_directory.handle.access(o_sub_path, .{})) |_| { |
| 2259 | | try cache_directory.handle.deleteTree(o_sub_path); |
| 2260 | | continue; |
| 2261 | | } else |err| switch (err) { |
| 2262 | | error.FileNotFound => {}, |
| 2263 | | else => |e| return e, |
| 2264 | | } |
| 2265 | | std.fs.rename( |
| 2266 | | cache_directory.handle, |
| 2267 | | tmp_dir_sub_path, |
| 2268 | | cache_directory.handle, |
| 2269 | | o_sub_path, |
| 2270 | | ) catch |err| { |
| 2271 | | log.err("unable to rename cache dir {s} to {s}: {s}", .{ tmp_dir_sub_path, o_sub_path, @errorName(err) }); |
| 2272 | | return err; |
| 2273 | | }; |
| 2274 | | break; |
| 2275 | | } else { |
| 2276 | | std.fs.rename( |
| 2277 | | cache_directory.handle, |
| 2278 | | tmp_dir_sub_path, |
| 2279 | | cache_directory.handle, |
| 2280 | | o_sub_path, |
| 2281 | | ) catch |err| switch (err) { |
| 2282 | | error.PathAlreadyExists => { |
| 2275 | error.AccessDenied => switch (builtin.os.tag) { |
| 2276 | .windows => { |
| 2277 | if (!seen_eaccess) return error.AccessDenied; |
| 2278 | seen_eaccess = true; |
| 2283 | 2279 | try cache_directory.handle.deleteTree(o_sub_path); |
| 2284 | 2280 | continue; |
| 2285 | 2281 | }, |
| 2286 | | else => |e| return e, |
| 2287 | | }; |
| 2288 | | break; |
| 2289 | | } |
| 2282 | else => return error.AccessDenied, |
| 2283 | }, |
| 2284 | error.PathAlreadyExists => { |
| 2285 | try cache_directory.handle.deleteTree(o_sub_path); |
| 2286 | continue; |
| 2287 | }, |
| 2288 | error.FileNotFound => { |
| 2289 | try cache_directory.handle.makePath("o"); |
| 2290 | continue; |
| 2291 | }, |
| 2292 | else => |e| return e, |
| 2293 | }; |
| 2294 | break; |
| 2290 | 2295 | } |
| 2291 | 2296 | } |
| 2292 | 2297 | |
| ... | ... | @@ -2386,6 +2391,10 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2386 | 2391 | try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.main_mod, .{ .files = man }); |
| 2387 | 2392 | |
| 2388 | 2393 | // Synchronize with other matching comments: ZigOnlyHashStuff |
| 2394 | man.hash.add(comp.config.use_llvm); |
| 2395 | man.hash.add(comp.config.use_lib_llvm); |
| 2396 | man.hash.add(comp.config.dll_export_fns); |
| 2397 | man.hash.add(comp.config.is_test); |
| 2389 | 2398 | man.hash.add(comp.config.test_evented_io); |
| 2390 | 2399 | man.hash.addOptionalBytes(comp.test_filter); |
| 2391 | 2400 | man.hash.addOptionalBytes(comp.test_name_prefix); |
| ... | ... | @@ -2393,6 +2402,20 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2393 | 2402 | man.hash.add(comp.formatted_panics); |
| 2394 | 2403 | man.hash.add(mod.emit_h != null); |
| 2395 | 2404 | man.hash.add(mod.error_limit); |
| 2405 | } else { |
| 2406 | cache_helpers.addResolvedTarget(&man.hash, comp.root_mod.resolved_target); |
| 2407 | man.hash.add(comp.root_mod.optimize_mode); |
| 2408 | man.hash.add(comp.root_mod.code_model); |
| 2409 | man.hash.add(comp.root_mod.single_threaded); |
| 2410 | man.hash.add(comp.root_mod.error_tracing); |
| 2411 | man.hash.add(comp.root_mod.pic); |
| 2412 | man.hash.add(comp.root_mod.omit_frame_pointer); |
| 2413 | man.hash.add(comp.root_mod.stack_check); |
| 2414 | man.hash.add(comp.root_mod.red_zone); |
| 2415 | man.hash.add(comp.root_mod.sanitize_c); |
| 2416 | man.hash.add(comp.root_mod.sanitize_thread); |
| 2417 | man.hash.add(comp.root_mod.unwind_tables); |
| 2418 | man.hash.add(comp.root_mod.structured_cfg); |
| 2396 | 2419 | } |
| 2397 | 2420 | |
| 2398 | 2421 | for (comp.objects) |obj| { |
| ... | ... | @@ -3829,8 +3852,19 @@ pub fn obtainCObjectCacheManifest( |
| 3829 | 3852 | // Only things that need to be added on top of the base hash, and only things |
| 3830 | 3853 | // that apply both to @cImport and compiling C objects. No linking stuff here! |
| 3831 | 3854 | // Also nothing that applies only to compiling .zig code. |
| 3855 | cache_helpers.addResolvedTarget(&man.hash, owner_mod.resolved_target); |
| 3856 | man.hash.add(owner_mod.optimize_mode); |
| 3857 | man.hash.add(owner_mod.code_model); |
| 3858 | man.hash.add(owner_mod.single_threaded); |
| 3859 | man.hash.add(owner_mod.error_tracing); |
| 3860 | man.hash.add(owner_mod.pic); |
| 3861 | man.hash.add(owner_mod.omit_frame_pointer); |
| 3862 | man.hash.add(owner_mod.stack_check); |
| 3863 | man.hash.add(owner_mod.red_zone); |
| 3832 | 3864 | man.hash.add(owner_mod.sanitize_c); |
| 3833 | 3865 | man.hash.add(owner_mod.sanitize_thread); |
| 3866 | man.hash.add(owner_mod.unwind_tables); |
| 3867 | man.hash.add(owner_mod.structured_cfg); |
| 3834 | 3868 | man.hash.addListOfBytes(owner_mod.cc_argv); |
| 3835 | 3869 | man.hash.add(comp.config.link_libcpp); |
| 3836 | 3870 | |