diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-12-07 00:09:33 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-07 00:09:33 -0800 |
| commit | 0812b5746622c4263ad0fcf23bea847a547b0c4d (patch) | |
| tree | ea5f3cdd1e26c7345010f274e631f8804d807e95 /lib/std | |
| parent | 274555be21ea756d8480a586f771274a79a58d80 (diff) | |
| parent | 592499404527b49e9d09a8fa358a8d702e61f614 (diff) | |
| download | zig-0812b5746622c4263ad0fcf23bea847a547b0c4d.tar.gz zig-0812b5746622c4263ad0fcf23bea847a547b0c4d.zip | |
Merge pull request #10288 from SpexGuy/test-build
Add test executable builds to build.zig
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/build.zig | 201 | ||||
| -rw-r--r-- | lib/std/build/InstallRawStep.zig | 2 |
2 files changed, 113 insertions, 90 deletions
diff --git a/lib/std/build.zig b/lib/std/build.zig index 483ac1d82d..e3e3041dbb 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -320,6 +320,14 @@ pub const Builder = struct { return LibExeObjStep.createTest(self, "test", root_src.dupe(self)); } + pub fn addTestExe(self: *Builder, name: []const u8, root_src: []const u8) *LibExeObjStep { + return LibExeObjStep.createTestExe(self, name, .{ .path = root_src }); + } + + pub fn addTestExeSource(self: *Builder, name: []const u8, root_src: FileSource) *LibExeObjStep { + return LibExeObjStep.createTestExe(self, name, root_src.dupe(self)); + } + pub fn addAssemble(self: *Builder, name: []const u8, src: []const u8) *LibExeObjStep { return addAssembleSource(self, name, .{ .path = src }); } @@ -1569,6 +1577,7 @@ pub const LibExeObjStep = struct { lib, obj, @"test", + test_exe, }; pub const SharedLibKind = union(enum) { @@ -1617,6 +1626,10 @@ pub const LibExeObjStep = struct { return initExtraArgs(builder, name, root_src, .@"test", null, null); } + pub fn createTestExe(builder: *Builder, name: []const u8, root_src: FileSource) *LibExeObjStep { + return initExtraArgs(builder, name, root_src, .test_exe, null, null); + } + fn initExtraArgs( builder: *Builder, name_raw: []const u8, @@ -1698,7 +1711,7 @@ pub const LibExeObjStep = struct { .output_mode = switch (self.kind) { .lib => .Lib, .obj => .Obj, - .exe, .@"test" => .Exe, + .exe, .@"test", .test_exe => .Exe, }, .link_mode = if (self.linkage) |some| @as(std.builtin.LinkMode, switch (some) { .dynamic => .Dynamic, @@ -1762,7 +1775,7 @@ pub const LibExeObjStep = struct { /// Creates a `RunStep` with an executable built with `addExecutable`. /// Add command line arguments with `addArg`. pub fn run(exe: *LibExeObjStep) *RunStep { - assert(exe.kind == .exe); + assert(exe.kind == .exe or exe.kind == .test_exe); // It doesn't have to be native. We catch that if you actually try to run it. // Consider that this is declarative; the run step may not be run unless a user @@ -1770,6 +1783,10 @@ pub const LibExeObjStep = struct { const run_step = RunStep.create(exe.builder, exe.builder.fmt("run {s}", .{exe.step.name})); run_step.addArtifactArg(exe); + if (exe.kind == .test_exe) { + run_step.addArg(exe.builder.zig_exe); + } + if (exe.vcpkg_bin_path) |path| { run_step.addPathDir(path); } @@ -1816,7 +1833,7 @@ pub const LibExeObjStep = struct { pub fn producesPdbFile(self: *LibExeObjStep) bool { if (!self.target.isWindows() and !self.target.isUefi()) return false; if (self.strip) return false; - return self.isDynamicLibrary() or self.kind == .exe; + return self.isDynamicLibrary() or self.kind == .exe or self.kind == .test_exe; } pub fn linkLibC(self: *LibExeObjStep) void { @@ -1976,12 +1993,12 @@ pub const LibExeObjStep = struct { } pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void { - assert(self.kind == .@"test"); + assert(self.kind == .@"test" or self.kind == .test_exe); self.name_prefix = self.builder.dupe(text); } pub fn setFilter(self: *LibExeObjStep, text: ?[]const u8) void { - assert(self.kind == .@"test"); + assert(self.kind == .@"test" or self.kind == .test_exe); self.filter = if (text) |t| self.builder.dupe(t) else null; } @@ -2052,7 +2069,7 @@ pub const LibExeObjStep = struct { /// Returns the generated header file. /// This function can only be called for libraries or object files which have `emit_h` set. pub fn getOutputHSource(self: *LibExeObjStep) FileSource { - assert(self.kind != .exe); + assert(self.kind != .exe and self.kind != .test_exe and self.kind != .@"test"); assert(self.emit_h); return FileSource{ .generated = &self.output_h_path_source }; } @@ -2222,6 +2239,7 @@ pub const LibExeObjStep = struct { .exe => "build-exe", .obj => "build-obj", .@"test" => "test", + .test_exe => "test", }; zig_args.append(cmd) catch unreachable; @@ -2268,8 +2286,9 @@ pub const LibExeObjStep = struct { .static_path => |static_path| try zig_args.append(static_path.getPath(builder)), .other_step => |other| switch (other.kind) { - .exe => unreachable, - .@"test" => unreachable, + .exe => @panic("Cannot link with an executable build artifact"), + .test_exe => @panic("Cannot link with an executable build artifact"), + .@"test" => @panic("Cannot link with a test"), .obj => { try zig_args.append(other.getOutputSource().getPath(builder)); }, @@ -2542,89 +2561,93 @@ pub const LibExeObjStep = struct { try zig_args.append(builder.pathFromRoot(version_script)); } - if (self.exec_cmd_args) |exec_cmd_args| { - for (exec_cmd_args) |cmd_arg| { - if (cmd_arg) |arg| { - try zig_args.append("--test-cmd"); - try zig_args.append(arg); - } else { - try zig_args.append("--test-cmd-bin"); - } - } - } else { - const need_cross_glibc = self.target.isGnuLibC() and self.is_linking_libc; - - switch (self.builder.host.getExternalExecutor(self.target_info, .{ - .qemu_fixes_dl = need_cross_glibc and builder.glibc_runtimes_dir != null, - .link_libc = self.is_linking_libc, - })) { - .native => {}, - .bad_dl, .bad_os_or_cpu => { - try zig_args.append("--test-no-exec"); - }, - .rosetta => if (builder.enable_rosetta) { - try zig_args.append("--test-cmd-bin"); - } else { - try zig_args.append("--test-no-exec"); - }, - .qemu => |bin_name| ok: { - if (builder.enable_qemu) qemu: { - const glibc_dir_arg = if (need_cross_glibc) - builder.glibc_runtimes_dir orelse break :qemu - else - null; + if (self.kind == .@"test") { + if (self.exec_cmd_args) |exec_cmd_args| { + for (exec_cmd_args) |cmd_arg| { + if (cmd_arg) |arg| { try zig_args.append("--test-cmd"); - try zig_args.append(bin_name); - if (glibc_dir_arg) |dir| { - // TODO look into making this a call to `linuxTriple`. This - // needs the directory to be called "i686" rather than - // "i386" which is why we do it manually here. - const fmt_str = "{s}" ++ fs.path.sep_str ++ "{s}-{s}-{s}"; - const cpu_arch = self.target.getCpuArch(); - const os_tag = self.target.getOsTag(); - const abi = self.target.getAbi(); - const cpu_arch_name: []const u8 = if (cpu_arch == .i386) - "i686" + try zig_args.append(arg); + } else { + try zig_args.append("--test-cmd-bin"); + } + } + } else { + const need_cross_glibc = self.target.isGnuLibC() and self.is_linking_libc; + + switch (self.builder.host.getExternalExecutor(self.target_info, .{ + .qemu_fixes_dl = need_cross_glibc and builder.glibc_runtimes_dir != null, + .link_libc = self.is_linking_libc, + })) { + .native => {}, + .bad_dl, .bad_os_or_cpu => { + try zig_args.append("--test-no-exec"); + }, + .rosetta => if (builder.enable_rosetta) { + try zig_args.append("--test-cmd-bin"); + } else { + try zig_args.append("--test-no-exec"); + }, + .qemu => |bin_name| ok: { + if (builder.enable_qemu) qemu: { + const glibc_dir_arg = if (need_cross_glibc) + builder.glibc_runtimes_dir orelse break :qemu else - @tagName(cpu_arch); - const full_dir = try std.fmt.allocPrint(builder.allocator, fmt_str, .{ - dir, cpu_arch_name, @tagName(os_tag), @tagName(abi), - }); - - try zig_args.append("--test-cmd"); - try zig_args.append("-L"); + null; try zig_args.append("--test-cmd"); - try zig_args.append(full_dir); + try zig_args.append(bin_name); + if (glibc_dir_arg) |dir| { + // TODO look into making this a call to `linuxTriple`. This + // needs the directory to be called "i686" rather than + // "i386" which is why we do it manually here. + const fmt_str = "{s}" ++ fs.path.sep_str ++ "{s}-{s}-{s}"; + const cpu_arch = self.target.getCpuArch(); + const os_tag = self.target.getOsTag(); + const abi = self.target.getAbi(); + const cpu_arch_name: []const u8 = if (cpu_arch == .i386) + "i686" + else + @tagName(cpu_arch); + const full_dir = try std.fmt.allocPrint(builder.allocator, fmt_str, .{ + dir, cpu_arch_name, @tagName(os_tag), @tagName(abi), + }); + + try zig_args.append("--test-cmd"); + try zig_args.append("-L"); + try zig_args.append("--test-cmd"); + try zig_args.append(full_dir); + } + try zig_args.append("--test-cmd-bin"); + break :ok; } + try zig_args.append("--test-no-exec"); + }, + .wine => |bin_name| if (builder.enable_wine) { + try zig_args.append("--test-cmd"); + try zig_args.append(bin_name); try zig_args.append("--test-cmd-bin"); - break :ok; - } - try zig_args.append("--test-no-exec"); - }, - .wine => |bin_name| if (builder.enable_wine) { - try zig_args.append("--test-cmd"); - try zig_args.append(bin_name); - try zig_args.append("--test-cmd-bin"); - } else { - try zig_args.append("--test-no-exec"); - }, - .wasmtime => |bin_name| if (builder.enable_wasmtime) { - try zig_args.append("--test-cmd"); - try zig_args.append(bin_name); - try zig_args.append("--test-cmd"); - try zig_args.append("--dir=."); - try zig_args.append("--test-cmd-bin"); - } else { - try zig_args.append("--test-no-exec"); - }, - .darling => |bin_name| if (builder.enable_darling) { - try zig_args.append("--test-cmd"); - try zig_args.append(bin_name); - try zig_args.append("--test-cmd-bin"); - } else { - try zig_args.append("--test-no-exec"); - }, + } else { + try zig_args.append("--test-no-exec"); + }, + .wasmtime => |bin_name| if (builder.enable_wasmtime) { + try zig_args.append("--test-cmd"); + try zig_args.append(bin_name); + try zig_args.append("--test-cmd"); + try zig_args.append("--dir=."); + try zig_args.append("--test-cmd-bin"); + } else { + try zig_args.append("--test-no-exec"); + }, + .darling => |bin_name| if (builder.enable_darling) { + try zig_args.append("--test-cmd"); + try zig_args.append(bin_name); + try zig_args.append("--test-cmd-bin"); + } else { + try zig_args.append("--test-no-exec"); + }, + } } + } else if (self.kind == .test_exe) { + try zig_args.append("--test-no-exec"); } for (self.packages.items) |pkg| { @@ -2877,13 +2900,13 @@ pub const InstallArtifactStep = struct { .step = Step.init(.install_artifact, builder.fmt("install {s}", .{artifact.step.name}), builder.allocator, make), .artifact = artifact, .dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) { - .obj => unreachable, - .@"test" => unreachable, - .exe => InstallDir{ .bin = {} }, + .obj => @panic("Cannot install a .obj build artifact."), + .@"test" => @panic("Cannot install a test build artifact, use addTestExe instead."), + .exe, .test_exe => InstallDir{ .bin = {} }, .lib => InstallDir{ .lib = {} }, }, .pdb_dir = if (artifact.producesPdbFile()) blk: { - if (artifact.kind == .exe) { + if (artifact.kind == .exe or artifact.kind == .test_exe) { break :blk InstallDir{ .bin = {} }; } else { break :blk InstallDir{ .lib = {} }; diff --git a/lib/std/build/InstallRawStep.zig b/lib/std/build/InstallRawStep.zig index 6f83630b06..43669fefe7 100644 --- a/lib/std/build/InstallRawStep.zig +++ b/lib/std/build/InstallRawStep.zig @@ -451,7 +451,7 @@ pub fn create(builder: *Builder, artifact: *LibExeObjStep, dest_filename: []cons .dest_dir = if (options.dest_dir) |d| d else switch (artifact.kind) { .obj => unreachable, .@"test" => unreachable, - .exe => .bin, + .exe, .test_exe => .bin, .lib => unreachable, }, .dest_filename = dest_filename, |
