cargo
cargo copied to clipboard
Tracking Issue for RFC 3028: Allow "artifact dependencies" on bin, cdylib, and staticlib crates
Summary
RFC: #3028 Related Issues: #4316 Implementation: #9992 Documentation: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#artifact-dependencies Issues: https://github.com/rust-lang/cargo/labels/Z-bindeps
Allow Cargo packages to depend on bin, cdylib, and staticlib crates, and use the artifacts built by those crates.
Unresolved issues
- [ ] Make a list of any known implementation or design issues.
- [ ] Add support for inheriting the source of an artifact dependency
Notes
- [ ] Once implemented, reopen https://github.com/rust-lang/rfcs/pull/3035
- [ ] When stabilizing, be sure to update INDEX_V_MAX.
About tracking issues
Tracking issues are used to record the overall progress of implementation. They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Please note that a cargo package only being able to provide a single cdylib or staticlib is a limitation imposed by cargo which technically could be lifted in the future. I'd prefer for this feature to be able to accommodate multiple cdylib or staticlib artifacts from a single package.
@joshtriplett @jyn514 I found a problem in the original RFC that makes it unfit for our use case. Specifically, it is presumed that a given dependency crate will be built for one and only one architecture producing one binary artifact. We have need to build a given crate for multiple architectures producing one artifact per architecture.
Are package renames allowed? That is something like:
[dependencies]
foo-x86 = { package = "foo", artifact = "bin", target = "x86_64-unknown-linux-gnu" }
foo-aarch64 = { package = "foo", artifact = "bin", target = "aarch64-unknown-linux-gnu" }
On Fri, Aug 13, 2021 at 05:20:12AM -0700, bjorn3 wrote:
Are package renames allowed? That is something like:
[dependencies] foo-x86 = { package = "foo", artifact = "bin", target = "x86_64-unknown-linux-gnu" } foo-aarch64 = { package = "foo", artifact = "bin", target = "aarch64-unknown-linux-gnu" }
I'm planning to write a brief follow-up RFC allowing exactly that.
Is there anyone actively working on this RFC?
Could a cargo maintainer post a brief write-up of how they'd implement this? E.g. relevant files in this repository, gotchas, etc.
The followup RFC is https://github.com/rust-lang/rfcs/pull/3176.
Is there anyone actively working on this RFC?
@Byron plans to start work on this tomorrow.
👍 Thanks for the updates!
Thank you @npmccallum for the introduction. Even though I am delayed, I believe a draft PR should be submitted in the next couple of days as I am ramping up.
Another thing to consider is a binary crate that depends on other binary crates and expects its dependencies to be available in PATH.
If people want to start testing this out, it should now be available on the latest nightly (nightly-2022-02-24).
I believe I've hit an issue with this feature. Here's a git repo that reproduces it.
At first, it was combining this feature with per-package-target, but that didn't turn out to be necessary. So the issue is strictly with the use of the bindeps feature.
Looks like my issue was already reported here, though the example I provided is a bit smaller. Sorry for the noise.
For anyone watching this issue and looking to contribute towards its eventual stabilization, I've identified three bugs in bindeps that need addressing (and/or that you should watch out for when testing this feature): #10525, #10526, and #10527 .
Another bug I found (will open issue soon) if a lib has a "name" property, the env wont be set neither for new name or old name, meaning can't be used as an artifact.
Also on rustfmt, not sure who's fault (probably rustfmt) https://github.com/rust-lang/rustfmt/issues/5332
The use case of making env!("CARGO_BIN_FILE_SOMEBINARY") relative, such that the build products can be moved around (as long as they stay in the same place relative to each other), could be improved.
It's not obvious to me what the best way to do this currently is, but providing an env var with the path for the current binary would be handy, as you could then derive a relative path from the two absolute paths.
Btw, I think this feature doesn't work when the dependency-crate has a custom .cargo/config 😿
So, let's say that my directory structure is:
crate-a/.cargo/config -- contains a `[build] target = ...` + `[unstable] build-std = ...`
crate-a/Cargo.toml
crate-a/src/main.rs
crate-b/Cargo.toml -- contains artifact-dependency on crate-a
crate-b/src/main.rs
When Cargo builds crate-a for crate-b, it seems to ignore the fact that crate-a has a custom .cargo; on the other hand, I can't move that .cargo into crate-b, because I'm actually cross-compiling (host is x86_64, target is AVR).
.cargo/config is only read from the current directory and it's parent directories. The .cargo/config for crate-a would be ignored too if you used cargo build --manifest-path crate-a/Cargo.toml and not cd crate-a; cargo build. For the target = key in .cargo/config you are already required to specify it anyway for artifact dependencies I believe. For the build-std = key I'm not sure how to handle that with artifact dependencies.
(fwiw, similar discussions: https://github.com/rust-lang/cargo/pull/10330, https://github.com/rust-lang/cargo/issues/10444)
Shouldn't this feature be enabled through cargo.toml and not a cli flag? https://doc.rust-lang.org/nightly/cargo/reference/unstable.html says:
New syntax in Cargo.toml requires a cargo-features key at the top of Cargo.toml, before any tables.
Trying this with bindeps or artifact-dependencies led to the error unknown cargo feature.
Normally a feature like this would use cargo-features in Cargo.toml, but due to some implementation complexities, this uses -Zbindeps since it is a somewhat global feature that affects various parts of Cargo that aren't easily "turned on" with cargo-features.
feature request: https://github.com/rust-lang/cargo/issues/11108
Is there something like target = "host" to complement target = "target"?
Is there something like
target = "host"to complementtarget = "target"?
It was mentioned in the section of Rationale and alternatives in RFC 3028. But no. Not inside the current implementation.
Thanks, sorry I missed that, glad it is there.
Buck and Bazel are interested in using artifact dependencies as a way to express dependencies on crates.io binaries, such as rustfilt or bindgen-cli. (https://github.com/bazelbuild/rules_rust/issues/1739)
However both build systems rely on cargo metadata for understanding the dependency graph described by a Cargo.toml, and currently artifact dependencies are invisible in the output of cargo metadata, which is blocking us from using this feature. https://github.com/rust-lang/cargo/issues/10607
Just another use case and a solution: I'm using trycmd to run cli commands in documentation. These commands' binaries should be built before testing. I couldn't make tests to depend on binaries in other crates in the project.
I found a workaround using escargot to build these binaries by specifying their Cargo.toml in tests.
Are there any issues blocking stabilization of this feature?
There are quite a few issues tracked in https://github.com/rust-lang/cargo/labels/Z-bindeps. It looks like most of those need to be resolved.