You should be able to see the commands that cross invokes using the -vv/--verbose flag: cross build -vv --target=x86_64-unknown-linux-gnu Answer from SkiFire13 on reddit.com
🌐
GitHub
github.com › cross-rs › cross
GitHub - cross-rs/cross: “Zero setup” cross compilation and “cross testing” of Rust crates
FROM rust:1 # set CROSS_CONTAINER_IN_CONTAINER to inform `cross` that it is executed from within a container ENV CROSS_CONTAINER_IN_CONTAINER=true # install `cross` RUN cargo install cross ...
Starred by 8.1K users
Forked by 451 users
Languages   Rust 58.8% | Shell 20.0% | Dockerfile 12.8% | Python 7.3%
🌐
crates.io
crates.io › crates › cross
cross - crates.io: Rust Package Registry
May 1, 2025 - FROM rust:1 # set CROSS_CONTAINER_IN_CONTAINER to inform `cross` that it is executed from within a container ENV CROSS_CONTAINER_IN_CONTAINER=true # install `cross` RUN cargo install cross ...
🌐
Rust
rust-lang.github.io › rustup › cross-compilation.html
Cross-compilation - The rustup book
With the arm-linux-androideabi ... the --target flag, as in cargo build --target=arm-linux-androideabi. Note that rustup target add only installs the Rust standard library for a given target. There are typically other tools necessary to cross-compile, particularly a ...
🌐
Reddit
reddit.com › r/rust › how does cargo cross work?
r/rust on Reddit: How does cargo cross work?
March 20, 2023 -

Can someone explain to me like I'm an idiot what exactly does

cross build

do beneath the hood?

Let's say I'm using 2 docker images:

  • builder:rust1.66

  • builder:rust1.67

each with the correspoding Rust toolchain installed

Locally I've got rust 1.68

Cross.toml at the root of my project contains the following

[target.x86_64-unknown-linux-gnu]
image = "builder:rust1.66"

When I run

cross build --target=x86_64-unknown-linux-gnu

I would expect that the project gets built with Rust 1.66

However, it gets built with local toolchain

cross -v                                     
+ cargo metadata --format-version 1
+ rustc --print sysroot
+ rustup toolchain list
+ rustup target list --toolchain 1.68.0-x86_64-unknown-linux-gnu
+ rustup component list --toolchain 1.68.0-x86_64-unknown-linux-gnu
[cross] note: Falling back to `cargo` on the host.

Even if I change Cross.toml to contain

[target.x86_64-unknown-linux-gnu]
image = "builder:rust1.67"

the same thing happens.

  1. Why does cross use my local toolchain?

  2. Why does it not reflect changes in the builder image?

Top answer
1 of 2
3
You should be able to see the commands that cross invokes using the -vv/--verbose flag: cross build -vv --target=x86_64-unknown-linux-gnu
2 of 2
2
Hello! Thanks for the interest in cross :) I'll try to answer your questions, should probably put this up on the wiki as well :3 As u/SkiFire13 mentioned, you can see what cross does with -v I'll explain the output on current main (cross 99b8069c 2023-02-12) + cargo metadata --format-version 1 --filter-platform x86_64-unknown-linux-gnu This command grabs the paths that need to be mounted and used into the container later. + rustc --print sysroot This finds the sysroot of the toolchains. + /usr/local/bin/docker + /usr/local/bin/docker version -f '{{ .Server.Os }},,,{{ .Server.Arch }}' these two commands just checks if docker/podman is available, and also what architecture the server runs on, like linux/amd64 for x86_64 or linux/arm64 for aarch64 It also enables certain flags if it's docker or podman + rustup toolchain list Here we get the list of installed toolchains, if the required toolchain is not installed, we install it. (default toolchain is always for target x86_64-unknown-linux-gnu unless otherwise overriden, the provided images on ghcr are currently all for x86_64) So, for a system running aarch64, we still install a x86_64 rust toolchain, there are plans to change this (and it's possible to do already, see https://github.com/cross-rs/cross/issues/751 ) + rustup target list --toolchain stable-x86_64-unknown-linux-gnu This checks what targets are available in the toolchain, if the required target is missing, we install it. + rustup component list --toolchain stable-x86_64-unknown-linux-gnu Here we check if all required components are installed, like rust-src if -Zbuild-std is needed, etc. + /usr/local/bin/docker run --userns host --platform linux/amd64 -e 'PKG_CONFIG_ALLOW_CROSS=1' -e 'XARGO_HOME=/home/user/.xargo' -e 'CARGO_HOME=/home/user/.cargo' -e 'CROSS_RUST_SYSROOT=/home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu' -e 'CARGO_TARGET_DIR=/target' -e 'CROSS_RUNNER=' -e TERM -e 'USER=emil' -e 'CROSS_RUSTC_MAJOR_VERSION=1' -e 'CROSS_RUSTC_MINOR_VERSION=67' -e 'CROSS_RUSTC_PATCH_VERSION=0' --name cross-stable-x86_64-unknown-linux-gnu-47e2d-fc594f156-x86_64-unknown-linux-gnu-b0dac-1679392166158 --rm --user 501:20 -v /home/user/.xargo:/home/user/.xargo:z -v /home/user/.cargo:/home/user/.cargo:z -v /home/user/.cargo/bin -v /home/user/my_project:/home/user/my_project:z -v /home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu:/home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu:z,ro -v /home/user/my_project/target:/target:z -w /home/user/my_project -t ghcr.io/cross-rs/x86_64-unknown-linux-gnu:main sh -c 'PATH="$PATH":"/home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin" cargo build -v --target x86_64-unknown-linux-gnu' And here is the magic, you can actually copy this line and run it yourself, cross does in it's default operation no magic fs or similar and cross is just a helper to call docker, I'll explain what everything does. docker run --userns host --platform linux/amd64 We want to run in the same namespace as the host and specify what platform to run for. -e 'PKG_CONFIG_ALLOW_CROSS=1' -e 'XARGO_HOME=/home/user/.xargo' -e 'CARGO_HOME=/home/user/.cargo' -e 'CROSS_RUST_SYSROOT=/home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu' -e 'CARGO_TARGET_DIR=/target' -e 'CROSS_RUNNER=' -e TERM -e 'USER=emil' -e 'CROSS_RUSTC_MAJOR_VERSION=1' -e 'CROSS_RUSTC_MINOR_VERSION=67' -e 'CROSS_RUSTC_PATCH_VERSION=0' These environment variables are forwarded to the container so that everything runs correctly --name cross-stable-x86_64-unknown-linux-gnu-47e2d-fc594f156-x86_64-unknown-linux-gnu-b0dac-1679392166158 --rm --user 501:20 Here we name the container and make it remove itself on exit, we also set the uid/gid -v /home/user/.xargo:/home/user/.xargo:z -v /home/user/.cargo:/home/user/.cargo:z -v /home/user/.cargo/bin Here we mount the different dot folders, like cargo and xargo (which is a old byproduct, it's not relevant anymore but is used in some cases) -v /home/user/my_project:/home/user/my_project:z Here we mount your code that you want to compile, if cargo metadata also pointed to other paths (like path dependencies), it'll mount those for you. -v /home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu:/home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu:z,ro This is why the toolchain in the docker container you specified is not used, we mount the local toolchain as a read-only path into the container. -v /home/user/my_project/target:/target:z This ensures that cross uses the same target-dir that you specified (or didn't) -w /home/user/my_project -t ghcr.io/cross-rs/x86_64-unknown-linux-gnu:main Now, we set the workind directory and then the image to use. And finally! sh -c 'PATH="$PATH":"/home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin" cargo build -v --target x86_64-unknown-linux-gnu' This will add to path the binaries for running your mounted toolchain, and then execute cargo. Everything after this point is handled by docker and cargo So, an answer to question 1: it uses your local toolchain to avoid stagnation in the docker images and to make it possible to use tools like cargo-bisect-rustc I'm not sure what question 2 is asking, but hopefully it's explained with the above Now, to actually use another version of rust, simply do cross +1.66 and it'll mount 1.66-x86_64-unknown-linux-gnu instead.
🌐
Reddit
reddit.com › r/rust › psa: for cross-compiling please use the "cross" tool.
r/rust on Reddit: PSA: For cross-compiling please use the "Cross" tool.
January 5, 2024 -

