Cargo features for host vs target (no_std)

I'm trying to use a crate in no_std mode. The crate has a feature (enabled by default) that guards use of std lib, and which can be disabled to be used in no_std environments. Pretty standard stuff, no pun intended.

But it's not working and I have no idea why. Cargo is doing something strange.

Cargo.toml has what seems to me to be the right thing from the documentation:

[dependencies.either]
version = "1.5.0"
default-features = false

and yet cargo build -v seems to be defining the default and use_std features regardless:

   Compiling either v1.5.0
     Running `rustc --crate-name either /home/dan/.cargo/registry/src/github.com-1ecc6299db9ec823/either-1.5.0/src/lib.rs --crate-type lib --emit=dep-info,link -C debuginfo=2 --cfg 'feature="default"' --cfg 'feature="use_std"' -C metadata=3ff95422768f7b18 -C extra-filename=-3ff95422768f7b18 --out-dir /home/dan/work/geek/rust/stm32rust/ws2812b/firmware/target/thumbv7m-none-eabi/debug/deps --target thumbv7m-none-eabi -L dependency=/home/dan/work/geek/rust/stm32rust/ws2812b/firmware/target/thumbv7m-none-eabi/debug/deps -L dependency=/home/dan/work/geek/rust/stm32rust/ws2812b/firmware/target/debug/deps --cap-lints allow -C link-arg=-Tlink.x -C linker=lld -Z linker-flavor=ld.lld`
error[E0463]: can't find crate for `std`
  |
  = note: the `thumbv7m-none-eabi` target may not be installed

running that rustc command without the --cfg 'feature="default"' --cfg 'feature="use_std"' args works and produces libs in the target directory (but cargo build wants to rebuild it on next invocation because of the difference, of course).

It doesn't seem to be anything like a nested dependency; as far as I can tell nothing else is pulling in either, and the build proceeds entirely without Either (to compile failures in my code) if I leave the stanza above out of Cargo.toml.

This is with rustc 1.27.0-nightly (7360d6dd6 2018-04-15) for the thumbv7m-none-eabi target.

Some more details here: https://github.com/bluss/either/issues/23 but I'm now doubtful it's the fault of the either crate specifically.

Update: in the github issue, @cuviper seems to have tied this.

However, cortex-m-rtfm-macros is a proc-macro crate, which means it's always compiled for the host as a plugin to rustc, where std is fine. I think this is a bug/limitation in Cargo: the either features selected here for the host are different than the either features selected for your target, but Cargo is simply using the superset of either features everywhere.

So this might be a not-yet-covered case in the recent ability to use cargo instead of xargo. I guess I'll try xargo again and see if it helps. cc @japaric

I believe the problem is covered in this issue:
https://github.com/rust-lang/cargo/issues/2589

1 Like