Build System
Relevant source files
This document covers the build process, CI/CD pipeline, and cross-compilation setup for the percpu crate ecosystem. The build system is designed to support multiple CPU architectures and testing environments while maintaining compatibility across bare-metal and hosted environments.
For information about feature flag configuration, see Feature Flags Configuration. For testing procedures and test structure, see Testing Guide.
Overview
The percpu build system consists of several components working together to support cross-platform compilation and testing:
- Cargo workspace with two crates:
percpu(runtime) andpercpu_macros(procedural macros) - Multi-target CI/CD pipeline testing across five different architectures
- Custom build scripts for linker integration and test configuration
- Feature-based conditional compilation for different deployment scenarios
Sources: .github/workflows/ci.yml(L1 - L56) Cargo.lock(L1 - L149) percpu/build.rs(L1 - L10)
Cross-Compilation Architecture
The build system supports a comprehensive matrix of target platforms, each requiring specific toolchain and runtime configurations:
flowchart TD
subgraph subGraph2["Build Configurations"]
FEATURES_PREEMPT["preempt,arm-el2Full Feature Set"]
FEATURES_NAIVE["sp-naiveSingle-CPU Fallback"]
CUSTOM_LINKER["Custom Linker Scriptstest_percpu.x"]
end
subgraph subGraph1["Toolchain Requirements"]
NIGHTLY["Rust Nightly Toolchain"]
COMPONENTS["rust-src, clippy, rustfmt"]
TARGETS["Cross-compilation Targets"]
end
subgraph subGraph0["Target Platforms"]
LINUX["x86_64-unknown-linux-gnuHosted Environment"]
BARE_X86["x86_64-unknown-noneBare Metal x86_64"]
BARE_RISCV["riscv64gc-unknown-none-elfBare Metal RISC-V"]
BARE_ARM["aarch64-unknown-none-softfloatBare Metal AArch64"]
BARE_LOONG["loongarch64-unknown-none-softfloatBare Metal LoongArch"]
end
COMPONENTS --> NIGHTLY
CUSTOM_LINKER --> LINUX
FEATURES_NAIVE --> LINUX
FEATURES_PREEMPT --> BARE_ARM
FEATURES_PREEMPT --> BARE_LOONG
FEATURES_PREEMPT --> BARE_RISCV
FEATURES_PREEMPT --> BARE_X86
NIGHTLY --> BARE_ARM
NIGHTLY --> BARE_LOONG
NIGHTLY --> BARE_RISCV
NIGHTLY --> BARE_X86
NIGHTLY --> LINUX
TARGETS --> NIGHTLY
Sources: .github/workflows/ci.yml(L12 - L19) .github/workflows/ci.yml(L25 - L27)
CI/CD Pipeline
The automated build and test pipeline runs on every push and pull request, ensuring code quality and cross-platform compatibility:
Build Matrix Configuration
| Target Platform | Test Environment | Feature Set | Special Requirements |
|---|---|---|---|
| x86_64-unknown-linux-gnu | Ubuntu 22.04 | sp-naive+ default | Unit tests enabled |
| x86_64-unknown-none | Ubuntu 22.04 | preempt,arm-el2 | Bare metal |
| riscv64gc-unknown-none-elf | Ubuntu 22.04 | preempt,arm-el2 | Bare metal |
| aarch64-unknown-none-softfloat | Ubuntu 22.04 | preempt,arm-el2 | Bare metal |
| loongarch64-unknown-none-softfloat | Ubuntu 22.04 | preempt,arm-el2 | Bare metal |
Pipeline Stages
flowchart TD
subgraph subGraph0["CI Job"]
CLIPPY["cargo clippy --target TARGET --features preempt,arm-el2"]
BUILD["cargo build --target TARGET --features preempt,arm-el2"]
TEST["cargo test --target x86_64-unknown-linux-gnu"]
subgraph subGraph1["Doc Job"]
DOC_CHECKOUT["actions/checkout@v4"]
DOC_TOOLCHAIN["dtolnay/rust-toolchain@nightly"]
DOC_BUILD["cargo doc --no-deps"]
DEPLOY["JamesIves/github-pages-deploy-action@v4"]
CHECKOUT["actions/checkout@v4"]
TOOLCHAIN["dtolnay/rust-toolchain@nightly"]
VERSION_CHECK["rustc --version --verbose"]
FORMAT["cargo fmt --all --check"]
end
end
BUILD --> TEST
CHECKOUT --> TOOLCHAIN
CLIPPY --> BUILD
DOC_BUILD --> DEPLOY
DOC_CHECKOUT --> DOC_TOOLCHAIN
DOC_TOOLCHAIN --> DOC_BUILD
FORMAT --> CLIPPY
TOOLCHAIN --> VERSION_CHECK
VERSION_CHECK --> FORMAT
Sources: .github/workflows/ci.yml(L6 - L33) .github/workflows/ci.yml(L34 - L56)
Build Script Integration
The percpu crate includes a custom build script that handles linker configuration for testing environments:
Conditional Linker Configuration
The build script in percpu/build.rs(L1 - L10) performs platform-specific setup:
// Pseudo-code representation of build.rs logic
if target_os == "linux" && !feature("sp-naive") {
// Add custom linker script for per-CPU section testing
add_link_arg("-no-pie");
add_link_arg("-T test_percpu.x");
}
This configuration ensures:
- Position-independent execution disabled (
-no-pie) for consistent memory layout - Custom linker script (
test_percpu.x) defines.percpusection placement - Conditional application only for Linux userspace testing without naive fallback
Sources: percpu/build.rs(L4 - L8)
Dependency Management
The build system manages a carefully curated set of dependencies optimized for cross-platform compatibility:
Core Runtime Dependencies
| Crate | Version | Purpose | Platform Support |
|---|---|---|---|
| cfg-if | 1.0.0 | Conditional compilation | All platforms |
| kernel_guard | 0.1.2 | Preemption safety | no_std compatible |
| spin | 0.9.8 | Synchronization primitives | no_std compatible |
| x86 | 0.52.0 | x86-specific operations | x86_64 only |
Macro Dependencies
| Crate | Version | Purpose |
|---|---|---|
| proc-macro2 | 1.0.93 | Token manipulation |
| quote | 1.0.38 | Code generation |
| syn | 2.0.96 | AST parsing |
Sources: Cargo.lock(L61 - L78)
Documentation Generation
The build system includes automated documentation generation and deployment:
Documentation Pipeline
flowchart TD
subgraph Deployment["Deployment"]
PAGES["GitHub Pages"]
BRANCH["gh-pages Branch"]
DEPLOY_ACTION["JamesIves/github-pages-deploy-action@v4"]
end
subgraph subGraph0["Documentation Build"]
SOURCE["Source Code + Doc Comments"]
RUSTDOC["cargo doc --no-deps"]
FLAGS["RUSTDOCFLAGS Environment"]
OUTPUT["target/doc Directory"]
end
BRANCH --> PAGES
DEPLOY_ACTION --> BRANCH
FLAGS --> RUSTDOC
OUTPUT --> DEPLOY_ACTION
RUSTDOC --> OUTPUT
SOURCE --> RUSTDOC
Documentation Configuration
The documentation build uses specific flags for enhanced output:
-Zunstable-options --enable-index-page- Enables unified index page-D rustdoc::broken_intra_doc_links- Treats broken links as errors-D missing-docs- Requires documentation for all public items
Sources: .github/workflows/ci.yml(L42 - L56)
Feature-Based Build Variants
The build system supports multiple feature combinations for different deployment scenarios:
Feature Matrix
| Feature Set | Target Use Case | Platforms | Build Behavior |
|---|---|---|---|
| Default | Multi-CPU systems | Bare metal targets | Full per-CPU implementation |
| sp-naive | Single-CPU systems | Linux userspace | Global variable fallback |
| preempt | Preemption-aware | All platforms | NoPreemptGuard integration |
| arm-el2 | Hypervisor mode | AArch64 only | EL2 register usage |
Build Commands by Use Case
# Bare metal development
cargo build --target x86_64-unknown-none --features "preempt,arm-el2"
# Linux userspace testing
cargo test --target x86_64-unknown-linux-gnu --features "sp-naive"
# Documentation generation
cargo doc --no-deps
Sources: .github/workflows/ci.yml(L25 - L32)