CI #4513
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| permissions: | |
| contents: read | |
| on: | |
| pull_request: | |
| push: | |
| branches: | |
| - main | |
| - dev | |
| schedule: | |
| - cron: '0 2 * * *' | |
| workflow_dispatch: | |
| env: | |
| CARGO_INCREMENTAL: 0 | |
| CARGO_NET_GIT_FETCH_WITH_CLI: true | |
| CARGO_NET_RETRY: 10 | |
| CARGO_TERM_COLOR: always | |
| RUST_BACKTRACE: 1 | |
| RUST_TEST_THREADS: 1 | |
| RUSTDOCFLAGS: -D warnings | |
| RUSTFLAGS: -D warnings | |
| RUSTUP_MAX_RETRIES: 10 | |
| PORTABLE_ATOMIC_DENY_WARNINGS: 1 | |
| # NB: sync with: | |
| # - docs.rs metadata in Cargo.toml | |
| # - test_features list in tools/build.sh and tools/test.sh. | |
| TEST_FEATURES: float,std,serde,critical-section | |
| defaults: | |
| run: | |
| shell: bash --noprofile --norc -CeEuxo pipefail {0} | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} | |
| cancel-in-progress: true | |
| jobs: | |
| msrv: | |
| needs: tidy | |
| uses: taiki-e/github-actions/.github/workflows/msrv.yml@main | |
| with: | |
| # NB: sync with env.TEST_FEATURES | |
| # Exclude serde and critical-section features because the MSRV when it is enabled depends on the MSRV of them | |
| args: --features float,std --ignore-unknown-features | |
| tidy: | |
| uses: taiki-e/github-actions/.github/workflows/tidy.yml@main | |
| permissions: | |
| contents: read | |
| pull-requests: write # for gh pr edit --add-assignee | |
| repository-projects: read # for gh pr edit --add-assignee | |
| secrets: inherit | |
| with: | |
| clippy: false # covered by TESTS=1 ./tools/build.sh | |
| docs-target: x86_64-unknown-linux-gnu,aarch64-unknown-linux-gnu,powerpc64le-unknown-linux-gnu,s390x-unknown-linux-gnu,armv5te-unknown-linux-gnueabi | |
| prepare: | |
| runs-on: ubuntu-slim | |
| timeout-minutes: 15 # Max execution time of ubuntu-slim runner. | |
| steps: | |
| - uses: taiki-e/checkout-action@v1 | |
| - name: Prepare | |
| id: prepare | |
| run: printf 'test-matrix=%s\n' "$(jq -c . .github/workflows/test-matrix.json)" >>"${GITHUB_OUTPUT}" | |
| outputs: | |
| test-matrix: ${{ steps.prepare.outputs.test-matrix }} | |
| test: | |
| needs: [prepare, tidy] | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJSON(needs.prepare.outputs.test-matrix) }} | |
| runs-on: ${{ matrix.os || 'ubuntu-latest' }} | |
| timeout-minutes: 120 # TODO: reduce | |
| steps: | |
| - uses: taiki-e/checkout-action@v1 | |
| # - run: sudo apt-get -o Acquire::Retries=10 -qq update && sudo apt-get -o Acquire::Retries=10 -o Dpkg::Use-Pty=0 install -y --no-install-recommends moreutils | |
| # if: startsWith(matrix.os, 'ubuntu') || matrix.os == '' | |
| # - run: brew install moreutils | |
| # if: startsWith(matrix.os, 'macos') | |
| # - run: C:/msys64/usr/bin/pacman -S --noconfirm moreutils | |
| # if: startsWith(matrix.os, 'windows') | |
| - uses: taiki-e/install-action@cargo-hack | |
| - uses: taiki-e/install-action@cargo-minimal-versions | |
| - uses: taiki-e/install-action@cargo-careful | |
| # 0.4.8 fails with at least nightly-2023-05-09 to nightly-2024-01-05 | |
| if: startsWith(matrix.rust, 'nightly') && !(startsWith(matrix.rust, 'nightly-2023') || startsWith(matrix.rust, 'nightly-2024')) | |
| - uses: taiki-e/install-action@v2 | |
| with: | |
| tool: cargo-careful@0.4.7 | |
| if: startsWith(matrix.rust, 'nightly-2023') || startsWith(matrix.rust, 'nightly-2024') | |
| - uses: taiki-e/github-actions/install-rust@main | |
| with: | |
| toolchain: ${{ matrix.rust }} | |
| - id: prepare | |
| run: | | |
| if [[ "${TARGET}" == '' ]]; then | |
| printf 'matrix.target must be set\n' | |
| exit 1 | |
| fi | |
| host="$(rustc -vV | grep -E '^host:' | cut -d' ' -f2)" | |
| if [[ "${host}" != "${TARGET}" ]]; then | |
| printf '%s\n' "TARGET=--target=${TARGET}" >>"${GITHUB_ENV}" | |
| printf '%s\n' "target-not-host=true" >>"${GITHUB_OUTPUT}" | |
| fi | |
| cfgs=",$(RUSTC_BOOTSTRAP=1 rustc --print cfg --target "${TARGET}" | tr '\n' ',')" | |
| printf 'cfgs=%s\n' "${cfgs}" >>"${GITHUB_OUTPUT}" | |
| env: | |
| TARGET: ${{ matrix.target }} | |
| - uses: taiki-e/setup-cross-toolchain-action@v1 | |
| with: | |
| target: ${{ matrix.target }} | |
| if: steps.prepare.outputs.target-not-host == 'true' | |
| - run: | | |
| target_lower="${TARGET//-/_}" | |
| target_lower="${target_lower//./_}" | |
| target_upper=$(tr '[:lower:]' '[:upper:]' <<<"${target_lower}") | |
| flags='' | |
| if [[ "$(eval "printf '%s\n' \${CARGO_TARGET_${target_upper}_RUNNER:-}")" == *"qemu"* ]]; then | |
| flags+=" --cfg qemu" | |
| fi | |
| if [[ -n "${FLAGS}" ]]; then | |
| flags+=" ${FLAGS}" | |
| fi | |
| if [[ "${RUST}" == "nightly" ]]; then | |
| case "${TARGET}" in | |
| # TODO(windows): error: linker stdout: C:\a\portable-atomic\portable-atomic\target\debug\deps\portable_atomic-6f0d7f05900c9263.exe : warning LNK4072: section count 101 exceeds max (96); image may not run | |
| *-darwin* | aarch64*-windows-* | csky*) ;; | |
| *) flags+=" -D linker_messages" ;; | |
| esac | |
| fi | |
| if [[ -n "${flags}" ]]; then | |
| printf '%s\n' "RUSTFLAGS=${RUSTFLAGS} ${flags}" >>"${GITHUB_ENV}" | |
| printf '%s\n' "RUSTDOCFLAGS=${RUSTDOCFLAGS} ${flags}" >>"${GITHUB_ENV}" | |
| fi | |
| env: | |
| TARGET: ${{ matrix.target }} | |
| FLAGS: ${{ matrix.flags }} | |
| RUST: ${{ matrix.rust }} | |
| # for f16 and f128 | |
| # https://github.com/rust-lang/rust/blob/ffb9d94dcf4ade0d534842be3672d5e9f47e1333/compiler/rustc_codegen_llvm/src/llvm_util.rs#L373 | |
| # https://github.com/rust-lang/rust/blob/ffb9d94dcf4ade0d534842be3672d5e9f47e1333/compiler/rustc_codegen_cranelift/src/lib.rs#L203 | |
| # https://github.com/rust-lang/rust/blob/ffb9d94dcf4ade0d534842be3672d5e9f47e1333/compiler/rustc_codegen_gcc/src/builder.rs#L1916 | |
| - run: | | |
| rustflags="${RUSTFLAGS:-}" | |
| if rustc --print cfg ${TARGET:-} | grep -Fq has_reliable_f16; then | |
| rustflags+=' --cfg portable_atomic_unstable_f16 --cfg quickcheck_unstable_f16 --cfg rand_unstable_f16' | |
| fi | |
| if rustc --print cfg ${TARGET:-} | grep -Fq has_reliable_f128; then | |
| rustflags+=' --cfg portable_atomic_unstable_f128 --cfg quickcheck_unstable_f128 --cfg rand_unstable_f128' | |
| fi | |
| if [[ "${rustflags}" != "${RUSTFLAGS:-}" ]]; then | |
| printf '%s\n' "RUSTFLAGS=${rustflags}" >>"${GITHUB_ENV}" | |
| fi | |
| if: matrix.rust == 'nightly' && !contains(matrix.flags, 'codegen-backend=cranelift') && !contains(matrix.flags, 'codegen-backend=gcc') | |
| # TODO(gcc): for disabling some failing tests | |
| - run: printf '%s\n' "RUSTC_CODEGEN_GCC=1" >>"${GITHUB_ENV}" | |
| if: contains(matrix.flags, 'codegen-backend=gcc') | |
| # for serde on old nightly | |
| - run: printf '%s\n' "RUSTFLAGS=${RUSTFLAGS} --cfg no_diagnostic_namespace" >>"${GITHUB_ENV}" | |
| if: matrix.rust == 'nightly-2024-02-13' | |
| - run: tools/test.sh -vv ${TARGET:-} ${DOCTEST_XCOMPILE:-} ${BUILD_STD:-} ${RELEASE:-} | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} --cfg portable_atomic_unstable_coerce_unsized | |
| if: startsWith(matrix.rust, 'nightly') | |
| # We test doctest only once with the default build conditions because doctest is slow. Both api-test | |
| # and src/tests have extended copies of doctest, so this will not reduce test coverage. | |
| # {,no-}outline-atomics | |
| # portable_atomic_no_outline_atomics only affects x86_64, AArch64, Arm, powerpc64, and RISC-V Linux. | |
| # outline-atomics is disabled by default on AArch64/powerpc64 musl with static linking, AArch64 illumos, and AIX. | |
| # powerpc64le- (little-endian) is skipped because it is pwr8 by default | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg portable_atomic_no_outline_atomics | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} --cfg portable_atomic_no_outline_atomics | |
| if: startsWith(matrix.target, 'x86_64') || ((startsWith(matrix.target, 'aarch64') || startsWith(matrix.target, 'arm64')) || startsWith(matrix.target, 'powerpc64-')) && !(contains(matrix.target, '-musl') && matrix.flags == '') || startsWith(matrix.target, 'armv5te') || matrix.target == 'arm-linux-androideabi' || startsWith(matrix.target, 'riscv') | |
| # powerpc64 and RISC-V are skipped because tested below. | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| # Note: detect_false cfg is intended to make it easy for developers to test | |
| # cases where features usually available is not available, and is not a public API. | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg portable_atomic_test_detect_false | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} --cfg portable_atomic_test_detect_false | |
| # TODO(arm-linux-androideabi): hang | |
| if: startsWith(matrix.target, 'x86_64') || (startsWith(matrix.target, 'aarch64') || startsWith(matrix.target, 'arm64')) && !(contains(matrix.target, '-musl') && matrix.flags == '') || startsWith(matrix.target, 'armv5te') | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| QEMU_CPU: power7 # no quadword-atomics | |
| if: startsWith(matrix.target, 'powerpc64-') | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} | |
| QEMU_CPU: sifive-u34 # no zacas | |
| if: startsWith(matrix.target, 'riscv32') | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} | |
| QEMU_CPU: sifive-u54 # no zacas | |
| if: startsWith(matrix.target, 'riscv64') | |
| # portable_atomic_outline_atomics only affects AArch64 non-glibc-Linux/illumos, powerpc64, and RISC-V Linux. | |
| # powerpc64le- (little-endian) is skipped because it is pwr8 by default | |
| # RISC-V Linux is skipped because outline-atomics is enabled by default. | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg portable_atomic_outline_atomics | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} --cfg portable_atomic_outline_atomics | |
| if: (startsWith(matrix.target, 'aarch64') || startsWith(matrix.target, 'arm64')) && contains(matrix.target, '-musl') && matrix.flags == '' || startsWith(matrix.target, 'powerpc64-') | |
| # powerpc64 is skipped because tested below. | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| # Note: detect_false cfg is intended to make it easy for developers to test | |
| # cases where features usually available is not available, and is not a public API. | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg portable_atomic_outline_atomics --cfg portable_atomic_test_detect_false | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} --cfg portable_atomic_outline_atomics --cfg portable_atomic_test_detect_false | |
| if: (startsWith(matrix.target, 'aarch64') || startsWith(matrix.target, 'arm64')) && contains(matrix.target, '-musl') && matrix.flags == '' | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg portable_atomic_outline_atomics | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} --cfg portable_atomic_outline_atomics | |
| QEMU_CPU: power7 # no quadword-atomics | |
| if: startsWith(matrix.target, 'powerpc64-') | |
| # x86_64 +cmpxchg16b | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| # cmpxchg16b + outline-atomics (vmovdqa load/store) path is tested in first 2 runs on macOS. | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b --cfg portable_atomic_no_outline_atomics | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b --cfg portable_atomic_no_outline_atomics | |
| if: startsWith(matrix.target, 'x86_64') && !contains(steps.prepare.outputs.cfgs, ',target_feature="cmpxchg16b",') | |
| # x86_64 +cmpxchg16b,+avx | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b,+avx | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b,+avx | |
| if: startsWith(matrix.target, 'x86_64') | |
| # x86_64 +avx | |
| # macOS is skipped because it is +cmpxchg16b by default (+cmpxchg16b,+avx is tested above) | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+avx | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+avx | |
| if: startsWith(matrix.target, 'x86_64') && !contains(matrix.target, '-darwin') | |
| # aarch64 +lse | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+lse | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+lse | |
| if: (startsWith(matrix.target, 'aarch64') || startsWith(matrix.target, 'arm64')) && !contains(steps.prepare.outputs.cfgs, ',target_feature="lse",') | |
| # aarch64 +lse,+lse2 | |
| # macOS is skipped because it is +lse,+lse2 by default | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+lse,+lse2 | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+lse,+lse2 | |
| if: (startsWith(matrix.target, 'aarch64') || startsWith(matrix.target, 'arm64')) && !contains(matrix.target, '-darwin') | |
| # aarch64 +lse2,+lse128 | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+lse2,+lse128 | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+lse2,+lse128 | |
| # Only QEMU supports this, so skip other runners. | |
| if: (startsWith(matrix.target, 'aarch64') || startsWith(matrix.target, 'arm64')) && !(startsWith(matrix.os, 'macos') || contains(matrix.os, '-arm')) | |
| # powerpc64 pwr7 | |
| # powerpc64- (big-endian) is skipped because it is pre-pwr8 by default | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-cpu=pwr7 | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-cpu=pwr7 | |
| if: startsWith(matrix.target, 'powerpc64le-') | |
| # powerpc64 pwr8 | |
| # powerpc64le- (little-endian) is skipped because it is pwr8 by default | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-cpu=pwr8 | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-cpu=pwr8 | |
| if: startsWith(matrix.target, 'powerpc64-') | |
| # riscv +zabha | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+zabha | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+zabha | |
| if: startsWith(matrix.target, 'riscv') | |
| # riscv +zacas | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+zacas | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+zacas | |
| if: startsWith(matrix.target, 'riscv') | |
| # s390x z196 (arch9) | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-cpu=z196 | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-cpu=z196 | |
| if: startsWith(matrix.target, 's390x') | |
| # s390x z15 (arch13) | |
| - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-cpu=z15 | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-cpu=z15 | |
| if: startsWith(matrix.target, 's390x') | |
| # Skip targets that also checked by "build" job. | |
| - run: tools/build.sh "${TARGET}" | |
| env: | |
| SKIP_DEFAULT_TARGET: 1 | |
| TARGET: ${{ matrix.target }} | |
| - run: TESTS=1 tools/build.sh "${TARGET}" | |
| env: | |
| SKIP_DEFAULT_TARGET: 1 | |
| TARGET: ${{ matrix.target }} | |
| - run: cargo minimal-versions build --workspace --no-private --detach-path-deps=skip-exact --features "${TEST_FEATURES}" --ignore-unknown-features ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} | |
| if: matrix.rust != 'nightly-2021-08-21' | |
| - run: cargo minimal-versions build --workspace --no-private --detach-path-deps=skip-exact --features "${TEST_FEATURES}" --ignore-unknown-features ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} --direct | |
| # -Z direct-minimal-versions requires Cargo 1.70. | |
| if: (!(startsWith(matrix.rust, '1.5') || startsWith(matrix.rust, '1.6') || startsWith(matrix.rust, 'nightly-2021') || startsWith(matrix.rust, 'nightly-2022') || startsWith(matrix.rust, 'nightly-2023'))) | |
| test-bsd: | |
| needs: tidy | |
| name: test (${{ matrix.target }}${{ matrix.version }}) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # TODO: pkg: sqlite error while executing grmbl in file update.c:154: NOT NULL constraint failed: packages.path | |
| # - target: aarch64-unknown-freebsd | |
| # os: freebsd | |
| # version: '13.5' | |
| - target: aarch64-unknown-freebsd | |
| os: freebsd | |
| version: '14.3' | |
| - target: aarch64-unknown-freebsd | |
| os: freebsd | |
| version: '15.0' | |
| - target: aarch64-unknown-netbsd | |
| os: netbsd | |
| version: '10.1' | |
| - target: aarch64-unknown-openbsd | |
| os: openbsd | |
| version: '7.6' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 120 # TODO: build on OpenBSD is too slow | |
| steps: | |
| - uses: taiki-e/checkout-action@v1 | |
| - uses: taiki-e/cross-platform-actions-action@neoverse-v1 | |
| with: | |
| environment_variables: CARGO_INCREMENTAL CARGO_NET_RETRY CARGO_TERM_COLOR RUST_BACKTRACE RUST_TEST_THREADS RUSTDOCFLAGS RUSTFLAGS RUSTUP_MAX_RETRIES PORTABLE_ATOMIC_DENY_WARNINGS TEST_FEATURES | |
| operating_system: ${{ matrix.os }} | |
| # We don't test x86_64 here because there is no OS-specific code on x86_64. | |
| architecture: aarch64 | |
| version: ${{ matrix.version }} | |
| shell: bash | |
| sync_files: runner-to-vm | |
| run: | | |
| set -CeEuxo pipefail | |
| retry() { | |
| for i in {1..10}; do | |
| if "$@"; then | |
| return 0 | |
| else | |
| sleep "${i}" | |
| fi | |
| done | |
| "$@" | |
| } | |
| export CI=true | |
| export RUSTFLAGS="${RUSTFLAGS} --cfg qemu" | |
| # AArch64 FreeBSD/NetBSD/OpenBSD are tier 3 targets, so install Rust from package manager instead of rustup. | |
| case "$(uname -s)" in | |
| FreeBSD) retry sudo pkg install -y rust ;; | |
| NetBSD) retry sudo pkgin -y install rust ;; | |
| OpenBSD) retry sudo pkg_add rust ;; | |
| esac | |
| rustc -vV | |
| # VM is very slow, so only test OS-specific code and code using them. | |
| cargo test --features std --tests -- aarch64 | |
| case "$(uname -s)" in | |
| FreeBSD) | |
| RUSTFLAGS="${RUSTFLAGS} -C target-feature=+crt-static" \ | |
| cargo test --features std --tests --target aarch64-unknown-freebsd -- aarch64 | |
| ;; | |
| esac | |
| build: | |
| needs: tidy | |
| name: build (${{ matrix.name || matrix.rust }}) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - rust: '1.34' | |
| - rust: '1.36' | |
| - rust: '1.59' | |
| - rust: stable | |
| - rust: beta | |
| - rust: nightly | |
| # The oldest nightly that can compile this crate is nightly-2019-01-27 | |
| # which Atomic{I,U}{8,16,32,64} stabilized. | |
| # https://github.com/rust-lang/rust/pull/57425 | |
| # Note: Old nightly compilers are essentially fragile, so support for | |
| # them is on a best-effort basis. | |
| - rust: nightly-2019-01-27 | |
| # https://github.com/taiki-e/portable-atomic/pull/52 | |
| - rust: nightly-2020-06-21 | |
| # for AVR: https://github.com/rust-lang/compiler-builtins/issues/400 | |
| - rust: nightly-2020-12-26 | |
| # Check that test suite can be built | |
| - name: nightly, --tests | |
| rust: nightly | |
| tests: 1 | |
| # Check that this crate can be built for all builtin targets | |
| - name: stable, all tier1/tier2 | |
| rust: stable | |
| target-group: tier1/tier2 | |
| # Skip targets that also checked by other matrix. | |
| skip-default-target: 1 | |
| - name: nightly, all tier1/tier2 | |
| rust: nightly | |
| target-group: tier1/tier2 | |
| skip-default-target: 1 | |
| - name: nightly, all tier3 | |
| rust: nightly | |
| target-group: tier3 | |
| skip-default-target: 1 | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 120 # TODO: nightly builds take a long time because there are too many targets | |
| steps: | |
| - uses: taiki-e/checkout-action@v1 | |
| - uses: taiki-e/github-actions/free-device-space@main | |
| - uses: taiki-e/github-actions/install-rust@main | |
| with: | |
| toolchain: ${{ matrix.rust }} | |
| - uses: taiki-e/install-action@cargo-hack | |
| - run: tools/build.sh | |
| env: | |
| TESTS: ${{ matrix.tests }} | |
| TARGET_GROUP: ${{ matrix.target-group }} | |
| SKIP_DEFAULT_TARGET: ${{ matrix.skip-default-target }} | |
| ALL_TARGETS_MUST_BE_AVAILABLE: ${{ matrix.rust == 'nightly' || '' }} | |
| no-std: | |
| needs: tidy | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| rust: | |
| - '1.64' # LLVM 14 | |
| # - '1.69' # LLVM 15 | |
| - '1.72' # LLVM 16 | |
| # - '1.77' # LLVM 17 | |
| # - '1.81' # LLVM 18 | |
| # - '1.86' # LLVM 19 | |
| # - '1.90' # LLVM 20 | |
| - stable | |
| # - nightly-2022-08-12 # Rust 1.65, LLVM 14 | |
| # - nightly-2023-03-25 # Rust 1.70, LLVM 15 | |
| # - nightly-2023-08-08 # Rust 1.73, LLVM 16 | |
| # - nightly-2024-02-13 # Rust 1.78, LLVM 17 | |
| # - nightly-2024-07-31 # Rust 1.82, LLVM 18 | |
| # - nightly-2025-02-17 # Rust 1.87, LLVM 19 | |
| # - nightly-2025-08-06 # Rust 1.91, LLVM 20 | |
| - nightly | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: taiki-e/checkout-action@v1 | |
| - uses: taiki-e/github-actions/free-device-space@main | |
| - uses: taiki-e/github-actions/install-rust@main | |
| with: | |
| toolchain: ${{ matrix.rust }} | |
| - uses: taiki-e/install-action@cargo-hack | |
| if: matrix.rust == 'stable' | |
| - uses: taiki-e/install-action@espup | |
| if: matrix.rust == 'stable' | |
| - run: | | |
| retry() { | |
| for i in {1..10}; do | |
| if "$@"; then | |
| return 0 | |
| else | |
| sleep "${i}" | |
| fi | |
| done | |
| "$@" | |
| } | |
| if [[ "${{ matrix.rust }}" == "nightly"* ]]; then | |
| apt_packages=( | |
| avr-libc | |
| gcc-avr | |
| libelf-dev | |
| mspdebug | |
| simavr | |
| ) | |
| retry sudo apt-get -o Acquire::Retries=10 -qq update | |
| retry sudo apt-get -o Acquire::Retries=10 -o Dpkg::Use-Pty=0 install -y --no-install-recommends "${apt_packages[@]}" | |
| fi | |
| if [[ "${{ matrix.rust }}" == "nightly"* ]]; then | |
| mkdir -p -- "${HOME}"/msp430-gcc "${HOME}"/aarch64-l4re-gcc | |
| # https://www.ti.com/tool/MSP430-GCC-OPENSOURCE | |
| retry curl --proto '=https' --tlsv1.2 -fsSL --retry 10 --retry-connrefused https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-LlCjWuAbzH/9.3.1.2/msp430-gcc-9.3.1.11_linux64.tar.bz2 \ | |
| | tar xjf - --strip-components 1 -C "${HOME}"/msp430-gcc | |
| printf '%s\n' "${HOME}"/msp430-gcc/bin >>"${GITHUB_PATH}" | |
| # https://l4re.org/download/snapshots | |
| retry curl --proto '=https' --tlsv1.2 -fsSL --retry 10 --retry-connrefused https://l4re.org/download/snapshots/toolchain/toolchain-l4re-arm64-gcc-15.tar.xz \ | |
| | tar xJf - -C "${HOME}"/aarch64-l4re-gcc | |
| retry curl --proto '=https' --tlsv1.2 -fsSL --retry 10 --retry-connrefused -o "${HOME}"/aarch64-l4re-gcc/bin/l4image https://l4re.org/download/snapshots/pre-built-images/l4image | |
| chmod +x "${HOME}"/aarch64-l4re-gcc/bin/l4image | |
| printf '%s\n' "${HOME}"/aarch64-l4re-gcc/bin >>"${GITHUB_PATH}" | |
| elif [[ "${{ matrix.rust }}" == "stable" ]]; then | |
| # Use the latest toolchain once upstream bug fixed. | |
| retry espup install --targets esp32s2 --toolchain-version 1.90.0 | |
| fi | |
| # https://github.com/taiki-e/dockerfiles/pkgs/container/qemu-system | |
| retry docker create --name qemu-system ghcr.io/taiki-e/qemu-system | |
| mkdir -p -- qemu-system | |
| docker cp -- qemu-system:/qemu qemu-system/qemu | |
| docker rm -f -- qemu-system >/dev/null | |
| sudo cp -r -- qemu-system/qemu/. /usr/local/ | |
| rm -rf -- ./qemu-system | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: taiki-e/cache-cargo-install-action@v3 | |
| with: | |
| # https://github.com/agbrs/agb/tree/5fb928a/mgba-test-runner | |
| # To install locally: | |
| # apt install libelf-dev | |
| # cargo install mgba-test-runner --git https://github.com/agbrs/agb.git --rev 5fb928a | |
| tool: mgba-test-runner | |
| git: https://github.com/agbrs/agb.git | |
| rev: 5fb928a | |
| env: | |
| RUSTFLAGS: -W warnings | |
| if: startsWith(matrix.rust, 'nightly') | |
| - run: rm -- tests/avr/rust-toolchain.toml | |
| if: startsWith(matrix.rust, 'nightly-') | |
| # syn 2.0.107 & quote 1.0.42 & proc-macro2 1.0.104 requires Rust 1.68. | |
| - run: | | |
| cargo generate-lockfile | |
| cargo update -p proc-macro2 --precise 1.0.103 | |
| cargo update -p quote --precise 1.0.41 | |
| cargo update -p syn --precise 2.0.106 | |
| working-directory: tests/no-std-qemu | |
| if: matrix.rust == '1.64' | |
| - run: tools/no-std.sh | |
| env: | |
| ALL_TARGETS_MUST_BE_AVAILABLE: ${{ matrix.rust == 'nightly' || '' }} | |
| # TODO: xtensa-esp32-none-elf with assume-privileged | |
| - run: tools/build.sh +esp xtensa-esp32s2-none-elf | |
| if: matrix.rust == 'stable' | |
| # TODO: exit with 1 without message | |
| # - run: tools/build.sh +esp xtensa-esp32s2-none-elf | |
| # env: | |
| # TESTS: 1 | |
| # if: matrix.rust == 'stable' | |
| - run: tools/no-std.sh +esp xtensa-esp32s2-none-elf | |
| if: matrix.rust == 'stable' | |
| miri: | |
| needs: tidy | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: x86_64-unknown-linux-gnu | |
| - target: x86_64-unknown-linux-gnu | |
| flags: -C target-feature=+cmpxchg16b | |
| - target: x86_64-pc-windows-msvc | |
| - target: aarch64-unknown-linux-gnu | |
| - target: aarch64-apple-darwin | |
| - target: i686-unknown-linux-gnu | |
| - target: powerpc64le-unknown-linux-gnu | |
| - target: riscv64gc-unknown-linux-gnu | |
| - target: s390x-unknown-linux-gnu | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 180 | |
| steps: | |
| - uses: taiki-e/checkout-action@v1 | |
| - uses: taiki-e/github-actions/install-rust@nightly | |
| with: | |
| component: miri | |
| - uses: taiki-e/install-action@cargo-hack | |
| # - run: sudo apt-get -o Acquire::Retries=10 -qq update && sudo apt-get -o Acquire::Retries=10 -o Dpkg::Use-Pty=0 install -y --no-install-recommends moreutils | |
| - run: printf '%s\n' "TARGET=--target=${{ matrix.target }}" >>"${GITHUB_ENV}" | |
| if: matrix.target != 'x86_64-unknown-linux-gnu' | |
| - run: printf '%s\n' "MIRIFLAGS=-Zmiri-many-seeds=0..16" >>"${GITHUB_ENV}" | |
| if: github.event_name == 'schedule' && matrix.target == 'x86_64-unknown-linux-gnu' | |
| - run: tools/test.sh miri ${TARGET:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} ${{ matrix.flags }} | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} ${{ matrix.flags }} | |
| san: | |
| needs: tidy | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| sanitizer: | |
| - address | |
| - memory | |
| - thread | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: taiki-e/checkout-action@v1 | |
| - uses: taiki-e/github-actions/install-rust@nightly | |
| - uses: taiki-e/install-action@cargo-hack | |
| # - run: sudo apt-get -o Acquire::Retries=10 -qq update && sudo apt-get -o Acquire::Retries=10 -o Dpkg::Use-Pty=0 install -y --no-install-recommends moreutils | |
| - run: | | |
| printf 'ASAN_OPTIONS=detect_stack_use_after_return=1\n' >>"${GITHUB_ENV}" | |
| printf '%s\n' "RUSTFLAGS=${RUSTFLAGS} -Z sanitizer=address" >>"${GITHUB_ENV}" | |
| printf '%s\n' "RUSTDOCFLAGS=${RUSTDOCFLAGS} -Z sanitizer=address" >>"${GITHUB_ENV}" | |
| if: matrix.sanitizer == 'address' | |
| - run: | | |
| printf 'MSAN_OPTIONS=verbosity=2\n' >>"${GITHUB_ENV}" | |
| printf '%s\n' "RUSTFLAGS=${RUSTFLAGS} -Z sanitizer=memory -Z sanitizer-memory-track-origins" >>"${GITHUB_ENV}" | |
| printf '%s\n' "RUSTDOCFLAGS=${RUSTDOCFLAGS} -Z sanitizer=memory -Z sanitizer-memory-track-origins" >>"${GITHUB_ENV}" | |
| if: matrix.sanitizer == 'memory' | |
| - run: | | |
| printf '%s\n' "RUSTFLAGS=${RUSTFLAGS} -Z sanitizer=thread" >>"${GITHUB_ENV}" | |
| printf '%s\n' "RUSTDOCFLAGS=${RUSTDOCFLAGS} -Z sanitizer=thread" >>"${GITHUB_ENV}" | |
| if: matrix.sanitizer == 'thread' | |
| - run: tools/test.sh -Z build-std -vv | |
| # We test doctest only once with the default build conditions because doctest is slow. Both api-test | |
| # and src/tests have extended copies of doctest, so this will not reduce test coverage. | |
| # +cmpxchg16b | |
| - run: tools/test.sh -Z build-std -vv --tests | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b --cfg portable_atomic_no_outline_atomics | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b --cfg portable_atomic_no_outline_atomics | |
| valgrind: | |
| needs: tidy | |
| name: valgrind (${{ matrix.target }}) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: x86_64-unknown-linux-gnu | |
| - target: i686-unknown-linux-gnu | |
| - target: aarch64-unknown-linux-gnu | |
| os: ubuntu-24.04-arm | |
| - target: armv7-unknown-linux-gnueabihf | |
| os: ubuntu-24.04-arm | |
| # TODO: "unhandled instruction: 0x4508 0xD103" in atomic_sub in Arc::drop (as of Valgrind 3.26) | |
| # - target: thumbv7neon-unknown-linux-gnueabihf | |
| # os: ubuntu-24.04-arm | |
| runs-on: ${{ matrix.os || 'ubuntu-latest' }} | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: taiki-e/checkout-action@v1 | |
| - uses: taiki-e/github-actions/install-rust@nightly | |
| - uses: taiki-e/install-action@cargo-hack | |
| - id: prepare | |
| run: | | |
| if [[ "${TARGET}" == '' ]]; then | |
| printf 'matrix.target must be set\n' | |
| exit 1 | |
| fi | |
| host="$(rustc -vV | grep -E '^host:' | cut -d' ' -f2)" | |
| if [[ "${host}" != "${TARGET}" ]]; then | |
| printf '%s\n' "TARGET=--target=${TARGET}" >>"${GITHUB_ENV}" | |
| fi | |
| env: | |
| TARGET: ${{ matrix.target }} | |
| # - run: apt-get -o Acquire::Retries=10 -qq update && apt-get -o Acquire::Retries=10 -o Dpkg::Use-Pty=0 install -y --no-install-recommends moreutils | |
| - uses: taiki-e/setup-cross-toolchain-action@v1 | |
| with: | |
| target: ${{ matrix.target }} | |
| runner: valgrind | |
| - run: tools/test.sh valgrind -vv ${TARGET:-} | |
| # x86_64 +cmpxchg16b | |
| - run: tools/test.sh valgrind -vv ${TARGET:-} | |
| env: | |
| # outline-atomics (vmovdqa load/store) path has been tested above, disable outline-atomics and test cmpxchg16b load/store path. | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b --cfg portable_atomic_no_outline_atomics | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b --cfg portable_atomic_no_outline_atomics | |
| if: startsWith(matrix.target, 'x86_64') | |
| # x86_64 +cmpxchg16b,+avx | |
| - run: tools/test.sh valgrind -vv ${TARGET:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b,+avx | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b,+avx | |
| if: startsWith(matrix.target, 'x86_64') | |
| # On AArch64 linux-gnu, outline-atomics is enabled by default. | |
| - run: tools/test.sh valgrind -vv ${TARGET:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg portable_atomic_no_outline_atomics | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} --cfg portable_atomic_no_outline_atomics | |
| if: (startsWith(matrix.target, 'aarch64') || startsWith(matrix.target, 'arm64')) | |
| # aarch64 +lse | |
| # As of Valgrind 3.26, Valgrind supports atomic instructions of Armv8.0, Armv8.1 (FEAT_LSE), and Armv8.3 (FEAT_LRCPC). | |
| - run: tools/test.sh valgrind -vv ${TARGET:-} | |
| env: | |
| RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+lse | |
| RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+lse | |
| if: (startsWith(matrix.target, 'aarch64') || startsWith(matrix.target, 'arm64')) | |
| valgrind-cross: | |
| needs: tidy | |
| name: valgrind (${{ matrix.target }}) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: powerpc64le-unknown-linux-gnu | |
| arch: ppc64le | |
| - target: riscv64gc-unknown-linux-gnu | |
| arch: riscv64 | |
| - target: s390x-unknown-linux-gnu | |
| arch: s390x | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: taiki-e/checkout-action@v1 | |
| - uses: taiki-e/github-actions/install-rust@nightly | |
| # - run: sudo apt-get -o Acquire::Retries=10 -qq update && apt-get -o Acquire::Retries=10 -o Dpkg::Use-Pty=0 install -y --no-install-recommends moreutils | |
| - uses: taiki-e/setup-cross-toolchain-action@v1 | |
| with: | |
| target: ${{ matrix.target }} | |
| runner: valgrind | |
| - run: | | |
| export CARGO_PROFILE_RELEASE_DEBUG_ASSERTIONS=true | |
| # Skip debug mode because it's slow. | |
| binary_path=$( | |
| ./tools/test.sh build-valgrind --target "${TARGET}" --release | |
| ) | |
| mv -- "${binary_path}" ./release | |
| binary_path=$( | |
| CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1 \ | |
| CARGO_PROFILE_RELEASE_LTO=fat \ | |
| ./tools/test.sh build-valgrind --target "${TARGET}" --release | |
| ) | |
| mv -- "${binary_path}" ./release-fat-lto | |
| case "${TARGET}" in | |
| s390x*) | |
| # s390x z196 (arch9) | |
| binary_path=$( | |
| RUSTFLAGS="${RUSTFLAGS:-} -C target-cpu=z196" \ | |
| ./tools/test.sh build-valgrind --target "${TARGET}" --release | |
| ) | |
| mv -- "${binary_path}" ./release-z196 | |
| binary_path=$( | |
| RUSTFLAGS="${RUSTFLAGS:-} -C target-cpu=z196" \ | |
| CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1 \ | |
| CARGO_PROFILE_RELEASE_LTO=fat \ | |
| ./tools/test.sh build-valgrind --target "${TARGET}" --release | |
| ) | |
| mv -- "${binary_path}" ./release-z196-fat-lto | |
| # s390x z15 (arch13) | |
| binary_path=$( | |
| RUSTFLAGS="${RUSTFLAGS:-} -C target-cpu=z15" \ | |
| ./tools/test.sh build-valgrind --target "${TARGET}" --release | |
| ) | |
| mv -- "${binary_path}" ./release-z15 | |
| binary_path=$( | |
| RUSTFLAGS="${RUSTFLAGS:-} -C target-cpu=z15" \ | |
| CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1 \ | |
| CARGO_PROFILE_RELEASE_LTO=fat \ | |
| ./tools/test.sh build-valgrind --target "${TARGET}" --release | |
| ) | |
| mv -- "${binary_path}" ./release-z15-fat-lto | |
| ;; | |
| esac | |
| env: | |
| TARGET: ${{ matrix.target }} | |
| - uses: uraimo/run-on-arch-action@v3 | |
| with: | |
| arch: none | |
| distro: none | |
| base_image: --platform=linux/${{ matrix.arch }} ghcr.io/taiki-e/valgrind:${{ matrix.arch }}-cross | |
| shell: /bin/bash | |
| run: | | |
| set -CeEuxo pipefail | |
| export RUST_BACKTRACE=1 | |
| export RUST_TEST_THREADS=1 | |
| export PORTABLE_ATOMIC_DENY_WARNINGS=1 | |
| # NB: Sync with arguments in tools/test.sh. | |
| args=(-v --error-exitcode=1 --error-limit=no --leak-check=full --track-origins=yes --fair-sched=yes --gen-suppressions=all) | |
| target="${{ matrix.target }}" | |
| supp="$(pwd)/tools/valgrind/${target%%-*}.supp" | |
| if [[ -f "${supp}" ]]; then | |
| args+=(--suppressions="${supp}") | |
| fi | |
| for bin in ./release*; do | |
| valgrind "${args[@]}" "${bin}" | |
| done | |
| asm-test: | |
| needs: tidy | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: taiki-e/checkout-action@v1 | |
| - uses: taiki-e/github-actions/install-rust@nightly | |
| with: | |
| component: rust-src | |
| - uses: taiki-e/install-action@espup | |
| - run: | | |
| retry() { | |
| for i in {1..10}; do | |
| if "$@"; then | |
| return 0 | |
| else | |
| sleep "${i}" | |
| fi | |
| done | |
| "$@" | |
| } | |
| # Use the latest toolchain once upstream bug fixed. | |
| retry espup install --targets esp32s2 --toolchain-version 1.90.0 | |
| - run: cargo test --manifest-path tests/asm-test/Cargo.toml | |
| - run: cargo +esp test --manifest-path tests/asm-test/Cargo.toml |