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

Repeated #[link] attributes for the same library cause it to be passed as many times to the linker. #38460

Open
vadimcn opened this issue Dec 18, 2016 · 10 comments
Labels
A-linkage Area: linking into static, shared libraries and binaries C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@vadimcn
Copy link
Contributor

vadimcn commented Dec 18, 2016

If I specify #[link(name="pythonXY")] on 30 extern C blocks, and then compile with rustc -l dylib=pythonXY:python27, then python27.lib is passed to the linker 30 times.

In extreme cases this may cause trouble on Windows, where the maximum length of the command line is 32000 bytes. Also, may slow down linking.

@vadimcn
Copy link
Contributor Author

vadimcn commented Dec 18, 2016

As I mentioned on IRC, we could probably safely collapse repetitions of the same library. Beyond that, there's a risk of breaking someone.
Also, we can de-dupe libs passed to msvc linker, as it doesn't do left-to-right scanning and considers all libraries at once.

cc @retep998, @dgrunwald, @alexcrichton.

@retep998
Copy link
Member

While we can de-dupe libraries passed to the msvc linker, we should still be careful to preserve the order of the first mention of any given library, because if a symbol can come from several libraries, link.exe will pick whichever library has it first.

@Ericson2314
Copy link
Contributor

Item order is generally not something important in Rust. I hope with lld we can both deduplicate and ignore source order so only the set of names, and association between extern blocks and names, matter.

Can lld be used for windows too any time soon, because simply picking the first provider of a symbol would seem to to violate the mapping of extern blocks and lib names, unless I am missing something.

@retep998
Copy link
Member

retep998 commented Jan 7, 2017

@Ericson2314 LLD has the same behavior as link.exe, so switching to LLD won't provide any benefits over just using link.exe for pc-windows-msvc. They both can resolve references in either direction, unlike ld which can only resolve references to symbols provided later. They both care about the order of two libraries foo and bar when they provide the same symbol. For both LLD and link.exe we can safely deduplicate input as long as we preserve the order of the first mention of each input, and they will behave identically.

@Ericson2314
Copy link
Contributor

Ericson2314 commented Jan 7, 2017

@retep998 So currently in all cases we cannot enforce that the symbol is linked from the requested block (except maybe macos where I hear unresolved symbols can mention a library name)? Bummer. IIRC the plan is to link lld into rustc. Perhaps that would make adding new functionality to lld to fix this issue more worthwhile. If what I said about macos is true, then perhaps lld already has some functionality for this under the hood as IIRC lld has mainly been used for that platform.

@retep998
Copy link
Member

retep998 commented Jan 7, 2017

@Ericson2314 At the moment there is no way to choose which library a symbol gets resolved from except to make sure that library comes first. The only way you'd be able to have full explicit control is if LLD one day adds that feature.

@Mark-Simulacrum Mark-Simulacrum added the A-linkage Area: linking into static, shared libraries and binaries label Jun 23, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-feature-request Category: A feature request, i.e: not implemented / a PR. label Jul 26, 2017
@retep998
Copy link
Member

@Ericson2314 When #58713 is implemented you will be able to guarantee a symbol comes from a certain library for a specific subset of cases.

@retep998
Copy link
Member

A more extreme case of this issue found in the wild: MSxDOS/ntapi#2

@jonas-schievink jonas-schievink added C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed C-feature-request Category: A feature request, i.e: not implemented / a PR. labels May 28, 2020
@retep998
Copy link
Member

Information on how linker order matters for msvc: https://docs.microsoft.com/en-us/cpp/build/reference/link-input-files?view=vs-2019

Object files on the command line are processed in the order they appear on the command line. Libraries are searched in command line order as well, with the following caveat: Symbols that are unresolved when bringing in an object file from a library are searched for in that library first, and then the following libraries from the command line and /DEFAULTLIB (Specify Default Library) directives, and then to any libraries at the beginning of the command line.

@nagisa
Copy link
Member

nagisa commented May 28, 2020

This can cause linkage to fail entirely as described in #65847

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue 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.
bors added a commit to rust-lang-ci/rust that referenced this issue May 5, 2021
…ochenkov

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants