diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 23848c3..d921982 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,7 @@ jobs: matrix: include: - { target: x86_64-unknown-linux-gnu, os: ubuntu-latest } + - { target: aarch64-unknown-linux-gnu, os: ubuntu-latest } - { target: aarch64-apple-darwin, os: macos-latest } - { target: x86_64-pc-windows-msvc, os: windows-latest } - { target: aarch64-pc-windows-msvc, os: windows-latest } @@ -61,6 +62,8 @@ jobs: with: key: ${{ matrix.target }} + # `check` does not link, so no cross-linker is needed here. Linking is + # exercised by the release workflow. - run: cargo check --all-targets --target ${{ matrix.target }} # Guard the promise the README makes: an ordinary export carries no personal diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f097d6e..942fd82 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,11 +42,16 @@ jobs: runs-on: ${{ matrix.os }} permissions: contents: write + # Only consulted when building the matching target, so it is harmless on + # the other legs. + env: + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc strategy: fail-fast: false matrix: include: - { target: x86_64-unknown-linux-gnu, os: ubuntu-latest } + - { target: aarch64-unknown-linux-gnu, os: ubuntu-latest, apt: gcc-aarch64-linux-gnu } - { target: aarch64-apple-darwin, os: macos-latest } - { target: x86_64-pc-windows-msvc, os: windows-latest } - { target: aarch64-pc-windows-msvc, os: windows-latest } @@ -59,6 +64,27 @@ jobs: with: targets: ${{ matrix.target }} + - name: Install cross-linker + if: matrix.apt != '' + run: | + sudo apt-get update + sudo apt-get install --yes --no-install-recommends ${{ matrix.apt }} + + - name: Keep runner paths out of the binary + shell: bash + run: | + # Panic messages otherwise embed the runner's home directory, which + # reaches every published binary via the toolchain and registry paths + # baked in by file!(). CONTRIBUTING.md documents the same step for + # local release builds. + if [ "$RUNNER_OS" = "Windows" ]; then + home=$(cygpath -w "$HOME") + else + home="$HOME" + fi + echo "RUSTFLAGS=--remap-path-prefix=$home=." >> "$GITHUB_ENV" + + # Builds, archives (.tar.gz on Unix, .zip on Windows), checksums and # uploads to the release in one step. - uses: taiki-e/upload-rust-binary-action@v1 @@ -73,29 +99,60 @@ jobs: # Debian and RPM packages, for the distributions that want one. linux-packages: - name: Linux packages + name: Linux packages (${{ matrix.arch }}) needs: release-please if: needs.release-please.outputs.released == 'true' runs-on: ubuntu-latest permissions: contents: write + env: + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc + strategy: + # One architecture failing must not cost the release the other's packages. + fail-fast: false + matrix: + include: + - { target: x86_64-unknown-linux-gnu, arch: amd64 } + - { target: aarch64-unknown-linux-gnu, arch: arm64, apt: gcc-aarch64-linux-gnu } steps: - uses: actions/checkout@v7 with: ref: ${{ needs.release-please.outputs.tag }} - uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.target }} + + - name: Install cross-linker + if: matrix.apt != '' + run: | + sudo apt-get update + sudo apt-get install --yes --no-install-recommends ${{ matrix.apt }} + + - name: Keep runner paths out of the binary + shell: bash + run: | + # Panic messages otherwise embed the runner's home directory, which + # reaches every published binary via the toolchain and registry paths + # baked in by file!(). CONTRIBUTING.md documents the same step for + # local release builds. + if [ "$RUNNER_OS" = "Windows" ]; then + home=$(cygpath -w "$HOME") + else + home="$HOME" + fi + echo "RUSTFLAGS=--remap-path-prefix=$home=." >> "$GITHUB_ENV" - name: Install packaging tools run: cargo install --locked cargo-deb cargo-generate-rpm - name: Build - run: cargo build --release + run: cargo build --release --target ${{ matrix.target }} - name: Build .deb and .rpm run: | - cargo deb --no-build --output dist/ - cargo generate-rpm --output dist/ + cargo deb --no-build --target ${{ matrix.target }} --output dist/ + cargo generate-rpm --target ${{ matrix.target }} --output dist/ - name: Checksums working-directory: dist diff --git a/README.md b/README.md index 4980b7f..20d6eaf 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ plus Debian and RPM packages. See | Platform | Asset | | --- | --- | | Linux x86-64 | `loop-extract-vX.Y.Z-x86_64-unknown-linux-gnu.tar.gz`, `.deb`, `.rpm` | +| Linux ARM64 | `loop-extract-vX.Y.Z-aarch64-unknown-linux-gnu.tar.gz`, `.deb`, `.rpm` | | macOS Apple Silicon | `loop-extract-vX.Y.Z-aarch64-apple-darwin.tar.gz` | | Windows x86-64 | `loop-extract-vX.Y.Z-x86_64-pc-windows-msvc.zip` | | Windows ARM64 | `loop-extract-vX.Y.Z-aarch64-pc-windows-msvc.zip` | @@ -45,10 +46,12 @@ sha256sum -c loop-extract-vX.Y.Z-x86_64-unknown-linux-gnu.tar.gz.sha256 ### Linux ```bash -sudo dpkg -i loop-extract_X.Y.Z-1_amd64.deb # Debian, Ubuntu -sudo rpm -i loop-extract-X.Y.Z-1.x86_64.rpm # Fedora, RHEL, openSUSE +sudo dpkg -i loop-extract_X.Y.Z-1_amd64.deb # Debian, Ubuntu +sudo rpm -i loop-extract-X.Y.Z-1.x86_64.rpm # Fedora, RHEL, openSUSE ``` +Replace `amd64` with `arm64`, or `x86_64` with `aarch64`, on ARM hardware. + Or extract the tarball and put the binary on your `PATH`. ### macOS