If a crate is used both as a normal dependency and a build-dependency, features enabled for the build-dependency are also enabled for the normal dependency. This leads to build failures in the no_std world, because an use_std feature that is turned on for the build-dependency is also turned on for the normal dependency.
cargo new bar --lib
cd bar
cargo new foo --lib
In bar/foo/Cargo.toml:
[features]
default = ["use_std"]
use_std = []
In bar/foo/src/lib.rs:
#[cfg_attr(not(feature = "use_std"), no_std)]
pub fn return_42() -> u32 { 42 }
#[cfg(feature = "use_std")]
pub fn print_42() {
println!("{}", return_42());
}
In bar/Cargo.toml:
[dependencies.foo]
path = "foo"
default-features = false
[build-dependencies.foo]
path = "foo"
In bar/src/lib.rs:
#![no_std]
extern crate foo;
pub fn return_42() -> u32 {
foo::return_42()
}
Compiling with cargo build --verbose:
Compiling foo v0.1.0 (file:///…/bar/foo)
Running `rustc --crate-name foo foo/src/lib.rs --crate-type lib --emit=dep-info,link
-C debuginfo=2
--cfg 'feature="default"' --cfg 'feature="use_std"'
-C metadata=5cd2c90dafa7c435 -C extra-filename=-5cd2c90dafa7c435
--out-dir /…/bar/target/debug/deps
-C incremental=/…/bar/target/debug/incremental
-L dependency=/…/bar/target/debug/deps`
Compiling bar v0.1.0 (file:///…/bar)
Running `rustc --crate-name bar src/lib.rs --crate-type lib --emit=dep-info,link
-C debuginfo=2 -C metadata=0a475a34b1347c78
-C extra-filename=-0a475a34b1347c78 --out-dir /…/bar/target/debug/deps
-C incremental=/…/bar/target/debug/incremental
-L dependency=/…/bar/target/debug/deps
--extern foo=/…/bar/target/debug/deps/libfoo-5cd2c90dafa7c435.rlib`
We see that --cfg 'feature="default"' --cfg 'feature="use_std"' is passed, i.e. the use_std feature is activated even though default-features = false is used. When we comment out the [build-dependencies.foo] section, foo is built without the use_std feature.
The problem is that compilation for custom targets using xargo/cargo-xbuild fails when the std feature is activated for the custom target:
cargo xbuild --target some-custom-target.json --verbose
+ "rustc" "--print" "sysroot"
+ "rustc" "--print" "target-list"
+ RUSTFLAGS="--sysroot /…/bar/target/sysroot"
+ "cargo" "build" "--target" "some-custom-target" "--verbose"
Compiling foo v0.1.0 (file:///…/bar/foo)
Running `rustc --crate-name foo foo/src/lib.rs --crate-type lib --emit=dep-info,link
-C debuginfo=2
--cfg 'feature="default"' --cfg 'feature="use_std"'
-C metadata=beb376bcf23896f4
-C extra-filename=-beb376bcf23896f4
--out-dir /…/bar/target/some-custom-target/debug/deps
--target /…/bar/some-custom-target.json
-C incremental=/…/bar/target/some-custom-target/debug/incremental
-L dependency=/…/bar/target/some-custom-target/debug/deps
-L dependency=/…/bar/target/debug/deps
--sysroot /…/bar/target/sysroot`
error[E0463]: can't find crate for `std` ] 0/2: foo
|
= note: the `some-custom-target-6722811146760112169` target may not be installed
error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`.
error: Could not compile `foo`.
We see that the use_std feature is turned on even though we are compiling for the custom target. So this is definitely not the build dependency getting built because build scripts are compiled for the host target.
There are two ways to work around this, but both have sigificant downsides:
no_std mode and don't use any std-dependent features and build scripts. This makes writing build scripts harder.Both workarounds don't really work for build dependencies of dependencies.
cargo 1.29.0-nightly (af9e40c26 2018-07-05)
release: 1.29.0
commit-hash: af9e40c26b4ea2ebd6f31ee86ee61d5ac1c74eb0
commit-date: 2018-07-05
rustc 1.29.0-nightly (254f8796b 2018-07-13)
binary: rustc
commit-hash: 254f8796b729810846e2b97620032ecaf103db33
commit-date: 2018-07-13
host: x86_64-unknown-linux-gnu
release: 1.29.0-nightly
LLVM version: 7.0
Oh wow, it seems like this issue was already reported multiple times:
rust-lang/cargo#4866 rust-lang/cargo#4664 rust-lang/cargo#2589 rust-lang/cargo#4361
The oldest report is from April 2016, over two years ago. Given that embedded is a target domain of Rust's 2018 roadmap and build scripts are a common stable feature of cargo, I think we should tackle this issue. Especially because it leads to very confusing errors and there are no good workarounds.
Indeed the intention is to solve this issue!
@Eh2406 I'm curious, would you be interested in tackling this issue? I think it has implications on resolution but it's not exclusively concerned with crate graph resolution. There's a lot of interaction with the backend as well where Cargo actually invokes rustc
I am happy to help any way I can. However, this has been open for a long time because it is very hard, and tangled with many of the other things that need to be rethought.
The goal is that build script and the real build have the same dependency with different features.
serde is on, and my main uses that code with cfg(feature("serde")) then they head better aggry about if serde is on....
Oh in general I see this as having a pretty simple (sort of) model of what should happen. Right now in cargo's backend we have a graph of "units" where each unit is basically a tuple of (package, target, profile, info). Here we have a precise dependency graph of what to do and each "unit" corresponds to one process, be it rustc, rustdoc, a build script, etc. Occasionally a unit needs to ask "what features are active for me?" but this question doesn't have an answer right now. We can at best coarsely answer "this package has all these features enabled", but that's not correct when you have cross-compiling in effect.
The "solution" here is to basically propagate features not through the crate graph resolution, but rather through the unit dependencies. When one unit depends on another it depends on it with a set of features, and those features get unioned over time into a unit, not a package. We can probably make this distinction a bit more coarse and group it by (unit, kind) where kind is in the "info" above and basically says "compile for the target" or "compile for the host".
If that all makes sense then the profile bits I don't think interact with features at all. Each unit already has a profile selected as well, so if it did the information is in theory there! I also don't think that public/private dependencies would affect much here too, I think it's mostly just feature propagation? (as we do today, only a little less aggressively). And finally for Cargo.lock features don't come into play either, that's just a resolution of crate graph versions and we pessimistically assume that all features are activated to generate it, so there's no need to record features in Cargo.lock
All that leaves build scripts (I think?) and that's indeed true! In theory this doesn't matter as build scripts are compiled with environment variables indicating enabled features, but they're also today compiled with --cfg directives which can indeed cause problems I think. I haven't thought this one through too much :)
That sounds a lot more doable than I was expecting. Conveniently, Cargo.lock does not record features so that is off the list.
Let me try and explain what I was thinking with relation to public/private dependencies.
let's say we are compiling a witch depends on b and c each of which depends on d.
Currently no matter the nature of that "depends"; b and c will both see the same version of d and, the d that b and c see have the same features, and d will only bilt once per target.
After a minimal fix to this, if b is only a build dependency, then we wave the second invariant, and consequently the third as well. #5237 asked us to wave the first invariant for similar reasons.
After impl private dependencies then, if b only has a private dependency on d then we will wave some or all the invariants, design work tbd. So there is a similar problem shape. Although as I type, I am not seeing a deeper connection.
On another concern, do all bild unit dependencies on d see the same features, or do each get only the features it asked for?
Hm yeah I'm not sure if there's a connection there either, but it's something I suspect that fleshing out the implementation would show pretty readily!
Currently whether or not you're a build or normal dependency all feature calculations are done the same way, you're always compiled with the same set of features in both contexts (which is the bug here)
Currently whether or not you're a build or normal dependency all feature calculations are done the same way, you're always compiled with the same set of features in both contexts (which is the bug here)
Agreed, so after this bug is fixed if I depend on a and d while a has a build dependency on d with feature foo then:
main.rs sees d as not having foo a's build.rs sees d as having foo.My current question is, I depend on a, b and d while a has a build dependency on d with feature foo and b has a build dependency on d with feature bar then:
main.rs sees d as not having neither foo nor bar.a's build.rs sees d as having foo but does it see bar?d's build.rs sees d as having bar but does it see foo?@Eh2406 for your first scenario, indeed! That's what I imagine for this issue as well.
In your second scenario then a and b will see d with both the foo and bar features because we can only compile the library once and features are defined to get unioned. I think the main thrust of this issue is what then cross compiling (more than one target involved) we're already compiling two artifacts so we should no longer be unioning across targets.
because we can only compile the library once
Just a random idea, I was thinking that maybe the Unit could include the features to lift this restriction. At least for build-deps, it would be easy to do utilizing the ProfileFor flag.
@alexcrichton That would make the change smaller. I am concerned how do we explain the rule for when do "features get unioned". For example:
we're already compiling two artifacts so we should no longer be unioning across targets
implies that this only works if cross compiling!? That my main.rs sees d as having foo and bar if it is being built locally, but not if cross compiling.
@ehuss Lol. Two people respond, two contradictory answers. :-) I am glad to hear that the other alternative is conceivable doable.
@Eh2406 another excellent question! This is where you get to a sort of obscure part of Cargo today where let's say you've got a compiler for x86_64-unknown-linux-gnu installed. It turns out these two invocations are actually pretty different:
cargo buildcargo build --target x86_64-unknown-linux-gnuIn the latter invocation Cargo thinks it's cross compiling so it'll build more than the first invocation. This means that if you have a big dependency which is both a target and a build dependency the first command will build it once while the second command will build it twice.
The behavior here has been in place since the early days of Cargo but has definitely been brought up as suspect over time. The benefit is that cargo build can be faster, but the downside is that you'd naively think the two commands above are equivalent but they're not.
So to answer your question, Cargo already gives an "uncomfortable answer" to when you're not cross compiling you get different results than if you're cross compiling. In that sense I think it's ok to not worry about it with respect to this issue. If we ever fix this issue it'll naturally fall out that features will be separated as well.
@ehuss due to the unioning nature of features we have to iteratively walk the dependency graph to discover features enabled, so I think this probably won't be embedded in a Unit directly but rather be stored as a Unit => Vec<String> map or something like that which is built after we calculate all Units and their dependencies.
So currently cargo build and cargo build --target x86_64-unknown-linux-gnu are observable different, one compiles deps once and the other twice.
After this issue is fixed they will additionality have different output code; a build.rs will see all features with cargo build and only dev features with cargo build --target x86_64-unknown-linux-gnu.
edit: that is backwards. build.rs will always see all features. main.rs will only see real deps features in cargo build --target x86_64-unknown-linux-gnu but will see all features in cargo build
That is a significantly bigger change, but we can chalk that up to just another part of that long standing oddity.
@Eh2406 I think you're right yeah! Unfortunately no matter how this is sliced it's a sort of big change :(
I'm convinced despite the braking of things this needs to happen. Where should I get started?
Relevant: #5656 if we make them more different we should document when to add it to CI.
@Eh2406 I think the basic steps here are to delete the Resolve::features method and then "get everything compiling again". It basically makes no sense to query what features are activated for a package any more unless you also have the context of "for what build target?" in mind
Ok so I have a branch with a new build_target: Option<()> peram on features, and the 14 places where it is called are passing None. What Is next? What type goes in that arg, and what do we do with it? Next time I am awake I can start figuring it out. Presumably some Enom (dev | target) or None for all, unless we have one already, and then do a graph traversal for features needed by that type for that id.
@Eh2406 hm from this point I'm not really sure how this would be best done! I haven't thought through this too much myself but I'm fine reviewing any implementation! I suspect the first thing that sticks on the wall will be good enough :)
@ehuss I know you have been working on different build args for different target like things. (sorry if I have the terminology wrong.) Do you have advice for me? Specificky is there existing systems/types I should be using/aware of for consistency with your work?
IIUC, the intent is to only fix this for the cross-compile case? If that's correct, I don't think it would interact with the profile changes at all. As Alex mentioned, it would probably need to build a map so that given a Unit it can return the correct set of features to use (looking at kind to determine if it is a build-dep and pkg to figure out which features). Then in build_base_args() and rustdoc() it should use that map to determine the correct --cfg flags.
At least that's my best guess of how I understand it. I'm not terribly familiar with how features or Resolve work, so I don't really know how to compute the feature set.
@ehuss That was very helpful! I am not very familiar with how anything but Resolve work, so that gives me somewhere to start. I can definitely do the inner Resolve side, I may bug you again to see if I got the outer part correct.
Hm, but thinking about it more, kind by itself isn't enough to distinguish between a build-dep and other deps. That's the part that I was thinking about before, it doesn't seem like Unit has enough information to differentiate them. It could say build_config.requested_target.is_some() && unit.kind==Host to say it is a cross-compile build-dep, but that would be wrong for proc-macro and plugins. Maybe that doesn't matter, or has another way to mitigate or differentiate.
I'm also a little uneasy about only addressing the cross-compile build-dep case. Although that probably covers that vast majority of use cases, it seems like it could be confusing. There have been quite a few feature requests for more granular feature and dependency control. But fixing this one case would be a big win, so it's probably a good first step!
So I think for the inner Resolve side I need to do a BFS over the dependency tree to build a sub tree for things needed each Kind. In a quick scan I did not fined where we determined what Kind a dep is; I'd prefer to reuse the existing code if possible.
Edit: looks like the code you pointed me to is already doing a BFS over the dependency tree, exactly to figure out how all the pieces fit together. So recalculating features should "just" be worked in there, and removed from Resolve as @alexcrichton originally suggested.
@ehuss you commented you had free cycles, want to give this a try?
I'll take a look. One question I had, when a feature is enabled with slash syntax, should it enable it for both the regular dependency and the build dependency? For example, --features somedep/feat1 or inside a [features] block? Or should it only affect certain types of dependencies? Or does there need to be more control for selecting the type of dependency?
I just checked whether I had any crates in my cache that optionally enabled features for a build dependency, looks like out of the 145 versions of crates with build-dependencies (of 1298 versions of crates in my cache) none of them do.
This script needs ripgrep, yq (for tq) and jq installed:
→ rg -0 --no-ignore -l -g 'Cargo.toml' 'build-dependencies' | xargs -0 tq -r '
select(has("features") and has("build-dependencies"))
| ([.features[][] | select(contains("/")) | (. / "/")[0]] | unique) as $optionaled
| (."build-dependencies" | keys) as $deps
| select(any($deps | .[]; . as $dep | any($optionaled | .[]; . == $dep)))
| .package.name
'
I think eventually we would need to have more control over selecting the type of dependency. Maybe not so much for build dependencies, but for test dependencies I can definitely see situations where testing an optional feature requires activating extra optional features of a dependency just for the tests.
It seems like there should be an RFC detailing the full intended design of features and optional dependencies, there's likely to be interaction between fixing this, #5364, #5565, #1596, #1796, #2589 (dup of this), and #3494. Having an overall roadmap of how these would all work together could help answer questions like that.
Reading through #5565 some more, I wonder if namespaced features could be extended to cover different dependency contexts as well.
+1 for an rfc. +1 for more control eventually. but also a +1 for finding some way to make progress for now and give the no-std people a workaround.
If I understand the current behavior (a big if), then everything always activates for everything. If the common syntax can be made to distinguish between build/target then we may get no-std working, even if there still exist syntaxes that do activate for both.
For now would it be conservative to say --features somedep/feat1 activates both?
I think having --features somedep/feat1 and the same in Cargo.toml activate both is probably the only backwards compatible way to do it. From what I've seen of this issue it would fix the common case, i.e. having some crate which has a common dependency with one of its build crates and needs that common dependency to be built with different features for "normal" vs "build" builds.
It would also fix the example in the OP, as despite that being the uncommon case of having a direct dependency used as both a normal and build dependency it doesn't activate any optional features of it based on its own features.
@ehuss FWIW I always figured that the way features would be activated would be by dependency edge. For example when building some artifact there were a number of dependency edges that caused that artifact to be needed to be built, and those edges are what determines features (rather then edges elsewhere "randomly" in the graph).
In that sense I figured the slash syntax would basically enable whatever kind of dependency the dependency is listed as. (and if the dependency is listed twice in two sections then "good luck")
I'm not opposed to an RFC on this topic but I don't think there's really a whole lot of debate to be had about this. I suspect there's basically "one correct design" and while it probably takes some discussion to reach that point it's not necessarily RFC-scale discussion.
I don't see how this can be introduced in a backwards-compatible fashion (without some kind of flag). If you have something like the following:
[package]
name = "foo"
version = "0.1.0"
[dependencies]
serde = {version = "1.0", features=["rc"]}
[build-dependencies]
serde = "1.0"
Today, the serde dependency will have the rc feature in both cases. If it is changed so that build-dependencies no longer have the same features as normal dependencies, that might break some packages that expect that behavior.
@alexcrichton I'm not sure I understand your comment about the dependency edges. That would mean that features would only be decoupled in the cross-compile scenario, correct? In normal host builds there is usually only one artifact, so build-deps and normal-deps would still be unified.
There seems to be a lot of desire to fully decouple features based on the dependency kind (normal/build/dev), and to avoid enabling features for any dependencies that are not used. proc_macro and plugins also complicate things (particularly in the non-cross-compile scenario). It seems like only addressing the cross-compile case would miss some use cases, and might be a confusing behavior. Am I misunderstanding things?
Sounds like you understand things well!
That would mean that features would only be decoupled in the cross-compile scenario, correct?
This has been a long conversation but here is where I tried to ask the same thing:
https://github.com/rust-lang/cargo/issues/5730#issuecomment-405593610
I believe the answer is yes.
@ehuss it's true that this is technically a breaking change, but I suspect it's minor enough that we can get away with it. For sure though we'll want to run crater and/or monitor breakage closely to assess the situation. Even if it causes a lot of breakage though I think we'll still want to implement this in one way or another.
I also think you're right that this is probably the point where we'll have to bite the bullet and finally make cargo build the exact same as cargo build --target $host. I don't expect that will cause many problems in practice, though. It was originally done to cut down on the number of theoretically compiled crates, but in practice I don't think any slow-to-compile crates are shared between build scripts and the main build frequently (mostly just small crates like log and libc afaik)
A comment here: https://github.com/rust-embedded/wg/issues/256#issuecomment-438483578 from @japaric mentions a workaround.
The workaround is to use the host dependency in no_std mode everywhere, (...)
I don't really understand what is meant there or how to do it, can someone be so kind to explain it please?
Apparently as mentioned here renaming a crate is also a workaround?: https://github.com/bendst/serde/commit/6be419375bec9c6c581ac454fa6ba575dfb510f0
Apparently as mentioned here renaming a crate is also a workaround?: bendst/serde@6be4193
The renamed crate is only used by my custom binary serialization crate. Every build script and proc macro still uses regular serde. It treats serde2 as a completely different dependency.
The workaround is a dirty hack and not maintainable :)
Thank you for the explanation @bendst.
If there are any reproducable workarounds maybe @phil-opp should add them to the original post?
If there are any reproducable workarounds maybe @phil-opp should add them to the original post?
I added both workarounds to the issue description. However, they both have significant downsides (not maintainable, std-dependent features not available in build scripts, not possible if it's a build dependency of a dependency) and are not really practical.
I put together a somewhat hacky but effective workaround for build-dependencies flavor of this issue, which is probably the most common one. (certainly it is really important for nostd users like myself). You can find at https://github.com/auxoncorp/cargo-5730. The basic approach is to make a separate crate for your build dependencies, then use that library to delegate to it from your build.rs.
The workaround is effective, but it should be very clear that it's only a workaround. I spent a few hours staring at the cargo source to see if I could fix it myself first, but it's clearly beyond anybody who's not a cargo maintainer. This issue if very important for nostd users, and some assistance from the cargo team to get it fixed the right way would be most appreciated.
@mullr I've done a similarly hacky workaround in a few crates, namely: in the build instructions I say you have to cargo install bindgen, rather than using the bindgen crate. It's not the greatest solution, but it's been a decent enough stopgap for now.
I encountered a similar bug today. I am not sure if it is the same bug or not. See more info here.
wasm-logger (v0.1.4, commit cc8b22b1) depends on web-sys which in turn depends on env_logger as a build-dependencies. env_logger depends on log with features = ["std"]
wasm-logger v0.1.4 did not enable featues = ["std"] but still able to use the function log::set_boxed_logger (which is behind feature="std") if it is compiled with web-sys="0.3.22".
But with web-sys="0.3.23", wasm-logger 0.1.4 fails to build. The difference in web-sys 0.3.23 is that env_logger is just an optionally dependencies.
It seems that this issue also affects dev-dependencies: if I have serde-test in dev-dependencies" then this will enable thestdfeature inserde, even if I am only doing acargo build`.
@Amanieu yes, there are also separate-but-related issues for dev-dependencies as well: #4664 (see also #4866 which mentions this)
The main issue tracking this for dev-dependencies is https://github.com/rust-lang/cargo/issues/1796 AFAICT. I believe it is a separate issue because it is unclear whether these two issues should be solved in the same way: for build dependencies it's pretty clear that you often want different features than for runtime dependencies and that really isn't a problem outside of the current implementation, but having regular runtime dependencies and dev-dependencies use different features could lead to accidentally testing something different from what you're shipping.
Please note that this makes no_std almost unusable in many cases.
@mullr thanks again for the workaround, it saved me once more today.
I just ran into this as well trying to add nom as a dep to a no_std library. One of my build deps uses nom, and the end result is memchr failing to build. Very confusing.
This issue also applies to dev-dependencies. See
https://github.com/dalek-cryptography/ed25519-dalek/issues/95
and the workaround:
https://github.com/dalek-cryptography/ed25519-dalek/issues/95#issuecomment-533865568
Here's a workaround I devised for build dependencies:
Make all build dependencies optional, add a feature to enable then, and allow running the build script via cargo run:
# Cargo.toml
[package]
build = "build.rs"
[[bin]]
name = "build-script-build"
path = "build.rs"
[features]
build = ["dep"]
[build-dependencies]
dep = { ..., optional = true }
In the build script, if the feature isn't enabled, re-execute the build script:
// build.rs
#[cfg(not(feature = "build"))]
fn main() {
let cargo = std::env::var_os("CARGO").unwrap()
let args = [
/* cargo, */ "run",
"--bin", "build-script-build",
"--features", "build",
"--target-dir", /* $OUT_DIR/bindgen */
];
let mut target_dir = std::path::PathBuf::from(std::env::var_os("OUT_DIR").unwrap());
target_dir.push("bindgen");
assert!(std::process::Command::new(&cargo).args(args).arg(&target_dir).status().unwrap().success())
}
#[cfg(feature = "build")]
fn main() {
// normal build script
// TODO: do nothing if this is invoked as a build script
}
Note, during a normal build, the build script gets executed 3 times: once as the original build script, then again as the build script with the feature enabled, then as the bin target for cargo run. Some logic should be added so the second execution does nothing.
This is causing a fair amount of pain while trying to sort out support for the Nordic nRF9160 chip, as you have to use Nordic's C library, which means using bindgen as a build-dep, which has a ton of dependencies, which have various std/no_std features.
I also wanted to note that the cargo-5730 workaround crate noted above seems to break publishing to crates.io. I some useful crates for this chip, but I can't publish them at the moment.
@thejpster yeah, it's really annoying with bindgen. The only workarounds I'm aware of are making a minimal -sys crate for the wrapped C library (potentially as a crate in the same workspace, as these are unaffected), or requiring people cargo install bindgen in advance
minimal -sys crate for the wrapped C library
Could you elaborate on this (happy to take it off this thread to avoid spamming everyone)? I have a -sys crate, but that still calls bindgen as a build dependency. Are you suggesting I pre-generate the headers and bundle them in the -sys crate? One problem with this approach is that the headers are under a non-free licence and I am not a lawyer.
@thejpster when I've encountered this particular failure, it's when I'm linking a crate whose own build-dependencies activate std
Are you encountering problems when consuming that -sys crate from another crate in the same workspace (even one which shares dependencies with std features with bindgen)? So far that much has been fine for me.
I think this is a minimal reproduction.
$ cargo new --lib crate_a
$ nano ./crate_a/src/lib.rs # make crate no_std
$ head ./crate_a/src/lib.rs
#![no_std]
...
$ nano ./crate_a/Cargo.toml # add build-dep
$ cat crate_a/Cargo.toml
...
[build-dependencies]
bindgen = "0.51"
$ cargo new --lib crate_b
$ nano ./crate_b/src/lib.rs # make crate no_std
$ head ./crate_b/src/lib.rs
#![no_std]
...
$ nano crate_b/Cargo.toml # add dep
$ cat crate_b/Cargo.toml
...
[dependencies]
crate_a = { path = "../crate_a" }
byteorder = { version = "1.3", default-features=false }
$ cd ./crate_b
$ cargo build --release --target=thumbv8m.main-none-eabi
Updating crates.io index
Compiling byteorder v1.3.2
error[E0463]: can't find crate for `std`
|
= note: the `thumbv8m.main-none-eabi` target may not be installed
error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`.
error: Could not compile `byteorder`.
To learn more, run the command again with --verbose.
Removing the bindgen build-dependency in crate_a makes everything work.
@thejpster reproed. I tried putting them in a workspace and had the same problem 😢
I think I may have been confusing myself with some of the discrepancies between how build-dependencies and dev-dependencies features are unified.
I believe I ended up "solving" this one via the cargo install bindgen "solution" the last time I encountered it. Ugh.
@tarcieri, I'm using bindgen as a CLI tool, but now docs.rs won't build my documentation. See https://github.com/rust-lang/docs.rs/issues/444
@thejpster that's rather unfortunate, but seems like it might be resolved when Ubuntu 20.04 is released?
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.
Most helpful comment
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.