authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-12-07 00:09:33-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-12-07 00:09:33-08:00
log0812b5746622c4263ad0fcf23bea847a547b0c4d
treeea5f3cdd1e26c7345010f274e631f8804d807e95
parent274555be21ea756d8480a586f771274a79a58d80
parent592499404527b49e9d09a8fa358a8d702e61f614
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #10288 from SpexGuy/test-build

Add test executable builds to build.zig

2 files changed, 113 insertions(+), 90 deletions(-)

lib/std/build.zig+112-89
......@@ -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,
......@@ -1762,7 +1775,7 @@ pub const LibExeObjStep = struct {
17621775 /// Creates a `RunStep` with an executable built with `addExecutable`.
17631776 /// Add command line arguments with `addArg`.
17641777 pub fn run(exe: *LibExeObjStep) *RunStep {
1765 assert(exe.kind == .exe);
1778 assert(exe.kind == .exe or exe.kind == .test_exe);
17661779
17671780 // It doesn't have to be native. We catch that if you actually try to run it.
17681781 // Consider that this is declarative; the run step may not be run unless a user
......@@ -1770,6 +1783,10 @@ pub const LibExeObjStep = struct {
17701783 const run_step = RunStep.create(exe.builder, exe.builder.fmt("run {s}", .{exe.step.name}));
17711784 run_step.addArtifactArg(exe);
17721785
1786 if (exe.kind == .test_exe) {
1787 run_step.addArg(exe.builder.zig_exe);
1788 }
1789
17731790 if (exe.vcpkg_bin_path) |path| {
17741791 run_step.addPathDir(path);
17751792 }
......@@ -1816,7 +1833,7 @@ pub const LibExeObjStep = struct {
18161833 pub fn producesPdbFile(self: *LibExeObjStep) bool {
18171834 if (!self.target.isWindows() and !self.target.isUefi()) return false;
18181835 if (self.strip) return false;
1819 return self.isDynamicLibrary() or self.kind == .exe;
1836 return self.isDynamicLibrary() or self.kind == .exe or self.kind == .test_exe;
18201837 }
18211838
18221839 pub fn linkLibC(self: *LibExeObjStep) void {
......@@ -1976,12 +1993,12 @@ pub const LibExeObjStep = struct {
19761993 }
19771994
19781995 pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void {
1979 assert(self.kind == .@"test");
1996 assert(self.kind == .@"test" or self.kind == .test_exe);
19801997 self.name_prefix = self.builder.dupe(text);
19811998 }
19821999
19832000 pub fn setFilter(self: *LibExeObjStep, text: ?[]const u8) void {
1984 assert(self.kind == .@"test");
2001 assert(self.kind == .@"test" or self.kind == .test_exe);
19852002 self.filter = if (text) |t| self.builder.dupe(t) else null;
19862003 }
19872004
......@@ -2052,7 +2069,7 @@ pub const LibExeObjStep = struct {
20522069 /// Returns the generated header file.
20532070 /// This function can only be called for libraries or object files which have `emit_h` set.
20542071 pub fn getOutputHSource(self: *LibExeObjStep) FileSource {
2055 assert(self.kind != .exe);
2072 assert(self.kind != .exe and self.kind != .test_exe and self.kind != .@"test");
20562073 assert(self.emit_h);
20572074 return FileSource{ .generated = &self.output_h_path_source };
20582075 }
......@@ -2222,6 +2239,7 @@ pub const LibExeObjStep = struct {
22222239 .exe => "build-exe",
22232240 .obj => "build-obj",
22242241 .@"test" => "test",
2242 .test_exe => "test",
22252243 };
22262244 zig_args.append(cmd) catch unreachable;
22272245
......@@ -2268,8 +2286,9 @@ pub const LibExeObjStep = struct {
22682286 .static_path => |static_path| try zig_args.append(static_path.getPath(builder)),
22692287
22702288 .other_step => |other| switch (other.kind) {
2271 .exe => unreachable,
2272 .@"test" => unreachable,
2289 .exe => @panic("Cannot link with an executable build artifact"),
2290 .test_exe => @panic("Cannot link with an executable build artifact"),
2291 .@"test" => @panic("Cannot link with a test"),
22732292 .obj => {
22742293 try zig_args.append(other.getOutputSource().getPath(builder));
22752294 },
......@@ -2542,89 +2561,93 @@ pub const LibExeObjStep = struct {
25422561 try zig_args.append(builder.pathFromRoot(version_script));
25432562 }
25442563
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;
2564 if (self.kind == .@"test") {
2565 if (self.exec_cmd_args) |exec_cmd_args| {
2566 for (exec_cmd_args) |cmd_arg| {
2567 if (cmd_arg) |arg| {
25762568 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"
2569 try zig_args.append(arg);
2570 } else {
2571 try zig_args.append("--test-cmd-bin");
2572 }
2573 }
2574 } else {
2575 const need_cross_glibc = self.target.isGnuLibC() and self.is_linking_libc;
2576
2577 switch (self.builder.host.getExternalExecutor(self.target_info, .{
2578 .qemu_fixes_dl = need_cross_glibc and builder.glibc_runtimes_dir != null,
2579 .link_libc = self.is_linking_libc,
2580 })) {
2581 .native => {},
2582 .bad_dl, .bad_os_or_cpu => {
2583 try zig_args.append("--test-no-exec");
2584 },
2585 .rosetta => if (builder.enable_rosetta) {
2586 try zig_args.append("--test-cmd-bin");
2587 } else {
2588 try zig_args.append("--test-no-exec");
2589 },
2590 .qemu => |bin_name| ok: {
2591 if (builder.enable_qemu) qemu: {
2592 const glibc_dir_arg = if (need_cross_glibc)
2593 builder.glibc_runtimes_dir orelse break :qemu
25882594 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
2594 try zig_args.append("--test-cmd");
2595 try zig_args.append("-L");
2595 null;
25962596 try zig_args.append("--test-cmd");
2597 try zig_args.append(full_dir);
2597 try zig_args.append(bin_name);
2598 if (glibc_dir_arg) |dir| {
2599 // TODO look into making this a call to `linuxTriple`. This
2600 // needs the directory to be called "i686" rather than
2601 // "i386" which is why we do it manually here.
2602 const fmt_str = "{s}" ++ fs.path.sep_str ++ "{s}-{s}-{s}";
2603 const cpu_arch = self.target.getCpuArch();
2604 const os_tag = self.target.getOsTag();
2605 const abi = self.target.getAbi();
2606 const cpu_arch_name: []const u8 = if (cpu_arch == .i386)
2607 "i686"
2608 else
2609 @tagName(cpu_arch);
2610 const full_dir = try std.fmt.allocPrint(builder.allocator, fmt_str, .{
2611 dir, cpu_arch_name, @tagName(os_tag), @tagName(abi),
2612 });
2613
2614 try zig_args.append("--test-cmd");
2615 try zig_args.append("-L");
2616 try zig_args.append("--test-cmd");
2617 try zig_args.append(full_dir);
2618 }
2619 try zig_args.append("--test-cmd-bin");
2620 break :ok;
25982621 }
2622 try zig_args.append("--test-no-exec");
2623 },
2624 .wine => |bin_name| if (builder.enable_wine) {
2625 try zig_args.append("--test-cmd");
2626 try zig_args.append(bin_name);
25992627 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 },
2628 } else {
2629 try zig_args.append("--test-no-exec");
2630 },
2631 .wasmtime => |bin_name| if (builder.enable_wasmtime) {
2632 try zig_args.append("--test-cmd");
2633 try zig_args.append(bin_name);
2634 try zig_args.append("--test-cmd");
2635 try zig_args.append("--dir=.");
2636 try zig_args.append("--test-cmd-bin");
2637 } else {
2638 try zig_args.append("--test-no-exec");
2639 },
2640 .darling => |bin_name| if (builder.enable_darling) {
2641 try zig_args.append("--test-cmd");
2642 try zig_args.append(bin_name);
2643 try zig_args.append("--test-cmd-bin");
2644 } else {
2645 try zig_args.append("--test-no-exec");
2646 },
2647 }
26272648 }
2649 } else if (self.kind == .test_exe) {
2650 try zig_args.append("--test-no-exec");
26282651 }
26292652
26302653 for (self.packages.items) |pkg| {
......@@ -2877,13 +2900,13 @@ pub const InstallArtifactStep = struct {
28772900 .step = Step.init(.install_artifact, builder.fmt("install {s}", .{artifact.step.name}), builder.allocator, make),
28782901 .artifact = artifact,
28792902 .dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) {
2880 .obj => unreachable,
2881 .@"test" => unreachable,
2882 .exe => InstallDir{ .bin = {} },
2903 .obj => @panic("Cannot install a .obj build artifact."),
2904 .@"test" => @panic("Cannot install a test build artifact, use addTestExe instead."),
2905 .exe, .test_exe => InstallDir{ .bin = {} },
28832906 .lib => InstallDir{ .lib = {} },
28842907 },
28852908 .pdb_dir = if (artifact.producesPdbFile()) blk: {
2886 if (artifact.kind == .exe) {
2909 if (artifact.kind == .exe or artifact.kind == .test_exe) {
28872910 break :blk InstallDir{ .bin = {} };
28882911 } else {
28892912 break :blk InstallDir{ .lib = {} };
lib/std/build/InstallRawStep.zig+1-1
......@@ -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,