authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-12-13 18:28:00-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-01 17:51:19-07:00
log33cdf33b95676dca9f91216e0f8742f9cf7e84fb
tree59ccf012a4fc839def23bce321c1735b6bdf5651
parentb162c3c820d8a6446bbdfba90b3c135ebcd76fcb

compiler: update many references to bin_file.options


11 files changed, 319 insertions(+), 231 deletions(-)

src/Compilation.zig+197-173
...@@ -77,6 +77,7 @@ system_libs: std.StringArrayHashMapUnmanaged(SystemLib),...@@ -77,6 +77,7 @@ system_libs: std.StringArrayHashMapUnmanaged(SystemLib),
77version: ?std.SemanticVersion,77version: ?std.SemanticVersion,
78libc_installation: ?*const LibCInstallation,78libc_installation: ?*const LibCInstallation,
79skip_linker_dependencies: bool,79skip_linker_dependencies: bool,
80no_builtin: bool,
8081
81c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{},82c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{},
82win32_resource_table: if (build_options.only_core_functionality) void else std.AutoArrayHashMapUnmanaged(*Win32Resource, void) =83win32_resource_table: if (build_options.only_core_functionality) void else std.AutoArrayHashMapUnmanaged(*Win32Resource, void) =
...@@ -988,10 +989,9 @@ pub const InitOptions = struct {...@@ -988,10 +989,9 @@ pub const InitOptions = struct {
988 linker_tsaware: bool = false,989 linker_tsaware: bool = false,
989 linker_nxcompat: bool = false,990 linker_nxcompat: bool = false,
990 linker_dynamicbase: bool = true,991 linker_dynamicbase: bool = true,
991 linker_optimization: ?u8 = null,992 linker_compress_debug_sections: ?link.File.Elf.CompressDebugSections = null,
992 linker_compress_debug_sections: ?link.CompressDebugSections = null,
993 linker_module_definition_file: ?[]const u8 = null,993 linker_module_definition_file: ?[]const u8 = null,
994 linker_sort_section: ?link.SortSection = null,994 linker_sort_section: ?link.File.Elf.SortSection = null,
995 major_subsystem_version: ?u32 = null,995 major_subsystem_version: ?u32 = null,
996 minor_subsystem_version: ?u32 = null,996 minor_subsystem_version: ?u32 = null,
997 clang_passthrough_mode: bool = false,997 clang_passthrough_mode: bool = false,
...@@ -1011,7 +1011,7 @@ pub const InitOptions = struct {...@@ -1011,7 +1011,7 @@ pub const InitOptions = struct {
1011 /// building such dependencies themselves, this flag must be set to avoid1011 /// building such dependencies themselves, this flag must be set to avoid
1012 /// infinite recursion.1012 /// infinite recursion.
1013 skip_linker_dependencies: bool = false,1013 skip_linker_dependencies: bool = false,
1014 hash_style: link.HashStyle = .both,1014 hash_style: link.File.Elf.HashStyle = .both,
1015 entry: ?[]const u8 = null,1015 entry: ?[]const u8 = null,
1016 force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{},1016 force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{},
1017 stack_size: ?u64 = null,1017 stack_size: ?u64 = null,
...@@ -1049,8 +1049,6 @@ pub const InitOptions = struct {...@@ -1049,8 +1049,6 @@ pub const InitOptions = struct {
1049 /// (Windows) PDB output path1049 /// (Windows) PDB output path
1050 pdb_out_path: ?[]const u8 = null,1050 pdb_out_path: ?[]const u8 = null,
1051 error_limit: ?Compilation.Module.ErrorInt = null,1051 error_limit: ?Compilation.Module.ErrorInt = null,
1052 /// (SPIR-V) whether to generate a structured control flow graph or not
1053 want_structured_cfg: ?bool = null,
1054};1052};
10551053
1056fn addModuleTableToCacheHash(1054fn addModuleTableToCacheHash(
...@@ -1277,10 +1275,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1277,10 +1275,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1277 }1275 }
1278 }1276 }
12791277
1280 const linker_optimization: u8 = options.linker_optimization orelse switch (options.root_mod.optimize_mode) {
1281 .Debug => @as(u8, 0),
1282 else => @as(u8, 3),
1283 };
1284 // TODO: https://github.com/ziglang/zig/issues/179691278 // TODO: https://github.com/ziglang/zig/issues/17969
1285 const formatted_panics = options.formatted_panics orelse (options.root_mod.optimize_mode == .Debug);1279 const formatted_panics = options.formatted_panics orelse (options.root_mod.optimize_mode == .Debug);
12861280
...@@ -1359,7 +1353,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1359,7 +1353,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1359 hash.add(formatted_panics);1353 hash.add(formatted_panics);
1360 hash.add(options.emit_h != null);1354 hash.add(options.emit_h != null);
1361 hash.add(error_limit);1355 hash.add(error_limit);
1362 hash.addOptional(options.want_structured_cfg);
13631356
1364 // In the case of incremental cache mode, this `zig_cache_artifact_directory`1357 // In the case of incremental cache mode, this `zig_cache_artifact_directory`
1365 // is computed based on a hash of non-linker inputs, and it is where all1358 // is computed based on a hash of non-linker inputs, and it is where all
...@@ -1641,13 +1634,13 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1641,13 +1634,13 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1641 .framework_dirs = options.framework_dirs,1634 .framework_dirs = options.framework_dirs,
1642 .llvm_opt_bisect_limit = options.llvm_opt_bisect_limit,1635 .llvm_opt_bisect_limit = options.llvm_opt_bisect_limit,
1643 .skip_linker_dependencies = options.skip_linker_dependencies,1636 .skip_linker_dependencies = options.skip_linker_dependencies,
1637 .no_builtin = options.no_builtin,
1644 };1638 };
16451639
1646 if (bin_file_emit) |emit| {1640 if (bin_file_emit) |emit| {
1647 comp.bin_file = try link.File.open(arena, .{1641 comp.bin_file = try link.File.open(arena, .{
1648 .comp = comp,1642 .comp = comp,
1649 .emit = emit,1643 .emit = emit,
1650 .optimization = linker_optimization,
1651 .linker_script = options.linker_script,1644 .linker_script = options.linker_script,
1652 .z_nodelete = options.linker_z_nodelete,1645 .z_nodelete = options.linker_z_nodelete,
1653 .z_notext = options.linker_z_notext,1646 .z_notext = options.linker_z_notext,
...@@ -1666,7 +1659,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1666,7 +1659,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1666 .symbol_wrap_set = options.symbol_wrap_set,1659 .symbol_wrap_set = options.symbol_wrap_set,
1667 .function_sections = options.function_sections,1660 .function_sections = options.function_sections,
1668 .data_sections = options.data_sections,1661 .data_sections = options.data_sections,
1669 .no_builtin = options.no_builtin,
1670 .allow_shlib_undefined = options.linker_allow_shlib_undefined,1662 .allow_shlib_undefined = options.linker_allow_shlib_undefined,
1671 .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,1663 .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,
1672 .compress_debug_sections = options.linker_compress_debug_sections orelse .none,1664 .compress_debug_sections = options.linker_compress_debug_sections orelse .none,
...@@ -1713,7 +1705,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1713,7 +1705,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1713 .force_undefined_symbols = options.force_undefined_symbols,1705 .force_undefined_symbols = options.force_undefined_symbols,
1714 .pdb_source_path = options.pdb_source_path,1706 .pdb_source_path = options.pdb_source_path,
1715 .pdb_out_path = options.pdb_out_path,1707 .pdb_out_path = options.pdb_out_path,
1716 .want_structured_cfg = options.want_structured_cfg,
1717 .entry_addr = null, // CLI does not expose this option (yet?)1708 .entry_addr = null, // CLI does not expose this option (yet?)
1718 });1709 });
1719 }1710 }
...@@ -2076,7 +2067,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void...@@ -2076,7 +2067,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
2076 };2067 };
2077 if (is_hit) {2068 if (is_hit) {
2078 comp.last_update_was_cache_hit = true;2069 comp.last_update_was_cache_hit = true;
2079 log.debug("CacheMode.whole cache hit for {s}", .{comp.bin_file.options.root_name});2070 log.debug("CacheMode.whole cache hit for {s}", .{comp.root_name});
2080 const digest = man.final();2071 const digest = man.final();
20812072
2082 comp.wholeCacheModeSetBinFilePath(&digest);2073 comp.wholeCacheModeSetBinFilePath(&digest);
...@@ -2085,7 +2076,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void...@@ -2085,7 +2076,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
2085 comp.bin_file.lock = man.toOwnedLock();2076 comp.bin_file.lock = man.toOwnedLock();
2086 return;2077 return;
2087 }2078 }
2088 log.debug("CacheMode.whole cache miss for {s}", .{comp.bin_file.options.root_name});2079 log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name});
20892080
2090 // Initialize `bin_file.emit` with a temporary Directory so that compilation can2081 // Initialize `bin_file.emit` with a temporary Directory so that compilation can
2091 // continue on the same path as incremental, using the temporary Directory.2082 // continue on the same path as incremental, using the temporary Directory.
...@@ -2169,7 +2160,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void...@@ -2169,7 +2160,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
2169 // import_table here.2160 // import_table here.
2170 // Likewise, in the case of `zig test`, the test runner is the root source file,2161 // Likewise, in the case of `zig test`, the test runner is the root source file,
2171 // and so there is nothing to import the main file.2162 // and so there is nothing to import the main file.
2172 if (comp.bin_file.options.is_test) {2163 if (comp.config.is_test) {
2173 _ = try module.importPkg(module.main_mod);2164 _ = try module.importPkg(module.main_mod);
2174 }2165 }
21752166
...@@ -2194,7 +2185,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void...@@ -2194,7 +2185,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
2194 }2185 }
21952186
2196 try comp.work_queue.writeItem(.{ .analyze_mod = std_mod });2187 try comp.work_queue.writeItem(.{ .analyze_mod = std_mod });
2197 if (comp.bin_file.options.is_test) {2188 if (comp.config.is_test) {
2198 try comp.work_queue.writeItem(.{ .analyze_mod = module.main_mod });2189 try comp.work_queue.writeItem(.{ .analyze_mod = module.main_mod });
2199 }2190 }
22002191
...@@ -2208,20 +2199,20 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void...@@ -2208,20 +2199,20 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
2208 if (comp.module) |module| {2199 if (comp.module) |module| {
2209 if (builtin.mode == .Debug and comp.verbose_intern_pool) {2200 if (builtin.mode == .Debug and comp.verbose_intern_pool) {
2210 std.debug.print("intern pool stats for '{s}':\n", .{2201 std.debug.print("intern pool stats for '{s}':\n", .{
2211 comp.bin_file.options.root_name,2202 comp.root_name,
2212 });2203 });
2213 module.intern_pool.dump();2204 module.intern_pool.dump();
2214 }2205 }
22152206
2216 if (builtin.mode == .Debug and comp.verbose_generic_instances) {2207 if (builtin.mode == .Debug and comp.verbose_generic_instances) {
2217 std.debug.print("generic instances for '{s}:0x{x}':\n", .{2208 std.debug.print("generic instances for '{s}:0x{x}':\n", .{
2218 comp.bin_file.options.root_name,2209 comp.root_name,
2219 @as(usize, @intFromPtr(module)),2210 @as(usize, @intFromPtr(module)),
2220 });2211 });
2221 module.intern_pool.dumpGenericInstances(comp.gpa);2212 module.intern_pool.dumpGenericInstances(comp.gpa);
2222 }2213 }
22232214
2224 if (comp.bin_file.options.is_test and comp.totalErrorCount() == 0) {2215 if (comp.config.is_test and comp.totalErrorCount() == 0) {
2225 // The `test_functions` decl has been intentionally postponed until now,2216 // The `test_functions` decl has been intentionally postponed until now,
2226 // at which point we must populate it with the list of test functions that2217 // at which point we must populate it with the list of test functions that
2227 // have been discovered and not filtered out.2218 // have been discovered and not filtered out.
...@@ -2336,7 +2327,7 @@ fn maybeGenerateAutodocs(comp: *Compilation, prog_node: *std.Progress.Node) !voi...@@ -2336,7 +2327,7 @@ fn maybeGenerateAutodocs(comp: *Compilation, prog_node: *std.Progress.Node) !voi
2336 // file copies at the end of generate() can also be extracted to2327 // file copies at the end of generate() can also be extracted to
2337 // separate jobs2328 // separate jobs
2338 if (!build_options.only_c and !build_options.only_core_functionality) {2329 if (!build_options.only_c and !build_options.only_core_functionality) {
2339 if (comp.bin_file.options.docs_emit) |emit| {2330 if (comp.docs_emit) |emit| {
2340 var dir = try emit.directory.handle.makeOpenPath(emit.sub_path, .{});2331 var dir = try emit.directory.handle.makeOpenPath(emit.sub_path, .{});
2341 defer dir.close();2332 defer dir.close();
23422333
...@@ -2426,24 +2417,16 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes...@@ -2426,24 +2417,16 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
2426 try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.main_mod, .{ .files = man });2417 try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.main_mod, .{ .files = man });
24272418
2428 // Synchronize with other matching comments: ZigOnlyHashStuff2419 // Synchronize with other matching comments: ZigOnlyHashStuff
2429 man.hash.add(comp.config.use_llvm);2420 man.hash.add(comp.config.test_evented_io);
2430 man.hash.add(comp.config.use_lib_llvm);
2431 man.hash.add(comp.bin_file.options.dll_export_fns);
2432 man.hash.add(comp.bin_file.options.is_test);
2433 man.hash.add(comp.test_evented_io);
2434 man.hash.addOptionalBytes(comp.test_filter);2421 man.hash.addOptionalBytes(comp.test_filter);
2435 man.hash.addOptionalBytes(comp.test_name_prefix);2422 man.hash.addOptionalBytes(comp.test_name_prefix);
2436 man.hash.add(comp.skip_linker_dependencies);2423 man.hash.add(comp.skip_linker_dependencies);
2437 man.hash.add(comp.formatted_panics);2424 man.hash.add(comp.formatted_panics);
2438 man.hash.add(mod.emit_h != null);2425 man.hash.add(mod.emit_h != null);
2439 man.hash.add(mod.error_limit);2426 man.hash.add(mod.error_limit);
2440 man.hash.add(comp.bin_file.options.want_structured_cfg);
2441 }2427 }
24422428
2443 try man.addOptionalFile(comp.bin_file.options.linker_script);2429 for (comp.objects) |obj| {
2444 try man.addOptionalFile(comp.bin_file.options.version_script);
2445
2446 for (comp.bin_file.options.objects) |obj| {
2447 _ = try man.addFile(obj.path, null);2430 _ = try man.addFile(obj.path, null);
2448 man.hash.add(obj.must_link);2431 man.hash.add(obj.must_link);
2449 man.hash.add(obj.loption);2432 man.hash.add(obj.loption);
...@@ -2469,39 +2452,19 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes...@@ -2469,39 +2452,19 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
2469 }2452 }
2470 }2453 }
24712454
2455 man.hash.addOptionalBytes(comp.sysroot);
2456 man.hash.addOptional(comp.version);
2472 man.hash.addListOfBytes(comp.rc_include_dir_list);2457 man.hash.addListOfBytes(comp.rc_include_dir_list);
24732458
2474 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_asm);2459 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_asm);
2475 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_ir);2460 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_ir);
2476 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_bc);2461 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_bc);
24772462
2478 man.hash.add(comp.bin_file.stack_size);
2479 man.hash.add(comp.bin_file.options.gc_sections);
2480 man.hash.add(comp.bin_file.options.eh_frame_hdr);
2481 man.hash.add(comp.bin_file.options.emit_relocs);
2482 man.hash.add(comp.bin_file.options.rdynamic);
2483 man.hash.addListOfBytes(comp.bin_file.options.lib_dirs);
2484 man.hash.addListOfBytes(comp.bin_file.options.rpath_list);
2485 man.hash.addListOfBytes(comp.bin_file.options.symbol_wrap_set.keys());
2486 man.hash.add(comp.bin_file.options.each_lib_rpath);
2487 man.hash.add(comp.bin_file.build_id);
2488 man.hash.add(comp.skip_linker_dependencies);2463 man.hash.add(comp.skip_linker_dependencies);
2489 man.hash.add(comp.bin_file.options.z_nodelete);
2490 man.hash.add(comp.bin_file.options.z_notext);
2491 man.hash.add(comp.bin_file.options.z_defs);
2492 man.hash.add(comp.bin_file.options.z_origin);
2493 man.hash.add(comp.bin_file.options.z_nocopyreloc);
2494 man.hash.add(comp.bin_file.options.z_now);
2495 man.hash.add(comp.bin_file.options.z_relro);
2496 man.hash.add(comp.bin_file.options.z_common_page_size orelse 0);
2497 man.hash.add(comp.bin_file.options.z_max_page_size orelse 0);
2498 man.hash.add(comp.bin_file.options.hash_style);
2499 man.hash.add(comp.bin_file.options.compress_debug_sections);
2500 man.hash.add(comp.include_compiler_rt);2464 man.hash.add(comp.include_compiler_rt);
2501 man.hash.add(comp.bin_file.options.sort_section);
2502 if (comp.config.link_libc) {2465 if (comp.config.link_libc) {
2503 man.hash.add(comp.bin_file.options.libc_installation != null);2466 man.hash.add(comp.libc_installation != null);
2504 if (comp.bin_file.options.libc_installation) |libc_installation| {2467 if (comp.libc_installation) |libc_installation| {
2505 man.hash.addOptionalBytes(libc_installation.crt_dir);2468 man.hash.addOptionalBytes(libc_installation.crt_dir);
2506 if (target.abi == .msvc) {2469 if (target.abi == .msvc) {
2507 man.hash.addOptionalBytes(libc_installation.msvc_lib_dir);2470 man.hash.addOptionalBytes(libc_installation.msvc_lib_dir);
...@@ -2510,55 +2473,93 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes...@@ -2510,55 +2473,93 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
2510 }2473 }
2511 man.hash.addOptionalBytes(target.dynamic_linker.get());2474 man.hash.addOptionalBytes(target.dynamic_linker.get());
2512 }2475 }
2513 man.hash.addOptionalBytes(comp.bin_file.options.soname);
2514 man.hash.add(comp.bin_file.options.version);
2515 try link.hashAddSystemLibs(man, comp.system_libs);2476 try link.hashAddSystemLibs(man, comp.system_libs);
2516 man.hash.addListOfBytes(comp.bin_file.options.force_undefined_symbols.keys());2477
2517 man.hash.add(comp.bin_file.allow_shlib_undefined);2478 man.hash.add(comp.config.use_llvm);
2518 man.hash.add(comp.bin_file.options.bind_global_refs_locally);2479 man.hash.add(comp.config.use_lib_llvm);
2519 man.hash.add(comp.bin_file.options.tsan);2480 man.hash.add(comp.config.is_test);
2520 man.hash.addOptionalBytes(comp.bin_file.options.sysroot);2481 man.hash.add(comp.config.import_memory);
2521 man.hash.add(comp.bin_file.options.linker_optimization);2482 man.hash.add(comp.config.export_memory);
25222483 man.hash.add(comp.config.shared_memory);
2523 switch (comp.bin_file.tag) {2484
2524 .elf => {2485 if (comp.bin_file) |lf| {
2525 const elf = comp.bin_file.cast(link.File.Elf).?;2486 man.hash.add(lf.stack_size);
2526 man.hash.add(elf.image_base);2487 man.hash.add(lf.gc_sections);
2527 },2488 man.hash.addListOfBytes(lf.rpath_list);
2528 .wasm => {2489 man.hash.add(lf.build_id);
2529 const wasm = comp.bin_file.cast(link.File.Wasm).?;2490 man.hash.addListOfBytes(lf.force_undefined_symbols.keys());
2530 man.hash.add(comp.config.import_memory);2491 man.hash.add(lf.allow_shlib_undefined);
2531 man.hash.add(comp.config.export_memory);2492
2532 man.hash.add(comp.config.shared_memory);2493 switch (lf.tag) {
2533 man.hash.add(wasm.initial_memory);2494 .elf => {
2534 man.hash.add(wasm.max_memory);2495 const elf = lf.cast(link.File.Elf).?;
2535 man.hash.add(wasm.global_base);2496 man.hash.add(elf.rdynamic);
2536 },2497 man.hash.add(elf.eh_frame_hdr);
2537 .macho => {2498 man.hash.add(elf.image_base);
2538 const macho = comp.bin_file.cast(link.File.MachO).?;2499 man.hash.add(elf.emit_relocs);
2539 man.hash.addListOfBytes(comp.framework_dirs);2500 man.hash.add(elf.z_nodelete);
2540 try link.hashAddFrameworks(man, macho.frameworks);2501 man.hash.add(elf.z_notext);
2541 try man.addOptionalFile(macho.entitlements);2502 man.hash.add(elf.z_defs);
2542 man.hash.add(macho.pagezero_size);2503 man.hash.add(elf.z_origin);
2543 man.hash.add(macho.headerpad_size);2504 man.hash.add(elf.z_nocopyreloc);
2544 man.hash.add(macho.headerpad_max_install_names);2505 man.hash.add(elf.z_now);
2545 man.hash.add(macho.dead_strip_dylibs);2506 man.hash.add(elf.z_relro);
2546 },2507 man.hash.add(elf.z_common_page_size orelse 0);
2547 .coff => {2508 man.hash.add(elf.z_max_page_size orelse 0);
2548 const coff = comp.bin_file.cast(link.File.Coff).?;2509 man.hash.addListOfBytes(elf.lib_dirs);
2549 man.hash.add(coff.image_base);2510 man.hash.add(elf.hash_style);
2550 man.hash.add(coff.subsystem);2511 man.hash.add(elf.compress_debug_sections);
2551 man.hash.add(coff.tsaware);2512 man.hash.addListOfBytes(elf.symbol_wrap_set.keys());
2552 man.hash.add(coff.nxcompat);2513 man.hash.add(elf.each_lib_rpath);
2553 man.hash.add(coff.dynamicbase);2514 man.hash.addOptional(elf.sort_section);
2554 man.hash.add(coff.major_subsystem_version);2515 man.hash.addOptionalBytes(elf.soname);
2555 man.hash.add(coff.minor_subsystem_version);2516 man.hash.add(elf.bind_global_refs_locally);
2556 },2517 try man.addOptionalFile(elf.linker_script);
2518 try man.addOptionalFile(elf.version_script);
2519 },
2520 .wasm => {
2521 const wasm = lf.cast(link.File.Wasm).?;
2522 man.hash.add(wasm.rdynamic);
2523 man.hash.add(wasm.initial_memory);
2524 man.hash.add(wasm.max_memory);
2525 man.hash.add(wasm.global_base);
2526 },
2527 .macho => {
2528 const macho = lf.cast(link.File.MachO).?;
2529 man.hash.addListOfBytes(comp.framework_dirs);
2530 try link.File.MachO.hashAddFrameworks(man, macho.frameworks);
2531 try man.addOptionalFile(macho.entitlements);
2532 man.hash.add(macho.pagezero_vmsize);
2533 man.hash.add(macho.headerpad_size);
2534 man.hash.add(macho.headerpad_max_install_names);
2535 man.hash.add(macho.dead_strip_dylibs);
2536 },
2537 .coff => {
2538 const coff = lf.cast(link.File.Coff).?;
2539 man.hash.add(coff.dll_export_fns);
2540 man.hash.add(coff.image_base);
2541 man.hash.addOptional(coff.subsystem);
2542 man.hash.add(coff.tsaware);
2543 man.hash.add(coff.nxcompat);
2544 man.hash.add(coff.dynamicbase);
2545 man.hash.add(coff.major_subsystem_version);
2546 man.hash.add(coff.minor_subsystem_version);
2547 man.hash.addListOfBytes(coff.lib_dirs);
2548 },
2549 .spirv => {
2550 const spirv = lf.cast(link.File.SpirV).?;
2551 _ = spirv;
2552 // TODO
2553 },
2554 .c => {}, // TODO
2555 .plan9 => {}, // TODO
2556 .nvptx => {}, // TODO
2557 }
2557 }2558 }
2558}2559}
25592560
2560fn emitOthers(comp: *Compilation) void {2561fn emitOthers(comp: *Compilation) void {
2561 if (comp.bin_file.options.output_mode != .Obj or comp.module != null or2562 if (comp.config.output_mode != .Obj or comp.module != null or
2562 comp.c_object_table.count() == 0)2563 comp.c_object_table.count() == 0)
2563 {2564 {
2564 return;2565 return;
...@@ -2724,10 +2725,10 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2724,10 +2725,10 @@ pub fn saveState(comp: *Compilation) !void {
2724 var bufs_list: [6]std.os.iovec_const = undefined;2725 var bufs_list: [6]std.os.iovec_const = undefined;
2725 var bufs_len: usize = 0;2726 var bufs_len: usize = 0;
27262727
2727 const emit = comp.bin_file.options.emit orelse return;2728 const lf = comp.bin_file orelse return;
27282729
2729 if (comp.module) |mod| {2730 if (comp.module) |zcu| {
2730 const ip = &mod.intern_pool;2731 const ip = &zcu.intern_pool;
2731 const header: Header = .{2732 const header: Header = .{
2732 .intern_pool = .{2733 .intern_pool = .{
2733 .items_len = @intCast(ip.items.len),2734 .items_len = @intCast(ip.items.len),
...@@ -2751,7 +2752,7 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2751,7 +2752,7 @@ pub fn saveState(comp: *Compilation) !void {
2751 }2752 }
2752 var basename_buf: [255]u8 = undefined;2753 var basename_buf: [255]u8 = undefined;
2753 const basename = std.fmt.bufPrint(&basename_buf, "{s}.zcs", .{2754 const basename = std.fmt.bufPrint(&basename_buf, "{s}.zcs", .{
2754 comp.bin_file.options.root_name,2755 comp.root_name,
2755 }) catch o: {2756 }) catch o: {
2756 basename_buf[basename_buf.len - 4 ..].* = ".zcs".*;2757 basename_buf[basename_buf.len - 4 ..].* = ".zcs".*;
2757 break :o &basename_buf;2758 break :o &basename_buf;
...@@ -2759,7 +2760,7 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2759,7 +2760,7 @@ pub fn saveState(comp: *Compilation) !void {
27592760
2760 // Using an atomic file prevents a crash or power failure from corrupting2761 // Using an atomic file prevents a crash or power failure from corrupting
2761 // the previous incremental compilation state.2762 // the previous incremental compilation state.
2762 var af = try emit.directory.handle.atomicFile(basename, .{});2763 var af = try lf.emit.directory.handle.atomicFile(basename, .{});
2763 defer af.deinit();2764 defer af.deinit();
2764 try af.file.pwritevAll(bufs_list[0..bufs_len], 0);2765 try af.file.pwritevAll(bufs_list[0..bufs_len], 0);
2765 try af.finish();2766 try af.finish();
...@@ -3507,7 +3508,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v...@@ -3507,7 +3508,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
3507 error.AnalysisFail => return,3508 error.AnalysisFail => return,
3508 };3509 };
3509 const decl = module.declPtr(decl_index);3510 const decl = module.declPtr(decl_index);
3510 if (decl.kind == .@"test" and comp.bin_file.options.is_test) {3511 if (decl.kind == .@"test" and comp.config.is_test) {
3511 // Tests are always emitted in test binaries. The decl_refs are created by3512 // Tests are always emitted in test binaries. The decl_refs are created by
3512 // Module.populateTestFunctions, but this will not queue body analysis, so do3513 // Module.populateTestFunctions, but this will not queue body analysis, so do
3513 // that now.3514 // that now.
...@@ -3850,7 +3851,7 @@ pub fn obtainCObjectCacheManifest(comp: *const Compilation) Cache.Manifest {...@@ -3850,7 +3851,7 @@ pub fn obtainCObjectCacheManifest(comp: *const Compilation) Cache.Manifest {
3850 // based on the zig library directory alone. The zig lib directory file3851 // based on the zig library directory alone. The zig lib directory file
3851 // path is purposefully either in the cache or not in the cache. The3852 // path is purposefully either in the cache or not in the cache. The
3852 // decision should not be overridden here.3853 // decision should not be overridden here.
3853 if (comp.bin_file.options.libc_installation != null) {3854 if (comp.libc_installation != null) {
3854 man.hash.addListOfBytes(comp.libc_include_dir_list);3855 man.hash.addListOfBytes(comp.libc_include_dir_list);
3855 }3856 }
38563857
...@@ -4248,9 +4249,9 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P...@@ -4248,9 +4249,9 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
4248 // file and building an object we need to link them together, but with just one it should go4249 // file and building an object we need to link them together, but with just one it should go
4249 // directly to the output file.4250 // directly to the output file.
4250 const direct_o = comp.c_source_files.len == 1 and comp.module == null and4251 const direct_o = comp.c_source_files.len == 1 and comp.module == null and
4251 comp.bin_file.options.output_mode == .Obj and comp.bin_file.options.objects.len == 0;4252 comp.config.output_mode == .Obj and comp.objects.len == 0;
4252 const o_basename_noext = if (direct_o)4253 const o_basename_noext = if (direct_o)
4253 comp.bin_file.options.root_name4254 comp.root_name
4254 else4255 else
4255 c_source_basename[0 .. c_source_basename.len - std.fs.path.extension(c_source_basename).len];4256 c_source_basename[0 .. c_source_basename.len - std.fs.path.extension(c_source_basename).len];
42564257
...@@ -4304,8 +4305,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P...@@ -4304,8 +4305,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
4304 try argv.appendSlice(c_object.src.extra_flags);4305 try argv.appendSlice(c_object.src.extra_flags);
4305 try argv.appendSlice(c_object.src.cache_exempt_flags);4306 try argv.appendSlice(c_object.src.cache_exempt_flags);
43064307
4307 const out_obj_path = if (comp.bin_file.options.emit) |emit|4308 const out_obj_path = if (comp.bin_file) |lf|
4308 try emit.directory.join(arena, &.{emit.sub_path})4309 try lf.emit.directory.join(arena, &.{lf.emit.sub_path})
4309 else4310 else
4310 "/dev/null";4311 "/dev/null";
43114312
...@@ -4883,8 +4884,9 @@ pub fn addCCArgs(...@@ -4883,8 +4884,9 @@ pub fn addCCArgs(
4883 argv: *std.ArrayList([]const u8),4884 argv: *std.ArrayList([]const u8),
4884 ext: FileExt,4885 ext: FileExt,
4885 out_dep_path: ?[]const u8,4886 out_dep_path: ?[]const u8,
4887 mod: *Package.Module,
4886) !void {4888) !void {
4887 const target = comp.getTarget();4889 const target = mod.resolved_target.result;
48884890
4889 // As of Clang 16.x, it will by default read extra flags from /etc/clang.4891 // As of Clang 16.x, it will by default read extra flags from /etc/clang.
4890 // I'm sure the person who implemented this means well, but they have a lot4892 // I'm sure the person who implemented this means well, but they have a lot
...@@ -4905,15 +4907,15 @@ pub fn addCCArgs(...@@ -4905,15 +4907,15 @@ pub fn addCCArgs(
4905 try argv.append("-fno-caret-diagnostics");4907 try argv.append("-fno-caret-diagnostics");
4906 }4908 }
49074909
4908 if (comp.bin_file.options.function_sections) {4910 if (comp.bin_file.function_sections) {
4909 try argv.append("-ffunction-sections");4911 try argv.append("-ffunction-sections");
4910 }4912 }
49114913
4912 if (comp.bin_file.options.data_sections) {4914 if (comp.bin_file.data_sections) {
4913 try argv.append("-fdata-sections");4915 try argv.append("-fdata-sections");
4914 }4916 }
49154917
4916 if (comp.bin_file.options.no_builtin) {4918 if (comp.no_builtin) {
4917 try argv.append("-fno-builtin");4919 try argv.append("-fno-builtin");
4918 }4920 }
49194921
...@@ -4953,7 +4955,7 @@ pub fn addCCArgs(...@@ -4953,7 +4955,7 @@ pub fn addCCArgs(
4953 }));4955 }));
4954 }4956 }
49554957
4956 if (comp.bin_file.options.link_libunwind) {4958 if (comp.config.link_libunwind) {
4957 const libunwind_include_path = try std.fs.path.join(arena, &[_][]const u8{4959 const libunwind_include_path = try std.fs.path.join(arena, &[_][]const u8{
4958 comp.zig_lib_directory.path.?, "libunwind", "include",4960 comp.zig_lib_directory.path.?, "libunwind", "include",
4959 });4961 });
...@@ -4987,7 +4989,7 @@ pub fn addCCArgs(...@@ -4987,7 +4989,7 @@ pub fn addCCArgs(
4987 "-nostdinc",4989 "-nostdinc",
4988 "-fno-spell-checking",4990 "-fno-spell-checking",
4989 });4991 });
4990 if (comp.bin_file.options.lto) {4992 if (comp.config.lto) {
4991 try argv.append("-flto");4993 try argv.append("-flto");
4992 }4994 }
49934995
...@@ -5042,9 +5044,8 @@ pub fn addCCArgs(...@@ -5042,9 +5044,8 @@ pub fn addCCArgs(
5042 argv.appendAssumeCapacity(arg);5044 argv.appendAssumeCapacity(arg);
5043 }5045 }
5044 }5046 }
5045 const code_model = comp.bin_file.options.machine_code_model;5047 if (mod.code_model != .default) {
5046 if (code_model != .default) {5048 try argv.append(try std.fmt.allocPrint(arena, "-mcmodel={s}", .{@tagName(mod.code_model)}));
5047 try argv.append(try std.fmt.allocPrint(arena, "-mcmodel={s}", .{@tagName(code_model)}));
5048 }5049 }
50495050
5050 switch (target.os.tag) {5051 switch (target.os.tag) {
...@@ -5093,7 +5094,7 @@ pub fn addCCArgs(...@@ -5093,7 +5094,7 @@ pub fn addCCArgs(
5093 try argv.append("-mthumb");5094 try argv.append("-mthumb");
5094 }5095 }
50955096
5096 if (comp.sanitize_c and !comp.bin_file.options.tsan) {5097 if (mod.sanitize_c and !mod.sanitize_thread) {
5097 try argv.append("-fsanitize=undefined");5098 try argv.append("-fsanitize=undefined");
5098 try argv.append("-fsanitize-trap=undefined");5099 try argv.append("-fsanitize-trap=undefined");
5099 // It is very common, and well-defined, for a pointer on one side of a C ABI5100 // It is very common, and well-defined, for a pointer on one side of a C ABI
...@@ -5104,27 +5105,27 @@ pub fn addCCArgs(...@@ -5104,27 +5105,27 @@ pub fn addCCArgs(
5104 // Without this flag, Clang would invoke UBSAN when such an extern5105 // Without this flag, Clang would invoke UBSAN when such an extern
5105 // function was called.5106 // function was called.
5106 try argv.append("-fno-sanitize=function");5107 try argv.append("-fno-sanitize=function");
5107 } else if (comp.sanitize_c and comp.bin_file.options.tsan) {5108 } else if (mod.sanitize_c and mod.sanitize_thread) {
5108 try argv.append("-fsanitize=undefined,thread");5109 try argv.append("-fsanitize=undefined,thread");
5109 try argv.append("-fsanitize-trap=undefined");5110 try argv.append("-fsanitize-trap=undefined");
5110 try argv.append("-fno-sanitize=function");5111 try argv.append("-fno-sanitize=function");
5111 } else if (!comp.sanitize_c and comp.bin_file.options.tsan) {5112 } else if (!mod.sanitize_c and mod.sanitize_thread) {
5112 try argv.append("-fsanitize=thread");5113 try argv.append("-fsanitize=thread");
5113 }5114 }
51145115
5115 if (comp.bin_file.options.red_zone) {5116 if (mod.red_zone) {
5116 try argv.append("-mred-zone");5117 try argv.append("-mred-zone");
5117 } else if (target_util.hasRedZone(target)) {5118 } else if (target_util.hasRedZone(target)) {
5118 try argv.append("-mno-red-zone");5119 try argv.append("-mno-red-zone");
5119 }5120 }
51205121
5121 if (comp.bin_file.options.omit_frame_pointer) {5122 if (mod.omit_frame_pointer) {
5122 try argv.append("-fomit-frame-pointer");5123 try argv.append("-fomit-frame-pointer");
5123 } else {5124 } else {
5124 try argv.append("-fno-omit-frame-pointer");5125 try argv.append("-fno-omit-frame-pointer");
5125 }5126 }
51265127
5127 const ssp_buf_size = comp.bin_file.options.stack_protector;5128 const ssp_buf_size = mod.stack_protector;
5128 if (ssp_buf_size != 0) {5129 if (ssp_buf_size != 0) {
5129 try argv.appendSlice(&[_][]const u8{5130 try argv.appendSlice(&[_][]const u8{
5130 "-fstack-protector-strong",5131 "-fstack-protector-strong",
...@@ -5135,7 +5136,7 @@ pub fn addCCArgs(...@@ -5135,7 +5136,7 @@ pub fn addCCArgs(
5135 try argv.append("-fno-stack-protector");5136 try argv.append("-fno-stack-protector");
5136 }5137 }
51375138
5138 switch (comp.bin_file.options.optimize_mode) {5139 switch (mod.optimize_mode) {
5139 .Debug => {5140 .Debug => {
5140 // windows c runtime requires -D_DEBUG if using debug libraries5141 // windows c runtime requires -D_DEBUG if using debug libraries
5141 try argv.append("-D_DEBUG");5142 try argv.append("-D_DEBUG");
...@@ -5165,7 +5166,7 @@ pub fn addCCArgs(...@@ -5165,7 +5166,7 @@ pub fn addCCArgs(
5165 },5166 },
5166 }5167 }
51675168
5168 if (target_util.supports_fpic(target) and comp.bin_file.options.pic) {5169 if (target_util.supports_fpic(target) and mod.pic) {
5169 try argv.append("-fPIC");5170 try argv.append("-fPIC");
5170 }5171 }
51715172
...@@ -5940,7 +5941,7 @@ pub fn get_libc_crt_file(comp: *Compilation, arena: Allocator, basename: []const...@@ -5940,7 +5941,7 @@ pub fn get_libc_crt_file(comp: *Compilation, arena: Allocator, basename: []const
5940 {5941 {
5941 return comp.crt_files.get(basename).?.full_object_path;5942 return comp.crt_files.get(basename).?.full_object_path;
5942 }5943 }
5943 const lci = comp.bin_file.options.libc_installation orelse return error.LibCInstallationNotAvailable;5944 const lci = comp.libc_installation orelse return error.LibCInstallationNotAvailable;
5944 const crt_dir_path = lci.crt_dir orelse return error.LibCInstallationMissingCRTDir;5945 const crt_dir_path = lci.crt_dir orelse return error.LibCInstallationMissingCRTDir;
5945 const full_path = try std.fs.path.join(arena, &[_][]const u8{ crt_dir_path, basename });5946 const full_path = try std.fs.path.join(arena, &[_][]const u8{ crt_dir_path, basename });
5946 return full_path;5947 return full_path;
...@@ -6112,7 +6113,7 @@ fn canBuildZigLibC(target: std.Target, use_llvm: bool) bool {...@@ -6112,7 +6113,7 @@ fn canBuildZigLibC(target: std.Target, use_llvm: bool) bool {
61126113
6113pub fn getZigBackend(comp: Compilation) std.builtin.CompilerBackend {6114pub fn getZigBackend(comp: Compilation) std.builtin.CompilerBackend {
6114 const target = comp.root_mod.resolved_target.result;6115 const target = comp.root_mod.resolved_target.result;
6115 return target_util.zigBackend(target, comp.bin_file.options.use_llvm);6116 return target_util.zigBackend(target, comp.config.use_llvm);
6116}6117}
61176118
6118pub fn updateSubCompilation(6119pub fn updateSubCompilation(
...@@ -6165,6 +6166,9 @@ fn buildOutputFromZig(...@@ -6165,6 +6166,9 @@ fn buildOutputFromZig(
61656166
6166 assert(output_mode != .Exe);6167 assert(output_mode != .Exe);
61676168
6169 const lf = comp.bin_file.?;
6170 const unwind_tables = if (lf.cast(link.File.Elf)) |elf| elf.eh_frame_hdr else false;
6171
6168 const config = try Config.resolve(.{6172 const config = try Config.resolve(.{
6169 .output_mode = output_mode,6173 .output_mode = output_mode,
6170 .resolved_target = comp.root_mod.resolved_target,6174 .resolved_target = comp.root_mod.resolved_target,
...@@ -6173,6 +6177,7 @@ fn buildOutputFromZig(...@@ -6173,6 +6177,7 @@ fn buildOutputFromZig(
6173 .emit_bin = true,6177 .emit_bin = true,
6174 .root_optimize_mode = comp.compilerRtOptMode(),6178 .root_optimize_mode = comp.compilerRtOptMode(),
6175 .link_libc = comp.config.link_libc,6179 .link_libc = comp.config.link_libc,
6180 .any_unwind_tables = unwind_tables,
6176 });6181 });
61776182
6178 const root_mod = Package.Module.create(.{6183 const root_mod = Package.Module.create(.{
...@@ -6187,9 +6192,10 @@ fn buildOutputFromZig(...@@ -6187,9 +6192,10 @@ fn buildOutputFromZig(
6187 .stack_protector = 0,6192 .stack_protector = 0,
6188 .red_zone = comp.root_mod.red_zone,6193 .red_zone = comp.root_mod.red_zone,
6189 .omit_frame_pointer = comp.root_mod.omit_frame_pointer,6194 .omit_frame_pointer = comp.root_mod.omit_frame_pointer,
6190 .unwind_tables = comp.bin_file.options.eh_frame_hdr,6195 .unwind_tables = unwind_tables,
6191 .pic = comp.root_mod.pic,6196 .pic = comp.root_mod.pic,
6192 .optimize_mode = comp.compilerRtOptMode(),6197 .optimize_mode = comp.compilerRtOptMode(),
6198 .structured_cfg = comp.root_mod.structured_cfg,
6193 },6199 },
6194 .global = config,6200 .global = config,
6195 .cc_argv = &.{},6201 .cc_argv = &.{},
...@@ -6210,21 +6216,21 @@ fn buildOutputFromZig(...@@ -6210,21 +6216,21 @@ fn buildOutputFromZig(
6210 .global_cache_directory = comp.global_cache_directory,6216 .global_cache_directory = comp.global_cache_directory,
6211 .local_cache_directory = comp.global_cache_directory,6217 .local_cache_directory = comp.global_cache_directory,
6212 .zig_lib_directory = comp.zig_lib_directory,6218 .zig_lib_directory = comp.zig_lib_directory,
6219 .self_exe_path = comp.self_exe_path,
6213 .resolved = config,6220 .resolved = config,
6214 .root_mod = root_mod,6221 .root_mod = root_mod,
6215 .cache_mode = .whole,6222 .cache_mode = .whole,
6216 .root_name = root_name,6223 .root_name = root_name,
6217 .thread_pool = comp.thread_pool,6224 .thread_pool = comp.thread_pool,
6218 .libc_installation = comp.bin_file.options.libc_installation,6225 .libc_installation = comp.libc_installation,
6219 .emit_bin = emit_bin,6226 .emit_bin = emit_bin,
6220 .link_mode = .Static,6227 .link_mode = .Static,
6221 .function_sections = true,6228 .function_sections = true,
6222 .data_sections = true,6229 .data_sections = true,
6223 .no_builtin = true,6230 .no_builtin = true,
6224 .emit_h = null,6231 .emit_h = null,
6225 .self_exe_path = comp.self_exe_path,
6226 .verbose_cc = comp.verbose_cc,6232 .verbose_cc = comp.verbose_cc,
6227 .verbose_link = comp.bin_file.options.verbose_link,6233 .verbose_link = comp.verbose_link,
6228 .verbose_air = comp.verbose_air,6234 .verbose_air = comp.verbose_air,
6229 .verbose_intern_pool = comp.verbose_intern_pool,6235 .verbose_intern_pool = comp.verbose_intern_pool,
6230 .verbose_generic_instances = comp.verbose_intern_pool,6236 .verbose_generic_instances = comp.verbose_intern_pool,
...@@ -6234,7 +6240,6 @@ fn buildOutputFromZig(...@@ -6234,7 +6240,6 @@ fn buildOutputFromZig(
6234 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,6240 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
6235 .clang_passthrough_mode = comp.clang_passthrough_mode,6241 .clang_passthrough_mode = comp.clang_passthrough_mode,
6236 .skip_linker_dependencies = true,6242 .skip_linker_dependencies = true,
6237 .want_structured_cfg = comp.bin_file.options.want_structured_cfg,
6238 });6243 });
6239 defer sub_compilation.destroy();6244 defer sub_compilation.destroy();
62406245
...@@ -6242,8 +6247,8 @@ fn buildOutputFromZig(...@@ -6242,8 +6247,8 @@ fn buildOutputFromZig(
62426247
6243 assert(out.* == null);6248 assert(out.* == null);
6244 out.* = Compilation.CRTFile{6249 out.* = Compilation.CRTFile{
6245 .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{6250 .full_object_path = try sub_compilation.bin_file.?.emit.directory.join(comp.gpa, &[_][]const u8{
6246 sub_compilation.bin_file.options.emit.?.sub_path,6251 sub_compilation.bin_file.?.emit.sub_path,
6247 }),6252 }),
6248 .lock = sub_compilation.bin_file.toOwnedLock(),6253 .lock = sub_compilation.bin_file.toOwnedLock(),
6249 };6254 };
...@@ -6260,51 +6265,70 @@ pub fn build_crt_file(...@@ -6260,51 +6265,70 @@ pub fn build_crt_file(
6260 const tracy_trace = trace(@src());6265 const tracy_trace = trace(@src());
6261 defer tracy_trace.end();6266 defer tracy_trace.end();
62626267
6263 const target = comp.getTarget();6268 const gpa = comp.gpa;
6264 const basename = try std.zig.binNameAlloc(comp.gpa, .{6269 const basename = try std.zig.binNameAlloc(gpa, .{
6265 .root_name = root_name,6270 .root_name = root_name,
6266 .target = target,6271 .target = comp.root_mod.resolved_target.result,
6267 .output_mode = output_mode,6272 .output_mode = output_mode,
6268 });6273 });
6269 errdefer comp.gpa.free(basename);6274 errdefer gpa.free(basename);
62706275
6271 const sub_compilation = try Compilation.create(comp.gpa, .{6276 const config = try Config.resolve(.{
6277 .output_mode = output_mode,
6278 .resolved_target = comp.root_mod.resolved_target,
6279 .is_test = false,
6280 .have_zcu = false,
6281 .emit_bin = true,
6282 .root_optimize_mode = comp.compilerRtOptMode(),
6283 .link_libc = false,
6284 .lto = switch (output_mode) {
6285 .Lib => comp.config.lto,
6286 .Obj, .Exe => false,
6287 },
6288 });
6289 const root_mod = Package.Module.create(.{
6290 .paths = .{
6291 .root = .{ .root_dir = comp.zig_lib_directory },
6292 .root_src_path = "",
6293 },
6294 .fully_qualified_name = "root",
6295 .inherited = .{
6296 .strip = comp.compilerRtStrip(),
6297 .stack_check = false,
6298 .stack_protector = 0,
6299 .sanitize_c = false,
6300 .sanitize_thread = false,
6301 .red_zone = comp.root_mod.red_zone,
6302 .omit_frame_pointer = comp.root_mod.omit_frame_pointer,
6303 .valgrind = false,
6304 .unwind_tables = false,
6305 .pic = comp.root_mod.pic,
6306 .optimize_mode = comp.compilerRtOptMode(),
6307 .structured_cfg = comp.root_mod.structured_cfg,
6308 },
6309 .global = config,
6310 .cc_argv = &.{},
6311 });
6312
6313 const sub_compilation = try Compilation.create(gpa, .{
6272 .local_cache_directory = comp.global_cache_directory,6314 .local_cache_directory = comp.global_cache_directory,
6273 .global_cache_directory = comp.global_cache_directory,6315 .global_cache_directory = comp.global_cache_directory,
6274 .zig_lib_directory = comp.zig_lib_directory,6316 .zig_lib_directory = comp.zig_lib_directory,
6317 .self_exe_path = comp.self_exe_path,
6275 .cache_mode = .whole,6318 .cache_mode = .whole,
6276 .target = target,6319 .resolved = config,
6320 .root_mod = root_mod,
6277 .root_name = root_name,6321 .root_name = root_name,
6278 .main_mod = null,
6279 .output_mode = output_mode,
6280 .thread_pool = comp.thread_pool,6322 .thread_pool = comp.thread_pool,
6281 .libc_installation = comp.bin_file.options.libc_installation,6323 .libc_installation = comp.libc_installation,
6282 .emit_bin = .{6324 .emit_bin = .{
6283 .directory = null, // Put it in the cache directory.6325 .directory = null, // Put it in the cache directory.
6284 .basename = basename,6326 .basename = basename,
6285 },6327 },
6286 .optimize_mode = comp.compilerRtOptMode(),
6287 .want_sanitize_c = false,
6288 .want_stack_check = false,
6289 .want_stack_protector = 0,
6290 .want_red_zone = comp.bin_file.options.red_zone,
6291 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
6292 .want_valgrind = false,
6293 .want_tsan = false,
6294 .want_pic = comp.bin_file.options.pic,
6295 .want_pie = null,
6296 .want_lto = switch (output_mode) {
6297 .Lib => comp.bin_file.options.lto,
6298 .Obj, .Exe => false,
6299 },
6300 .emit_h = null,6328 .emit_h = null,
6301 .strip = comp.compilerRtStrip(),
6302 .is_native_os = comp.bin_file.options.is_native_os,
6303 .is_native_abi = comp.bin_file.options.is_native_abi,
6304 .self_exe_path = comp.self_exe_path,
6305 .c_source_files = c_source_files,6329 .c_source_files = c_source_files,
6306 .verbose_cc = comp.verbose_cc,6330 .verbose_cc = comp.verbose_cc,
6307 .verbose_link = comp.bin_file.options.verbose_link,6331 .verbose_link = comp.verbose_link,
6308 .verbose_air = comp.verbose_air,6332 .verbose_air = comp.verbose_air,
6309 .verbose_intern_pool = comp.verbose_intern_pool,6333 .verbose_intern_pool = comp.verbose_intern_pool,
6310 .verbose_generic_instances = comp.verbose_generic_instances,6334 .verbose_generic_instances = comp.verbose_generic_instances,
...@@ -6314,17 +6338,16 @@ pub fn build_crt_file(...@@ -6314,17 +6338,16 @@ pub fn build_crt_file(
6314 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,6338 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
6315 .clang_passthrough_mode = comp.clang_passthrough_mode,6339 .clang_passthrough_mode = comp.clang_passthrough_mode,
6316 .skip_linker_dependencies = true,6340 .skip_linker_dependencies = true,
6317 .want_structured_cfg = comp.bin_file.options.want_structured_cfg,
6318 });6341 });
6319 defer sub_compilation.destroy();6342 defer sub_compilation.destroy();
63206343
6321 try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);6344 try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);
63226345
6323 try comp.crt_files.ensureUnusedCapacity(comp.gpa, 1);6346 try comp.crt_files.ensureUnusedCapacity(gpa, 1);
63246347
6325 comp.crt_files.putAssumeCapacityNoClobber(basename, .{6348 comp.crt_files.putAssumeCapacityNoClobber(basename, .{
6326 .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{6349 .full_object_path = try sub_compilation.bin_file.?.emit.directory.join(gpa, &[_][]const u8{
6327 sub_compilation.bin_file.options.emit.?.sub_path,6350 sub_compilation.bin_file.?.emit.sub_path,
6328 }),6351 }),
6329 .lock = sub_compilation.bin_file.toOwnedLock(),6352 .lock = sub_compilation.bin_file.toOwnedLock(),
6330 });6353 });
...@@ -6357,10 +6380,11 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void {...@@ -6357,10 +6380,11 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void {
6357/// compiler-rt, libcxx, libc, libunwind, etc.6380/// compiler-rt, libcxx, libc, libunwind, etc.
6358pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode {6381pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode {
6359 if (comp.debug_compiler_runtime_libs) {6382 if (comp.debug_compiler_runtime_libs) {
6360 return comp.bin_file.options.optimize_mode;6383 return comp.root_mod.optimize_mode;
6361 }6384 }
6362 switch (comp.bin_file.options.optimize_mode) {6385 const target = comp.root_mod.resolved_target.result;
6363 .Debug, .ReleaseSafe => return target_util.defaultCompilerRtOptimizeMode(comp.getTarget()),6386 switch (comp.root_mod.optimize_mode) {
6387 .Debug, .ReleaseSafe => return target_util.defaultCompilerRtOptimizeMode(target),
6364 .ReleaseFast => return .ReleaseFast,6388 .ReleaseFast => return .ReleaseFast,
6365 .ReleaseSmall => return .ReleaseSmall,6389 .ReleaseSmall => return .ReleaseSmall,
6366 }6390 }
...@@ -6369,5 +6393,5 @@ pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode {...@@ -6369,5 +6393,5 @@ pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode {
6369/// This decides whether to strip debug info for all zig-provided libraries, including6393/// This decides whether to strip debug info for all zig-provided libraries, including
6370/// compiler-rt, libcxx, libc, libunwind, etc.6394/// compiler-rt, libcxx, libc, libunwind, etc.
6371pub fn compilerRtStrip(comp: Compilation) bool {6395pub fn compilerRtStrip(comp: Compilation) bool {
6372 return comp.bin_file.options.strip;6396 return comp.root_mod.strip;
6373}6397}
src/Package/Module.zig+17
...@@ -30,6 +30,8 @@ sanitize_c: bool,...@@ -30,6 +30,8 @@ sanitize_c: bool,
30sanitize_thread: bool,30sanitize_thread: bool,
31unwind_tables: bool,31unwind_tables: bool,
32cc_argv: []const []const u8,32cc_argv: []const []const u8,
33/// (SPIR-V) whether to generate a structured control flow graph or not
34structured_cfg: bool,
3335
34/// The contents of `@import("builtin")` for this module.36/// The contents of `@import("builtin")` for this module.
35generated_builtin_source: []const u8,37generated_builtin_source: []const u8,
...@@ -82,6 +84,7 @@ pub const CreateOptions = struct {...@@ -82,6 +84,7 @@ pub const CreateOptions = struct {
82 unwind_tables: ?bool = null,84 unwind_tables: ?bool = null,
83 sanitize_c: ?bool = null,85 sanitize_c: ?bool = null,
84 sanitize_thread: ?bool = null,86 sanitize_thread: ?bool = null,
87 structured_cfg: ?bool = null,
85 };88 };
86};89};
8790
...@@ -268,6 +271,17 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {...@@ -268,6 +271,17 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
268 break :sp target_util.default_stack_protector_buffer_size;271 break :sp target_util.default_stack_protector_buffer_size;
269 };272 };
270273
274 const structured_cfg = b: {
275 if (options.inherited.structured_cfg) |x| break :b x;
276 if (options.parent) |p| break :b p.structured_cfg;
277 // We always want a structured control flow in shaders. This option is
278 // only relevant for OpenCL kernels.
279 break :b switch (target.os.tag) {
280 .opencl => false,
281 else => true,
282 };
283 };
284
271 const llvm_cpu_features: ?[*:0]const u8 = b: {285 const llvm_cpu_features: ?[*:0]const u8 = b: {
272 if (resolved_target.llvm_cpu_features) |x| break :b x;286 if (resolved_target.llvm_cpu_features) |x| break :b x;
273 if (!options.global.use_llvm) break :b null;287 if (!options.global.use_llvm) break :b null;
...@@ -350,6 +364,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {...@@ -350,6 +364,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
350 .sanitize_thread = sanitize_thread,364 .sanitize_thread = sanitize_thread,
351 .unwind_tables = unwind_tables,365 .unwind_tables = unwind_tables,
352 .cc_argv = &.{},366 .cc_argv = &.{},
367 .structured_cfg = structured_cfg,
353 };368 };
354 break :b new;369 break :b new;
355 };370 };
...@@ -381,6 +396,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {...@@ -381,6 +396,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
381 .sanitize_thread = sanitize_thread,396 .sanitize_thread = sanitize_thread,
382 .unwind_tables = unwind_tables,397 .unwind_tables = unwind_tables,
383 .cc_argv = options.cc_argv,398 .cc_argv = options.cc_argv,
399 .structured_cfg = structured_cfg,
384 };400 };
385401
386 try mod.deps.ensureUnusedCapacity(arena, 1);402 try mod.deps.ensureUnusedCapacity(arena, 1);
...@@ -422,6 +438,7 @@ pub fn createLimited(gpa: Allocator, options: LimitedOptions) Allocator.Error!*P...@@ -422,6 +438,7 @@ pub fn createLimited(gpa: Allocator, options: LimitedOptions) Allocator.Error!*P
422 .unwind_tables = undefined,438 .unwind_tables = undefined,
423 .cc_argv = undefined,439 .cc_argv = undefined,
424 .generated_builtin_source = undefined,440 .generated_builtin_source = undefined,
441 .structured_cfg = undefined,
425 };442 };
426 return mod;443 return mod;
427}444}
src/codegen/llvm.zig+1-1
...@@ -3084,7 +3084,7 @@ pub const Object = struct {...@@ -3084,7 +3084,7 @@ pub const Object = struct {
3084 if (comp.unwind_tables) {3084 if (comp.unwind_tables) {
3085 try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder);3085 try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder);
3086 }3086 }
3087 if (comp.skip_linker_dependencies or comp.bin_file.options.no_builtin) {3087 if (comp.skip_linker_dependencies or comp.no_builtin) {
3088 // The intent here is for compiler-rt and libc functions to not generate3088 // The intent here is for compiler-rt and libc functions to not generate
3089 // infinite recursion. For example, if we are compiling the memcpy function,3089 // infinite recursion. For example, if we are compiling the memcpy function,
3090 // and llvm detects that the body is equivalent to memcpy, it may replace the3090 // and llvm detects that the body is equivalent to memcpy, it may replace the
src/codegen/spirv.zig+4-8
...@@ -191,13 +191,9 @@ pub const Object = struct {...@@ -191,13 +191,9 @@ pub const Object = struct {
191 air: Air,191 air: Air,
192 liveness: Liveness,192 liveness: Liveness,
193 ) !void {193 ) !void {
194 const target = mod.getTarget();194 const decl = mod.declPtr(decl_index);
195 // We always want a structured control flow in shaders. This option is only relevant195 const namespace = mod.namespacePtr(decl.src_namespace);
196 // for OpenCL kernels.196 const structured_cfg = namespace.file_scope.mod.structured_cfg;
197 const want_structured_cfg = switch (target.os.tag) {
198 .opencl => mod.comp.bin_file.options.want_structured_cfg orelse false,
199 else => true,
200 };
201197
202 var decl_gen = DeclGen{198 var decl_gen = DeclGen{
203 .gpa = self.gpa,199 .gpa = self.gpa,
...@@ -208,7 +204,7 @@ pub const Object = struct {...@@ -208,7 +204,7 @@ pub const Object = struct {
208 .air = air,204 .air = air,
209 .liveness = liveness,205 .liveness = liveness,
210 .type_map = &self.type_map,206 .type_map = &self.type_map,
211 .control_flow = switch (want_structured_cfg) {207 .control_flow = switch (structured_cfg) {
212 true => .{ .structured = .{} },208 true => .{ .structured = .{} },
213 false => .{ .unstructured = .{} },209 false => .{ .unstructured = .{} },
214 },210 },
src/link.zig+4-15
...@@ -32,8 +32,6 @@ pub const SystemLib = struct {...@@ -32,8 +32,6 @@ pub const SystemLib = struct {
32 path: ?[]const u8,32 path: ?[]const u8,
33};33};
3434
35pub const SortSection = enum { name, alignment };
36
37pub const CacheMode = enum { incremental, whole };35pub const CacheMode = enum { incremental, whole };
3836
39pub fn hashAddSystemLibs(37pub fn hashAddSystemLibs(
...@@ -51,10 +49,6 @@ pub fn hashAddSystemLibs(...@@ -51,10 +49,6 @@ pub fn hashAddSystemLibs(
5149
52pub const producer_string = if (builtin.is_test) "zig test" else "zig " ++ build_options.version;50pub const producer_string = if (builtin.is_test) "zig test" else "zig " ++ build_options.version;
5351
54pub const HashStyle = enum { sysv, gnu, both };
55
56pub const CompressDebugSections = enum { none, zlib, zstd };
57
58pub const File = struct {52pub const File = struct {
59 tag: Tag,53 tag: Tag,
6054
...@@ -105,12 +99,9 @@ pub const File = struct {...@@ -105,12 +99,9 @@ pub const File = struct {
105 image_base: ?u64,99 image_base: ?u64,
106 function_sections: bool,100 function_sections: bool,
107 data_sections: bool,101 data_sections: bool,
108 no_builtin: bool,
109 eh_frame_hdr: bool,102 eh_frame_hdr: bool,
110 emit_relocs: bool,103 emit_relocs: bool,
111 rdynamic: bool,104 rdynamic: bool,
112 optimization: u8,
113 linker_script: ?[]const u8,
114 z_nodelete: bool,105 z_nodelete: bool,
115 z_notext: bool,106 z_notext: bool,
116 z_defs: bool,107 z_defs: bool,
...@@ -123,7 +114,7 @@ pub const File = struct {...@@ -123,7 +114,7 @@ pub const File = struct {
123 tsaware: bool,114 tsaware: bool,
124 nxcompat: bool,115 nxcompat: bool,
125 dynamicbase: bool,116 dynamicbase: bool,
126 compress_debug_sections: CompressDebugSections,117 compress_debug_sections: Elf.CompressDebugSections,
127 bind_global_refs_locally: bool,118 bind_global_refs_locally: bool,
128 import_symbols: bool,119 import_symbols: bool,
129 import_table: bool,120 import_table: bool,
...@@ -136,13 +127,14 @@ pub const File = struct {...@@ -136,13 +127,14 @@ pub const File = struct {
136 each_lib_rpath: bool,127 each_lib_rpath: bool,
137 build_id: std.zig.BuildId,128 build_id: std.zig.BuildId,
138 disable_lld_caching: bool,129 disable_lld_caching: bool,
139 hash_style: HashStyle,130 hash_style: Elf.HashStyle,
140 sort_section: ?SortSection,131 sort_section: ?Elf.SortSection,
141 major_subsystem_version: ?u32,132 major_subsystem_version: ?u32,
142 minor_subsystem_version: ?u32,133 minor_subsystem_version: ?u32,
143 gc_sections: ?bool,134 gc_sections: ?bool,
144 allow_shlib_undefined: ?bool,135 allow_shlib_undefined: ?bool,
145 subsystem: ?std.Target.SubSystem,136 subsystem: ?std.Target.SubSystem,
137 linker_script: ?[]const u8,
146 version_script: ?[]const u8,138 version_script: ?[]const u8,
147 soname: ?[]const u8,139 soname: ?[]const u8,
148 print_gc_sections: bool,140 print_gc_sections: bool,
...@@ -192,9 +184,6 @@ pub const File = struct {...@@ -192,9 +184,6 @@ pub const File = struct {
192 /// (Windows) .def file to specify when linking184 /// (Windows) .def file to specify when linking
193 module_definition_file: ?[]const u8,185 module_definition_file: ?[]const u8,
194186
195 /// (SPIR-V) whether to generate a structured control flow graph or not
196 want_structured_cfg: ?bool,
197
198 wasi_emulated_libs: []const wasi_libc.CRTFile,187 wasi_emulated_libs: []const wasi_libc.CRTFile,
199 };188 };
200189
src/link/Coff.zig+20-4
...@@ -10,6 +10,15 @@ base: link.File,...@@ -10,6 +10,15 @@ base: link.File,
10image_base: u64,10image_base: u64,
11error_flags: link.File.ErrorFlags = .{},11error_flags: link.File.ErrorFlags = .{},
12dll_export_fns: bool,12dll_export_fns: bool,
13subsystem: ?std.Target.SubSystem,
14tsaware: bool,
15nxcompat: bool,
16dynamicbase: bool,
17/// TODO this and minor_subsystem_version should be combined into one property and left as
18/// default or populated together. They should not be separate fields.
19major_subsystem_version: u32,
20minor_subsystem_version: u32,
21lib_dirs: []const []const u8,
1322
14ptr_width: PtrWidth,23ptr_width: PtrWidth,
15page_size: u32,24page_size: u32,
...@@ -403,6 +412,13 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Coff {...@@ -403,6 +412,13 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Coff {
403 },412 },
404413
405 .dll_export_fns = options.dll_export_fns,414 .dll_export_fns = options.dll_export_fns,
415 .subsystem = options.subsystem,
416 .tsaware = options.tsaware,
417 .nxcompat = options.nxcompat,
418 .dynamicbase = options.dynamicbase,
419 .major_subsystem_version = options.major_subsystem_version orelse 6,
420 .minor_subsystem_version = options.minor_subsystem_version orelse 0,
421 .lib_dirs = options.lib_dirs,
406 };422 };
407423
408 const use_llvm = comp.config.use_llvm;424 const use_llvm = comp.config.use_llvm;
...@@ -2305,8 +2321,8 @@ fn writeHeader(self: *Coff) !void {...@@ -2305,8 +2321,8 @@ fn writeHeader(self: *Coff) !void {
2305 .minor_operating_system_version = 0,2321 .minor_operating_system_version = 0,
2306 .major_image_version = 0,2322 .major_image_version = 0,
2307 .minor_image_version = 0,2323 .minor_image_version = 0,
2308 .major_subsystem_version = 6,2324 .major_subsystem_version = self.major_subsystem_version,
2309 .minor_subsystem_version = 0,2325 .minor_subsystem_version = self.minor_subsystem_version,
2310 .win32_version_value = 0,2326 .win32_version_value = 0,
2311 .size_of_image = size_of_image,2327 .size_of_image = size_of_image,
2312 .size_of_headers = size_of_headers,2328 .size_of_headers = size_of_headers,
...@@ -2339,8 +2355,8 @@ fn writeHeader(self: *Coff) !void {...@@ -2339,8 +2355,8 @@ fn writeHeader(self: *Coff) !void {
2339 .minor_operating_system_version = 0,2355 .minor_operating_system_version = 0,
2340 .major_image_version = 0,2356 .major_image_version = 0,
2341 .minor_image_version = 0,2357 .minor_image_version = 0,
2342 .major_subsystem_version = 6,2358 .major_subsystem_version = self.major_subsystem_version,
2343 .minor_subsystem_version = 0,2359 .minor_subsystem_version = self.minor_subsystem_version,
2344 .win32_version_value = 0,2360 .win32_version_value = 0,
2345 .size_of_image = size_of_image,2361 .size_of_image = size_of_image,
2346 .size_of_headers = size_of_headers,2362 .size_of_headers = size_of_headers,
src/link/Elf.zig+54-6
...@@ -1,6 +1,29 @@...@@ -1,6 +1,29 @@
1base: link.File,1base: link.File,
2image_base: u64,2image_base: u64,
3rdynamic: bool,3rdynamic: bool,
4eh_frame_hdr: bool,
5emit_relocs: bool,
6z_nodelete: bool,
7z_notext: bool,
8z_defs: bool,
9z_origin: bool,
10z_nocopyreloc: bool,
11z_now: bool,
12z_relro: bool,
13/// TODO make this non optional and resolve the default in open()
14z_common_page_size: ?u64,
15/// TODO make this non optional and resolve the default in open()
16z_max_page_size: ?u64,
17lib_dirs: []const []const u8,
18hash_style: HashStyle,
19compress_debug_sections: CompressDebugSections,
20symbol_wrap_set: std.StringArrayHashMapUnmanaged(void),
21each_lib_rpath: bool,
22sort_section: ?SortSection,
23soname: ?[]const u8,
24bind_global_refs_locally: bool,
25linker_script: ?[]const u8,
26version_script: ?[]const u8,
427
5ptr_width: PtrWidth,28ptr_width: PtrWidth,
629
...@@ -201,6 +224,9 @@ const minimum_atom_size = 64;...@@ -201,6 +224,9 @@ const minimum_atom_size = 64;
201pub const min_text_capacity = padToIdeal(minimum_atom_size);224pub const min_text_capacity = padToIdeal(minimum_atom_size);
202225
203pub const PtrWidth = enum { p32, p64 };226pub const PtrWidth = enum { p32, p64 };
227pub const HashStyle = enum { sysv, gnu, both };
228pub const CompressDebugSections = enum { none, zlib, zstd };
229pub const SortSection = enum { name, alignment };
204230
205pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Elf {231pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Elf {
206 if (build_options.only_c) unreachable;232 if (build_options.only_c) unreachable;
...@@ -374,6 +400,27 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Elf {...@@ -374,6 +400,27 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Elf {
374 },400 },
375401
376 .rdynamic = options.rdynamic,402 .rdynamic = options.rdynamic,
403 .eh_frame_hdr = options.eh_frame_hdr,
404 .emit_relocs = options.emit_relocs,
405 .z_nodelete = options.z_nodelete,
406 .z_notext = options.z_notext,
407 .z_defs = options.z_defs,
408 .z_origin = options.z_origin,
409 .z_nocopyreloc = options.z_nocopyreloc,
410 .z_now = options.z_now,
411 .z_relro = options.z_relro,
412 .z_common_page_size = options.z_common_page_size,
413 .z_max_page_size = options.z_max_page_size,
414 .lib_dirs = options.lib_dirs,
415 .hash_style = options.hash_style,
416 .compress_debug_sections = options.compress_debug_sections,
417 .symbol_wrap_set = options.symbol_wrap_set,
418 .each_lib_rpath = options.each_lib_rpath,
419 .sort_section = options.sort_section,
420 .soname = options.soname,
421 .bind_global_refs_locally = options.bind_global_refs_locally,
422 .linker_script = options.linker_script,
423 .version_script = options.version_script,
377 };424 };
378 if (use_llvm and comp.config.have_zcu) {425 if (use_llvm and comp.config.have_zcu) {
379 self.llvm_object = try LlvmObject.create(arena, options);426 self.llvm_object = try LlvmObject.create(arena, options);
...@@ -2424,8 +2471,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v...@@ -2424,8 +2471,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
2424 man.hash.add(self.bind_global_refs_locally);2471 man.hash.add(self.bind_global_refs_locally);
2425 man.hash.add(self.compress_debug_sections);2472 man.hash.add(self.compress_debug_sections);
2426 man.hash.add(comp.config.any_sanitize_thread);2473 man.hash.add(comp.config.any_sanitize_thread);
2427 man.hash.addOptionalBytes(self.sysroot);2474 man.hash.addOptionalBytes(comp.sysroot);
2428 man.hash.add(self.optimization);
24292475
2430 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.2476 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
2431 _ = try man.hit();2477 _ = try man.hit();
...@@ -2500,7 +2546,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v...@@ -2500,7 +2546,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
25002546
2501 try argv.append("--error-limit=0");2547 try argv.append("--error-limit=0");
25022548
2503 if (self.sysroot) |sysroot| {2549 if (comp.sysroot) |sysroot| {
2504 try argv.append(try std.fmt.allocPrint(arena, "--sysroot={s}", .{sysroot}));2550 try argv.append(try std.fmt.allocPrint(arena, "--sysroot={s}", .{sysroot}));
2505 }2551 }
25062552
...@@ -2511,9 +2557,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v...@@ -2511,9 +2557,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
2511 .ReleaseFast, .ReleaseSafe => try argv.append("--lto-O3"),2557 .ReleaseFast, .ReleaseSafe => try argv.append("--lto-O3"),
2512 }2558 }
2513 }2559 }
2514 try argv.append(try std.fmt.allocPrint(arena, "-O{d}", .{2560 switch (comp.root_mod.optimize_mode) {
2515 self.optimization,2561 .Debug => {},
2516 }));2562 .ReleaseSmall => try argv.append("-O2"),
2563 .ReleaseFast, .ReleaseSafe => try argv.append("-O3"),
2564 }
25172565
2518 if (comp.config.entry) |entry| {2566 if (comp.config.entry) |entry| {
2519 try argv.append("--entry");2567 try argv.append("--entry");
src/link/MachO/load_commands.zig+1-1
...@@ -476,7 +476,7 @@ pub fn inferSdkVersion(gpa: Allocator, comp: *const Compilation) ?std.SemanticVe...@@ -476,7 +476,7 @@ pub fn inferSdkVersion(gpa: Allocator, comp: *const Compilation) ?std.SemanticVe
476476
477 const sdk_layout = macho_file.sdk_layout orelse return null;477 const sdk_layout = macho_file.sdk_layout orelse return null;
478 const sdk_dir = switch (sdk_layout) {478 const sdk_dir = switch (sdk_layout) {
479 .sdk => macho_file.sysroot.?,479 .sdk => comp.sysroot.?,
480 .vendored => std.fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null,480 .vendored => std.fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null,
481 };481 };
482 if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| {482 if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| {
src/link/MachO/zld.zig+1-1
...@@ -249,7 +249,7 @@ pub fn linkWithZld(...@@ -249,7 +249,7 @@ pub fn linkWithZld(
249 }249 }
250 }250 }
251251
252 if (macho_file.sysroot) |syslibroot| {252 if (comp.sysroot) |syslibroot| {
253 try argv.append("-syslibroot");253 try argv.append("-syslibroot");
254 try argv.append(syslibroot);254 try argv.append(syslibroot);
255 }255 }
src/link/SpirV.zig+2
...@@ -47,6 +47,8 @@ base: link.File,...@@ -47,6 +47,8 @@ base: link.File,
4747
48object: codegen.Object,48object: codegen.Object,
4949
50pub const base_tag: link.File.Tag = .spirv;
51
50pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*SpirV {52pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*SpirV {
51 const gpa = options.comp.gpa;53 const gpa = options.comp.gpa;
52 const target = options.comp.root_mod.resolved_target.result;54 const target = options.comp.root_mod.resolved_target.result;
src/main.zig+18-22
...@@ -828,9 +828,9 @@ fn buildOutputType(...@@ -828,9 +828,9 @@ fn buildOutputType(
828 var linker_script: ?[]const u8 = null;828 var linker_script: ?[]const u8 = null;
829 var version_script: ?[]const u8 = null;829 var version_script: ?[]const u8 = null;
830 var disable_c_depfile = false;830 var disable_c_depfile = false;
831 var linker_sort_section: ?link.SortSection = null;831 var linker_sort_section: ?link.File.Elf.SortSection = null;
832 var linker_gc_sections: ?bool = null;832 var linker_gc_sections: ?bool = null;
833 var linker_compress_debug_sections: ?link.CompressDebugSections = null;833 var linker_compress_debug_sections: ?link.File.Elf.CompressDebugSections = null;
834 var linker_allow_shlib_undefined: ?bool = null;834 var linker_allow_shlib_undefined: ?bool = null;
835 var linker_bind_global_refs_locally: ?bool = null;835 var linker_bind_global_refs_locally: ?bool = null;
836 var linker_import_symbols: bool = false;836 var linker_import_symbols: bool = false;
...@@ -855,7 +855,7 @@ fn buildOutputType(...@@ -855,7 +855,7 @@ fn buildOutputType(
855 var linker_tsaware = false;855 var linker_tsaware = false;
856 var linker_nxcompat = false;856 var linker_nxcompat = false;
857 var linker_dynamicbase = true;857 var linker_dynamicbase = true;
858 var linker_optimization: ?u8 = null;858 var linker_optimization: ?[]const u8 = null;
859 var linker_module_definition_file: ?[]const u8 = null;859 var linker_module_definition_file: ?[]const u8 = null;
860 var test_no_exec = false;860 var test_no_exec = false;
861 var force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{};861 var force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{};
...@@ -881,7 +881,7 @@ fn buildOutputType(...@@ -881,7 +881,7 @@ fn buildOutputType(
881 var enable_link_snapshots: bool = false;881 var enable_link_snapshots: bool = false;
882 var debug_incremental: bool = false;882 var debug_incremental: bool = false;
883 var install_name: ?[]const u8 = null;883 var install_name: ?[]const u8 = null;
884 var hash_style: link.HashStyle = .both;884 var hash_style: link.File.Elf.HashStyle = .both;
885 var entitlements: ?[]const u8 = null;885 var entitlements: ?[]const u8 = null;
886 var pagezero_size: ?u64 = null;886 var pagezero_size: ?u64 = null;
887 var lib_search_strategy: SystemLib.SearchStrategy = .paths_first;887 var lib_search_strategy: SystemLib.SearchStrategy = .paths_first;
...@@ -894,7 +894,6 @@ fn buildOutputType(...@@ -894,7 +894,6 @@ fn buildOutputType(
894 var pdb_out_path: ?[]const u8 = null;894 var pdb_out_path: ?[]const u8 = null;
895 var debug_format: ?link.File.DebugFormat = null;895 var debug_format: ?link.File.DebugFormat = null;
896 var error_limit: ?Module.ErrorInt = null;896 var error_limit: ?Module.ErrorInt = null;
897 var want_structured_cfg: ?bool = null;
898 // These are before resolving sysroot.897 // These are before resolving sysroot.
899 var lib_dir_args: std.ArrayListUnmanaged([]const u8) = .{};898 var lib_dir_args: std.ArrayListUnmanaged([]const u8) = .{};
900 var extra_cflags: std.ArrayListUnmanaged([]const u8) = .{};899 var extra_cflags: std.ArrayListUnmanaged([]const u8) = .{};
...@@ -1110,9 +1109,9 @@ fn buildOutputType(...@@ -1110,9 +1109,9 @@ fn buildOutputType(
1110 try extra_rcflags.append(arena, next_arg);1109 try extra_rcflags.append(arena, next_arg);
1111 }1110 }
1112 } else if (mem.startsWith(u8, arg, "-fstructured-cfg")) {1111 } else if (mem.startsWith(u8, arg, "-fstructured-cfg")) {
1113 want_structured_cfg = true;1112 mod_opts.structured_cfg = true;
1114 } else if (mem.startsWith(u8, arg, "-fno-structured-cfg")) {1113 } else if (mem.startsWith(u8, arg, "-fno-structured-cfg")) {
1115 want_structured_cfg = false;1114 mod_opts.structured_cfg = false;
1116 } else if (mem.eql(u8, arg, "--color")) {1115 } else if (mem.eql(u8, arg, "--color")) {
1117 const next_arg = args_iter.next() orelse {1116 const next_arg = args_iter.next() orelse {
1118 fatal("expected [auto|on|off] after --color", .{});1117 fatal("expected [auto|on|off] after --color", .{});
...@@ -1152,11 +1151,11 @@ fn buildOutputType(...@@ -1152,11 +1151,11 @@ fn buildOutputType(
1152 install_name = args_iter.nextOrFatal();1151 install_name = args_iter.nextOrFatal();
1153 } else if (mem.startsWith(u8, arg, "--compress-debug-sections=")) {1152 } else if (mem.startsWith(u8, arg, "--compress-debug-sections=")) {
1154 const param = arg["--compress-debug-sections=".len..];1153 const param = arg["--compress-debug-sections=".len..];
1155 linker_compress_debug_sections = std.meta.stringToEnum(link.CompressDebugSections, param) orelse {1154 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Elf.CompressDebugSections, param) orelse {
1156 fatal("expected --compress-debug-sections=[none|zlib|zstd], found '{s}'", .{param});1155 fatal("expected --compress-debug-sections=[none|zlib|zstd], found '{s}'", .{param});
1157 };1156 };
1158 } else if (mem.eql(u8, arg, "--compress-debug-sections")) {1157 } else if (mem.eql(u8, arg, "--compress-debug-sections")) {
1159 linker_compress_debug_sections = link.CompressDebugSections.zlib;1158 linker_compress_debug_sections = link.File.Elf.CompressDebugSections.zlib;
1160 } else if (mem.eql(u8, arg, "-pagezero_size")) {1159 } else if (mem.eql(u8, arg, "-pagezero_size")) {
1161 const next_arg = args_iter.nextOrFatal();1160 const next_arg = args_iter.nextOrFatal();
1162 pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| {1161 pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| {
...@@ -2067,7 +2066,7 @@ fn buildOutputType(...@@ -2067,7 +2066,7 @@ fn buildOutputType(
2067 if (it.only_arg.len == 0) {2066 if (it.only_arg.len == 0) {
2068 linker_compress_debug_sections = .zlib;2067 linker_compress_debug_sections = .zlib;
2069 } else {2068 } else {
2070 linker_compress_debug_sections = std.meta.stringToEnum(link.CompressDebugSections, it.only_arg) orelse {2069 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Elf.CompressDebugSections, it.only_arg) orelse {
2071 fatal("expected [none|zlib|zstd] after --compress-debug-sections, found '{s}'", .{it.only_arg});2070 fatal("expected [none|zlib|zstd] after --compress-debug-sections, found '{s}'", .{it.only_arg});
2072 };2071 };
2073 }2072 }
...@@ -2138,14 +2137,9 @@ fn buildOutputType(...@@ -2138,14 +2137,9 @@ fn buildOutputType(
2138 } else if (mem.eql(u8, arg, "-version-script") or mem.eql(u8, arg, "--version-script")) {2137 } else if (mem.eql(u8, arg, "-version-script") or mem.eql(u8, arg, "--version-script")) {
2139 version_script = linker_args_it.nextOrFatal();2138 version_script = linker_args_it.nextOrFatal();
2140 } else if (mem.eql(u8, arg, "-O")) {2139 } else if (mem.eql(u8, arg, "-O")) {
2141 const opt = linker_args_it.nextOrFatal();2140 linker_optimization = linker_args_it.nextOrFatal();
2142 linker_optimization = std.fmt.parseUnsigned(u8, opt, 10) catch |err| {
2143 fatal("unable to parse optimization level '{s}': {s}", .{ opt, @errorName(err) });
2144 };
2145 } else if (mem.startsWith(u8, arg, "-O")) {2141 } else if (mem.startsWith(u8, arg, "-O")) {
2146 linker_optimization = std.fmt.parseUnsigned(u8, arg["-O".len..], 10) catch |err| {2142 linker_optimization = arg["-O".len..];
2147 fatal("unable to parse optimization level '{s}': {s}", .{ arg, @errorName(err) });
2148 };
2149 } else if (mem.eql(u8, arg, "-pagezero_size")) {2143 } else if (mem.eql(u8, arg, "-pagezero_size")) {
2150 const next_arg = linker_args_it.nextOrFatal();2144 const next_arg = linker_args_it.nextOrFatal();
2151 pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| {2145 pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| {
...@@ -2176,7 +2170,7 @@ fn buildOutputType(...@@ -2176,7 +2170,7 @@ fn buildOutputType(
2176 linker_print_map = true;2170 linker_print_map = true;
2177 } else if (mem.eql(u8, arg, "--sort-section")) {2171 } else if (mem.eql(u8, arg, "--sort-section")) {
2178 const arg1 = linker_args_it.nextOrFatal();2172 const arg1 = linker_args_it.nextOrFatal();
2179 linker_sort_section = std.meta.stringToEnum(link.SortSection, arg1) orelse {2173 linker_sort_section = std.meta.stringToEnum(link.File.Elf.SortSection, arg1) orelse {
2180 fatal("expected [name|alignment] after --sort-section, found '{s}'", .{arg1});2174 fatal("expected [name|alignment] after --sort-section, found '{s}'", .{arg1});
2181 };2175 };
2182 } else if (mem.eql(u8, arg, "--allow-shlib-undefined") or2176 } else if (mem.eql(u8, arg, "--allow-shlib-undefined") or
...@@ -2222,7 +2216,7 @@ fn buildOutputType(...@@ -2222,7 +2216,7 @@ fn buildOutputType(
2222 try linker_export_symbol_names.append(arena, linker_args_it.nextOrFatal());2216 try linker_export_symbol_names.append(arena, linker_args_it.nextOrFatal());
2223 } else if (mem.eql(u8, arg, "--compress-debug-sections")) {2217 } else if (mem.eql(u8, arg, "--compress-debug-sections")) {
2224 const arg1 = linker_args_it.nextOrFatal();2218 const arg1 = linker_args_it.nextOrFatal();
2225 linker_compress_debug_sections = std.meta.stringToEnum(link.CompressDebugSections, arg1) orelse {2219 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Elf.CompressDebugSections, arg1) orelse {
2226 fatal("expected [none|zlib|zstd] after --compress-debug-sections, found '{s}'", .{arg1});2220 fatal("expected [none|zlib|zstd] after --compress-debug-sections, found '{s}'", .{arg1});
2227 };2221 };
2228 } else if (mem.startsWith(u8, arg, "-z")) {2222 } else if (mem.startsWith(u8, arg, "-z")) {
...@@ -2405,7 +2399,7 @@ fn buildOutputType(...@@ -2405,7 +2399,7 @@ fn buildOutputType(
2405 mem.eql(u8, arg, "--hash-style"))2399 mem.eql(u8, arg, "--hash-style"))
2406 {2400 {
2407 const next_arg = linker_args_it.nextOrFatal();2401 const next_arg = linker_args_it.nextOrFatal();
2408 hash_style = std.meta.stringToEnum(link.HashStyle, next_arg) orelse {2402 hash_style = std.meta.stringToEnum(link.File.Elf.HashStyle, next_arg) orelse {
2409 fatal("expected [sysv|gnu|both] after --hash-style, found '{s}'", .{2403 fatal("expected [sysv|gnu|both] after --hash-style, found '{s}'", .{
2410 next_arg,2404 next_arg,
2411 });2405 });
...@@ -2625,6 +2619,10 @@ fn buildOutputType(...@@ -2625,6 +2619,10 @@ fn buildOutputType(
2625 };2619 };
2626 defer global_cache_directory.handle.close();2620 defer global_cache_directory.handle.close();
26272621
2622 if (linker_optimization) |o| {
2623 warn("ignoring deprecated linker optimization setting '{s}'", .{o});
2624 }
2625
2628 create_module.global_cache_directory = global_cache_directory;2626 create_module.global_cache_directory = global_cache_directory;
2629 create_module.opts.emit_llvm_ir = emit_llvm_ir != .no;2627 create_module.opts.emit_llvm_ir = emit_llvm_ir != .no;
2630 create_module.opts.emit_llvm_bc = emit_llvm_bc != .no;2628 create_module.opts.emit_llvm_bc = emit_llvm_bc != .no;
...@@ -3409,7 +3407,6 @@ fn buildOutputType(...@@ -3409,7 +3407,6 @@ fn buildOutputType(
3409 .linker_tsaware = linker_tsaware,3407 .linker_tsaware = linker_tsaware,
3410 .linker_nxcompat = linker_nxcompat,3408 .linker_nxcompat = linker_nxcompat,
3411 .linker_dynamicbase = linker_dynamicbase,3409 .linker_dynamicbase = linker_dynamicbase,
3412 .linker_optimization = linker_optimization,
3413 .linker_compress_debug_sections = linker_compress_debug_sections,3410 .linker_compress_debug_sections = linker_compress_debug_sections,
3414 .linker_module_definition_file = linker_module_definition_file,3411 .linker_module_definition_file = linker_module_definition_file,
3415 .major_subsystem_version = major_subsystem_version,3412 .major_subsystem_version = major_subsystem_version,
...@@ -3458,7 +3455,6 @@ fn buildOutputType(...@@ -3458,7 +3455,6 @@ fn buildOutputType(
3458 .reference_trace = reference_trace,3455 .reference_trace = reference_trace,
3459 .pdb_out_path = pdb_out_path,3456 .pdb_out_path = pdb_out_path,
3460 .error_limit = error_limit,3457 .error_limit = error_limit,
3461 .want_structured_cfg = want_structured_cfg,
3462 }) catch |err| switch (err) {3458 }) catch |err| switch (err) {
3463 error.LibCUnavailable => {3459 error.LibCUnavailable => {
3464 const triple_name = try target.zigTriple(arena);3460 const triple_name = try target.zigTriple(arena);