Build Configuration and Dependencies
Relevant source files
Purpose and Scope
This document details the build configuration and dependency management aspects of the axsignal crate. It explains how the crate is configured for different target architectures, its external dependencies, build-time configuration mechanisms, and integration with the ArceOS ecosystem. For information about the signal handling implementation details, refer to Signal Management System and Architecture Support.
Dependency Structure
The axsignal crate is designed with carefully selected dependencies to provide Unix-like signal handling functionality within the ArceOS framework.
flowchart TD
subgraph subGraph2["Patched Dependencies"]
page_table_multiarch["page_table_multiarch"]
page_table_entry["page_table_entry"]
end
subgraph subGraph1["ArceOS Dependencies"]
axconfig["axconfig"]
axhal["axhal (with uspace feature)"]
axtask["axtask (with multitask feature)"]
end
subgraph subGraph0["Core Dependencies"]
axerrno["axerrno (0.1.0)"]
bitflags["bitflags (2.6)"]
cfg_if["cfg-if (1.0.0)"]
linux_raw_sys["linux-raw-sys (0.9.3)"]
log["log (0.4)"]
strum_macros["strum_macros (0.27.1)"]
lock_api["lock_api (0.4.12)"]
derive_more["derive_more (2.0.1)"]
end
axsignal["axsignal Crate"]
axhal --> page_table_entry
axhal --> page_table_multiarch
axsignal --> axconfig
axsignal --> axerrno
axsignal --> axhal
axsignal --> axtask
axsignal --> bitflags
axsignal --> cfg_if
axsignal --> derive_more
axsignal --> linux_raw_sys
axsignal --> lock_api
axsignal --> log
axsignal --> strum_macros
Diagram: Dependency Structure of axsignal Crate
Sources: Cargo.toml(L6 - L26)
Standard Dependencies
The axsignal crate relies on several standard Rust crates:
| Dependency | Version | Purpose |
|---|---|---|
| axerrno | 0.1.0 | Provides error code definitions for system calls |
| bitflags | 2.6 | Used for creating type-safe bit flags (e.g., signal sets) |
| cfg-if | 1.0.0 | Simplifies conditional compilation |
| linux-raw-sys | 0.9.3 | Provides low-level Linux system call definitions |
| log | 0.4 | Logging functionality |
| strum_macros | 0.27.1 | Used for enum string conversions |
| lock_api | 0.4.12 | Abstractions for synchronization primitives |
| derive_more | 2.0.1 | Additional derive macros for common traits |
The linux-raw-sys dependency is configured with default-features = false and explicitly enables the general and no_std features, ensuring compatibility with the no_std environment of ArceOS.
Sources: Cargo.toml(L6 - L26)
ArceOS Dependencies
The crate integrates with ArceOS through the following dependencies:
| Dependency | Features | Purpose |
|---|---|---|
| axconfig | (none) | Configuration constants and parameters from ArceOS |
| axhal | uspace | Hardware abstraction layer with userspace support |
| axtask | multitask | Task/thread management system |
These dependencies are sourced directly from the ArceOS GitHub repository:
axconfig = { git = "https://github.com/oscomp/arceos.git" }
axhal = { git = "https://github.com/oscomp/arceos.git", features = ["uspace"] }
axtask = { git = "https://github.com/oscomp/arceos.git", features = ["multitask"] }
Sources: Cargo.toml(L10 - L14)
Dependency Patches
The axsignal crate applies patches to two dependencies:
[patch.crates-io]
page_table_multiarch = { git = "https://github.com/Mivik/page_table_multiarch.git", rev = "19ededd" }
page_table_entry = { git = "https://github.com/Mivik/page_table_multiarch.git", rev = "19ededd" }
These patches ensure compatibility with the specific memory management requirements of ArceOS by using patched versions of the page table libraries.
Sources: Cargo.toml(L28 - L30)
Architecture-Specific Build Configuration
The axsignal crate is designed to support multiple CPU architectures, with different implementation details for each. The build system automatically configures the appropriate architecture-specific code based on the target platform.
flowchart TD
subgraph subGraph2["Implementation Files"]
arch_mod["arch/mod.rs"]
x86_64_impl["arch/x86_64.rs"]
aarch64_impl["arch/aarch64.rs"]
riscv_impl["arch/riscv.rs"]
loongarch64_impl["arch/loongarch64.rs"]
end
subgraph subGraph1["Supported Architectures"]
x86_64["x86_64"]
x86["x86"]
powerpc["powerpc"]
powerpc64["powerpc64"]
s390x["s390x"]
arm["arm"]
aarch64["aarch64"]
other["Other Architectures"]
end
subgraph subGraph0["Architecture-Specific Config"]
sa_restorer_cfg["sa_restorer cfg flag"]
end
build_rs["build.rs"]
target["CARGO_CFG_TARGET_ARCH"]
aarch64 --> sa_restorer_cfg
arch_mod --> aarch64_impl
arch_mod --> loongarch64_impl
arch_mod --> riscv_impl
arch_mod --> x86_64_impl
arm --> sa_restorer_cfg
build_rs --> target
other --> sa_restorer_cfg
powerpc --> sa_restorer_cfg
powerpc64 --> sa_restorer_cfg
s390x --> sa_restorer_cfg
sa_restorer_cfg --> arch_mod
target --> sa_restorer_cfg
x86 --> sa_restorer_cfg
Diagram: Architecture-Specific Build Configuration
Sources: build.rs(L1 - L25)
The sa_restorer Configuration
The build.rs script creates a configuration flag called sa_restorer that is enabled only for specific architectures. This flag is used to conditionally compile code that handles the signal return trampoline mechanism:
fn main() {
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
alias(
"sa_restorer",
[
"x86_64",
"x86",
"powerpc",
"powerpc64",
"s390x",
"arm",
"aarch64",
]
.contains(&target_arch.as_str()),
);
}
The sa_restorer feature is architecture-dependent because only certain architectures support or require a dedicated signal return trampoline. This configuration flag allows the signal handling implementation to adapt to the specifics of each architecture.
Sources: build.rs(L1 - L15)
Build Script Helper Function
The build script uses a helper function called alias to create the configuration flag:
#![allow(unused)] fn main() { fn alias(alias: &str, has_feature: bool) { println!("cargo:rustc-check-cfg=cfg({alias})"); if has_feature { println!("cargo:rustc-cfg={alias}"); } } }
This function:
- Declares the existence of the configuration option via
cargo:rustc-check-cfg - Conditionally enables the configuration via
cargo:rustc-cfg
Sources: build.rs(L18 - L25)
Conditional Compilation Structure
The axsignal crate makes extensive use of Rust's conditional compilation features to adapt to different environments and architectures. This approach allows the code to maintain compatibility with multiple platforms while minimizing redundancy.
flowchart TD
subgraph subGraph2["Conditional Code Paths"]
sa_restorer_code["Signal Restorer Logic"]
arch_specific["Architecture-Specific Signal Context"]
common_code["Common Signal Code"]
end
subgraph subGraph1["Architecture Implementations"]
x86_64_impl["x86_64 Implementation"]
aarch64_impl["aarch64 Implementation"]
riscv_impl["RISC-V Implementation"]
loongarch_impl["LoongArch64 Implementation"]
end
subgraph subGraph0["Compilation Conditions"]
target_arch["Target Architecture"]
sa_restorer["sa_restorer Feature"]
feature_flags["Feature Flags"]
end
crate["axsignal Crate"]
build["build.rs"]
aarch64_impl --> arch_specific
arch_specific --> common_code
build --> sa_restorer
crate --> target_arch
loongarch_impl --> arch_specific
riscv_impl --> arch_specific
sa_restorer --> sa_restorer_code
target_arch --> aarch64_impl
target_arch --> loongarch_impl
target_arch --> riscv_impl
target_arch --> x86_64_impl
x86_64_impl --> arch_specific
Diagram: Conditional Compilation Structure
Sources: build.rs(L1 - L25) Cargo.toml(L6 - L26)
Target Architecture Selection
The cfg-if crate is used throughout the codebase to selectively include architecture-specific implementations based on the target architecture. For example, in the arch/mod.rs file, different architecture-specific modules would be conditionally included:
cfg_if::cfg_if! {
if #[cfg(target_arch = "x86_64")] {
mod x86_64;
pub use self::x86_64::*;
} else if #[cfg(target_arch = "aarch64")] {
mod aarch64;
pub use self::aarch64::*;
} else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] {
mod riscv;
pub use self::riscv::*;
} else if #[cfg(target_arch = "loongarch64")] {
mod loongarch64;
pub use self::loongarch64::*;
} else {
compile_error!("Unsupported target architecture");
}
}
This pattern ensures that only the appropriate architecture-specific code is compiled into the final binary.
Sources: Cargo.toml(L16)
The sa_restorer Configuration
The sa_restorer configuration flag created by the build script enables conditional compilation of code related to the signal restoration mechanism. In architectures that support sa_restorer, the signal action structure will include an additional field for the restorer function pointer.
For example, code using this flag might look like:
pub struct SignalOSAction {
pub handler: usize,
pub flags: SaFlags,
pub mask: SignalSet,
#[cfg(sa_restorer)]
pub restorer: usize,
}
This conditional field ensures that the signal action structure is correctly defined for each supported architecture.
Sources: build.rs(L1 - L15)
Integration with ArceOS
The axsignal crate is designed to integrate seamlessly with the ArceOS operating system kernel. This integration is facilitated by the dependency specifications in the Cargo.toml file and the design of the signal handling interfaces.
flowchart TD
subgraph subGraph1["axsignal Integration"]
axsignal["axsignal Crate"]
managers["Signal Managers"]
arch_support["Architecture Support"]
signal_types["Signal Types"]
end
subgraph subGraph0["ArceOS Ecosystem"]
arceos["ArceOS Kernel"]
axconfig["axconfig"]
axhal["axhal"]
axtask["axtask"]
other_modules["Other ArceOS Modules"]
end
arceos --> axconfig
arceos --> axhal
arceos --> axsignal
arceos --> axtask
arceos --> other_modules
axhal --> arch_support
axsignal --> axconfig
axsignal --> axhal
axsignal --> axtask
axtask --> managers
Diagram: Integration with ArceOS Ecosystem
Sources: Cargo.toml(L10 - L14)
Dependency on axhal
The axhal dependency is included with the uspace feature enabled:
axhal = { git = "https://github.com/oscomp/arceos.git", features = ["uspace"] }
This dependency provides the hardware abstraction layer functionalities required for signal handling, such as:
- Access to trap frames and CPU context management
- Architecture-specific operations for signal handling
- Userspace support for delivering signals to user applications
The uspace feature specifically enables the userspace support components in axhal that are necessary for implementing signal handling in a user/kernel separated environment.
Sources: Cargo.toml(L11)
Dependency on axtask
The axtask dependency is included with the multitask feature enabled:
axtask = { git = "https://github.com/oscomp/arceos.git", features = ["multitask"] }
This dependency provides the task/thread management system that axsignal uses to:
- Associate signal handlers with specific threads
- Manage signal delivery to the appropriate targets
- Coordinate the execution and scheduling of signal handlers
The multitask feature ensures that proper thread management capabilities are available, which is essential for implementing per-thread signal handling.
Sources: Cargo.toml(L12 - L14)
Dependency on axconfig
The axconfig dependency contains ArceOS configuration constants and parameters:
axconfig = { git = "https://github.com/oscomp/arceos.git" }
This dependency provides configuration settings that affect signal handling behavior, such as:
- Maximum number of concurrent signals
- Sizes of signal-related buffers
- System-wide constants affecting signal delivery
Sources: Cargo.toml(L10)
Build-Time Configuration Summary
The following table summarizes the key build-time configuration aspects of the axsignal crate:
| Configuration Aspect | Mechanism | Purpose |
|---|---|---|
| Architecture Support | Target architecture detection | Select appropriate architecture-specific implementation |
| sa_restorer Feature | build.rs script | Enable/disable restorer functionality based on architecture |
| ArceOS Integration | Git dependencies | Connect with other ArceOS components |
| Feature Flags | Cargo features | Enable specific functionality (e.g., uspace, multitask) |
| Dependency Patching | Cargo [patch] section | Ensure compatibility with specific dependency versions |
Sources: build.rs(L1 - L25) Cargo.toml(L1 - L31)
Conclusion
The build configuration and dependency management of the axsignal crate are designed to support a flexible, cross-architecture signal handling implementation that integrates seamlessly with the ArceOS ecosystem. The crate uses conditional compilation extensively to adapt to different target architectures while maintaining a clean and maintainable codebase.
The build script provides architecture-specific configurations, while carefully selected dependencies enable the crate to leverage existing ArceOS components for tasks such as thread management and hardware abstraction. This approach allows axsignal to provide Unix-like signal handling capabilities across multiple architectures with minimal redundancy and maximum compatibility.