Reputation: 31
I'm working on a Rust executable project (audio codec + driver) that needs to compile to ARM Cortex-M, as well as ARM64 and X86 Linux platforms. We would like to have the project structure such that target specific code can be put in separate target specific files and directories, while target independent code kept in only one place. For example, we would like the top level main.rs
to conditionally include arm64/main.rs
, thumb/main.rs
, and x86/main.rs
files, where each target specific main.rs
file is likely to do vastly different things.
My questions are:
C/C++
this is trivial, but I don't know how to do this using cfg!
macros.Cargo.toml
instead of having them in Rust source files?Any help, or pointers to projects that do this sort of thing is highly appreciated.
Upvotes: 2
Views: 1163
Reputation: 1101
You can use the #[cfg(...)]
attribute on anything, including functions, modules, and individual blocks of code.
The simplest way would be to create several main
functions in one file, where each has a #[cfg(...)]
attribute on it. The reference has a big list of configuration options you can use.
#[cfg(target_arch = "x86_64")]
fn main() {
println!("Hello from x86_64");
}
#[cfg(target_arch = "arm")]
fn main() {
println!("Hello from ARM");
}
But you asked about multiple files. In Rust, each file is a module, and you can attach the same cfg
attribute to the module declaration. For example, you might have two arch-specific files:
// main_x86_64.rs
pub fn main() {
println!("Hello from x86_64");
}
// main_arm.rs
pub fn main() {
println!("Hello from ARM");
}
Then, in the real main function, conditionally compile one of them in and conditionally call one main function or the other.
// 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();
}
If you're looking for a broader pattern, I'd point you to the way core
organizes platform-specific things. There's an arch
module that conditionally compiles in each platform's submodule on just that platform. You can see in the source code that there's a cfg
attribute for each submodule so that it only gets compiled in on that platform.
Upvotes: 4