| ... | @@ -190,6 +190,7 @@ compiler_rt_lib: ?CRTFile = null, | ... | @@ -190,6 +190,7 @@ compiler_rt_lib: ?CRTFile = null, |
| 190 | compiler_rt_obj: ?CRTFile = null, | 190 | compiler_rt_obj: ?CRTFile = null, |
| 191 | | 191 | |
| 192 | glibc_so_files: ?glibc.BuiltSharedObjects = null, | 192 | glibc_so_files: ?glibc.BuiltSharedObjects = null, |
| | 193 | wasi_emulated_libs: []const wasi_libc.CRTFile, |
| 193 | | 194 | |
| 194 | /// For example `Scrt1.o` and `libc_nonshared.a`. These are populated after building libc from source, | 195 | /// For example `Scrt1.o` and `libc_nonshared.a`. These are populated after building libc from source, |
| 195 | /// The set of needed CRT (C runtime) files differs depending on the target and compilation settings. | 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,6 +708,8 @@ pub const Win32Resource = struct { |
| 707 | | 708 | |
| 708 | pub const MiscTask = enum { | 709 | pub const MiscTask = enum { |
| 709 | write_builtin_zig, | 710 | write_builtin_zig, |
| | 711 | rename_results, |
| | 712 | check_whole_cache, |
| 710 | glibc_crt_file, | 713 | glibc_crt_file, |
| 711 | glibc_shared_objects, | 714 | glibc_shared_objects, |
| 712 | musl_crt_file, | 715 | musl_crt_file, |
| ... | @@ -1500,6 +1503,7 @@ pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { | ... | @@ -1500,6 +1503,7 @@ pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { |
| 1500 | .function_sections = options.function_sections, | 1503 | .function_sections = options.function_sections, |
| 1501 | .data_sections = options.data_sections, | 1504 | .data_sections = options.data_sections, |
| 1502 | .native_system_include_paths = options.native_system_include_paths, | 1505 | .native_system_include_paths = options.native_system_include_paths, |
| | 1506 | .wasi_emulated_libs = options.wasi_emulated_libs, |
| 1503 | }; | 1507 | }; |
| 1504 | | 1508 | |
| 1505 | // Prevent some footguns by making the "any" fields of config reflect | 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,7 +1525,6 @@ pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { |
| 1521 | .z_max_page_size = options.linker_z_max_page_size, | 1525 | .z_max_page_size = options.linker_z_max_page_size, |
| 1522 | .darwin_sdk_layout = libc_dirs.darwin_sdk_layout, | 1526 | .darwin_sdk_layout = libc_dirs.darwin_sdk_layout, |
| 1523 | .frameworks = options.frameworks, | 1527 | .frameworks = options.frameworks, |
| 1524 | .wasi_emulated_libs = options.wasi_emulated_libs, | | |
| 1525 | .lib_dirs = options.lib_dirs, | 1528 | .lib_dirs = options.lib_dirs, |
| 1526 | .rpath_list = options.rpath_list, | 1529 | .rpath_list = options.rpath_list, |
| 1527 | .symbol_wrap_set = options.symbol_wrap_set, | 1530 | .symbol_wrap_set = options.symbol_wrap_set, |
| ... | @@ -1672,10 +1675,10 @@ pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { | ... | @@ -1672,10 +1675,10 @@ pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { |
| 1672 | }; | 1675 | }; |
| 1673 | errdefer comp.destroy(); | 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); | 1680 | const capable_of_building_compiler_rt = canBuildLibCompilerRt(target, comp.config.use_llvm); |
| 1678 | const capable_of_building_zig_libc = canBuildZigLibC(target, options.config.use_llvm); | 1681 | const capable_of_building_zig_libc = canBuildZigLibC(target, comp.config.use_llvm); |
| 1679 | | 1682 | |
| 1680 | // Add a `CObject` for each `c_source_files`. | 1683 | // Add a `CObject` for each `c_source_files`. |
| 1681 | try comp.c_object_table.ensureTotalCapacity(gpa, options.c_source_files.len); | 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,25 +1771,21 @@ pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { |
| 1768 | }); | 1771 | }); |
| 1769 | } | 1772 | } |
| 1770 | | 1773 | |
| 1771 | if (comp.bin_file) |lf| { | 1774 | if (comp.wantBuildWasiLibcFromSource()) { |
| 1772 | if (lf.cast(link.File.Wasm)) |wasm| { | 1775 | if (!target_util.canBuildLibC(target)) return error.LibCUnavailable; |
| 1773 | if (comp.wantBuildWasiLibcFromSource()) { | | |
| 1774 | if (!target_util.canBuildLibC(target)) return error.LibCUnavailable; | | |
| 1775 | | 1776 | |
| 1776 | // worst-case we need all components | 1777 | // worst-case we need all components |
| 1777 | try comp.work_queue.ensureUnusedCapacity(wasm.wasi_emulated_libs.len + 2); | 1778 | try comp.work_queue.ensureUnusedCapacity(comp.wasi_emulated_libs.len + 2); |
| 1778 | | 1779 | |
| 1779 | for (wasm.wasi_emulated_libs) |crt_file| { | 1780 | for (comp.wasi_emulated_libs) |crt_file| { |
| 1780 | comp.work_queue.writeItemAssumeCapacity(.{ | 1781 | comp.work_queue.writeItemAssumeCapacity(.{ |
| 1781 | .wasi_libc_crt_file = crt_file, | 1782 | .wasi_libc_crt_file = crt_file, |
| 1782 | }); | 1783 | }); |
| 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 | } | | |
| 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 | if (comp.wantBuildMinGWFromSource()) { | 1791 | if (comp.wantBuildMinGWFromSource()) { |
| ... | @@ -1832,11 +1831,11 @@ pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { | ... | @@ -1832,11 +1831,11 @@ pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { |
| 1832 | } | 1831 | } |
| 1833 | | 1832 | |
| 1834 | if (comp.bin_file) |lf| { | 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 | // LLD might drop some symbols as unused during LTO and GCing, therefore, | 1835 | // LLD might drop some symbols as unused during LTO and GCing, therefore, |
| 1837 | // we force mark them for resolution here. | 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 | .x86 => "__tls_index", | 1839 | .x86 => "__tls_index", |
| 1841 | else => "_tls_index", | 1840 | else => "_tls_index", |
| 1842 | }; | 1841 | }; |
| ... | @@ -2024,12 +2023,14 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void | ... | @@ -2024,12 +2023,14 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void |
| 2024 | try comp.addNonIncrementalStuffToCacheManifest(&man); | 2023 | try comp.addNonIncrementalStuffToCacheManifest(&man); |
| 2025 | | 2024 | |
| 2026 | const is_hit = man.hit() catch |err| { | 2025 | const is_hit = man.hit() catch |err| { |
| 2027 | // TODO properly bubble these up instead of emitting a warning | | |
| 2028 | const i = man.failed_file_index orelse return err; | 2026 | const i = man.failed_file_index orelse return err; |
| 2029 | const pp = man.files.items[i].prefixed_path orelse return err; | 2027 | const pp = man.files.items[i].prefixed_path orelse return err; |
| 2030 | const prefix = man.cache.prefixes()[pp.prefix].path orelse ""; | 2028 | const prefix = man.cache.prefixes()[pp.prefix].path orelse ""; |
| 2031 | std.log.warn("{s}: {s}{s}", .{ @errorName(err), prefix, pp.sub_path }); | 2029 | return comp.setMiscFailure( |
| 2032 | return err; | 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 | if (is_hit) { | 2035 | if (is_hit) { |
| 2035 | comp.last_update_was_cache_hit = true; | 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,7 +2222,17 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void |
| 2221 | const tmp_dir_sub_path = "tmp" ++ s ++ Package.Manifest.hex64(tmp_dir_rand_int); | 2222 | const tmp_dir_sub_path = "tmp" ++ s ++ Package.Manifest.hex64(tmp_dir_rand_int); |
| 2222 | const o_sub_path = "o" ++ s ++ digest; | 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 | comp.wholeCacheModeSetBinFilePath(whole, &digest); | 2236 | comp.wholeCacheModeSetBinFilePath(whole, &digest); |
| 2226 | | 2237 | |
| 2227 | // Failure here only means an unnecessary cache miss. | 2238 | // Failure here only means an unnecessary cache miss. |
| ... | @@ -2251,42 +2262,36 @@ fn renameTmpIntoCache( | ... | @@ -2251,42 +2262,36 @@ fn renameTmpIntoCache( |
| 2251 | tmp_dir_sub_path: []const u8, | 2262 | tmp_dir_sub_path: []const u8, |
| 2252 | o_sub_path: []const u8, | 2263 | o_sub_path: []const u8, |
| 2253 | ) !void { | 2264 | ) !void { |
| | 2265 | var seen_eaccess = false; |
| 2254 | while (true) { | 2266 | while (true) { |
| 2255 | if (builtin.os.tag == .windows) { | 2267 | std.fs.rename( |
| 2256 | // Work around windows `renameW` can't fail with `PathAlreadyExists` | 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 | // See https://github.com/ziglang/zig/issues/8362 | 2274 | // See https://github.com/ziglang/zig/issues/8362 |
| 2258 | if (cache_directory.handle.access(o_sub_path, .{})) |_| { | 2275 | error.AccessDenied => switch (builtin.os.tag) { |
| 2259 | try cache_directory.handle.deleteTree(o_sub_path); | 2276 | .windows => { |
| 2260 | continue; | 2277 | if (!seen_eaccess) return error.AccessDenied; |
| 2261 | } else |err| switch (err) { | 2278 | seen_eaccess = true; |
| 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 => { | | |
| 2283 | try cache_directory.handle.deleteTree(o_sub_path); | 2279 | try cache_directory.handle.deleteTree(o_sub_path); |
| 2284 | continue; | 2280 | continue; |
| 2285 | }, | 2281 | }, |
| 2286 | else => |e| return e, | 2282 | else => return error.AccessDenied, |
| 2287 | }; | 2283 | }, |
| 2288 | break; | 2284 | error.PathAlreadyExists => { |
| 2289 | } | 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,6 +2391,10 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2386 | try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.main_mod, .{ .files = man }); | 2391 | try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.main_mod, .{ .files = man }); |
| 2387 | | 2392 | |
| 2388 | // Synchronize with other matching comments: ZigOnlyHashStuff | 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 | man.hash.add(comp.config.test_evented_io); | 2398 | man.hash.add(comp.config.test_evented_io); |
| 2390 | man.hash.addOptionalBytes(comp.test_filter); | 2399 | man.hash.addOptionalBytes(comp.test_filter); |
| 2391 | man.hash.addOptionalBytes(comp.test_name_prefix); | 2400 | man.hash.addOptionalBytes(comp.test_name_prefix); |
| ... | @@ -2393,6 +2402,20 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes | ... | @@ -2393,6 +2402,20 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2393 | man.hash.add(comp.formatted_panics); | 2402 | man.hash.add(comp.formatted_panics); |
| 2394 | man.hash.add(mod.emit_h != null); | 2403 | man.hash.add(mod.emit_h != null); |
| 2395 | man.hash.add(mod.error_limit); | 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 | for (comp.objects) |obj| { | 2421 | for (comp.objects) |obj| { |
| ... | @@ -3829,8 +3852,19 @@ pub fn obtainCObjectCacheManifest( | ... | @@ -3829,8 +3852,19 @@ pub fn obtainCObjectCacheManifest( |
| 3829 | // Only things that need to be added on top of the base hash, and only things | 3852 | // Only things that need to be added on top of the base hash, and only things |
| 3830 | // that apply both to @cImport and compiling C objects. No linking stuff here! | 3853 | // that apply both to @cImport and compiling C objects. No linking stuff here! |
| 3831 | // Also nothing that applies only to compiling .zig code. | 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 | man.hash.add(owner_mod.sanitize_c); | 3864 | man.hash.add(owner_mod.sanitize_c); |
| 3833 | man.hash.add(owner_mod.sanitize_thread); | 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 | man.hash.addListOfBytes(owner_mod.cc_argv); | 3868 | man.hash.addListOfBytes(owner_mod.cc_argv); |
| 3835 | man.hash.add(comp.config.link_libcpp); | 3869 | man.hash.add(comp.config.link_libcpp); |
| 3836 | | 3870 | |