Development Guide
Relevant source files
This guide provides essential information for developers working with or contributing to the page_table_multiarch library. It covers the development environment setup, multi-architecture compilation strategy, testing approach, and documentation generation processes.
For detailed build instructions and testing procedures, see Building and Testing. For contribution guidelines and coding standards, see Contributing.
Development Environment Overview
The page_table_multiarch project uses a sophisticated multi-architecture development approach that requires specific toolchain configurations and conditional compilation strategies. The project is designed to work across five different target architectures while maintaining a unified development experience.
Development Architecture Matrix
flowchart TD
subgraph subGraph2["CI Pipeline Components"]
FORMAT["cargo fmt"]
CLIPPY["cargo clippy"]
BUILD["cargo build"]
TEST["cargo test"]
DOC["cargo doc"]
end
subgraph subGraph1["Target Architectures"]
LINUX["x86_64-unknown-linux-gnu"]
NONE["x86_64-unknown-none"]
RISCV["riscv64gc-unknown-none-elf"]
ARM["aarch64-unknown-none-softfloat"]
LOONG["loongarch64-unknown-none-softfloat"]
end
subgraph subGraph0["Development Environment"]
RUST["Rust Nightly Toolchain"]
COMPONENTS["rust-src, clippy, rustfmt"]
end
ARM --> BUILD
ARM --> CLIPPY
COMPONENTS --> ARM
COMPONENTS --> LINUX
COMPONENTS --> LOONG
COMPONENTS --> NONE
COMPONENTS --> RISCV
LINUX --> BUILD
LINUX --> CLIPPY
LINUX --> FORMAT
LINUX --> TEST
LOONG --> BUILD
LOONG --> CLIPPY
NONE --> BUILD
NONE --> CLIPPY
RISCV --> BUILD
RISCV --> CLIPPY
RUST --> COMPONENTS
TEST --> DOC
Sources: .github/workflows/ci.yml(L10 - L32)
Workspace Dependency Structure
The development environment manages dependencies through a two-crate workspace with architecture-specific conditional compilation. The dependency resolution varies based on the target platform to include only necessary architecture support crates.
flowchart TD
subgraph subGraph2["Hardware Support Crates"]
TOCK["tock-registers v0.9.0"]
RAW_CPUID["raw-cpuid v10.7.0"]
BIT_FIELD["bit_field v0.10.2"]
BIT_FIELD_2["bit_field v0.10.2"]
VOLATILE["volatile v0.4.6"]
CRITICAL["critical-section v1.2.0"]
EMBEDDED["embedded-hal v1.0.0"]
end
subgraph subGraph1["page_table_entry Dependencies"]
PTE_MEM["memory_addr v0.3.1"]
AARCH64["aarch64-cpu v10.0.0"]
BITFLAGS["bitflags v2.8.0"]
X86_64["x86_64 v0.15.2"]
end
subgraph subGraph0["page_table_multiarch Dependencies"]
PTM["page_table_multiarch v0.5.3"]
LOG["log v0.4.25"]
MEMORY["memory_addr v0.3.1"]
PTE["page_table_entry v0.5.3"]
RISCV_CRATE["riscv v0.12.1"]
X86_CRATE["x86 v0.52.0"]
end
AARCH64 --> TOCK
PTE --> AARCH64
PTE --> BITFLAGS
PTE --> PTE_MEM
PTE --> X86_64
PTM --> LOG
PTM --> MEMORY
PTM --> PTE
PTM --> RISCV_CRATE
PTM --> X86_CRATE
RISCV_CRATE --> CRITICAL
RISCV_CRATE --> EMBEDDED
X86_CRATE --> BIT_FIELD
X86_CRATE --> RAW_CPUID
Sources: Cargo.lock(L57 - L75) Cargo.lock(L5 - L149)
Multi-Architecture Development Strategy
The project employs a conditional compilation strategy that allows development and testing across multiple architectures while maintaining code clarity and avoiding unnecessary dependencies for specific targets.
Conditional Compilation System
The build system uses Cargo's target-specific dependencies and feature flags to include only the necessary architecture support:
| Target Architecture | Included Dependencies | Special Features |
|---|---|---|
| x86_64-unknown-linux-gnu | x86,x86_64, full test suite | Unit testing enabled |
| x86_64-unknown-none | x86,x86_64 | Bare metal support |
| riscv64gc-unknown-none-elf | riscv | RISC-V Sv39/Sv48 support |
| aarch64-unknown-none-softfloat | aarch64-cpu | ARM EL2 support available |
| loongarch64-unknown-none-softfloat | Basic LoongArch support | Custom PWC configuration |
Documentation Build Configuration
Documentation generation requires special configuration to include all architecture-specific code regardless of the build target:
flowchart TD
subgraph subGraph1["Architecture Inclusion"]
ALL_ARCH["All architecture modules included"]
X86_DOCS["x86_64 documentation"]
ARM_DOCS["AArch64 documentation"]
RISCV_DOCS["RISC-V documentation"]
LOONG_DOCS["LoongArch documentation"]
end
subgraph subGraph0["Documentation Build Process"]
DOC_ENV["RUSTFLAGS: --cfg doc"]
DOC_FLAGS["RUSTDOCFLAGS: -Zunstable-options --enable-index-page"]
DOC_BUILD["cargo doc --no-deps --all-features"]
end
ALL_ARCH --> ARM_DOCS
ALL_ARCH --> LOONG_DOCS
ALL_ARCH --> RISCV_DOCS
ALL_ARCH --> X86_DOCS
DOC_BUILD --> ALL_ARCH
DOC_ENV --> DOC_BUILD
DOC_FLAGS --> DOC_BUILD
Sources: .github/workflows/ci.yml(L40 - L49)
CI/CD Pipeline Architecture
The continuous integration system validates code across all supported architectures using a matrix build strategy. This ensures that changes work correctly across the entire supported platform ecosystem.
CI Matrix Strategy
flowchart TD
subgraph subGraph3["Documentation Pipeline"]
DOC_BUILD["cargo doc --no-deps --all-features"]
PAGES_DEPLOY["GitHub Pages Deployment"]
end
subgraph subGraph2["Validation Steps"]
VERSION_CHECK["rustc --version --verbose"]
FORMAT_CHECK["cargo fmt --all -- --check"]
CLIPPY_CHECK["cargo clippy --target TARGET --all-features"]
BUILD_STEP["cargo build --target TARGET --all-features"]
UNIT_TEST["cargo test --target x86_64-unknown-linux-gnu"]
end
subgraph subGraph1["Build Matrix"]
NIGHTLY["Rust Nightly Toolchain"]
TARGETS["5 Target Architectures"]
end
subgraph subGraph0["CI Trigger Events"]
PUSH["git push"]
PR["pull_request"]
end
BUILD_STEP --> UNIT_TEST
CLIPPY_CHECK --> BUILD_STEP
DOC_BUILD --> PAGES_DEPLOY
FORMAT_CHECK --> CLIPPY_CHECK
NIGHTLY --> TARGETS
PR --> NIGHTLY
PUSH --> NIGHTLY
TARGETS --> VERSION_CHECK
UNIT_TEST --> DOC_BUILD
VERSION_CHECK --> FORMAT_CHECK
Sources: .github/workflows/ci.yml(L1 - L33) .github/workflows/ci.yml(L34 - L56)
Quality Gates
The CI pipeline enforces several quality gates that must pass before code integration:
| Check Type | Command | Scope | Failure Behavior |
|---|---|---|---|
| Format | cargo fmt --all -- --check | All files | Hard failure |
| Clippy | cargo clippy --target TARGET --all-features | Per target | Hard failure |
| Build | cargo build --target TARGET --all-features | Per target | Hard failure |
| Unit Tests | cargo test --target x86_64-unknown-linux-gnu | Linux only | Hard failure |
| Documentation | cargo doc --no-deps --all-features | All features | Soft failure on non-default branch |
Development Workflow Integration
The development environment integrates multiple tools and processes to maintain code quality across architecture boundaries:
Toolchain Requirements
- Rust Toolchain: Nightly required for unstable features and cross-compilation support
- Components:
rust-srcfor cross-compilation,clippyfor linting,rustfmtfor formatting - Targets: All five supported architectures must be installed for comprehensive testing
Feature Flag Usage
The project uses Cargo feature flags to control compilation of architecture-specific code:
flowchart TD
subgraph subGraph1["Compilation Outcomes"]
FULL_BUILD["Complete architecture support"]
DOC_BUILD["Documentation with all architectures"]
ARM_PRIVILEGE["ARM EL2 privilege level support"]
end
subgraph subGraph0["Feature Control"]
ALL_FEATURES["--all-features"]
DOC_CFG["--cfg doc"]
ARM_EL2["arm-el2 feature"]
end
ALL_FEATURES --> FULL_BUILD
ARM_EL2 --> ARM_PRIVILEGE
DOC_CFG --> DOC_BUILD
FULL_BUILD --> DOC_BUILD
Sources: .github/workflows/ci.yml(L25 - L27) .github/workflows/ci.yml(L42)
The development environment is designed to handle the complexity of multi-architecture support while providing developers with clear feedback about compatibility and correctness across all supported platforms. The CI pipeline ensures that every change is validated against the complete matrix of supported architectures before integration.