Sworld

Sworld

The only way to do great work is to love what you do.

Compile Rust programs to MacOS and Linux on Win

I previously wrote an article introducing how to compile Rust programs for Linux on Windows, but the native configuration method for Rust is not very straightforward. Today, I want to introduce a simpler method to compile Rust programs for MacOS and Linux. Similarly, you can also compile for Windows on these platforms.

Cross-rs#

Cross-rs is a Rust cross-compilation tool that can compile Rust programs for other platforms with almost a single command when dependencies are not complex. Its principle is to use Docker to run the cross-compilation toolchain, so Docker or Podman needs to be installed on the machine. This library also supports testing, which is not the focus of this article, so I will just mention it here.

Installation#

It is worth noting that since this project depends on Docker, you need to ensure a stable internet connection during compilation. The download speed of Docker Hub images may be slow, so it is recommended to use an image source that you can access quickly.

With the Rust toolchain, Docker, or Podman installed, use the following command to install cross:

cargo install cross --git https://github.com/cross-rs/cross

Basic Usage#

For simple projects, after installation, you can directly use cross to compile:

# Compile for the target architecture x86_64 Linux
cross build --target x86_64-unknown-linux-gnu --release
# Compile for the target architecture aarch64 Linux
cross build --target aarch64-unknown-linux-gnu --release

Here, I will take a Socks5 proxy software that I previously practiced writing as an example, and the compilation result is as follows:

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

# info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
# info: latest update on 2025-03-18, rust version 1.85.1 (4eb161250 2025-03-15)
# info: downloading component 'cargo'
# ......
# info: checking for self-update
# info: downloading component 'rust-src'
# info: installing component 'rust-src'

# Unable to find image 'ghcr.io/cross-rs/x86_64-unknown-linux-gnu:main' locally
# main: Pulling from cross-rs/x86_64-unknown-linux-gnu
# d9802f032d67: Pull complete
# ......
# b4f2b8f6bece: Pull complete
# Digest: sha256:e01aa4c146da3834f49ead052f7f9b9cff95e3dd576f909c87cea473bba84e1b
# Status: Downloaded newer image for ghcr.io/cross-rs/x86_64-unknown-linux-gnu:main

#    Compiling libc v0.2.159
# ......
#    Compiling tokio-byteorder v0.3.0
#    Compiling socks5_tcp v0.1.0 (/mnt/d/socks5_tcp)
#     Finished `release` profile [optimized] target(s) in 58.03s

As can be seen, it is basically divided into the following stages:

  1. Installing the toolchain for the target platform
  2. Downloading the Docker image for compilation
  3. Compiling the program

Then we get an executable file that runs on Linux, located at target/x86_64-unknown-linux-gnu/release/socks5_tcp. However, when dealing with complex projects, you may need to handle external dependencies; and when compiling for MacOS or MSVC targets, some additional configurations may be required, as described in the following sections.

Handling External Dependencies#

To customize the compilation process, we need to create a Cross.toml file in the project root directory with the following content:

# The format here is `target.<target-triple>`, and multiple configurations for different targets can exist
[target.aarch64-unknown-linux-gnu]
# pre-build can execute some commands before compilation, commonly used to install dependencies
pre-build = [
    "apt-get update",
    "apt-get install -y libssl-dev",
]
# You can also specify a Docker image with image
image = "test-image"
# Specify some environment variables
env.aaa = "bbb"

The configuration method is basically as above. For further customization, please refer to the official documentation.

Compiling for MacOS#

Due to licensing reasons, the cross-rs team cannot provide us with pre-compiled images and is not allowed to distribute Apple's SDK, so we need to obtain the SDK legally ourselves to compile an image. Below, I will take aarch64-apple-darwin as an example, and other platforms are similar.

Building the Image#

We need to clone the cross-rs code, update the submodules, and build the image after configuration:

# Setup cross toolchains
git clone https://github.com/cross-rs/cross
cd cross
git submodule update --init --remote
cargo xtask configure-crosstool

# Build docker images
cargo build-docker-image aarch64-apple-darwin-cross --build-arg 'MACOS_SDK_URL=https://github.com/joseluisq/macosx-sdks/releases/download/12.3/MacOSX12.3.sdk.tar.xz' --tag local

# Compile our application
cross build --target aarch64-apple-darwin --release

The SDK version requirements for building are as follows:

  • i686-apple-darwin: SDK <= 10.13
  • x86_64-apple-darwin: SDK <= 13.0 or SDK <= 12.4
  • aarch64-apple-darwin: SDK >= 10.16 and (SDK <= 13.0 or SDK <= 12.4)

Configuring Cross.toml#

After the build is complete, it becomes very simple. We just need to create a Cross.toml file in the project root directory, specifying that the corresponding target uses our local image, with the following content:

# Reference: https://github.com/cross-rs/cross-toolchains
[target.aarch64-apple-darwin]
image = "ghcr.io/cross-rs/aarch64-apple-darwin-cross:local"

Subsequent compilations will be the same as for Linux, and I will not elaborate further.

Compiling for Windows#

MSVC may be the optimal target for Windows, but for convenience, I still chose the GNU toolchain. We can use x86_64-pc-windows-gnu or i686-pc-windows-gnu as targets, and the compilation method is similar to Linux:

cross build --target x86_64-pc-windows-gnu --release

This way, we can compile executable files for Windows on Linux or MacOS without needing to configure MSVC. If you really want the MSVC compilation results, please read the README and Issues of the official repository.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.