Open HertzDevil opened 2 years ago
It looks like LLVM's CMakeLists.txt doesn't support BUILD_SHARED_LIBS
on MSVC: https://llvm.org/docs/CMake.html#llvm-related-variables
It does have a LLVM_BUILD_LLVM_C_DYLIB
variable which produces Release\lib\LLVM-C.lib
and Release\bin\LLVM-C.dll
. I do not know whether this DLL is sufficient for our LibLLVM
. I am even less sure whether llvm_ext.obj
would work.
Related: #9278
LoadLibraryExA
multiple times with different absolute paths, instead of once with an unqualified name. That would be good for crystal run
and similar because it means we don't have to "install" the DLLs into a fixed location, and even Crystal itself doesn't need to be in %PATH%
.dumpbin /exports LLVM-C.dll
shows that it provides everything in LibLLVM
already except for the unused bindings in #13438. The problem is llvm_ext.cc
; it depends on LLVM's C++ interfaces, so it must link against LLVM statically, which means a Crystal compiler distributed with just LLVM-C.dll
cannot be used to rebuild Crystal. Removing the DIBuilder
stuffs is easy, the rest not so much.
The top question is still figuring out how to distribute the static libraries and the DLL import libraries side-by-side. Generating import libraries from the DLLs themselves and placing them in the cache directory is probably not a viable option.
Idea: if --static
is provided, Crystal will manually look up foo-static.lib
followed by foo.lib
, otherwise Crystal tries foo-dynamic.lib
and then foo.lib
. This will solve the CRYSTAL_LIBRARY_PATH
issue, but it still requires all libraries under --static
to link against the static CRT (/MT
), because that remains controlled by the same flag:
In the future this would become {{ flag?(:static) ? "libucrt" : "ucrt" }}
. Ditto for the CRT startup library.
After #13436 we will perform an actual library search anyway, because we need to open the library files to search for the DLL imports. Two consequences are that we don't even need to pass /LIBPATH
to cl.exe
at all, and that we could produce a compiler error prior to linking if the library cannot be found.
We have fully switched to dynamic linking and I think we could consider this issue finished once the following TODO is also addressed:
We already have two use cases for load-time dynamic linking on Windows: distributing the LLVM libraries, and linking to MPIR without license issues. (Run-time dynamic linking would be equivalent to porting
Crystal::Loader
to Windows.) #11573 shows that this is indeed possible, but we are still far from supporting it in the compiler itself. Here are some thoughts:$ORIGIN\lib
is already used for the static libraries, we might need to find a different place for the import libraries, and the@[Link]
annotations would have to be adjusted only on Windows depending onflag?(:static)
.%PATH%
, so are the DLLs, but we might want to have more control over the DLL search order./MD
as well, or it can choose not to care with/Zl
, which should be fine as our preludes already provide eitherlibcmt
ormsvcrt
. On the contrary, DLLs should not link to the CRT statically. This means there are at least 3 flavors of linking:/MT
(this is the current situation, and will likely be what is implied by the--static
compiler flag eventually)/MD
/MD
(this is what-Dpreview_dll
implies)/MD
scenario we should have a separate CI job that builds everything. A complete Crystal distribution, however, will probably include both static and dynamic libraries.