| author | |
| committer | |
| log | 4a233d18717e0f5729218e02eebf29ad46449a38 |
| tree | 1613cacd1dc7db37b9884d4c33d77e67e9760e55 |
| parent | 3c93c1664a3c3546076b39c2d40405f5db537dae |
The CI now runs C backend tests in addition to compiling them. It uses
-std=c99 -pedantic -Werror in order to catch non-conformant C code.
This necessitated disabling a test case that caused a C compile error,
in addition to disabling a handful of warnings that are already being
triggered by Zig's C backend output for the behavior tests.
The upshot is that I was able to, very cleanly, integrate the C backend
tests into the build system, so that it communicates via the test runner
protocol along with all the other behavior tests.5 files changed, 62 insertions(+), 15 deletions(-)
lib/std/Build.zig+1-2| ... | @@ -679,8 +679,7 @@ pub fn addRunArtifact(b: *Build, exe: *CompileStep) *RunStep { | ... | @@ -679,8 +679,7 @@ pub fn addRunArtifact(b: *Build, exe: *CompileStep) *RunStep { |
| 679 | run_step.addArtifactArg(exe); | 679 | run_step.addArtifactArg(exe); |
| 680 | 680 | ||
| 681 | if (exe.kind == .@"test") { | 681 | if (exe.kind == .@"test") { |
| 682 | run_step.stdio = .zig_test; | 682 | run_step.enableTestRunnerMode(); |
| 683 | run_step.addArgs(&.{"--listen=-"}); | ||
| 684 | } | 683 | } |
| 685 | 684 | ||
| 686 | if (exe.vcpkg_bin_path) |path| { | 685 | if (exe.vcpkg_bin_path) |path| { |
lib/std/Build/RunStep.zig+5| ... | @@ -140,6 +140,11 @@ pub fn setName(self: *RunStep, name: []const u8) void { | ... | @@ -140,6 +140,11 @@ pub fn setName(self: *RunStep, name: []const u8) void { |
| 140 | self.rename_step_with_output_arg = false; | 140 | self.rename_step_with_output_arg = false; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | pub fn enableTestRunnerMode(rs: *RunStep) void { | ||
| 144 | rs.stdio = .zig_test; | ||
| 145 | rs.addArgs(&.{"--listen=-"}); | ||
| 146 | } | ||
| 147 | |||
| 143 | pub fn addArtifactArg(self: *RunStep, artifact: *CompileStep) void { | 148 | pub fn addArtifactArg(self: *RunStep, artifact: *CompileStep) void { |
| 144 | self.argv.append(Arg{ .artifact = artifact }) catch @panic("OOM"); | 149 | self.argv.append(Arg{ .artifact = artifact }) catch @panic("OOM"); |
| 145 | self.step.dependOn(&artifact.step); | 150 | self.step.dependOn(&artifact.step); |
lib/std/zig/Server.zig+4-8| ... | @@ -104,11 +104,9 @@ pub fn receiveMessage(s: *Server) !InMessage.Header { | ... | @@ -104,11 +104,9 @@ pub fn receiveMessage(s: *Server) !InMessage.Header { |
| 104 | const buf = fifo.readableSlice(0); | 104 | const buf = fifo.readableSlice(0); |
| 105 | assert(fifo.readableLength() == buf.len); | 105 | assert(fifo.readableLength() == buf.len); |
| 106 | if (buf.len >= @sizeOf(Header)) { | 106 | if (buf.len >= @sizeOf(Header)) { |
| 107 | const header = @ptrCast(*align(1) const Header, buf[0..@sizeOf(Header)]); | ||
| 108 | // workaround for https://github.com/ziglang/zig/issues/14904 | 107 | // workaround for https://github.com/ziglang/zig/issues/14904 |
| 109 | const bytes_len = bswap_and_workaround_u32(&header.bytes_len); | 108 | const bytes_len = bswap_and_workaround_u32(buf[4..][0..4]); |
| 110 | // workaround for https://github.com/ziglang/zig/issues/14904 | 109 | const tag = bswap_and_workaround_tag(buf[0..][0..4]); |
| 111 | const tag = bswap_and_workaround_tag(&header.tag); | ||
| 112 | 110 | ||
| 113 | if (buf.len - @sizeOf(Header) >= bytes_len) { | 111 | if (buf.len - @sizeOf(Header) >= bytes_len) { |
| 114 | fifo.discard(@sizeOf(Header)); | 112 | fifo.discard(@sizeOf(Header)); |
| ... | @@ -281,14 +279,12 @@ fn bswap_u32_array(slice: []u32) void { | ... | @@ -281,14 +279,12 @@ fn bswap_u32_array(slice: []u32) void { |
| 281 | } | 279 | } |
| 282 | 280 | ||
| 283 | /// workaround for https://github.com/ziglang/zig/issues/14904 | 281 | /// workaround for https://github.com/ziglang/zig/issues/14904 |
| 284 | fn bswap_and_workaround_u32(x: *align(1) const u32) u32 { | 282 | fn bswap_and_workaround_u32(bytes_ptr: *const [4]u8) u32 { |
| 285 | const bytes_ptr = @ptrCast(*const [4]u8, x); | ||
| 286 | return std.mem.readIntLittle(u32, bytes_ptr); | 283 | return std.mem.readIntLittle(u32, bytes_ptr); |
| 287 | } | 284 | } |
| 288 | 285 | ||
| 289 | /// workaround for https://github.com/ziglang/zig/issues/14904 | 286 | /// workaround for https://github.com/ziglang/zig/issues/14904 |
| 290 | fn bswap_and_workaround_tag(x: *align(1) const InMessage.Tag) InMessage.Tag { | 287 | fn bswap_and_workaround_tag(bytes_ptr: *const [4]u8) InMessage.Tag { |
| 291 | const bytes_ptr = @ptrCast(*const [4]u8, x); | ||
| 292 | const int = std.mem.readIntLittle(u32, bytes_ptr); | 288 | const int = std.mem.readIntLittle(u32, bytes_ptr); |
| 293 | return @intToEnum(InMessage.Tag, int); | 289 | return @intToEnum(InMessage.Tag, int); |
| 294 | } | 290 | } |
test/behavior/atomics.zig+6| ... | @@ -209,6 +209,12 @@ test "atomicrmw with floats" { | ... | @@ -209,6 +209,12 @@ test "atomicrmw with floats" { |
| 209 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 209 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 210 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 210 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 211 | 211 | ||
| 212 | if (builtin.zig_backend == .stage2_c) { | ||
| 213 | // TODO: test.c:34929:7: error: address argument to atomic operation must be a pointer to integer or pointer ('zig_f32 *' (aka 'float *') invalid | ||
| 214 | // when compiling with -std=c99 -pedantic | ||
| 215 | return error.SkipZigTest; | ||
| 216 | } | ||
| 217 | |||
| 212 | if ((builtin.zig_backend == .stage2_llvm or builtin.zig_backend == .stage2_c) and | 218 | if ((builtin.zig_backend == .stage2_llvm or builtin.zig_backend == .stage2_c) and |
| 213 | builtin.cpu.arch == .aarch64) | 219 | builtin.cpu.arch == .aarch64) |
| 214 | { | 220 | { |
test/tests.zig+46-5| ... | @@ -988,18 +988,59 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { | ... | @@ -988,18 +988,59 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 988 | these_tests.overrideZigLibDir("lib"); | 988 | these_tests.overrideZigLibDir("lib"); |
| 989 | these_tests.addIncludePath("test"); | 989 | these_tests.addIncludePath("test"); |
| 990 | 990 | ||
| 991 | const run = b.addRunArtifact(these_tests); | 991 | const qualified_name = b.fmt("{s}-{s}-{s}{s}{s}{s}", .{ |
| 992 | run.skip_foreign_checks = true; | ||
| 993 | run.setName(b.fmt("run test {s}-{s}-{s}{s}{s}{s}", .{ | ||
| 994 | options.name, | 992 | options.name, |
| 995 | triple_txt, | 993 | triple_txt, |
| 996 | @tagName(test_target.optimize_mode), | 994 | @tagName(test_target.optimize_mode), |
| 997 | libc_suffix, | 995 | libc_suffix, |
| 998 | single_threaded_suffix, | 996 | single_threaded_suffix, |
| 999 | backend_suffix, | 997 | backend_suffix, |
| 1000 | })); | 998 | }); |
| 999 | |||
| 1000 | if (test_target.target.ofmt == std.Target.ObjectFormat.c) { | ||
| 1001 | var altered_target = test_target.target; | ||
| 1002 | altered_target.ofmt = null; | ||
| 1001 | 1003 | ||
| 1002 | step.dependOn(&run.step); | 1004 | const compile_c = b.addExecutable(.{ |
| 1005 | .name = qualified_name, | ||
| 1006 | .link_libc = test_target.link_libc, | ||
| 1007 | .target = altered_target, | ||
| 1008 | }); | ||
| 1009 | compile_c.overrideZigLibDir("lib"); | ||
| 1010 | compile_c.addCSourceFileSource(.{ | ||
| 1011 | .source = these_tests.getOutputSource(), | ||
| 1012 | .args = &.{ | ||
| 1013 | // TODO output -std=c89 compatible C code | ||
| 1014 | "-std=c99", | ||
| 1015 | "-pedantic", | ||
| 1016 | "-Werror", | ||
| 1017 | // TODO stop violating these pedantic errors | ||
| 1018 | "-Wno-address-of-packed-member", | ||
| 1019 | "-Wno-gnu-folding-constant", | ||
| 1020 | "-Wno-incompatible-pointer-types", | ||
| 1021 | "-Wno-overlength-strings", | ||
| 1022 | }, | ||
| 1023 | }); | ||
| 1024 | compile_c.addIncludePath("lib"); // for zig.h | ||
| 1025 | if (test_target.link_libc == false and test_target.target.getOsTag() == .windows) { | ||
| 1026 | compile_c.subsystem = .Console; | ||
| 1027 | compile_c.linkSystemLibrary("kernel32"); | ||
| 1028 | compile_c.linkSystemLibrary("ntdll"); | ||
| 1029 | } | ||
| 1030 | |||
| 1031 | const run = b.addRunArtifact(compile_c); | ||
| 1032 | run.skip_foreign_checks = true; | ||
| 1033 | run.enableTestRunnerMode(); | ||
| 1034 | run.setName(b.fmt("run test {s}", .{qualified_name})); | ||
| 1035 | |||
| 1036 | step.dependOn(&run.step); | ||
| 1037 | } else { | ||
| 1038 | const run = b.addRunArtifact(these_tests); | ||
| 1039 | run.skip_foreign_checks = true; | ||
| 1040 | run.setName(b.fmt("run test {s}", .{qualified_name})); | ||
| 1041 | |||
| 1042 | step.dependOn(&run.step); | ||
| 1043 | } | ||
| 1003 | } | 1044 | } |
| 1004 | return step; | 1045 | return step; |
| 1005 | } | 1046 | } |