I want to conditionally enable run-time checks and logging, independently from each other and from debug and release mode. So I've started adding two features to my project, one called "invariant-checking" and one called "logging". Ultimately i want their use to be through macros I define in a crate which is visible project-wide.
I had assumed that if I filled out the features section the same way in all of the crates the same way then when I activated the feature while compiling the bin crate, then all the lib crates would also have the feature enabled, but this is not the case! How can I enable and disable features across multiple crates? Hopefully this can be done by only changing one thing like the command-line arguments to cargo.
To clarify exactly what I want, here's an example, which I will also reproduce below:
There are three crates, the main, bin, crate, and two lib crates, called "middle" and "common". Here are the relevant parts of the relevant files:
main.rs
extern crate common;
extern crate middle;
fn main() {
common::check!();
middle::run();
println!("done");
}
the main Cargo.toml
[dependencies]
[dependencies.common]
path = "libs/common"
[dependencies.middle]
path = "libs/middle"
[features]
default = []
invariant-checking = []
logging = []
middle's lib.rs
extern crate common;
pub fn run() {
common::check!();
common::run();
}
middle's Cargo.toml
[dependencies]
[dependencies.common]
path = "../common"
[features]
default = []
invariant-checking = []
logging = []
common's lib.rs
#[macro_export]
macro_rules! check {
() => {{
if cfg!(feature = "invariant-checking") {
println!("invariant-checking {}:{}", file!(), line!());
}
if cfg!(feature = "logging") {
println!("logging {}:{}", file!(), line!());
}
}};
}
pub fn run() {
check!()
}
and finally common's Cargo.toml
[dependencies]
[features]
default = []
invariant-checking = []
logging = []
When i run cargo run --features "invariant-checking,logging"
I get the following output
invariant-checking src\main.rs:5
logging src\main.rs:5
done
but want it to log in middle and common as well. How can I transform this project such that it will do that, and still allow me to get only "done" as output by changing only one place?