我正在开发一个Rust可执行项目(音频编解码器+驱动程序(,该项目需要编译到ARM Cortex-m以及ARM64和X86 Linux平台。我们希望拥有这样的项目结构,即特定于目标的代码可以放在单独的特定于目标文件和目录中,而与目标无关的代码只能放在一个地方。例如,我们希望顶级main.rs
有条件地包括arm64/main.rs
、thumb/main.rs
和x86/main.rs
文件,其中每个特定于目标的main.rs
文件可能会做截然不同的事情。
我的问题是:
- 做这样的事最好的方法是什么?通常,在
C/C++
中,这是微不足道的,但我不知道如何使用cfg!
宏来实现这一点 - 有没有一种方法可以直接在
Cargo.toml
中指定这些东西,而不是在Rust源文件中指定它们
我们非常感谢任何帮助或指向做这类事情的项目的指针。
您可以对任何内容使用#[cfg(...)]
属性,包括函数、模块和单个代码块。
最简单的方法是在一个文件中创建几个main
函数,每个函数都有一个#[cfg(...)]
属性。
#[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
模块,它在每个平台的子模块中有条件地编译。您可以在源代码中看到,每个子模块都有一个cfg
属性,因此它只能在该平台上编译。