diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9997ca7f3cf1..5f254330901e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -178,7 +178,7 @@ jobs: fetch-depth: 0 - name: Build and Test working-directory: ci - run: '& $Env:USERPROFILE\deps\zig-x86_64-windows-gnu-${{env.ci-zig-version}}\bin\zig.exe build -Dbuild-type=Debug -Dskip-non-native cmake-bootstrap tidy update-stage1' + run: '& $Env:USERPROFILE\deps\zig-x86_64-windows-gnu-${{env.ci-zig-version}}\bin\zig.exe build -Dbuild-type=Debug -Dskip-non-native cmake-bootstrap tidy update-stage1 msvc' x86_64-windows-release: if: github.repository_owner == 'ziglang' runs-on: [self-hosted, Windows, x86_64] diff --git a/ci/build.zig b/ci/build.zig index a8fad42d9021..47152163eeee 100644 --- a/ci/build.zig +++ b/ci/build.zig @@ -1,7 +1,7 @@ const std = @import("std"); pub fn build(b: *std.Build) void { - const host = b.standardTargetOptions(.{ + const host_target = b.standardTargetOptions(.{ .whitelist = &.{ .{ .cpu_arch = .x86_64, @@ -52,9 +52,9 @@ pub fn build(b: *std.Build) void { .musl, }, }); - const host_triple = host.result.linuxTriple(b.allocator) catch @panic("OOM"); - const host_cpu = host.query.serializeCpuAlloc(b.allocator) catch @panic("OOM"); - const host_exe_file_ext = host.result.exeFileExt(); + const host_triple = host_target.result.linuxTriple(b.allocator) catch @panic("OOM"); + const host_cpu = host_target.query.serializeCpuAlloc(b.allocator) catch @panic("OOM"); + const host_exe_file_ext = host_target.result.exeFileExt(); const build_type = b.option(enum { None, Debug, Release, RelWithDebInfo, MinSizeRel }, "build-type", "CMake build type") orelse .Debug; const tool_optimize = b.option( std.builtin.OptimizeMode, @@ -62,18 +62,18 @@ pub fn build(b: *std.Build) void { "Prioritize performance, safety, or binary size for build tools", ) orelse .ReleaseSafe; - const binaryen_lazy_dep = if (host.result.cpu.arch != .aarch64 or host.result.os.tag != .windows) + const binaryen_lazy_dep = if (host_target.result.cpu.arch != .aarch64 or host_target.result.os.tag != .windows) b.lazyDependency(b.fmt("binaryen-{s}", .{host_triple}), .{}) else null; const cmake_lazy_dep = b.lazyDependency(b.fmt("cmake-{s}", .{host_triple}), .{}); const ninja_lazy_dep = b.lazyDependency(b.fmt("ninja-{s}", .{host_triple}), .{}); - const qemu_lazy_dep = if (host.result.cpu.arch == .x86_64 and host.result.os.tag == .linux) + const qemu_lazy_dep = if (host_target.result.cpu.arch == .x86_64 and host_target.result.os.tag == .linux) b.lazyDependency(b.fmt("qemu-{s}", .{host_triple}), .{}) else null; const tidy_lazy_dep = b.lazyDependency(b.fmt("tidy-{s}", .{host_triple}), .{}); - const wasmtime_lazy_dep = if (host.result.cpu.arch != .aarch64 or host.result.os.tag != .windows) + const wasmtime_lazy_dep = if (host_target.result.cpu.arch != .aarch64 or host_target.result.os.tag != .windows) b.lazyDependency(b.fmt("wasmtime-{s}", .{host_triple}), .{}) else null; @@ -86,7 +86,7 @@ pub fn build(b: *std.Build) void { const zig_llvm_lld_clang_dep = zig_llvm_lld_clang_lazy_dep orelse return; const cmake_exe = cmake_dep.path(b.fmt("{s}bin/cmake{s}", .{ - if (host.result.isDarwin()) "CMake.app/Contents/" else "", + if (host_target.result.isDarwin()) "CMake.app/Contents/" else "", host_exe_file_ext, })); const ninja_exe = ninja_dep.path(b.fmt("ninja{s}", .{host_exe_file_ext})); @@ -105,17 +105,17 @@ pub fn build(b: *std.Build) void { const run_exe = b.addExecutable(.{ .name = "run", .root_source_file = b.path("run.zig"), - .target = host, + .target = host_target, .optimize = tool_optimize, .strip = false, }); run_exe.step.max_rss = 276_529_152; - const run_chmod_step = if (host.result.isDarwin()) steps: { + const run_chmod_step = if (host_target.result.isDarwin()) steps: { const chmod_exe = b.addExecutable(.{ .name = "chmod", .root_source_file = b.path("chmod.zig"), - .target = host, + .target = host_target, .optimize = tool_optimize, .strip = false, }); @@ -316,8 +316,8 @@ pub fn build(b: *std.Build) void { "$--search-prefix", "$5", }); - if (host.result.isDarwin()) run_tests.addArg("-Denable-macos-sdk"); - if (host.result.os.tag == .windows) run_tests.addArgs(&.{"-Denable-symlinks-windows"}); + if (host_target.result.isDarwin()) run_tests.addArg("-Denable-macos-sdk"); + if (host_target.result.os.tag == .windows) run_tests.addArgs(&.{"-Denable-symlinks-windows"}); if (b.option(bool, "skip-non-native", "Skip non-native tests") orelse false) run_tests.addArg("-Dskip-non-native"); if (qemu_lazy_dep) |_| run_tests.addArg("-fqemu"); @@ -426,7 +426,7 @@ pub fn build(b: *std.Build) void { const cmp_exe = b.addExecutable(.{ .name = "cmp", .root_source_file = b.path("cmp.zig"), - .target = host, + .target = host_target, .optimize = tool_optimize, .strip = false, }); @@ -553,5 +553,135 @@ pub fn build(b: *std.Build) void { run_tests_with_updated_stage4.addFileArg(b.path("../test/behavior.zig")); update_stage1_step.dependOn(&run_tests_with_updated_stage4.step); } + + msvc: { + const msvc_target = target: { + var target = host_target.result; + target.abi = .msvc; + break :target target; + }; + const libc = std.zig.LibCDirs.detect( + b.allocator, + b.pathFromRoot("../lib"), + msvc_target, + true, + true, + null, + ) catch |err| switch (err) { + else => |e| @panic(@errorName(e)), + }; + const msvc_arch = switch (host_target.result.cpu.arch) { + .x86 => "x86", + .x86_64 => "x64", + .arm, .armeb, .thumb, .thumbeb => "arm", + .aarch64 => "arm64", + else => break :msvc, + }; + const cl_exe = b.pathResolve(&.{ + (libc.libc_installation orelse break :msvc).msvc_lib_dir orelse break :msvc, + "..", + "..", + "bin", + b.fmt("Host{s}", .{msvc_arch}), + msvc_arch, + b.fmt("cl{s}", .{host_exe_file_ext}), + }); + const msvc_triple = msvc_target.linuxTriple(b.allocator) catch @panic("OOM"); + + const msvc_step = b.step("msvc", "Run the behavior tests compiled with MSVC"); + + const build_msvc_behavior_tests = std.Build.Step.Run.create(b, "build msvc behavior tests"); + build_msvc_behavior_tests.step.max_rss = 213_237_760; + if (false) + build_msvc_behavior_tests.addFileArg(stage3_exe) + else + build_msvc_behavior_tests.addArg(b.cache_root.join(b.allocator, &.{ + "o", + "4aeed00bc8dFaa6ee10d8a09a88bd97b", + "build", + "stage3", + "bin", + b.fmt("zig{s}", .{host_exe_file_ext}), + }) catch @panic("OOM")); + build_msvc_behavior_tests.addArgs(&.{ + "test", + "-ofmt=c", + "--test-no-exec", + "-target", + msvc_triple, + "-lc", + }); + build_msvc_behavior_tests.addFileArg(b.path("../test/behavior.zig")); + const behavior_msvc_source = + build_msvc_behavior_tests.addPrefixedOutputFileArg("-femit-bin=", "behavior-msvc.c"); + + const build_msvc_compiler_rt = std.Build.Step.Run.create(b, "build msvc compiler-rt"); + build_msvc_compiler_rt.step.max_rss = 164_306_944; + if (false) + build_msvc_compiler_rt.addFileArg(stage3_exe) + else + build_msvc_compiler_rt.addArg(b.cache_root.join(b.allocator, &.{ + "o", + "4aeed00bc8dFaa6ee10d8a09a88bd97b", + "build", + "stage3", + "bin", + b.fmt("zig{s}", .{host_exe_file_ext}), + }) catch @panic("OOM")); + build_msvc_compiler_rt.addArgs(&.{ + "build-obj", + "-ofmt=c", + "-OReleaseSmall", + "--name", + "compiler_rt", + "-target", + msvc_triple, + "-lc", + }); + build_msvc_compiler_rt.addFileArg(b.path("../lib/compiler_rt.zig")); + const compiler_rt_msvc_source = + build_msvc_compiler_rt.addPrefixedOutputFileArg("-femit-bin=", "compiler_rt-msvc.c"); + + const build_msvc_tests = std.Build.Step.Run.create(b, "build msvc tests"); + build_msvc_tests.step.max_rss = 556_036_096; + build_msvc_tests.addArgs(&.{ cl_exe, "/W3", "/Z7" }); + build_msvc_tests.addPrefixedDirectoryArg("/I", b.path("../lib")); + build_msvc_tests.addFileArg(behavior_msvc_source); + build_msvc_tests.addFileArg(compiler_rt_msvc_source); + const msvc_tests_exe = build_msvc_tests.addPrefixedOutputFileArg( + "/Fe:", + b.fmt("behavior-msvc{s}", .{host_exe_file_ext}), + ); + // Link args must appear after all other args. + build_msvc_tests.addArgs(&.{ + "/link", + "/nologo", + "/debug", + "/subsystem:console", + "kernel32.lib", + "ntdll.lib", + "libcmt.lib", + }); + build_msvc_tests.setEnvironmentVariable("INCLUDE", std.mem.join( + b.allocator, + &.{std.fs.path.delimiter}, + libc.libc_include_dir_list, + ) catch @panic("OOM")); + build_msvc_tests.setEnvironmentVariable("LIB", std.mem.join( + b.allocator, + &.{std.fs.path.delimiter}, + &.{ + libc.libc_installation.?.msvc_lib_dir.?, + libc.libc_installation.?.crt_dir.?, + libc.libc_installation.?.kernel32_lib_dir.?, + }, + ) catch @panic("OOM")); + if (true) build_msvc_tests.has_side_effects = true; + + const run_msvc_tests = std.Build.Step.Run.create(b, "run msvc tests"); + run_msvc_tests.step.max_rss = 2; + run_msvc_tests.addFileArg(msvc_tests_exe); + msvc_step.dependOn(&run_msvc_tests.step); + } } }