Skip to content

Commit 3771e77

Browse files
committed
Add test executable builds to build.zig
1 parent 933999d commit 3771e77

File tree

2 files changed

+107
-88
lines changed

2 files changed

+107
-88
lines changed

lib/std/build.zig

Lines changed: 106 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,14 @@ pub const Builder = struct {
320320
return LibExeObjStep.createTest(self, "test", root_src.dupe(self));
321321
}
322322

323+
pub fn addTestExe(self: *Builder, name: []const u8, root_src: []const u8) *LibExeObjStep {
324+
return LibExeObjStep.createTestExe(self, name, .{ .path = root_src });
325+
}
326+
327+
pub fn addTestExeSource(self: *Builder, name: []const u8, root_src: FileSource) *LibExeObjStep {
328+
return LibExeObjStep.createTestExe(self, name, root_src.dupe(self));
329+
}
330+
323331
pub fn addAssemble(self: *Builder, name: []const u8, src: []const u8) *LibExeObjStep {
324332
return addAssembleSource(self, name, .{ .path = src });
325333
}
@@ -1569,6 +1577,7 @@ pub const LibExeObjStep = struct {
15691577
lib,
15701578
obj,
15711579
@"test",
1580+
test_exe,
15721581
};
15731582

15741583
pub const SharedLibKind = union(enum) {
@@ -1617,6 +1626,10 @@ pub const LibExeObjStep = struct {
16171626
return initExtraArgs(builder, name, root_src, .@"test", null, null);
16181627
}
16191628

1629+
pub fn createTestExe(builder: *Builder, name: []const u8, root_src: FileSource) *LibExeObjStep {
1630+
return initExtraArgs(builder, name, root_src, .test_exe, null, null);
1631+
}
1632+
16201633
fn initExtraArgs(
16211634
builder: *Builder,
16221635
name_raw: []const u8,
@@ -1698,7 +1711,7 @@ pub const LibExeObjStep = struct {
16981711
.output_mode = switch (self.kind) {
16991712
.lib => .Lib,
17001713
.obj => .Obj,
1701-
.exe, .@"test" => .Exe,
1714+
.exe, .@"test", .test_exe => .Exe,
17021715
},
17031716
.link_mode = if (self.linkage) |some| @as(std.builtin.LinkMode, switch (some) {
17041717
.dynamic => .Dynamic,
@@ -1816,7 +1829,7 @@ pub const LibExeObjStep = struct {
18161829
pub fn producesPdbFile(self: *LibExeObjStep) bool {
18171830
if (!self.target.isWindows() and !self.target.isUefi()) return false;
18181831
if (self.strip) return false;
1819-
return self.isDynamicLibrary() or self.kind == .exe;
1832+
return self.isDynamicLibrary() or self.kind == .exe or self.kind == .test_exe;
18201833
}
18211834

18221835
pub fn linkLibC(self: *LibExeObjStep) void {
@@ -1976,12 +1989,12 @@ pub const LibExeObjStep = struct {
19761989
}
19771990

19781991
pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void {
1979-
assert(self.kind == .@"test");
1992+
assert(self.kind == .@"test" or self.kind == .test_exe);
19801993
self.name_prefix = self.builder.dupe(text);
19811994
}
19821995

19831996
pub fn setFilter(self: *LibExeObjStep, text: ?[]const u8) void {
1984-
assert(self.kind == .@"test");
1997+
assert(self.kind == .@"test" or self.kind == .test_exe);
19851998
self.filter = if (text) |t| self.builder.dupe(t) else null;
19861999
}
19872000

@@ -2222,6 +2235,7 @@ pub const LibExeObjStep = struct {
22222235
.exe => "build-exe",
22232236
.obj => "build-obj",
22242237
.@"test" => "test",
2238+
.test_exe => "test",
22252239
};
22262240
zig_args.append(cmd) catch unreachable;
22272241

@@ -2268,8 +2282,9 @@ pub const LibExeObjStep = struct {
22682282
.static_path => |static_path| try zig_args.append(static_path.getPath(builder)),
22692283

22702284
.other_step => |other| switch (other.kind) {
2271-
.exe => unreachable,
2272-
.@"test" => unreachable,
2285+
.exe => @panic("Cannot link with an executable build artifact"),
2286+
.test_exe => @panic("Cannot link with an executable build artifact"),
2287+
.@"test" => @panic("Cannot link with a test"),
22732288
.obj => {
22742289
try zig_args.append(other.getOutputSource().getPath(builder));
22752290
},
@@ -2542,89 +2557,93 @@ pub const LibExeObjStep = struct {
25422557
try zig_args.append(builder.pathFromRoot(version_script));
25432558
}
25442559

2545-
if (self.exec_cmd_args) |exec_cmd_args| {
2546-
for (exec_cmd_args) |cmd_arg| {
2547-
if (cmd_arg) |arg| {
2548-
try zig_args.append("--test-cmd");
2549-
try zig_args.append(arg);
2550-
} else {
2551-
try zig_args.append("--test-cmd-bin");
2552-
}
2553-
}
2554-
} else {
2555-
const need_cross_glibc = self.target.isGnuLibC() and self.is_linking_libc;
2556-
2557-
switch (self.builder.host.getExternalExecutor(self.target_info, .{
2558-
.qemu_fixes_dl = need_cross_glibc and builder.glibc_runtimes_dir != null,
2559-
.link_libc = self.is_linking_libc,
2560-
})) {
2561-
.native => {},
2562-
.bad_dl, .bad_os_or_cpu => {
2563-
try zig_args.append("--test-no-exec");
2564-
},
2565-
.rosetta => if (builder.enable_rosetta) {
2566-
try zig_args.append("--test-cmd-bin");
2567-
} else {
2568-
try zig_args.append("--test-no-exec");
2569-
},
2570-
.qemu => |bin_name| ok: {
2571-
if (builder.enable_qemu) qemu: {
2572-
const glibc_dir_arg = if (need_cross_glibc)
2573-
builder.glibc_runtimes_dir orelse break :qemu
2574-
else
2575-
null;
2560+
if (self.kind == .@"test") {
2561+
if (self.exec_cmd_args) |exec_cmd_args| {
2562+
for (exec_cmd_args) |cmd_arg| {
2563+
if (cmd_arg) |arg| {
25762564
try zig_args.append("--test-cmd");
2577-
try zig_args.append(bin_name);
2578-
if (glibc_dir_arg) |dir| {
2579-
// TODO look into making this a call to `linuxTriple`. This
2580-
// needs the directory to be called "i686" rather than
2581-
// "i386" which is why we do it manually here.
2582-
const fmt_str = "{s}" ++ fs.path.sep_str ++ "{s}-{s}-{s}";
2583-
const cpu_arch = self.target.getCpuArch();
2584-
const os_tag = self.target.getOsTag();
2585-
const abi = self.target.getAbi();
2586-
const cpu_arch_name: []const u8 = if (cpu_arch == .i386)
2587-
"i686"
2565+
try zig_args.append(arg);
2566+
} else {
2567+
try zig_args.append("--test-cmd-bin");
2568+
}
2569+
}
2570+
} else {
2571+
const need_cross_glibc = self.target.isGnuLibC() and self.is_linking_libc;
2572+
2573+
switch (self.builder.host.getExternalExecutor(self.target_info, .{
2574+
.qemu_fixes_dl = need_cross_glibc and builder.glibc_runtimes_dir != null,
2575+
.link_libc = self.is_linking_libc,
2576+
})) {
2577+
.native => {},
2578+
.bad_dl, .bad_os_or_cpu => {
2579+
try zig_args.append("--test-no-exec");
2580+
},
2581+
.rosetta => if (builder.enable_rosetta) {
2582+
try zig_args.append("--test-cmd-bin");
2583+
} else {
2584+
try zig_args.append("--test-no-exec");
2585+
},
2586+
.qemu => |bin_name| ok: {
2587+
if (builder.enable_qemu) qemu: {
2588+
const glibc_dir_arg = if (need_cross_glibc)
2589+
builder.glibc_runtimes_dir orelse break :qemu
25882590
else
2589-
@tagName(cpu_arch);
2590-
const full_dir = try std.fmt.allocPrint(builder.allocator, fmt_str, .{
2591-
dir, cpu_arch_name, @tagName(os_tag), @tagName(abi),
2592-
});
2593-
2591+
null;
25942592
try zig_args.append("--test-cmd");
2595-
try zig_args.append("-L");
2596-
try zig_args.append("--test-cmd");
2597-
try zig_args.append(full_dir);
2593+
try zig_args.append(bin_name);
2594+
if (glibc_dir_arg) |dir| {
2595+
// TODO look into making this a call to `linuxTriple`. This
2596+
// needs the directory to be called "i686" rather than
2597+
// "i386" which is why we do it manually here.
2598+
const fmt_str = "{s}" ++ fs.path.sep_str ++ "{s}-{s}-{s}";
2599+
const cpu_arch = self.target.getCpuArch();
2600+
const os_tag = self.target.getOsTag();
2601+
const abi = self.target.getAbi();
2602+
const cpu_arch_name: []const u8 = if (cpu_arch == .i386)
2603+
"i686"
2604+
else
2605+
@tagName(cpu_arch);
2606+
const full_dir = try std.fmt.allocPrint(builder.allocator, fmt_str, .{
2607+
dir, cpu_arch_name, @tagName(os_tag), @tagName(abi),
2608+
});
2609+
2610+
try zig_args.append("--test-cmd");
2611+
try zig_args.append("-L");
2612+
try zig_args.append("--test-cmd");
2613+
try zig_args.append(full_dir);
2614+
}
2615+
try zig_args.append("--test-cmd-bin");
2616+
break :ok;
25982617
}
2618+
try zig_args.append("--test-no-exec");
2619+
},
2620+
.wine => |bin_name| if (builder.enable_wine) {
2621+
try zig_args.append("--test-cmd");
2622+
try zig_args.append(bin_name);
25992623
try zig_args.append("--test-cmd-bin");
2600-
break :ok;
2601-
}
2602-
try zig_args.append("--test-no-exec");
2603-
},
2604-
.wine => |bin_name| if (builder.enable_wine) {
2605-
try zig_args.append("--test-cmd");
2606-
try zig_args.append(bin_name);
2607-
try zig_args.append("--test-cmd-bin");
2608-
} else {
2609-
try zig_args.append("--test-no-exec");
2610-
},
2611-
.wasmtime => |bin_name| if (builder.enable_wasmtime) {
2612-
try zig_args.append("--test-cmd");
2613-
try zig_args.append(bin_name);
2614-
try zig_args.append("--test-cmd");
2615-
try zig_args.append("--dir=.");
2616-
try zig_args.append("--test-cmd-bin");
2617-
} else {
2618-
try zig_args.append("--test-no-exec");
2619-
},
2620-
.darling => |bin_name| if (builder.enable_darling) {
2621-
try zig_args.append("--test-cmd");
2622-
try zig_args.append(bin_name);
2623-
try zig_args.append("--test-cmd-bin");
2624-
} else {
2625-
try zig_args.append("--test-no-exec");
2626-
},
2624+
} else {
2625+
try zig_args.append("--test-no-exec");
2626+
},
2627+
.wasmtime => |bin_name| if (builder.enable_wasmtime) {
2628+
try zig_args.append("--test-cmd");
2629+
try zig_args.append(bin_name);
2630+
try zig_args.append("--test-cmd");
2631+
try zig_args.append("--dir=.");
2632+
try zig_args.append("--test-cmd-bin");
2633+
} else {
2634+
try zig_args.append("--test-no-exec");
2635+
},
2636+
.darling => |bin_name| if (builder.enable_darling) {
2637+
try zig_args.append("--test-cmd");
2638+
try zig_args.append(bin_name);
2639+
try zig_args.append("--test-cmd-bin");
2640+
} else {
2641+
try zig_args.append("--test-no-exec");
2642+
},
2643+
}
26272644
}
2645+
} else if (self.kind == .test_exe) {
2646+
try zig_args.append("--test-no-exec");
26282647
}
26292648

26302649
for (self.packages.items) |pkg| {
@@ -2877,13 +2896,13 @@ pub const InstallArtifactStep = struct {
28772896
.step = Step.init(.install_artifact, builder.fmt("install {s}", .{artifact.step.name}), builder.allocator, make),
28782897
.artifact = artifact,
28792898
.dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) {
2880-
.obj => unreachable,
2881-
.@"test" => unreachable,
2882-
.exe => InstallDir{ .bin = {} },
2899+
.obj => @panic("Cannot install a .obj build artifact."),
2900+
.@"test" => @panic("Cannot install a test build artifact, use addTestExe instead."),
2901+
.exe, .test_exe => InstallDir{ .bin = {} },
28832902
.lib => InstallDir{ .lib = {} },
28842903
},
28852904
.pdb_dir = if (artifact.producesPdbFile()) blk: {
2886-
if (artifact.kind == .exe) {
2905+
if (artifact.kind == .exe or artifact.kind == .test_exe) {
28872906
break :blk InstallDir{ .bin = {} };
28882907
} else {
28892908
break :blk InstallDir{ .lib = {} };

lib/std/build/InstallRawStep.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ pub fn create(builder: *Builder, artifact: *LibExeObjStep, dest_filename: []cons
451451
.dest_dir = if (options.dest_dir) |d| d else switch (artifact.kind) {
452452
.obj => unreachable,
453453
.@"test" => unreachable,
454-
.exe => .bin,
454+
.exe, .test_exe => .bin,
455455
.lib => unreachable,
456456
},
457457
.dest_filename = dest_filename,

0 commit comments

Comments
 (0)