Issue in conditional compilation of extern crates

I'm writing a rust program (App) which uses an extern crate (VM). The VM crate itself uses another extern crate (GC). My development host is Linux, and the target is x86_64-rumprun-netbsd.

I build App using the following command:
'cargo build --target=x86_64-rumprun-netbsd'

But the target is not automatically passed to extern crates. So, to import VM in my app, I use the following in Cargo.toml:

[dependencies.VM]
path = "../../../VM"
target = "x86_64-rumprun-netbsd"

And then in VM, I use the following to pass the target to GC:

[target.x86_64-rumprun-netbsd.dependencies]
gc = { path = "src/gc", target = "x86_64-rumprun-netbsd"}

However the result is not completely as I expected. For the following code in build.rs of VM:

#[cfg(target_os = "linux")]
#[cfg(target_arch = "x86_64")]
fn main() {
    println!("detected linux");
...

#[cfg(all(target_os = "netbsd", target_vendor = "rumprun"))]
#[cfg(target_arch = "x86_64")]
fn main() {
    use std::path::Path;
    println!("detected rumprun-netbsd");

I receive this output:

detected linux
TARGET = Some("x86_64-rumprun-netbsd")
OPT_LEVEL = Some("0")
TARGET = Some("x86_64-rumprun-netbsd")
HOST = Some("x86_64-unknown-linux-gnu")
TARGET = Some("x86_64-rumprun-netbsd")
TARGET = Some("x86_64-rumprun-netbsd")
HOST = Some("x86_64-unknown-linux-gnu")
CC_x86_64-rumprun-netbsd = None
CC_x86_64_rumprun_netbsd = None
TARGET_CC = None
CC = Some(" gcc")
TARGET = Some("x86_64-rumprun-netbsd")
HOST = Some("x86_64-unknown-linux-gnu")
CFLAGS_x86_64-rumprun-netbsd = None
CFLAGS_x86_64_rumprun_netbsd = None
TARGET_CFLAGS = None
CFLAGS = Some("")
PROFILE = Some("debug")

It seems that the target is correctly passed to build.rs, but the conditional comilation does something esle.

Do you have any opinions?

The build.rs script is compiled for the host, which means any #[cfg] within matches the host itself as the target. Then when the build script runs, it will see the cross-compilation TARGET in its environment.

I changed the source code to:

fn main() {
    println!("detected linux");
    if cfg!(target_os = "linux"){
        println!("Linux");
    }
    else if cfg!(target_os = "netbsd") {
        println!("netbsd");
    }

But it prints:
detected linux
Again Linux
TARGET = Some("x86_64-rumprun-netbsd")

So, the TARGET for build.rs is Linux, both at compile-time and runtime.

cfg! works the same way as #[cfg]. You need to use env::var to read the TARGET dynamically.