From ffef5d26b6bbaf52d80c74ac3879a233a7a1a513 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 21 Sep 2019 23:55:56 -0400 Subject: [PATCH 01/18] 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 | 287 ++++++++++++++++----- 22 files changed, 480 insertions(+), 90 deletions(-) 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; } From dc2463d9a9c67aa495883325ca62b172402ab4db Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 00:46:49 -0400 Subject: [PATCH 02/18] windows ci: make the case of file names agree --- ci/azure/windows_script.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/azure/windows_script.bat b/ci/azure/windows_script.bat index 32b394852f..dcd78981eb 100644 --- a/ci/azure/windows_script.bat +++ b/ci/azure/windows_script.bat @@ -10,7 +10,7 @@ SET "PATH=%PREVPATH%" SET "MSYSTEM=%PREVMSYSTEM%" SET "ZIGBUILDDIR=%SRCROOT%\build" -SET "ZIGINSTALLDIR=%ZIGBUILDDIR%\release" +SET "ZIGINSTALLDIR=%ZIGBUILDDIR%\Release" SET "ZIGPREFIXPATH=%SRCROOT%\llvm+clang-9.0.0-win64-msvc-release" call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 From 2510edeb71cad68bd133fd1e3dce08f3a74bbdc7 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 11:10:28 -0400 Subject: [PATCH 03/18] fix linux stat struct on aarch64 The ABI was incorrect. --- std/os/bits/linux/arm64.zig | 40 ++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/std/os/bits/linux/arm64.zig b/std/os/bits/linux/arm64.zig index 657424cd6d..692efc0eb3 100644 --- a/std/os/bits/linux/arm64.zig +++ b/std/os/bits/linux/arm64.zig @@ -1,11 +1,13 @@ // arm64-specific declarations that are intended to be imported into the POSIX namespace. // This does include Linux-only APIs. -const std = @import("../../std.zig"); +const std = @import("../../../std.zig"); const linux = std.os.linux; const socklen_t = linux.socklen_t; const iovec = linux.iovec; const iovec_const = linux.iovec_const; +const uid_t = linux.uid_t; +const gid_t = linux.gid_t; pub const SYS_io_setup = 0; pub const SYS_io_destroy = 1; @@ -382,7 +384,14 @@ pub const msghdr_const = extern struct { msg_flags: i32, }; -pub const off_t = i64; +pub const blksize_t = i32; +pub const nlink_t = u32; +pub const time_t = isize; +pub const mode_t = u32; +pub const off_t = isize; +pub const ino_t = usize; +pub const dev_t = usize; +pub const blkcnt_t = isize; /// Renamed to Stat to not conflict with the stat function. /// atime, mtime, and ctime have functions to return `timespec`, @@ -391,23 +400,22 @@ pub const off_t = i64; /// in C, macros are used to hide the differences. Here we use /// methods to accomplish this. pub const Stat = extern struct { - dev: u64, - ino: u64, - nlink: usize, - - mode: u32, - uid: u32, - gid: u32, - __pad0: u32, - rdev: u64, + dev: dev_t, + ino: ino_t, + mode: mode_t, + nlink: nlink_t, + uid: uid_t, + gid: gid_t, + rdev: dev_t, + __pad: usize, size: off_t, - blksize: isize, - blocks: i64, - + blksize: blksize_t, + __pad2: i32, + blocks: blkcnt_t, atim: timespec, mtim: timespec, ctim: timespec, - __unused: [3]isize, + __unused: [2]u32, pub fn atime(self: Stat) timespec { return self.atim; @@ -423,7 +431,7 @@ pub const Stat = extern struct { }; pub const timespec = extern struct { - tv_sec: isize, + tv_sec: time_t, tv_nsec: isize, }; From 9627a75b071787d49c10c45bd2d8e83423b988fe Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 14:00:05 -0400 Subject: [PATCH 04/18] clean up compiler_rt with some enum literals --- std/special/compiler_rt.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig index b222c31d83..638a9bb60c 100644 --- a/std/special/compiler_rt.zig +++ b/std/special/compiler_rt.zig @@ -233,7 +233,7 @@ comptime { @export("__aeabi_dcmpgt", @import("compiler_rt/arm/aeabi_dcmp.zig").__aeabi_dcmpgt, linkage); @export("__aeabi_dcmpun", @import("compiler_rt/comparedf2.zig").__unorddf2, linkage); } - if (builtin.os == builtin.Os.windows) { + if (builtin.os == .windows) { if (!builtin.link_libc) { @export("_chkstk", @import("compiler_rt/stack_probe.zig")._chkstk, strong_linkage); @export("__chkstk", @import("compiler_rt/stack_probe.zig").__chkstk, strong_linkage); @@ -247,11 +247,11 @@ comptime { } switch (builtin.arch) { - builtin.Arch.i386 => { + .i386 => { @export("_aulldiv", @import("compiler_rt/aulldiv.zig")._aulldiv, strong_linkage); @export("_aullrem", @import("compiler_rt/aullrem.zig")._aullrem, strong_linkage); }, - builtin.Arch.x86_64 => { + .x86_64 => { // The "ti" functions must use @Vector(2, u64) parameter types to adhere to the ABI // that LLVM expects compiler-rt to have. @export("__divti3", @import("compiler_rt/divti3.zig").__divti3_windows_x86_64, linkage); From 786052c7d33973bf0bb34483301142b07bd48880 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 14:40:54 -0400 Subject: [PATCH 05/18] disable running cross compiled macos tests due to #3295 --- test/tests.zig | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/tests.zig b/test/tests.zig index 327dd0c070..63fadc6f7d 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -28,6 +28,7 @@ const TestTarget = struct { mode: builtin.Mode = .Debug, link_libc: bool = false, single_threaded: bool = false, + disable_native: bool = false, }; const test_targets = [_]TestTarget{ @@ -175,6 +176,8 @@ const test_targets = [_]TestTarget{ .abi = .gnu, }, }, + // TODO https://github.com/ziglang/zig/issues/3295 + .disable_native = true, }, TestTarget{ @@ -365,6 +368,14 @@ pub fn addPkgTests( if (skip_single_threaded and test_target.single_threaded) continue; + const ArchTag = @TagType(builtin.Arch); + if (test_target.disable_native and + test_target.target.getOs() == builtin.os and + ArchTag(test_target.target.getArch()) == ArchTag(builtin.arch)) + { + continue; + } + const want_this_mode = for (modes) |m| { if (m == test_target.mode) break true; } else false; From cf4cc9b148e069b46a197d0423e4d25654aea26c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 14:41:47 -0400 Subject: [PATCH 06/18] do the release tests last because they take longer --- test/tests.zig | 73 +++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/test/tests.zig b/test/tests.zig index 63fadc6f7d..e7bfd48f06 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -40,42 +40,6 @@ const test_targets = [_]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{ @@ -201,6 +165,43 @@ const test_targets = [_]TestTarget{ // }, // .link_libc = true, //}, + + // Do the release tests last because they take a long time + 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, + }, }; const max_stdout_size = 1 * 1024 * 1024; // 1 MB From 12b195f9d507bfc0aa4d0199972ae32d096ef1ad Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 15:32:52 -0400 Subject: [PATCH 07/18] ci: update windows image to MSVC 2019 --- ci/azure/pipelines.yml | 2 +- ci/azure/windows_script.bat | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/azure/pipelines.yml b/ci/azure/pipelines.yml index 8e6fcde636..bcc2f11945 100644 --- a/ci/azure/pipelines.yml +++ b/ci/azure/pipelines.yml @@ -27,7 +27,7 @@ jobs: displayName: 'Build and test' - job: BuildWindows pool: - vmImage: 'vs2017-win2016' + vmImage: 'windows-2019' timeoutInMinutes: 360 diff --git a/ci/azure/windows_script.bat b/ci/azure/windows_script.bat index dcd78981eb..ee6016a345 100644 --- a/ci/azure/windows_script.bat +++ b/ci/azure/windows_script.bat @@ -13,11 +13,11 @@ SET "ZIGBUILDDIR=%SRCROOT%\build" SET "ZIGINSTALLDIR=%ZIGBUILDDIR%\Release" SET "ZIGPREFIXPATH=%SRCROOT%\llvm+clang-9.0.0-win64-msvc-release" -call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 +call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 mkdir %ZIGBUILDDIR% 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 +cmake.exe .. -Thost=x64 -G"Visual Studio 16 2019" -A x64 "-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 test || exit /b From 1d6d6d522877243772550edfb0df12c21ed63376 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 15:58:57 -0400 Subject: [PATCH 08/18] remove redundant assert --- src/buffer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/buffer.cpp b/src/buffer.cpp index 3564481b84..86435e0f14 100644 --- a/src/buffer.cpp +++ b/src/buffer.cpp @@ -61,7 +61,6 @@ void buf_appendf(Buf *buf, const char *format, ...) { // these functions are not static inline so they can be better used as template parameters bool buf_eql_buf(Buf *buf, Buf *other) { - assert(buf->list.length); return buf_eql_mem(buf, buf_ptr(other), buf_len(other)); } From 65b495af58bcd010b997d9036ee39808451ef76c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 15:59:06 -0400 Subject: [PATCH 09/18] windows CI: use MinSizeRel to work around MSVC bug See #3024 --- ci/azure/windows_script.bat | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ci/azure/windows_script.bat b/ci/azure/windows_script.bat index ee6016a345..f1a69202e0 100644 --- a/ci/azure/windows_script.bat +++ b/ci/azure/windows_script.bat @@ -17,8 +17,9 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliar mkdir %ZIGBUILDDIR% cd %ZIGBUILDDIR% -cmake.exe .. -Thost=x64 -G"Visual Studio 16 2019" -A x64 "-DCMAKE_INSTALL_PREFIX=%ZIGINSTALLDIR%" "-DCMAKE_PREFIX_PATH=%ZIGPREFIXPATH%" -DCMAKE_BUILD_TYPE=Release || exit /b -msbuild /p:Configuration=Release INSTALL.vcxproj || exit /b +REM Here we use MinSizeRel instead of Release to work around https://github.com/ziglang/zig/issues/3024 +cmake.exe .. -Thost=x64 -G"Visual Studio 16 2019" -A x64 "-DCMAKE_INSTALL_PREFIX=%ZIGINSTALLDIR%" "-DCMAKE_PREFIX_PATH=%ZIGPREFIXPATH%" -DCMAKE_BUILD_TYPE=MinSizeRel || exit /b +msbuild /p:Configuration=MinSizeRel INSTALL.vcxproj || exit /b "%ZIGINSTALLDIR%\bin\zig.exe" build test || exit /b From 31b72da84a14cb3652b3b770ac64e367d021529b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 16:40:48 -0400 Subject: [PATCH 10/18] more info in assertion failures --- src/util.cpp | 9 +-------- src/util.hpp | 10 ++++++++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 65b1fe3082..13bfbbcd47 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -18,17 +18,10 @@ void zig_panic(const char *format, ...) { vfprintf(stderr, format, ap); fflush(stderr); va_end(ap); - stage2_panic(nullptr, 0); + stage2_panic("", 0); abort(); } -void assert(bool ok) { - if (!ok) { - const char *msg = "Assertion failed. This is a bug in the Zig compiler."; - stage2_panic(msg, strlen(msg)); - } -} - uint32_t int_hash(int i) { return (uint32_t)(i % UINT32_MAX); } diff --git a/src/util.hpp b/src/util.hpp index 1248635de9..8abcef32ce 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -43,15 +43,21 @@ ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF(1, 2) void zig_panic(const char *format, ...); +static inline void zig_assert(bool ok, const char *file, int line, const char *func) { + if (!ok) { + zig_panic("Assertion failed at %s:%d in %s. This is a bug in the Zig compiler.", file, line, func); + } +} + #ifdef _WIN32 #define __func__ __FUNCTION__ #endif -#define zig_unreachable() zig_panic("unreachable: %s:%s:%d", __FILE__, __func__, __LINE__) +#define zig_unreachable() zig_panic("Unreachable at %s:%d in %s. This is a bug in the Zig compiler.", __FILE__, __LINE__, __func__) // Assertions in stage1 are always on, and they call zig @panic. #undef assert -void assert(bool ok); +#define assert(ok) zig_assert(ok, __FILE__, __LINE__, __func__) #if defined(_MSC_VER) static inline int clzll(unsigned long long mask) { From a239c7439f4743960bd11be66ae05962eebfa279 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 17:41:15 -0400 Subject: [PATCH 11/18] more helpful error message when failing to parse glibc abi.txt --- src/glibc.cpp | 21 ++++++++++++++++++--- src/os.cpp | 2 +- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/glibc.cpp b/src/glibc.cpp index c6ac875048..b2402bc293 100644 --- a/src/glibc.cpp +++ b/src/glibc.cpp @@ -93,8 +93,10 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo { SplitIterator it = memSplit(buf_to_slice(abi_txt_contents), str("\n")); ZigGLibCVerList *ver_list_base = nullptr; + int line_num = 0; for (;;) { if (ver_list_base == nullptr) { + line_num += 1; Optional> opt_line = SplitIterator_next_separate(&it); if (!opt_line.is_some) break; @@ -122,7 +124,19 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo target->os = OsLinux; err = target_parse_abi(&target->abi, (char*)opt_abi.value.ptr, opt_abi.value.len); - assert(err == ErrorNone); + if (err != ErrorNone) { + fprintf(stderr, "Error parsing %s:%d: %s\n", buf_ptr(glibc_abi->abi_txt_path), + line_num, err_str(err)); + fprintf(stderr, "arch: '%.*s', os: '%.*s', abi: '%.*s'\n", + (int)opt_arch.value.len, (const char*)opt_arch.value.ptr, + (int)opt_os.value.len, (const char*)opt_os.value.ptr, + (int)opt_abi.value.len, (const char*)opt_abi.value.ptr); + fprintf(stderr, "parsed from target: '%.*s'\n", + (int)opt_target.value.len, (const char*)opt_target.value.ptr); + fprintf(stderr, "parsed from line:\n%.*s\n", (int)opt_line.value.len, opt_line.value.ptr); + fprintf(stderr, "Zig installation appears to be corrupted.\n"); + exit(1); + } glibc_abi->version_table.put(target, ver_list_base); } @@ -130,6 +144,7 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo } for (size_t fn_i = 0; fn_i < glibc_abi->all_functions.length; fn_i += 1) { ZigGLibCVerList *ver_list = &ver_list_base[fn_i]; + line_num += 1; Optional> opt_line = SplitIterator_next_separate(&it); assert(opt_line.is_some); @@ -266,7 +281,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con // - If there are no versions, don't emit it // - Take the greatest one <= than the target one // - If none of them is <= than the - // specified one don't pick any default version + // specified one don't pick any default version if (ver_list->len == 0) continue; uint8_t chosen_def_ver_index = 255; for (uint8_t ver_i = 0; ver_i < ver_list->len; ver_i += 1) { @@ -322,7 +337,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con codegen_set_lib_version(child_gen, lib->sover, 0, 0); child_gen->is_dynamic = true; child_gen->is_dummy_so = true; - child_gen->version_script_path = map_file_path; + child_gen->version_script_path = map_file_path; child_gen->enable_cache = false; child_gen->output_dir = dummy_dir; codegen_build_and_link(child_gen); diff --git a/src/os.cpp b/src/os.cpp index 3a6ed2c286..6dc3777f8c 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -116,7 +116,7 @@ static void os_spawn_process_posix(ZigList &args, Termination *ter pid_t pid; int rc = posix_spawnp(&pid, args.at(0), nullptr, nullptr, const_cast(argv), environ); if (rc != 0) { - zig_panic("posix_spawn failed: %s", strerror(rc)); + zig_panic("unable to spawn %s: %s", args.at(0), strerror(rc)); } int status; From 2c8495b4bb261d440bc6d1a6b0415a64c8d99222 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 18:11:55 -0400 Subject: [PATCH 12/18] git, I love you, but please stop mangling my files --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index 355918890b..8f894eb569 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,5 @@ *.zig text eol=lf +*.txt text eol=lf langref.html.in text eol=lf deps/* linguist-vendored From f14ba904d78a9edb6f7dcf89f70b9c0be346a0fb Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 18:14:53 -0400 Subject: [PATCH 13/18] tolerate windows newlines in glibc text files --- src/glibc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/glibc.cpp b/src/glibc.cpp index b2402bc293..50ccf20efe 100644 --- a/src/glibc.cpp +++ b/src/glibc.cpp @@ -50,7 +50,7 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo } { - SplitIterator it = memSplit(buf_to_slice(vers_txt_contents), str("\n")); + SplitIterator it = memSplit(buf_to_slice(vers_txt_contents), str("\r\n")); for (;;) { Optional> opt_component = SplitIterator_next(&it); if (!opt_component.is_some) break; @@ -65,7 +65,7 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo } } { - SplitIterator it = memSplit(buf_to_slice(fns_txt_contents), str("\n")); + SplitIterator it = memSplit(buf_to_slice(fns_txt_contents), str("\r\n")); for (;;) { Optional> opt_component = SplitIterator_next(&it); if (!opt_component.is_some) break; @@ -91,7 +91,7 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo } } { - SplitIterator it = memSplit(buf_to_slice(abi_txt_contents), str("\n")); + SplitIterator it = memSplit(buf_to_slice(abi_txt_contents), str("\r\n")); ZigGLibCVerList *ver_list_base = nullptr; int line_num = 0; for (;;) { From d6f7b573aacd924e199f6bb62c8e0c7e79138930 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 16:24:49 -0400 Subject: [PATCH 14/18] silence nonportable include path warnings when building glibc on windows --- src/link.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/link.cpp b/src/link.cpp index d595580f9a..0d51188bb3 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1295,6 +1295,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { c_file->args.append("-include"); c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h")); c_file->args.append("-DMODULE_NAME=libc"); + c_file->args.append("-Wno-nonportable-include-path"); c_file->args.append("-include"); c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h")); c_file->args.append("-DTOP_NAMESPACE=glibc"); @@ -1321,6 +1322,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { c_file->args.append("-include"); c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h")); c_file->args.append("-DMODULE_NAME=libc"); + c_file->args.append("-Wno-nonportable-include-path"); c_file->args.append("-include"); c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h")); c_file->args.append("-DPIC"); @@ -1377,6 +1379,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { c_file->args.append("-include"); c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h")); c_file->args.append("-DMODULE_NAME=libc"); + c_file->args.append("-Wno-nonportable-include-path"); c_file->args.append("-include"); c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h")); c_file->args.append("-DPIC"); @@ -1420,6 +1423,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { c_file->args.append("-include"); c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h")); c_file->args.append("-DMODULE_NAME=libc"); + c_file->args.append("-Wno-nonportable-include-path"); c_file->args.append("-include"); c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h")); c_file->args.append("-DPIC"); From 23f339f1b4686ee9c6d81e25d884bb407530dbcc Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 19:03:17 -0400 Subject: [PATCH 15/18] add emscripten to std.build.Target.defaultAbi After upgrading to LLVM 9 we now have the emscripten OS available. Fix the compile error in this function by specifying the default ABI for emscripten. --- std/build.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/std/build.zig b/std/build.zig index cddf7c72a1..915b255857 100644 --- a/std/build.zig +++ b/std/build.zig @@ -1015,6 +1015,7 @@ pub const Target = union(enum) { => return .msvc, .linux, .wasi, + .emscripten, => return .musl, } } From c161ce3f7c424274269bda0bf054a04540bc26cf Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 19:05:17 -0400 Subject: [PATCH 16/18] mingw-w64 libc: fix incorrect detection of _xgetbv It was using __GNUC__ < 8 to check if _xgetbv intrinsic is available. Since we always use zig cc with this header, we know we have clang 9, which does have this intrinsic. --- .../any-windows-any/psdk_inc/intrin-impl.h | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/lib/libc/include/any-windows-any/psdk_inc/intrin-impl.h b/lib/libc/include/any-windows-any/psdk_inc/intrin-impl.h index 4c6d8fd029..591d9994ba 100644 --- a/lib/libc/include/any-windows-any/psdk_inc/intrin-impl.h +++ b/lib/libc/include/any-windows-any/psdk_inc/intrin-impl.h @@ -1938,32 +1938,6 @@ __buildmov(__movsd, unsigned __LONG32, "d") #define __INTRINSIC_DEFINED___movsd #endif /* __INTRINSIC_PROLOG */ -#if !defined(__GNUC__) || __GNUC__ < 8 /* GCC 8 has already defined _xgetbv */ -/* NOTE: This should be in immintrin.h */ -#if __INTRINSIC_PROLOG(_xgetbv) -unsigned __int64 _xgetbv(unsigned int); -#if !__has_builtin(_xgetbv) -__INTRINSICS_USEINLINE -unsigned __int64 _xgetbv(unsigned int index) -{ -#if defined(__x86_64__) || defined(_AMD64_) - unsigned __int64 val1, val2; -#else - unsigned __LONG32 val1, val2; -#endif /* defined(__x86_64__) || defined(_AMD64_) */ - - __asm__ __volatile__( - "xgetbv" - : "=a" (val1), "=d" (val2) - : "c" (index)); - - return (((unsigned __int64)val2) << 32) | val1; -} -#endif -#define __INTRINSIC_DEFINED__xgetbv -#endif /* __INTRINSIC_PROLOG */ -#endif /* __GNUC__ < 8 */ - #endif /* defined(__x86_64__) || defined(_AMD64_) || defined(__i386__) || defined(_X86_) */ /* ***************************************************** */ From 96affd683a302402d470f9a41b801f2e42639859 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 19:11:41 -0400 Subject: [PATCH 17/18] enable test coverage for cross compiling windows mingw-w64 closes #3285 --- test/tests.zig | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/test/tests.zig b/test/tests.zig index e7bfd48f06..7dc1d1f620 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -154,17 +154,16 @@ const test_targets = [_]TestTarget{ }, }, - // TODO https://github.com/ziglang/zig/issues/3285 - //TestTarget{ - // .target = Target{ - // .Cross = CrossTarget{ - // .os = .windows, - // .arch = .x86_64, - // .abi = .gnu, - // }, - // }, - // .link_libc = true, - //}, + TestTarget{ + .target = Target{ + .Cross = CrossTarget{ + .os = .windows, + .arch = .x86_64, + .abi = .gnu, + }, + }, + .link_libc = true, + }, // Do the release tests last because they take a long time TestTarget{ From 55925b6e259b5453b8af29a5365d82378cb1d54b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Sep 2019 19:47:07 -0400 Subject: [PATCH 18/18] windows CI: fix name collision Previously the CMAKE_BUILD_TYPE=Release was conflicting with the "distribution" directory `release`. I renamed this to `dist` so that it won't conflict with any build types. --- ci/azure/windows_script.bat | 2 +- ci/azure/windows_upload | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/ci/azure/windows_script.bat b/ci/azure/windows_script.bat index f1a69202e0..5c44abcbe1 100644 --- a/ci/azure/windows_script.bat +++ b/ci/azure/windows_script.bat @@ -10,7 +10,7 @@ SET "PATH=%PREVPATH%" SET "MSYSTEM=%PREVMSYSTEM%" SET "ZIGBUILDDIR=%SRCROOT%\build" -SET "ZIGINSTALLDIR=%ZIGBUILDDIR%\Release" +SET "ZIGINSTALLDIR=%ZIGBUILDDIR%\dist" SET "ZIGPREFIXPATH=%SRCROOT%\llvm+clang-9.0.0-win64-msvc-release" call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 diff --git a/ci/azure/windows_upload b/ci/azure/windows_upload index 266d1b57dd..d5527fa13a 100755 --- a/ci/azure/windows_upload +++ b/ci/azure/windows_upload @@ -6,16 +6,15 @@ set -e if [ "${BUILD_REASON}" != "PullRequest" ]; then cd "$ZIGBUILDDIR" - rm release/*.exe - mv ../LICENSE release/ - mv ../zig-cache/langref.html release/ - mv release/bin/zig.exe release/ - rmdir release/bin + mv ../LICENSE dist/ + mv ../zig-cache/langref.html dist/ + mv dist/bin/zig.exe dist/ + rmdir dist/bin - VERSION=$(release/zig.exe version) + VERSION=$(dist/zig.exe version) DIRNAME="zig-windows-x86_64-$VERSION" TARBALL="$DIRNAME.zip" - mv release "$DIRNAME" + mv dist "$DIRNAME" 7z a "$TARBALL" "$DIRNAME" mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"