authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-06-16 01:43:20-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-06-20 21:08:23-04:00
log4f921814c0a6555a61d9e0a92fcc6f30bc20e994
tree1991b1341621c3b1ec4297a7e93e18a12d3a2693
parente949341b705c16b46544f26f5aab0a16670f42b4

main: handle more cli args for `zig test -ofmt=c`


8 files changed, 184 insertions(+), 120 deletions(-)

lib/zig.h+17-9
...@@ -4557,9 +4557,12 @@ static inline void zig_msvc_atomic_store_i128(zig_i128 volatile* obj, zig_i128 a...@@ -4557,9 +4557,12 @@ static inline void zig_msvc_atomic_store_i128(zig_i128 volatile* obj, zig_i128 a
4557#include <intrin.h>4557#include <intrin.h>
4558#endif4558#endif
45594559
4560static inline void* zig_e_zig_windows_teb(void) zig_mangled(zig_e_zig_windows_teb, "zig_windows_teb");
4561static inline void* zig_e_zig_windows_peb(void) zig_mangled(zig_e_zig_windows_peb, "zig_windows_peb");
4562
4560#if defined(zig_thumb)4563#if defined(zig_thumb)
45614564
4562static inline void* zig_windows_teb(void) {4565static inline void* zig_e_zig_windows_teb(void) {
4563 void* teb = 0;4566 void* teb = 0;
4564#if defined(zig_msvc)4567#if defined(zig_msvc)
4565 teb = (void*)_MoveFromCoprocessor(15, 0, 13, 0, 2);4568 teb = (void*)_MoveFromCoprocessor(15, 0, 13, 0, 2);
...@@ -4571,7 +4574,7 @@ static inline void* zig_windows_teb(void) {...@@ -4571,7 +4574,7 @@ static inline void* zig_windows_teb(void) {
45714574
4572#elif defined(zig_aarch64)4575#elif defined(zig_aarch64)
45734576
4574static inline void* zig_windows_teb(void) {4577static inline void* zig_e_zig_windows_teb(void) {
4575 void* teb = 0;4578 void* teb = 0;
4576#if defined(zig_msvc)4579#if defined(zig_msvc)
4577 teb = (void*)__readx18qword(0x0);4580 teb = (void*)__readx18qword(0x0);
...@@ -4583,7 +4586,7 @@ static inline void* zig_windows_teb(void) {...@@ -4583,7 +4586,7 @@ static inline void* zig_windows_teb(void) {
45834586
4584#elif defined(zig_x86_32)4587#elif defined(zig_x86_32)
45854588
4586static inline void* zig_windows_teb(void) {4589static inline void* zig_e_zig_windows_teb(void) {
4587 void* teb = 0;4590 void* teb = 0;
4588#if defined(zig_msvc)4591#if defined(zig_msvc)
4589 teb = (void*)__readfsdword(0x18);4592 teb = (void*)__readfsdword(0x18);
...@@ -4593,7 +4596,7 @@ static inline void* zig_windows_teb(void) {...@@ -4593,7 +4596,7 @@ static inline void* zig_windows_teb(void) {
4593 return teb;4596 return teb;
4594}4597}
45954598
4596static inline void* zig_windows_peb(void) {4599static inline void* zig_e_zig_windows_peb(void) {
4597 void* peb = 0;4600 void* peb = 0;
4598#if defined(zig_msvc)4601#if defined(zig_msvc)
4599 peb = (void*)__readfsdword(0x30);4602 peb = (void*)__readfsdword(0x30);
...@@ -4605,7 +4608,7 @@ static inline void* zig_windows_peb(void) {...@@ -4605,7 +4608,7 @@ static inline void* zig_windows_peb(void) {
46054608
4606#elif defined(zig_x86_64)4609#elif defined(zig_x86_64)
46074610
4608static inline void* zig_windows_teb(void) {4611static inline void* zig_e_zig_windows_teb(void) {
4609 void* teb = 0;4612 void* teb = 0;
4610#if defined(zig_msvc)4613#if defined(zig_msvc)
4611 teb = (void*)__readgsqword(0x30);4614 teb = (void*)__readgsqword(0x30);
...@@ -4615,7 +4618,7 @@ static inline void* zig_windows_teb(void) {...@@ -4615,7 +4618,7 @@ static inline void* zig_windows_teb(void) {
4615 return teb;4618 return teb;
4616}4619}
46174620
4618static inline void* zig_windows_peb(void) {4621static inline void* zig_e_zig_windows_peb(void) {
4619 void* peb = 0;4622 void* peb = 0;
4620#if defined(zig_msvc)4623#if defined(zig_msvc)
4621 peb = (void*)__readgsqword(0x60);4624 peb = (void*)__readgsqword(0x60);
...@@ -4629,7 +4632,9 @@ static inline void* zig_windows_peb(void) {...@@ -4629,7 +4632,9 @@ static inline void* zig_windows_peb(void) {
46294632
4630#if defined(zig_loongarch)4633#if defined(zig_loongarch)
46314634
4632static inline void zig_loongarch_cpucfg(uint32_t word, uint32_t* result) {4635static inline void zig_e_zig_loongarch_cpucfg(uint32_t word, uint32_t* result) zig_mangled(zig_e_zig_loongarch_cpucfg, "zig_loongarch_cpucfg");
4636
4637static inline void zig_e_zig_loongarch_cpucfg(uint32_t word, uint32_t* result) {
4633#if defined(zig_gnuc_asm)4638#if defined(zig_gnuc_asm)
4634 __asm__("cpucfg %[result], %[word]" : [result] "=r" (result) : [word] "r" (word));4639 __asm__("cpucfg %[result], %[word]" : [result] "=r" (result) : [word] "r" (word));
4635#else4640#else
...@@ -4639,7 +4644,10 @@ static inline void zig_loongarch_cpucfg(uint32_t word, uint32_t* result) {...@@ -4639,7 +4644,10 @@ static inline void zig_loongarch_cpucfg(uint32_t word, uint32_t* result) {
46394644
4640#elif defined(zig_x86) && !defined(zig_x86_16)4645#elif defined(zig_x86) && !defined(zig_x86_16)
46414646
4642static inline void zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) {4647static inline void zig_e_zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) zig_mangled(zig_e_zig_x86_cpuid, "zig_x86_cpuid");
4648static inline uint32_t zig_e_zig_x86_get_xcr0(void) zig_mangled(zig_e_zig_x86_get_xcr0, "zig_x86_get_xcr0");
4649
4650static inline void zig_e_zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) {
4643#if defined(zig_msvc)4651#if defined(zig_msvc)
4644 int cpu_info[4];4652 int cpu_info[4];
4645 __cpuidex(cpu_info, leaf_id, subid);4653 __cpuidex(cpu_info, leaf_id, subid);
...@@ -4657,7 +4665,7 @@ static inline void zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax...@@ -4657,7 +4665,7 @@ static inline void zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax
4657#endif4665#endif
4658}4666}
46594667
4660static inline uint32_t zig_x86_get_xcr0(void) {4668static inline uint32_t zig_e_zig_x86_get_xcr0(void) {
4661#if defined(zig_msvc)4669#if defined(zig_msvc)
4662 return (uint32_t)_xgetbv(0);4670 return (uint32_t)_xgetbv(0);
4663#elif defined(zig_gnuc_asm)4671#elif defined(zig_gnuc_asm)
src/Compilation.zig+60-49
...@@ -103,16 +103,12 @@ native_system_include_paths: []const []const u8,...@@ -103,16 +103,12 @@ native_system_include_paths: []const []const u8,
103/// Corresponds to `-u <symbol>` for ELF/MachO and `/include:<symbol>` for COFF/PE.103/// Corresponds to `-u <symbol>` for ELF/MachO and `/include:<symbol>` for COFF/PE.
104force_undefined_symbols: std.array_hash_map.String(void),104force_undefined_symbols: std.array_hash_map.String(void),
105105
106c_object_table: std.array_hash_map.Auto(*CObject, void) = .empty,106c_objects: std.ArrayList(*CObject) = .empty,
107win32_resource_table: if (dev.env.supports(.win32_resource)) std.array_hash_map.Auto(*Win32Resource, void) else struct {107win32_resources: if (dev.env.supports(.win32_resource)) std.ArrayList(*Win32Resource) else struct {
108 pub fn keys(_: @This()) [0]void {108 items: [0]*struct {},
109 return .{};109 pub const empty: @This() = .{ .items = .{} };
110 }
111 pub fn count(_: @This()) u0 {
112 return 0;
113 }
114 pub fn deinit(_: @This(), _: Allocator) void {}110 pub fn deinit(_: @This(), _: Allocator) void {}
115} = .{},111} = .empty,
116112
117link_diags: link.Diags,113link_diags: link.Diags,
118link_queue: link.Queue = .empty,114link_queue: link.Queue = .empty,
...@@ -915,21 +911,6 @@ pub const CrtFile = struct {...@@ -915,21 +911,6 @@ pub const CrtFile = struct {
915 }911 }
916};912};
917913
918/// Supported languages for "zig clang -x <lang>".
919/// Loosely based on llvm-project/clang/include/clang/Driver/Types.def
920pub const LangToExt = std.StaticStringMap(FileExt).initComptime(.{
921 .{ "c", .c },
922 .{ "c-header", .h },
923 .{ "c++", .cpp },
924 .{ "c++-header", .hpp },
925 .{ "objective-c", .m },
926 .{ "objective-c-header", .hm },
927 .{ "objective-c++", .mm },
928 .{ "objective-c++-header", .hmm },
929 .{ "assembler", .assembly },
930 .{ "assembler-with-cpp", .assembly_with_cpp },
931});
932
933/// For passing to a C compiler.914/// For passing to a C compiler.
934pub const CSourceFile = struct {915pub const CSourceFile = struct {
935 /// Many C compiler flags are determined by settings contained in the owning Module.916 /// Many C compiler flags are determined by settings contained in the owning Module.
...@@ -2486,8 +2467,10 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,...@@ -2486,8 +2467,10 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
2486 };2467 };
2487 errdefer comp.destroy();2468 errdefer comp.destroy();
24882469
2470 if (target.ofmt == .c) return comp;
2471
2489 // Add a `CObject` for each `c_source_files`.2472 // Add a `CObject` for each `c_source_files`.
2490 try comp.c_object_table.ensureTotalCapacity(gpa, options.c_source_files.len);2473 try comp.c_objects.ensureTotalCapacity(gpa, options.c_source_files.len);
2491 for (options.c_source_files) |c_source_file| {2474 for (options.c_source_files) |c_source_file| {
2492 const c_object = try gpa.create(CObject);2475 const c_object = try gpa.create(CObject);
2493 errdefer gpa.destroy(c_object);2476 errdefer gpa.destroy(c_object);
...@@ -2496,7 +2479,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,...@@ -2496,7 +2479,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
2496 .status = .{ .new = {} },2479 .status = .{ .new = {} },
2497 .src = c_source_file,2480 .src = c_source_file,
2498 };2481 };
2499 comp.c_object_table.putAssumeCapacityNoClobber(c_object, {});2482 comp.c_objects.appendAssumeCapacity(c_object);
2500 }2483 }
25012484
2502 // Add a `Win32Resource` for each `rc_source_files` and one for `manifest_file`.2485 // Add a `Win32Resource` for each `rc_source_files` and one for `manifest_file`.
...@@ -2504,7 +2487,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,...@@ -2504,7 +2487,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
2504 options.rc_source_files.len + @intFromBool(options.manifest_file != null);2487 options.rc_source_files.len + @intFromBool(options.manifest_file != null);
2505 if (win32_resource_count > 0) {2488 if (win32_resource_count > 0) {
2506 dev.check(.win32_resource);2489 dev.check(.win32_resource);
2507 try comp.win32_resource_table.ensureTotalCapacity(gpa, win32_resource_count);2490 try comp.win32_resources.ensureTotalCapacity(gpa, win32_resource_count);
2508 for (options.rc_source_files) |rc_source_file| {2491 for (options.rc_source_files) |rc_source_file| {
2509 const win32_resource = try gpa.create(Win32Resource);2492 const win32_resource = try gpa.create(Win32Resource);
2510 errdefer gpa.destroy(win32_resource);2493 errdefer gpa.destroy(win32_resource);
...@@ -2513,7 +2496,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,...@@ -2513,7 +2496,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
2513 .status = .{ .new = {} },2496 .status = .{ .new = {} },
2514 .src = .{ .rc = rc_source_file },2497 .src = .{ .rc = rc_source_file },
2515 };2498 };
2516 comp.win32_resource_table.putAssumeCapacityNoClobber(win32_resource, {});2499 comp.win32_resources.appendAssumeCapacity(win32_resource);
2517 }2500 }
25182501
2519 if (options.manifest_file) |manifest_path| {2502 if (options.manifest_file) |manifest_path| {
...@@ -2524,11 +2507,11 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,...@@ -2524,11 +2507,11 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
2524 .status = .{ .new = {} },2507 .status = .{ .new = {} },
2525 .src = .{ .manifest = manifest_path },2508 .src = .{ .manifest = manifest_path },
2526 };2509 };
2527 comp.win32_resource_table.putAssumeCapacityNoClobber(win32_resource, {});2510 comp.win32_resources.appendAssumeCapacity(win32_resource);
2528 }2511 }
2529 }2512 }
25302513
2531 if (comp.emit_bin != null and target.ofmt != .c) {2514 if (comp.emit_bin != null) {
2532 if (!comp.skip_linker_dependencies) {2515 if (!comp.skip_linker_dependencies) {
2533 // If we need to build libc for the target, add work items for it.2516 // If we need to build libc for the target, add work items for it.
2534 // We go through the work queue so that building can be done in parallel.2517 // We go through the work queue so that building can be done in parallel.
...@@ -2749,20 +2732,20 @@ pub fn destroy(comp: *Compilation) void {...@@ -2749,20 +2732,20 @@ pub fn destroy(comp: *Compilation) void {
2749 openbsd_file.deinit(gpa, io);2732 openbsd_file.deinit(gpa, io);
2750 }2733 }
27512734
2752 for (comp.c_object_table.keys()) |key| {2735 for (comp.c_objects.items) |c_object| {
2753 key.destroy(gpa, io);2736 c_object.destroy(gpa, io);
2754 }2737 }
2755 comp.c_object_table.deinit(gpa);2738 comp.c_objects.deinit(gpa);
27562739
2757 for (comp.failed_c_objects.values()) |bundle| {2740 for (comp.failed_c_objects.values()) |bundle| {
2758 bundle.destroy(gpa);2741 bundle.destroy(gpa);
2759 }2742 }
2760 comp.failed_c_objects.deinit(gpa);2743 comp.failed_c_objects.deinit(gpa);
27612744
2762 for (comp.win32_resource_table.keys()) |key| {2745 for (comp.win32_resources.items) |win32_resource| {
2763 key.destroy(gpa, io);2746 win32_resource.destroy(gpa, io);
2764 }2747 }
2765 comp.win32_resource_table.deinit(gpa);2748 comp.win32_resources.deinit(gpa);
27662749
2767 for (comp.failed_win32_resources.values()) |*value| {2750 for (comp.failed_win32_resources.values()) |*value| {
2768 value.deinit(gpa);2751 value.deinit(gpa);
...@@ -3016,8 +2999,8 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE...@@ -3016,8 +2999,8 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
3016 // changes. For now, to avoid crashing the linker in this case, don't kick off C object2999 // changes. For now, to avoid crashing the linker in this case, don't kick off C object
3017 // updates if we've done prelink already. https://codeberg.org/ziglang/zig/issues/320813000 // updates if we've done prelink already. https://codeberg.org/ziglang/zig/issues/32081
3018 } else {3001 } else {
3019 try comp.c_object_work_queue.ensureUnusedCapacity(gpa, comp.c_object_table.count());3002 try comp.c_object_work_queue.ensureUnusedCapacity(gpa, comp.c_objects.items.len);
3020 for (comp.c_object_table.keys()) |c_object| {3003 for (comp.c_objects.items) |c_object| {
3021 comp.c_object_work_queue.pushBackAssumeCapacity(c_object);3004 comp.c_object_work_queue.pushBackAssumeCapacity(c_object);
3022 try comp.appendFileSystemInput(try .fromUnresolved(arena, comp.dirs, &.{c_object.src.src_path}));3005 try comp.appendFileSystemInput(try .fromUnresolved(arena, comp.dirs, &.{c_object.src.src_path}));
3023 }3006 }
...@@ -3032,8 +3015,8 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE...@@ -3032,8 +3015,8 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
30323015
3033 // For compiling Win32 resources, we rely on the cache hash system to avoid duplicating work.3016 // For compiling Win32 resources, we rely on the cache hash system to avoid duplicating work.
3034 // Add a Job for each Win32 resource file.3017 // Add a Job for each Win32 resource file.
3035 try comp.win32_resource_work_queue.ensureUnusedCapacity(gpa, comp.win32_resource_table.count());3018 try comp.win32_resource_work_queue.ensureUnusedCapacity(gpa, comp.win32_resources.items.len);
3036 for (comp.win32_resource_table.keys()) |win32_resource| {3019 for (comp.win32_resources.items) |win32_resource| {
3037 comp.win32_resource_work_queue.pushBackAssumeCapacity(win32_resource);3020 comp.win32_resource_work_queue.pushBackAssumeCapacity(win32_resource);
3038 switch (win32_resource.src) {3021 switch (win32_resource.src) {
3039 .rc => |f| {3022 .rc => |f| {
...@@ -3140,9 +3123,9 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE...@@ -3140,9 +3123,9 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
3140 return;3123 return;
3141 }3124 }
31423125
3143 if (comp.zcu == null and comp.config.output_mode == .Obj and comp.c_object_table.count() == 1) {3126 if (comp.zcu == null and comp.config.output_mode == .Obj and comp.c_objects.items.len == 1) {
3144 // This is `zig build-obj foo.c`. We can emit asm and LLVM IR/bitcode.3127 // This is `zig build-obj foo.c`. We can emit asm and LLVM IR/bitcode.
3145 const c_obj_path = comp.c_object_table.keys()[0].status.success.object_path;3128 const c_obj_path = comp.c_objects.items[0].status.success.object_path;
3146 if (comp.emit_asm) |path| try comp.emitFromCObject(arena, c_obj_path, ".s", path);3129 if (comp.emit_asm) |path| try comp.emitFromCObject(arena, c_obj_path, ".s", path);
3147 if (comp.emit_llvm_ir) |path| try comp.emitFromCObject(arena, c_obj_path, ".ll", path);3130 if (comp.emit_llvm_ir) |path| try comp.emitFromCObject(arena, c_obj_path, ".ll", path);
3148 if (comp.emit_llvm_bc) |path| try comp.emitFromCObject(arena, c_obj_path, ".bc", path);3131 if (comp.emit_llvm_bc) |path| try comp.emitFromCObject(arena, c_obj_path, ".bc", path);
...@@ -3482,14 +3465,14 @@ fn addNonIncrementalStuffToCacheManifest(...@@ -3482,14 +3465,14 @@ fn addNonIncrementalStuffToCacheManifest(
34823465
3483 try link.hashInputs(man, comp.link_inputs);3466 try link.hashInputs(man, comp.link_inputs);
34843467
3485 for (comp.c_object_table.keys()) |key| {3468 for (comp.c_objects.items) |c_object| {
3486 _ = try man.addFile(key.src.src_path, null);3469 _ = try man.addFile(c_object.src.src_path, null);
3487 man.hash.addOptional(key.src.ext);3470 man.hash.addOptional(c_object.src.ext);
3488 man.hash.addListOfBytes(key.src.extra_flags);3471 man.hash.addListOfBytes(c_object.src.extra_flags);
3489 }3472 }
34903473
3491 for (comp.win32_resource_table.keys()) |key| {3474 for (comp.win32_resources.items) |win32_resource| {
3492 switch (key.src) {3475 switch (win32_resource.src) {
3493 .rc => |rc_src| {3476 .rc => |rc_src| {
3494 _ = try man.addFile(rc_src.src_path, null);3477 _ = try man.addFile(rc_src.src_path, null);
3495 man.hash.addListOfBytes(rc_src.extra_flags);3478 man.hash.addListOfBytes(rc_src.extra_flags);
...@@ -5592,9 +5575,10 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr...@@ -5592,9 +5575,10 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
5592 c_source_basename[0 .. c_source_basename.len - fs.path.extension(c_source_basename).len];5575 c_source_basename[0 .. c_source_basename.len - fs.path.extension(c_source_basename).len];
55935576
5594 const target = comp.getTarget();5577 const target = comp.getTarget();
5578 assert(target.ofmt != .c);
5595 const o_ext = target.ofmt.fileExt(target.cpu.arch);5579 const o_ext = target.ofmt.fileExt(target.cpu.arch);
5596 const digest = if (!comp.disable_c_depfile and try man.hit()) man.final() else blk: {5580 const digest = if (!comp.disable_c_depfile and try man.hit()) man.final() else blk: {
5597 var argv = std.array_list.Managed([]const u8).init(gpa);5581 var argv: std.array_list.Managed([]const u8) = .init(gpa);
5598 defer argv.deinit();5582 defer argv.deinit();
55995583
5600 // In case we are doing passthrough mode, we need to detect -S and -emit-llvm.5584 // In case we are doing passthrough mode, we need to detect -S and -emit-llvm.
...@@ -7057,6 +7041,33 @@ pub const FileExt = enum {...@@ -7057,6 +7041,33 @@ pub const FileExt = enum {
7057 .unknown => "",7041 .unknown => "",
7058 };7042 };
7059 }7043 }
7044
7045 /// The value accepted by "zig clang -x <lang>" and passed to "clang -x <lang>".
7046 pub fn toLang(ext: FileExt) ?[]const u8 {
7047 return switch (ext) {
7048 else => null,
7049 .c => "c",
7050 .h => "c-header",
7051 .cpp => "c++",
7052 .hpp => "c++-header",
7053 .m => "objective-c",
7054 .hm => "objective-c-header",
7055 .mm => "objective-c++",
7056 .hmm => "objective-c++-header",
7057 .assembly => "assembler",
7058 .assembly_with_cpp => "assembler-with-cpp",
7059 };
7060 }
7061
7062 /// Supported languages for "zig clang -x <lang>".
7063 /// Loosely based on llvm-project/clang/include/clang/Driver/Types.def
7064 pub const from_lang = std.StaticStringMap(FileExt).initComptime(init: {
7065 var init: []const struct { []const u8, FileExt } = &.{};
7066 for (std.enums.values(FileExt)) |file_ext| if (file_ext.toLang()) |lang| {
7067 init = init ++ .{.{ lang, file_ext }};
7068 };
7069 break :init init;
7070 });
7060};7071};
70617072
7062pub fn hasObjectExt(filename: []const u8) bool {7073pub fn hasObjectExt(filename: []const u8) bool {
src/codegen/c.zig+4-1
...@@ -328,6 +328,9 @@ fn isReservedIdent(ident: []const u8) bool {...@@ -328,6 +328,9 @@ fn isReservedIdent(ident: []const u8) bool {
328 return true;328 return true;
329 }329 }
330330
331 // zig.h
332 if (mem.startsWith(u8, ident, "zig_")) return true;
333
331 return reserved_idents.has(ident);334 return reserved_idents.has(ident);
332}335}
333336
...@@ -3755,7 +3758,7 @@ fn airCmpLteErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3755,7 +3758,7 @@ fn airCmpLteErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
3755 try f.writeCValue(w, local, .other);3758 try f.writeCValue(w, local, .other);
3756 try w.writeAll(" = ");3759 try w.writeAll(" = ");
3757 try f.writeCValue(w, operand, .other);3760 try f.writeCValue(w, operand, .other);
3758 try w.print(" < sizeof({f}) / sizeof(*{0f});", .{fmtIdentSolo("zig_errorName")});3761 try w.writeAll(" < sizeof(zig_errorName) / sizeof(*zig_errorName);");
3759 try f.newline();3762 try f.newline();
3760 return local;3763 return local;
3761}3764}
src/link.zig+2-2
...@@ -933,8 +933,8 @@ pub const File = struct {...@@ -933,8 +933,8 @@ pub const File = struct {
933 // Until then, we do `lld -r -o output.o input.o` even though the output is the same933 // Until then, we do `lld -r -o output.o input.o` even though the output is the same
934 // as the input. For the preprocessing case (`zig cc -E -o foo`) we copy the file934 // as the input. For the preprocessing case (`zig cc -E -o foo`) we copy the file
935 // to the final location. See also the corresponding TODO in Coff linking.935 // to the final location. See also the corresponding TODO in Coff linking.
936 assert(comp.c_object_table.count() == 1);936 assert(comp.c_objects.items.len == 1);
937 const the_key = comp.c_object_table.keys()[0];937 const the_key = comp.c_objects.items[0];
938 const cached_pp_file_path = the_key.status.success.object_path;938 const cached_pp_file_path = the_key.status.success.object_path;
939 Io.Dir.copyFile(939 Io.Dir.copyFile(
940 cached_pp_file_path.root_dir.handle,940 cached_pp_file_path.root_dir.handle,
src/link/Lld.zig+20-20
...@@ -313,14 +313,14 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void {...@@ -313,14 +313,14 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void {
313 object_files.appendAssumeCapacity(try input.path().?.toStringZ(arena));313 object_files.appendAssumeCapacity(try input.path().?.toStringZ(arena));
314 }314 }
315315
316 try object_files.ensureUnusedCapacity(arena, comp.c_object_table.count() +316 try object_files.ensureUnusedCapacity(arena, comp.c_objects.items.len +
317 comp.win32_resource_table.count() + 2);317 comp.win32_resources.items.len + 2);
318318
319 for (comp.c_object_table.keys()) |key| {319 for (comp.c_objects.items) |c_object| {
320 object_files.appendAssumeCapacity(try key.status.success.object_path.toStringZ(arena));320 object_files.appendAssumeCapacity(try c_object.status.success.object_path.toStringZ(arena));
321 }321 }
322 for (comp.win32_resource_table.keys()) |key| {322 for (comp.win32_resources.items) |win32_resource| {
323 object_files.appendAssumeCapacity(try arena.dupeSentinel(u8, key.status.success.res_path, 0));323 object_files.appendAssumeCapacity(try arena.dupeSentinel(u8, win32_resource.status.success.res_path, 0));
324 }324 }
325 if (zcu_obj_path) |p| object_files.appendAssumeCapacity(try p.toStringZ(arena));325 if (zcu_obj_path) |p| object_files.appendAssumeCapacity(try p.toStringZ(arena));
326 if (compiler_rt_path) |p| object_files.appendAssumeCapacity(try p.toStringZ(arena));326 if (compiler_rt_path) |p| object_files.appendAssumeCapacity(try p.toStringZ(arena));
...@@ -395,8 +395,8 @@ fn coffLink(lld: *Lld, arena: Allocator) !void {...@@ -395,8 +395,8 @@ fn coffLink(lld: *Lld, arena: Allocator) !void {
395 const the_object_path = blk: {395 const the_object_path = blk: {
396 if (link.firstObjectInput(comp.link_inputs)) |obj| break :blk obj.path;396 if (link.firstObjectInput(comp.link_inputs)) |obj| break :blk obj.path;
397397
398 if (comp.c_object_table.count() != 0)398 if (comp.c_objects.items.len != 0)
399 break :blk comp.c_object_table.keys()[0].status.success.object_path;399 break :blk comp.c_objects.items[0].status.success.object_path;
400400
401 if (zcu_obj_path) |p|401 if (zcu_obj_path) |p|
402 break :blk p;402 break :blk p;
...@@ -546,12 +546,12 @@ fn coffLink(lld: *Lld, arena: Allocator) !void {...@@ -546,12 +546,12 @@ fn coffLink(lld: *Lld, arena: Allocator) !void {
546 },546 },
547 };547 };
548548
549 for (comp.c_object_table.keys()) |key| {549 for (comp.c_objects.items) |c_object| {
550 try argv.append(try key.status.success.object_path.toString(arena));550 try argv.append(try c_object.status.success.object_path.toString(arena));
551 }551 }
552552
553 for (comp.win32_resource_table.keys()) |key| {553 for (comp.win32_resources.items) |win32_resource| {
554 try argv.append(key.status.success.res_path);554 try argv.append(win32_resource.status.success.res_path);
555 }555 }
556556
557 if (zcu_obj_path) |p| {557 if (zcu_obj_path) |p| {
...@@ -805,8 +805,8 @@ fn elfLink(lld: *Lld, arena: Allocator) !void {...@@ -805,8 +805,8 @@ fn elfLink(lld: *Lld, arena: Allocator) !void {
805 const the_object_path = blk: {805 const the_object_path = blk: {
806 if (link.firstObjectInput(comp.link_inputs)) |obj| break :blk obj.path;806 if (link.firstObjectInput(comp.link_inputs)) |obj| break :blk obj.path;
807807
808 if (comp.c_object_table.count() != 0)808 if (comp.c_objects.items.len != 0)
809 break :blk comp.c_object_table.keys()[0].status.success.object_path;809 break :blk comp.c_objects.items[0].status.success.object_path;
810810
811 if (zcu_obj_path) |p|811 if (zcu_obj_path) |p|
812 break :blk p;812 break :blk p;
...@@ -1099,8 +1099,8 @@ fn elfLink(lld: *Lld, arena: Allocator) !void {...@@ -1099,8 +1099,8 @@ fn elfLink(lld: *Lld, arena: Allocator) !void {
1099 whole_archive = false;1099 whole_archive = false;
1100 }1100 }
11011101
1102 for (comp.c_object_table.keys()) |key| {1102 for (comp.c_objects.items) |c_object| {
1103 try argv.append(try key.status.success.object_path.toString(arena));1103 try argv.append(try c_object.status.success.object_path.toString(arena));
1104 }1104 }
11051105
1106 if (zcu_obj_path) |p| {1106 if (zcu_obj_path) |p| {
...@@ -1381,8 +1381,8 @@ fn wasmLink(lld: *Lld, arena: Allocator) !void {...@@ -1381,8 +1381,8 @@ fn wasmLink(lld: *Lld, arena: Allocator) !void {
1381 const the_object_path = blk: {1381 const the_object_path = blk: {
1382 if (link.firstObjectInput(comp.link_inputs)) |obj| break :blk obj.path;1382 if (link.firstObjectInput(comp.link_inputs)) |obj| break :blk obj.path;
13831383
1384 if (comp.c_object_table.count() != 0)1384 if (comp.c_objects.items.len != 0)
1385 break :blk comp.c_object_table.keys()[0].status.success.object_path;1385 break :blk comp.c_objects.items[0].status.success.object_path;
13861386
1387 if (zcu_obj_path) |p|1387 if (zcu_obj_path) |p|
1388 break :blk p;1388 break :blk p;
...@@ -1566,8 +1566,8 @@ fn wasmLink(lld: *Lld, arena: Allocator) !void {...@@ -1566,8 +1566,8 @@ fn wasmLink(lld: *Lld, arena: Allocator) !void {
1566 whole_archive = false;1566 whole_archive = false;
1567 }1567 }
15681568
1569 for (comp.c_object_table.keys()) |key| {1569 for (comp.c_objects.items) |c_object| {
1570 try argv.append(try key.status.success.object_path.toString(arena));1570 try argv.append(try c_object.status.success.object_path.toString(arena));
1571 }1571 }
1572 if (zcu_obj_path) |p| {1572 if (zcu_obj_path) |p| {
1573 try argv.append(try p.toString(arena));1573 try argv.append(try p.toString(arena));
src/link/MachO.zig+7-7
...@@ -377,9 +377,9 @@ pub fn flush(...@@ -377,9 +377,9 @@ pub fn flush(
377 // This is a set of object files emitted by clang in a single `build-exe` invocation.377 // This is a set of object files emitted by clang in a single `build-exe` invocation.
378 // For instance, the implicit `a.o` as compiled by `zig build-exe a.c` will end up378 // For instance, the implicit `a.o` as compiled by `zig build-exe a.c` will end up
379 // in this set.379 // in this set.
380 try positionals.ensureUnusedCapacity(comp.c_object_table.keys().len);380 try positionals.ensureUnusedCapacity(comp.c_objects.items.len);
381 for (comp.c_object_table.keys()) |key| {381 for (comp.c_objects.items) |c_object| {
382 positionals.appendAssumeCapacity(try link.openObjectInput(io, diags, key.status.success.object_path));382 positionals.appendAssumeCapacity(try link.openObjectInput(io, diags, c_object.status.success.object_path));
383 }383 }
384384
385 if (zcu_obj_path) |path| try positionals.append(try link.openObjectInput(io, diags, path));385 if (zcu_obj_path) |path| try positionals.append(try link.openObjectInput(io, diags, path));
...@@ -657,8 +657,8 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {...@@ -657,8 +657,8 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {
657 .dso_exact => |dso_exact| try argv.appendSlice(&.{ "-l", dso_exact.name }),657 .dso_exact => |dso_exact| try argv.appendSlice(&.{ "-l", dso_exact.name }),
658 };658 };
659659
660 for (comp.c_object_table.keys()) |key| {660 for (comp.c_objects.items) |c_object| {
661 try argv.append(try key.status.success.object_path.toString(arena));661 try argv.append(try c_object.status.success.object_path.toString(arena));
662 }662 }
663663
664 if (zcu_obj_path) |p| {664 if (zcu_obj_path) |p| {
...@@ -749,8 +749,8 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {...@@ -749,8 +749,8 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {
749 .dso_exact => |dso_exact| try argv.appendSlice(&.{ "-l", dso_exact.name }),749 .dso_exact => |dso_exact| try argv.appendSlice(&.{ "-l", dso_exact.name }),
750 };750 };
751751
752 for (comp.c_object_table.keys()) |key| {752 for (comp.c_objects.items) |c_object| {
753 try argv.append(try key.status.success.object_path.toString(arena));753 try argv.append(try c_object.status.success.object_path.toString(arena));
754 }754 }
755755
756 if (zcu_obj_path) |p| {756 if (zcu_obj_path) |p| {
src/link/MachO/relocatable.zig+4-4
...@@ -9,8 +9,8 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat...@@ -9,8 +9,8 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat
9 try positionals.ensureUnusedCapacity(comp.link_inputs.len);9 try positionals.ensureUnusedCapacity(comp.link_inputs.len);
10 positionals.appendSliceAssumeCapacity(comp.link_inputs);10 positionals.appendSliceAssumeCapacity(comp.link_inputs);
1111
12 for (comp.c_object_table.keys()) |key| {12 for (comp.c_objects.items) |c_object| {
13 try positionals.append(try link.openObjectInput(io, diags, key.status.success.object_path));13 try positionals.append(try link.openObjectInput(io, diags, c_object.status.success.object_path));
14 }14 }
1515
16 if (module_obj_path) |path| try positionals.append(try link.openObjectInput(io, diags, path));16 if (module_obj_path) |path| try positionals.append(try link.openObjectInput(io, diags, path));
...@@ -86,8 +86,8 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?...@@ -86,8 +86,8 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
86 try positionals.ensureUnusedCapacity(comp.link_inputs.len);86 try positionals.ensureUnusedCapacity(comp.link_inputs.len);
87 positionals.appendSliceAssumeCapacity(comp.link_inputs);87 positionals.appendSliceAssumeCapacity(comp.link_inputs);
8888
89 for (comp.c_object_table.keys()) |key| {89 for (comp.c_objects.items) |c_object| {
90 try positionals.append(try link.openObjectInput(io, diags, key.status.success.object_path));90 try positionals.append(try link.openObjectInput(io, diags, c_object.status.success.object_path));
91 }91 }
9292
93 if (module_obj_path) |path| try positionals.append(try link.openObjectInput(io, diags, path));93 if (module_obj_path) |path| try positionals.append(try link.openObjectInput(io, diags, path));
src/main.zig+70-28
...@@ -887,6 +887,7 @@ const CliModule = struct {...@@ -887,6 +887,7 @@ const CliModule = struct {
887 inherited: Package.Module.CreateOptions.Inherited,887 inherited: Package.Module.CreateOptions.Inherited,
888 target_arch_os_abi: ?[]const u8,888 target_arch_os_abi: ?[]const u8,
889 target_mcpu: ?[]const u8,889 target_mcpu: ?[]const u8,
890 dynamic_linker: ?[]const u8,
890891
891 deps: []const Dep,892 deps: []const Dep,
892 resolved: ?*Package.Module,893 resolved: ?*Package.Module,
...@@ -943,6 +944,7 @@ fn buildOutputType(...@@ -943,6 +944,7 @@ fn buildOutputType(
943 var emit_implib_arg_provided = false;944 var emit_implib_arg_provided = false;
944 var target_arch_os_abi: ?[]const u8 = null;945 var target_arch_os_abi: ?[]const u8 = null;
945 var target_mcpu: ?[]const u8 = null;946 var target_mcpu: ?[]const u8 = null;
947 var dynamic_linker: ?[]const u8 = null;
946 var emit_h: Emit = .no;948 var emit_h: Emit = .no;
947 var soname: SOName = undefined;949 var soname: SOName = undefined;
948 var want_compiler_rt: ?bool = null;950 var want_compiler_rt: ?bool = null;
...@@ -1059,7 +1061,6 @@ fn buildOutputType(...@@ -1059,7 +1061,6 @@ fn buildOutputType(
1059 // Populated just before the call to `createModule`.1061 // Populated just before the call to `createModule`.
1060 .dirs = undefined,1062 .dirs = undefined,
1061 .object_format = null,1063 .object_format = null,
1062 .dynamic_linker = null,
1063 .modules = .empty,1064 .modules = .empty,
1064 .opts = .{1065 .opts = .{
1065 .is_test = switch (arg_mode) {1066 .is_test = switch (arg_mode) {
...@@ -1179,6 +1180,7 @@ fn buildOutputType(...@@ -1179,6 +1180,7 @@ fn buildOutputType(
1179 &cc_argv,1180 &cc_argv,
1180 &target_arch_os_abi,1181 &target_arch_os_abi,
1181 &target_mcpu,1182 &target_mcpu,
1183 &dynamic_linker,
1182 &deps,1184 &deps,
1183 &c_source_files_owner_index,1185 &c_source_files_owner_index,
1184 &rc_source_files_owner_index,1186 &rc_source_files_owner_index,
...@@ -1397,9 +1399,9 @@ fn buildOutputType(...@@ -1397,9 +1399,9 @@ fn buildOutputType(
1397 } else if (mem.cutPrefix(u8, arg, "-O")) |rest| {1399 } else if (mem.cutPrefix(u8, arg, "-O")) |rest| {
1398 mod_opts.optimize_mode = parseOptimizeMode(rest);1400 mod_opts.optimize_mode = parseOptimizeMode(rest);
1399 } else if (mem.eql(u8, arg, "--dynamic-linker")) {1401 } else if (mem.eql(u8, arg, "--dynamic-linker")) {
1400 create_module.dynamic_linker = args_iter.nextOrFatal();1402 dynamic_linker = args_iter.nextOrFatal();
1401 } else if (mem.eql(u8, arg, "--no-dynamic-linker")) {1403 } else if (mem.eql(u8, arg, "--no-dynamic-linker")) {
1402 create_module.dynamic_linker = "";1404 dynamic_linker = "";
1403 } else if (mem.eql(u8, arg, "--sysroot")) {1405 } else if (mem.eql(u8, arg, "--sysroot")) {
1404 const next_arg = args_iter.nextOrFatal();1406 const next_arg = args_iter.nextOrFatal();
1405 create_module.sysroot = next_arg;1407 create_module.sysroot = next_arg;
...@@ -1846,7 +1848,7 @@ fn buildOutputType(...@@ -1846,7 +1848,7 @@ fn buildOutputType(
1846 const lang = if (rest.len == 0) args_iter.nextOrFatal() else rest;1848 const lang = if (rest.len == 0) args_iter.nextOrFatal() else rest;
1847 if (mem.eql(u8, lang, "none")) {1849 if (mem.eql(u8, lang, "none")) {
1848 file_ext = null;1850 file_ext = null;
1849 } else if (Compilation.LangToExt.get(lang)) |got_ext| {1851 } else if (Compilation.FileExt.from_lang.get(lang)) |got_ext| {
1850 file_ext = got_ext;1852 file_ext = got_ext;
1851 } else {1853 } else {
1852 fatal("language not recognized: {s}", .{lang});1854 fatal("language not recognized: {s}", .{lang});
...@@ -1983,7 +1985,7 @@ fn buildOutputType(...@@ -1983,7 +1985,7 @@ fn buildOutputType(
1983 const lang = mem.sliceTo(it.only_arg, 0);1985 const lang = mem.sliceTo(it.only_arg, 0);
1984 if (mem.eql(u8, lang, "none")) {1986 if (mem.eql(u8, lang, "none")) {
1985 file_ext = null;1987 file_ext = null;
1986 } else if (Compilation.LangToExt.get(lang)) |got_ext| {1988 } else if (Compilation.FileExt.from_lang.get(lang)) |got_ext| {
1987 file_ext = got_ext;1989 file_ext = got_ext;
1988 } else {1990 } else {
1989 fatal("language not recognized: {q}", .{lang});1991 fatal("language not recognized: {q}", .{lang});
...@@ -2610,12 +2612,11 @@ fn buildOutputType(...@@ -2610,12 +2612,11 @@ fn buildOutputType(
2610 mem.eql(u8, arg, "--dynamic-linker") or2612 mem.eql(u8, arg, "--dynamic-linker") or
2611 mem.eql(u8, arg, "-dynamic-linker"))2613 mem.eql(u8, arg, "-dynamic-linker"))
2612 {2614 {
2613 create_module.dynamic_linker = linker_args_it.nextOrFatal();2615 dynamic_linker = linker_args_it.nextOrFatal();
2614 } else if (mem.eql(u8, arg, "-I") or2616 } else if (mem.eql(u8, arg, "--no-dynamic-linker") or
2615 mem.eql(u8, arg, "--no-dynamic-linker") or
2616 mem.eql(u8, arg, "-no-dynamic-linker"))2617 mem.eql(u8, arg, "-no-dynamic-linker"))
2617 {2618 {
2618 create_module.dynamic_linker = "";2619 dynamic_linker = "";
2619 } else if (mem.eql(u8, arg, "-E") or2620 } else if (mem.eql(u8, arg, "-E") or
2620 mem.eql(u8, arg, "--export-dynamic") or2621 mem.eql(u8, arg, "--export-dynamic") or
2621 mem.eql(u8, arg, "-export-dynamic"))2622 mem.eql(u8, arg, "-export-dynamic"))
...@@ -3184,6 +3185,7 @@ fn buildOutputType(...@@ -3184,6 +3185,7 @@ fn buildOutputType(
3184 .inherited = mod_opts,3185 .inherited = mod_opts,
3185 .target_arch_os_abi = target_arch_os_abi,3186 .target_arch_os_abi = target_arch_os_abi,
3186 .target_mcpu = target_mcpu,3187 .target_mcpu = target_mcpu,
3188 .dynamic_linker = dynamic_linker,
3187 .deps = try deps.toOwnedSlice(arena),3189 .deps = try deps.toOwnedSlice(arena),
3188 .resolved = null,3190 .resolved = null,
3189 .c_source_files_start = c_source_files_owner_index,3191 .c_source_files_start = c_source_files_owner_index,
...@@ -3842,10 +3844,59 @@ fn buildOutputType(...@@ -3842,10 +3844,59 @@ fn buildOutputType(
3842 if (test_exec_args.items.len == 0 and target.ofmt == .c and emit_bin_resolved != .no) {3844 if (test_exec_args.items.len == 0 and target.ofmt == .c and emit_bin_resolved != .no) {
3843 // Default to using `zig run` to execute the produced .c code from `zig test`.3845 // Default to using `zig run` to execute the produced .c code from `zig test`.
3844 try test_exec_args.appendSlice(arena, &.{ self_exe_path, "run" });3846 try test_exec_args.appendSlice(arena, &.{ self_exe_path, "run" });
3845 if (dirs.zig_lib.path) |p| {3847 // Skip passing `-ofmt`, we want the default for the target, not `.c` anymore.
3846 try test_exec_args.appendSlice(arena, &.{ "-I", p });3848
3849 var prev_has_cflags = false;
3850 var prev_has_rcflags = false;
3851 if (dirs.zig_lib.path) |zig_lib_path| {
3852 try test_exec_args.appendSlice(arena, &.{ "-cflags", "-I", zig_lib_path, "--" });
3853 prev_has_cflags = true;
3854 }
3855 try test_exec_args.append(arena, null);
3856 for (create_module.modules.keys(), create_module.modules.values()) |mod_name, mod| {
3857 for (create_module.c_source_files.items[mod.c_source_files_start..mod.c_source_files_end]) |c_source_file| {
3858 const cflags_len = c_source_file.extra_flags.len + c_source_file.cache_exempt_flags.len;
3859 if (prev_has_cflags or cflags_len > 0) {
3860 try test_exec_args.ensureUnusedCapacity(arena, 1 + cflags_len + 1);
3861 test_exec_args.appendAssumeCapacity("-cflags");
3862 for (c_source_file.extra_flags) |extra_flag| test_exec_args.appendAssumeCapacity(extra_flag);
3863 for (c_source_file.cache_exempt_flags) |cache_exempt_flag| test_exec_args.appendAssumeCapacity(cache_exempt_flag);
3864 test_exec_args.appendAssumeCapacity("--");
3865 }
3866 prev_has_cflags = cflags_len > 0;
3867 if (c_source_file.ext) |ext| try test_exec_args.appendSlice(arena, &.{ "-x", ext.toLang() });
3868 try test_exec_args.append(arena, c_source_file.src_path);
3869 if (c_source_file.ext) |_| try test_exec_args.appendSlice(arena, &.{ "-x", "none" });
3870 }
3871 for (create_module.rc_source_files.items[mod.rc_source_files_start..mod.rc_source_files_end]) |rc_source_file| {
3872 const rcflags_len = rc_source_file.extra_flags.len;
3873 if (prev_has_rcflags or rcflags_len > 0) {
3874 try test_exec_args.ensureUnusedCapacity(arena, 1 + rcflags_len + 1);
3875 test_exec_args.appendAssumeCapacity("-rcflags");
3876 for (rc_source_file.extra_flags) |extra_flag| test_exec_args.appendAssumeCapacity(extra_flag);
3877 test_exec_args.appendAssumeCapacity("--");
3878 }
3879 prev_has_rcflags = rcflags_len > 0;
3880 try test_exec_args.append(arena, rc_source_file.src_path);
3881 }
3882 if (mod.target_arch_os_abi) |triple| try test_exec_args.appendSlice(arena, &.{ "-target", triple });
3883 if (mod.target_mcpu) |mcpu| try test_exec_args.appendSlice(arena, &.{ "-mcpu", mcpu });
3884 if (mod.dynamic_linker) |dl| if (dl.len > 0)
3885 try test_exec_args.appendSlice(arena, &.{ "--dynamic-linker", dl })
3886 else
3887 try test_exec_args.append(arena, "--no-dynamic-linker");
3888 try test_exec_args.ensureUnusedCapacity(arena, mod.cc_argv.len);
3889 for (mod.cc_argv) |cc_arg| test_exec_args.appendAssumeCapacity(cc_arg);
3890 for (mod.deps) |dep| try test_exec_args.appendSlice(arena, &.{
3891 "--dep",
3892 if (std.mem.eql(u8, dep.key, dep.value)) dep.value else try std.fmt.allocPrint(arena, "{s}={s}", .{ dep.key, dep.value }),
3893 });
3894 try test_exec_args.append(arena, try std.fmt.allocPrint(arena, "-M{s}", .{mod_name}));
3847 }3895 }
38483896
3897 try test_exec_args.ensureUnusedCapacity(arena, comp.global_cc_argv.len);
3898 for (comp.global_cc_argv) |global_cc_arg| test_exec_args.appendAssumeCapacity(global_cc_arg);
3899 if (create_module.resolved_options.link_libcpp) try test_exec_args.append(arena, "-lc++");
3849 if (create_module.resolved_options.link_libc) {3900 if (create_module.resolved_options.link_libc) {
3850 try test_exec_args.append(arena, "-lc");3901 try test_exec_args.append(arena, "-lc");
3851 } else if (target.os.tag == .windows) {3902 } else if (target.os.tag == .windows) {
...@@ -3855,21 +3906,10 @@ fn buildOutputType(...@@ -3855,21 +3906,10 @@ fn buildOutputType(
3855 });3906 });
3856 }3907 }
38573908
3858 const first_cli_mod = create_module.modules.values()[0];3909 try test_exec_args.ensureUnusedCapacity(arena, 2 * log_scopes.items.len + @intFromBool(verbose_link) + @intFromBool(verbose_cc));
3859 if (first_cli_mod.target_arch_os_abi) |triple| {3910 for (log_scopes.items) |log_scope| test_exec_args.appendSliceAssumeCapacity(&.{ "--debug-log", log_scope });
3860 try test_exec_args.appendSlice(arena, &.{ "-target", triple });3911 if (verbose_link) test_exec_args.appendAssumeCapacity("--verbose-link");
3861 }3912 if (verbose_cc) test_exec_args.appendAssumeCapacity("--verbose-cc");
3862 if (first_cli_mod.target_mcpu) |mcpu| {
3863 try test_exec_args.append(arena, try std.fmt.allocPrint(arena, "-mcpu={s}", .{mcpu}));
3864 }
3865 if (create_module.dynamic_linker) |dl| {
3866 if (dl.len > 0) {
3867 try test_exec_args.appendSlice(arena, &.{ "--dynamic-linker", dl });
3868 } else {
3869 try test_exec_args.append(arena, "--no-dynamic-linker");
3870 }
3871 }
3872 try test_exec_args.append(arena, null); // placeholder for the path of the emitted C source file
3873 }3913 }
38743914
3875 try runOrTest(3915 try runOrTest(
...@@ -3898,7 +3938,6 @@ const CreateModule = struct {...@@ -3898,7 +3938,6 @@ const CreateModule = struct {
3898 dirs: Compilation.Directories,3938 dirs: Compilation.Directories,
3899 modules: std.array_hash_map.String(CliModule),3939 modules: std.array_hash_map.String(CliModule),
3900 opts: Compilation.Config.Options,3940 opts: Compilation.Config.Options,
3901 dynamic_linker: ?[]const u8,
3902 object_format: ?[]const u8,3941 object_format: ?[]const u8,
3903 /// undefined until createModule() for the root module is called.3942 /// undefined until createModule() for the root module is called.
3904 resolved_options: Compilation.Config,3943 resolved_options: Compilation.Config,
...@@ -3960,7 +3999,7 @@ fn createModule(...@@ -3960,7 +3999,7 @@ fn createModule(
3960 var target_parse_options: std.Target.Query.ParseOptions = .{3999 var target_parse_options: std.Target.Query.ParseOptions = .{
3961 .arch_os_abi = cli_mod.target_arch_os_abi orelse "native",4000 .arch_os_abi = cli_mod.target_arch_os_abi orelse "native",
3962 .cpu_features = cli_mod.target_mcpu,4001 .cpu_features = cli_mod.target_mcpu,
3963 .dynamic_linker = create_module.dynamic_linker,4002 .dynamic_linker = cli_mod.dynamic_linker,
3964 .object_format = create_module.object_format,4003 .object_format = create_module.object_format,
3965 };4004 };
39664005
...@@ -7844,6 +7883,7 @@ fn handleModArg(...@@ -7844,6 +7883,7 @@ fn handleModArg(
7844 cc_argv: *std.ArrayList([]const u8),7883 cc_argv: *std.ArrayList([]const u8),
7845 target_arch_os_abi: *?[]const u8,7884 target_arch_os_abi: *?[]const u8,
7846 target_mcpu: *?[]const u8,7885 target_mcpu: *?[]const u8,
7886 dynamic_linker: *?[]const u8,
7847 deps: *std.ArrayList(CliModule.Dep),7887 deps: *std.ArrayList(CliModule.Dep),
7848 c_source_files_owner_index: *usize,7888 c_source_files_owner_index: *usize,
7849 rc_source_files_owner_index: *usize,7889 rc_source_files_owner_index: *usize,
...@@ -7892,6 +7932,7 @@ fn handleModArg(...@@ -7892,6 +7932,7 @@ fn handleModArg(
7892 .inherited = mod_opts.*,7932 .inherited = mod_opts.*,
7893 .target_arch_os_abi = target_arch_os_abi.*,7933 .target_arch_os_abi = target_arch_os_abi.*,
7894 .target_mcpu = target_mcpu.*,7934 .target_mcpu = target_mcpu.*,
7935 .dynamic_linker = dynamic_linker.*,
7895 .deps = try deps.toOwnedSlice(arena),7936 .deps = try deps.toOwnedSlice(arena),
7896 .resolved = null,7937 .resolved = null,
7897 .c_source_files_start = c_source_files_owner_index.*,7938 .c_source_files_start = c_source_files_owner_index.*,
...@@ -7903,6 +7944,7 @@ fn handleModArg(...@@ -7903,6 +7944,7 @@ fn handleModArg(
7903 mod_opts.* = .{};7944 mod_opts.* = .{};
7904 target_arch_os_abi.* = null;7945 target_arch_os_abi.* = null;
7905 target_mcpu.* = null;7946 target_mcpu.* = null;
7947 dynamic_linker.* = null;
7906 c_source_files_owner_index.* = create_module.c_source_files.items.len;7948 c_source_files_owner_index.* = create_module.c_source_files.items.len;
7907 rc_source_files_owner_index.* = create_module.rc_source_files.items.len;7949 rc_source_files_owner_index.* = create_module.rc_source_files.items.len;
7908}7950}