diff --git a/build.zig b/build.zig index 457314b42a..b38fb87cb7 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 65724e7827..e12f16f15f 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 1253f78b87..adfe3c7178 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 9d1dbfb7c4..32b394852f 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 d7ae47ed71..c6ac875048 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 54a49e9d58..cddf7c72a1 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 45d93bfd9f..5c280ac551 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 d0a826a55e..9a35e27c21 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 0181e949dd..2bb23f04ce 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 40258eab5f..e624733ba8 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 483d4cda90..69dcdf06cc 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 45432a6c07..4be95b0565 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 fef63110ee..4b3e1094da 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 2b1b5d07ee..657424cd6d 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 9548e0803a..626acd00d6 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 ff19d090af..1408b60ab0 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 a821c5dd9f..a0bb740529 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 3f2a2d5bb0..4180c7459c 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 a5bbefa1db..b222c31d83 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 a51d9854ce..33bfdabcfb 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 f82dd25270..cc5efc64fc 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 bbaf62ac94..327dd0c070 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, +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, }, - CrossTarget{ - .os = .macosx, - .arch = .x86_64, - .abi = .gnu, + TestTarget{ + .single_threaded = true, }, - CrossTarget{ - .os = .windows, - .arch = .x86_64, - .abi = .msvc, + + 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; + + 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; - 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_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; }