It is fairly typical for me to cross-compile from my MacOS development machine to my embedded targets of STM32, RP2040, and the Raspberry Pi platforms. To support this I have in the past struggled to install (although not toooo hard to do) to install all of the necessary tools to cross-compile directly on those targets. Last night, for the first time, I tried the rust native "Cross" tool. Oh My Gosh! I am never going back sans some currently unforeseen limitation on this. The ease of using this tool and it simply working should not be ignored.

Get back to building and innovating instead of fighting the tool chain!

Ok, for some, that may be too much to read, so...

TLDR; Use the rust Cross tool to perform cross-compiling for different targets! ;)

Top answer
1 of 5
28
I typically cross compile for different architectures on Linux and have found great success with using mold instead of cross. To make statically linked musl binaries you can add this .cargo/config.toml file: # Linker options for MUSL targets. We need to manually specify --target as cargo # doesn't do that for us by default [target.x86_64-unknown-linux-musl] linker = "clang" rustflags = [ "-C", "link-arg=-fuse-ld=mold", "-C", "link-arg=--target=x86_64-unknown-linux-musl", ] [target.aarch64-unknown-linux-musl] linker = "clang" rustflags = [ "-C", "link-arg=-fuse-ld=mold", "-C", "link-arg=--target=aarch64-unknown-linux-musl", ] And then compile using cargo build --release --target aarch64-unknown-linux-musl This works great in CI as well (with the drawback that you need clang installed as well). Extract from my gitlab ci: .mold: setup: # Install the latest available Clang version in Bullseye - apt-get update - DEBIAN_FRONTEND=noninteractive apt-get install -y clang-13 # Clang is installed with a prefix, which is not what we want - ln -s /usr/bin/clang-13 /usr/bin/clang - clang --version # Install mold - curl -L -o mold.tar.gz https://github.com/rui314/mold/releases/download/v2.1.0/mold-2.1.0-x86_64-linux.tar.gz - echo "67a479bf2eddf10dd223e488ceedddca49174f629f7a4bbaeaab80c5b5702021 mold.tar.gz"|sha256sum --check --status - tar -xz --strip-components=1 -C /usr/ -f mold.tar.gz - rm mold.tar.gz - mold --version build-aarch64-musl: stage: deploy needs: - test script: - !reference [.mold, setup] - rustup target add aarch64-unknown-linux-musl - cargo build --release --target aarch64-unknown-linux-musl artifacts: paths: - target/aarch64-unknown-linux-musl/release/binary
2 of 5
22
I'm surprised you had much difficulty with STM32 and RP2040 targets. For example, the RP2040 target is just: rustup target add thumbv6m-none-eabi cargo install elf2uf2-rs Then set up a .cargo/config file similar to this: [build] target = "thumbv6m-none-eabi" [target.thumbv6m-none-eabi] runner = "elf2uf2-rs -d" And you can flash code with cargo run --release. Doesn't get much easier than that. That being said, I can see cross being useful for the Raspberry Pi boards.
🌐
GitHub
github.com › cross-rs › cross › wiki › Getting-Started
Getting Started · cross-rs/cross Wiki · GitHub
January 21, 2023 - $ cargo init --bin hello $ cd hello ...u/debug/hello` Hello, world! This will automatically install the Rust target required and the Docker image containing the toolchain to cross-compile your target....
Author   cross-rs
🌐
crates.io
crates.io › crates › cargo-cross
cargo-cross - crates.io: Rust Package Registry
February 5, 2026 - A cargo subcommand for cross-compilation, no need docker! A powerful GitHub Action for building, testing, and checking Rust projects with cross-compilation support. This action automatically downloads and configures the necessary cross-compilation ...
🌐
Rust
docs.rs › cargo-cross › latest › cargo_cross
cargo_cross - Rust
cargo-cross: Cross-compilation tool for Rust projects
Find elsewhere
🌐
GitHub
github.com › rust-cross › cargo-xwin
GitHub - rust-cross/cargo-xwin: Cross compile Cargo project to Windows MSVC target with ease · GitHub
Cross compile Cargo project to Windows msvc target with ease using xwin or windows-msvc-sysroot. By using this software you are consented to accept the license at https://go.microsoft.com/fwlink/?LinkId=2086102 · Install clang (On macOS run ...
Starred by 571 users
Forked by 45 users
Languages   Rust 96.3% | Dockerfile 2.2% | CMake 1.5%
🌐
Docs.rs
docs.rs › crate › cross › 0.1.13
cross 0.1.13 - Docs.rs
cross has the exact same CLI as Cargo but as it relies on Docker you'll have to start the daemon before you can use it. # (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
🌐
Rust
docs.rs › cross
cross - Rust
⚠️ Warning: The cross library is for internal use only: only the command-line interface is stable. The library may change at any point for any reason. For documentation on the CLI, please see the repository README or the wiki. pub use self::errors::install_panic_hook; pub use self::errors::install_termination_hook; pub use self::rustc::TargetList; pub use self::rustc::VersionMetaExt; docker · errors · rustc · shell · temp · Cargo ·
🌐
GitHub
github.com › rust-cross › cargo-zigbuild
GitHub - rust-cross/cargo-zigbuild: Compile Cargo project with zig as linker · GitHub
docker run --rm -it -v $(pwd):/io -w /io ghcr.io/rust-cross/cargo-zigbuild \ cargo zigbuild --release --target x86_64-apple-darwin
Starred by 2.4K users
Forked by 87 users
Languages   Rust 94.1% | C 2.8% | C++ 1.7% | Dockerfile 1.4%
🌐
Tangram Vision
tangramvision.com › blog › cross-compiling-your-project-in-rust
Tangram Vision Blog | Cross-Compiling Your Project in Rust
February 13, 2024 - with cross is as simple as swapping the commands: ... So for a “standard” Rust project building with cargo, it is as simple as swapping out cargo for cross for whatever commands you’re used to using to build or test Rust projects.
🌐
LogRocket
blog.logrocket.com › home › a guide to cross-compilation in rust
A guide to cross-compilation in Rust - LogRocket Blog
June 4, 2024 - Instead, we’re going to use the Cross crate, which used to be maintained by the Rust Embedded Working Group Tools group. First, let’s set up a simple project that will show which platform it’s running on. To do this, we’re going to use the current_platform crate, which is an easy way to see what platform your code is running on, as well as what platform it was compiled on. Let’s make a new crate with cargo new and add the crate with cargo add current_platform.
🌐
Rustprojectprimer
rustprojectprimer.com › building › cross.html
Cross-Compiling - Rust Project Primer
Set environment variables to tell Cargo which linker to use and where pkg-config can find the target’s libraries. Optionally, install qemu-user-binfmt to enable transparent emulation of non-native binaries via binfmt_misc. To cross-compile for ARM64 on a Debian-based system: # install the cross-compiler and target libraries sudo dpkg --add-architecture arm64 sudo apt update sudo apt install gcc-aarch64-linux-gnu libssl-dev:arm64 # add the Rust target rustup target add aarch64-unknown-linux-gnu # tell Cargo which linker to use export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc # tell pkg-config where to find arm64 libraries export PKG_CONFIG_LIBDIR=/usr/lib/aarch64-linux-gnu/pkgconfig export PKG_CONFIG_ALLOW_CROSS=true # build cargo build --target aarch64-unknown-linux-gnu
🌐
Docker
docker.com › blog › cross-compiling-rust-code-for-multiple-architectures
Cross Compiling Rust Code for Multiple Architectures | Docker
August 8, 2022 - FROM rust:latest RUN apt update && apt upgrade -y RUN apt install -y g++-mingw-w64-x86-64 RUN rustup target add x86_64-pc-windows-gnu RUN rustup toolchain install stable-x86_64-pc-windows-gnu WORKDIR /app CMD ["cargo", "build", "--target", "x86_64-pc-windows-gnu"] The first line creates your image from the Rust base image. The next command upgrades the contents of your image’s packages to the latest version and installs mingw, an open source program that builds Windows applications. The next two lines are key to getting cross compilation working.
🌐
Reddit
reddit.com › r/rust › [review] introducing cargo-xwin: a solution for cross-compiling rust on macos to msvc
r/rust on Reddit: [Review] Introducing cargo-xwin: A Solution for Cross-Compiling Rust on macOS to MSVC
May 26, 2023 -

Hello, Rustaceans!

Like many of you, I've faced challenges in cross-compiling Rust from macOS to MSVC. The more popular crates such as "cross" have proven ineffective in my pursuit, leaving me to explore other avenues.

Today, I am excited to introduce a real game-changer - the [cargo-xwin](https://github.com/rust-cross/cargo-xwin) crate! After countless trials and errors, cargo-xwin was the only one that truly met my needs.

Why is this crate a standout? It works smoothly and effortlessly, proving itself as a true diamond in the rough. I've been running it on a Macbook M1 with macOS v13, and the performance has been seamless, making it a breeze to cross compile my Rust code to MSVC.

What sets cargo-xwin apart is its solid performance and effectiveness. While this might just be my personal experience, I strongly encourage anyone grappling with the same cross-compiling issues to give this crate a try. Your experience may vary, but it just might save you the same headache it saved me.

For anyone interested in testing out the crate, you can find it here: [cargo-xwin](https://github.com/rust-cross/cargo-xwin)

In conclusion, if you've been wrestling with the cross-compiling conundrum like I was, I truly believe cargo-xwin could be the solution you're searching for. Give it a try, and let's open a dialogue about our experiences with it!

Happy coding, everyone!

(Note: I am not affiliated with the creators of cargo-xwin - just a satisfied user sharing a valuable find.)

🌐
DEV Community
dev.to › carolineee › how-to-use-cargo-to-cross-compile-rust-programs-for-raspberry-pi-26l
How to use Cargo to cross compile Rust programs for Raspberry Pi? - DEV Community
August 28, 2025 - # 1) Install cargo install cross rustup target add aarch64-unknown-linux-gnu # 64-bit Pi OS rustup target add armv7-unknown-linux-gnueabihf # 32-bit Pi 2/3/4 OS rustup target add arm-unknown-linux-gnueabihf # ARMv6 (Pi Zero/1) # 2) Build cross build --target aarch64-unknown-linux-gnu --release # or: cross build --target armv7-unknown-linux-gnueabihf --release # or: cross build --target arm-unknown-linux-gnueabihf --release # 3) Copy & run on the Pi scp target/<target>/release/yourapp pi@raspberrypi.local:/home/pi/ ssh pi@raspberrypi.local ./yourapp
🌐
The Cargo Book
doc.rust-lang.org › cargo › commands › cargo.html
cargo - The Cargo Book
Run tests for a cross-compiled target: cargo test --target i686-unknown-linux-gnu · Create a new package that builds an executable: cargo new foobar · Create a package in the current directory: mkdir foo && cd foo cargo init . Learn about a command’s options and usage: cargo help clean · See https://github.com/rust-lang/cargo/issues for issues.
🌐
John Millikin
john-millikin.com › notes-on-cross-compiling-rust
Notes on cross-compiling Rust - John Millikin
Whereas Go will build its standard library from source when cross-compiling, Rust relies on precompiled libraries · [3]. We can use rustup to fetch a prebuilt std for Linux on ARMv7. rustup target add armv7-unknown-linux-gnueabihf # info: downloading component 'rust-std' for 'armv7-unknown-linux-gnueabihf' # info: installing component 'rust-std' for 'armv7-unknown-linux-gnueabihf' # info: using up to 500.0 MiB of RAM to unpack components # 18.2 MiB / 18.2 MiB (100 %) 11.5 MiB/s in 1s ETA: 0s · cargo build --target armv7-unknown-linux-gnueabihf # Compiling helloworld v0.0.1 (/Users/john/src/r