-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Produce idata content for dll/dylib import on windows #30027
Comments
So… you basically want to have import This, at very least, would be problematic with extern blocks that have overlapping definitions. |
Using the right markers for the globals, it's possible to make LLVM handle that gracefully, by concatenating the necessary elements. However, a better solution would be for rust to do overlap checking prior to generating the LLVM code, and generate a single import block for the entire program, thus avoiding any duplicate imports. At any rate, avoiding duplicate creation of imports can't be much more challenging than avoiding duplicate reification of generics. |
Could you elaborate on the rationale for this? Do other compilers do this? e.g. MSVC or clang? |
MSVC comes with a (proprietary) tool for producing .lib from .def, and .def from .dll, if you're missing the prior. Most other compilers targeting Windows actually lack this facility, requiring reliance on MSVC's toolchain. The rationale is twofold:
|
The behavior of |
@SlugFiller could you elaborate on the LLD aspect of this? From what I understand import libraries are basically a "linker thing" in the sense that the MSVC linker is the only one that consumes them. The GNU linker in the MinGW toolchain, for example, I believe doesn't use the same strategy? (or at least encodes it differently) Along those lines I would expect that LLD would basically take care of itself and not require a lot of manual interaction with these sorts of imports and whatnot. I'm not entirely sure about the story here, though, as I've played around very little with LLD. |
@alexcrichton MinGW is first and foremost a set of header files and libraries mimicking those available in MSVC, starting with those import libraries. The rest of the toolchain is simply a port of the GCC toolchain. So, I can guarantee you that MinGW consumes import libraries, and is bundled with "off-brand" replicas of import libraries for common Microsoft DLLs. As far as I know, they should be cross-compatible/interchangeable with the Microsoft ones, although there's always a chance that tiny differences would cause incompatibilities if trying to mix-and-match. Avoiding that minefield is reason enough to avoid dependency on them entirely. LLD, at it's core, is just a linker, but it does successfully consume import libraries, as the changelog for it maintains up to date compatibility reports with import libraries. A recent patch (dated Jun 17), mentions a dependency on an MSVC tool (lib.exe) to produce import libraries. To my knowledge, LLD is not bundled with any import libraries, but can consume both those bundled with MSVC and MinGW. This does mean it still has an external dependency on one of those two. As I've demonstrated above, import libraries can be created manually through LLVM, thereby eliminating dependency on any external toolchains. Note that this is not a "linker thing", but a "compiler thing": Most compilers output DLL imports simply as static imports, indistinguishable from dependencies on static libraries. True DLL imports require a matching idata section. The linker can link such an idata section into the program, without needing any special awareness of its contents. In particular, without the idata section, the compiler "erases" the data of which DLL any given import must come from. This information is stored in the idata section. |
If this can be done with no runtime overhead over the linker resolving imports from static libraries, and if it can be done without needing the compiler to look at the DLLs itself, and if it doesn't further overload the meaning of |
@retep998 I don't understand what you mean by "runtime overhead". It doesn't use LoadLibrary, if that's what you mean. The idata section is how all Windows programs must define their import tables. It's part of the PE format. Import libraries must use the same method (Although import libraries skip any inlining optimizations LLVM can offer for the import stubs) The compiler doesn't need to look in the DLLs. The information provided in the For not overloading the meaning, a possibility is to use a different type of |
Well if it ends up with the same PE imports as using import libraries, and all it needs is the information in the |
if I understand what this does correctly--removes the need to have the import library on Windows--I really want this. |
@SlugFiller I really wish you'd create an RFC for this. It's such a genuinely useful thing to have. |
Just as a note, whatever the proposed syntax is, it would need to have a way to specify an ordinal instead of a symbol name, as some DLLs have symbols that are only identifiable by their ordinal rather than their name. |
👍 👍 👍 This would be absolutely amazing for Windows targeting. It would remove so much hell in compiling/cross-compiling to windows, including dealing with msvc/mingw32. |
Is it certain this would require an RFC? It uses the existing |
I'd much rather this used a new kind or new syntax rather than changing the behavior of |
Ok, maybe like |
Cause nobody mentioned it yet, |
All an import library really is, is a mapping from a symbol such as Anyway, to make rustc be able to emit this sort of information without losing out on anything, all the user needs to be able to do is specify these things:
Have I missed anything? As far as I can tell this should be sufficient. |
Also to clarify how important ordinals are, there are 13,907 exports in the Windows SDK only accessible via ordinal (out of a total of 145,802 exports cataloged by me). |
Interestingly, the So actually it seems Rust could theoretically just add |
@rkarp this has been brought up before. It doesn't work if you're cross-compiling (since you don't have those DLLs), or you're targeting a newer version of Windows (so your DLLs lack some specific export), or you need an API exported through an ordinal. |
👍 to this. This will help lowering the entry level into rust development on windows because once we ship lld, and we figure out a solution for CRT, you won't need to install anything any more beyond the rust toolchain itself. It will also make cross compiling to windows easier from other platforms. |
wait a sec, it's that easy to add IData in LLVM? I have been searching for this way to long, as i want to write a little toy pascal frontend for LLVM and (object)Pascal naturally comes with this kind of specifying imports (internalname, dllname, externalname). Seems that ticket helped accidentally, too :D |
There is an RFC open for this feature: rust-lang/rfcs#2627 |
cc #58713 , maybe close this as a duplicate. |
Given the RFC has been accepted and a tracking issue has been created, please direct all further discussion there. |
From what I can tell the
kind="dylib"
link hint is mostly ignored on windows, as rust expects a matching import library to be found. I suggest it should, instead, produce an appropriate idata section in the LLVM code.For example, for the following:
Rust should produce (Assuming 32-bit. For 64-bit target, a bunch of i32s should replaced with i64s below):
The text was updated successfully, but these errors were encountered: