Subject: [PATCH bazel-zig-cc v2 0/3] Windows support

From: Fabian Hahn <[email-masked]>
Date: Sun, 29 May 2022 17:35:15 +0100

Hello,

Second version of my patchset adding Windows support to bazel-zig-cc.

Changelog compared to v1:
 - fixed lint failures
 - dropped patch to add extra platform constraint settings
 - added patch to add testing for Windows target using wine-binfmt
 - added README.md entries explaining Windows support

I hope it passes CI, but I do not know how to trigger it other than
sending you a second patch version. In case of further failures, I
will of course look into fixing them.  Please let me know if anything
looks like it is missing :)

Best,
Fabian

Fabian Hahn (3):
  added Windows host support
  added support for Windows targets
  added Windows target testing

 .build.yml                          |  1 +
 README.md                           | 25 ++++++++++++-
 WORKSPACE                           |  4 +-
 ci/test                             | 14 ++++++-
 test/c/BUILD                        | 24 +++++++++++-
 test/c/main_winver.c                | 16 ++++++++
 toolchain/BUILD.sdk.bazel           |  1 +
 toolchain/defs.bzl                  | 58 +++++++++++++++++++++++------
 toolchain/platform/defs.bzl         |  7 +++-
 toolchain/private/BUILD.sdk.bazel   |  1 +
 toolchain/private/cc_toolchains.bzl |  6 +--
 toolchain/private/defs.bzl          | 27 +++++++++++++-
 12 files changed, 161 insertions(+), 23 deletions(-)
 create mode 100644 test/c/main_winver.c

-- 
2.25.1

---

From: Fabian Hahn <[email-masked]>
Date: Sun, 29 May 2022 17:35:18 +0100

---
 .build.yml           |  1 +
 README.md            | 10 ++++++++--
 WORKSPACE            |  4 +++-
 ci/test              | 14 ++++++++++++--
 test/c/BUILD         | 24 +++++++++++++++++++++++-
 test/c/main_winver.c | 16 ++++++++++++++++
 6 files changed, 63 insertions(+), 6 deletions(-)
 create mode 100644 test/c/main_winver.c

diff --git a/.build.yml b/.build.yml
index 6aeec50..c9cbfa0 100644
--- a/.build.yml
+++ b/.build.yml
@@ -5,6 +5,7 @@ packages:
   - qemu-user-static
   - binfmt-support
   - moreutils
+  - wine-binfmt
 sources:
   - https://git.sr.ht/~motiejus/bazel-zig-cc
 environment:
diff --git a/README.md b/README.md
index e6fd5e2..7a86ced 100644
--- a/README.md
+++ b/README.md
@@ -401,8 +401,9 @@ This repository is used on the following (host) platforms:
 - `windows_amd64`, a.k.a. `x64`.
 
 The tests are running (CId) on linux-amd64, and are assuming the kernel is
-configured to run arm64 binaries. There are two reasonably convenient ways to
-configure arm64 emulation:
+configured to run `linux_arm64` and `windows_amd64` binaries.
+
+There are two reasonably convenient ways to configure `linux_arm64` emulation:
 
 1. Install and configure [`binfmt_misc`][binfmt_misc]:
    ```
@@ -414,6 +415,11 @@ configure arm64 emulation:
    docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
    ```
 
+In order to install and configure `windows_amd64` emulation:
+```
+apt install wine-binfmt
+```
+
 ## Transient docker environment
 
 A standalone Docker environment to play with bazel-zig-cc:
