Search code examples
rustrust-cargo

cargo build sees my cfg() in the code but not in my Cargo.toml causing unresolved import


I want a dependency that only exists when my special cfg is enabled.

Simple example project:
main.rs:

fn main() {
    test()
}

#[cfg(my_cfg)]
fn test() {
    use inotify::Inotify;
    println!("my_cfg is enabled")
}

#[cfg(not(my_cfg))]
fn test() {
    println!("my_cfg is not enabled")
}

build.rs:

use std::env;
fn main() {
    println!("cargo:rerun-if-env-changed=MYENV");
    if let Ok(config) = env::var("MYENV"){
        match config.as_str() {
            "my_cfg"=>println!("cargo:rustc-cfg=my_cfg"), 
            _=>{}
        }
    }
}

Cargo.toml:

[package]
name = "hello"
version = "0.1.0"
edition = "2021"

[target.'cfg(my_cfg)'.dependencies]
inotify = "0.10.2"

when I run:

cargo run

I get my expected output of:

"my_cfg is not enabled"

But when I run:

MYENV=my_cfg cargo run

I will get an unresolved import 'inotify' error:

error[E0432]: unresolved import `inotify`
 --> src/main.rs:7:9
  |
7 |     use inotify::Inotify;
  |         ^^^^^^^ use of undeclared crate or module `inotify`

For more information about this error, try `rustc --explain E0432`.
error: could not compile `hello` (bin "hello") due to previous error

This means that in my main.rs the right version of the test function was selected i.e. my_cfg is enabled.
But in my Cargo.toml my dependency is not recognized.

When I run cargo build with the --verbose option to see the rustc call I can see the --cfg my_cfg in there.

What is going on here?
I believe I'm doing this right if I read the documentation:
https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html

edit:

Okay so I have learned I cannot use custom cfgs in Cargo.toml, is there any other way I can change the dependencies from a build.rs file?


Solution

  • I found how I can do it, I can use the RUSTFLAGS environment variable to feed custom cfg options to dependencies lower down the chain.

    So in this case build with the command:

    RUSTFLAGS="--cfg my_cfg" cargo build
    

    And then it works!