Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upbuild-dependencies and dependencies should not have features unified #4866
Comments
whitequark
added a commit
to whitequark/crc-rs
that referenced
this issue
Dec 27, 2017
alexcrichton
added
A-features
C-feature-request
labels
Dec 28, 2017
This comment has been minimized.
This comment has been minimized.
vitiral
commented
Dec 30, 2017
|
wow, I certainly would not have anticipated this (and appear to have not tested it...). Yay me! |
This comment has been minimized.
This comment has been minimized.
gnzlbg
commented
Feb 4, 2018
|
Not only dev-dependencies, features of platform-specific dependencies are also unified: With this [package]
name = "cargo_fubar"
version = "0.1.0"
authors = ["fubar <fubar@fubar.com>"]
[target.'cfg(target_os = "macos")'.dependencies]
mach = "0.1.*"
[dependencies.libc]
version = "0.2"
default-features = false
Compiling libc v0.2.36
Running `rustc --crate-name libc /foo/.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.36/src/lib.rs --crate-type lib --emit=dep-info,link -C debuginfo=2 --cfg 'feature="default"' --cfg 'feature="use_std"' -C metadata=af3eb212fae2904c -C extra-filename=-af3eb212fae2904c --out-dir /foo/projects/sideprojects/cargo_fubar/target/x86_64-unknown-linux-gnu/debug/deps --target x86_64-unknown-linux-gnu -L dependency=/foo/cargo_fubar/target/x86_64-unknown-linux-gnu/debug/deps -L dependency=/foo/cargo_fubar/target/debug/deps --cap-lints allow`Note how I have a platform-specific dependency for MacOSX which should absolutely have nothing to do with linux builds, yet Removing the platform specific dependency and recompiling for linux produces: Compiling libc v0.2.36
Running `rustc --crate-name libc /foo/.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.36/src/lib.rs --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=ebd4a22423d44421 -C extra-filename=-ebd4a22423d44421 --out-dir /foo/cargo_fubar/target/x86_64-unknown-linux-gnu/debug/deps --target x86_64-unknown-linux-gnu -L dependency=/foo/cargo_fubar/target/x86_64-unknown-linux-gnu/debug/deps -L dependency=/foo/cargo_fubar/target/debug/deps --cap-lints allow`Any workarounds? |
This comment has been minimized.
This comment has been minimized.
gnzlbg
commented
Feb 4, 2018
|
@alexcrichton I disagree about this being a feature request, I think this is a pretty severe bug in |
alexcrichton
added
C-bug
and removed
C-feature-request
labels
Feb 4, 2018
This comment has been minimized.
This comment has been minimized.
gnzlbg
commented
Feb 4, 2018
|
So I've added a test for this in PR #5007. If nobody beats me to it (and I hope somebody will) I'll either submit a new PR with a fix or add it to that PR (if it doesn't get merged). |
This comment has been minimized.
This comment has been minimized.
gnzlbg
commented
Feb 5, 2018
|
So fixing this is very hard, it looks like cargo was designed under the assumption that the features of all dependencies, dev-dependencies, target.dependencies,.... ought to be unified to be able to generate a single dependency graph for build, test, --target, etc. What I've ended up doing as a workaround is having multiple |
This comment has been minimized.
This comment has been minimized.
gnzlbg
commented
Feb 5, 2018
|
Someone should raise this with the tools team. I don't know how anybody manages to use cargo for targeting any If your crate happens to use std in any way for, for example, testing or benchmarking, chances are its always being built with std linked in, and forcing other crates to be linked with std as well :/ |
This comment has been minimized.
This comment has been minimized.
vitiral
commented
Feb 5, 2018
•
|
@gnzlbg that's an interesting workaround, however it wouldn't fix the issue if your For testing/benchmarking only could you have |
This comment has been minimized.
This comment has been minimized.
|
I think this is related to #4463. |
This was referenced Mar 9, 2018
This comment has been minimized.
This comment has been minimized.
|
Yeah this is crucial blocker for cross compilation. The solution is a huge refactor where each If it helps Haskell's Cabal has some great prior art here.
Lastly, this all becomes far more important with public dependencies, when it's required that similar public dependency edges point to the same node. Separately solution spaces are the one way to break those constraints. Also, as #4866 (comment) sadly demonstrates, the original idea that is a single solution in a [Ironically, I do think we can eventually simultaneously and cheaply type-check each crate against all possible dependencies (!!!), so perhaps this isn't so bad. Even if the lockfile contains only a few canonical plans for different platforms, we can ensure that all others will at least typecheck!] |
This comment has been minimized.
This comment has been minimized.
gnzlbg
commented
Mar 18, 2018
|
@Ericson2314 To really solve this I think that cargo would need to support a dependency graph per profile. Huge refactor is probably an understatement. We would not only need a backwards compatible mode to support old Also, this will also mean that Also, the solution might be RFC worthy :/ |
This comment has been minimized.
This comment has been minimized.
|
Uhhhh I'm not really sure what profiles are (though I think that goes for most of us), but I wouldn't really expect them to need their own graphs in general? Debug vs release should explicitly be the same thing. system test are really just binaries with a special purpose. The best example would be unit tests since they are turning the primary component (whatever it may be) into a binary. In otherwords, I think components + optimizations is a much better model than this hopelessly overloaded concept of "profiles". |
This comment has been minimized.
This comment has been minimized.
|
@gnzlbg I hope old lock files can at least be read only. |
This comment has been minimized.
This comment has been minimized.
gnzlbg
commented
Mar 19, 2018
I meant, if we are going to move Some people have requested "dev-only" features, others have requested ways to turn on/off "unstable" feature, the way to customize things in The problem we have right now is that cargo is designed towards a single dependency graph. Even if we only end up with two after fixing this, the solution should be able to handle
So the reason
I think this is a must - it's part of backwards compatibility. It is just another constraint that one needs to keep in mind when trying to fix this. |
This comment has been minimized.
This comment has been minimized.
OK yeah agreed on not hard-coding a fixed number for sure.
I've see a few those requests; IMO profiles are such a broken concept people should resubmit their requests in more general terms so we can start over.
Yeah so when we're building different binaries (bench binaries, test binaries) it makes total sense to me that we have a different dependency graph. Less clear to me is that should be built with a changed library (assuming the package isn't just binaries): arguably,
Ah sorry my "at least" would probably have been better as an "at most". I would definitely not want to support writing old |
whitequark
referenced this issue
Apr 6, 2018
Closed
Depend on a no_std compatible version of chrono #60
Pzixel
referenced this issue
Jul 16, 2018
Closed
pwasm-abi-derive is not compatible with no-std libs #54
phil-opp
referenced this issue
Jul 16, 2018
Open
Features of dependencies are enabled if they're enabled in build-dependencies; breaks no_std libs #5730
mbrubeck
referenced this issue
Aug 23, 2018
Open
Don't pass `--features` from `dev-dependencies` to `dependencies` #4664
This comment has been minimized.
This comment has been minimized.
|
This is still plenty relevant, but hasn't been prioritized in any fashion. |
stale
bot
removed
the
stale
label
Sep 15, 2018
dwijnand
added a commit
to dwijnand/cargo
that referenced
this issue
Sep 15, 2018
bors
added a commit
that referenced
this issue
Sep 15, 2018
alexcrichton
referenced this issue
Oct 4, 2018
Closed
Features of dependencies merge between different targets #6121
This comment has been minimized.
This comment has been minimized.
yaram
commented
Nov 23, 2018
|
I'm facing this issue at the moment. Would be nice if it got some attention. |
This was referenced Jan 1, 2019
This was referenced Jan 10, 2019
dwijnand
referenced this issue
Jan 20, 2019
Open
Cargo wrongly links `std` to `no_std` crate with conditional dependency on `std`, even when that dependency is not selected #6571
This was referenced Jan 27, 2019
This was referenced Jan 27, 2019
This comment has been minimized.
This comment has been minimized.
tarcieri
commented
Jan 27, 2019
•
|
I've been looking into this problem. I believe the feature resolver is here? https://github.com/rust-lang/cargo/blob/bd536c6/src/cargo/core/resolver/context.rs#L158 /// Return all dependencies and the features we want from them.
fn resolve_features<'b>(
&mut self,
parent: Option<&Summary>,
s: &'b Summary,
method: &'b Method<'_>,
) -> ActivateResult<Vec<(Dependency, Vec<InternedString>)>> {
let dev_deps = match *method {
Method::Everything => true,
Method::Required { dev_deps, .. } => dev_deps,
};
// First, filter by dev-dependencies
let deps = s.dependencies();
let deps = deps.iter().filter(|d| d.is_transitive() || dev_deps);
let reqs = build_requirements(s, method)?;
let mut ret = Vec::new();
let mut used_features = HashSet::new();
let default_dep = (false, Vec::new());
// Next, collect all actually enabled dependencies and their features.
for dep in deps {
[...]
}
[...]
}If this is the correct resolver, it does appear to unilaterally incorporate the |
This comment has been minimized.
This comment has been minimized.
|
I think that is correct, specifically that code is looking at all features that are activated for that Summary then filtering out all dev dependencies of transitive crates. I think this is a request that this dependency get built more then once. I think there are deeper structural problems that will have to be worked out to make this happen. There are lots of things that assume that the "list of things to build" can be indexed by |
This comment has been minimized.
This comment has been minimized.
|
It's not just the code. There are high-level design decisions to be made. I'm not yet convinced just separating dev-dependencies is the right direction. Some projects specifically want features to be unified (rustc-workspace-hack). I'm also concerned that will break existing projects. There are a variety of issues with features and dependency unification, and I think it would be best to have a picture of what it should ultimately look like before attacking it piecemeal. |
This comment has been minimized.
This comment has been minimized.
tarcieri
commented
Jan 27, 2019
•
|
The biggest issue at hand is this is an extremely confusing failure mode for dalek-cryptography/curve25519-dalek#187 (comment) Where in other cases spurious feature activation wouldn't matter, Concretely the following would make sense to me:
The first issue is exceedingly common with tools like The second issue pops up frequently when Either way this is a nightmare for both |
This comment has been minimized.
This comment has been minimized.
tarcieri
commented
Jan 27, 2019
•
I got lost trying to trace how this all works, but something I've been wondering about is how cargo workspaces provide a common dependency resolution in Cargo.lock, but are able to activate specific dependencies and features per package within the workspace. Could |
This comment has been minimized.
This comment has been minimized.
|
I could have sworn I'd already written up instructions for how this might be tackled at a high level, but I can't seem to find them now. Regardless both @Eh2406 and @ehuss are right. This is a pretty deep change to how Cargo works and doesn't have a targeted fix (trust me, if we could think of an easy fix after this many years we would have implemented it). This is also a pretty big change to Cargo and needs to be considered carefully and measured for its impact on the ecosystem. I personally believe, however, that we need to do all we can to close out this an related issues. I'm a fan of a model where dependency edges activate features but only within the context of a particular target. After resolution, when we're actually building crates, we'd enable features only for a particular target and that would produce the desired behavior here. Now that I'm thinking about this @ehuss didn't you have an excellent writeup about this somewhere as well? We may want to invest a bit of time deduplicating all these issues... |
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton Perhaps you're thinking of #5730 (comment) and rust-lang/crates-io-cargo-teams#13 (comment)? I have categorized all the issues in my notes. There are some duplicates, but I think they all contain some useful information and subtle differences. |
This comment has been minimized.
This comment has been minimized.
|
Ah I believe those are indeed what I'm thinking of, yes! And seems fine to me to leave open if they're different! |
whitequark commentedDec 27, 2017
•
edited
Consider this real-world example from crc-rs:
The build dependency, of course, needs (and has) the
stdfeature. The runtime dependency does not. Moreover, on my platform, there is nostd. However, cargo treats them as the same package, and as a result it is impossible to actually build crc-rs at all.