Misc #22180
openProvide official Windows (mswin) binary packages and a version manager
Description
Japanese version of this proposal: https://gist.github.com/hsbt/552b01f2aac616af6f8056148407900a
Background¶
Ruby used to ship official Windows binaries. https://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ still has mswin32 zips from the 1.6 to 1.9-preview era, and they were discontinued around 1.9. One reason is that a bare zip was not usable as a distribution. https://bugs.ruby-lang.org/issues/999 reports that the ruby-1.9.1-preview1 mswin32 zip was missing the OpenSSL and zlib DLLs, so gem update did not work at all.
Since then, installing Ruby on Windows has depended on third-party distributions. The mswin platform, which is what ruby/ruby CI actually builds and tests with MSVC, has had no end-user distribution at all. https://bugs.ruby-lang.org/issues/19325 shows how the current state is perceived by Windows users.
The technical ground has changed. Over the last few months I fixed all the tests that remained broken on mswin myself: nmake check, test-bundler and test-bundled-gems are green now, and nmake exam, which runs all of the test suites, completes as well. The build manages its C dependencies with a pinned vcpkg manifest (vcpkg.json), and CI covers VS 2022, VS 2026 and windows-11-arm. MSVC ABI (vcruntime140) has been stable since 2015. The missing piece is distribution, not build quality.
Timing also matters. In the era of writing code with AI, the people who need a working Ruby on Windows are increasingly ordinary users who let a coding assistant set up the environment for them, and consumer AI tools operate natively on Windows, not through WSL. An assistant working unattended needs a runtime that installs without elevation and without GUI dialogs, exposes a machine-readable version index, and is relocatable so that installs are deterministic. Unattended provisioning is already the norm in CI (setup-ruby exists precisely for this), and AI assistants bring the same requirement to end-user machines. Python reached the same conclusion with PEP 773, described below. Ruby has no official answer to this on Windows today.
Proposal¶
I propose to provide an official Windows distribution based on the mswin platform, made of three components. All of them, including the test-suite fixes above, are work I implemented and verified myself. Nothing below is a design on paper.
1. ruby/ruby: a binary-package target. A new nmake-only target packages the installed tree together with the vcpkg runtime DLLs, the VC runtime and the license terms of everything redistributed into a relocatable zip, with build-machine specific paths scrubbed from rbconfig.rb. Thanks to LOAD_RELATIVE the tree runs from any location. I will submit the pull request shortly.
This is implemented and verified. The package passes a smoke test with PATH restricted to System32 (openssl, fiddle, psych, zlib and RubyGems all work), and C extensions compile with VS Build Tools. In a survey of the 500 most-downloaded gems on rubygems.org forced to build from source, 21 of the 44 gems with a native extension built and loaded. All 23 failures were gem-side or environment-side issues (gcc-only code, POSIX-only source, missing third-party libraries), none caused by the package or by ruby itself, with identical results on 3.3.11, 3.4.10 and 4.0.5.
2. ruby/actions: building and publishing. Automation builds the zips and publishes them together with sha256 checksums: daily builds of master and release builds of the maintained series. Released series (3.3, 3.4, 4.0) are built from their release tarballs with the same packaging script applied externally, so no change to the stable branches is required. This also enables re-packaging revisions (-1, -2) when a bundled dependency such as OpenSSL needs a security update without a new Ruby release. This part is already working too: in addition to master, zips of 3.3.11, 3.4.10 and 4.0.5 have been built and verified this way, and they are the packages the gem survey above was run on.
3. rbmanager: a version manager for Windows. The same shape as Python's install manager (PEP 773, https://peps.python.org/pep-0773/). A single native executable (the rb command) installs a zip from a URL or a local path, extracts it under %LOCALAPPDATA%, switches versions with an NTFS junction, and needs one user-level PATH entry and no elevation. A working prototype written in C# is already complete and verified on a real machine:
> rb install ruby-4.1.0-x64-mswin64_140.zip
Extracting ruby-4.1.0-x64-mswin64_140 ...
Installed ruby-4.1.0-x64-mswin64_140
> ruby -v
ruby 4.1.0dev (2026-06-29T22:22:44Z master 2ce6b8e54a) +PRISM [x64-mswin64_140]
> rb list
ruby-3.3.11-x64-mswin64_140
ruby-3.4.10-x64-mswin64_140
ruby-4.0.5-x64-mswin64_140
* ruby-4.1.0-x64-mswin64_140
> rb use 4.0
Now using ruby-4.0.5-x64-mswin64_140
> ruby -v
ruby 4.0.5 (2026-05-20 revision 64336ffd0e) +PRISM [x64-mswin64_140]
The example installs from a local zip today. Once the official version index described below is published, rb install 4.1 will resolve the version, download the zip and verify its checksum by itself.
What building on the platform vendor's toolchain enables¶
This proposal is complementary to the existing gcc-based distributions and does not compete with them. Some capabilities are decided by third-party vendors rather than by Ruby, because their SDKs assume the MSVC toolchain and ABI, and those become reachable with an official MSVC-built runtime.
Machine-learning runtime assets become directly reusable: the prebuilt Windows packages of ONNX Runtime, libtorch and OpenCV are MSVC binaries with C++ ABIs, and CUDA's nvcc accepts only cl.exe as its host compiler on Windows, so Ruby extensions binding GPU and ML runtimes need an MSVC-built Ruby to link cleanly. PDB symbols connect Ruby to the standard Windows diagnostics stack: WinDbg and Visual Studio can debug a mixed stack of Ruby and vendor DLLs, WER minidumps from end users become analyzable, and publishing official symbol packages becomes possible for the first time. And extension authors can pull C dependencies from the same vcpkg ecosystem that ruby/ruby itself already uses through vcpkg.json.
What I ask to decide¶
First, make these official distribution artifacts: announce them on the www.ruby-lang.org download page and host the zips, checksums and a static version index (the equivalent of pymanager's index-windows.json) on ruby-lang.org infrastructure. GitHub Releases can serve as the initial hosting during the preview period.
Second, sign the published binaries with a project identity (for example SignPath Foundation issues OSS code-signing certificates) rather than an individual certificate.
Third, host rbmanager as a repository under the ruby organization.
The concrete zip layout and naming rule are implementation details. I will work them out with @nobu (Nobuyoshi Nakada) and document the result in doc/distribution/windows.md, so they are not something to decide on this ticket.
Scope and non-goals¶
This proposal does not replace or deprecate any existing third-party distribution. It adds an official channel for the platform the core team itself builds and tests.
I already operate the official snap distribution and the entire release pipeline including security releases, and these artifacts ride on the same automation and the same operator, so this proposal does not change the current maintenance level.
Pure-Ruby gems work with no toolchain. Building a C extension requires VS Build Tools, which Microsoft has licensed for building open-source dependencies without a paid Visual Studio license since 2022, and a ridk-like bootstrap (win32/install-buildtools.cmd is the seed) is follow-up work. Precompiled x64-mswin64 gems across the ecosystem are long-term work and not a prerequisite. The survey above identified 12 gems that already support Windows with x64-mingw-ucrt precompiled binaries and only lack a working MSVC source path, a concrete and small upstream fix list. That list includes nokogiri and ffi, so applications depending on them (Rails, for example) do not work on this distribution yet. The fixes are tractable: I have already verified a one-line fix for msgpack locally and will send these upstream.
TLS trust anchors are not bundled in the zip. rbmanager provisions certificates from the Windows certificate store at install time, and I will separately propose OpenSSL::X509::Store#add_store support for the OpenSSL 3.2+ org.openssl.winstore:// store in ruby/openssl as the permanent solution.
x64 comes first. arm64 (arm64-mswin64) already builds in CI and will follow once its test suite is green.
Roadmap¶
The rollout is incremental rather than tied to a single date. Zips for the released series (3.3, 3.4, 4.0) will be published progressively for their existing releases. For 4.1, nightly zips of master are published continuously, and a zip follows each preview release as soon as it is out. Only the GA of rbmanager and the distribution mechanism as a whole is aligned with the Ruby 4.1 release in December.
Updated by hsbt (Hiroshi SHIBATA) 21 days ago
- Status changed from Open to Assigned
Updated by alanwu (Alan Wu) 19 days ago
ยท Edited
It looks like packaging vcruntime140.dll is dubious, because it gets security updates all the time, even if it's not a direct violation of Microsoft's redistribution terms: https://www.quora.com/Am-I-legally-allowed-in-C-Visual-Studio-to-distribute-msvcp140-dll-and-vcruntime140-dll-bundled-as-resources-into-my-close-source-executable-or-do-I-need-to-tell-my-users-to-download-them-from-Microsoft
It's also possible to include the Redistributable DLLs with your installer in merge modules. This method is now deprecated because libraries deployed this way can't be updated automatically by Windows Update.
Curious if you've considered linking with UCRT instead? If it works, that's one fewer DLL to ship, and one fewer thing to install for users on Windows 10 and up.
Updated by naruse (Yui NARUSE) 17 days ago
It looks like packaging vcruntime140.dll is dubious...
vcruntime is a part of libc on Windows and Visual C++. Though libc on Unix usually consists from a single binary, Windows separates it into Universal CRT and VCRuntime. ucrt provides main part of libc, and VCRuntime provides C compiler related things for example exception hendling and so on.
Just remove vcruntime140.dll and assume the user installed VC++ Redistributable package is rather reasonable.
Updated by matz (Yukihiro Matsumoto) 16 days ago
I approve all three asks: making these official distribution artifacts on ruby-lang.org, signing them with a project identity, and hosting rbmanager under the ruby organization.
The lack of an official Windows distribution has been a weak point of Ruby for decades, and this proposal fixes it for the very platform the core team builds and tests on, without competing with the existing gcc-based distributions. The fact that everything is already implemented and verified, and rides on the release automation hsbt already operates, makes this an easy decision.
Details such as the vcruntime bundling question can be settled among the people already discussing them.
Matz.
Updated by hsbt (Hiroshi SHIBATA) 13 days ago
Thanks all. I adopted naruse's suggestion: vcruntime140.dll was removed from the binary-package target in https://github.com/ruby/ruby/pull/17662 before the merge, so the runtime installed by the VC++ Redistributable stays serviced by Windows Update.
rb setup in rbmanager now checks for the Redistributable and installs it when missing. For users who extract the zip without rbmanager, it will be documented as a prerequisite in ruby/ruby or download page of www.
Updated by hsbt (Hiroshi SHIBATA) 11 days ago
I discussed the code signing plan for the official Windows binaries with @shugo (Shugo Maeda) . For the time being, we will use SignPath Foundation, which provides free code signing for open source projects. The publisher name on the binaries will be "SignPath Foundation" during this period.
In the long term, we will move to a certificate under a Ruby-related name, either Azure Trusted Signing or a regular OV code signing certificate. Since identity validation for Azure Trusted Signing is not yet available to Japanese entities, that option would need cooperation from an eligible organization, for example Ruby Central.