-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Add binary dependencies to dep-info files #61727
Conversation
Based on local testing once this is in the beta compiler we can delete in-stage |
src/librustc_interface/passes.rs
Outdated
.files() | ||
.iter() | ||
.filter(|fmap| fmap.is_real_file()) | ||
.filter(|fmap| !fmap.is_imported()) | ||
.map(|fmap| escape_dep_filename(&fmap.name)) | ||
.collect(); | ||
|
||
for cnum in compiler.cstore.crates_untracked() { |
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.
Does this include all crates in library search paths, or only the ones brought in via extern crate
?
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 believe it'll be only those "used" (extern crate, use, etc)
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.
Can you add a test confirming this?
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 think such a test would be relatively complicated (probably some sort of run-make, I guess) but basically the crates_untracked()
bit here starting to pick up all tests would be noticed by plenty of other tests AFAIK since it interacts with incremental, etc. too. I have confirmed manually that not all crates in the sysroot and other search paths show up.
cc #57717 |
So to confirm that I understand the change here, the purpose of this is that rustbuild wants to do less manual cleaning and instead rely on Cargo as much as it can to automatically rebuild things. Rustbuild will always execute Cargo 6 times (std0, test0, rustc0, std1, test1, rustc1), but the idea is that today between each of these invocations we have this weird The purpose of this patch is to tell Cargo more about the dep-info of inputs. Cargo currently today uses dep-info to learn about source code to recompile when something changes, but naturally if any of the binary dependencies (like libstd) change the crate also needs to be recompiled. That's the purpose of this, right? Can you also test out that this doesn't break Cargo? It should be the case that |
Yes, that's the plan once this patch is in a beta compiler. We'll still need clear_if_dirty checks between stages (for
Yes, exactly -- I think this is probably the 95% solution or so, as it doesn't track native dependencies (C libraries that we link to, primarily), but I'm not sure to what extent we know about those when we emit dep-info. I can investigate adding them but since they're not really the primary use case I think it can probably be delayed for a later patch. Cargo tests all pass with this change; some of the logic in Cargo may no longer be necessary (i.e., we are possibly double-fingerprinting rlibs, etc. and can skip that work now), but that's more of a performance question, not a correctness question. I'm also not sure whether Cargo fingerprints rlibs at all. |
@bors: r+ Nice! That all sounds great to me! I agree that Cargo is probably double fingerprinting things or checking too much, but that's ok until it causes issues :) FWIW I'd love to get rid of |
📌 Commit da73a36 has been approved by |
That's strange. I'm getting a few errors. plugins::plugin_to_the_max---- plugins::plugin_to_the_max stdout ---- running `/Users/eric/Proj/rust/cargo/target/debug/cargo build` running `/Users/eric/Proj/rust/cargo/target/debug/cargo doc` thread 'plugins::plugin_to_the_max' panicked at ' Expected: execs but: exited with exit code: 101 --- stdout 1 freshness::rename_with_path_deps---- freshness::rename_with_path_deps stdout ---- running `/Users/eric/Proj/rust/cargo/target/debug/cargo build` running `/Users/eric/Proj/rust/cargo/target/debug/cargo build` thread 'freshness::rename_with_path_deps' panicked at ' Expected: execs but: differences: 0 - |[FINISHED] [..]| + | Compiling a v0.5.0 (/Users/eric/Proj/rust/cargo/target/cit/t695/foo2/a)| Maybe it's because I'm running on macos? I can dig in a little later. |
@bors: r- |
I cannot reproduce either failure on either macOS or Linux so I think maybe CI is our best bet at this point. As a starting point, let's try to get official builds on at least Linux: @bors try |
Add binary dependencies to dep-info files I'm not sure about the lack of incremental-tracking here, but since I'm pretty sure this runs on every compile anyway it might not matter? If there's a better place/way to get at the information I want, I'm happy to refactor the code to match. r? @alexcrichton
The rustdoc error went away after I did The issue is that the dep-info file contains absolute paths like FYI, I don't think using EDIT: Or don't use rustup, as in: |
Just to double-check: after this gets into beta, we can fix #54712 relatively easily, right? |
Okay, I'm able to reproduce the Cargo test failure now -- I'm not sure how easily we can fix that. Maybe I can remove the behavior of including non-sysroot dependencies (or anything passed via I'm personally not sure that such a test is critical -- it appears to have been added by rust-lang/cargo@e9428cb. I feel like the case of moving the directory is largely uncommon so regressing on it may not be that bad? @alexcrichton, what do you think?
I think it'll be fixed trivially, yes, but there may be unexpected roadblocks down the line, I'm not sure. |
☀️ Try build successful - checks-travis |
I was hoping this would fix #59105 (I run into it a lot), but cargo does not parse the dep-info file for registry dependencies. 😢 |
Oh, hm, that's rather a blocker for this being useful for rustbuild. Can we remove that limitation? Presumably it's for performance reasons? |
Hm so we should handle absolute paths in dep files since Cargo's own internal format stores everything relative to the project root (or something like that, I remember something along those lines). I do think this is a feature we need to preserve in Cargo, it's been requested for CI systems historically where caches are persisted but the build directory changes over time. We don't track dep-info files for registry deps because dep info tracking is historically only giving us source information, and there's no need to track source information for registry deps because cargo assumes it can't change. If we learn about sysroot dependencies as well though then we could probably go ahead and parse it, it's not exactly a slow part of the build! |
For reference this is the new cargo.d when building with this PR applied; the new content starts at line 142. I'm investigating why we're not properly handling paths to dependencies in Cargo and will likely file a PR with necessary changes soon.
I'll include a patch which enables parsing and tracking dep-files for dependencies as well (or file a separate PR for it, depending on complexity). |
Marking this as S-blocked on rust-lang/cargo#7030 and rust-lang/cargo#7034. |
…chton Support absolute paths in dep-info files These changes are a little more invasive then I would've liked, but I couldn't come up with a significantly better way to structure this. Comments (or backwards-compat) concerns are appreciated, of course! cc rust-lang/rust#61727 r? @alexcrichton
@Mark-Simulacrum I've been testing this on Windows and am having problems with it creating a mixture of dos paths and device paths. That is, I see things like:
Would it be possible to get all one style? It makes it difficult to check for the prefix in Cargo. Cargo typically uses dos-style paths, since that's the default for most rust things. Or if you have ideas how to easily handle both kinds, that would be great. |
I would expect us to have all once style... I'm guessing some part of the compiler isn't properly handling these paths and/or is canonicalizing them unlike the others. It might be rather hard for me to debug since I don't have easy access to windows... but I do think it should be possible to make the path types uniform. I'll look at what I can do to debug Windows in a bit. |
@ehuss if you put paths through |
@ehuss You should probably canonicalize both sides before checking for prefix, but I would try to avoid giving the user UNC paths, because of the arguable worse UX. |
The compiler uses I think what's happening is Cargo is executing rustc as:
which emits:
One thing Cargo should be sure to do is handle whatever path comes from users and work regardless of whether it's UNC or otherwise absolute. In this case, however, I think all paths are synthesized by Cargo and passed down to rustc. With that background, I think there's perhaps two ways to fix this issue @ehuss raised. One is that rustc could be less aggressive about printing UNC paths. The path to the standard library, for example, seems reasonable to be UNC. The path to Alternatively Cargo, since it's synthesizing all the arguments here, could more aggressively canoicalize everything going into rustc. For example it could canonicalize the value of I would suspect in terms of man-hours its easier to change Cargo instead of rustc, but this is arguably not a great feature of rustc that it's canonicalizing paths in its output where it doesn't do that anywhere else. |
I often use the free VMs from microsoft when I'm not near a windows machine. I added a hack to my Cargo PR to deal with the extended-length paths. I don't have much of an opinion on it, but I'd be curious if there are any other consumers of the |
Yes, I'm aware of the free VMs (though I use these). I also don't know Windows at all so getting started is usually quite a hassle -- if it becomes necessary, I can invest the time it'll take me to get Windows working, but I'd rather not, if that makes sense :) I think I agree with Alex here that fixing/doing the right thing in Cargo would be easier than modifying rustc. I think we don't guarantee the .d contents too much today so it should be feasible to fix this in rustc itself later down the road. |
I think @ehuss actually brings up a good point, can this be tested to make sure it actually works on Windows with |
I spent a couple hours yesterday trying to get a Windows VM working to compile Rust within it, but unfortunately didn't really make any headway. I can try to get just make working and attempt to synthesize a |
da73a36
to
d749b5e
Compare
@alexcrichton I've now implemented a |
@bors: r+ Sounds good to me! |
📌 Commit d749b5e has been approved by |
… r=alexcrichton Add binary dependencies to dep-info files I'm not sure about the lack of incremental-tracking here, but since I'm pretty sure this runs on every compile anyway it might not matter? If there's a better place/way to get at the information I want, I'm happy to refactor the code to match. r? @alexcrichton
Rollup of 9 pull requests Successful merges: - rust-lang#61727 (Add binary dependencies to dep-info files) - rust-lang#62736 (Polonius: fix some cases of `killed` fact generation, and most of the `ui` test suite) - rust-lang#62758 (ci: Install clang on Windows through tarballs) - rust-lang#62784 (Add riscv32i-unknown-none-elf target) - rust-lang#62814 (add support for hexagon-unknown-linux-musl) - rust-lang#62827 (Don't link mcjit/interpreter LLVM components) - rust-lang#62901 (cleanup: Remove `extern crate serialize as rustc_serialize`s) - rust-lang#62903 (Support SDKROOT env var on iOS) - rust-lang#62906 (Require a value for configure --debuginfo-level) Failed merges: - rust-lang#62910 (cleanup: Remove lint annotations in specific crates that are already enforced by rustbuild) r? @ghost
Rollup of 9 pull requests Successful merges: - #61727 (Add binary dependencies to dep-info files) - #62736 (Polonius: fix some cases of `killed` fact generation, and most of the `ui` test suite) - #62758 (ci: Install clang on Windows through tarballs) - #62784 (Add riscv32i-unknown-none-elf target) - #62814 (add support for hexagon-unknown-linux-musl) - #62827 (Don't link mcjit/interpreter LLVM components) - #62901 (cleanup: Remove `extern crate serialize as rustc_serialize`s) - #62903 (Support SDKROOT env var on iOS) - #62906 (Require a value for configure --debuginfo-level) Failed merges: - #62910 (cleanup: Remove lint annotations in specific crates that are already enforced by rustbuild) r? @ghost
Fix some issues with absolute paths in dep-info files. There were some issues with how #7030 was handling translating paths in dep-info files. The main consequence is that when coupled with rust-lang/rust#61727 (which has not yet merged), the fingerprint would fail and be considered dirty when it should be fresh. It was joining [`target_root`](https://github.com/rust-lang/cargo/blame/1140c527c4c3b3e2533b9771d67f88509ef7fc16/src/cargo/core/compiler/fingerprint.rs#L1352-L1360) which had 3 different values, but stripping [only one](https://github.com/rust-lang/cargo/blame/1140c527c4c3b3e2533b9771d67f88509ef7fc16/src/cargo/core/compiler/mod.rs#L323). This means for different scenarios (like using `--target`), it was creating incorrect paths in some cases. For example a target having a proc-macro dependency which would be in the host directory. The solution here is to always use CARGO_TARGET_DIR as the base that all relative paths are checked against. This should handle all host/target differences. The tests are marked with `#[ignore]` because 61727 has not yet merged. This includes a second commit (which I can open as a separate PR if needed) which is an alternate solution to #7034. It adds dep-info tracking for registry dependencies. However, it tries to limit which kinds of paths it tracks. It will not track package-relative paths (like source files). It also adds an mtime cache to significantly reduce the number of stat calls (because every dependency was stating every file in sysroot). Finally, I've run some tests using this PR with 61727 in rust-lang/rust. I can confirm that a second build is fresh (it doesn't erroneously rebuild). I can also confirm that the problem in rust-lang/rust#59105 has *finally* been fixed! My confidence in all this is pretty low, but I've been unable to think of any specific ways to make it fail. If anyone has ideas on how to better test this, let me know. Also, feel free to ask questions since I've been thinking about this a lot for the past few weeks, and there is quite a bit of subtle stuff going on.
I'm not sure about the lack of incremental-tracking here, but since I'm pretty sure this runs on every compile anyway it might not matter? If there's a better place/way to get at the information I want, I'm happy to refactor the code to match.
r? @alexcrichton