Skip to content

Commit 0151f3b

Browse files
committed
stage2: Add support for testing LLVM enabled builds in test-stage2
To make sure that we don't have to rebuild libc for every case, we now have a seperate cache directory for the global cache, which remains the same between test runs. Also make sure to destory the Compilation before executing a child process, otherwise the compiler deadlocks. (ziglang#7596)
1 parent a926c91 commit 0151f3b

File tree

3 files changed

+73
-1
lines changed

3 files changed

+73
-1
lines changed

src/test.zig

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ pub const TestContext = struct {
135135
extension: Extension,
136136
object_format: ?std.builtin.ObjectFormat = null,
137137
emit_h: bool = false,
138+
llvm_backend: bool = false,
138139

139140
files: std.ArrayList(File),
140141

@@ -266,6 +267,21 @@ pub const TestContext = struct {
266267
return &ctx.cases.items[ctx.cases.items.len - 1];
267268
}
268269

270+
/// Adds a test case that uses the LLVM backend to emit an executable.
271+
/// Currently this implies linking libc, because only then we can generate a testable executable.
272+
pub fn exeUsingLlvmBackend(ctx: *TestContext, name: []const u8, target: CrossTarget) *Case {
273+
ctx.cases.append(Case{
274+
.name = name,
275+
.target = target,
276+
.updates = std.ArrayList(Update).init(ctx.cases.allocator),
277+
.output_mode = .Exe,
278+
.extension = .Zig,
279+
.files = std.ArrayList(File).init(ctx.cases.allocator),
280+
.llvm_backend = true,
281+
}) catch unreachable;
282+
return &ctx.cases.items[ctx.cases.items.len - 1];
283+
}
284+
269285
pub fn addObj(
270286
ctx: *TestContext,
271287
name: []const u8,
@@ -518,10 +534,30 @@ pub const TestContext = struct {
518534
try thread_pool.init(std.testing.allocator);
519535
defer thread_pool.deinit();
520536

537+
// Use the same global cache dir for all the tests, such that we for example don't have to
538+
// rebuild musl libc for every case (when LLVM backend is enabled).
539+
var global_tmp = std.testing.tmpDir(.{});
540+
defer global_tmp.cleanup();
541+
542+
var cache_dir = try global_tmp.dir.makeOpenPath("zig-cache", .{});
543+
defer cache_dir.close();
544+
const tmp_dir_path = try std.fs.path.join(std.testing.allocator, &[_][]const u8{ ".", "zig-cache", "tmp", &global_tmp.sub_path });
545+
defer std.testing.allocator.free(tmp_dir_path);
546+
547+
const global_cache_directory: Compilation.Directory = .{
548+
.handle = cache_dir,
549+
.path = try std.fs.path.join(std.testing.allocator, &[_][]const u8{ tmp_dir_path, "zig-cache" }),
550+
};
551+
defer std.testing.allocator.free(global_cache_directory.path.?);
552+
521553
for (self.cases.items) |case| {
522554
if (build_options.skip_non_native and case.target.getCpuArch() != std.Target.current.cpu.arch)
523555
continue;
524556

557+
// Skip tests that require LLVM backend when it is not available
558+
if (!build_options.have_llvm and case.llvm_backend)
559+
continue;
560+
525561
var prg_node = root_node.start(case.name, case.updates.items.len);
526562
prg_node.activate();
527563
defer prg_node.end();
@@ -537,6 +573,7 @@ pub const TestContext = struct {
537573
case,
538574
zig_lib_directory,
539575
&thread_pool,
576+
global_cache_directory,
540577
);
541578
}
542579
}
@@ -548,6 +585,7 @@ pub const TestContext = struct {
548585
case: Case,
549586
zig_lib_directory: Compilation.Directory,
550587
thread_pool: *ThreadPool,
588+
global_cache_directory: Compilation.Directory,
551589
) !void {
552590
const target_info = try std.zig.system.NativeTargetInfo.detect(allocator, case.target);
553591
const target = target_info.target;
@@ -601,7 +639,7 @@ pub const TestContext = struct {
601639
null;
602640
const comp = try Compilation.create(allocator, .{
603641
.local_cache_directory = zig_cache_directory,
604-
.global_cache_directory = zig_cache_directory,
642+
.global_cache_directory = global_cache_directory,
605643
.zig_lib_directory = zig_lib_directory,
606644
.thread_pool = thread_pool,
607645
.root_name = "test_case",
@@ -619,6 +657,9 @@ pub const TestContext = struct {
619657
.object_format = case.object_format,
620658
.is_native_os = case.target.isNativeOs(),
621659
.is_native_abi = case.target.isNativeAbi(),
660+
.link_libc = case.llvm_backend,
661+
.use_llvm = case.llvm_backend,
662+
.self_exe_path = std.testing.zig_exe_path,
622663
});
623664
defer comp.destroy();
624665

test/stage2/llvm_backend.zig

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const std = @import("std");
2+
const TestContext = @import("../../src/test.zig").TestContext;
3+
const build_options = @import("build_options");
4+
5+
// These tests should work with all platforms, but we're using linux_x64 for
6+
// now for consistency. Will be expanded eventually.
7+
const linux_x64 = std.zig.CrossTarget{
8+
.cpu_arch = .x86_64,
9+
.os_tag = .linux,
10+
};
11+
12+
pub fn addCases(ctx: *TestContext) !void {
13+
{
14+
var case = ctx.exeUsingLlvmBackend("simple addition and subtraction", linux_x64);
15+
16+
case.addCompareOutput(
17+
\\fn add(a: i32, b: i32) i32 {
18+
\\ return a + b;
19+
\\}
20+
\\
21+
\\export fn main() c_int {
22+
\\ var a: i32 = -5;
23+
\\ const x = add(a, 7);
24+
\\ var y = add(2, 0);
25+
\\ y -= x;
26+
\\ return y;
27+
\\}
28+
, "");
29+
}
30+
}

test/stage2/test.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub fn addCases(ctx: *TestContext) !void {
3131
try @import("spu-ii.zig").addCases(ctx);
3232
try @import("arm.zig").addCases(ctx);
3333
try @import("aarch64.zig").addCases(ctx);
34+
try @import("llvm_backend.zig").addCases(ctx);
3435

3536
{
3637
var case = ctx.exe("hello world with updates", linux_x64);

0 commit comments

Comments
 (0)