You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It appears that cargo regressed on #4866 -- when a dependency exists as both a build-dependency and normal dependency, but they use different features, the features are unified. The documentation around features explicitly states otherwise:
The version "2" resolver avoids unifying features in a few situations where that unification can be unwanted. The exact situations are described in the resolver chapter, but in short, it avoids unifying in these situations:
Build-dependencies and proc-macros do not share features with normal dependencies.
Dev-dependencies do not activate features unless building a target that needs them (like tests or examples).
Avoiding the unification is necessary for some situations. For example, if a build-dependency enables a std feature, and the same dependency is used as a normal dependency for a no_std environment, enabling std would break the build.
fn main() {
println!("Hello from foo");
bar::lib();
}
crates/foo/Cargo.toml
[package]
name = "foo"
version = "0.1.0"
[dependencies]
bar.path = "../bar"
[build-dependencies]
bar = { path = "../bar", features = ["build_feature"] }
crates/bar/src/lib.rs
pub fn lib() {
println!("Hello from bar");
#[cfg(feature = "build_feature")]
println!(" bar build_feature on!");
}
crates/bar/Cargo.toml
[package]
name = "bar"
version = "0.1.0"
[features]
build_feature = []
Cargo.toml
[workspace]
members = ["crates/*"]
Build the workspace: cargo build
Run the foo binary: ./target/debug/foo
Expected Result:
Hello from foo
Hello from bar
Actual Result:
Hello from foo
Hello from bar
bar build_feature on!
Reproducer 2
The above is a simplified version of what I found was happening in our code base. Just in case there's a difference I'm not aware of, the specific issue I noticed in our code base was structured as follows:
foo has a featured called "build_feature".
foo has a dev-dependency of bar.path = "../bar"
bar has a build-dependency of foo = { path = "../foo", features["build_feature"] }
Running cargo test -p foo builds foo's tests with "build_feature" enabled.
crates/foo/src/lib.rs
pub fn lib() {
println!("Hello from foo");
#[cfg(feature = "build_feature")]
panic!("foo build_feature on!");
}
#[cfg(test)]
mod test {
#[test]
fn basic() {
bar::lib();
super::lib();
}
}
crates/foo/Cargo.toml
[package]
name = "foo"
version = "0.1.0"
[features]
build_feature = []
[dev-dependencies]
bar.path = "../bar"
crates/bar/src/lib.rs
pub fn lib() {
println!("Hello from bar");
}
crates/bar/Cargo.toml
[package]
name = "bar"
version = "0.1.0"
[build-dependencies]
foo = { path = "../foo", features = ["build_feature"] }
Cargo.toml
[workspace]
members = ["crates/*"]
Expected Result:
<test succeeds>
Actual Result:
---- test::basic stdout ----
Hello from bar
Hello from foo
thread 'test::basic' panicked at 'foo build_feature on!', crates/foo/src/lib.rs:4:5
Possible Solution(s)
No response
Notes
No response
Version
$ cargo version --verbose
cargo 1.71.1 (7f1d04c00 2023-07-29)
release: 1.71.1
commit-hash: 7f1d04c0053083b98fa50b69b6f56e339b0556a8
commit-date: 2023-07-29
host: aarch64-apple-darwin
libgit2: 1.6.4 (sys:0.17.1 vendored)
libcurl: 7.88.1 (sys:0.4.61+curl-8.0.1 system ssl:(SecureTransport) LibreSSL/3.3.6)
ssl: OpenSSL 1.1.1t 7 Feb 2023
os: Mac OS 13.4.1 [64-bit]
The text was updated successfully, but these errors were encountered:
So I haven't had the chance to run this to verify but don't you need workspace.resolver = "2"?
I think this solves the issue. Is this something specific to virtual workspaces? Just confirming before closing the issue.
I had reduced the example too much. The original code-base has package.edition = "2021" in each of the member crate's Cargo.toml files. But I guess this has no effect in virtual workspaces?
Yes, and sorry for the inconvenience. We had some efforts around this, e.g. #10910 and #12388. Please read the doc here and here for more.
The resolver is a global option that affects the entire workspace. The resolver version in dependencies is ignored, only the value in the top-level package will be used. If using a virtual workspace, the version should be specified in the [workspace] table, for example:
Problem
It appears that cargo regressed on #4866 -- when a dependency exists as both a build-dependency and normal dependency, but they use different features, the features are unified. The documentation around features explicitly states otherwise:
Steps
Reproducer 1
<directory layout>
crates/foo/src/main.rs
crates/foo/Cargo.toml
crates/bar/src/lib.rs
crates/bar/Cargo.toml
Cargo.toml
cargo build
foo
binary:./target/debug/foo
Expected Result:
Actual Result:
Reproducer 2
The above is a simplified version of what I found was happening in our code base. Just in case there's a difference I'm not aware of, the specific issue I noticed in our code base was structured as follows:
foo
has a featured called"build_feature"
.foo
has a dev-dependency ofbar.path = "../bar"
bar
has a build-dependency offoo = { path = "../foo", features["build_feature"] }
cargo test -p foo
buildsfoo
's tests with"build_feature"
enabled.crates/foo/src/lib.rs
crates/foo/Cargo.toml
crates/bar/src/lib.rs
crates/bar/Cargo.toml
Cargo.toml
Expected Result:
Actual Result:
Possible Solution(s)
No response
Notes
No response
Version
The text was updated successfully, but these errors were encountered: