authorgravatar for timonkruiper@gmail.comTimon Kruiper <timonkruiper@gmail.com> 2021-01-03 17:10:28+01:00
committergravatar for timonkruiper@gmail.comTimon Kruiper <timonkruiper@gmail.com> 2021-01-03 21:13:38+01:00
log0151f3b76ad9dca6c73d44876c263d5e27d92ab3
treeba5b4391a07a8cafb85916cf1525cadb473ce508
parenta926c91814bbfa29be7f75c7cfeeda0e2d0669d2

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. (#7596)

3 files changed, 73 insertions(+), 1 deletions(-)

src/test.zig+42-1
......@@ -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 created+30
......@@ -0,0 +1,30 @@
1const std = @import("std");
2const TestContext = @import("../../src/test.zig").TestContext;
3const 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.
7const linux_x64 = std.zig.CrossTarget{
8 .cpu_arch = .x86_64,
9 .os_tag = .linux,
10};
11
12pub 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+1
......@@ -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);