diff --git a/.github/actions/mold/action.yml b/.github/actions/mold/action.yml new file mode 100644 index 00000000..bdf4f184 --- /dev/null +++ b/.github/actions/mold/action.yml @@ -0,0 +1,17 @@ +name: Link with mold +description: > + Install mold and link this job's x86_64 Linux Rust builds with it in place + of the bundled rust-lld: fewer threads and less random writing. C builds keep + the system linker. MOLD_RUSTFLAGS carries the flags for a step that sets the + target's rustflags itself or builds through RUSTFLAGS, which overrides them. +runs: + using: composite + steps: + - uses: rui314/setup-mold@v1 + with: + make-default: false + - shell: bash + run: | + flags="-C linker-features=-lld -C link-arg=-fuse-ld=mold" + echo "MOLD_RUSTFLAGS=$flags" >> "$GITHUB_ENV" + echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS=$flags" >> "$GITHUB_ENV" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0716b83d..eb831c15 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,6 +121,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7.0.1 + - uses: ./.github/actions/mold - uses: dtolnay/rust-toolchain@stable with: components: rustfmt, clippy @@ -251,6 +252,7 @@ jobs: # Build + test + header-diff job (no push); don't leave the token # in the checkout's git config. persist-credentials: false + - uses: ./.github/actions/mold - uses: dtolnay/rust-toolchain@stable with: components: clippy @@ -383,6 +385,8 @@ jobs: steps: - uses: actions/checkout@v7.0.1 if: needs.changes.outputs.code == 'true' + - uses: ./.github/actions/mold + if: needs.changes.outputs.code == 'true' && runner.os == 'Linux' - uses: dtolnay/rust-toolchain@stable if: needs.changes.outputs.code == 'true' - name: Prepend toolchain bin to PATH (macos shim workaround) @@ -460,6 +464,8 @@ jobs: if: needs.changes.outputs.code == 'true' with: persist-credentials: false + - uses: ./.github/actions/mold + if: needs.changes.outputs.code == 'true' && runner.os == 'Linux' - uses: dtolnay/rust-toolchain@stable if: needs.changes.outputs.code == 'true' - name: Prepend toolchain bin to PATH (macos shim workaround) @@ -494,6 +500,8 @@ jobs: if: needs.changes.outputs.code == 'true' with: persist-credentials: false + - uses: ./.github/actions/mold + if: needs.changes.outputs.code == 'true' - uses: dtolnay/rust-toolchain@stable if: needs.changes.outputs.code == 'true' - uses: Swatinem/rust-cache@v2 @@ -539,6 +547,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7.0.1 + - uses: ./.github/actions/mold - uses: dtolnay/rust-toolchain@stable with: toolchain: "1.92.0" @@ -565,6 +574,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7.0.1 + - uses: ./.github/actions/mold - uses: dtolnay/rust-toolchain@stable with: components: clippy @@ -854,6 +864,7 @@ jobs: - uses: actions/checkout@v7.0.1 with: persist-credentials: false + - uses: ./.github/actions/mold - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 with: @@ -932,10 +943,13 @@ jobs: - uses: Swatinem/rust-cache@v2 - uses: taiki-e/install-action@cargo-llvm-cov - uses: taiki-e/install-action@nextest + - uses: ./.github/actions/mold # Through nextest, as the test job runs: a process per test. Some tests # set process-wide state (the CLI's SIGINT disposition), and the plain - # harness would run them as threads of one process. - - run: cargo llvm-cov nextest --profile ci -p structured-zstd --features hash,std,dict-builder --lcov --output-path lcov.info + # harness would run them as threads of one process. cargo-llvm-cov sets + # RUSTFLAGS, which overrides the target's rustflags, so the mold flags + # go in through RUSTFLAGS and it appends its instrumentation to them. + - run: RUSTFLAGS="$MOLD_RUSTFLAGS" cargo llvm-cov nextest --profile ci -p structured-zstd --features hash,std,dict-builder --lcov --output-path lcov.info working-directory: zstd - uses: codecov/codecov-action@v7 with: @@ -980,7 +994,9 @@ jobs: # `-max_total_time` seconds of fresh fuzzing on top. name: Fuzz smoke needs: lint - timeout-minutes: 20 + # Six targets at 90 s each plus the sanitizer builds run close to + # twenty minutes on a cold cache. + timeout-minutes: 30 runs-on: ubuntu-latest env: # Override `rust-toolchain.toml` (which pins stable) so `cargo fuzz` @@ -1001,6 +1017,11 @@ jobs: steps: - uses: actions/checkout@v7.0.1 - uses: dtolnay/rust-toolchain@nightly + - uses: ./.github/actions/mold + # cargo-fuzz builds with RUSTFLAGS of its own, appending any it is + # given, so the mold flags reach it through RUSTFLAGS. + - name: Link the fuzz builds with mold + run: echo "RUSTFLAGS=$MOLD_RUSTFLAGS" >> "$GITHUB_ENV" - uses: Swatinem/rust-cache@v2 with: prefix-key: fuzz @@ -1255,6 +1276,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7.0.1 + - uses: ./.github/actions/mold - uses: dtolnay/rust-toolchain@stable - name: Install benchmark target run: rustup target add ${{ matrix.bench.target_triple }} @@ -1290,9 +1312,12 @@ jobs: # decompress/level_-1_fast/decodecorpus-z000033/c_stream on # i9-9900K; the win comes from _bzhi_u64-backed # mask_lower_bits in the FSE state-update hot path. - CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS: "-C target-cpu=x86-64-v3" + # + # The gnu target's baseline is added in the script below, beside + # the mold link flags the job's environment already holds. CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS: "-C target-cpu=x86-64-v3" run: | + export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C target-cpu=x86-64-v3 $MOLD_RUSTFLAGS" # `--no-run` builds without executing; `--message-format=json` # exposes the resolved binary path in the build log so we # can ship just the executable to shards. Building BOTH