Open vadimcn opened 7 years ago
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.
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.
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.
@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.
@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.
@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.
@Ericson2314 When https://github.com/rust-lang/rust/issues/58713 is implemented you will be able to guarantee a symbol comes from a certain library for a specific subset of cases.
A more extreme case of this issue found in the wild: https://github.com/MSxDOS/ntapi/issues/2
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.
This can cause linkage to fail entirely as described in #65847
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.