Question
I want to compile a very simple Rust program for Windows while developing on Linux.
fn main() {
println!("Hello, and bye.");
}
I found commands like these:
rustc --target=i686-w64-mingw32-gcc main.rs
rustc --target=i686_pc_windows_gnu -C linker=i686-w64-mingw32-gcc main.rs
However, they do not work. I get an error saying the std crate is missing:
$ rustc --target=i686_pc_windows_gnu -C linker=i686-w64-mingw32-gcc main.rs
main.rs:1:1: 1:1 error: can't find crate for `std`
main.rs:1 fn main() {
^
error: aborting due to previous error
Is it possible to compile Rust code on Linux so that it runs on Windows? If so, what needs to be installed or configured correctly?
Short Answer
By the end of this page, you will understand how Rust cross-compilation works, why the std crate error happens, how Rust targets and linkers fit together, and how to build a Windows executable from Linux using the correct target toolchain.
Concept
Rust can compile code for platforms other than the one you are currently using. This is called cross-compilation.
When you compile Rust code for another operating system, Rust needs two major things:
- A target that tells Rust which platform you want to build for
- The correct standard library and linker tools for that target
In the question, the error says Rust cannot find the std crate. That usually means:
- the Windows target has not been installed in Rust, or
- the compiler is being asked to build for a target that does not have its standard library available
In Rust, std is not automatically available for every platform unless that platform's target support is installed. For example, building on Linux for Linux works out of the box because your default toolchain already includes the Linux standard library. But if you want to build for Windows, you must install the Windows target.
A second piece is the linker. Rust compiles your code, but it still needs a platform-appropriate linker to produce the final executable. For the windows-gnu target, developers commonly use a MinGW cross-linker such as:
i686-w64-mingw32-gcc
So the full setup for cross-compiling from Linux to Windows usually means:
- Install the Rust Windows target
- Install a Windows-compatible linker
- Build using that target
This matters in real programming because teams often build software for multiple operating systems from one CI server or one development machine.
Mental Model
Think of Rust cross-compilation like writing a letter in your home country and sending it to another country.
- Your Rust source code is the message
- The target triple is the destination country
- The standard library for that target is the local language and formatting rules
- The linker is the local postal system that packages the message correctly
If you only write the message but do not know the destination's rules, the package cannot be prepared correctly. That is why Rust complains when std for the Windows target is missing: it does not have the platform-specific pieces needed to finish the build.
Syntax and Examples
To cross-compile Rust from Linux to Windows, you typically use a target triple.
Common Windows targets
x86_64-pc-windows-gnu→ 64-bit Windows using GNU toolchaini686-pc-windows-gnu→ 32-bit Windows using GNU toolchainx86_64-pc-windows-msvc→ 64-bit Windows using MSVC toolchain
From Linux, the GNU Windows target is usually the practical choice.
Install the target with rustup
rustup target add x86_64-pc-windows-gnu
Or for 32-bit Windows:
rustup target add i686-pc-windows-gnu
Install the linker
On Debian or Ubuntu, you might install MinGW like this:
sudo apt install gcc-mingw-w64-x86-64 gcc-mingw-w64-i686
Compile a single file
rustc --target=x86_64-pc-windows-gnu -C linker=x86_64-w64-mingw32-gcc main.rs
Example program
fn main() {
println!("Hello, and bye.");
}
Step by Step Execution
Consider this file:
fn main() {
println!("Hello, and bye.");
}
And this command:
rustc --target=x86_64-pc-windows-gnu -C linker=x86_64-w64-mingw32-gcc main.rs
Here is what happens step by step:
rustcreadsmain.rs- It sees that the program uses
println!, which depends on Rust's standard library - Because you passed
--target=x86_64-pc-windows-gnu, Rust tries to build for 64-bit Windows GNU - Rust looks for the
stdcrate compiled forx86_64-pc-windows-gnu - If that target has not been installed with
rustup, compilation fails withcan't find crate for 'std' - If the target exists, Rust compiles your code into object files for Windows
- Rust then calls the linker you provided:
x86_64-w64-mingw32-gcc - The linker creates the final Windows executable
- The result is a
.exefile that can run on Windows
Why the original command failed
Real World Use Cases
Cross-compiling Rust is useful in many real situations:
- CI/CD pipelines: Build Linux, Windows, and macOS artifacts from automated build servers
- Open-source releases: Publish
.exefiles for Windows users even if maintainers work on Linux - Embedded or constrained environments: Build for a platform you are not actively running
- CLI tools: Ship one command-line app to users on multiple operating systems
- Internal tooling: Generate Windows utilities from a Linux-based engineering environment
Example scenarios
- A team maintains a Rust CLI on Ubuntu but wants GitHub Releases to include
tool.exe - A server-side Linux build machine creates Windows binaries for QA testers
- A developer writes a small Rust utility on Linux and sends the compiled
.exeto Windows coworkers
Real Codebase Usage
In real projects, developers usually do not invoke rustc manually for cross-platform builds. Instead, they use Cargo, configuration files, and repeatable build scripts.
Common patterns
1. Cargo target builds
cargo build --release --target x86_64-pc-windows-gnu
This places the result in a target-specific folder such as:
target/x86_64-pc-windows-gnu/release/
2. Linker configuration in project config
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
This avoids repeating linker flags every time.
3. Separate targets for 32-bit and 64-bit
Teams often choose one of these depending on deployment needs:
i686-pc-windows-gnufor older 32-bit systemsx86_64-pc-windows-gnufor modern 64-bit Windows systems
4. Release builds for distribution
cargo build --release --target x86_64-pc-windows-gnu
Release mode creates optimized binaries suitable for shipping.
5. Validation in CI
Common Mistakes
Here are common beginner mistakes when cross-compiling Rust.
1. Using the wrong target name
Broken:
rustc --target=i686_pc_windows_gnu main.rs
Rust target triples use hyphens, not underscores:
Correct:
rustc --target=i686-pc-windows-gnu main.rs
2. Forgetting to install the target
Broken idea: assuming --target automatically downloads support files.
Correct setup:
rustup target add i686-pc-windows-gnu
Without this, Rust often fails with:
can't find crate for `std`
3. Confusing the target with the linker
Broken:
rustc --target=i686-w64-mingw32-gcc main.rs
i686-w64-mingw32-gcc is a linker executable, not a Rust target triple.
Correct:
rustc --target=i686-pc-windows-gnu -C linker=i686-w64-mingw32-gcc main.rs
4. Not installing MinGW cross tools
Even if Rust has the target installed, linking can still fail if the Windows GNU linker is missing.
Comparisons
| Concept | What it is | Example | When to use |
|---|---|---|---|
| Rust target triple | The platform Rust should compile for | x86_64-pc-windows-gnu | Always when cross-compiling |
| Linker | External tool that produces the final executable | x86_64-w64-mingw32-gcc | Needed to finish the build |
| Native compilation | Build for your current OS | Linux to Linux | Default case |
| Cross-compilation | Build for a different OS or CPU | Linux to Windows | Multi-platform releases |
rustc | Low-level compiler command | rustc main.rs |
Cheat Sheet
Quick setup
64-bit Windows target
rustup target add x86_64-pc-windows-gnu
sudo apt install gcc-mingw-w64-x86-64
cargo build --target x86_64-pc-windows-gnu
32-bit Windows target
rustup target add i686-pc-windows-gnu
sudo apt install gcc-mingw-w64-i686
cargo build --target i686-pc-windows-gnu
Single-file compilation
rustc --target=x86_64-pc-windows-gnu -C linker=x86_64-w64-mingw32-gcc main.rs
Important rules
--targetmust be a Rust target triple, not a linker name- The target's standard library must be installed with
rustup target add ... - The linker must match the architecture
- Prefer Cargo for anything beyond tiny examples
- On Linux,
windows-gnuis usually easier thanwindows-msvc
Common target triples
x86_64-pc-windows-gnu
i686-pc-windows-gnu
Common linker names
x86_64-w64-mingw32-gcc
i686-w64-mingw32-gcc
Common error meaning
FAQ
Can I compile Rust for Windows while using Linux?
Yes. This is called cross-compilation. You need the correct Rust target and a Windows-compatible linker.
Why does Rust say it cannot find the std crate?
Usually because the target standard library is not installed. Run rustup target add <target> for the Windows target you want.
What is the correct Windows target for Linux users?
Most Linux users choose x86_64-pc-windows-gnu for 64-bit Windows or i686-pc-windows-gnu for 32-bit Windows.
What is the difference between target and linker?
The target tells Rust what platform to build for. The linker is the external tool that creates the final executable for that platform.
Should I use rustc or Cargo for cross-compiling?
Use Cargo for real projects. It is easier to configure, repeat, and maintain.
Can I build the MSVC Windows target from Linux?
In most normal setups, Linux users target windows-gnu instead. MSVC targets usually depend on Microsoft's toolchain.
Why does architecture matter when choosing the linker?
Because 32-bit targets need 32-bit linkers, and 64-bit targets need 64-bit linkers. Mixing them causes build failures.
Mini Project
Description
Create a tiny Rust command-line program on Linux and build it into a Windows executable. This project demonstrates the full cross-compilation workflow: installing a target, configuring the linker, and producing a .exe file that can run on Windows.
Goal
Build a working Windows .exe from Linux using Cargo and the x86_64-pc-windows-gnu target.
Requirements
- Create a new Rust binary project using Cargo.
- Print a simple message that confirms the program is running.
- Install the Windows GNU Rust target.
- Configure Cargo to use the correct MinGW linker.
- Build the project for 64-bit Windows in release mode.
Keep learning
Related questions
Accessing Cargo Package Metadata in Rust
Learn how to read Cargo package metadata like version, name, and authors in Rust using compile-time environment macros.
Associated Types vs Generic Type Parameters in Rust: When to Use Each
Learn when to use associated types vs generic parameters in Rust traits, with clear rules, examples, and practical API design advice.
Can a Struct Extend Another Struct in Rust? Composition vs Inheritance
Learn how Rust handles struct reuse without inheritance, using composition, traits, and wrapper structs with practical examples.