Skip to content

build: add support to build rules_zig on Windows - #687

Open
AlexTereshenkov wants to merge 26 commits into
hermeticbuild:mainfrom
AlexTereshenkov:tereshenkov/add-builds-on-windows
Open

AlexTereshenkov wants to merge 26 commits into
hermeticbuild:mainfrom
AlexTereshenkov:tereshenkov/add-builds-on-windows

Conversation

@AlexTereshenkov

@AlexTereshenkov AlexTereshenkov commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

This PR makes change in the project to be able to:

  1. Build the project itself on a Windows machine (i.e., user clones the repo and bazel build //... && bazel test //... just works. I was able to verify this on a personal Windows device (without WSL being involved in any way).

  2. Build a binary executable on a Linux machine and run the .exe file on a Windows machine (testing cross-platform builds); if that's of interest, we could perhaps move this part into a separate PR and have a more evolved matrix there to test all possible combinations (i.e. host / target platforms Windows, Linux, macOS).

@AlexTereshenkov AlexTereshenkov changed the title WIP build: add support to build rules_zig on Windows build: add support to build rules_zig on Windows Oct 20, 2026
@AlexTereshenkov

Copy link
Copy Markdown
Contributor Author

I am not sure whether we want to support building the project on Windows as it means we'd need to ensure we don't use anything POSIX specific and use only tools that are compatible across POSIX and Windows. There shouldn't be much; to make the project Windows compatible, I only had to ensure the paths are compared properly (Windows path is C:\Directory whereas on Linux it's /c/directory with forward / backward slashes difference), line encodings in files are standard when checking out the repository and logic comparing any files generated in tests / builds can be compared properly, respecting the forward/backward slashes and their escapes.

@aherrmann What are your thoughts? I think majority of potential contributors would be on a Linux or macOS, so maybe we shouldn't bother?

For the cross-platform builds, we definitely want to have it, however. If you agree, I could make it a separate PR.

Comment thread .github/workflows/ci.yaml
targetPattern: "//..."
tagFilters: ""
# No remote cache or execution while bringing up Windows.
remoteEnabled: false

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BuildBuddy does support Windows (claimed in https://www.buildbuddy.io/docs/rbe-platforms/) for RBE, but since we'll test running on Windows a binary that was built on Linux, I thought we might want to use the same type of runner?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if the free BuildBuddy offering (https://www.buildbuddy.io/pricing/) offers RBE on Windows, I only see Linux listed on that pricing page.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right,

darwin and windows are currently only available for self-hosted executors

Please never mind.

Comment thread .github/workflows/ci.yaml Outdated
Comment thread .github/workflows/ci.yaml Outdated
Comment thread zig/private/packages/module_graph.zig
Comment thread .bazelrc Outdated

@aherrmann aherrmann left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for pushing this forward!

I have mostly only nits.

if that's of interest, we could perhaps move this part into a separate PR and have a more evolved matrix there to test all possible combinations (i.e. host / target platforms Windows, Linux, macOS).

Yes, placing that into a separate PR sounds good. I'm wondering about the best available approaches there that don't make CI too slow. Some completely unchecked ideas:

  • GHA driven approach: first pass matrix generates and stores cross-platform artifacts; second pass matrix tests each on its target platform. (that's what's laid out here)
  • Bazel RBE driven approach: cross-compile binaries to different target platforms on each host, make them an input to a test target that routes to the target platform via RE. (requires RE runners on the target platforms, we may not have that here)
  • emulation approach: cross-compile binaries to different target platforms on each host, make them an input to a test target that uses emulation/API-compat-layers (wine/darling/...) to run the binary. (hermetically providing those emulators is probably not easy today)

Comment on lines -99 to +101
if: inputs.folder == '.' && inputs.targetPattern == '//...'
# Generated files are platform independent, so Linux and macOS already
# cover this check.
if: inputs.folder == '.' && inputs.targetPattern == '//...' && runner.os != 'Windows'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that we're going through the trouble of making this step Windows compatible just below, we may as well run it on Windows to make sure that it would also work for a contributor on Windows.

@AlexTereshenkov AlexTereshenkov Oct 22, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disabled this at a first attempt as I realized it's going to be a rabbit hole (the errors started appearing quickly and were nasty to pin down). I totally agree that it would be terrific to have everything buildable on Windows, but I can't seem to get it working on two Windows laptops. It passes on CI in this action, but the fact that it fails on ordinary laptop that people might be using is concerning.

I had all kinds of issues --

  • Windows disables --enable_runfiles by default, and multirun's Python runner needs a real .runfiles directory
  • Bazel doesn't pass BUILD_WORKSPACE_DIRECTORY (or any BUILD_* variable) to a script run under --run_under, so a wrapper has to set them (I had a Python wrapper)
  • bazel run starts the script in the runfiles directory, not the workspace
  • wrong bash picked up (WSL): bash on a Windows PATH is often WSL's launcher, which can't see C:/ paths, so the script requires BAZEL_SH and uses that bash explicitly.
  • Shebangs and nested bash calls hit WSL too: #!/usr/bin/env bash resolves bash through PATH, so the wrapper puts the chosen bash's directory (in /c/... form) first on PATH and exports BAZEL_SH for multirun's inner calls
  • Bazel server restarts (open): The server started from your terminal used system32\bash.exe, while nested bazel query calls use c:/msys64/..., so each nested call restarts the server.
  • xargs: environment is too large for exec (open): MSYS xargs fails in update_deleted_packages even after trimming the environment to about 7 KB

After hours of troubleshooting I got some steps in utils:update succeed, but it bloated the logic so much that I start wondering whether we shall proceed at all. The environment might be so different between Windows setups, so I fear even if we make it all work on my two laptops, some other nasty problem might manifest itself on another user's machine.

Options:

  1. Run build and test on Windows runner to ensure compatibility (some additional platform is always great to build on, I reckon?), but don't support running //util:update on Windows. If a contributor wants to update the BUILD files, they would need to use WSL (or make changes manually).
  2. Abandon the idea of making builds Windows friendly and focus on the cross-platform builds in a separate PR.

Do you see any other path forward? @aherrmann

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies, I misread this as the Windows file generation checks already working in principle, but just being excluded as redundant. Of course, if this is a litany of random Windows compatibility fixes to get these checks working, then those do not all need to be covered at once. I'm all in favor of small incremental steps. So, let's focus this PR on the stated goal of getting the build and test of //... working. I think long term it would be good to get the file generation steps working, if only since each of those also indicates a likely hermeticity issue. But, that can be done gradually, and may also require some work on third-party dependencies, e.g. regarding that multirun issue.

Comment thread .github/actions/test/action.yaml Outdated
Comment thread .github/actions/test/action.yaml
Comment thread .github/actions/test/action.yaml Outdated
Comment thread .github/actions/test/action.yaml Outdated
Comment thread .github/workflows/ci.yaml
targetPattern: "//..."
tagFilters: ""
# No remote cache or execution while bringing up Windows.
remoteEnabled: false

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if the free BuildBuddy offering (https://www.buildbuddy.io/pricing/) offers RBE on Windows, I only see Linux listed on that pricing page.

Comment thread .github/workflows/ci.yaml
Comment on lines +163 to +165
# Minimal smoke test to verify that rules_zig builds and tests on Windows.
# Not yet part of all_tests, so a failure does not block merging.
test-windows:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to start here, the long term goal is to add windows to the os matrix, correct?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. I've tried to enable it under matrix but that led to explosion of errors under the e2e (bazelrc configuration needs to be adjusted and some extra flags need to be passed + some way Zig works with dynamic libraries need (dll) need to be take into account). At some point, however, it would be great to have it in the matrix, yes.

Comment thread zig/zls/workspace_printer.zig
Comment thread .bazelrc Outdated
Comment thread .bazelrc Outdated
AlexTereshenkov and others added 2 commits October 24, 2026 14:36
@AlexTereshenkov
AlexTereshenkov force-pushed the tereshenkov/add-builds-on-windows branch from 51b3193 to a4b2d56 Compare October 24, 2026 13:08
@AlexTereshenkov
AlexTereshenkov force-pushed the tereshenkov/add-builds-on-windows branch from 2f42013 to 537af42 Compare October 24, 2026 13:42
@AlexTereshenkov

Copy link
Copy Markdown
Contributor Author

Okay, I believe this is ready for final review with all the comments addressed. @aherrmann :)

@AlexTereshenkov
AlexTereshenkov marked this pull request as ready for review October 26, 2026 09:26
@AlexTereshenkov

Copy link
Copy Markdown
Contributor Author

Please don't forget to squash and merge when merging this PR :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants