@@ -320,6 +320,14 @@ pub const Builder = struct {
320
320
return LibExeObjStep .createTest (self , "test" , root_src .dupe (self ));
321
321
}
322
322
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
+
323
331
pub fn addAssemble (self : * Builder , name : []const u8 , src : []const u8 ) * LibExeObjStep {
324
332
return addAssembleSource (self , name , .{ .path = src });
325
333
}
@@ -1569,6 +1577,7 @@ pub const LibExeObjStep = struct {
1569
1577
lib ,
1570
1578
obj ,
1571
1579
@"test" ,
1580
+ test_exe ,
1572
1581
};
1573
1582
1574
1583
pub const SharedLibKind = union (enum ) {
@@ -1617,6 +1626,10 @@ pub const LibExeObjStep = struct {
1617
1626
return initExtraArgs (builder , name , root_src , .@"test" , null , null );
1618
1627
}
1619
1628
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
+
1620
1633
fn initExtraArgs (
1621
1634
builder : * Builder ,
1622
1635
name_raw : []const u8 ,
@@ -1698,7 +1711,7 @@ pub const LibExeObjStep = struct {
1698
1711
.output_mode = switch (self .kind ) {
1699
1712
.lib = > .Lib ,
1700
1713
.obj = > .Obj ,
1701
- .exe , .@"test" = > .Exe ,
1714
+ .exe , .@"test" , .test_exe = > .Exe ,
1702
1715
},
1703
1716
.link_mode = if (self .linkage ) | some | @as (std .builtin .LinkMode , switch (some ) {
1704
1717
.dynamic = > .Dynamic ,
@@ -1762,14 +1775,18 @@ pub const LibExeObjStep = struct {
1762
1775
/// Creates a `RunStep` with an executable built with `addExecutable`.
1763
1776
/// Add command line arguments with `addArg`.
1764
1777
pub fn run (exe : * LibExeObjStep ) * RunStep {
1765
- assert (exe .kind == .exe );
1778
+ assert (exe .kind == .exe or exe . kind == .test_exe );
1766
1779
1767
1780
// It doesn't have to be native. We catch that if you actually try to run it.
1768
1781
// Consider that this is declarative; the run step may not be run unless a user
1769
1782
// option is supplied.
1770
1783
const run_step = RunStep .create (exe .builder , exe .builder .fmt ("run {s}" , .{exe .step .name }));
1771
1784
run_step .addArtifactArg (exe );
1772
1785
1786
+ if (exe .kind == .test_exe ) {
1787
+ run_step .addArg (exe .builder .zig_exe );
1788
+ }
1789
+
1773
1790
if (exe .vcpkg_bin_path ) | path | {
1774
1791
run_step .addPathDir (path );
1775
1792
}
@@ -1816,7 +1833,7 @@ pub const LibExeObjStep = struct {
1816
1833
pub fn producesPdbFile (self : * LibExeObjStep ) bool {
1817
1834
if (! self .target .isWindows () and ! self .target .isUefi ()) return false ;
1818
1835
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 ;
1820
1837
}
1821
1838
1822
1839
pub fn linkLibC (self : * LibExeObjStep ) void {
@@ -1976,12 +1993,12 @@ pub const LibExeObjStep = struct {
1976
1993
}
1977
1994
1978
1995
pub fn setNamePrefix (self : * LibExeObjStep , text : []const u8 ) void {
1979
- assert (self .kind == .@"test" );
1996
+ assert (self .kind == .@"test" or self . kind == .test_exe );
1980
1997
self .name_prefix = self .builder .dupe (text );
1981
1998
}
1982
1999
1983
2000
pub fn setFilter (self : * LibExeObjStep , text : ? []const u8 ) void {
1984
- assert (self .kind == .@"test" );
2001
+ assert (self .kind == .@"test" or self . kind == .test_exe );
1985
2002
self .filter = if (text ) | t | self .builder .dupe (t ) else null ;
1986
2003
}
1987
2004
@@ -2052,7 +2069,7 @@ pub const LibExeObjStep = struct {
2052
2069
/// Returns the generated header file.
2053
2070
/// This function can only be called for libraries or object files which have `emit_h` set.
2054
2071
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" );
2056
2073
assert (self .emit_h );
2057
2074
return FileSource { .generated = & self .output_h_path_source };
2058
2075
}
@@ -2222,6 +2239,7 @@ pub const LibExeObjStep = struct {
2222
2239
.exe = > "build-exe" ,
2223
2240
.obj = > "build-obj" ,
2224
2241
.@"test" = > "test" ,
2242
+ .test_exe = > "test" ,
2225
2243
};
2226
2244
zig_args .append (cmd ) catch unreachable ;
2227
2245
@@ -2268,8 +2286,9 @@ pub const LibExeObjStep = struct {
2268
2286
.static_path = > | static_path | try zig_args .append (static_path .getPath (builder )),
2269
2287
2270
2288
.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" ),
2273
2292
.obj = > {
2274
2293
try zig_args .append (other .getOutputSource ().getPath (builder ));
2275
2294
},
@@ -2542,89 +2561,93 @@ pub const LibExeObjStep = struct {
2542
2561
try zig_args .append (builder .pathFromRoot (version_script ));
2543
2562
}
2544
2563
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 | {
2576
2568
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
2588
2594
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 ;
2596
2596
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 ;
2598
2621
}
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 );
2599
2627
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
+ }
2627
2648
}
2649
+ } else if (self .kind == .test_exe ) {
2650
+ try zig_args .append ("--test-no-exec" );
2628
2651
}
2629
2652
2630
2653
for (self .packages .items ) | pkg | {
@@ -2877,13 +2900,13 @@ pub const InstallArtifactStep = struct {
2877
2900
.step = Step .init (.install_artifact , builder .fmt ("install {s}" , .{artifact .step .name }), builder .allocator , make ),
2878
2901
.artifact = artifact ,
2879
2902
.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 = {} },
2883
2906
.lib = > InstallDir { .lib = {} },
2884
2907
},
2885
2908
.pdb_dir = if (artifact .producesPdbFile ()) blk : {
2886
- if (artifact .kind == .exe ) {
2909
+ if (artifact .kind == .exe or artifact . kind == .test_exe ) {
2887
2910
break :blk InstallDir { .bin = {} };
2888
2911
} else {
2889
2912
break :blk InstallDir { .lib = {} };
0 commit comments