Cross-compile a Rust application from Linux to Windows
Other answers, while technically correct, are more difficult than they need to be. There's no need to use rustc
(in fact it's discouraged, just use cargo
), you only need rustup
, cargo
and your distribution's mingw-w64.
Add the target (you can also change this for whatever target you're cross compiling for):
rustup target add x86_64-pc-windows-gnu
You can build your crate easily with:
cargo build --target x86_64-pc-windows-gnu
No need for messing around with ~/.cargo/config
or anything else.
EDIT: Just wanted to add that while you can use the above it can also sometimes be a headache. I wanted to add that the rust tools team also maintains a project called cross: https://github.com/rust-embedded/cross This might be another solution that you want to look into
The Rust distribution only provides compiled libraries for the host system. However, according to Arch Linux's wiki page on Rust, you could copy the compiled libraries from the Windows packages in the download directory (note that there are i686 and x86-64 packages) in the appropriate place on your system (in /usr/lib/rustlib
or /usr/local/lib/rustlib
, depending on where Rust is installed), install mingw-w64-gcc and Wine and you should be able to cross-compile.
If you're using Cargo, you can tell Cargo where to look for ar
and the linker by adding this to ~/.cargo/config
(where $ARCH
is the architecture you use):
[target.$ARCH-pc-windows-gnu]
linker = "/usr/bin/$ARCH-w64-mingw32-gcc"
ar = "/usr/$ARCH-w64-mingw32/bin/ar"
Note: the exact paths can vary based on your distribution. Check the list of files for the mingw-w64 package(s) (GCC and binutils) in your distribution.
Then you can use Cargo like this:
$ # Build
$ cargo build --release --target "$ARCH-pc-windows-gnu"
$ # Run unit tests under wine
$ cargo test --target "$ARCH-pc-windows-gnu"
UPDATE 2019-06-11
This fails for me with:
Running `rustc --crate-name animation examples/animation.rs --color always --crate-type bin --emit=dep-info,link -C debuginfo=2 --cfg 'feature="default"' -C metadata=006e668c6384c29b -C extra-filename=-006e668c6384c29b --out-dir /home/roman/projects/rust-sdl2/target/x86_64-pc-windows-gnu/debug/examples --target x86_64-pc-windows-gnu -C ar=x86_64-w64-mingw32-gcc-ar -C linker=x86_64-w64-mingw32-gcc -C incremental=/home/roman/projects/rust-sdl2/target/x86_64-pc-windows-gnu/debug/incremental -L dependency=/home/roman/projects/rust-sdl2/target/x86_64-pc-windows-gnu/debug/deps -L dependency=/home/roman/projects/rust-sdl2/target/debug/deps --extern bitflags=/home/roman/projects/rust-sdl2/target/x86_64-pc-windows-gnu/debug/deps/libbitflags-2c7b3e3d10e1e0dd.rlib --extern lazy_static=/home/roman/projects/rust-sdl2/target/x86_64-pc-windows-gnu/debug/deps/liblazy_static-a80335916d5ac241.rlib --extern libc=/home/roman/projects/rust-sdl2/target/x86_64-pc-windows-gnu/debug/deps/liblibc-387157ce7a56c1ec.rlib --extern num=/home/roman/projects/rust-sdl2/target/x86_64-pc-windows-gnu/debug/deps/libnum-18ac2d75a7462b42.rlib --extern rand=/home/roman/projects/rust-sdl2/target/x86_64-pc-windows-gnu/debug/deps/librand-7cf254de4aeeab70.rlib --extern sdl2=/home/roman/projects/rust-sdl2/target/x86_64-pc-windows-gnu/debug/deps/libsdl2-3f37ebe30a087396.rlib --extern sdl2_sys=/home/roman/projects/rust-sdl2/target/x86_64-pc-windows-gnu/debug/deps/libsdl2_sys-3edefe52781ad7ef.rlib -L native=/home/roman/.cargo/registry/src/github.com-1ecc6299db9ec823/winapi-x86_64-pc-windows-gnu-0.4.0/lib`
error: linking with `x86_64-w64-mingw32-gcc` failed: exit code: 1
Maybe this will help https://github.com/rust-lang/rust/issues/44787
Static compile sdl2
There is option to static-compile sdl but it didn't work for me.
Also mixer is not included when used with bundled.
Let's cross-compile examples from rust-sdl2 project from Ubuntu to Windows x86_64
In ~/.cargo/config
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
ar = "x86_64-w64-mingw32-gcc-ar"
Then run this:
sudo apt-get install gcc-mingw-w64-x86-64 -y
# use rustup to add target https://github.com/rust-lang/rustup.rs#cross-compilation
rustup target add x86_64-pc-windows-gnu
# Based on instructions from https://github.com/AngryLawyer/rust-sdl2/
# First we need sdl2 libs
# links to packages https://www.libsdl.org/download-2.0.php
sudo apt-get install libsdl2-dev -y
curl -s https://www.libsdl.org/release/SDL2-devel-2.0.9-mingw.tar.gz | tar xvz -C /tmp
# Prepare files for building
mkdir -p ~/projects
cd ~/projects
git clone https://github.com/Rust-SDL2/rust-sdl2
cd rust-sdl2
cp -r /tmp/SDL2-2.0.9/x86_64-w64-mingw32/lib/* ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/
cp /tmp/SDL2-2.0.9/x86_64-w64-mingw32/bin/SDL2.dll .
Build examples at once
cargo build --target=x86_64-pc-windows-gnu --verbose --examples
Or stop after first fail:
echo; for i in examples/*; do [ $? -eq 0 ] && cargo build --target=x86_64-pc-windows-gnu --verbose --example $(basename $i .rs); done
Run
cargo build
will put binaries in target/x86_64-pc-windows-gnu/debug/examples/
Copy needed files:
cp /tmp/SDL2-2.0.4/x86_64-w64-mingw32/bin/SDL2.dll target/x86_64-pc-windows-gnu/debug/examples/
cp assets/sine.wav target/x86_64-pc-windows-gnu/debug/examples/
Then copy directory target/x86_64-pc-windows-gnu/debug/examples/
to your Windows machine and run exe files.
Run in cmd.exe
If you want to see the console output when running exe files, you may run them from cmd.exe
.
To open cmd.exe
in current directory in file explorer, right click with shift on empty place in window and choose Open command window here
.
Backtraces with mingw should work now - if not use msvc https://github.com/rust-lang/rust/pull/39234