Building and Testing
Relevant source files
This page covers the development workflow for building and testing the page_table_multiarch library. It explains the multi-architecture build system, test execution across different targets, and the CI/CD pipeline that ensures code quality across all supported platforms.
For information about contributing code changes, see Contributing. For architectural details about the supported platforms, see Supported Platforms.
Build System Architecture
The project uses a Cargo workspace structure with conditional compilation to support multiple processor architectures. The build system automatically includes only the necessary dependencies and code paths based on the target architecture.
Workspace Structure
flowchart TD
subgraph subGraph3["Conditional Dependencies"]
TARGET_CFG["Target Architecture"]
X86_DEPS["x86 v0.52x86_64 v0.15.1"]
ARM_DEPS["aarch64-cpu v10.0"]
RV_DEPS["riscv v0.12"]
LA_DEPS["Built-in support"]
DOC_DEPS["All dependenciesfor documentation"]
end
subgraph subGraph2["Cargo Workspace"]
ROOT["Cargo.tomlWorkspace Root"]
subgraph subGraph1["page_table_entry"]
PTE_CARGO["page_table_entry/Cargo.toml"]
PTE_LIB["lib.rs"]
PTE_ARCH["arch/ entries"]
end
subgraph page_table_multiarch["page_table_multiarch"]
PTM_CARGO["page_table_multiarch/Cargo.toml"]
PTM_LIB["lib.rs"]
PTM_ARCH["arch/ modules"]
end
end
PTE_CARGO --> ARM_DEPS
PTE_CARGO --> DOC_DEPS
PTE_CARGO --> X86_DEPS
PTM_CARGO --> ARM_DEPS
PTM_CARGO --> LA_DEPS
PTM_CARGO --> PTE_CARGO
PTM_CARGO --> RV_DEPS
PTM_CARGO --> X86_DEPS
ROOT --> PTE_CARGO
ROOT --> PTM_CARGO
TARGET_CFG --> ARM_DEPS
TARGET_CFG --> DOC_DEPS
TARGET_CFG --> LA_DEPS
TARGET_CFG --> RV_DEPS
TARGET_CFG --> X86_DEPS
Architecture-Specific Dependencies
The build system conditionally includes dependencies based on the compilation target:
| Target Architecture | Dependencies | Purpose |
|---|---|---|
| x86_64 | x86 v0.52,x86_64 v0.15.1 | x86-specific register and instruction access |
| aarch64 | aarch64-cpu v10.0 | ARM system register manipulation |
| riscv32/64 | riscv v0.12 | RISC-V CSR and instruction support |
| loongarch64 | Built-in | Native LoongArch64 support |
| Documentation | All dependencies | Complete API documentation |
Sources: Cargo.toml(L1 - L20) Cargo.lock(L1 - L150)
Development Environment Setup
Prerequisites
The project requires the Rust nightly toolchain with specific components and targets:
# Install nightly toolchain with required components
rustup toolchain install nightly
rustup component add --toolchain nightly rust-src clippy rustfmt
# Add target architectures for cross-compilation
rustup target add --toolchain nightly x86_64-unknown-none
rustup target add --toolchain nightly riscv64gc-unknown-none-elf
rustup target add --toolchain nightly aarch64-unknown-none-softfloat
rustup target add --toolchain nightly loongarch64-unknown-none-softfloat
Environment Configuration
For documentation builds and certain tests, set the doc configuration flag:
export RUSTFLAGS="--cfg doc"
This enables all architecture-specific code paths during documentation generation, ensuring complete API coverage.
Sources: .github/workflows/ci.yml(L15 - L19) .github/workflows/ci.yml(L31 - L32) .github/workflows/ci.yml(L42)
Building the Project
Basic Build Commands
# Build for the host architecture (typically x86_64)
cargo build
# Build with all features enabled
cargo build --all-features
# Cross-compile for specific targets
cargo build --target x86_64-unknown-none --all-features
cargo build --target riscv64gc-unknown-none-elf --all-features
cargo build --target aarch64-unknown-none-softfloat --all-features
cargo build --target loongarch64-unknown-none-softfloat --all-features
Build Process Flow
flowchart TD
subgraph Compilation["Compilation"]
COMPILE["rustc compilation"]
CFG_FLAGS["Conditional compilation#[cfg(target_arch)]"]
ARCH_MODULES["Architecture-specific modules"]
LINK["Link final binary/library"]
end
subgraph subGraph0["Dependency Resolution"]
RESOLVE["Cargo resolves dependencies"]
TARGET_CHECK["Target Architecture"]
X86_PATH["Include x86/x86_64 crates"]
ARM_PATH["Include aarch64-cpu crate"]
RV_PATH["Include riscv crate"]
LA_PATH["Built-in support only"]
end
START["cargo build --target TARGET"]
ARCH_MODULES --> LINK
ARM_PATH --> COMPILE
CFG_FLAGS --> ARCH_MODULES
COMPILE --> CFG_FLAGS
LA_PATH --> COMPILE
RESOLVE --> TARGET_CHECK
RV_PATH --> COMPILE
START --> RESOLVE
TARGET_CHECK --> ARM_PATH
TARGET_CHECK --> LA_PATH
TARGET_CHECK --> RV_PATH
TARGET_CHECK --> X86_PATH
X86_PATH --> COMPILE
The build process uses Rust's conditional compilation features to include only the relevant code and dependencies for each target architecture.
Sources: .github/workflows/ci.yml(L26 - L27)
Running Tests
Test Execution Matrix
Tests are executed differently based on the target platform due to hardware and emulation constraints:
| Target | Test Type | Execution Environment |
|---|---|---|
| x86_64-unknown-linux-gnu | Unit tests | Native execution |
| x86_64-unknown-none | Build verification | Compile-only |
| riscv64gc-unknown-none-elf | Build verification | Compile-only |
| aarch64-unknown-none-softfloat | Build verification | Compile-only |
| loongarch64-unknown-none-softfloat | Build verification | Compile-only |
Test Commands
# Run all tests (only works on x86_64-unknown-linux-gnu)
cargo test -- --nocapture
# Build verification for embedded targets
cargo build --target x86_64-unknown-none --all-features
cargo build --target riscv64gc-unknown-none-elf --all-features
cargo build --target aarch64-unknown-none-softfloat --all-features
cargo build --target loongarch64-unknown-none-softfloat --all-features
# Code quality checks
cargo fmt --all -- --check
cargo clippy --target TARGET --all-features -- -A clippy::new_without_default
Test Architecture
flowchart TD
subgraph subGraph1["Target Matrix"]
LINUX["x86_64-unknown-linux-gnu"]
BARE_X86["x86_64-unknown-none"]
RV["riscv64gc-unknown-none-elf"]
ARM["aarch64-unknown-none-softfloat"]
LOONG["loongarch64-unknown-none-softfloat"]
end
subgraph subGraph0["Test Pipeline"]
FORMAT["cargo fmt --check"]
CLIPPY["cargo clippy"]
BUILD["cargo build"]
UNIT_TEST["cargo test"]
end
BUILD --> ARM
BUILD --> BARE_X86
BUILD --> LINUX
BUILD --> LOONG
BUILD --> RV
BUILD --> UNIT_TEST
CLIPPY --> BUILD
FORMAT --> CLIPPY
UNIT_TEST --> LINUX
Unit tests execute only on x86_64-unknown-linux-gnu because the embedded targets lack standard library support required for the test harness.
Sources: .github/workflows/ci.yml(L28 - L32) .github/workflows/ci.yml(L24 - L25) .github/workflows/ci.yml(L22 - L23)
CI/CD Pipeline
GitHub Actions Workflow
The CI pipeline runs on every push and pull request, executing a comprehensive test matrix across all supported architectures.
flowchart TD
subgraph Documentation["Documentation"]
DOC_BUILD["cargo doc --no-deps"]
DEPLOY["Deploy to GitHub Pages"]
end
subgraph subGraph3["CI Steps"]
CHECKOUT["actions/checkout@v4"]
TOOLCHAIN["Setup Rust nightly"]
VERSION_CHECK["rustc --version"]
FMT_CHECK["Format check"]
CLIPPY_CHECK["Clippy analysis"]
BUILD_STEP["Build verification"]
TEST_STEP["Unit test execution"]
end
subgraph subGraph2["Build Matrix"]
NIGHTLY["Rust Nightly Toolchain"]
subgraph subGraph1["Target Matrix"]
LINUX_GNU["x86_64-unknown-linux-gnu"]
X86_NONE["x86_64-unknown-none"]
RISCV64["riscv64gc-unknown-none-elf"]
AARCH64["aarch64-unknown-none-softfloat"]
LOONGARCH["loongarch64-unknown-none-softfloat"]
end
end
subgraph subGraph0["CI Triggers"]
PUSH["git push"]
PR["Pull Request"]
end
AARCH64 --> BUILD_STEP
BUILD_STEP --> TEST_STEP
CHECKOUT --> DOC_BUILD
CHECKOUT --> TOOLCHAIN
CLIPPY_CHECK --> BUILD_STEP
DOC_BUILD --> DEPLOY
FMT_CHECK --> CLIPPY_CHECK
LINUX_GNU --> TEST_STEP
LOONGARCH --> BUILD_STEP
PR --> CHECKOUT
PUSH --> CHECKOUT
RISCV64 --> BUILD_STEP
TOOLCHAIN --> VERSION_CHECK
VERSION_CHECK --> FMT_CHECK
X86_NONE --> BUILD_STEP
CI Configuration Details
The workflow configuration includes specific settings for multi-architecture support:
| Configuration | Value | Purpose |
|---|---|---|
| fail-fast | false | Continue testing other targets if one fails |
| rust-toolchain | nightly | Required for unstable features |
| components | rust-src, clippy, rustfmt | Development tools and source code |
| RUSTFLAGS | --cfg doc | Enable documentation-specific code paths |
| RUSTDOCFLAGS | -Zunstable-options --enable-index-page | Enhanced documentation features |
Sources: .github/workflows/ci.yml(L1 - L57)
Documentation Generation
Local Documentation Build
# Build documentation with all features
RUSTFLAGS="--cfg doc" cargo doc --no-deps --all-features
# Open generated documentation
open target/doc/page_table_multiarch/index.html
Documentation Pipeline
sequenceDiagram
participant Developer as Developer
participant GitHubActions as GitHub Actions
participant CargoDoc as Cargo Doc
participant GitHubPages as GitHub Pages
Developer ->> GitHubActions: Push to main branch
GitHubActions ->> CargoDoc: RUSTFLAGS=--cfg doc
Note over CargoDoc: cargo doc --no-deps --all-features
CargoDoc ->> GitHubActions: Generated documentation
GitHubActions ->> GitHubPages: Deploy to gh-pages branch
GitHubPages ->> Developer: Updated documentation site
Note over GitHubActions,GitHubPages: Documentation URL:<br>https://arceos-org.github.io/page_table_multiarch
The documentation build process uses special configuration flags to ensure all architecture-specific APIs are documented, even when building on a single architecture.
Documentation Features
- Index page generation: Provides a unified entry point for all crates
- Broken link detection: Fails build on invalid cross-references
- Missing documentation warnings: Ensures comprehensive API coverage
- All-features documentation: Includes conditional compilation paths
Sources: .github/workflows/ci.yml(L34 - L57) .github/workflows/ci.yml(L43) Cargo.toml(L15)