在 Rust 中包含 CPU 个特定于体系结构的源文件

Including CPU architecture specific source files in Rust

我正在开发一个需要编译到 ARM Cortex-M 以及 ARM64 和 X86 Linux 平台的 Rust 可执行项目(音频编解码器 + 驱动程序)。我们希望拥有这样的项目结构,即目标特定代码可以放在单独的目标特定文件和目录中,而目标独立代码仅保存在一个地方。例如,我们希望顶级 main.rs 有条件地包含 arm64/main.rsthumb/main.rsx86/main.rs 文件,其中每个目标特定的 main.rs 文件可能做截然不同的事情。

我的问题是:

  1. 做这样的事情最好的方法是什么?通常,在 C/C++ 中这是微不足道的,但我不知道如何使用 cfg! 宏来做到这一点。
  2. 有没有办法直接在 Cargo.toml 中指定这些东西,而不是将它们放在 Rust 源文件中?

非常感谢任何帮助或指向执行此类操作的项目的指示。

您可以对任何内容使用 #[cfg(...)] 属性,包括函数、模块和单个代码块。

最简单的方法是在一个文件中创建多个 main 函数,每个函数都有一个 #[cfg(...)] 属性。 The reference 有大量您可以使用的配置选项。

#[cfg(target_arch = "x86_64")]
fn main() {
    println!("Hello from x86_64");
}

#[cfg(target_arch = "arm")]
fn main() {
    println!("Hello from ARM");
}

但是你问的是多个文件。在 Rust 中,每个文件都是一个模块,您可以将相同的 cfg 属性附加到模块声明中。例如,您可能有两个特定于架构的文件:

// main_x86_64.rs
pub fn main() {
    println!("Hello from x86_64");
}
// main_arm.rs
pub fn main() {
    println!("Hello from ARM");
}

然后,在真正的主函数中,有条件地编译其中一个,有条件地调用一个主函数或另一个。

// main.rs

#[cfg(target_arch = "x86_64")]
mod main_x86_64;

#[cfg(target_arch = "arm")]
mod main_arm;

#[cfg(target_arch = "x86_64")]
fn main() {
    main_x86_64::main();
}

#[cfg(target_arch = "arm")]
fn main() {
    main_arm::main();
}

如果您正在寻找更广泛的模式,我会向您指出 core 组织特定于平台的内容的方式。有一个 arch module that conditionally compiles in each platform's submodule on just that platform. You can see in the source code 每个子模块都有一个 cfg 属性,因此它只能在该平台上编译。