Web Development · Programming Languages
Cross-Compile Rust for 32-Bit Windows (i686) in 2026
Rust 1.100 drops host tools for i686 Windows. Here is how to build 32-bit Windows binaries from a 64-bit machine, with MSVC, MinGW and a CI setup.
Abhishek Gupta
5 min read
Sponsored
If you ship a Windows installer or plugin that still includes a 32-bit build, one line of the Rust blog’s October 2 announcement matters to you: after Rust 1.100.0, you cannot install a toolchain on a 32-bit Windows host. You can still produce 32-bit Windows binaries. You just do it from a 64-bit machine, which is how most of you already work.
This guide shows how to cross-compile Rust for 32-bit Windows (i686) from 64-bit Windows, Linux and CI, and what to test before 1.100 arrives.
What exactly changed
To cross-compile Rust for 32-bit Windows after 1.100.0, you build on a 64-bit host and add the target with rustup. The Rust project is demoting two targets to “std-only”, meaning the standard library is still built and shipped but the compiler binaries are not:
| Target | Before | After 1.100.0 |
|---|---|---|
i686-pc-windows-msvc | Tier 1, with host tools | Tier 1, without host tools |
i686-pc-windows-gnu | Tier 2, with host tools | Tier 2, without host tools |
The post gives the reason plainly. Machines that only run 32-bit x86 left production more than 15 years ago, general 32-bit Windows support ended in October 2025, and building these toolchains on modern hardware has gone badly. Compiler binaries built for i686 MSVC have crashed, and the GNU C++ toolchain has run out of memory while building LLVM.
Two things stay the same. Prebuilt standard library for both targets keeps shipping, and the MSVC target keeps getting tested in CI as a Tier 1 target. Other 32-bit platforms are not affected. The release date of 1.100.0 was not given in the announcement, so treat the work below as something to do this month rather than at the last minute.
Build from 64-bit Windows (MSVC)
This is the path most teams want, and it is short.
rustup target add i686-pc-windows-msvc
cargo build --release --target i686-pc-windows-msvc
The output lands in target\i686-pc-windows-msvc\release\. Two things go wrong here more than anything else:
- Missing x86 C++ tools. The MSVC linker for x86 comes with Visual Studio Build Tools, and the x86 component can be missing if you installed only the x64 workload. The linker error mentions
link.exeorkernel32.libnot found. Open the Visual Studio Installer and add the “MSVC x86/x64 build tools” component. - Build scripts and proc macros. These compile for the host (64-bit), not the target. A crate that assumes
target_pointer_widthequals the host’s will misbehave. If a build script generates code with pointer sizes baked in, check it.
To avoid typing the target every time, put it in .cargo/config.toml for a dedicated crate:
[build]
target = "i686-pc-windows-msvc"
I would not do this for a workspace that also produces 64-bit binaries. Use a CI matrix instead.
Build from Linux or macOS
You have two routes, and they differ in how much Windows you need on your machine.
GNU target with MinGW-w64. On Debian or Ubuntu:
sudo apt install gcc-mingw-w64-i686
rustup target add i686-pc-windows-gnu
Then tell Cargo which linker to use:
# .cargo/config.toml
[target.i686-pc-windows-gnu]
linker = "i686-w64-mingw32-gcc"
cargo build --release --target i686-pc-windows-gnu
Remember that this target is Tier 2: it builds, but the test coverage is thinner than for MSVC. Binaries link against the MinGW runtime, so check which DLLs they need before you ship.
MSVC target with cargo-xwin. If you must match the MSVC ABI (for example to link against a vendor’s .lib), cargo-xwin fetches the Windows SDK and CRT and uses lld:
cargo install cargo-xwin
rustup target add i686-pc-windows-msvc
cargo xwin build --release --target i686-pc-windows-msvc
The first run downloads a few hundred megabytes of SDK files, so cache them in CI. Note that cargo-xwin is a third-party tool and you should review its licence terms for the Windows SDK downloads before using it in a commercial pipeline.
Test the 32-bit build in CI
Building is only half the job. A 32-bit binary can compile and still fail at runtime, usually through pointer-width assumptions in unsafe code or FFI structs. Windows on 64-bit hardware runs 32-bit executables through WOW64, so a standard GitHub Actions Windows runner can run the tests:
jobs:
test-i686:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- run: rustup target add i686-pc-windows-msvc
- run: cargo test --target i686-pc-windows-msvc
cargo test --target builds the tests for 32-bit and runs them, which is what you want. Run this job on every pull request while you still ship 32-bit, not just at release time. If your pipeline touches secrets, also read how CI caches can leak them.
The general mechanism is documented in the rustup book on cross-compilation: rustup installs a prebuilt standard library for the target, and you supply the linker. That split is exactly what “std-only” keeps. What goes away is the compiler binary that runs on 32-bit Windows, not your ability to produce programs that run there.
Do you still need the 32-bit build?
Be honest about this before investing time. A 32-bit build costs CI minutes, test time and a second set of pointer-width bugs to chase, and every release you carry it multiplies that cost. Ask three questions:
- Do you have customers on 32-bit Windows? That OS lost general support in October 2025.
- Does a plugin host (an old DAW, CAD tool or ERP client) load only 32-bit DLLs? That is the most common real reason.
- Is there a hardware driver or vendor SDK that ships only as 32-bit?
If all three answers are no, dropping the target is cheaper than maintaining it. If any answer is yes, add the CI job above now so that the 1.100 change is a non-event. Our Rust release notes for 1.99.0 cover the other thing to review this month.
Need help untangling a legacy Windows build pipeline? CODERCOPS offers engineering services for exactly this kind of migration.
Frequently asked questions
- Does Rust stop supporting 32-bit Windows programs?
- No. Rust 1.100.0 removes host tools for i686 Windows, which means the compiler itself no longer ships for 32-bit Windows machines. Programs built for i686 Windows still work, and the MSVC target stays Tier 1 and tested in CI. You build them from a 64-bit host.
- How do I build a 32-bit Windows executable from 64-bit Windows?
- Install the target with rustup target add i686-pc-windows-msvc, make sure Visual Studio Build Tools include the x86 C++ tools, and run cargo build --target i686-pc-windows-msvc. The binary appears under target/i686-pc-windows-msvc/. A 64-bit Windows machine runs it directly.
- Can I cross-compile i686 Windows binaries from Linux?
- Yes. For the GNU target, install a MinGW-w64 i686 toolchain and point Cargo at its linker. For the MSVC target, a tool such as cargo-xwin downloads the Windows SDK pieces for you. Test the result on a Windows runner or under Wine.
- Why did the Rust project make this change?
- The Rust blog says 32-bit-only x86 desktop and server CPUs left production over 15 years ago, and that building toolchains for i686 Windows on modern hardware has run into crashes and out-of-memory failures while building LLVM. Cross-compiling from a better-supported host is the recommended path.
Sources
Sponsored
More from this category
More from Web Development
Sponsored
Discussion
Join the conversation.
Comments are powered by GitHub Discussions. Sign in with your GitHub account to leave a comment.
Sponsored