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) and percpu_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 PlatformTest EnvironmentFeature SetSpecial Requirements
x86_64-unknown-linux-gnuUbuntu 22.04sp-naive+ defaultUnit tests enabled
x86_64-unknown-noneUbuntu 22.04preempt,arm-el2Bare metal
riscv64gc-unknown-none-elfUbuntu 22.04preempt,arm-el2Bare metal
aarch64-unknown-none-softfloatUbuntu 22.04preempt,arm-el2Bare metal
loongarch64-unknown-none-softfloatUbuntu 22.04preempt,arm-el2Bare 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 .percpu section 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

CrateVersionPurposePlatform Support
cfg-if1.0.0Conditional compilationAll platforms
kernel_guard0.1.2Preemption safetyno_std compatible
spin0.9.8Synchronization primitivesno_std compatible
x860.52.0x86-specific operationsx86_64 only

Macro Dependencies

CrateVersionPurpose
proc-macro21.0.93Token manipulation
quote1.0.38Code generation
syn2.0.96AST 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 SetTarget Use CasePlatformsBuild Behavior
DefaultMulti-CPU systemsBare metal targetsFull per-CPU implementation
sp-naiveSingle-CPU systemsLinux userspaceGlobal variable fallback
preemptPreemption-awareAll platformsNoPreemptGuard integration
arm-el2Hypervisor modeAArch64 onlyEL2 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)