Skip to content
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

Feature-dependent dependencies are documented to not work #365

Closed
jsgf opened this issue Sep 26, 2019 · 5 comments · Fixed by #424
Closed

Feature-dependent dependencies are documented to not work #365

jsgf opened this issue Sep 26, 2019 · 5 comments · Fixed by #424
Labels
crate/core Related to the `tracing-core` crate crate/tracing Related to the `tracing` crate kind/bug Something isn't working

Comments

@jsgf
Copy link
Contributor

jsgf commented Sep 26, 2019

Bug Report

Version

Current git master

Crates

  • tracing
  • tracing-core

Description

According to the Cargo documentation:

Unlike in your Rust source code, you cannot use [target.'cfg(feature = "my_crate")'.dependencies] to add dependencies based on optional crate features. Use the [features] section instead.

However, the tracing crates are apparently doing this successfully:

[target.'cfg(not(feature = "std"))'.dependencies]
spin = "0.5"
lazy_static = { version = "1", features = ["spin_no_std"] }

It seems like something which could break in future versions of Cargo.

Corresponding Cargo issue: rust-lang/cargo#7442

@jsgf jsgf changed the title Feature-dependent dependencies are documented not to work Feature-dependent dependencies are documented to not work Sep 26, 2019
@jsgf
Copy link
Contributor Author

jsgf commented Sep 26, 2019

According to rust-lang/cargo#7442 (comment), cfg(not(feature = "std")) always evaluates to true, so this is a no-op.

@hawkw
Copy link
Member

hawkw commented Sep 26, 2019

Thanks for bringing this up!

The intention was to follow the convention commonly used by other crates which can conditionally support no_std, where rather than having a feature flag that enables no_std support, instead, there is a feature flag for the std dependency that can be disabled. However, in order to support no_std, we have to enable other dependencies/dependency feature flags which are not required when the standard library is present. I was hoping that this use of target.'cfg(...)'.dependencies would allow us to do that, but I guess that's not the case.

I think the only viable solution here is to change from having a std feature to having a no_std feature. Then, it would be easy to only add the spin dependency (and lazy_static/spin_no_std feature) when the no_std feature is enabled. Unfortunately, this is technically a breaking change, if the feature flags are considered part of the crate's API surface. I don't know if there are currently any downstream users who depend on default-features = false enabling no_std support, though.

@jsgf
Copy link
Contributor Author

jsgf commented Sep 26, 2019

Well, right now everything is getting the no_std behaviour whether they want it or not, but I'm not sure what effect that has (other than any dep graph containing this crate will be using lazy_static with spin).

@hawkw
Copy link
Member

hawkw commented Oct 3, 2019

Upon further consideration, I think the best approach is probably to do the following:

  1. Vendor any code from dependencies that are only needed for no_std support in-tree.
  2. Mark the vendored code as #[cfg(not(feature = "std"))]
  3. Carefully watch the upstreams the vendored code comes from for any major bugfixes
  4. Hope Cargo eventually adds better mechanisms for conditionally supporting no_std than feature flags.

This has some potential downsides for no_std users, primarily: potential binary bloat, and the inability to pick up fixes in tracing's dependencies until tracing updates the vendored copies of those dependencies' code. However, these only affect potential future no_std users, and wouldn't be a problem for a majority of the userbase; and we wouldn't have to issue a breaking change release for a change that isn't breaking for any current users.

@hawkw hawkw added kind/bug Something isn't working crate/core Related to the `tracing-core` crate crate/tracing Related to the `tracing` crate labels Nov 14, 2019
hawkw pushed a commit that referenced this issue Nov 16, 2019
Following the suggested fix on #365:
#365 (comment)

tracing-core's use of `spin` is feature-gated. `lazy_static` is vendored
for either feature but I've modified it to respect our feature flags.
I've also removed doc comments that no longer compile and suppressed a
couple of warnings with the lints that are now being applied.

At this point
* Including this in another project with std `lazy_static`
  works 
* Tracing unit tests pass both with and without
  `--no-default-features`

Fixes #365

* core: vendor lazy_static and spin for no_std support

* core: fmt vendored code

* core: trim down vendored spin, reduce visibility and addresss warnings

* core: limit vendored lazy_static for use only with no_std, fix warnings

* core: update paths to now-vendored no_std libs

* tracing: use spin::Once re-exported from tracing-core instead of crate

* core: remove ineffectual doc(hidden)

* core: refmt stdlib module

* core: bump to 0.1.8 to expose export of vendored spin::Once to tracing
@hawkw
Copy link
Member

hawkw commented Nov 16, 2019

PR #424 fixes this. Once we publish new tracing and tracing-core releases, the incorrect dependencies should be gone! :) Thanks @jsgf for the report and @thombles for taking the time to fix this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crate/core Related to the `tracing-core` crate crate/tracing Related to the `tracing` crate kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants