1name: CI2permissions: {}3on:4 push: { branches: [main] }5 pull_request:67concurrency:8 # Make sure that new pushes cancel running jobs9 group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}10 cancel-in-progress: true1112env:13 CARGO_TERM_COLOR: always14 LIBM_BUILD_VERBOSE: true15 RUSTDOCFLAGS: -Dwarnings16 RUSTFLAGS: -Dwarnings17 RUST_BACKTRACE: full18 BENCHMARK_RUSTC: nightly-2026-02-10 # Pin the toolchain for reproducable results1920jobs:21 # Determine which tests should be run based on changed files.22 calculate_vars:23 name: Calculate workflow variables24 runs-on: ubuntu-24.0425 timeout-minutes: 1026 env:27 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}28 PR_NUMBER: ${{ github.event.pull_request.number }}29 outputs:30 extensive_matrix: ${{ steps.script.outputs.extensive_matrix }}31 may_skip_libm_ci: ${{ steps.script.outputs.may_skip_libm_ci }}32 steps:33 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.234 with:35 persist-credentials: false36 fetch-depth: 50037 - name: Fetch pull request ref38 run: git fetch origin "$GITHUB_REF:$GITHUB_REF"39 if: github.event_name == 'pull_request'40 - run: |41 set -eo pipefail # Needed to actually fail the job if ci-util fails42 python3 ci/ci-util.py generate-matrix | tee "$GITHUB_OUTPUT"43 id: script4445 test:46 name: Build and test47 timeout-minutes: 6048 # NOTE: self-hosted riscv64 runners are experimental and may be flaky.49 # Do not block CI on failures from this platform for now.50 continue-on-error: ${{ contains(matrix.os, 'self-hosted') }}51 strategy:52 fail-fast: false53 matrix:54 include:55 - target: aarch64-apple-darwin56 os: macos-1557 - target: aarch64-unknown-linux-gnu58 os: ubuntu-24.04-arm59 - target: aarch64-pc-windows-msvc60 os: windows-11-arm61 - target: arm-unknown-linux-gnueabi62 os: ubuntu-24.0463 - target: arm-unknown-linux-gnueabihf64 os: ubuntu-24.0465 - target: armv7-unknown-linux-gnueabihf66 os: ubuntu-24.0467 - target: i586-unknown-linux-gnu68 os: ubuntu-24.0469 - target: i686-unknown-linux-gnu70 os: ubuntu-24.0471 - target: loongarch64-unknown-linux-gnu72 os: ubuntu-24.0473 - target: powerpc-unknown-linux-gnu74 os: ubuntu-24.0475 - target: powerpc64-unknown-linux-gnu76 os: ubuntu-24.0477 - target: powerpc64le-unknown-linux-gnu78 os: ubuntu-24.0479 - target: powerpc64le-unknown-linux-gnu80 os: ubuntu-24.04-ppc64le81 # FIXME(ci): re-enable these once more capacity is avialable82 # - target: riscv64gc-unknown-linux-gnu83 # os: ["self-hosted", "linux", "riscv64"]84 - target: riscv64gc-unknown-linux-gnu85 os: ubuntu-24.0486 - target: s390x-unknown-linux-gnu87 os: ubuntu-24.04-s390x88 - target: thumbv6m-none-eabi89 os: ubuntu-24.0490 - target: thumbv7em-none-eabi91 os: ubuntu-24.0492 - target: thumbv7em-none-eabihf93 os: ubuntu-24.0494 - target: thumbv7m-none-eabi95 os: ubuntu-24.0496 - target: wasm32-unknown-unknown97 os: ubuntu-24.0498 - target: x86_64-unknown-linux-gnu99 os: ubuntu-24.04100 - target: x86_64-apple-darwin101 os: macos-15-intel102 - target: i686-pc-windows-msvc103 os: windows-2025104 - target: x86_64-pc-windows-msvc105 os: windows-2025106 - target: i686-pc-windows-gnu107 os: windows-2025108 channel: nightly-i686-gnu109 - target: x86_64-pc-windows-gnu110 os: windows-2025111 channel: nightly-x86_64-gnu112 runs-on: ${{ matrix.os }}113 needs: [calculate_vars]114 env:115 BUILD_ONLY: ${{ matrix.build_only }}116 JOB_TARGET: ${{ matrix.target }}117 JOB_CHANNEL: ${{ matrix.channel }}118 MAY_SKIP_LIBM_CI: ${{ needs.calculate_vars.outputs.may_skip_libm_ci }}119 RUN_IN_DOCKER: ${{ matrix.os == 'ubuntu-24.04' }}120 steps:121 - name: Print runner information122 shell: bash123 run: |124 set -x125 uname -a126 lscpu || (sysctl -a | grep cpu) || true127 echo "home: ${HOME:-not found}"128 pwd129130 # Native ppc and s390x runners don't have rustup by default131 - name: Install rustup132 if: matrix.os == 'ubuntu-24.04-ppc64le' || matrix.os == 'ubuntu-24.04-s390x'133 run: sudo apt-get update && sudo apt-get install -y rustup134135 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2136 with: { persist-credentials: false }137 - name: Install Rust (rustup)138 shell: bash139 run: |140 channel="nightly"141 # Account for channels that have required components (MinGW)142 [ -n "$JOB_CHANNEL" ] && channel="$JOB_CHANNEL"143 rustup update "$channel" --no-self-update144 rustup default "$channel"145 rustup target add "$JOB_TARGET"146147 - uses: taiki-e/install-action@bfadeaba214680fb4ab63e710bcb2a6a17019fdc # v2.70.4148 with:149 tool: nextest@0.9.131150151 - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1152 with:153 key: ${{ matrix.target }}154 - name: Cache Docker layers155 uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4156 if: ${{ env.RUN_IN_DOCKER == 'true' }}157 with:158 path: /tmp/.buildx-cache159 key: ${{ matrix.target }}-buildx-${{ github.sha }}160 restore-keys: ${{ matrix.target }}-buildx-161 # Configure buildx to use Docker layer caching162 - uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4163 if: ${{ env.RUN_IN_DOCKER == 'true' }}164165 - name: Cache compiler-rt166 id: cache-compiler-rt167 uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4168 with:169 path: compiler-rt170 key: ${{ runner.os }}-compiler-rt-${{ hashFiles('ci/download-compiler-rt.sh') }}171 - name: Download compiler-rt reference sources172 if: steps.cache-compiler-rt.outputs.cache-hit != 'true'173 run: ./ci/download-compiler-rt.sh174 shell: bash175 - run: echo "RUST_COMPILER_RT_ROOT=$(realpath ./compiler-rt)" >> "$GITHUB_ENV"176 shell: bash177178 - name: Download musl source179 run: ./ci/update-musl.sh180 shell: bash181182 - name: Verify API list183 if: matrix.os == 'ubuntu-24.04' || contains(matrix.os, 'self-hosted')184 run: |185 # Must be run on the host (not in Docker) because git and fs access is required.186 python3 etc/update-api-list.py --check187 cargo test -p update-api-list188189 # Non-linux tests just use our raw script190 - name: Run locally191 if: ${{ env.RUN_IN_DOCKER != 'true' }}192 shell: bash193 run: ./ci/run.sh "$JOB_TARGET"194195 # Otherwise we use our docker containers to run builds196 - name: Run in Docker197 if: ${{ env.RUN_IN_DOCKER == 'true' }}198 run: ./ci/run-docker.sh "$JOB_TARGET"199200 - name: Print test logs if available201 if: always()202 run: if [ -f "target/test-log.txt" ]; then cat target/test-log.txt; fi203 shell: bash204205 # Workaround to keep Docker cache smaller206 # https://github.com/docker/build-push-action/issues/252207 # https://github.com/moby/buildkit/issues/1896208 - name: Move Docker cache209 if: ${{ env.RUN_IN_DOCKER == 'true' }}210 run: |211 rm -rf /tmp/.buildx-cache212 mv /tmp/.buildx-cache-new /tmp/.buildx-cache213214 clippy:215 name: Clippy216 runs-on: ubuntu-24.04217 timeout-minutes: 10218 steps:219 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2220 with: { persist-credentials: false }221 # Unlike rustfmt, stable clippy does not work on code with nightly features.222 - name: Install nightly `clippy`223 run: |224 rustup update nightly --no-self-update225 rustup default nightly226 rustup component add clippy227 - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1228 - name: Download musl source229 run: ./ci/update-musl.sh230 - run: cargo clippy --workspace --all-targets231232 zizmor:233 name: Zizmor (Static analysis for GitHub Actions)234 runs-on: ubuntu-24.04235 permissions:236 security-events: write237 timeout-minutes: 10238 steps:239 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2240 with: { persist-credentials: false }241 - uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2242243 build-custom:244 name: Build custom target245 runs-on: ubuntu-24.04246 timeout-minutes: 10247 steps:248 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2249 with: { persist-credentials: false }250 - name: Install Rust251 run: |252 rustup update nightly --no-self-update253 rustup default nightly254 rustup component add rust-src255 - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1256 - run: |257 # Ensure we can build with custom target.json files (these can interact258 # poorly with build scripts)259 cargo build -p compiler_builtins -p libm \260 --target etc/thumbv7em-none-eabi-renamed.json \261 -Zbuild-std=core \262 -Zjson-target-spec263264 # FIXME: move this target to test job once https://github.com/rust-lang/rust/pull/150138 merged.265 build-thumbv6k:266 name: Build thumbv6k267 runs-on: ubuntu-24.04268 timeout-minutes: 10269 steps:270 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2271 with: { persist-credentials: false }272 - name: Install Rust273 run: |274 rustup update nightly --no-self-update275 rustup default nightly276 rustup component add rust-src277 - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1278 - run: |279 cargo build -p compiler_builtins -p libm \280 --target etc/thumbv6-none-eabi.json \281 -Zbuild-std=core \282 -Zjson-target-spec283284 benchmarks:285 name: Benchmarks286 timeout-minutes: 30287 strategy:288 fail-fast: false289 matrix:290 include:291 - target: aarch64-unknown-linux-gnu292 os: ubuntu-24.04-arm293 - target: i686-unknown-linux-gnu294 os: ubuntu-24.04295 - target: x86_64-unknown-linux-gnu296 os: ubuntu-24.04297 runs-on: ${{ matrix.os }}298 env:299 JOB_TARGET: ${{ matrix.target }}300 steps:301 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2302 with: { persist-credentials: false }303 - uses: taiki-e/install-action@bfadeaba214680fb4ab63e710bcb2a6a17019fdc # v2.70.4304 with:305 tool: cargo-binstall@1.17.7306307 - name: Set up dependencies308 run: ./ci/install-bench-deps.sh "$JOB_TARGET"309 - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1310 with:311 key: ${{ matrix.target }}312 - name: Download musl source313 run: ./ci/update-musl.sh314315 - name: Run icount benchmarks316 env:317 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}318 PR_NUMBER: ${{ github.event.pull_request.number }}319 run: ./ci/bench-icount.sh "$JOB_TARGET"320321 - name: Upload the benchmark baseline322 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0323 with:324 name: ${{ env.BASELINE_NAME }}325 path: ${{ env.BASELINE_NAME }}.tar.xz326327 - name: Print test logs if available328 if: always()329 run: if [ -f "target/test-log.txt" ]; then cat target/test-log.txt; fi330 shell: bash331332 miri:333 name: Miri334 runs-on: ubuntu-24.04335 timeout-minutes: 10336 steps:337 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2338 with: { persist-credentials: false }339 - name: Install Rust (rustup)340 run: rustup update nightly --no-self-update && rustup default nightly341 shell: bash342 - run: rustup component add miri343 - run: cargo miri setup344 - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1345 - run: ./ci/miri.sh346347 msrv:348 name: Check libm MSRV349 runs-on: ubuntu-24.04350 timeout-minutes: 10351 env:352 RUSTFLAGS: # No need to check warnings on old MSRV, unset `-Dwarnings`353 steps:354 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2355 with: { persist-credentials: false }356 - name: Install Rust357 run: |358 msrv="$(perl -ne 'print if s/rust-version\s*=\s*"(.*)"/\1/g' libm/Cargo.toml)"359 echo "MSRV: $msrv"360 rustup update "$msrv" --no-self-update && rustup default "$msrv"361 - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1362 - run: |363 # FIXME(msrv): Remove the workspace Cargo.toml so 1.63 cargo doesn't see364 # `edition = "2024"` and get spooked.365 rm Cargo.toml366 cargo build --manifest-path libm/Cargo.toml367368 rustfmt:369 name: Rustfmt370 runs-on: ubuntu-24.04371 timeout-minutes: 10372 steps:373 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2374 with: { persist-credentials: false }375 - name: Install nightly `rustfmt`376 run: rustup set profile minimal && rustup default nightly && rustup component add rustfmt377 - run: cargo fmt -- --check378379 extensive:380 name: Extensive tests for ${{ matrix.ty }}381 needs:382 # Wait on `clippy` so we have some confidence that the crate will build383 - clippy384 - calculate_vars385 runs-on: ubuntu-24.04386 timeout-minutes: 240 # 4 hours387 strategy:388 matrix:389 # Use the output from `calculate_vars` to create the matrix390 # FIXME: it would be better to run all jobs (i.e. all types) but mark those that391 # didn't change as skipped, rather than completely excluding the job. However,392 # this is not currently possible https://github.com/actions/runner/issues/1985.393 include: ${{ fromJSON(needs.calculate_vars.outputs.extensive_matrix).extensive_matrix }}394 env:395 TO_TEST: ${{ matrix.to_test }}396 steps:397 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2398 with: { persist-credentials: false }399 - name: Install Rust400 run: |401 rustup update nightly --no-self-update402 rustup default nightly403 - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1404 - name: download musl source405 run: ./ci/update-musl.sh406 - name: Run extensive tests407 run: ./ci/run-extensive.sh408 - name: Print test logs if available409 run: if [ -f "target/test-log.txt" ]; then cat target/test-log.txt; fi410 shell: bash411412 success:413 needs:414 - benchmarks415 - build-custom416 - build-thumbv6k417 - clippy418 - extensive419 - miri420 - msrv421 - rustfmt422 - test423 - zizmor424 runs-on: ubuntu-24.04425 timeout-minutes: 10426 # GitHub branch protection is exceedingly silly and treats "jobs skipped because a dependency427 # failed" as success. So we have to do some contortions to ensure the job fails if any of its428 # dependencies fails.429 if: always() # make sure this is never "skipped"430 env:431 NEEDS: ${{ toJson(needs) }}432 steps:433 # Manually check the status of all dependencies. `if: failure()` does not work.434 - name: check if any dependency failed435 run: jq --exit-status 'all(.result == "success")' <<< "$NEEDS"
Findings
✓ No findings reported for this file.