diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2025-04-20 17:54:11 +0100 |
|---|---|---|
| committer | Matthew Lugg <mlugg@mlugg.co.uk> | 2025-04-22 22:50:36 +0100 |
| commit | 927f233ff82bd422b387b4eef7fcbc67823e4b85 (patch) | |
| tree | b921686a62e6e60efa6db973488d9fffb93c8ebb /lib/std/Build/Step/Compile.zig | |
| parent | 6a7ca4b8b0fcce9e5f6a4d3f799e83021929c975 (diff) | |
| download | zig-927f233ff82bd422b387b4eef7fcbc67823e4b85.tar.gz zig-927f233ff82bd422b387b4eef7fcbc67823e4b85.zip | |
compiler: allow emitting tests to an object file
This is fairly straightforward; the actual compiler changes are limited
to the CLI, since `Compilation` already supports this combination.
A new `std.Build` API is introduced to allow representing this. By
passing the `emit_object` option to `std.Build.addTest`, you get a
`Step.Compile` which emits an object file; you can then use that as you
would any other object, such as either installing it for external use,
or linking it into another step.
A standalone test is added to cover the build system API. It builds a
test into an object, and links it into a final executable, which it then
runs.
Using this build system mechanism prevents the build system from
noticing that you're running a `zig test`, so the build runner and test
runner do not communicate over stdio. However, that's okay, because the
real-world use cases for this feature don't want to do that anyway!
Resolves: #23374
Diffstat (limited to 'lib/std/Build/Step/Compile.zig')
| -rw-r--r-- | lib/std/Build/Step/Compile.zig | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index ff6e766c58..e436865108 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -293,6 +293,7 @@ pub const Kind = enum { lib, obj, @"test", + test_obj, }; pub const HeaderInstallation = union(enum) { @@ -370,7 +371,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile { } // Avoid the common case of the step name looking like "zig test test". - const name_adjusted = if (options.kind == .@"test" and mem.eql(u8, name, "test")) + const name_adjusted = if ((options.kind == .@"test" or options.kind == .test_obj) and mem.eql(u8, name, "test")) "" else owner.fmt("{s} ", .{name}); @@ -385,6 +386,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile { .lib => "zig build-lib", .obj => "zig build-obj", .@"test" => "zig test", + .test_obj => "zig test-obj", }, name_adjusted, @tagName(options.root_module.optimize orelse .Debug), @@ -396,7 +398,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile { .target = target, .output_mode = switch (options.kind) { .lib => .Lib, - .obj => .Obj, + .obj, .test_obj => .Obj, .exe, .@"test" => .Exe, }, .link_mode = options.linkage, @@ -1053,6 +1055,7 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 { .exe => "build-exe", .obj => "build-obj", .@"test" => "test", + .test_obj => "test-obj", }; try zig_args.append(cmd); @@ -1222,9 +1225,9 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 { switch (other.kind) { .exe => return step.fail("cannot link with an executable build artifact", .{}), .@"test" => return step.fail("cannot link with a test", .{}), - .obj => { + .obj, .test_obj => { const included_in_lib_or_obj = !my_responsibility and - (dep_compile.kind == .lib or dep_compile.kind == .obj); + (dep_compile.kind == .lib or dep_compile.kind == .obj or dep_compile.kind == .test_obj); if (!already_linked and !included_in_lib_or_obj) { try zig_args.append(other.getEmittedBin().getPath2(b, step)); total_linker_objects += 1; |
