-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Make sure search paths inside OUT_DIR precede external paths #15221
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
Make sure search paths inside OUT_DIR precede external paths #15221
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @ehuss (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
Not sure what the CI failure for "check-version-bump" is but I'm assuming it's some minor book keeping that's validating a version number somewhere needs to be bumped because I made a consequential change? But the output when running locally doesn't make sense to me:
I haven't touched |
That CI job failure is completely unrelated to this PR. See #15222. |
Just note that it is generally recommended an issue to be discussed and labeled as https://doc.crates.io/contrib/process/working-on-cargo.html#before-hacking-on-cargo |
Good note but I also wanted to see how difficult such a change would be to help guide any questions that might come up in the issue. |
9bdda46
to
c8d12c5
Compare
I think I've resolved all the outstanding review requests. Please let me know if there's any other concerns. I did add a comment to the LibraryPath documentation that may be worth discussing (but also OK just leaving this for future consideration):
@rustbot review |
c8d12c5
to
97bc22f
Compare
@rustbot author |
Will need it in a follow-up PR
97bc22f
to
3bb95ae
Compare
Regardless of crate search paths emitted, always prefer searching search paths pointing into the artifacts directory to those pointing outside. This way libraries built by Cargo are preferred even if the same library name exists in the system & a crate earlier in the build process emitted a system library path for searching.
3bb95ae
to
6c6b34e
Compare
@rustbot review |
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.
Thank you for working with us! I really love how you documented the rationale and how the code is organized.
This looks great. Going to merge it :)
Update cargo 4 commits in 864f74d4eadcaea3eeda37a2e7f4d34de233d51e..d811228b14ae2707323f37346aee3f4147e247e6 2025-04-11 20:37:27 +0000 to 2025-04-15 15:18:42 +0000 - use `zlib-rs` for gzip compression in rust code (rust-lang/cargo#15417) - test(rustfix): Use `snapbox` for snapshot testing (rust-lang/cargo#15429) - chore(deps): update rust crate gix to 0.71.0 [security] (rust-lang/cargo#15391) - Make sure search paths inside OUT_DIR precede external paths (rust-lang/cargo#15221) Also, * The license exception of sha1_smol with BSD-3-Clause is no longer needed, as `gix-*` doesn't depend on it. * Cargo depends on zlib-rs, which is distributed under Zlib license r? ghost
Update cargo 4 commits in 864f74d4eadcaea3eeda37a2e7f4d34de233d51e..d811228b14ae2707323f37346aee3f4147e247e6 2025-04-11 20:37:27 +0000 to 2025-04-15 15:18:42 +0000 - use `zlib-rs` for gzip compression in rust code (rust-lang/cargo#15417) - test(rustfix): Use `snapbox` for snapshot testing (rust-lang/cargo#15429) - chore(deps): update rust crate gix to 0.71.0 [security] (rust-lang/cargo#15391) - Make sure search paths inside OUT_DIR precede external paths (rust-lang/cargo#15221) Also, * The license exception of sha1_smol with BSD-3-Clause is no longer needed, as `gix-*` doesn't depend on it. * Cargo depends on zlib-rs, which is distributed under Zlib license r? ghost
If a library exists both in an added folder inside OUT_DIR and in the OS, prefer to use the one within OUT_DIR. Folders within OUT_DIR and folders outside OUT_DIR do not change their relative order between themselves.
This is accomplished by sorting by whether we think the path is inside the search path or outside.
What does this PR try to resolve?
Fixes #15220. If a Rust crates builds a dynamic library & that same dynamic library is installed in the host OS, the result of the build's success & consistent behavior of executed tools depends on whether or not the user has the conflicting dynamic library in the external search path. If they do, then the host OS library will always be used which is unexpected - updates to your Rust dependency will still have you linking & running against an old host OS library (i.e. someone who doesn't have that library has a different silent behavior).
How should we test and review this PR?
This is what I did to verify my issue got resolved but I'm sure there's a simpler example one could construct.
dynamic-link
feature.Before my change, it fails with a linker error saying it can't find
llama_model_n_head_kv
because /usr/lib appears in the search path before the directory that contains the libllama.so that was built internally by the crate. This is because cpal depends on alsa-sys which uses pkg-config which adds /usr/lib to the search path before the llama-cpp-sys-2 build.rs is run.Additional information
I'm not sure how to add tests so open to some help on that. I wanted to make sure that this approach is even correct. I coded this to change Cargo minimally and defensively since I don't know the internals of Cargo very well (e.g. I don't know if I have to compare against both
script_out_dir
/script_out_dir_when_generated
since I don't know the difference & there's not really any explanation on what they are).It's possible this over-complicates the implementation so open to any feedback. Additionally, the sort that happens prior to each build up of the rustc environment is not where I'd ideally place it. I think it would be more efficient to have the list of search paths be free-floating and not tied to a BuildOutput so that they could be kept updated live & resorted only on insertion (since it's changed less frequently than rustc is invoked). Additionally, the generalized sort is correct but pessimistic - maintaining the list sorted could be done efficiently with some minor book keeping (i.e. you'd only need to sort the new paths & then could quickly inject into the middle of a VecDeque).
And of course in terms of correctness, I didn't do a thorough job testing across all possible platforms. From first principles this seems directionally correct but it's always possible this breaks someone else's workflow. I'm also uneasy that the relative position of
-L
/-l
arguments changes in this PR & I'm not sure if that's observable behavior or not (i.e. it used to be -L for a crate followed by-l
for a crate), but now it's-L
for all crates, still grouped by crated internally, followed by-l
by crate).