diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a9f4efb..d4a6a6f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -8,11 +8,22 @@ on:
push:
branches:
- main
- - dev
+ # - dev
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
+env:
+ CARGO_INCREMENTAL: 0
+ CARGO_NET_RETRY: 10
+ CARGO_TERM_COLOR: always
+ QEMU_STRACE: 1
+ RUST_BACKTRACE: full
+ RUST_TEST_THREADS: 1
+ RUSTDOCFLAGS: -D warnings
+ RUSTFLAGS: -D warnings
+ RUSTUP_MAX_RETRIES: 10
+
defaults:
run:
shell: bash
@@ -90,10 +101,11 @@ jobs:
working-directory: rust-cross-toolchain/docker/test/fixtures/rust
- run: cargo $BUILD_STD run --verbose --target ${{ matrix.target }}
working-directory: rust-cross-toolchain/docker/test/fixtures/rust
- if: matrix.target != 'x86_64-unknown-linux-gnux32'
- - run: cargo $BUILD_STD test --verbose --target ${{ matrix.target }}
+ - run: cargo $BUILD_STD test --verbose --target ${{ matrix.target }} $DOCTEST_XCOMPILE
working-directory: rust-cross-toolchain/docker/test/fixtures/rust
- if: matrix.target != 'x86_64-unknown-linux-gnux32'
+ - run: ./target/${{ matrix.target }}/debug/rust-test
+ working-directory: rust-cross-toolchain
+ if: matrix.target != 'mipsisa32r6el-unknown-linux-gnu'
tidy:
runs-on: ubuntu-latest
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5f449c1..b8df544 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,12 @@ Note: In this file, do not use the hard wrap in the middle of a sentence for com
## [Unreleased]
+- Support binfmt. This allows running the cross-compiled binaries directly. ([#3](https://github.com/taiki-e/setup-cross-toolchain/pull/3))
+
+- Set the `DOCTEST_XCOMPILE` environment variable to easily run cross-testing of doctest. ([#3](https://github.com/taiki-e/setup-cross-toolchain/pull/3))
+
+- Add `runner` input option. ([#3](https://github.com/taiki-e/setup-cross-toolchain/pull/3))
+
## [1.0.0] - 2022-02-20
Initial release
diff --git a/README.md b/README.md
index 7120fbe..09b13d4 100644
--- a/README.md
+++ b/README.md
@@ -18,9 +18,10 @@ GitHub Action for setup toolchains for cross compilation and cross testing for R
### Inputs
-| Name | Required | Description | Type | Default |
-|----------|:--------:|----------------------------------------------------------------------------------|--------|----------------|
-| target | **true** | Target triple | String | |
+| Name | Required | Description | Type | Default |
+|----------|:--------:|---------------|--------|----------------|
+| target | **true** | Target triple | String | |
+| runner | false | Test runner | String | |
### Example workflow: Basic usage
@@ -39,6 +40,10 @@ jobs:
# setup-cross-toolchain 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.
+ - run: ./target/aarch64-unknown-linux-gnu/debug/my-app
```
### Example workflow: Multiple targets
@@ -80,51 +85,86 @@ jobs:
- 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.
+
+```yaml
+jobs:
+ test:
+ strategy:
+ matrix:
+ rust:
+ - stable
+ - nightly
+ target:
+ - aarch64-unknown-linux-gnu
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install Rust
+ run: rustup update ${{ matrix.rust }} && rustup default ${{ matrix.rust }}
+ - name: Install cross-compilation tools
+ uses: taiki-e/setup-cross-toolchain@v1
+ with:
+ target: ${{ matrix.target }}
+ # On nightly and `-Z doctest-xcompile` is available,
+ # `$DOCTEST_XCOMPILE` is `-Z doctest-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
+```
+
## Platform Support
### Linux (GNU)
| C++ | test |
| --- | ---- |
-| ✓ (libstdc++) | ✓ (qemu) |
+| ✓ (libstdc++) | ✓ |
**Supported targets**:
-| target | host |
-| ------ | ----- |
-| `aarch64-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] |
-| `arm-unknown-linux-gnueabi` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] |
-| `armv5te-unknown-linux-gnueabi` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] |
-| `armv7-unknown-linux-gnueabi` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] |
-| `armv7-unknown-linux-gnueabihf` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] |
-| `i586-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] |
-| `i686-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] |
-| `mips-unknown-linux-gnu` | ubuntu-18.04 [2] |
-| `mips64-unknown-linux-gnuabi64` | ubuntu-18.04 [2] |
-| `mips64el-unknown-linux-gnuabi64` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] |
-| `mipsel-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] |
-| `mipsisa32r6el-unknown-linux-gnu` (tier3) | ubuntu-latest/ubuntu-20.04 [1] |
-| `mipsisa64r6el-unknown-linux-gnuabi64` (tier3) | ubuntu-latest/ubuntu-20.04 [1] |
-| `powerpc-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] |
-| `powerpc64-unknown-linux-gnu` | ubuntu-18.04 [2] |
-| `powerpc64le-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] |
-| `riscv64gc-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1] |
-| `s390x-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] |
-| `sparc64-unknown-linux-gnu` | ubuntu-18.04 [2] |
-| `thumbv7neon-unknown-linux-gnueabihf` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] |
-| `x86_64-unknown-linux-gnu` [3] | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] |
+| target | host | runner |
+| ------ | ----- | ------ |
+| `aarch64-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] | qemu-user (default) |
+| `arm-unknown-linux-gnueabi` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] | qemu-user (default) |
+| `armv5te-unknown-linux-gnueabi` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] | qemu-user (default) |
+| `armv7-unknown-linux-gnueabi` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] | qemu-user (default) |
+| `armv7-unknown-linux-gnueabihf` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] | qemu-user (default) |
+| `i586-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] | native (default), qemu-user |
+| `i686-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] | native (default), qemu-user |
+| `mips-unknown-linux-gnu` | ubuntu-18.04 [2] | qemu-user (default) |
+| `mips64-unknown-linux-gnuabi64` | ubuntu-18.04 [2] | qemu-user (default) |
+| `mips64el-unknown-linux-gnuabi64` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] | qemu-user (default) |
+| `mipsel-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] | qemu-user (default) |
+| `mipsisa32r6el-unknown-linux-gnu` (tier3) | ubuntu-latest/ubuntu-20.04 [1] | qemu-user (default) [3] |
+| `mipsisa64r6el-unknown-linux-gnuabi64` (tier3) | ubuntu-latest/ubuntu-20.04 [1] | qemu-user (default) |
+| `powerpc-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] | qemu-user (default) |
+| `powerpc64-unknown-linux-gnu` | ubuntu-18.04 [2] | qemu-user (default) |
+| `powerpc64le-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] | qemu-user (default) |
+| `riscv64gc-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1] | qemu-user (default) |
+| `s390x-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] | qemu-user (default) |
+| `sparc64-unknown-linux-gnu` | ubuntu-18.04 [2] | qemu-user (default) |
+| `thumbv7neon-unknown-linux-gnueabihf` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] | qemu-user (default) |
+| `x86_64-unknown-linux-gnu` | ubuntu-latest/ubuntu-20.04 [1], ubuntu-18.04 [2] | native (default), qemu-user |
[1] GCC 9, glibc 2.31
[2] GCC 7, glibc 2.27
-[3] no-op
+[3] binfmt doesn't work
## Related Projects
- [rust-cross-toolchain]: Toolchains for cross compilation and cross testing for Rust.
- [install-action]: GitHub Action for installing development tools.
+- [create-gh-release-action]: GitHub Action for creating GitHub Releases based on changelog.
+- [upload-rust-binary-action]: GitHub Action for building and uploading Rust binary to GitHub Releases.
+[create-gh-release-action]: https://github.com/taiki-e/create-gh-release-action
[install-action]: https://github.com/taiki-e/install-action
[rust-cross-toolchain]: https://github.com/taiki-e/rust-cross-toolchain
+[upload-rust-binary-action]: https://github.com/taiki-e/upload-rust-binary-action
## License
diff --git a/action.yml b/action.yml
index d25c587..6ced206 100644
--- a/action.yml
+++ b/action.yml
@@ -5,6 +5,9 @@ inputs:
target:
description: Target name
required: true
+ runner:
+ description: Test runner
+ required: false
runs:
using: node16
diff --git a/main.sh b/main.sh
index 7bbe9d2..af728c3 100755
--- a/main.sh
+++ b/main.sh
@@ -10,6 +10,16 @@ x() {
"${cmd}" "$@"
)
}
+retry() {
+ for i in {1..5}; do
+ if "$@"; then
+ return 0
+ else
+ sleep "${i}"
+ fi
+ done
+ "$@"
+}
bail() {
echo "::error::$*"
exit 1
@@ -18,28 +28,43 @@ warn() {
echo "::warning::$*"
}
+export DEBIAN_FRONTEND=noninteractive
+export RUSTUP_MAX_RETRIES="${RUSTUP_MAX_RETRIES:-10}"
+
if [[ $# -gt 0 ]]; then
bail "invalid argument '$1'"
fi
target="${INPUT_TARGET:?}"
+runner="${INPUT_RUNNER:-}"
+
target_lower="${target//-/_}"
target_lower="${target_lower//./_}"
target_upper="$(tr '[:lower:]' '[:upper:]' <<<"${target_lower}")"
host=$(rustc -Vv | grep host | sed 's/host: //')
+rustc_version=$(rustc -Vv | grep 'release: ' | sed 's/release: //')
+rustup_target_list=$(rustup target list)
-target_list=$(rustup target list)
-if grep <<<"${target_list}" -Eq "^${target}( |$)"; then
- rustup target add "${target}" &>/dev/null
-else
- # for -Z build-std
- rustup component add rust-src &>/dev/null
- echo "BUILD_STD=-Z build-std" >>"${GITHUB_ENV}"
-fi
-echo "CARGO_BUILD_TARGET=${target}" >>"${GITHUB_ENV}"
+# Refs: https://github.com/multiarch/qemu-user-static.
+register_binfmt() {
+ local url=https://raw.githubusercontent.com/qemu/qemu/44f28df24767cf9dca1ddc9b23157737c4cbb645/scripts/qemu-binfmt-conf.sh
+ retry curl --proto '=https' --tlsv1.2 -fsSL --retry 10 --retry-connrefused -o __qemu-binfmt-conf.sh "${url}"
+ # They confuse binfmt.
+ sed -i 's/ mipsn32 mipsn32el / /' ./__qemu-binfmt-conf.sh
+ chmod +x ./__qemu-binfmt-conf.sh
+ if [ ! -d /proc/sys/fs/binfmt_misc ]; then
+ bail "kernel does not support binfmt"
+ fi
+ if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
+ sudo mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
+ fi
+ sudo ./__qemu-binfmt-conf.sh --qemu-path /usr/bin --persistent yes
+ rm ./__qemu-binfmt-conf.sh
+}
case "${host}" in
x86_64-unknown-linux-gnu)
+ apt_packages=()
case "${target}" in
x86_64-unknown-linux-gnu) ;;
*-linux-gnu*)
@@ -81,10 +106,8 @@ case "${host}" in
*) cc_target="${target/-unknown/}" ;;
esac
apt_target="${apt_target:-"${cc_target/i586/i686}"}"
- sudo apt-get -o Acquire::Retries=10 -qq update
# TODO: can we reduce the setup time by providing an option to skip installing packages for C++?
- sudo apt-get -o Acquire::Retries=10 -qq -o Dpkg::Use-Pty=0 install -y \
- "g++-${multilib:+multilib-}${apt_target/_/-}"
+ apt_packages+=("g++-${multilib:+multilib-}${apt_target/_/-}")
# https://github.com/taiki-e/rust-cross-toolchain/blob/main/docker/test/entrypoint.sh
echo "CARGO_TARGET_${target_upper}_LINKER=${apt_target}-gcc" >>"${GITHUB_ENV}"
@@ -97,102 +120,137 @@ case "${host}" in
*) bail "unsupported target '${target}'" ;;
esac
+ use_qemu=''
case "${target}" in
- x86_64-unknown-linux-gnu) ;;
*-unknown-linux-*)
- # https://github.com/taiki-e/rust-cross-toolchain/blob/590d6cb4d3a72c26c5096f2ad3033980298cd4aa/docker/test/entrypoint.sh#L251
- # We basically set the newer and more powerful CPU as the
- # default QEMU_CPU so that we can test more CPU features.
- # In some contexts, we want to test for a specific CPU,
- # so respect user-set QEMU_CPU.
- case "${target}" in
- aarch64-* | aarch64_be-*)
- qemu_arch="${target%%-*}"
- qemu_cpu=a64fx
- ;;
- arm* | thumbv7neon-*)
- qemu_arch=arm
+ case "${runner}" in
+ '')
case "${target}" in
- # ARMv6: https://en.wikipedia.org/wiki/ARM11
- arm-* | armv6-*) qemu_cpu=arm11mpcore ;;
- # ARMv4: https://en.wikipedia.org/wiki/StrongARM
- armv4t-*) qemu_cpu=sa1110 ;;
- # ARMv5TE
- armv5te-*) qemu_cpu=arm1026 ;;
- # ARMv7-A+NEONv2
- armv7-* | thumbv7neon-*) qemu_cpu=cortex-a15 ;;
- *) bail "unrecognized target '${target}'" ;;
+ # On x86, qemu-user is not used by default.
+ x86_64-* | i*86-*) ;;
+ *) use_qemu='1' ;;
esac
;;
- i*86-*) qemu_arch=i386 ;;
- hexagon-*) qemu_arch=hexagon ;;
- m68k-*) qemu_arch=m68k ;;
- mips-* | mipsel-*) qemu_arch="${target%%-*}" ;;
- mips64-* | mips64el-*)
- qemu_arch="${target%%-*}"
- # As of qemu 6.1, only Loongson-3A4000 supports MSA instructions with mips64r5.
- qemu_cpu=Loongson-3A4000
- ;;
- mipsisa32r6-* | mipsisa32r6el-*)
- qemu_arch="${target%%-*}"
- qemu_arch="${qemu_arch/isa32r6/}"
- qemu_cpu=mips32r6-generic
- ;;
- mipsisa64r6-* | mipsisa64r6el-*)
- qemu_arch="${target%%-*}"
- qemu_arch="${qemu_arch/isa64r6/64}"
- qemu_cpu=I6400
- ;;
- powerpc-*spe)
- qemu_arch=ppc
- qemu_cpu=e500v2
- ;;
- powerpc-*)
- qemu_arch=ppc
- qemu_cpu=Vger
- ;;
- powerpc64-*)
- qemu_arch=ppc64
- qemu_cpu=power10
- ;;
- powerpc64le-*)
- qemu_arch=ppc64le
- qemu_cpu=power10
- ;;
- riscv32gc-* | riscv64gc-*) qemu_arch="${target%%gc-*}" ;;
- s390x-*) qemu_arch=s390x ;;
- sparc-*) qemu_arch=sparc32plus ;;
- sparc64-*) qemu_arch=sparc64 ;;
- x86_64-*)
- qemu_arch=x86_64
- # qemu does not seem to support emulating x86_64 CPU features on x86_64 hosts.
- # > qemu-x86_64: warning: TCG doesn't support requested feature
- #
- # A way that works well for emulating x86_64 CPU features on x86_64 hosts is to use Intel SDE.
- # https://www.intel.com/content/www/us/en/developer/articles/tool/software-development-emulator.html
- # It is not OSS, but it is licensed under Intel Simplified Software License and redistribution is allowed.
- # https://www.intel.com/content/www/us/en/developer/articles/license/pre-release-license-agreement-for-software-development-emulator.html
- # https://www.intel.com/content/www/us/en/developer/articles/license/onemkl-license-faq.html
- ;;
- *) bail "unrecognized target '${target}'" ;;
- esac
- if [[ -n "${qemu_cpu:-}" ]] && [[ -z "${QEMU_CPU:-}" ]]; then
- echo "QEMU_CPU=${qemu_cpu}" >>"${GITHUB_ENV}"
- fi
- case "${target}" in
- *-linux-gnu*) qemu_ld_prefix="/usr/${apt_target}" ;;
+ qemu-user) use_qemu='1' ;;
+ *) bail "unrecognized runner '${runner}'" ;;
esac
- if [[ -n "${qemu_ld_prefix:-}" ]] && [[ -z "${QEMU_LD_PREFIX:-}" ]]; then
- echo "QEMU_LD_PREFIX=${qemu_ld_prefix}" >>"${GITHUB_ENV}"
- fi
- echo "CARGO_TARGET_${target_upper}_RUNNER=qemu-${qemu_arch}" >>"${GITHUB_ENV}"
- # https://github.com/taiki-e/dockerfiles/pkgs/container/qemu-user
- docker create --name qemu-user ghcr.io/taiki-e/qemu-user
- sudo docker cp qemu-user:/usr/bin/qemu-${qemu_arch} /usr/bin/qemu-${qemu_arch}
- docker rm -f qemu-user >/dev/null
- x qemu-${qemu_arch} --version
;;
esac
+ if [[ -n "${use_qemu}" ]]; then
+ # https://github.com/taiki-e/rust-cross-toolchain/blob/590d6cb4d3a72c26c5096f2ad3033980298cd4aa/docker/test/entrypoint.sh#L251
+ # We basically set the newer and more powerful CPU as the
+ # default QEMU_CPU so that we can test more CPU features.
+ # In some contexts, we want to test for a specific CPU,
+ # so respect user-set QEMU_CPU.
+ case "${target}" in
+ aarch64-* | aarch64_be-*)
+ qemu_arch="${target%%-*}"
+ qemu_cpu=a64fx
+ ;;
+ arm* | thumbv7neon-*)
+ qemu_arch=arm
+ case "${target}" in
+ # ARMv6: https://en.wikipedia.org/wiki/ARM11
+ arm-* | armv6-*) qemu_cpu=arm11mpcore ;;
+ # ARMv4: https://en.wikipedia.org/wiki/StrongARM
+ armv4t-*) qemu_cpu=sa1110 ;;
+ # ARMv5TE
+ armv5te-*) qemu_cpu=arm1026 ;;
+ # ARMv7-A+NEONv2
+ armv7-* | thumbv7neon-*) qemu_cpu=cortex-a15 ;;
+ *) bail "unrecognized target '${target}'" ;;
+ esac
+ ;;
+ i*86-*) qemu_arch=i386 ;;
+ hexagon-*) qemu_arch=hexagon ;;
+ m68k-*) qemu_arch=m68k ;;
+ mips-* | mipsel-*) qemu_arch="${target%%-*}" ;;
+ mips64-* | mips64el-*)
+ qemu_arch="${target%%-*}"
+ # As of qemu 6.1, only Loongson-3A4000 supports MSA instructions with mips64r5.
+ qemu_cpu=Loongson-3A4000
+ ;;
+ mipsisa32r6-* | mipsisa32r6el-*)
+ qemu_arch="${target%%-*}"
+ qemu_arch="${qemu_arch/isa32r6/}"
+ qemu_cpu=mips32r6-generic
+ ;;
+ mipsisa64r6-* | mipsisa64r6el-*)
+ qemu_arch="${target%%-*}"
+ qemu_arch="${qemu_arch/isa64r6/64}"
+ qemu_cpu=I6400
+ ;;
+ powerpc-*spe)
+ qemu_arch=ppc
+ qemu_cpu=e500v2
+ ;;
+ powerpc-*)
+ qemu_arch=ppc
+ qemu_cpu=Vger
+ ;;
+ powerpc64-*)
+ qemu_arch=ppc64
+ qemu_cpu=power10
+ ;;
+ powerpc64le-*)
+ qemu_arch=ppc64le
+ qemu_cpu=power10
+ ;;
+ riscv32gc-* | riscv64gc-*) qemu_arch="${target%%gc-*}" ;;
+ s390x-*) qemu_arch=s390x ;;
+ sparc-*) qemu_arch=sparc32plus ;;
+ sparc64-*) qemu_arch=sparc64 ;;
+ x86_64-*)
+ qemu_arch=x86_64
+ # qemu does not seem to support emulating x86_64 CPU features on x86_64 hosts.
+ # > qemu-x86_64: warning: TCG doesn't support requested feature
+ #
+ # A way that works well for emulating x86_64 CPU features on x86_64 hosts is to use Intel SDE.
+ # https://www.intel.com/content/www/us/en/developer/articles/tool/software-development-emulator.html
+ # It is not OSS, but it is licensed under Intel Simplified Software License and redistribution is allowed.
+ # https://www.intel.com/content/www/us/en/developer/articles/license/pre-release-license-agreement-for-software-development-emulator.html
+ # https://www.intel.com/content/www/us/en/developer/articles/license/onemkl-license-faq.html
+ ;;
+ *) bail "unrecognized target '${target}'" ;;
+ esac
+ echo "CARGO_TARGET_${target_upper}_RUNNER=qemu-${qemu_arch}" >>"${GITHUB_ENV}"
+ if [[ -n "${qemu_cpu:-}" ]] && [[ -z "${QEMU_CPU:-}" ]]; then
+ echo "QEMU_CPU=${qemu_cpu}" >>"${GITHUB_ENV}"
+ fi
+ case "${target}" in
+ *-linux-gnu*) qemu_ld_prefix="/usr/${apt_target}" ;;
+ esac
+ if [[ -n "${qemu_ld_prefix:-}" ]] && [[ -z "${QEMU_LD_PREFIX:-}" ]]; then
+ echo "QEMU_LD_PREFIX=${qemu_ld_prefix}" >>"${GITHUB_ENV}"
+ fi
+ # https://github.com/taiki-e/dockerfiles/pkgs/container/qemu-user
+ docker create --name qemu-user ghcr.io/taiki-e/qemu-user
+ mkdir -p .setup-cross-toolchain
+ docker cp qemu-user:/usr/bin .setup-cross-toolchain/qemu
+ docker rm -f qemu-user >/dev/null
+ sudo mv .setup-cross-toolchain/qemu/qemu-* /usr/bin/
+ rm -rf ./.setup-cross-toolchain
+ x qemu-${qemu_arch} --version
+ register_binfmt
+ fi
+
+ retry sudo apt-get -o Acquire::Retries=10 -qq update
+ retry sudo apt-get -o Acquire::Retries=10 -qq -o Dpkg::Use-Pty=0 install -y --no-install-recommends \
+ "${apt_packages[@]}"
;;
*) bail "unsupported host '${host}'" ;;
esac
+
+if grep <<<"${rustup_target_list}" -Eq "^${target}( |$)"; then
+ retry rustup target add "${target}" &>/dev/null
+else
+ # for -Z build-std
+ retry rustup component add rust-src &>/dev/null
+ echo "BUILD_STD=-Z build-std" >>"${GITHUB_ENV}"
+fi
+echo "CARGO_BUILD_TARGET=${target}" >>"${GITHUB_ENV}"
+if [[ "${rustc_version}" == *"nightly"* ]] || [[ "${rustc_version}" == *"dev"* ]]; then
+ if cargo -Z help | grep -Eq '-Z doctest-xcompile\b'; then
+ echo "DOCTEST_XCOMPILE=-Z doctest-xcompile" >>"${GITHUB_ENV}"
+ fi
+fi