From ffef5d26b6bbaf52d80c74ac3879a233a7a1a513 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 21 Sep 2019 23:55:56 -0400 Subject: [PATCH] significantly increase test coverage * add zig build option `-Dskip-libc` to skip tests that build libc (e.g. if you don't want to wait for musl to build) * add `-Denable-wine` option which uses wine to run cross compiled windows tests on non-windows hosts * add `-Denable-qemu` option which uses qemu to run cross compiled foreign architecture tests * add `-Denable-foreign-glibc=path` option which combined with `-Denable-qemu` enables running cross compiled tests that link against glibc. See https://github.com/ziglang/zig/wiki/Updating-libc#glibc for how to produce this directory. * the test matrix is done manually. release test builds are only enabled by default for the native target. this should save us some CI time, while still providing decent coverage of release builds. - add test coverage for `x86_64-linux-musl -lc` (building musl libc) - add test coverage for `x86_64-linux-gnu -lc` (building glibc) - add test coverage for `aarch64v8_5a-linux-none` - add test coverage for `aarch64v8_5a-linux-musl -lc` (building musl libc) - add test coverage for `aarch64v8_5a-linux-gnu -lc` (building glibc) - add test coverage for `arm-linux-none` - test coverage for `arm-linux-musleabihf -lc` (building musl libc) is disabled due to #3286 - test coverage for `arm-linux-gnueabihf -lc` (building glibc) is disabled due to #3287 - test coverage for `x86_64-windows-gnu -lc` (building mingw-w64) is disabled due to #3285 * enable qemu testing on the Linux CI job. There's not really a good reason to enable wine, since we have a Windows CI job as well. * remove the no longer needed `--build-file ../build.zig` from CI scripts * fix bug in glibc compilation where it wasn't properly reading the abi list txt files, resulting in "key not found" error. * std.build.Target gains: - isNetBSD - isLinux - osRequiresLibC - getArchPtrBitWidth - getExternalExecutor * zig build system gains support for enabling wine and enabling qemu. `artifact.enable_wine = true;`, `artifact.enable_qemu = true;`. This communicates that the system has these tools installed and the build system will use them to run tests. * zig build system gains support for overriding the dynamic linker of an executable artifact. * fix std.c.lseek prototype. makes behavior tests for arm-linux-musleabihf pass. * disable std lib tests that are failing on ARM. See #3288, #3289 * provide `std.os.off_t`. * disable some of the compiler_rt symbols for arm 32 bit. Fixes compiler_rt tests for arm 32 bit * add __stack_chk_guard when linking against glibc. Fixes std lib tests for aarch64-linux-gnu * workaround for "unable to inline function" using `@inlineCall`. Fixes compiler_rt tests for arm 32 bit. --- build.zig | 14 +- ci/azure/linux_script | 4 +- ci/azure/macos_script | 2 +- ci/azure/windows_script.bat | 2 +- src/glibc.cpp | 2 +- std/build.zig | 175 ++++++++++++- std/c.zig | 2 +- std/fmt/parse_float.zig | 4 + std/fs/path.zig | 8 + std/io/test.zig | 4 + std/os/bits/darwin.zig | 4 +- std/os/bits/freebsd.zig | 4 +- std/os/bits/linux/arm-eabi.zig | 4 +- std/os/bits/linux/arm64.zig | 4 +- std/os/bits/linux/x86_64.zig | 4 +- std/os/bits/netbsd.zig | 4 +- std/os/test.zig | 4 + std/rb.zig | 9 + std/special/compiler_rt.zig | 5 +- std/special/compiler_rt/arm/aeabi_dcmp.zig | 12 +- std/special/compiler_rt/arm/aeabi_fcmp.zig | 12 +- test/tests.zig | 291 ++++++++++++++++----- 22 files changed, 482 insertions(+), 92 deletions(-) diff --git a/build.zig b/build.zig index 457314b42a6d77e1bca4ebb01519c700f59832b5..b38fb87cb7068e44f56d056f4a25ad6b7f027f31 100644 --- a/build.zig +++ b/build.zig @@ -70,6 +70,7 @@ pub fn build(b: *Builder) !void { const skip_release_fast = b.option(bool, "skip-release-fast", "Main test suite skips release-fast builds") orelse skip_release; const skip_release_safe = b.option(bool, "skip-release-safe", "Main test suite skips release-safe builds") orelse skip_release; const skip_non_native = b.option(bool, "skip-non-native", "Main test suite skips non-native builds") orelse false; + const skip_libc = b.option(bool, "skip-libc", "Main test suite skips tests that link libc") orelse false; const skip_self_hosted = b.option(bool, "skip-self-hosted", "Main test suite skips building self hosted compiler") orelse false; if (!skip_self_hosted) { // TODO re-enable this after https://github.com/ziglang/zig/issues/2377 @@ -96,6 +97,10 @@ pub fn build(b: *Builder) !void { const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter"); + const is_wine_enabled = b.option(bool, "enable-wine", "Use Wine to run cross compiled Windows tests") orelse false; + const is_qemu_enabled = b.option(bool, "enable-qemu", "Use QEMU to run cross compiled foreign architecture tests") orelse false; + const glibc_multi_dir = b.option([]const u8, "enable-foreign-glibc", "Provide directory with glibc installations to run cross compiled tests that link glibc"); + const test_stage2_step = b.step("test-stage2", "Run the stage2 compiler tests"); test_stage2_step.dependOn(&test_stage2.step); @@ -122,19 +127,16 @@ pub fn build(b: *Builder) !void { } const modes = chosen_modes[0..chosen_mode_index]; - const multi_and_single = [_]bool{ false, true }; - const just_multi = [_]bool{false}; - // run stage1 `zig fmt` on this build.zig file just to make sure it works test_step.dependOn(&fmt_build_zig.step); const fmt_step = b.step("test-fmt", "Run zig fmt against build.zig to make sure it works"); fmt_step.dependOn(&fmt_build_zig.step); - test_step.dependOn(tests.addPkgTests(b, test_filter, "test/stage1/behavior.zig", "behavior", "Run the behavior tests", modes, multi_and_single, skip_non_native)); + test_step.dependOn(tests.addPkgTests(b, test_filter, "test/stage1/behavior.zig", "behavior", "Run the behavior tests", modes, false, skip_non_native, skip_libc, is_wine_enabled, is_qemu_enabled, glibc_multi_dir)); - test_step.dependOn(tests.addPkgTests(b, test_filter, "std/std.zig", "std", "Run the standard library tests", modes, multi_and_single, skip_non_native)); + test_step.dependOn(tests.addPkgTests(b, test_filter, "std/std.zig", "std", "Run the standard library tests", modes, false, skip_non_native, skip_libc, is_wine_enabled, is_qemu_enabled, glibc_multi_dir)); - test_step.dependOn(tests.addPkgTests(b, test_filter, "std/special/compiler_rt.zig", "compiler-rt", "Run the compiler_rt tests", modes, just_multi, skip_non_native)); + test_step.dependOn(tests.addPkgTests(b, test_filter, "std/special/compiler_rt.zig", "compiler-rt", "Run the compiler_rt tests", modes, true, skip_non_native, true, is_wine_enabled, is_qemu_enabled, glibc_multi_dir)); test_step.dependOn(tests.addCompareOutputTests(b, test_filter, modes)); test_step.dependOn(tests.addStandaloneTests(b, test_filter, modes)); diff --git a/ci/azure/linux_script b/ci/azure/linux_script index 65724e7827098f45d84ec32da0f5babeece5ed55..e12f16f15f47f012514c69280660a6f64377d05b 100755 --- a/ci/azure/linux_script +++ b/ci/azure/linux_script @@ -12,7 +12,7 @@ sudo apt-get update -q sudo apt-get remove -y llvm-* sudo rm -rf /usr/local/* -sudo apt-get install -y libxml2-dev libclang-9-dev llvm-9 llvm-9-dev cmake s3cmd gcc-7 g++-7 +sudo apt-get install -y libxml2-dev libclang-9-dev llvm-9 llvm-9-dev cmake s3cmd gcc-7 g++-7 qemu export CC=gcc-7 export CXX=g++-7 @@ -20,7 +20,7 @@ mkdir build cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j2 install -./zig build --build-file ../build.zig test +./zig build test -Denable-qemu if [ "${BUILD_REASON}" != "PullRequest" ]; then ARTIFACTSDIR="$BUILDDIR/artifacts" diff --git a/ci/azure/macos_script b/ci/azure/macos_script index 1253f78b875a5a8a8bd21c928f5e2df63025dc6c..adfe3c7178c657a96e2f8d00763853cacc4c224d 100755 --- a/ci/azure/macos_script +++ b/ci/azure/macos_script @@ -70,7 +70,7 @@ mkdir build cd build cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_INSTALL_PREFIX=$(pwd)/release -DZIG_STATIC=ON make $JOBS install -release/bin/zig build --build-file ../build.zig test +release/bin/zig build test if [ "${BUILD_REASON}" != "PullRequest" ]; then mv ../LICENSE release/ diff --git a/ci/azure/windows_script.bat b/ci/azure/windows_script.bat index 9d1dbfb7c44a063bb70d60d58bdc102febc7e68c..32b394852f60da59d11d4dc88c6e52c19ded968a 100644 --- a/ci/azure/windows_script.bat +++ b/ci/azure/windows_script.bat @@ -20,7 +20,7 @@ cd %ZIGBUILDDIR% cmake.exe .. -Thost=x64 -G"Visual Studio 15 2017 Win64" "-DCMAKE_INSTALL_PREFIX=%ZIGINSTALLDIR%" "-DCMAKE_PREFIX_PATH=%ZIGPREFIXPATH%" -DCMAKE_BUILD_TYPE=Release || exit /b msbuild /p:Configuration=Release INSTALL.vcxproj || exit /b -"%ZIGINSTALLDIR%\bin\zig.exe" build --build-file ..\build.zig test || exit /b +"%ZIGINSTALLDIR%\bin\zig.exe" build test || exit /b set "PATH=%CD:~0,2%\msys64\usr\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem" SET "MSYSTEM=MINGW64" diff --git a/src/glibc.cpp b/src/glibc.cpp index d7ae47ed71973d307d2250a0ba4e5df9964f0137..c6ac875048a0c4218a0d4cb768f9ad630a0ba649 100644 --- a/src/glibc.cpp +++ b/src/glibc.cpp @@ -99,9 +99,9 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo if (!opt_line.is_some) break; ver_list_base = allocate(glibc_abi->all_functions.length); - ZigTarget *target = allocate(1); SplitIterator line_it = memSplit(opt_line.value, str(" ")); for (;;) { + ZigTarget *target = allocate(1); Optional> opt_target = SplitIterator_next(&line_it); if (!opt_target.is_some) break; diff --git a/std/build.zig b/std/build.zig index 54a49e9d58e554af20359bc9b162f5ee87ef4cf9..cddf7c72a18bbb96d2c3710d5dc03a4a333ae70c 100644 --- a/std/build.zig +++ b/std/build.zig @@ -1175,6 +1175,13 @@ pub const Target = union(enum) { }; } + pub fn isLinux(self: Target) bool { + return switch (self.getOs()) { + .linux => true, + else => false, + }; + } + pub fn isUefi(self: Target) bool { return switch (self.getOs()) { .uefi => true, @@ -1196,9 +1203,125 @@ pub const Target = union(enum) { }; } + pub fn isNetBSD(self: Target) bool { + return switch (self.getOs()) { + .netbsd => true, + else => false, + }; + } + pub fn wantSharedLibSymLinks(self: Target) bool { return !self.isWindows(); } + + pub fn osRequiresLibC(self: Target) bool { + return self.isDarwin() or self.isFreeBSD() or self.isNetBSD(); + } + + pub fn getArchPtrBitWidth(self: Target) u32 { + switch (self.getArch()) { + .avr, + .msp430, + => return 16, + + .arc, + .arm, + .armeb, + .hexagon, + .le32, + .mips, + .mipsel, + .powerpc, + .r600, + .riscv32, + .sparc, + .sparcel, + .tce, + .tcele, + .thumb, + .thumbeb, + .i386, + .xcore, + .nvptx, + .amdil, + .hsail, + .spir, + .kalimba, + .shave, + .lanai, + .wasm32, + .renderscript32, + .aarch64_32, + => return 32, + + .aarch64, + .aarch64_be, + .mips64, + .mips64el, + .powerpc64, + .powerpc64le, + .riscv64, + .x86_64, + .nvptx64, + .le64, + .amdil64, + .hsail64, + .spir64, + .wasm64, + .renderscript64, + .amdgcn, + .bpfel, + .bpfeb, + .sparcv9, + .s390x, + => return 64, + } + } + + pub const Executor = union(enum) { + native, + qemu: []const u8, + wine: []const u8, + unavailable, + }; + + pub fn getExternalExecutor(self: Target) Executor { + if (@TagType(Target)(self) == .Native) return .native; + + // If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture. + if (self.getOs() == builtin.os) { + return switch (self.getArch()) { + .aarch64 => Executor{ .qemu = "qemu-aarch64" }, + .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" }, + .arm => Executor{ .qemu = "qemu-arm" }, + .armeb => Executor{ .qemu = "qemu-armeb" }, + .i386 => Executor{ .qemu = "qemu-i386" }, + .mips => Executor{ .qemu = "qemu-mips" }, + .mipsel => Executor{ .qemu = "qemu-mipsel" }, + .mips64 => Executor{ .qemu = "qemu-mips64" }, + .mips64el => Executor{ .qemu = "qemu-mips64el" }, + .powerpc => Executor{ .qemu = "qemu-ppc" }, + .powerpc64 => Executor{ .qemu = "qemu-ppc64" }, + .powerpc64le => Executor{ .qemu = "qemu-ppc64le" }, + .riscv32 => Executor{ .qemu = "qemu-riscv32" }, + .riscv64 => Executor{ .qemu = "qemu-riscv64" }, + .s390x => Executor{ .qemu = "qemu-s390x" }, + .sparc => Executor{ .qemu = "qemu-sparc" }, + .x86_64 => Executor{ .qemu = "qemu-x86_64" }, + else => return .unavailable, + }; + } + + if (self.isWindows()) { + switch (self.getArchPtrBitWidth()) { + 32 => return Executor{ .wine = "wine" }, + 64 => return Executor{ .wine = "wine64" }, + else => return .unavailable, + } + } + + return .unavailable; + } }; const Pkg = struct { @@ -1266,6 +1389,7 @@ pub const LibExeObjStep = struct { include_dirs: ArrayList(IncludeDir), output_dir: ?[]const u8, need_system_paths: bool, + is_linking_libc: bool = false, installed_path: ?[]const u8, install_step: ?*InstallArtifactStep, @@ -1275,6 +1399,20 @@ pub const LibExeObjStep = struct { valgrind_support: ?bool = null, + /// Uses system Wine installation to run cross compiled Windows build artifacts. + enable_wine: bool = false, + + /// Uses system QEMU installation to run cross compiled foreign architecture build artifacts. + enable_qemu: bool = false, + + /// After following the steps in https://github.com/ziglang/zig/wiki/Updating-libc#glibc, + /// this will be the directory $glibc-build-dir/install/glibcs + /// Given the example of the aarch64 target, this is the directory + /// that contains the path `aarch64-linux-gnu/lib/ld-linux-aarch64.so.1`. + glibc_multi_install_dir: ?[]const u8 = null, + + dynamic_linker: ?[]const u8 = null, + const LinkObject = union(enum) { StaticPath: []const u8, OtherStep: *LibExeObjStep, @@ -1504,7 +1642,9 @@ pub const LibExeObjStep = struct { pub fn linkSystemLibrary(self: *LibExeObjStep, name: []const u8) void { self.link_objects.append(LinkObject{ .SystemLib = self.builder.dupe(name) }) catch unreachable; - if (!isLibCLibrary(name)) { + if (isLibCLibrary(name)) { + self.is_linking_libc = true; + } else { self.need_system_paths = true; } } @@ -1840,6 +1980,11 @@ pub const LibExeObjStep = struct { zig_args.append(builder.pathFromRoot(linker_script)) catch unreachable; } + if (self.dynamic_linker) |dynamic_linker| { + try zig_args.append("--dynamic-linker"); + try zig_args.append(dynamic_linker); + } + if (self.version_script) |version_script| { try zig_args.append("--version-script"); try zig_args.append(builder.pathFromRoot(version_script)); @@ -1854,6 +1999,34 @@ pub const LibExeObjStep = struct { try zig_args.append("--test-cmd-bin"); } } + } else switch (self.target.getExternalExecutor()) { + .native, .unavailable => {}, + .qemu => |bin_name| if (self.enable_qemu) qemu: { + const need_cross_glibc = self.target.isGnu() and self.target.isLinux() and self.is_linking_libc; + const glibc_dir_arg = if (need_cross_glibc) + self.glibc_multi_install_dir orelse break :qemu + else + null; + try zig_args.append("--test-cmd"); + try zig_args.append(bin_name); + if (glibc_dir_arg) |dir| { + const full_dir = try fs.path.join(builder.allocator, [_][]const u8{ + dir, + try self.target.linuxTriple(builder.allocator), + }); + + try zig_args.append("--test-cmd"); + try zig_args.append("-L"); + try zig_args.append("--test-cmd"); + try zig_args.append(full_dir); + } + try zig_args.append("--test-cmd-bin"); + }, + .wine => |bin_name| if (self.enable_wine) { + try zig_args.append("--test-cmd"); + try zig_args.append(bin_name); + try zig_args.append("--test-cmd-bin"); + }, } for (self.packages.toSliceConst()) |pkg| { zig_args.append("--pkg-begin") catch unreachable; diff --git a/std/c.zig b/std/c.zig index 45d93bfd9f635abd231409dfd09073a9bad97a93..5c280ac551de509833e4bde1d1c1cba0c7a5ff6b 100644 --- a/std/c.zig +++ b/std/c.zig @@ -63,7 +63,7 @@ pub extern "c" fn close(fd: fd_t) c_int; pub extern "c" fn @"close$NOCANCEL"(fd: fd_t) c_int; pub extern "c" fn fstat(fd: fd_t, buf: *Stat) c_int; pub extern "c" fn @"fstat$INODE64"(fd: fd_t, buf: *Stat) c_int; -pub extern "c" fn lseek(fd: fd_t, offset: isize, whence: c_int) isize; +pub extern "c" fn lseek(fd: fd_t, offset: off_t, whence: c_int) off_t; pub extern "c" fn open(path: [*]const u8, oflag: c_uint, ...) c_int; pub extern "c" fn openat(fd: c_int, path: [*]const u8, oflag: c_uint, ...) c_int; pub extern "c" fn raise(sig: c_int) c_int; diff --git a/std/fmt/parse_float.zig b/std/fmt/parse_float.zig index d0a826a55ef62d60c978aabe4ed62d7b32639e51..9a35e27c21909d9bb933f2b9f12728bdc1d36de4 100644 --- a/std/fmt/parse_float.zig +++ b/std/fmt/parse_float.zig @@ -382,6 +382,10 @@ pub fn parseFloat(comptime T: type, s: []const u8) !T { } test "fmt.parseFloat" { + if (@import("builtin").arch == .arm) { + // TODO https://github.com/ziglang/zig/issues/3289 + return error.SkipZigTest; + } const testing = std.testing; const expect = testing.expect; const expectEqual = testing.expectEqual; diff --git a/std/fs/path.zig b/std/fs/path.zig index 0181e949ddc55caf3c93f53578a6603896e4d5a8..2bb23f04cedd84f7b83cce491fb4ddee8109e2ee 100644 --- a/std/fs/path.zig +++ b/std/fs/path.zig @@ -646,6 +646,10 @@ test "resolve" { } test "resolveWindows" { + if (@import("builtin").arch == .aarch64) { + // TODO https://github.com/ziglang/zig/issues/3288 + return error.SkipZigTest; + } if (windows.is_the_target) { const cwd = try process.getCwdAlloc(debug.global_allocator); const parsed_cwd = windowsParsePath(cwd); @@ -1086,6 +1090,10 @@ pub fn relativePosix(allocator: *Allocator, from: []const u8, to: []const u8) ![ } test "relative" { + if (@import("builtin").arch == .aarch64) { + // TODO https://github.com/ziglang/zig/issues/3288 + return error.SkipZigTest; + } testRelativeWindows("c:/blah\\blah", "d:/games", "D:\\games"); testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa", ".."); testRelativeWindows("c:/aaaa/bbbb", "c:/cccc", "..\\..\\cccc"); diff --git a/std/io/test.zig b/std/io/test.zig index 40258eab5f2e67c9a1411e1a754f29bd95067fe7..e624733ba8e4508f067230d8ee6719e92d3fd1dc 100644 --- a/std/io/test.zig +++ b/std/io/test.zig @@ -11,6 +11,10 @@ const fs = std.fs; const File = std.fs.File; test "write a file, read it, then delete it" { + if (builtin.arch == .aarch64 and builtin.glibc_version != null) { + // TODO https://github.com/ziglang/zig/issues/3288 + return error.SkipZigTest; + } var raw_bytes: [200 * 1024]u8 = undefined; var allocator = &std.heap.FixedBufferAllocator.init(raw_bytes[0..]).allocator; diff --git a/std/os/bits/darwin.zig b/std/os/bits/darwin.zig index 483d4cda908f157d9a585339ee07cfaa7b6ad9b0..69dcdf06cc6f5b905d75ed9dab53982a22ddd812 100644 --- a/std/os/bits/darwin.zig +++ b/std/os/bits/darwin.zig @@ -43,6 +43,8 @@ pub const mach_timebase_info_data = extern struct { denom: u32, }; +pub const off_t = i64; + /// Renamed to Stat to not conflict with the stat function. /// atime, mtime, and ctime have functions to return `timespec`, /// because although this is a POSIX API, the layout and names of @@ -65,7 +67,7 @@ pub const Stat = extern struct { ctimensec: isize, birthtimesec: isize, birthtimensec: isize, - size: i64, + size: off_t, blocks: i64, blksize: i32, flags: u32, diff --git a/std/os/bits/freebsd.zig b/std/os/bits/freebsd.zig index 45432a6c076d82ac2845651a70e0f10ce89d8408..4be95b05658a194e0c6f7c9d847987b3b6f8fc4b 100644 --- a/std/os/bits/freebsd.zig +++ b/std/os/bits/freebsd.zig @@ -73,6 +73,8 @@ pub const msghdr_const = extern struct { msg_flags: i32, }; +pub const off_t = i64; + /// Renamed to Stat to not conflict with the stat function. /// atime, mtime, and ctime have functions to return `timespec`, /// because although this is a POSIX API, the layout and names of @@ -96,7 +98,7 @@ pub const Stat = extern struct { ctim: timespec, birthtim: timespec, - size: i64, + size: off_t, blocks: i64, blksize: isize, flags: u32, diff --git a/std/os/bits/linux/arm-eabi.zig b/std/os/bits/linux/arm-eabi.zig index fef63110eea21ae2ee1ffdcd341e3cf717b1108d..4b3e1094da3ee0c129b4a00e157b364891408e94 100644 --- a/std/os/bits/linux/arm-eabi.zig +++ b/std/os/bits/linux/arm-eabi.zig @@ -511,6 +511,8 @@ pub const msghdr_const = extern struct { msg_flags: i32, }; +pub const off_t = i64; + /// Renamed to Stat to not conflict with the stat function. /// atime, mtime, and ctime have functions to return `timespec`, /// because although this is a POSIX API, the layout and names of @@ -527,7 +529,7 @@ pub const Stat = extern struct { gid: u32, rdev: u64, __rdev_padding: u32, - size: i64, + size: off_t, blksize: i32, blocks: u64, atim: timespec, diff --git a/std/os/bits/linux/arm64.zig b/std/os/bits/linux/arm64.zig index 2b1b5d07eee02c94b47fa966c32c528086082613..657424cd6dc546f2e9073115687c8a40494f34f4 100644 --- a/std/os/bits/linux/arm64.zig +++ b/std/os/bits/linux/arm64.zig @@ -382,6 +382,8 @@ pub const msghdr_const = extern struct { msg_flags: i32, }; +pub const off_t = i64; + /// Renamed to Stat to not conflict with the stat function. /// atime, mtime, and ctime have functions to return `timespec`, /// because although this is a POSIX API, the layout and names of @@ -398,7 +400,7 @@ pub const Stat = extern struct { gid: u32, __pad0: u32, rdev: u64, - size: i64, + size: off_t, blksize: isize, blocks: i64, diff --git a/std/os/bits/linux/x86_64.zig b/std/os/bits/linux/x86_64.zig index 9548e0803a9b11dedef682dffa0f22bd2b4ca83e..626acd00d61799bc83290325f82c5d1f8bc85a46 100644 --- a/std/os/bits/linux/x86_64.zig +++ b/std/os/bits/linux/x86_64.zig @@ -479,6 +479,8 @@ pub const msghdr_const = extern struct { msg_flags: i32, }; +pub const off_t = i64; + /// Renamed to Stat to not conflict with the stat function. /// atime, mtime, and ctime have functions to return `timespec`, /// because although this is a POSIX API, the layout and names of @@ -495,7 +497,7 @@ pub const Stat = extern struct { gid: u32, __pad0: u32, rdev: u64, - size: i64, + size: off_t, blksize: isize, blocks: i64, diff --git a/std/os/bits/netbsd.zig b/std/os/bits/netbsd.zig index ff19d090af715c2b8b05be9f134f8b3a4d9d995d..1408b60ab0a07a03f9fb13a54dfd2f961ffaec3d 100644 --- a/std/os/bits/netbsd.zig +++ b/std/os/bits/netbsd.zig @@ -73,6 +73,8 @@ pub const msghdr_const = extern struct { msg_flags: i32, }; +pub const off_t = i64; + /// Renamed to Stat to not conflict with the stat function. /// atime, mtime, and ctime have functions to return `timespec`, /// because although this is a POSIX API, the layout and names of @@ -94,7 +96,7 @@ pub const Stat = extern struct { ctim: timespec, birthtim: timespec, - size: i64, + size: off_t, blocks: i64, blksize: isize, flags: u32, diff --git a/std/os/test.zig b/std/os/test.zig index a821c5dd9fe2acd9e1fbdbcfc7b63a72137c0c0a..a0bb7405290388a81c8f77159689e62c2ded53dd 100644 --- a/std/os/test.zig +++ b/std/os/test.zig @@ -95,6 +95,10 @@ test "cpu count" { } test "AtomicFile" { + if (builtin.arch == .aarch64 and builtin.glibc_version != null) { + // TODO https://github.com/ziglang/zig/issues/3288 + return error.SkipZigTest; + } var buffer: [1024]u8 = undefined; const allocator = &std.heap.FixedBufferAllocator.init(buffer[0..]).allocator; const test_out_file = "tmp_atomic_file_test_dest.txt"; diff --git a/std/rb.zig b/std/rb.zig index 3f2a2d5bb09ce3a4c25a104ae36abe0f81b6a446..4180c7459c3c62de30f66eb3f7ab5af667b22d01 100644 --- a/std/rb.zig +++ b/std/rb.zig @@ -511,6 +511,11 @@ fn testCompare(l: *Node, r: *Node) mem.Compare { } test "rb" { + if (@import("builtin").arch == .aarch64) { + // TODO https://github.com/ziglang/zig/issues/3288 + return error.SkipZigTest; + } + var tree: Tree = undefined; var ns: [10]testNumber = undefined; ns[0].value = 42; @@ -571,6 +576,10 @@ test "inserting and looking up" { } test "multiple inserts, followed by calling first and last" { + if (@import("builtin").arch == .aarch64) { + // TODO https://github.com/ziglang/zig/issues/3288 + return error.SkipZigTest; + } var tree: Tree = undefined; tree.init(testCompare); var zeroth: testNumber = undefined; diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig index a5bbefa1db801fefcfc4b7e2e4507a77d45f5f97..b222c31d835a16977befa1f320113ba8541ad3c8 100644 --- a/std/special/compiler_rt.zig +++ b/std/special/compiler_rt.zig @@ -143,7 +143,7 @@ comptime { @export("__negsf2", @import("compiler_rt/negXf2.zig").__negsf2, linkage); @export("__negdf2", @import("compiler_rt/negXf2.zig").__negdf2, linkage); - if (is_arm_arch and !is_arm_64) { + if (is_arm_arch and !is_arm_64 and !is_test) { @export("__aeabi_unwind_cpp_pr0", __aeabi_unwind_cpp_pr0, strong_linkage); @export("__aeabi_unwind_cpp_pr1", __aeabi_unwind_cpp_pr1, linkage); @export("__aeabi_unwind_cpp_pr2", __aeabi_unwind_cpp_pr2, linkage); @@ -264,6 +264,9 @@ comptime { else => {}, } } else { + if (builtin.glibc_version != null) { + @export("__stack_chk_guard", __stack_chk_guard, linkage); + } @export("__divti3", @import("compiler_rt/divti3.zig").__divti3, linkage); @export("__modti3", @import("compiler_rt/modti3.zig").__modti3, linkage); @export("__multi3", @import("compiler_rt/multi3.zig").__multi3, linkage); diff --git a/std/special/compiler_rt/arm/aeabi_dcmp.zig b/std/special/compiler_rt/arm/aeabi_dcmp.zig index a51d9854cea0d50fb2b35219eb3cd00d36ef663e..33bfdabcfbac54f033b3e64466eb532750323313 100644 --- a/std/special/compiler_rt/arm/aeabi_dcmp.zig +++ b/std/special/compiler_rt/arm/aeabi_dcmp.zig @@ -14,31 +14,31 @@ const ConditionalOperator = enum { pub nakedcc fn __aeabi_dcmpeq() noreturn { @setRuntimeSafety(false); - aeabi_dcmp(.Eq); + @inlineCall(aeabi_dcmp, .Eq); unreachable; } pub nakedcc fn __aeabi_dcmplt() noreturn { @setRuntimeSafety(false); - aeabi_dcmp(.Lt); + @inlineCall(aeabi_dcmp, .Lt); unreachable; } pub nakedcc fn __aeabi_dcmple() noreturn { @setRuntimeSafety(false); - aeabi_dcmp(.Le); + @inlineCall(aeabi_dcmp, .Le); unreachable; } pub nakedcc fn __aeabi_dcmpge() noreturn { @setRuntimeSafety(false); - aeabi_dcmp(.Ge); + @inlineCall(aeabi_dcmp, .Ge); unreachable; } pub nakedcc fn __aeabi_dcmpgt() noreturn { @setRuntimeSafety(false); - aeabi_dcmp(.Gt); + @inlineCall(aeabi_dcmp, .Gt); unreachable; } @@ -49,7 +49,7 @@ inline fn convert_dcmp_args_to_df2_args() void { ); } -inline fn aeabi_dcmp(comptime cond: ConditionalOperator) void { +fn aeabi_dcmp(comptime cond: ConditionalOperator) void { @setRuntimeSafety(false); asm volatile ( \\ push { r4, lr } diff --git a/std/special/compiler_rt/arm/aeabi_fcmp.zig b/std/special/compiler_rt/arm/aeabi_fcmp.zig index f82dd25270cf748d722c59446c2d04ccd787d583..cc5efc64fc0000deef7d555509fd4f18c084578f 100644 --- a/std/special/compiler_rt/arm/aeabi_fcmp.zig +++ b/std/special/compiler_rt/arm/aeabi_fcmp.zig @@ -14,31 +14,31 @@ const ConditionalOperator = enum { pub nakedcc fn __aeabi_fcmpeq() noreturn { @setRuntimeSafety(false); - aeabi_fcmp(.Eq); + @inlineCall(aeabi_fcmp, .Eq); unreachable; } pub nakedcc fn __aeabi_fcmplt() noreturn { @setRuntimeSafety(false); - aeabi_fcmp(.Lt); + @inlineCall(aeabi_fcmp, .Lt); unreachable; } pub nakedcc fn __aeabi_fcmple() noreturn { @setRuntimeSafety(false); - aeabi_fcmp(.Le); + @inlineCall(aeabi_fcmp, .Le); unreachable; } pub nakedcc fn __aeabi_fcmpge() noreturn { @setRuntimeSafety(false); - aeabi_fcmp(.Ge); + @inlineCall(aeabi_fcmp, .Ge); unreachable; } pub nakedcc fn __aeabi_fcmpgt() noreturn { @setRuntimeSafety(false); - aeabi_fcmp(.Gt); + @inlineCall(aeabi_fcmp, .Gt); unreachable; } @@ -49,7 +49,7 @@ inline fn convert_fcmp_args_to_sf2_args() void { ); } -inline fn aeabi_fcmp(comptime cond: ConditionalOperator) void { +fn aeabi_fcmp(comptime cond: ConditionalOperator) void { @setRuntimeSafety(false); asm volatile ( \\ push { r4, lr } diff --git a/test/tests.zig b/test/tests.zig index bbaf62ac94dfb2a9fec54a7443d9314e2582d41a..327dd0c070dd1255685b3ed9469f133ffbef1610 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -23,22 +23,181 @@ const runtime_safety = @import("runtime_safety.zig"); const translate_c = @import("translate_c.zig"); const gen_h = @import("gen_h.zig"); -const cross_targets = [_]CrossTarget{ - CrossTarget{ - .os = .linux, - .arch = .x86_64, - .abi = .gnu, - }, - CrossTarget{ - .os = .macosx, - .arch = .x86_64, - .abi = .gnu, - }, - CrossTarget{ - .os = .windows, - .arch = .x86_64, - .abi = .msvc, +const TestTarget = struct { + target: Target = .Native, + mode: builtin.Mode = .Debug, + link_libc: bool = false, + single_threaded: bool = false, +}; + +const test_targets = [_]TestTarget{ + TestTarget{}, + TestTarget{ + .link_libc = true, }, + TestTarget{ + .single_threaded = true, + }, + + TestTarget{ + .mode = .ReleaseFast, + }, + TestTarget{ + .link_libc = true, + .mode = .ReleaseFast, + }, + TestTarget{ + .mode = .ReleaseFast, + .single_threaded = true, + }, + + TestTarget{ + .mode = .ReleaseSafe, + }, + TestTarget{ + .link_libc = true, + .mode = .ReleaseSafe, + }, + TestTarget{ + .mode = .ReleaseSafe, + .single_threaded = true, + }, + + TestTarget{ + .mode = .ReleaseSmall, + }, + TestTarget{ + .link_libc = true, + .mode = .ReleaseSmall, + }, + TestTarget{ + .mode = .ReleaseSmall, + .single_threaded = true, + }, + + TestTarget{ + .target = Target{ + .Cross = CrossTarget{ + .os = .linux, + .arch = .x86_64, + .abi = .none, + }, + }, + }, + TestTarget{ + .target = Target{ + .Cross = CrossTarget{ + .os = .linux, + .arch = .x86_64, + .abi = .gnu, + }, + }, + .link_libc = true, + }, + TestTarget{ + .target = Target{ + .Cross = CrossTarget{ + .os = .linux, + .arch = .x86_64, + .abi = .musl, + }, + }, + .link_libc = true, + }, + + TestTarget{ + .target = Target{ + .Cross = CrossTarget{ + .os = .linux, + .arch = builtin.Arch{ .aarch64 = builtin.Arch.Arm64.v8_5a }, + .abi = .none, + }, + }, + }, + TestTarget{ + .target = Target{ + .Cross = CrossTarget{ + .os = .linux, + .arch = builtin.Arch{ .aarch64 = builtin.Arch.Arm64.v8_5a }, + .abi = .musl, + }, + }, + .link_libc = true, + }, + TestTarget{ + .target = Target{ + .Cross = CrossTarget{ + .os = .linux, + .arch = builtin.Arch{ .aarch64 = builtin.Arch.Arm64.v8_5a }, + .abi = .gnu, + }, + }, + .link_libc = true, + }, + + TestTarget{ + .target = Target{ + .Cross = CrossTarget{ + .os = .linux, + .arch = builtin.Arch{ .arm = builtin.Arch.Arm32.v8_5a }, + .abi = .none, + }, + }, + }, + // TODO https://github.com/ziglang/zig/issues/3286 + //TestTarget{ + // .target = Target{ + // .Cross = CrossTarget{ + // .os = .linux, + // .arch = builtin.Arch{ .arm = builtin.Arch.Arm32.v8_5a }, + // .abi = .musleabihf, + // }, + // }, + // .link_libc = true, + //}, + // TODO https://github.com/ziglang/zig/issues/3287 + //TestTarget{ + // .target = Target{ + // .Cross = CrossTarget{ + // .os = .linux, + // .arch = builtin.Arch{ .arm = builtin.Arch.Arm32.v8_5a }, + // .abi = .gnueabihf, + // }, + // }, + // .link_libc = true, + //}, + + TestTarget{ + .target = Target{ + .Cross = CrossTarget{ + .os = .macosx, + .arch = .x86_64, + .abi = .gnu, + }, + }, + }, + + TestTarget{ + .target = Target{ + .Cross = CrossTarget{ + .os = .windows, + .arch = .x86_64, + .abi = .msvc, + }, + }, + }, + + // TODO https://github.com/ziglang/zig/issues/3285 + //TestTarget{ + // .target = Target{ + // .Cross = CrossTarget{ + // .os = .windows, + // .arch = .x86_64, + // .abi = .gnu, + // }, + // }, + // .link_libc = true, + //}, }; const max_stdout_size = 1 * 1024 * 1024; // 1 MB @@ -182,57 +341,69 @@ pub fn addPkgTests( name: []const u8, desc: []const u8, modes: []const Mode, - single_threaded_list: []const bool, + skip_single_threaded: bool, skip_non_native: bool, + skip_libc: bool, + is_wine_enabled: bool, + is_qemu_enabled: bool, + glibc_dir: ?[]const u8, ) *build.Step { const step = b.step(b.fmt("test-{}", name), desc); - var targets = std.ArrayList(*const CrossTarget).init(b.allocator); - defer targets.deinit(); - const host = CrossTarget{ .os = builtin.os, .arch = builtin.arch, .abi = builtin.abi }; - targets.append(&host) catch unreachable; - for (cross_targets) |*t| { - if (t.os == builtin.os and t.arch == builtin.arch and t.abi == builtin.abi) continue; - targets.append(t) catch unreachable; - } - - for (targets.toSliceConst()) |test_target| { - const is_native = (test_target.os == builtin.os and test_target.arch == builtin.arch); - if (skip_non_native and !is_native) + for (test_targets) |test_target| { + if (skip_non_native and test_target.target != .Native) continue; - for (modes) |mode| { - for ([_]bool{ false, true }) |link_libc| { - for (single_threaded_list) |single_threaded| { - if (link_libc and !is_native) { - // don't assume we have a cross-compiling libc set up - continue; - } - const these_tests = b.addTest(root_src); - these_tests.setNamePrefix(b.fmt( - "{}-{}-{}-{}-{}-{} ", - name, - @tagName(test_target.os), - @tagName(test_target.arch), - @tagName(mode), - if (link_libc) "c" else "bare", - if (single_threaded) "single" else "multi", - )); - these_tests.single_threaded = single_threaded; - these_tests.setFilter(test_filter); - these_tests.setBuildMode(mode); - if (!is_native) { - these_tests.setTarget(test_target.arch, test_target.os, test_target.abi); - } - if (link_libc) { - these_tests.linkSystemLibrary("c"); - } - if (mem.eql(u8, name, "std")) { - these_tests.overrideStdDir("std"); - } - step.dependOn(&these_tests.step); - } - } + + if (skip_libc and test_target.link_libc) + continue; + + if (test_target.link_libc and test_target.target.osRequiresLibC()) { + // This would be a redundant test. + continue; + } + + if (skip_single_threaded and test_target.single_threaded) + continue; + + const want_this_mode = for (modes) |m| { + if (m == test_target.mode) break true; + } else false; + if (!want_this_mode) continue; + + const libc_prefix = if (test_target.target.osRequiresLibC()) + "" + else if (test_target.link_libc) + "c" + else + "bare"; + + const triple_prefix = if (test_target.target == .Native) + ([]const u8)("native") + else + test_target.target.zigTripleNoSubArch(b.allocator) catch unreachable; + + const these_tests = b.addTest(root_src); + these_tests.setNamePrefix(b.fmt( + "{}-{}-{}-{}-{} ", + name, + triple_prefix, + @tagName(test_target.mode), + libc_prefix, + if (test_target.single_threaded) "single" else "multi", + )); + these_tests.single_threaded = test_target.single_threaded; + these_tests.setFilter(test_filter); + these_tests.setBuildMode(test_target.mode); + these_tests.setTheTarget(test_target.target); + if (test_target.link_libc) { + these_tests.linkSystemLibrary("c"); } + these_tests.overrideStdDir("std"); + these_tests.enable_wine = is_wine_enabled; + these_tests.enable_qemu = is_qemu_enabled; + these_tests.glibc_multi_install_dir = glibc_dir; + + step.dependOn(&these_tests.step); } return step; } -- 2.54.0