Closed
Description
With -Zbindeps
, if there is a dependency that is used as a binary artifact, and also as a normal dependency, the build script for that shared dependency is receiving the wrong features.
In the following example, common
gets built twice, once as the target bindep with feature f2, and once as a normal dependency with feature f1. However, the build script only has CARGO_FEATURE_F1
set in both cases.
#[cargo_test]
fn build_script_features_for_shared_dependency() {
// When a build script is built and run, its features should match. Here:
//
// foo
// -> artifact on d1 with target
// -> common with features f1
//
// d1
// -> common with features f2
//
// common has features f1 and f2, with a build script.
//
// When common is built as a dependency of d1, it should have features
// `f2` (for the library and the build script).
//
// When common is built as a dependency of foo, it should have features
// `f1` (for the library and the build script).
if cross_compile::disabled() {
return;
}
let target = cross_compile::alternate();
let p = project()
.file(
"Cargo.toml",
&r#"
[project]
name = "foo"
version = "0.0.1"
resolver = "2"
[dependencies]
d1 = { path = "d1", artifact = "bin", target = "$TARGET" }
common = { path = "common", features = ["f1"] }
"#
.replace("$TARGET", target),
)
.file(
"src/main.rs",
r#"
fn main() {
let _b = include_bytes!(env!("CARGO_BIN_FILE_D1"));
common::f1();
}
"#,
)
.file(
"d1/Cargo.toml",
r#"
[package]
name = "d1"
version = "0.0.1"
[dependencies]
common = { path = "../common", features = ["f2"] }
"#,
)
.file(
"d1/src/main.rs",
r#"fn main() {
common::f2();
}"#,
)
.file(
"common/Cargo.toml",
r#"
[package]
name = "common"
version = "0.0.1"
[features]
f1 = []
f2 = []
"#,
)
.file(
"common/src/lib.rs",
r#"
#[cfg(feature = "f1")]
pub fn f1() {}
#[cfg(feature = "f2")]
pub fn f2() {}
"#,
)
.file(
"common/build.rs",
&r#"
use std::env::var_os;
fn main() {
if std::env::var("TARGET").unwrap() == "$TARGET" {
assert!(var_os("CARGO_FEATURE_F1").is_none());
assert!(var_os("CARGO_FEATURE_F2").is_some());
} else {
assert!(var_os("CARGO_FEATURE_F1").is_some());
assert!(var_os("CARGO_FEATURE_F2").is_none());
}
assert_eq!(var_os("CARGO_FEATURE_F1").is_some(), cfg!(feature="f1"));
assert_eq!(var_os("CARGO_FEATURE_F2").is_some(), cfg!(feature="f2"));
}
"#
.replace("$TARGET", target),
)
.build();
p.cargo("build -Z bindeps")
.masquerade_as_nightly_cargo()
.run();
}
cc @Byron