-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Parse # env-dep
directives in dep-info files
#8421
Conversation
r? @ehuss (rust_highfive has picked a reviewer for you, use r? to override) |
a3fff7c
to
343e2a5
Compare
Note that this'll fail CI until we get a nightly tonight, but I was testing with a toolchain that has support for |
d0a11d3
to
01a16d8
Compare
Ok I've pushed up a commit which fixes some dep-info parsing bits in the test suite, but this actually uncovered an unfortunate behavior that I'm not sure what to do about: #[cargo_test]
fn env_build_script_no_rebuild() {
// Only nightly has support in dep-info files for this
if !cargo_test_support::is_nightly() {
return;
}
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
"#,
)
.file(
"build.rs",
r#"
fn main() {
println!("cargo:rustc-env=FOO=bar");
}
"#,
)
.file(
"src/main.rs",
r#"
fn main() {
println!("{:?}", env!("FOO"));
}
"#,
)
.build();
p.cargo("build").run();
p.cargo("build").with_stderr("[FINISHED] [..]").run();
} That test fails because it rebuilds. The problem is that Cargo sees the previous compilation read the env var Cargo can't really predict the value of env vars coming from build scripts, so I guess it just has to ignore them? We'd have to keep a list of "these env vars are defined by build scripts" from the previous compilation and use that to filter the env vars to check in Cargo itself. I'll try to think about this and see if there's something better. Handling |
Well, the behavior I would expect is that we don't necessarily rebuild the crate after re-running the build script -- I think today that's never the case, though, so would be "new feature" in some sense. I think I recall an issue about this but can't find it today. I think that sort of thing is pretty hard given Cargo's architecture today -- IIRC, we need to upfront decide everything we're planning to build. I guess in theory the crate could be a no-op build somewhat hackily (the cargo 'step' runs but compiler isn't invoked). |
This commit updates Cargo's parsing of rustc's dep-info files to account for changes made upstream in rust-lang/rust#71858. This means that if `env!` or `option_env!` is used in crate files Cargo will correctly rebuild the crate if the env var changes. Closes rust-lang#8417
01a16d8
to
784ea96
Compare
Ok I've pushed up a commit I think addresses the issue. I figured out an easy-ish way to do it because FWIW we unconditionally rebuild the crate if a build script is rerun, we definitely don't have any red/green style tracking like the compiler does where if the build script produces the same output we don't rebuild any crates. (same for if you recompile a crate and it produces byte-for-byte the same output we still build everything else) The main problem I was imagining is that we can't even predict what env vars a build script will set. At the point we translate rustc's dep info to Cargo's dep info, however, we have a |
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'm thinking it might be a good idea to update the metadata version since this changes the format of the dep-info file. It should be backwards-compatible since the new cargo ignores parse errors, but older versions of cargo do not (it fails with dep-info invalid
error). Not strictly necessary since switching to an older nightly is unusual, but might be worth avoiding.
There are a few comments that I'd like to see updated with the new behavior. Ones that I see (github won't let me annotate them):
- A brief note in the module-docs section "dep-info files" about env var support.
LocalFingerprint::find_stale_item
"a stale file or env var".parse_dep_info
"a list of paths and env vars"
Ok(Some(paths)) | ||
let info = match OnDiskDepInfo::parse(&data) { | ||
Some(info) => info, | ||
None => return Ok(None), |
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.
Could this at least log a warning that it failed to parse the dep-info file? I assume this would only happen if the file is corrupt (or in some different format?). I assume you changed this so if the format is changed again in the future, cargo will just silently rebuild (which seems like the correct approach).
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.
Hm actually I misinterpreted the previous code. I thought the previous iteration also ignored parsing errors but it looks like it only ignores I/O and/or not present errors. I do think, though, that it's reasonable to ignore corrupt files here since we'll rewrite them later anyway.
f0be800
to
643f12e
Compare
Ok updated! |
Not sure if you saw the note about changing the version in |
Er oops sorry I saw that and then completely forgot to add it, I'll look into escaping, I don't know what kind of escaping rustc does... |
Ok read up on the escaping rustc does and am now matching that here too |
Thanks, looks good! @bors r+ |
📌 Commit 0750a6f has been approved by |
☀️ Test successful - checks-azure |
Update cargo ## cargo 10 commits in c26576f9adddd254b3dd63aecba176434290a9f6..305eaf0dc5f5a38d6e8041319c2da95b71cf6a4a 2020-06-23 16:21:21 +0000 to 2020-06-30 14:16:08 +0000 - Update core-foundation requirement from 0.7.0 to 0.9.0 (rust-lang/cargo#8432) - Parse `# env-dep` directives in dep-info files (rust-lang/cargo#8421) - Move string interning to util (rust-lang/cargo#8419) - Expose built cdylib artifacts in the Compilation structure (rust-lang/cargo#8418) - Remove unused serde_derive dependency from the crates.io crate (rust-lang/cargo#8416) - Remove unused remove_dir_all dependency (rust-lang/cargo#8412) - Improve git error messages a bit (rust-lang/cargo#8409) - Improve the description of Config.home_path (rust-lang/cargo#8408) - Improve support for non-`master` main branches (rust-lang/cargo#8364) - Document that OUT_DIR in JSON messages is an absolute path (rust-lang/cargo#8403) ## rls 2020-06-19 15:36:00 +0200 to 2020-06-30 23:34:52 +0200 - Update cargo (rust-lang/rls#1686)
Update cargo, rls ## cargo 14 commits in c26576f9adddd254b3dd63aecba176434290a9f6..fede83ccf973457de319ba6fa0e36ead454d2e20 2020-06-23 16:21:21 +0000 to 2020-07-02 21:51:34 +0000 - Fix overflow error on 32-bit. (rust-lang/cargo#8446) - Exclude the target directory from backups using CACHEDIR.TAG (rust-lang/cargo#8378) - CONTRIBUTING.md: Link to Zulip rather than Discord (rust-lang/cargo#8436) - Update built-in help for features (rust-lang/cargo#8433) - Update core-foundation requirement from 0.7.0 to 0.9.0 (rust-lang/cargo#8432) - Parse `# env-dep` directives in dep-info files (rust-lang/cargo#8421) - Move string interning to util (rust-lang/cargo#8419) - Expose built cdylib artifacts in the Compilation structure (rust-lang/cargo#8418) - Remove unused serde_derive dependency from the crates.io crate (rust-lang/cargo#8416) - Remove unused remove_dir_all dependency (rust-lang/cargo#8412) - Improve git error messages a bit (rust-lang/cargo#8409) - Improve the description of Config.home_path (rust-lang/cargo#8408) - Improve support for non-`master` main branches (rust-lang/cargo#8364) - Document that OUT_DIR in JSON messages is an absolute path (rust-lang/cargo#8403) ## rls 2020-06-19 15:36:00 +0200 to 2020-06-30 23:34:52 +0200 - Update cargo (rust-lang/rls#1686)
…ulacrum build: Remove unnecessary `cargo:rerun-if-env-changed` annotations ... and a couple of related cleanups. rustc and cargo now track the majority of env var dependencies automatically (rust-lang/cargo#8421), so the annotations are no longer necessary.
…ulacrum build: Remove unnecessary `cargo:rerun-if-env-changed` annotations ... and a couple of related cleanups. rustc and cargo now track the majority of env var dependencies automatically (rust-lang/cargo#8421), so the annotations are no longer necessary.
…ulacrum build: Remove unnecessary `cargo:rerun-if-env-changed` annotations ... and a couple of related cleanups. rustc and cargo now track the majority of env var dependencies automatically (rust-lang/cargo#8421), so the annotations are no longer necessary.
…ulacrum build: Remove unnecessary `cargo:rerun-if-env-changed` annotations ... and a couple of related cleanups. rustc and cargo now track the majority of env var dependencies automatically (rust-lang/cargo#8421), so the annotations are no longer necessary.
// that's used for code generation but this is technically buggy where if | ||
// you write a binary that does `println!("{}", env!("OUT_DIR"))` we won't | ||
// recompile that if you move the target directory. Hopefully that's not too | ||
// bad of an issue for now... |
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.
@alecmocatta I think this comment here exactly describes your issue https://github.com/rust-lang/rust/issues/76511 ;)
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.
Yes I believe it does, thanks for finding this @RalfJung!
This commit updates Cargo's parsing of rustc's dep-info files to account
for changes made upstream in rust-lang/rust#71858. This means that if
env!
oroption_env!
is used in crate files Cargo will correctlyrebuild the crate if the env var changes.
Closes #8417