Home

Awesome

setup-cross-toolchain-action

release github actions

GitHub Action for setup toolchains for cross compilation and cross testing for Rust.

Usage

Inputs

NameRequiredDescriptionTypeDefault
targettrueTarget tripleString
runnerfalseTest runnerString

Example workflow: Basic usage

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Rust
        run: rustup update stable
      - name: Install cross-compilation tools
        uses: taiki-e/setup-cross-toolchain-action@v1
        with:
          target: aarch64-unknown-linux-gnu
      # setup-cross-toolchain-action sets the `CARGO_BUILD_TARGET` environment variable,
      # so there is no need for an explicit `--target` flag.
      - run: cargo test --verbose
      # `cargo run` also works.
      - run: cargo run --verbose
      # You can also run the cross-compiled binaries directly (via binfmt).
      - run: ./target/aarch64-unknown-linux-gnu/debug/my-app

Example workflow: Multiple targets

jobs:
  test:
    strategy:
      matrix:
        target:
          - aarch64-unknown-linux-gnu
          - riscv64gc-unknown-linux-gnu
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Rust
        run: rustup update stable
      - name: Install cross-compilation tools
        uses: taiki-e/setup-cross-toolchain-action@v1
        with:
          target: ${{ matrix.target }}
      - run: cargo test --verbose

Example workflow: Doctest

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Rust
        run: rustup update nightly && rustup default nightly
      - name: Install cross-compilation tools
        uses: taiki-e/setup-cross-toolchain-action@v1
        with:
          target: aarch64-unknown-linux-gnu
      - run: cargo test --verbose -Z doctest-xcompile

Cross-testing of doctest is currently available only on nightly. If you want to use stable and nightly in the same matrix, you can use the DOCTEST_XCOMPILE environment variable set by this action to enable doctest only in nightly.

jobs:
  test:
    strategy:
      matrix:
        rust:
          - stable
          - nightly
        target:
          - aarch64-unknown-linux-gnu
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Rust
        run: rustup update ${{ matrix.rust }} && rustup default ${{ matrix.rust }}
      - name: Install cross-compilation tools
        uses: taiki-e/setup-cross-toolchain-action@v1
        with:
          target: ${{ matrix.target }}
      # On nightly and `-Z doctest-xcompile` is available,
      # `$DOCTEST_XCOMPILE` is `-Zdoctest-xcompile`.
      #
      # On stable, `$DOCTEST_XCOMPILE` is not set.
      # Once `-Z doctest-xcompile` is stabilized, the corresponding flag
      # will be set to `$DOCTEST_XCOMPILE` (if it is available).
      - run: cargo test --verbose $DOCTEST_XCOMPILE

Example workflow: Tier 3 targets

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Rust
        run: rustup update nightly && rustup default nightly
      - name: Install cross-compilation tools
        uses: taiki-e/setup-cross-toolchain-action@v1
        with:
          target: aarch64_be-unknown-linux-gnu
      - run: cargo test --verbose -Z build-std

Cross-compilation of tier 3 targets currently requires nightly to build std. If you want to use tier 1/2 and tier 3 in the same matrix, you can use the BUILD_STD environment variable set by this action to use -Z build-std only for tier 3 targets.

jobs:
  test:
    strategy:
      matrix:
        target:
          - aarch64-unknown-linux-gnu
          - aarch64_be-unknown-linux-gnu
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Rust
        run: rustup update nightly && rustup default nightly
      - name: Install cross-compilation tools
        uses: taiki-e/setup-cross-toolchain-action@v1
        with:
          target: ${{ matrix.target }}
      # If target is tier 3, `$BUILD_STD` is `-Zbuild-std`.
      # Otherwise, `$BUILD_STD` is not set.
      #
      # Once `Z build-std` is stabilized, the corresponding flag
      # will be set to `$BUILD_STD` (if it is available).
      - run: cargo test --verbose $BUILD_STD

Platform Support

Linux (GNU)

C++test
✓ (libstdc++) [1]

[1] Except for loongarch64-unknown-linux-gnu

Supported targets:

targethostrunnernote
aarch64-unknown-linux-gnuUbuntu (18.04, 20.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-user
aarch64_be-unknown-linux-gnuUbuntu (18.04, 22.04), Debian (10, 11, 12) [2]qemu-usertier3
arm-unknown-linux-gnueabiUbuntu (18.04, 20.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-user
armeb-unknown-linux-gnueabiUbuntu (18.04, 22.04), Debian (10, 11, 12) [3]qemu-usertier3
armv5te-unknown-linux-gnueabiUbuntu (18.04, 20.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-user
armv7-unknown-linux-gnueabiUbuntu (18.04, 20.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-user
armv7-unknown-linux-gnueabihfUbuntu (18.04, 20.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-user
i586-unknown-linux-gnuUbuntu (18.04, 20.04, 22.04, 24.04) [1]qemu-user (default), native[7]
i686-unknown-linux-gnuUbuntu (18.04, 20.04, 22.04, 24.04) [1]native (default), qemu-user[7]
loongarch64-unknown-linux-gnuUbuntu (18.04, 20.04, 22.04, 24.04), Debian (10, 11, 12) [4]qemu-userexperimental
mips-unknown-linux-gnuUbuntu (18.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-usertier3 [6]
mips64-unknown-linux-gnuabi64Ubuntu (18.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-usertier3
mips64el-unknown-linux-gnuabi64Ubuntu (18.04, 20.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-usertier3
mipsel-unknown-linux-gnuUbuntu (18.04, 20.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-usertier3 [6]
mipsisa32r6-unknown-linux-gnuUbuntu (22.04, 24.04), Debian (10, 11, 12) [1]qemu-usertier3
mipsisa32r6el-unknown-linux-gnuUbuntu (20.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-usertier3
mipsisa64r6-unknown-linux-gnuabi64Ubuntu (22.04, 24.04), Debian (10, 11, 12) [1]qemu-usertier3
mipsisa64r6el-unknown-linux-gnuabi64Ubuntu (20.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-usertier3
powerpc-unknown-linux-gnuUbuntu (18.04, 20.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-user
powerpc64-unknown-linux-gnuUbuntu (18.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-user
powerpc64le-unknown-linux-gnuUbuntu (18.04, 20.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-user
riscv32gc-unknown-linux-gnuUbuntu (18.04, 20.04, 22.04, 24.04), Debian (10, 11, 12) [5]qemu-user
riscv64gc-unknown-linux-gnuubuntu (18.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-user
s390x-unknown-linux-gnuUbuntu (18.04, 20.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-user
sparc-unknown-linux-gnuUbuntu (18.04, 22.04, 24.04), Debian (10, 12) [1]qemu-usertier3, experimental
sparc64-unknown-linux-gnuUbuntu (18.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-user
thumbv7neon-unknown-linux-gnueabihfUbuntu (18.04, 20.04, 22.04, 24.04), Debian (10, 11, 12) [1]qemu-user
x86_64-unknown-linux-gnuUbuntu (18.04, 20.04, 22.04, 24.04), Debian (10, 11, 12) [1]native (default), qemu-user

[1] GCC 7, glibc 2.27 for Ubuntu 18.04. GCC 9, glibc 2.31 for Ubuntu 20.04. GCC 11, glibc 2.35 for Ubuntu 22.04, glibc 2.39 for Ubuntu 24.04. GCC 8, glibc 2.28 for Debian 10. GCC 10, glibc 2.31 for Debian 11. GCC 12, glibc 2.36 for Debian 12.<br> [2] GCC 10, glibc 2.31<br> [3] GCC 7, glibc 2.25<br> [4] GCC 13, glibc 2.36<br> [5] GCC 11, glibc 2.33<br> [6] Since nightly-2023-07-05, mips{,el}-unknown-linux-gnu requires release mode for building std<br> [7] Not fully supported with containers<br>

<!-- omit in toc -->

<a name="qemu-user-runner"></a>qemu-user runner

The current default QEMU version is 9.1.

You can select/pin the version by using qemu input option, or @ syntax in runner input option (if both are set, the latter is preferred). For example:

- uses: taiki-e/setup-cross-toolchain-action@v1
  with:
    target: aarch64-unknown-linux-gnu
    qemu: '7.2'
- uses: taiki-e/setup-cross-toolchain-action@v1
  with:
    target: aarch64-unknown-linux-gnu
    runner: qemu@8.1

Linux (musl)

libcGCCC++test
musl 1.2.3 / 1.1.24 [1]9? (libstdc++)

[1]: 1.2 on Rust 1.71+, otherwise 1.1. 1.1 toolchain is with a patch that fixes CVE-2020-28928.

Supported targets:

targethostrunnernote
aarch64-unknown-linux-muslx86_64 Linuxqemu-user
arm-unknown-linux-musleabix86_64 Linuxqemu-user
arm-unknown-linux-musleabihfx86_64 Linuxqemu-user
armv5te-unknown-linux-musleabix86_64 Linuxqemu-user
armv7-unknown-linux-musleabix86_64 Linuxqemu-user
armv7-unknown-linux-musleabihfx86_64 Linuxqemu-user
i586-unknown-linux-muslx86_64 Linuxqemu-user (default), native
i686-unknown-linux-muslx86_64 Linuxnative (default), qemu-user
x86_64-unknown-linux-muslx86_64 Linuxnative (default), qemu-user

(Other linux-musl targets supported by rust-cross-toolchain may also work, although this action's CI has not tested them.)

For the qemu-user runner, see "qemu-user runner" section for linux-gnu targets.

Linux (uClibc)

libcGCCC++test
uClibc-ng 1.0.3410.2.0✓ (libstdc++)

Supported targets:

targethostrunnernote
armv5te-unknown-linux-uclibceabix86_64 Linuxqemu-usertier3
armv7-unknown-linux-uclibceabix86_64 Linuxqemu-usertier3
armv7-unknown-linux-uclibceabihfx86_64 Linuxqemu-usertier3
mips-unknown-linux-uclibcx86_64 Linuxqemu-usertier3 [1]
mipsel-unknown-linux-uclibcx86_64 Linuxqemu-usertier3 [1]

[1] mips{,el}-unknown-linux-uclibc requires release mode for building std<br>

For the qemu-user runner, see "qemu-user runner" section for linux-gnu targets.

Android

clangC++test
14✓ (libc++)

Note: By making use of these targets you accept the Android SDK License

Supported targets:

targetapi levelhostrunnernote
aarch64-linux-android21 (default), 22-24, 26-33 [1]x86_64 Linuxqemu-user
arm-linux-androideabi21 / 19 [2] (default), 21-24, 26-33 [1]x86_64 Linuxqemu-user
armv7-linux-androideabi21 / 19 [2] (default), 21-24, 26-33 [1]x86_64 Linuxqemu-user
i686-linux-android21 / 19 [2] (default), 21-24, 26-33 [1]x86_64 Linuxnative (default), qemu-user
thumbv7neon-linux-androideabi21 / 19 [2] (default), 21-24, 26-33 [1]x86_64 Linuxqemu-user
x86_64-linux-android21 (default), 22-24, 26-33 [1]x86_64 Linuxnative (default), qemu-user

[1] This action currently uses the API level 24 system image, so cargo test and cargo run may not work on API level 26+. [2]: 21 on Rust 1.82+, otherwise 19.

You can select/pin the API level version by using @ syntax in target option. For example:

- uses: taiki-e/setup-cross-toolchain-action@v1
  with:
    target: arm-linux-androideabi@21

For the qemu-user runner, see "qemu-user runner" section for linux-gnu targets.

FreeBSD

C++test
✓ (libc++)

Supported targets:

targetversionhostnote
aarch64-unknown-freebsd12.4 (default), 13.3, 14.0Ubuntu, Debian [1]tier3
i686-unknown-freebsd12.4 (default), 13.3, 14.0Ubuntu, Debian [1]
x86_64-unknown-freebsd12.4 (default), 13.3, 14.0Ubuntu, Debian [1]

[1] Clang 13 for Ubuntu 18.04, otherwise Clang 15<br>

(Other FreeBSD targets supported by rust-cross-toolchain may also work, although this action's CI has not tested them.)

You can select/pin the OS version by using @ syntax in target option. For example:

- uses: taiki-e/setup-cross-toolchain-action@v1
  with:
    target: x86_64-unknown-freebsd@13

Only specifying a major version is supported.

NetBSD

GCCC++test
7.5.0✓ (libstdc++)

Supported targets:

targetversionhostnote
aarch64-unknown-netbsd9.4 (default), 10.0x86_64 Linuxtier3
x86_64-unknown-netbsd8.2 (default), 9.4, 10.0x86_64 Linux

(Other NetBSD targets supported by rust-cross-toolchain may also work, although this action's CI has not tested them.)

You can select/pin the OS version by using @ syntax in target option. For example:

- uses: taiki-e/setup-cross-toolchain-action@v1
  with:
    target: x86_64-unknown-netbsd@9

Only specifying a major version is supported.

illumos

libcGCCC++test
solaris 2.108.5.0✓ (libstdc++)

Supported targets:

targethostnote
x86_64-unknown-illumosx86_64 Linux (any libc)

WASI

libcClangC++test
wasi-sdk 23 (wasi-libc 3f43ea9)18? (libc++)

Supported targets:

targethostrunnernote
wasm32-wasix86_64 LinuxwasmtimeRemoved in Rust 1.84
wasm32-wasip1x86_64 Linuxwasmtime

(Other WASI targets supported by rust-cross-toolchain may also work, although this action's CI has not tested them.)

Windows (MinGW)

C++test
✓ (libstdc++)

Supported targets:

targethostrunnernote
x86_64-pc-windows-gnuWindows, Ubuntu (22.04), Debian (11, 12) [1]native (Windows host) / wine (Linux host)

[1] GCC 10, MinGW-w64 8 for Ubuntu 22.04. GCC 10, MinGW-w64 8 for Debian 11. GCC 12, MinGW-w64 10 for Debian 12.<br>

On Windows host, GitHub-provided Windows runners support cross-compile for other architectures or environments, so this action just runs rustup target add and/or sets some environment variables.

(Other Windows targets may also work, although this action's CI has not tested them.)

On Linux host, this action installs MinGW toolchain and Wine.

<!-- omit in toc -->

<a name="wine-runner"></a>wine runner

The current default Wine version is 9.0.

You can select/pin the version by using wine input option, or @ syntax in runner input option (if both are set, the latter is preferred). For example:

- uses: taiki-e/setup-cross-toolchain-action@v1
  with:
    target: x86_64-pc-windows-gnu
    wine: '9.3'
- uses: taiki-e/setup-cross-toolchain-action@v1
  with:
    target: x86_64-pc-windows-gnu
    runner: wine@9.3

Windows (LLVM MinGW)

libcClangC++test
Mingw-w64 7c9cfe618✓ (libc++)

Supported targets:

targethostrunnernote
aarch64-pc-windows-gnullvmUbuntu (22.04)wine
i686-pc-windows-gnullvmUbuntu (22.04)wine
x86_64-pc-windows-gnullvmUbuntu (22.04)wine

For the wine runner for {i686,x86_64}-pc-windows-gnullvm, see "wine runner" section for windows-gnu targets.

The wine runner for aarch64-pc-windows-gnullvm is AArch64 Wine running on qemu-user; specifying the Wine version is not yet supported, but the QEMU version can be specified by using qemu input option like Linux targets.

Windows (MSVC)

C++test
✓ [1]

[1] Only x86/x86_64 targets

Supported targets:

targethostrunnernote
aarch64-pc-windows-msvcWindows
i586-pc-windows-msvcWindowsnative
i686-pc-windows-msvcWindowsnative
x86_64-pc-windows-msvcWindowsnative

GitHub-provided Windows runners support cross-compile for other architectures or environments, so this action just runs rustup target add and/or sets some environment variables.

(Other Windows targets may also work, although this action's CI has not tested them.)

macOS

C++test
✓ [1]

[1] For x86_64-apple-darwin all runners and for aarch64-apple-darwin only arm64 runners. (x86_64h-apple-darwin is also x86_64 but build-only because the CPU of GitHub-provided macOS runners is older than Haswell. If you use a large runner or self-hosted runner, you may be able to run the test.)

Supported targets:

targethostrunnernote
aarch64-apple-darwinmacOSnative
x86_64-apple-darwinmacOSnative
x86_64h-apple-darwinmacOSnativetier3

GitHub-provided macOS runners support cross-compile for other architectures or environments, so this action just runs rustup target add and/or sets some environment variables.

(Other macOS targets may also work, although this action's CI has not tested them.)

Mac Catalyst

C++test
✓ [1]

[1] For x86_64-apple-ios-macabi only x86_64 runners and for aarch64-apple-ios-macabi only arm64 runners.

Supported targets:

targethostrunnernote
aarch64-apple-ios-macabimacOSnative
x86_64-apple-ios-macabimacOSnative

GitHub-provided macOS runners support cross-compile for other targets, so this action just runs rustup target add and/or sets some environment variables.

Compatibility

This action has been tested for GitHub-hosted runners (Ubuntu, macOS, Windows) and containers (Ubuntu, Debian). To use this action in self-hosted runners or in containers, at least the following tools are required:

--privileged option is currently required when using with containers (due to binfmt).

container:
  image: '...'
  options: --privileged

Related Projects

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.