Problem
I’m attempting to compile the most basic code to Windows while coding on Linux.
fn main() {
println!("Hello, and bye.")
}
These commands came from a search on the internet:
rustc --target=i686-w64-mingw32-gcc main.rs
rustc --target=i686_pc_windows_gnu -C linker=i686-w64-mingw32-gcc main.rs
Unfortunately, none of them work. It complains about the standard crate being 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 Linux code that will run on Windows?
Asked by Fedcomp
Solution #1
While other answers are technically correct, they are more complex than necessary. You don’t require rustc (in fact, it’s discouraged; instead, use cargo); all you need is rustup, cargo, and your distribution’s mingw-w64.
Add the target (which you can modify to whatever target you’re cross-compiling for):
rustup target add x86_64-pc-windows-gnu
rustup toolchain install stable-x86_64-pc-windows-gnu
You may easily construct your crate using the following materials:
cargo build --target x86_64-pc-windows-gnu
There’s no need to fiddle with /.cargo/config or anything else.
EDIT: I just wanted to point out that while you can use the above, it can also be a pain. I’d like to point out that the rust tools team also maintains a cross: https://github.com/rust-embedded/cross Another option to consider is https://github.com/rust-embedded/cross
Answered by zee
Solution #2
Only compiled libraries for the host system are included in the Rust distribution. However, according to the Arch Linux wiki page on Rust, you can cross-compile by copying the compiled libraries from the Windows packages in the download directory (note that there are i686 and x86-64 packages), installing mingw-w64-gcc, and installing Wine in the appropriate place on your system (in /usr/lib/rustlib or /usr/local/lib/rustlib, depending on where Rust is installed).
If you’re using Cargo, you can instruct it where to look for ar and the linker by adding the following to your /.cargo/config (where $ARCH is your architecture):
[target.$ARCH-pc-windows-gnu]
linker = "/usr/bin/$ARCH-w64-mingw32-gcc"
ar = "/usr/$ARCH-w64-mingw32/bin/ar"
Note that depending on your distribution, the exact pathways may differ. Check your distribution’s file list for the mingw-w64 package(s) (GCC and binutils).
Then you can use Cargo in the following way:
$ # Build
$ cargo build --release --target "$ARCH-pc-windows-gnu"
$ # Run unit tests under wine
$ cargo test --target "$ARCH-pc-windows-gnu"
Answered by Francis Gagné
Solution #3
UPDATE 2019-06-11
This doesn’t work for me because:
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
Perhaps this will be of assistance. https://github.com/rust-lang/rust/issues/44787
Static-compiling sdl is a possibility, however it didn’t work for me.
Also, while using the packaged, the mixer is not included.
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 .
Create multiple examples at the same time.
cargo build --target=x86_64-pc-windows-gnu --verbose --examples
Alternatively, you can stop after your first failure:
echo; for i in examples/*; do [ $? -eq 0 ] && cargo build --target=x86_64-pc-windows-gnu --verbose --example $(basename $i .rs); done
Binaries will be placed in target/x86 64-pc-windows-gnu/debug/examples/ by cargo build.
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, on your Windows system, copy the target/x86 64-pc-windows-gnu/debug/examples/ directory and run the exe files.
If you wish to see the console output when running exe files, you can use cmd.exe to do so.
In file explorer, right-click with shift on an empty space in the window and select Open command window here to open cmd.exe in the current directory.
Backtraces should now work with mingw; if not, use msvc (https://github.com/rust-lang/rust/pull/39234).
Answered by rofrol
Solution #4
Cross, a Docker-based solution, is available. Because all of the necessary tools are virtualized, you won’t need to install any additional packages on your PC. See the list of targets that are supported.
From project’s README:
It’s necessary to use one of these container engines. If both are installed, cross will use docker by default.
$ cargo install cross
Cross uses the same CLI as Cargo, but because it relies on Docker, you’ll need to run the daemon first.
# (ONCE PER BOOT)
# Start the Docker daemon, if it's not already running
$ sudo systemctl start docker
# MAGIC! This Just Works
$ cross build --target aarch64-unknown-linux-gnu
# EVEN MORE MAGICAL! This also Just Works
$ cross test --target mips64-unknown-linux-gnuabi64
# Obviously, this also Just Works
$ cross rustc --target powerpc-unknown-linux-gnu --release -- -C lto
Answered by raspi
Solution #5
This was the solution that worked for me. Although it is identical to one of the allowed responses, I did not feel it necessary to provide the toolchain.
rustup target add x86_64-pc-windows-gnu
cargo build --target x86_64-pc-windows-gnu
For further information, see the documentation.
Answered by rbansal
Post is based on https://stackoverflow.com/questions/31492799/cross-compile-a-rust-application-from-linux-to-windows