Support the `[features]` section in virtual manifests
twistezo opened this issue · 18 comments
I have project structure:
+---workspace_a
¦ ¦ Cargo.toml
¦ ¦
¦ +---src
¦ lib.rs
¦ Cargo.lock
¦ Cargo.toml
Main manifest ./Cargo.toml
:
[workspace]
members = ["workspace_a"]
[dependencies.workspace_a]
path = "./workspace_a"
[features]
only_a = [
"workspace_a/only_a"
]
Workspace manifest ./workspace_a/Cargo.toml
:
[package]
name = "workspace_a"
version = "0.1.0"
authors = ["author.com"]
[features]
only_a = []
And ./workspace_a/lib.rs
:
#[test]
fn test_a() {
assert_eq!(1, 1);
}
#[cfg(not(feature = "only_a"))]
#[test]
fn test_b() {
assert_eq!(1, 1);
}
When i'm in root and trying cargo test --all --features only_a
virtual manifest doesn't see feature in my workspace.
It's working when i'm in ./workspace_a/
or when main manifest it's not virtual.
Thanks for the report! Unfortunately though the [features]
section doesn't work in Cargo.toml
as a virtual manifest (without a [package]
section, but we should probably warn about this!
@alexcrichton any hope in future about this improvement ?
@twistezo I'll tag it as a feature request.
I have a different issue, that fits under this as an ‘umbrella issue’. Given these conditions:
- The current working directory is the virtual workspace directory.
- The virtual workspace has a crate member.
- The crate member defines an executable in
[[bin]]
in the crate Cargo manifest. - That executable requires a feature defined in the crate Cargo manifest.
Then this fails:
cargo run --package crate --bin other_executable --features other_executable_feature
error: target `other_executable` requires the features: `other_executable_feature`
Consider enabling them by passing e.g. `--features="other_executable_feature"`
Whereas this succeeds:
cargo run --package crate --bin other_executable --all-features
As well as this:
cd "${virtual_workspace_directory:?}" &&
cargo run --package crate --bin other_executable --features other_executable_feature
Any updates on this?
@Michel-Haber it's unclear what semantics exactly [features]
section in the virtual manifest should have, and what exact problems that should solve. So, the "feature request" part of it is in "needs design" phase. AFAIK, nobody is working on it.
As for "--features
flag has unexpected behavior with workspaces", we've tried to fix it in #5364, but that unfortunately broke code in the wild.
@matklad It seems reasonable to me for a workspace to be able to specify its features as re-exports of package features. i.e:
[features]
wsfeature = ["package1/feature1", "package2/feature2"]
A logical link may or may not exist between feature1 and feature2, but this allows for a cleaner selection of features for a set of projects, and, in its simplest form, would simply be a re-export of a package's feature.
This also fixes the unexpected behaviour of --features flag, since it becomes tied to the workspace itself, and not its packages.
This meant I wasted a bit of time today, so I linked the PR above. I just went with the --manifest-path
workaround for now. That said I would have expected cargo build --features="codespan"
to warn, and cargo build --features="moniker/codespan"
to 'just work'.
Please add a warning, so other poeple know about this, that would've saved me a couple of hours.
I also encountered this as part of brendanzab/codespan#31.
At a glance, it seems like @Michel-Haber's solution of having top-level feature flags which can enable specific crate features seems to be the most intuitive. What would be required to get the ball rolling on this?
There's some more information about this in #5849, notably how we tried to fix this but ended up being unable to because it's technically a breaking change.
Is it possible to allow us to 'opt in' to this, by allowing us to explicitly forward features in virtual manifests?
[workspace]
members = [
"./codespan",
"./codespan-reporting",
"./codespan-lsp",
]
[features]
"codespan/memory_usage" = ["codespan/memory_usage"]
"codespan-reporting/memory_usage" = ["codespan-reporting/memory_usage"]
It's not pretty, but it would at least clean up the icky workarounds we have to do when working with workspaced crates, and also allow us to set these features in the RLS config (which is not currently possible). I don't know if this would make future fixes more difficult though.
Would also be super nice to provide a warning when trying to use features without this explicit forwarding as well.
@alexcrichton One way of following the solution of top-level feature flags without introducing breaking change would be to actually ignore the feature flags if a features section is not present in the workspace toml file. If one is present but not well defined or used, this is a syntax error.
I rewrote @brendanzab 's proposition to show a more general approach to this:
[workspace]
members = [
"./crate1",
"./crate2",
"./crate3",
]
[features]
"feature1" = ["crate1/feature1", "crate2/feature1", "crate2/feature2"]
"feature2" = ["crate3/feature1"]
This can be used with:
cargo build --features "feature1"
But seeing as silently ignoring feature flags cannot be reasonably considered a feature but rather a bug, one can argue that any breakage, like the one caused by #5390 is in fact due to a bug fix!
Oh yes indeed! The previous fix may have been too big a hammer and I'd definitely believe it's possible to solve this without breaking crates. I don't personally (nor do I think @matklad) has time to work on this right now, but we can certainly help review PRs to finish implementing this!
@sanmai-NL I think your issue (and mine) are distinct from this, as it does not include a [feature]
specification in the workspace root Cargo.toml
. Maybe file a new issue?
I slightly object to adding [features]
only for acting as a convenient alias in virtual manifest. Some thoughts:
- Virtual manifests never be published to crates.io. If we ever get feature metadata RFC merged and implemented, what is the semantic of them in virtual manifest? I don't want a
[features]
section overloading with different meanings, which may exacerbate the already-complicated feature resolution. - This can somehow be done with
[alias]
section in.cargo/config.toml
, though[alias]
doesn't support variable interpolation so it is not an 100% substitution. We may want to work on that instead. - With
-Zpackage-features
stabilized as resolver v2 in 1.51, the need of forwarding features from virual manifests is resolved. - If two member packages have a feature under the same name
my-feat
, runningcargo build --features my-feat
enablesmy-feat
for the two packages. That's a new CLI behavior of-Zpackage-features
largely meeting the need of supporting[features]
in virtual manifest IMO. - FWIW, Cargo already have an error rejecting
[features]
in virtual manifests #6276
If there is anything that only a [features]
section of virtual manifests can achieve I am not aware of, please speak!
Based on the above, I actually propose to the cargo team that we close this.
Go ahead and close this. Please let us know if there is something wrong.