Commit ffef5d26b6
Changed files (22)
src
std
fs
io
special
compiler_rt
test
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"
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/
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"
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<ZigGLibCVerList>(glibc_abi->all_functions.length);
- ZigTarget *target = allocate<ZigTarget>(1);
SplitIterator line_it = memSplit(opt_line.value, str(" "));
for (;;) {
+ ZigTarget *target = allocate<ZigTarget>(1);
Optional<Slice<uint8_t>> opt_target = SplitIterator_next(&line_it);
if (!opt_target.is_some) break;
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;
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");
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;
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,
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,
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,
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,
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,
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,
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";
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 }
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 }
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);
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;
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;
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;
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,
+ },
+ 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,
},
- CrossTarget{
- .os = .macosx,
- .arch = .x86_64,
- .abi = .gnu,
+ TestTarget{
+ .link_libc = true,
+ .mode = .ReleaseSmall,
},
- CrossTarget{
- .os = .windows,
- .arch = .x86_64,
- .abi = .msvc,
+ 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 (test_targets) |test_target| {
+ if (skip_non_native and test_target.target != .Native)
+ continue;
- 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)
+ if (skip_libc and test_target.link_libc)
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 (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;
}
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));