diff --git a/WORKSPACE b/WORKSPACE
index eff4a8f..c1b3c0f 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -51,11 +51,13 @@ zig_toolchains()
 
 register_toolchains(
     # if no `--platform` is specified, these toolchains will be used for
-    # (linux,darwin)x(amd64,arm64)
+    # (linux,darwin,windows)x(amd64,arm64)
     "@zig_sdk//toolchain:linux_amd64_gnu.2.19",
     "@zig_sdk//toolchain:linux_arm64_gnu.2.28",
     "@zig_sdk//toolchain:darwin_amd64",
     "@zig_sdk//toolchain:darwin_arm64",
+    "@zig_sdk//toolchain:windows_amd64",
+    "@zig_sdk//toolchain:windows_arm64",
 
     # amd64 toolchains for libc-aware platforms:
     "@zig_sdk//libc_aware/toolchain:linux_amd64_gnu.2.19",
diff --git a/ci/test b/ci/test
index debdc0b..1ba6285 100755
--- a/ci/test
+++ b/ci/test
@@ -1,3 +1,13 @@
-#!/bin/sh
+#!/bin/bash
+set -euo pipefail
 
-exec bazel test ...
+bazel test ...
+
+# Windows tests
+# Unfortunately wine-binfmt breaks within the bazel sandbox, so we disable it
+# to run this test.
+bazel test //test/c:winver_windows_amd64 \
+    --spawn_strategy=standalone
+# There is no no easy way to run windows_arm64 binaries on Linux, so we just
+# cross compile one for testing.
+bazel build //test/c:winver_windows_arm64
diff --git a/test/c/BUILD b/test/c/BUILD
index 99e36c4..698c798 100644
--- a/test/c/BUILD
+++ b/test/c/BUILD
@@ -1,4 +1,4 @@
-load("@bazel-zig-cc//rules:platform.bzl", "platform_binary")
+load("@bazel-zig-cc//rules:platform.bzl", "platform_binary", "platform_test")
 
 cc_binary(
     name = "which_libc",
@@ -34,3 +34,25 @@ cc_binary(
         ("linux_arm64", "//platform:linux_arm64", "glibc_2.28"),
     ]
 ]
+
+cc_binary(
+    name = "winver",
+    srcs = ["main_winver.c"],
+    target_compatible_with = [
+        "@platforms//os:windows",
+    ],
+)
+
+platform_test(
+    name = "winver_windows_amd64",
+    src = "winver",
+    platform = "//platform:windows_amd64",
+    tags = ["manual"],
+)
+
+platform_binary(
+    name = "winver_windows_arm64",
+    src = "winver",
+    platform = "//platform:windows_arm64",
+    tags = ["manual"],
+)
diff --git a/test/c/main_winver.c b/test/c/main_winver.c
new file mode 100644
index 0000000..b5302af
--- /dev/null
+++ b/test/c/main_winver.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <windows.h>
+
+int main() {
+    DWORD version = GetVersion();
+    DWORD majorVersion = (DWORD)(LOBYTE(LOWORD(version)));
+    DWORD minorVersion = (DWORD)(HIBYTE(LOWORD(version)));
+
+    DWORD build = 0;
+    if (version < 0x80000000) {
+        build = (DWORD)(HIWORD(version));
+    }
+
+    printf("Running Windows version %d.%d (%d).\n", majorVersion, minorVersion, build);
+    return 0;
+}
-- 
2.25.1

---

From: Fabian Hahn <[email-masked]>
Date: Sun, 29 May 2022 17:35:16 +0100

---
 README.md                           |  1 +
 toolchain/BUILD.sdk.bazel           |  1 +
 toolchain/defs.bzl                  | 58 +++++++++++++++++++++++------
 toolchain/private/BUILD.sdk.bazel   |  1 +
 toolchain/private/cc_toolchains.bzl |  6 +--
 toolchain/private/defs.bzl          |  8 +++-
 6 files changed, 59 insertions(+), 16 deletions(-)

diff --git a/README.md b/README.md
index bbbd5bc..b092ae0 100644
--- a/README.md
+++ b/README.md
@@ -384,6 +384,7 @@ This repository is used on the following (host) platforms:
 - `linux_arm64`, a.k.a. `AArch64`.
 - `darwin_amd64`, the 64-bit post-PowerPC models.
 - `darwin_arm64`, the M1.
+- `windows_amd64`, a.k.a. `x64`.
 
 The tests are running (CId) on linux-amd64, and are assuming the kernel is
 configured to run arm64 binaries. There are two reasonably convenient ways to
diff --git a/toolchain/BUILD.sdk.bazel b/toolchain/BUILD.sdk.bazel
index ada3e5d..e1505b1 100644
--- a/toolchain/BUILD.sdk.bazel
+++ b/toolchain/BUILD.sdk.bazel
@@ -7,6 +7,7 @@ package(

 declare_files(
+    os = {os},
     zig_include_root = {zig_include_root},
 )
 
diff --git a/toolchain/defs.bzl b/toolchain/defs.bzl
index 9ab4e88..df2441d 100644
--- a/toolchain/defs.bzl
+++ b/toolchain/defs.bzl
@@ -1,6 +1,6 @@
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
 load("@bazel_tools//tools/build_defs/repo:utils.bzl", "read_user_netrc", "use_netrc")
-load("@bazel-zig-cc//toolchain/private:defs.bzl", "DEFAULT_INCLUDE_DIRECTORIES", "ZIG_TOOL_PATH", "target_structs")
+load("@bazel-zig-cc//toolchain/private:defs.bzl", "DEFAULT_INCLUDE_DIRECTORIES", "target_structs", "zig_tool_path")
 
 _fcntl_map = """
 GLIBC_2.2.5 {
@@ -16,21 +16,21 @@ __asm__(".symver fcntl64, [email-masked]");
 """
 
 # Official recommended version. Should use this when we have a usable release.
-URL_FORMAT_RELEASE = "https://ziglang.org/download/{version}/zig-{host_platform}-{version}.tar.xz"
+URL_FORMAT_RELEASE = "https://ziglang.org/download/{version}/zig-{host_platform}-{version}.{ext}"
 
 # Caution: nightly releases are purged from ziglang.org after ~90 days. A real
 # solution would be to allow the downstream project specify their own mirrors.
 # This is explained in
 # https://sr.ht/~motiejus/bazel-zig-cc/#alternative-download-urls and is
 # awaiting my attention or your contribution.
-URL_FORMAT_NIGHTLY = "https://ziglang.org/builds/zig-{host_platform}-{version}.tar.xz"
+URL_FORMAT_NIGHTLY = "https://ziglang.org/builds/zig-{host_platform}-{version}.{ext}"
 
 # Author's mirror that doesn't purge the nightlies so aggressively. I will be
 # cleaning those up manually only after the artifacts are not in use for many
 # months in bazel-zig-cc. dl.jakstys.lt is a small x86_64 server with an NVMe
 # drive sitting in my home closet on a 1GB/s symmetric residential connection,
 # which, as of writing, has been quite reliable.
-URL_FORMAT_JAKSTYS = "https://dl.jakstys.lt/zig/zig-{host_platform}-{version}.tar.xz"
+URL_FORMAT_JAKSTYS = "https://dl.jakstys.lt/zig/zig-{host_platform}-{version}.{ext}"
 
 _VERSION = "0.10.0-dev.2252+a4369918b"
 
@@ -39,12 +39,22 @@ _HOST_PLATFORM_SHA256 = {
     "linux-x86_64": "1d3c3769eba85a4334c93a3cfa35ad0ef914dd8cf9fd502802004c6908f5370c",
     "macos-aarch64": "ab46e7499e5bd7b6d6ff2ac331e1a4aa875a01b270dc40306bc29dbaf216fccf",
     "macos-x86_64": "fb213f996bcab805839e401292c42a92b63cd97deb1631e31bd61f534b7f6b1c",
+    "windows-x86_64": "14e43a64026512161f3d6201d8972a28f0508da2782c16e980f2ffa3bb7e6720",
+}
+
+_HOST_PLATFORM_EXT = {
+    "linux-aarch64": "tar.xz",
+    "linux-x86_64": "tar.xz",
+    "macos-aarch64": "tar.xz",
+    "macos-x86_64": "tar.xz",
+    "windows-x86_64": "zip",
 }
 
 def toolchains(
         version = _VERSION,
         url_formats = [URL_FORMAT_NIGHTLY, URL_FORMAT_JAKSTYS],
-        host_platform_sha256 = _HOST_PLATFORM_SHA256):
+        host_platform_sha256 = _HOST_PLATFORM_SHA256,
+        host_platform_ext = _HOST_PLATFORM_EXT):
     """
         Download zig toolchain and declare bazel toolchains.
         The platforms are not registered automatically, that should be done by
@@ -56,11 +66,13 @@ def toolchains(
         version = version,
         url_formats = url_formats,
         host_platform_sha256 = host_platform_sha256,
+        host_platform_ext = host_platform_ext,
         host_platform_include_root = {
             "linux-aarch64": "lib/zig/",
             "linux-x86_64": "lib/",
             "macos-aarch64": "lib/zig/",
             "macos-x86_64": "lib/zig/",
+            "windows-x86_64": "lib/",
         },
     )
 
@@ -81,6 +93,10 @@ export ZIG_GLOBAL_CACHE_DIR=$ZIG_LOCAL_CACHE_DIR
 exec "{zig}" "{zig_tool}" "$@"
 """
 
+ZIG_TOOL_WRAPPER_WINDOWS = """@echo off
+"{zig}" "{zig_tool}" %*
+"""
+
 _ZIG_TOOLS = [
     "c++",
     "cc",
@@ -103,11 +119,16 @@ def _zig_repository_impl(repository_ctx):
     if os.startswith("mac os"):
         os = "macos"
 
+    if os.startswith("windows"):
+        os = "windows"
+
     host_platform = "{}-{}".format(os, arch)
 
     zig_include_root = repository_ctx.attr.host_platform_include_root[host_platform]
     zig_sha256 = repository_ctx.attr.host_platform_sha256[host_platform]
+    zig_ext = repository_ctx.attr.host_platform_ext[host_platform]
     format_vars = {
+        "ext": zig_ext,
         "version": repository_ctx.attr.version,
         "host_platform": host_platform,
     }
@@ -121,12 +142,19 @@ def _zig_repository_impl(repository_ctx):
     )
 
     for zig_tool in _ZIG_TOOLS:
-        repository_ctx.file(
-            ZIG_TOOL_PATH.format(zig_tool = zig_tool),
-            ZIG_TOOL_WRAPPER.format(
-                zig = str(repository_ctx.path("zig")),
+        zig_tool_wrapper = ZIG_TOOL_WRAPPER.format(
+            zig = str(repository_ctx.path("zig")),
+            zig_tool = zig_tool,
+        )
+        if os == "windows":
+            zig_tool_wrapper = ZIG_TOOL_WRAPPER_WINDOWS.format(
+                zig = str(repository_ctx.path("zig")).replace("/", "\\") + ".exe",
                 zig_tool = zig_tool,
-            ),
+            )
+
+        repository_ctx.file(
+            zig_tool_path(os).format(zig_tool = zig_tool),
+            zig_tool_wrapper,
         )
 
     repository_ctx.file(
@@ -157,6 +185,7 @@ def _zig_repository_impl(repository_ctx):
             executable = False,
             substitutions = {
                 "{absolute_path}": _quote(str(repository_ctx.path(""))),
+                "{os}": _quote(os),
                 "{zig_include_root}": _quote(zig_include_root),
             },
         )
@@ -167,6 +196,7 @@ zig_repository = repository_rule(
         "host_platform_sha256": attr.string_dict(),
         "url_formats": attr.string_list(allow_empty = False),
         "host_platform_include_root": attr.string_dict(),
+        "host_platform_ext": attr.string_dict(),
     },
     implementation = _zig_repository_impl,
 )
@@ -175,9 +205,13 @@ def filegroup(name, **kwargs):
     native.filegroup(name = name, **kwargs)
     return ":" + name
 
-def declare_files(zig_include_root):
+def declare_files(os, zig_include_root):
     filegroup(name = "empty")
-    native.exports_files(["zig"], visibility = ["//visibility:public"])
+    if os == "windows":
+        native.exports_files(["zig.exe"], visibility = ["//visibility:public"])
+        native.alias(name = "zig", actual = ":zig.exe")
+    else:
+        native.exports_files(["zig"], visibility = ["//visibility:public"])
     filegroup(name = "lib/std", srcs = native.glob(["lib/std/**"]))
 
     lazy_filegroups = {}
diff --git a/toolchain/private/BUILD.sdk.bazel b/toolchain/private/BUILD.sdk.bazel
index 39a6a93..3e7c23e 100644
--- a/toolchain/private/BUILD.sdk.bazel
+++ b/toolchain/private/BUILD.sdk.bazel
@@ -1,6 +1,7 @@
 load("@bazel-zig-cc//toolchain/private:cc_toolchains.bzl", "declare_cc_toolchains")
 
 declare_cc_toolchains(
+    os = {os},
     absolute_path = {absolute_path},
     zig_include_root = {zig_include_root},
 )
diff --git a/toolchain/private/cc_toolchains.bzl b/toolchain/private/cc_toolchains.bzl
index 64e99f1..e6594db 100644
--- a/toolchain/private/cc_toolchains.bzl
+++ b/toolchain/private/cc_toolchains.bzl
@@ -1,4 +1,4 @@
-load(":defs.bzl", "DEFAULT_INCLUDE_DIRECTORIES", "ZIG_TOOL_PATH", "target_structs")
+load(":defs.bzl", "DEFAULT_INCLUDE_DIRECTORIES", "target_structs", "zig_tool_path")
 load("@bazel-zig-cc//toolchain:zig_toolchain.bzl", "zig_cc_toolchain_config")
 
 DEFAULT_TOOL_PATHS = {
@@ -11,7 +11,7 @@ DEFAULT_TOOL_PATHS = {
     "strip": "/usr/bin/false",
 }.items()
 
-def declare_cc_toolchains(absolute_path, zig_include_root):
+def declare_cc_toolchains(os, absolute_path, zig_include_root):
     for target_config in target_structs():
         gotarget = target_config.gotarget
         zigtarget = target_config.zigtarget
@@ -28,7 +28,7 @@ def declare_cc_toolchains(absolute_path, zig_include_root):
             if path[0] == "/":
                 absolute_tool_paths[name] = path
                 continue
-            tool_path = ZIG_TOOL_PATH.format(zig_tool = path)
+            tool_path = zig_tool_path(os).format(zig_tool = path)
             absolute_tool_paths[name] = "%s/%s" % (absolute_path, tool_path)
 
         linkopts = target_config.linkopts
diff --git a/toolchain/private/defs.bzl b/toolchain/private/defs.bzl
index 6059065..6804104 100644
--- a/toolchain/private/defs.bzl
+++ b/toolchain/private/defs.bzl
@@ -4,7 +4,7 @@ DEFAULT_INCLUDE_DIRECTORIES = [
     "libcxxabi/include",
 ]
 
-ZIG_TOOL_PATH = "tools/{zig_tool}"
+_ZIG_TOOL_PATH = "tools/{zig_tool}"
 
 # Zig supports even older glibcs than defined below, but we have tested only
 # down to 2.17.
@@ -30,6 +30,12 @@ _GLIBCS = [
 
 LIBCS = ["musl"] + ["gnu.{}".format(glibc) for glibc in _GLIBCS]
 
+def zig_tool_path(os):
+    if os == "windows":
+        return _ZIG_TOOL_PATH + ".bat"
+    else:
+        return _ZIG_TOOL_PATH
+
 def target_structs():
     ret = []
     for zigcpu, gocpu in (("x86_64", "amd64"), ("aarch64", "arm64")):
-- 
2.25.1

---

From: Fabian Hahn <[email-masked]>
Date: Sun, 29 May 2022 17:35:17 +0100

---
 README.md                   | 14 ++++++++++++++
 toolchain/platform/defs.bzl |  7 ++++++-
 toolchain/private/defs.bzl  | 19 +++++++++++++++++++
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index b092ae0..e6fd5e2 100644
--- a/README.md
+++ b/README.md
@@ -152,6 +152,8 @@ register_toolchains(
     "@zig_sdk//toolchain:linux_arm64_gnu.2.28",
     "@zig_sdk//toolchain:darwin_amd64",
     "@zig_sdk//toolchain:darwin_arm64",
+    "@zig_sdk//toolchain:windows_amd64",
+    "@zig_sdk//toolchain:windows_arm64",
 )
 ```
 
@@ -318,6 +320,18 @@ is currently not implemented.
 target macos.10 (Catalina), macos.11 (Big Sur) or macos.12 (Monterey). It
 currently targets the lowest version, without ability to change it.
 
+## Windows: output file extensions
+
+Bazel won't use common Windows file extensions for built output binaries.
+Instead, it will generate binaries with common Unix extensions that you might
+have to manually rename before deploying them to an actual Windows system:
+
+| Binary type    | Bazel extension | Windows extension |
+|----------------|-----------------|-------------------|
+| Static library | .a              | .lib              |
+| Shared library | .so             | .dll              |
+| Executable     | (no extension)  | .exe              |
+
 # Known Issues In Upstream
 
 This section lists issues that I've stumbled into when using `zig cc`, and is
diff --git a/toolchain/platform/defs.bzl b/toolchain/platform/defs.bzl
index cf42191..07e69a6 100644
--- a/toolchain/platform/defs.bzl
+++ b/toolchain/platform/defs.bzl
@@ -1,11 +1,16 @@
 load("@bazel-zig-cc//toolchain/private:defs.bzl", "LIBCS")
 
 _CPUS = (("x86_64", "amd64"), ("aarch64", "arm64"))
+_OS = {
+    "linux": ["linux"],
+    "macos": ["macos", "darwin"],
+    "windows": ["windows"],
+}
 
 def declare_platforms():
     # create @zig_sdk//{os}_{arch}_platform entries with zig and go conventions
     for zigcpu, gocpu in _CPUS:
-        for bzlos, oss in {"linux": ["linux"], "macos": ["macos", "darwin"]}.items():
+        for bzlos, oss in _OS.items():
             for os in oss:
                 declare_platform(gocpu, zigcpu, bzlos, os)
 
diff --git a/toolchain/private/defs.bzl b/toolchain/private/defs.bzl
index 6804104..2ba61f7 100644
--- a/toolchain/private/defs.bzl
+++ b/toolchain/private/defs.bzl
@@ -40,6 +40,7 @@ def target_structs():
     ret = []
     for zigcpu, gocpu in (("x86_64", "amd64"), ("aarch64", "arm64")):
         ret.append(_target_darwin(gocpu, zigcpu))
+        ret.append(_target_windows(gocpu, zigcpu))
         ret.append(_target_linux_musl(gocpu, zigcpu))
         for glibc in _GLIBCS:
             ret.append(_target_linux_gnu(gocpu, zigcpu, glibc))
@@ -69,6 +70,24 @@ def _target_darwin(gocpu, zigcpu):
         tool_paths = {"ld": "ld64.lld"},
     )
 
+def _target_windows(gocpu, zigcpu):
+    return struct(
+        gotarget = "windows_{}".format(gocpu),
+        zigtarget = "{}-windows-gnu".format(zigcpu),
+        includes = [
+            "libunwind/include",
+            "libc/include/any-windows-any",
+        ],
+        linkopts = [],
+        copts = [],
+        bazel_target_cpu = "x64_windows",
+        constraint_values = [
+            "@platforms//os:windows",
+            "@platforms//cpu:{}".format(zigcpu),
+        ],
+        tool_paths = {"ld": "ld64.lld"},
+    )
+
 def _target_linux_gnu(gocpu, zigcpu, glibc_version):
     glibc_suffix = "gnu.{}".format(glibc_version)
 
-- 
2.25.1

---

From: "builds.sr.ht" <[email-masked]>
Date: Sun, 29 May 2022 17:05:29 +0000

bazel-zig-cc/patches/.build.yml: FAILED in 29m34s

[Windows support][0] v2 from [Fabian Hahn][1]

[0]: https://lists.sr.ht/~motiejus/bazel-zig-cc/patches/32601
[1]: mailto:[email-masked]

✗ #769696 FAILED bazel-zig-cc/patches/.build.yml https://builds.sr.ht/~motiejus/job/769696

---

From: Motiejus Jakštys <[email-masked]>
Date: Mon, 30 May 2022 15:37:47 +0300

> looks like it is missing :)

Hi, Fabian,

As you may have noticed, the past patchset doesn't pass CI. If you
have a Linux machine, the tests are quite easy to execute manually[1].
Otherwise don't worry about sending multiple patch versions; I am
happy to ignore the patchsets (and the emails from the CI) until the
tests pass. That's what they are there for!

You can also use a transient docker environment[2] to isolate yourself
from the host OS. Let me know if that works for you.

Motiejus

[1]: https://git.sr.ht/~motiejus/bazel-zig-cc/tree/main/item/.build.yml
[2]: https://git.sr.ht/~motiejus/bazel-zig-cc#transient-docker-environment

---

From: [email-masked]
Date: Wed, 01 Jun 2022 18:05:37 +0100

Hey Motiejus,

> tests pass. That's what they are there for!

I've actually been running the tests successfully on my Ubuntu box. I a
bit confused at first looking at the failed build logs [1] until I
I realized what the problem was: Even though I updated .build.yml in my
patch, it actually uses the original baseline file in the repo to run
the CI steps. This means that my addition of the wine-binfmt Debian
package doesn't get picked up, which then causes the bazel test to fail
that tries to run the actual Windows binary as it doesn't know how to
interpret it. I now realized that there's further setup commands in the
"setup" task. I will try to add the package there instead.

> from the host OS. Let me know if that works for you.

I just tried this and my tests passed, but only after I manually ran
`update-binfmts --enable wine` inside the container. I'm a bit confused
because this wasn't needed for qemu arm64 emulation, but maybe that's a
wine-binfmt specific thing? Anyway, I will try to go with the setup
step approach and add that extra command there too if needed.

Best,
Fabian

[1] https://builds.sr.ht/~motiejus/job/769696

---

From: Motiejus Jakštys <[email-masked]>
Date: Thu, 2 Jun 2022 06:06:46 +0300

> step approach and add that extra command there too if needed.

That's fine. I pushed it to a branch, which kicked off CI[1]. That
passed.

I will review your patch in a short order. Sorry for the confusion and
thank you for clarifying.

Motiejus

[1]: https://builds.sr.ht/~motiejus/job/772421

---

From: Motiejus Jakštys <[email-masked]>
Date: Mon, 6 Jun 2022 10:37:37 +0300

> thank you for clarifying.

Hi Fabian,

I spent a couple of hours on this and published it to
motiejus_windows[1] branch. Notable changes:
- added test wrappers, so we no longer depend on wine-binfmt. Bazel
does something unusual with sandboxing, so we still need this for
linux-arm64.
- side effect: `bazel test ...` remains the only command to run all
tests by a mixture of "manual" and "no-sandbox" tags on some targets.
- fixed linux-arm64.gnu tests. Until the changes those failed on all
computers I've tried except CI. Now they work everywhere I've tried,
assuming dependencies are installed.
- trivial: renamed ext to _ext to convey "it's private", also updated
release scripts.

Please review my changes on top of yours in the branch[1] and let me
know if I didn't mess up anything. Then I can release v0.8.0.

As usual, thanks to Laurynas for tips.

Motiejus

[1]: https://git.sr.ht/~motiejus/bazel-zig-cc/tree/motiejus_windows

---

From: [email-masked]
Date: Wed, 08 Jun 2022 18:03:05 +0100

Hey Motiejus,

Thanks a lot for looking at my patches and adjusting them further.

> does something unusual with sandboxing, so we still need this for

I don't particularly mind, the run_under approach also looks fine to
me.

> tests by a mixture of "manual" and "no-sandbox" tags on some targets.

I didn't know about the no-sandbox tag in bazel, so that's a great
solution to make it work under `bazel test ...`!

> assuming dependencies are installed.

Right, I actually ended up passing QEMU_LD_PREFIX in --action_env and
thought I had somehow messed up my qemu setup. Good to see this fixed!

> know if I didn't mess up anything. Then I can release v0.8.0.

The only thing I noticed is that since we no longer explicitly run
bazel build in ci/test, we won't build the windows_arm64 test binary
anymore. As far as I know bazel test ... won't build targets that are
not required for running any tests, so unless we also put a command
for bael build ... somewhere it won't be covered. This is a very
minor point though, so feel free to ignore.

I did run your branch against my project both on Linux and Windows
machines and everything worked flawlessly. So from my point of view
this is good to go.

Best,
Fabian

---

From: Motiejus Jakštys <[email-masked]>
Date: Wed, 8 Jun 2022 22:51:08 +0300

> minor point though, so feel free to ignore.

Not in my experience: if an executable label doesn't have a "manual"
tag, it will be built.

Let's run a naîve test. Apply this patch to the branch:

diff --git a/test/windows/main.c b/test/windows/main.c
index b5302af..5f94789 100644
--- a/test/windows/main.c
+++ b/test/windows/main.c
@@ -1,6 +1,10 @@
 #include <stdio.h>
 #include <windows.h>

+#ifdef _M_ARM64
+error
+#endif
+
 int main() {
     DWORD version = GetVersion();
     DWORD majorVersion = (DWORD)(LOBYTE(LOWORD(version)));

And then run the following:

1) bazel test //test/windows:winver_windows_amd64  # OK
2) bazel build //test/windows:winver_windows_arm64  # FAIL
3) bazel test ...  # FAIL, the same way as above

According to your earlier description, only (2) should fail. But 3
fails too. I will not paste the full error message here, but suffice
to say, it is what I expect it to be.

> machines and everything worked flawlessly. So from my point of view

Will merge. Thank you for your contribution!

Motiejus

---

From: [email-masked]
Date: Thu, 09 Jun 2022 11:28:57 +0100

Hi Motiejus,

> to say, it is what I expect it to be.

Wow, you're right. I've been using bazel for over 5 years now and
never realized this. Thanks for the clarification, and thank you for
merging my patches and the release!

Best,
Fabian

---

From: Motiejus Jakštys <[email-masked]>
Date: Thu, 9 Jun 2022 14:48:53 +0300

On Thu, Jun 9, 2022 at 1:29 PM <[email-masked]> wrote:
> <...> and thank you for merging my patches and the release!

Hi Fabian,

No problem! Note that your name is featured in the README[1] now.
Please read it and make sure you understand what you have signed up
for. :)

Motiejus