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

Deduplicate native libs before they are passed to the linker #84794

Merged
merged 1 commit into from
May 5, 2021

Conversation

ChrisDenton
Copy link
Member

Stop spamming the linker with the same native library over and over again, if they directly follow from each other. This would help prevent this situation.

Issue #38460 has been open since 2016 so I think it's worth making an incomplete fix that at least addresses the most common symptom and without otherwise changing how Rust handles native libs. This PR is intended to be easy to revert (if necessary) when a more permanent fix is implemented.

@rust-highfive
Copy link
Collaborator

r? @jackh726

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 1, 2021
@joshtriplett
Copy link
Member

This seems reasonable, but also, I think it's a good motivation to do #76992 as well. With that change, it'd be reasonable to deduplicate libraries even if they're not adjacent.

@petrochenkov
Copy link
Contributor

@joshtriplett
This is a not a trivial problem, there are always issues like #84254 or https://github.com/rust-lang/rust/blob/master/compiler/rustc_target/src/spec/windows_gnu_base.rs#L33 that require preserving library order or disabling deduplication even in presence of --(start,end)-group (which also isn't necessarily supported on all platforms).

That's why I want to land the linking modifiers infra (#83507) first, and not change or fix any deduplication behavior (including #73319) until a modifier for disabling/enabling deduplication is added.
I plan to work on this in May/June (I just got busy with some unexpected life stuff last week, so I may not start this work immediately).

(FWIW, I don't think MSxDOS/ntapi#2 is purely a rustc's issue, with macro expansion you can do a lot of things slowing down you compilation deliberately, not necessarily related to linking.)

@ChrisDenton
Copy link
Member Author

Consider the following linker library order:

libA mylib libA libA libA libB

As far as I'm aware (please correct me if I'm wrong), this is exactly the same as:

libA mylib libA libB

Which is all this PR currently does. However the following is not the same, even if the linker is allowed to circle back to the start:

libA mylib libB

In the first cases, if a needed symbol is unresolved in mylib it will first be looked for in libA. In the last case it will look for the unresolved symbols in libB. In essence, from the view of mylib, it's swapped the order of libA and libB:

libA mylib libB libA ...

Therefore I think this PR is the most that can be done without potentially breaking some linking strategies.

@petrochenkov
Copy link
Contributor

Yeah, this PR should be pretty safe (from the description, I didn't check the code), modulo the "mingw linker + mixed import-static library" case linked above.

@jackh726
Copy link
Member

jackh726 commented May 2, 2021

I'm definitely not a good reviewer for this. So let's r? @petrochenkov

@ChrisDenton
Copy link
Member Author

modulo the "mingw linker + mixed import-static library" case linked above.

In the specific libmsvcrt.a case this PR doesn't pose a problem due to the way it's linked. In the more general case, I would (naïvely?) hope that Mingw does not otherwise produce libraries that it's own linker can't properly consume. On the other hand, if it does then it would be good if there's a test case I can use.

Either way I guess one workaround would be to allow up to one repetition. Perhaps only if the target linker is gcc/windows. Though I am slightly reluctant to introduce too many temporary hacks.

@petrochenkov
Copy link
Contributor

I would (naïvely?) hope that Mingw does not otherwise produce libraries that it's own linker can't properly consume

This is true, libmsvcrt.a is a very special case that can be solved by a linking modifier once linking modifiers (#83507) are implemented.

@bors r+ , this is the most conservative deduplication strategy, and once the modifiers are implemented we'll probably end up with aggressive deduplication (and opt-out when necessary) which is compatible with what this PR does.

@bors
Copy link
Contributor

bors commented May 3, 2021

📌 Commit e40faef has been approved by petrochenkov

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 3, 2021
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request May 4, 2021
…trochenkov

Deduplicate native libs before they are passed to the linker

Stop spamming the linker with the same native library over and over again, if they directly follow from each other. This would help prevent [this situation](MSxDOS/ntapi#2).

Issue rust-lang#38460 has been open since 2016 so I think it's worth making an incomplete fix that at least addresses the most common symptom and without otherwise changing how Rust handles native libs. This PR is intended to be easy to revert (if necessary) when a more permanent fix is implemented.
@Dylan-DPC-zz
Copy link

likely failure of rollup ?

@bors r-

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 4, 2021
@petrochenkov
Copy link
Contributor

Seems unlikely.
@bors r+ rollup=iffy

@bors
Copy link
Contributor

bors commented May 4, 2021

📌 Commit e40faef has been approved by petrochenkov

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 4, 2021
@bors
Copy link
Contributor

bors commented May 4, 2021

⌛ Testing commit e40faef with merge b79abea265ac16320d751e3075208554fae99591...

@rust-log-analyzer
Copy link
Collaborator

A job failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
  0  424M    0  926k    0     0   2261      0 54:38:56  0:06:59 54:31:57     0
  0  424M    0  926k    0     0   2256      0 54:46:12  0:07:00 54:39:12     0
  0  424M    0  926k    0     0   2250      0 54:54:58  0:07:01 54:47:57     0
  0  424M    0  926k    0     0   2248      0 54:57:54  0:07:02 54:50:52     0
curl: (56) OpenSSL SSL_read: Connection reset by peer, errno 54
clang+llvm-10.0.0-x86_64-apple-darwin/lib/libLLVMAnalysis.a: Lzma library error:  No progress is possible
tar: Error exit delayed from previous errors.
##[error]Process completed with exit code 1.
[command]/usr/local/bin/git version
git version 2.31.1
[command]/usr/local/bin/git config --local --name-only --get-regexp core\.sshCommand
[command]/usr/local/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :

@bors
Copy link
Contributor

bors commented May 4, 2021

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 4, 2021
@Mark-Simulacrum
Copy link
Member

@bors retry network error

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 4, 2021
@bors
Copy link
Contributor

bors commented May 5, 2021

⌛ Testing commit e40faef with merge 2d11e25...

@bors
Copy link
Contributor

bors commented May 5, 2021

☀️ Test successful - checks-actions
Approved by: petrochenkov
Pushing 2d11e25 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label May 5, 2021
@bors bors merged commit 2d11e25 into rust-lang:master May 5, 2021
@rustbot rustbot added this to the 1.54.0 milestone May 5, 2021
@ChrisDenton ChrisDenton deleted the dedup-native-libs branch May 5, 2021 12:41
bors added a commit to rust-lang-ci/rust that referenced this pull request May 23, 2021
…rochenkov

native lib: defer the duplicate check after relevant_lib check.

rust-lang#84794 break code using conditional-compilation with `#[link]` attributes.

```rust
#[cfg(target_env = "musl")]
cfg_if::cfg_if! {
    if #[cfg(any(target_feature = "crt-static", feature = "llvm-libunwind"))] {
        #[link(name = "unwind", kind = "static", modifiers = "-bundle")]
        extern "C" {}
    } else {
        #[link(name = "unwind", cfg(feature = "system-llvm-libunwind"))]
        #[link(name = "gcc_s", cfg(not(feature = "system-llvm-libunwind")))]
        extern "C" {}
    }
}

```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants