-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Build Deps getting mixed in with dependencies #2589
Comments
Interesting! This is, unfortunately, intended behavior. The resolution phase of Cargo doesn't know about target-specific or build dependencies, it just resolves everything, so the standard feature activation applies where features are all unioned. That is, To disable default features you'll have to ensure that all crates in the dependency graph don't use the default feature, regardless of whether they're part of a build script or not. |
I don't actually know how I would fix this though, as I can't turn off Or when cross compiling, it should make absolutely no difference how the packages are compiled in build deps phase, as they are going to be running on a different machine afterwards, so it's not like you need to try and re-use artifacts between the two. I feel like the build deps should be sealed off from the rest of your deps completely, as there are two completely different environments they are running in. As a short term workaround, I could clone the log crate and create a |
Unfortunately this just isn't how features work in Cargo. When you depend on something you can't depend on it only with one set of features as all other features get unioned. This means that if a dependency is shared then both dependants will receive the same feature set. |
I'm not happy, as at the end of the day, I can't use the log crate. I see a couple of places that might be at fault.
If I made an RFC for proposing My possible workarounds consist of duplicating crates under different names, or moving the build.rs in to a separate crate, which then depends on things as normal, and using a makefile to co-ordinate builds between them. Neither of these solutions are particularly nice. |
You should of course feel free too propose an RFC! I'd recommend trying to understand what's in play currently and think through how it can be changed first, however. Right now features are resolved at resolution time because they can introduce new dependencies which need to be applied. Features are also not a property of an edge in a dependency graph but a property of a node, which is to say that there is no way for you to depend on log with only some features activated, but rather you have to mutate the Along those lines, and RFC could perhaps tweak aspects like:
etc. |
I think the approach I'd take with the RFC would be to push to isolate build deps in the resolution phase. Essentially, I think it a project like
could be transformed into something looking like
where we run the main binary from build-dep in the directory of project automatically just like Of course, it would be nice to optimize for the common case where it's actually okay to share dependencies and not rebuild everything twice. Because I feel like the problem here is that there really are two distinct trees of dependencies, and any sharing they do is incidental. |
Oh, and I feel like features are actually not the main part of this, as I also had problems when the |
The "desugaring" you mentioned above is basically what happens today, the crux of this is indeed feature sharing. The same node in the dependency graph, |
I think I have the same problem, trying to use different features on Linux and Windows. I tried to declare it in different ways, here's the most explicit:
But cargo tries to compile unix_socket on Windows as well and fails. |
It seems to me that this also is causing a blocker for Servo, because it makes https://github.com/serde-rs/serde#using-serde-with-stable-rust-and-serde_codegen not work anymore. @alexcrichton You seem to be saying it has always been this way, but are you sure? How does anyone let users decide whether they want to go through serde_macros or just serde_codegen then? |
Try this on webrender_traits:
The intended result is that serde_codegen doesn't get build with syntex_syntax because it then gets pulled in only with default features through serde_macros. Unfortunately it doesn't happen and the with-syntex feature of serde_codegen still gets pulled in. |
This sounds like a regression because Serde seems to rely on this idiom. |
@nox I was under the impression that servo would only have one dependency on |
Oof, I just hit this with Do you foresee (a correct implementation of) separate dependency graphs causing any build problems or compatibility issues? |
Hello ! Any consensus/news on this one ? |
I just hit the same issue while cross-compiling for |
I wanted to second the fact that this is quite annoying to deal with when cross compiling. It makes using build scripts in a no_std environment quite cumbersome. Right now the "best" solution is to use manually specify the crate git in your [dependencies] section so you get two separate dependencies nodes. In general, it's very unintuitive that build dependencies for your host target and real dependencies for your cross-compilation target with different feature sets get resolved to the same dependency by cargo. |
We talked about this in the cargo team meeting today. What surprises me about this is that we generate a single resolution graph and then figure out what kind of dependencies they are. I would expect that we would generate a resolution graph for build dependencies totally separate from normal dependencies. Then, when generating the lock file and build plan, after figuring out features and so on, we merge the sets of dependency nodes from the two graphs, to dedup dependencies where possible (but this is an optimization). |
I ran into the same issue in [dependencies.failure]
version = "0.1"
default-features = false
[build-dependencies.failure]
git = "https://github.com/withoutboats/failure"
branch = "version-0.1"
default-features = false
features = ["std"] It fails with I can't use |
@alexcrichton is there any update on this? Is there any chance you or anybody else could take it or explain a path forward to fixing this? This is a major pain for build-time dependencies, since it prevents us from using a lot of crates, or worse yet, from updating them. To be honest I'd rather spend a couple weeks fixing this than having to land stuff like mozilla/cbindgen#222, for example... |
(Read that as an "I'm volunteering to take a look in my free time to this as long as I can ask questions to somebody" :P) |
@emilio I've been looking at this recently. The solution may take a while since it may require extensive changes. I feel like it's a high priority issue, so I'm going to continue pushing to make something happen. |
@ehuss that's amazing to know, thank you! Let me know if you have cargo-begginner-friendly-ish work you could get a hand with :) |
This is a temporary fix for https://gitlab.com/ra_kete/kmod-rs to circumvent Cargo issue rust-lang/cargo#2589. By specifying the memchr dependency using its Git URL rather than its crates.io version, it looks to Cargo different than the memchr dependency specified by bindgen. Hence the features of both dependencies are no longer unionized and we get a memchr free of libc. The plan is to use this workaround only as long as the above Cargo issue is not fixed. Afterwards we can just use the cstr_core release from crates.io again.
Build and dev dependencies are slightly different. You can have a fully independent copy of a build dependency since they are never linked into the same binary. For dev dependencies you might be passing values from that dependency into the crate under test, which requires that you use the same instantiation of the crate. (Basically, it seems to me that the dev-dependency case is slightly more complex, so having a separate issue to discuss it would be useful). |
@Nemo157 here is a reproduction of a build dependency (bindgen) triggering inclusion of https://github.com/coolreader18/rsspire/blob/weird-std/nspire-sys/Cargo.toml#L10 Here is a reddit thread about the above repro: https://www.reddit.com/r/rust/comments/a91qv0/for_a_no_std_crate_libstd_is_still_included_in/ In my personal observation many people are encountering this particular issue, especially in regard to tools like bindgen which use several dependencies which have an optional |
@tarcieri I’m referring to the eventual result of fixing these issues, not to the status quo, the implementation for each will be slightly different. |
I'm looking into what it would take to actually fix this and will post my results on #4866 (my preferred writeup on this issue) |
Non-unification of build-dependency features has been implemented and is available as a nightly-only feature on the latest nightly 2020-02-23. See the tracking issue at #7915. If people following this issue could try it out, and leave your feedback on the tracking issue (#7915), I would appreciate it. Particularly we'd like to know if it helps your project, does it cause any breakage, and does it significantly increase initial compile time. |
I am trying to depend on the
log
crate for my rust.ko project, butlog
is already in use inbindgen
, one of my build dependencies.bindgen
useslog
with theuse_std
feature, which is totally fine as that's running normally. However, when I addlog
to be build withdefault-features = false
for the kernel module, which cannot usestd
, I get errors where cargo tries to build, aslog
tries to findstd
.build transcript:
https://gist.github.com/tbelaire/a98527cf5d946e7c2fd4823dd16126a6
Cargo.lock:
https://gist.github.com/tbelaire/f0f89e8a21f9ce5498df07b6ec8e3a0c
The text was updated successfully, but these errors were encountered: