From baa5772203db7ed576ff012d61ddf4741d55179b Mon Sep 17 00:00:00 2001 From: herbenderbler Date: Fri, 30 Jan 2026 18:36:35 -0700 Subject: [PATCH 1/2] Added ARM support for existing GitHub Actions; added tests for this new update --- .github/workflows/build.yml | 56 ++++++++++++++++++------------------- .github/workflows/test.yml | 48 +++++++++++++++++++++++++++---- tests/cross_config.rs | 14 ++++++++++ 3 files changed, 85 insertions(+), 33 deletions(-) create mode 100644 tests/cross_config.rs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ec8dc2172..94eb98a7c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,16 +38,17 @@ jobs: pkg_config_path: /usr/lib/x86_64-linux-gnu/pkgconfig steps: - uses: actions/checkout@v4 + - name: Install Rust toolchain + uses: actions/setup-rust@v1 + with: + rust-version: stable + targets: ${{ matrix.target }} + - name: Install cross + uses: taiki-e/install-action@cross - name: Cache cargo & target directories uses: Swatinem/rust-cache@v2 - name: Build binary - uses: houseabsolute/actions-rust-cross@v0 - with: - command: build - target: ${{ matrix.target }} - args: "--locked --release" - strip: true - toolchain: stable + run: cross build --locked --release --target ${{ matrix.target }} - name: Build tar.gz for homebrew installs if: matrix.type == 'ubuntu-x64' run: | @@ -68,6 +69,10 @@ jobs: IN_PIPELINE: true steps: - uses: actions/checkout@v4 + - name: Install Rust toolchain + uses: actions/setup-rust@v1 + with: + rust-version: stable - name: Install cargo-deb run: cargo install -f cargo-deb - uses: awalsh128/cache-apt-pkgs-action@v1 @@ -91,16 +96,14 @@ jobs: if: github.ref == 'refs/heads/master' steps: - uses: actions/checkout@v4 + - name: Install Rust toolchain + uses: actions/setup-rust@v1 + with: + rust-version: stable - name: Cache cargo & target directories uses: Swatinem/rust-cache@v2 - name: Build binary - uses: houseabsolute/actions-rust-cross@v0 - with: - command: build - target: x86_64-apple-darwin - args: "--locked --release" - strip: true - toolchain: stable + run: cargo build --locked --release --target x86_64-apple-darwin - name: Build tar.gz for homebrew installs run: | tar czf x86_64-macos-rustscan.tar.gz -C target/x86_64-apple-darwin/release rustscan @@ -120,16 +123,14 @@ jobs: if: github.ref == 'refs/heads/master' steps: - uses: actions/checkout@v4 + - name: Install Rust toolchain + uses: actions/setup-rust@v1 + with: + rust-version: stable - name: Cache cargo & target directories uses: Swatinem/rust-cache@v2 - name: Build binary - uses: houseabsolute/actions-rust-cross@v0 - with: - command: build - target: aarch64-apple-darwin - args: "--locked --release" - strip: true - toolchain: stable + run: cargo build --locked --release --target aarch64-apple-darwin - name: Build tar.gz for homebrew installs run: | tar czf aarch64-macos-rustscan.tar.gz -C target/aarch64-apple-darwin/release rustscan @@ -163,16 +164,15 @@ jobs: path: target\i686-pc-windows-msvc\release\rustscan.exe steps: - uses: actions/checkout@v4 + - name: Install Rust toolchain + uses: actions/setup-rust@v1 + with: + rust-version: stable + targets: ${{ matrix.target }} - name: Cache cargo & target directories uses: Swatinem/rust-cache@v2 - name: Build binary - uses: houseabsolute/actions-rust-cross@v0 - with: - command: build - target: ${{ matrix.target }} - args: "--locked --release" - strip: true - toolchain: stable + run: cargo build --locked --release --target ${{ matrix.target }} - uses: actions/upload-artifact@v4 with: name: ${{ matrix.name }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 527f907c9..4518f210b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,12 +17,18 @@ jobs: - name: Checkout sources uses: actions/checkout@v4 - - name: Install stable toolchain - uses: actions-rs/toolchain@v1 + - name: Install Rust toolchain + uses: actions/setup-rust@v1 with: - profile: minimal - toolchain: ${{ matrix.rust }} - override: true + rust-version: ${{ matrix.rust }} + + - name: Install Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install Python dependencies + run: python -m pip install --upgrade pip setuptools wheel - uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 @@ -32,3 +38,35 @@ jobs: - name: Run just run: just test + + test-arm: + name: ARM Test Suite (aarch64) + runs-on: ubuntu-latest + strategy: + matrix: + target: [aarch64-unknown-linux-gnu] + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: actions/setup-rust@v1 + with: + rust-version: stable + targets: ${{ matrix.target }} + + - name: Install Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install Python dependencies + run: python -m pip install --upgrade pip setuptools wheel + + - name: Install cross + uses: taiki-e/install-action@cross + + - uses: Swatinem/rust-cache@v2 + + - name: Run cross tests + run: cross test --target ${{ matrix.target }} diff --git a/tests/cross_config.rs b/tests/cross_config.rs new file mode 100644 index 000000000..8a9959ff4 --- /dev/null +++ b/tests/cross_config.rs @@ -0,0 +1,14 @@ +use std::fs; + +#[test] +fn cross_config_includes_aarch64_target() { + let cross_toml = fs::read_to_string("Cross.toml").expect("Cross.toml should exist"); + assert!( + cross_toml.contains("[target.aarch64-unknown-linux-gnu]"), + "Cross.toml must define target.aarch64-unknown-linux-gnu" + ); + assert!( + cross_toml.contains("pre-build"), + "Cross.toml must define pre-build steps for aarch64 target" + ); +} From 35749adb098ca15a4468b887208c4c649486a570 Mon Sep 17 00:00:00 2001 From: herbenderbler Date: Fri, 30 Jan 2026 18:37:14 -0700 Subject: [PATCH 2/2] Added documentation for new ARM support --- Cross.toml | 6 +++ README.md | 2 + docs/arm-support.md | 90 ++++++++++++++++++++++++++++++++++++++++++++ src/benchmark/mod.rs | 8 +--- 4 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 Cross.toml create mode 100644 docs/arm-support.md diff --git a/Cross.toml b/Cross.toml new file mode 100644 index 000000000..d31e7f81f --- /dev/null +++ b/Cross.toml @@ -0,0 +1,6 @@ +[target.aarch64-unknown-linux-gnu] +pre-build = [ + "apt-get update", + "apt-get install -y python3 python3-pip", + "python3 -m pip install --upgrade pip setuptools wheel" +] diff --git a/README.md b/README.md index 4adc79407..865fa2638 100644 --- a/README.md +++ b/README.md @@ -56,11 +56,13 @@ Arch: | | | | | :----------------------------------------: | :------------------------------------: | :-------------------------: | | :book: [Installation Guide][toc-install] | :books: [Documentation][links-table-2] | :parrot: [Discord][discord] | +| | :penguin: [ARM Support](docs/arm-support.md) | | ## 🙋 Table of Contents - 📖 [Installation Guide][toc-install] - 🐋 [Docker Usage][toc-docker-usage] +- 🐧 [ARM Support](docs/arm-support.md) - 🦜 [Discord][discord] - 🤸 [Usage][usage-1] diff --git a/docs/arm-support.md b/docs/arm-support.md new file mode 100644 index 000000000..b6124124d --- /dev/null +++ b/docs/arm-support.md @@ -0,0 +1,90 @@ +# ARM support + +This document explains how RustScan's ARM support works, how to build ARM binaries locally, and how the CI pipeline validates ARM builds and tests. + +## What ARM targets are supported + +The CI pipeline builds and tests Linux ARM64 using the target: + +- `aarch64-unknown-linux-gnu` + +The build pipeline also produces additional Linux artifacts for other targets, but ARM validation focuses on aarch64 Linux. + +## CI overview (GitHub Actions) + +ARM support is provided via GitHub Actions using `actions/setup-rust` plus `cross` for cross-compilation. The pipeline includes: + +- A build matrix that includes `aarch64-unknown-linux-gnu` for Linux builds. +- A dedicated ARM test job that runs `cross test` for the aarch64 target. +- Explicit Python installation and dependency setup for the scripting integration tests. + +Key files: + +- CI workflows: [.github/workflows/build.yml](../.github/workflows/build.yml) and [.github/workflows/test.yml](../.github/workflows/test.yml) +- Cross configuration: [Cross.toml](../Cross.toml) + +### Why `cross` + +`cross` runs builds and tests inside a container that has the right toolchain for the target. This avoids local toolchain setup and makes the aarch64 Linux build reproducible in CI. + +### Python dependencies in ARM CI + +RustScan’s scripting tests execute a Python script from the fixtures directory, so Python must exist in the test environment. For ARM CI, Python is installed in the cross container using the `pre-build` hooks in [Cross.toml](../Cross.toml). + +## Local builds for ARM + +You can build ARM binaries locally using `cross` on any host OS that supports Docker/Podman. + +### 1) Install cross + +``` +cargo install cross +``` + +### 2) Build for aarch64 Linux + +``` +cross build --locked --release --target aarch64-unknown-linux-gnu +``` + +The resulting binary is located at: + +``` +target/aarch64-unknown-linux-gnu/release/rustscan +``` + +## Local tests for ARM + +Run the test suite for the ARM target with: + +``` +cross test --target aarch64-unknown-linux-gnu +``` + +This runs the Rust unit and integration tests inside the aarch64 container. The Python script-based test is included and relies on the Python setup defined in [Cross.toml](../Cross.toml). + +## Customizing the ARM container + +If you need additional tools in the ARM container (for example, extra Python packages), update the `pre-build` list in [Cross.toml](../Cross.toml). The current configuration installs Python and basic packaging tools. + +## Troubleshooting + +### Python script test failures + +If the `run_python_script` test fails, verify that the container has Python installed and that the script shebang is executable. In CI, this is handled by the `pre-build` steps in [Cross.toml](../Cross.toml). For local use, ensure your Docker/Podman backend is functioning and that `cross` can download the base image. + +### Missing target errors + +If you see target-related errors, ensure `cross` is installed and you are using the correct target triple: + +- `aarch64-unknown-linux-gnu` + +## FAQ + +**Does this add native ARM runners?** + +No. The ARM jobs run on standard GitHub-hosted runners and use `cross` to build and test aarch64 Linux in containers. + +**Can I build ARM binaries without cross?** + +Yes, but you’ll need to install a compatible target toolchain and linker locally. `cross` is the recommended approach because it’s consistent with CI. diff --git a/src/benchmark/mod.rs b/src/benchmark/mod.rs index 25b36dea4..0887e1c9e 100644 --- a/src/benchmark/mod.rs +++ b/src/benchmark/mod.rs @@ -42,12 +42,8 @@ impl Benchmark { let mut summary = String::from("\nRustScan Benchmark Summary"); for timer in &self.named_timers { - if timer.start.is_some() && timer.end.is_some() { - let runtime_secs = timer - .end - .unwrap() - .saturating_duration_since(timer.start.unwrap()) - .as_secs_f32(); + if let (Some(start), Some(end)) = (timer.start, timer.end) { + let runtime_secs = end.saturating_duration_since(start).as_secs_f32(); summary.push_str(&format!("\n{0: <10} | {1: <10}s", timer.name, runtime_secs)); } }