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

Be more conservative about which files are linked to the output dir. #5460

Merged
merged 4 commits into from
May 10, 2018

Conversation

ehuss
Copy link
Contributor

@ehuss ehuss commented May 2, 2018

This changes it so that only top-level targets requested on the command-line will be included in the output directory. Dependencies are no longer included.

Fixes #5444.

@rust-highfive
Copy link

r? @matklad

(rust_highfive has picked a reviewer for you, use r? to override)

@ehuss
Copy link
Contributor Author

ehuss commented May 2, 2018

I'm concerned about this breaking other projects. Let me know if you have ideas for public projects I could test that might be at risk of being affected.

Copy link
Member

@matklad matklad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, though I, being recently burnt with the --features flag, fear that this change might break someones build :)

Let's hold this off until the beta is branched perhaps?

let &(ref dir, ref roots) = self.export_dir.as_ref()?;
if roots.contains(unit) {
Some(dir.clone())
if self.roots.contains(unit) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this check is no longer necessary, because we now do the same filtering for target_dir and export_dir

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds correct, I have removed it.

@matklad
Copy link
Member

matklad commented May 2, 2018

Let me know if you have ideas for public projects I could test that might be at risk of being affected.

Servo definitely is worth checking!

if self.ws.members().find(|&p| p == unit.pkg).is_none() && !unit.target.is_bin() {
None
} else {
if self.roots.contains(unit) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a little suspect in the sense that this is pretty carefully crafted and I'm wary to switch wholesale to roots. Could we perhaps start off by basically skipping any rlib units? That is, we only care about binaries in the main workspace, mostly (and dylib/staticlib/cdylib/etc)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do that, though I felt like that would be a bigger change. It would still leave behind the race condition for the other output types (particularly rmeta files, though they don't cause catastrophic failures).

I made an experimental branch to try this here: ehuss@68e7d2e
It seems more risky to me, though.

It seems like a pretty heavy change just to avoid these non-panic dependencies. I'm still trying to think if there's an easier way...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm ok yeah it's definitely not worth this becoming a larger change.

So today the logic for "should I hardlink this up" is basically "am I a workspace member or am I a binary". That encompasses far too much as workspace member rlibs/rmeta have no business being linked up.

So this is instead saying that "if you were originally requested you're linked up". That includes libraries and rmeta business but you can't request more than one (even though we may compile many), so we should be resolving the race this way.

Writing this all down, I think the only difference is that all other workspace members aren't automatically linked up. I don't think, however, that it was possible for a workspace member to generate a relevant binary/staticlib for us to link upwards.

Or well, in other words, I think that this should be correct. I can't think of a way in which it would be wrong at least! In light of that I think we should be good to merge as soon as beta is branched.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what might go wrong are dynamic libraries. We add top target directory to LD_LIBRARY_PATH:

search_path.push(self.root_output.clone());
search_path.push(self.deps_output.clone());

However, in the next line we add the deps dir as well, so we should be fine here as well!

@ehuss
Copy link
Contributor Author

ehuss commented May 2, 2018

Let's hold this off until the beta is branched perhaps?

If we delay, we should probably temporarily disable the two _build_all_targets tests I added to avoid spurious CI errors.

@alexcrichton
Copy link
Member

I think this is fixing active regressions, though, right? In that sense we may not want to delay it?

@ehuss
Copy link
Contributor Author

ehuss commented May 2, 2018

I think this is fixing active regressions, though, right?

Not exactly. cargo build --all-targets with a panic profile didn't work at all in previous versions. The only other way I can think of to trigger the race condition is to use the new build-override profile with a shared dependency in a workspace.

@alexcrichton
Copy link
Member

Ah ok makes sense! Then yeah it's probably good to hold off until next week to merget (but we can sort out in the meantime)

ehuss added 4 commits May 10, 2018 08:46
This changes it so that only top-level targets requested on the command-line will be included in the output directory.  Dependencies are no longer included.

Fixes rust-lang#5444.
@ehuss
Copy link
Contributor Author

ehuss commented May 10, 2018

I've been trying to think of a less risky way to implement this, but I haven't been able to come up with anything good. Let me know if I should try something else. Unfortunately I'm not familiar with the use cases where a crate would depend on a cdylib/staticlib, so I'm not clear if/how it might be a problem.

@alexcrichton
Copy link
Member

@bors: r+

@bors
Copy link
Contributor

bors commented May 10, 2018

📌 Commit d0c2939 has been approved by alexcrichton

@bors
Copy link
Contributor

bors commented May 10, 2018

⌛ Testing commit d0c2939 with merge ef719bc...

bors added a commit that referenced this pull request May 10, 2018
Be more conservative about which files are linked to the output dir.

This changes it so that only top-level targets requested on the command-line will be included in the output directory.  Dependencies are no longer included.

Fixes #5444.
@bors
Copy link
Contributor

bors commented May 10, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: alexcrichton
Pushing ef719bc to master...

@bors bors merged commit d0c2939 into rust-lang:master May 10, 2018
ehuss added a commit to ehuss/cargo that referenced this pull request May 10, 2018
Fixes rust-lang#5435

Also re-enable tests now that rust-lang#5460 has landed.
bors added a commit that referenced this pull request May 10, 2018
Fix `panic` for binaries built during tests.

Fixes #5435

Also re-enable tests now that #5460 has landed.
ehuss added a commit to ehuss/rust that referenced this pull request May 14, 2018
Regression fixes:
- rust-lang/cargo#5503 - cargo rustc broken for tests in project with bins
- rust-lang/cargo#5520 - (rust-lang#50640) shared proc-macro dependency built incorrectly

Changes:
- rust-lang/cargo#5522 - Add option to set user-agent
- rust-lang/cargo#5519 - NFC: fix a couple of typos, found by codespell.
- rust-lang/cargo#5513 - Fix `panic` for binaries built during tests.
- rust-lang/cargo#5512 - simplify build_requirements
- rust-lang/cargo#5301 - Add --build-plan for 'cargo build'
- rust-lang/cargo#5460 - Be more conservative about which files are linked to the output dir.
- rust-lang/cargo#5509 - Use the new stable
- rust-lang/cargo#5507 - Does not print seconds fraction with minutes
- rust-lang/cargo#5498 - Bump to 0.29.0
- rust-lang/cargo#5497 - Mention +nightly in ARCHITECTURE.md
kennytm added a commit to kennytm/rust that referenced this pull request May 14, 2018
Update Cargo

Regression fixes:
- rust-lang/cargo#5503 - cargo rustc broken for tests in project with bins
- rust-lang/cargo#5520 - (rust-lang#50640) shared proc-macro dependency built incorrectly

Changes:
- rust-lang/cargo#5522 - Add option to set user-agent
- rust-lang/cargo#5519 - NFC: fix a couple of typos, found by codespell.
- rust-lang/cargo#5513 - Fix `panic` for binaries built during tests.
- rust-lang/cargo#5512 - simplify build_requirements
- rust-lang/cargo#5301 - Add --build-plan for 'cargo build'
- rust-lang/cargo#5460 - Be more conservative about which files are linked to the output dir.
- rust-lang/cargo#5509 - Use the new stable
- rust-lang/cargo#5507 - Does not print seconds fraction with minutes
- rust-lang/cargo#5498 - Bump to 0.29.0
- rust-lang/cargo#5497 - Mention +nightly in ARCHITECTURE.md
ehuss added a commit to ehuss/rust that referenced this pull request May 15, 2018
Unblocking PRs:
- rust-lang/cargo#5535 - Ignore <tab> in libtest output. (unblocks rust-lang#50387)
- rust-lang/cargo#5537 - Remove -Zno-trans test. (unblocks rust-lang#50615)
- rust-lang/cargo#5540 - Fix tests when CARGO_TARGET_DIR is set. (unblocks self)

Regression fixes:
- rust-lang/cargo#5503 - cargo rustc broken for tests in project with bins
- rust-lang/cargo#5520 - (rust-lang#50640) shared proc-macro dependency built incorrectly

Changes:
- rust-lang/cargo#5527 - Point Source Replacement to the Overriding Dependencies section
- rust-lang/cargo#5533 - Detail how to run locally-built nightly cargo
- rust-lang/cargo#5522 - Add option to set user-agent
- rust-lang/cargo#5519 - NFC: fix a couple of typos, found by codespell.
- rust-lang/cargo#5513 - Fix `panic` for binaries built during tests.
- rust-lang/cargo#5512 - simplify build_requirements
- rust-lang/cargo#5301 - Add --build-plan for 'cargo build'
- rust-lang/cargo#5460 - Be more conservative about which files are linked to the output dir.
- rust-lang/cargo#5509 - Use the new stable
- rust-lang/cargo#5507 - Does not print seconds fraction with minutes
- rust-lang/cargo#5498 - Bump to 0.29.0
- rust-lang/cargo#5497 - Mention +nightly in ARCHITECTURE.md
kennytm added a commit to kennytm/rust that referenced this pull request May 15, 2018
Update Cargo

Unblocking PRs:
- rust-lang/cargo#5535 - Ignore <tab> in libtest output. (unblocks rust-lang#50387)
- rust-lang/cargo#5537 - Remove -Zno-trans test. (unblocks rust-lang#50615)
- rust-lang/cargo#5540 - Fix tests when CARGO_TARGET_DIR is set. (unblocks self)

Regression fixes:
- rust-lang/cargo#5503 - cargo rustc broken for tests in project with bins
- rust-lang/cargo#5520 - (rust-lang#50640) shared proc-macro dependency built incorrectly

Changes:
- rust-lang/cargo#5527 - Point Source Replacement to the Overriding Dependencies section
- rust-lang/cargo#5533 - Detail how to run locally-built nightly cargo
- rust-lang/cargo#5522 - Add option to set user-agent
- rust-lang/cargo#5519 - NFC: fix a couple of typos, found by codespell.
- rust-lang/cargo#5513 - Fix `panic` for binaries built during tests.
- rust-lang/cargo#5512 - simplify build_requirements
- rust-lang/cargo#5301 - Add --build-plan for 'cargo build'
- rust-lang/cargo#5460 - Be more conservative about which files are linked to the output dir.
- rust-lang/cargo#5509 - Use the new stable
- rust-lang/cargo#5507 - Does not print seconds fraction with minutes
- rust-lang/cargo#5498 - Bump to 0.29.0
- rust-lang/cargo#5497 - Mention +nightly in ARCHITECTURE.md
ehuss added a commit to ehuss/rust that referenced this pull request May 16, 2018
Unblocking PRs:
- rust-lang/cargo#5535 - Ignore <tab> in libtest output. (unblocks rust-lang#50387)
- rust-lang/cargo#5537 - Remove -Zno-trans test. (unblocks rust-lang#50615)
- rust-lang/cargo#5540 - Fix tests when CARGO_TARGET_DIR is set. (unblocks self)

Regression fixes:
- rust-lang/cargo#5503 - cargo rustc broken for tests in project with bins
- rust-lang/cargo#5520 - (rust-lang#50640) shared proc-macro dependency built incorrectly

Changes:
- rust-lang/cargo#5527 - Point Source Replacement to the Overriding Dependencies section
- rust-lang/cargo#5533 - Detail how to run locally-built nightly cargo
- rust-lang/cargo#5522 - Add option to set user-agent
- rust-lang/cargo#5519 - NFC: fix a couple of typos, found by codespell.
- rust-lang/cargo#5513 - Fix `panic` for binaries built during tests.
- rust-lang/cargo#5512 - simplify build_requirements
- rust-lang/cargo#5301 - Add --build-plan for 'cargo build'
- rust-lang/cargo#5460 - Be more conservative about which files are linked to the output dir.
- rust-lang/cargo#5509 - Use the new stable
- rust-lang/cargo#5507 - Does not print seconds fraction with minutes
- rust-lang/cargo#5498 - Bump to 0.29.0
- rust-lang/cargo#5497 - Mention +nightly in ARCHITECTURE.md
bors added a commit to rust-lang/rust that referenced this pull request May 16, 2018
Update Cargo

Unblocking PRs:
- rust-lang/cargo#5535 - Ignore tab in libtest output. (unblocks #50387)
- rust-lang/cargo#5537 - Remove -Zno-trans test. (unblocks #50615)
- rust-lang/cargo#5540 - Fix tests when CARGO_TARGET_DIR is set. (unblocks self)

Regression fixes:
- rust-lang/cargo#5503 - cargo rustc broken for tests in project with bins
- rust-lang/cargo#5520 - shared proc-macro dependency built incorrectly

Changes:
- rust-lang/cargo#5527 - Point Source Replacement to the Overriding Dependencies section
- rust-lang/cargo#5533 - Detail how to run locally-built nightly cargo
- rust-lang/cargo#5522 - Add option to set user-agent
- rust-lang/cargo#5519 - NFC: fix a couple of typos, found by codespell.
- rust-lang/cargo#5513 - Fix `panic` for binaries built during tests.
- rust-lang/cargo#5512 - simplify build_requirements
- rust-lang/cargo#5301 - Add --build-plan for 'cargo build'
- rust-lang/cargo#5460 - Be more conservative about which files are linked to the output dir.
- rust-lang/cargo#5509 - Use the new stable
- rust-lang/cargo#5507 - Does not print seconds fraction with minutes
- rust-lang/cargo#5498 - Bump to 0.29.0
- rust-lang/cargo#5497 - Mention +nightly in ARCHITECTURE.md

The PR fixes #50640.
alexcrichton added a commit to alexcrichton/cargo that referenced this pull request Jun 29, 2018
There's a case where Cargo will recompile a project even if the fingerprint
looks like it's fresh, when some output files are missing. This was intended to
cover the case where an output file was deleted manually or otherwise messed
with. The check here was a bit too eager, however. It checked not only the
actual output destination of the compiler but *also* the location that we hard
link the output file up to.

Due to recent changes in rust-lang#5460 we don't always create the hard links for path
dependencies in the top-level dir, and this meant that if the library were
compiled and then tested later on the test may recompile the original library by
accident.

The fix in this commit is to cease looking for the hardlink if it exists or not.
This way we only check for the presence of the output file itself and only
recompile if that file is missing. The reason for this is that we
unconditionally relink files into place whether it's fresh or not, so we'll
always recreate the hard link anyway if it's missing.

cc rust-lang/rust#51717
bors added a commit that referenced this pull request Jun 29, 2018
Fix avoiding a rebuild when moving around a workspace

There's a case where Cargo will recompile a project even if the fingerprint
looks like it's fresh, when some output files are missing. This was intended to
cover the case where an output file was deleted manually or otherwise messed
with. The check here was a bit too eager, however. It checked not only the
actual output destination of the compiler but *also* the location that we hard
link the output file up to.

Due to recent changes in #5460 we don't always create the hard links for path
dependencies in the top-level dir, and this meant that if the library were
compiled and then tested later on the test may recompile the original library by
accident.

The fix in this commit is to cease looking for the hardlink if it exists or not.
This way we only check for the presence of the output file itself and only
recompile if that file is missing. The reason for this is that we
unconditionally relink files into place whether it's fresh or not, so we'll
always recreate the hard link anyway if it's missing.

cc rust-lang/rust#51717
Mark-Simulacrum pushed a commit to Mark-Simulacrum/cargo that referenced this pull request Jun 29, 2018
There's a case where Cargo will recompile a project even if the fingerprint
looks like it's fresh, when some output files are missing. This was intended to
cover the case where an output file was deleted manually or otherwise messed
with. The check here was a bit too eager, however. It checked not only the
actual output destination of the compiler but *also* the location that we hard
link the output file up to.

Due to recent changes in rust-lang#5460 we don't always create the hard links for path
dependencies in the top-level dir, and this meant that if the library were
compiled and then tested later on the test may recompile the original library by
accident.

The fix in this commit is to cease looking for the hardlink if it exists or not.
This way we only check for the presence of the output file itself and only
recompile if that file is missing. The reason for this is that we
unconditionally relink files into place whether it's fresh or not, so we'll
always recreate the hard link anyway if it's missing.

cc rust-lang/rust#51717
bors added a commit that referenced this pull request Jun 29, 2018
Fix avoiding a rebuild when moving around a workspace

This is a backport of #5669.

There's a case where Cargo will recompile a project even if the fingerprint
looks like it's fresh, when some output files are missing. This was intended to
cover the case where an output file was deleted manually or otherwise messed
with. The check here was a bit too eager, however. It checked not only the
actual output destination of the compiler but *also* the location that we hard
link the output file up to.

Due to recent changes in #5460 we don't always create the hard links for path
dependencies in the top-level dir, and this meant that if the library were
compiled and then tested later on the test may recompile the original library by
accident.

The fix in this commit is to cease looking for the hardlink if it exists or not.
This way we only check for the presence of the output file itself and only
recompile if that file is missing. The reason for this is that we
unconditionally relink files into place whether it's fresh or not, so we'll
always recreate the hard link anyway if it's missing.

cc rust-lang/rust#51717

r? @alexcrichton
bors added a commit that referenced this pull request Oct 12, 2018
Fix dylib reuse with uplift.

Due to #5460, the files that are copied to the root of the target dir depend on whether or not it is a direct target. This causes a problem with dylibs if you build a dylib directly, and then separately run a target that depends on that dylib.  It will run with the dylib path preferring the root dir, which picks up the old dylib.  This PR swaps the preference of the dylib search path so that the dylib in the `deps` dir is preferred.

This is maybe not the best solution for dynamic dependencies. I can imagine if you are trying to create a package, you'll want all of the shared libs along with the binary, and digging through the `deps` dir is not optimal.  However, unconditionally linking dependencies into the root has issues (which #5460 fixed).  There are other issues because shared libs do not include a hash in the filename.  A grander solution might involve coming up with a better strategy for organizing the `target` directory to avoid conflicts between targets.

Fixes #6162
@ehuss ehuss added this to the 1.28.0 milestone Feb 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Race condition when trying to compile a lib multiple times for different purposes.
5 participants