-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Any build scripts can now use cargo::metadata=KEY=VALUE #16436
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
Any build scripts can now use cargo::metadata=KEY=VALUE #16436
Conversation
47d8a0f to
c654a94
Compare
| assert_eq!(env::var("CARGO_DEP_A_FOO").unwrap(), "bar"); | ||
| assert_eq!(env::var("CARGO_DEP_A_BAR").unwrap(), "baz"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me, one unresolved question is what to name this env variable
- Technically,
name_keyis ambiguous.foo_bar_alice_bobcould befoo_bar+alice_bob,foo+bar_alice_bob, etc and technically packages could conflict - Whether we should
envifythe package name and key or not. iirc we do it in some places but not others. Overall, I would prefer we would never do it so it matches the name people see inCargo.toml
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Technically,
name_keyis ambiguous.foo_bar_alice_bobcould befoo_bar+alice_bob,foo+bar_alice_bob, etc and technically packages could conflict
I suppose one idea would be to using another delimiter between the name and key.
Maybe double underscore? foo_bar__alice_bob would now be different than foo__bar_alice_bob.
Not sure if there are any other delimiters that are compatible across enough platforms. I think POSIX is already pretty restrictive with what can be used an env var name.
- Whether we should
envifythe package name and key or not. iirc we do it in some places but not others. Overall, I would prefer we would never do it so it matches the name people see inCargo.toml
Given that env vars from cargo::metadata=KEY=VALUE are already envify'd in DEP_<links>_<key> I think it makes sense to keep that? I think it'd be more confusing if cargo::metadata=KEY=VALUE had multiple behaviors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that I highlighted these for being called out in the stabilization conversations and do not block this PR. I don't have concrete ideas to say exactly what should be done but want to raise these for a wider conversation.
00fac87 to
7253b99
Compare
| if dep.unit.mode.is_run_custom_build() { | ||
| let dep_metadata = build_runner.get_run_build_script_metadata(&dep.unit); | ||
|
|
||
| // FIXME: Do we need to handle dev-dependencies and/or build-dependencies? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling out for resolving
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should do whatever we do for links
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I spent some time testing this and as far as I can tell links only propagates env vars set with cargo::metadata if its a regular dependency.
I can see we explicitly filter out dev-dependencies in:
cargo/src/cargo/core/compiler/unit_dependencies.rs
Lines 987 to 990 in 577ab6f
| // Skip dependencies induced via dev-dependencies since | |
| // connections between `links` and build scripts only happens | |
| // via normal dependencies. Otherwise since dev-dependencies can | |
| // be cyclic we could have cyclic build-script executions. |
and I believe that build-dependencies are implicitly not included when the unit graph is built.
I removed the FIXME comment, but lmk if you think there is something I missed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably have tests showing the behavior for both ways of accessing metadata. Here is what I used for experimenting:
#[cargo_test]
fn metadata_from_dep_kinds() {
let set_metadata = r#"
fn main() {
println!("cargo::metadata=key=value");
}
"#;
let get_metadata = r#"
fn main() {
println!("cargo::warning={:?}", std::env::var("DEP_FOO_KEY"));
}
"#;
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
resolver = "3"
members = ["links", "n", "b", "d"]
"#,
)
.file(
"links/Cargo.toml",
r#"
[package]
name = "links"
edition = "2024"
links = "foo"
"#,
)
.file("links/src/lib.rs", "")
.file("links/build.rs", set_metadata)
.file(
"n/Cargo.toml",
r#"
[package]
name = "n"
edition = "2024"
[dependencies]
links.path = "../links"
"#,
)
.file("n/src/lib.rs", "")
.file("n/build.rs", get_metadata)
.file(
"b/Cargo.toml",
r#"
[package]
name = "b"
edition = "2024"
[build-dependencies]
links.path = "../links"
"#,
)
.file("b/src/lib.rs", "")
.file("b/build.rs", get_metadata)
.file(
"d/Cargo.toml",
r#"
[package]
name = "d"
edition = "2024"
[dev-dependencies]
links.path = "../links"
"#,
)
.file("d/src/lib.rs", "")
.file("d/build.rs", get_metadata)
.build();
p.cargo("check --all-targets")
.with_stderr_data(
str![[r#"
[COMPILING] links v0.0.0 ([ROOT]/foo/links)
[COMPILING] n v0.0.0 ([ROOT]/foo/n)
[COMPILING] b v0.0.0 ([ROOT]/foo/b)
[COMPILING] d v0.0.0 ([ROOT]/foo/d)
[WARNING] [email protected]: Ok("value")
[WARNING] [email protected]: Err(NotPresent)
[WARNING] [email protected]: Err(NotPresent)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
"#]]
.unordered(),
)
.run();
}just needs the new CARGO_DEP env variables added to it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ahh thanks, using cargo::warning so we can leverage the snapbox testing infra is clever.
I added this test to the test commit and modified it to include CARGO_DEP_LINKS_KEY in the feat commit.
Remaining `build`s: - linker is potentially involved - testing related to dev-dependencies (didn't look to see if `check --benches` could replace `bench`) Similarly, some `run`s` were removed so long as compilation verified the same details. Inspired by rust-lang#16436 which is adding more tests which don't need `build` but copied the existing ones.
### What does this PR try to resolve? Reduce test overhead by changing `build`s to `check`s. Similarly, some `run`s` were removed so long as compilation verified the same details. Inspired by #16436 which is adding more tests which don't need `build` but copied the existing ones. ### How to test and review this PR? Remaining `build`s: - linker is potentially involved - testing related to dev-dependencies (didn't look to see if `check --benches` could replace `bench`)
7253b99 to
180d3c5
Compare
This comment has been minimized.
This comment has been minimized.
| d.package_name() == dep.unit.pkg.name() | ||
| && d.source_id() == dep.unit.pkg.package_id().source_id() | ||
| && d.version_req().matches(unit.pkg.version()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note that while investigating #16436 (comment) I noticed that only checking the package name could lead to inconsistent behavior if a package has 2 versions of a package imported under different names.
To mitigate this I added checks for source_id and version. This is close to comparing package_id (Dependency does not have package_id)
Note that Dependency only has a version requirement so we use .matches(). I think in practice we should only have 1 possible matching version as Cargo would error while building the unit graph if the same dependencies. (ref)
correct me if I am wrong
This comment has been minimized.
This comment has been minimized.
180d3c5 to
a919c32
Compare
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
What does this PR try to resolve?
See #3544
-Zany-build-script-metadatafeatureCARGO_DEP_<name>_<key>env vars as described in DEP_FOO_KEY-like system that can work without "links" #3544 (comment) when-Zany-build-script-metadatais passedUnresolved questions
envify, see Any build scripts can now use cargo::metadata=KEY=VALUE #16436 (comment)How to test and review this PR?
See the e2e tests included in this PR.
As for the changes, they are not too bad.
meta: I picked this up to learn a bit more about the build script and unit graph code in Cargo.
r? @epage