os: add support for windows - #107
Open
AmyJeanes wants to merge 7 commits into
Open
Conversation
Tag wheels win_amd64, resolve bash through PATH (CreateProcess searches System32 first, which would launch the WSL bash), pass the build.sh path with forward slashes since MSYS2 bash treats backslashes as escapes, and hand the build interpreter to build.sh as PYTHON so scripts stop assuming a python3 on PATH. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016AgqYZYWLpwE2T5vS3nVEt
Per-package changes so every build.sh runs in an MSYS2 CLANG64 shell: - capnproto/ffmpeg/git-lfs/gcc-arm-none-eabi: .exe names, Windows archives, and native C:/ prefixes for pkgconf; ffmpeg is built static so consumers do not need DLL search path handling - acados: GENERIC BLASFEO/HPIPM targets (the x86 assembly kernels assume the SysV ABI), the pinned tera_renderer release binary instead of a rust toolchain, Windows venv layout when vendoring casadi - zeromq: no AF_UNIX transport on MinGW (afunix.h is MSVC only) - raylib: desktop backend with clang and the mingw distutils compiler, configured through a tracked build_ext config file; the cffi build output under raylib/Release is ignored - ncurses: PDCurses' console port shipped under the ncurses names, decided before the ncurses tarball would be downloaded - shims: run binaries via subprocess on Windows, os.exec* cannot replace the process there Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016AgqYZYWLpwE2T5vS3nVEt
replay selects AV_HWDEVICE_TYPE_D3D11VA on Windows; that needs the h264/hevc d3d11va2 hwaccels, which share their objects with the legacy d3d11va ones, so both variants are enabled. Only the mingw SDK headers are needed, no extra libraries. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016AgqYZYWLpwE2T5vS3nVEt
The venv's interpreter lives in Scripts/ there, and MSYS2 puts its own mingw CPython first on PATH, so pin uv to the managed 3.12 the wheels are built for. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016AgqYZYWLpwE2T5vS3nVEt
capnp and cppcheck linked libc++ dynamically, so they only ran from a shell with the MSYS2 CLANG64 bin directory on PATH; link them -static like ffmpeg. cppcheck also gets the subprocess shim the other packages use on Windows (os.execvp cannot replace the process there), and the capnproto smoketest joins PATH with os.pathsep so it runs there too. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016AgqYZYWLpwE2T5vS3nVEt
pacman installs the toolchain and build tools by MINGW_PACKAGE_PREFIX; the other MSYS2 environments are refused since the wheels rely on clang, lld and libc++. .gitattributes keeps the scripts LF on Windows checkouts. The uv shell installer unpacks with unzip, which a fresh MSYS2 lacks (a native unzip on PATH cannot open MSYS paths). MSYS2's git package is not installed: openpilot's venv git-lfs cannot drive that Cygwin-style git, so Git for Windows on the inherited PATH is the git for both repos. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016AgqYZYWLpwE2T5vS3nVEt
A fourth matrix entry builds on windows-latest in an MSYS2 CLANG64 shell
with the runner's PATH inherited; ./setup.sh installs the pacman
packages. Only that entry names its shell: the job's run default falls
back to `bash -e {0}`, GitHub's implicit default, so the Linux and macOS
steps are unchanged. A `test windows` job installs the wheels into a venv
of a stock Python with no MSYS2 on PATH and runs the smoketests, the
Windows counterpart of the distro-container test: it is the only place a
wheel that still depends on the toolchain's DLLs fails. The publish job
then uploads the Windows wheels to PyPI with the others (bootstrap-icons
is a py3-none-any duplicate, which --skip-existing drops).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016AgqYZYWLpwE2T5vS3nVEt
This was referenced Sep 7, 2026
AmyJeanes
added a commit
to AmyJeanes/panda
that referenced
this pull request
Sep 7, 2026
…ies#107 publishes --- TODO REMOVE AFTER DEPENDENCY PR MERGES (commaai/dependencies#107) --- This commit is dropped from the PR once the win_amd64 wheels are on PyPI. Until then it points uv at a GitHub release of the same wheels, built from that PR's branch on my fork, so the Windows CI entry runs here meanwhile: comma-deps-gcc-arm-none-eabi and comma-deps-cppcheck for sys_platform == 'win32'. Linux and macOS resolve from PyPI as before. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016AgqYZYWLpwE2T5vS3nVEt
AmyJeanes
added a commit
to AmyJeanes/rednose
that referenced
this pull request
Sep 7, 2026
…ies#107 publishes --- TODO REMOVE AFTER DEPENDENCY PR MERGES (commaai/dependencies#107) --- This commit is dropped from the PR once the win_amd64 wheels are on PyPI. Until then it points uv at a GitHub release of the same wheels, built from that PR's branch on my fork, so the Windows CI entry runs here meanwhile: comma-deps-eigen for sys_platform == 'win32'. Linux and macOS resolve from PyPI as before. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016AgqYZYWLpwE2T5vS3nVEt
AmyJeanes
added a commit
to AmyJeanes/opendbc
that referenced
this pull request
Sep 7, 2026
…ies#107 publishes --- TODO REMOVE AFTER DEPENDENCY PR MERGES (commaai/dependencies#107) --- This commit is dropped from the PR once the win_amd64 wheels are on PyPI. Until then it points uv at a GitHub release of the same wheels, built from that PR's branch on my fork, so the Windows CI entry runs here meanwhile: comma-deps-cppcheck for sys_platform == 'win32', and uv.lock relocked against that index. Linux and macOS resolve from PyPI as before; the lock is regenerated from PyPI when this commit goes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016AgqYZYWLpwE2T5vS3nVEt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Windows (win_amd64) wheels for all fifteen packages, built with clang, lld and libc++ from an MSYS2 CLANG64 shell, so that openpilot's PC tooling can be built and run natively on Windows for development. The other PRs in the series consume these wheels; openpilot's Windows CI job currently builds against a release of them from my fork and runs the full unit test suite there.
What changes:
setup.py(every package): wheels taggedwin_amd64;bashresolved through PATH (CreateProcess searches System32 first, which is the WSL launcher);build.shpaths passed with forward slashes; the build interpreter handed tobuild.shasPYTHONso the scripts stop assuming apython3on PATH.build.shper package, in one commit with the rationale per package in its message. The notable decisions:h264/hevc_d3d11va, any GPU vendor, mingw SDK headers suffice), and the network layer is off since only the file and pipe protocols are enabled.afunix.his MSVC-only; openpilot uses tcp:// on Windows).build_extconfig).subprocesson Windows:os.exec*cannot replace the process.setup.sh: pacman packages for the CLANG64 environment; other MSYS2 environments are refused..gitattributeskeeps the scripts LF on Windows checkouts.windows-latest(GitHub-hosted; the Namespace expression falls through to it) and atest windowsjob that installs the wheels into a venv of a stock Python with no MSYS2 on PATH and runs the smoketests, the Windows counterpart of the distro test. The publish job uploads the Windows wheels with the others (bootstrap-icons is apy3-none-anyduplicate, which--skip-existingdrops). A matrix entry can name its shell (the Windows one runs in the CLANG64 shell from setup-msys2); the others keepbash -e {0}, GitHub's implicit default, through the job's run defaults. An explicitshell: bashwould add pipefail, which breaks the Xcode select step onmacos-latest(macOS 26 has no Xcode 16).Not included: libdatachannel-py has no Windows wheel on PyPI and is not this repo's package; the openpilot PR keeps teleoprtc off Windows.
Tested: this workflow on this PR, all four platforms plus the distro containers: every wheel builds, the
test windowsjob installs the fifteen win_amd64 wheels into a venv of a stock Python with no MSYS2 on PATH and runs each package's smoketest, and the Linux and macOS jobs are unchanged. The wheels are what openpilot's Windows CI job syncs and builds against, and its full unit test suite passes there (856 tests): commaai/openpilot#38810. Locally, a clean-roomuv syncof the wheels into a fresh venv and cache, then openpilot's scons build and the same suite. Cold build times on GitHub-hosted runners: Windows 17 min (11 with ccache).This PR is part of a larger series of work bringing support for Windows to openpilot:
This PR goes first: the rednose, opendbc and panda PRs are drafts whose Windows CI entries install the wheels it publishes, and turn ready once they are on PyPI. Otherwise each PR merges independently; only the openpilot one depends on all of them.
The changes in this PR were generated by Claude Fable 5.1 but were human reviewed and fully tested end to end both locally and in CI.