mstorsjo wrote:

> Our intention was that we should be able to insert into an `llvm::Registry` 
> from the plugin. I suspect, that is the undefined symbol.

No, not quite.

When linking this plugin, it actually _does_ link against the shared libLLVM 
dylib. But it doesn't link against any clang libraries in any form, which ends 
up as the undefined symbols.

> I'll admit that I've never developed for Windows, and I'm also not too 
> familiar with TU-local statics and dynamic loaders. Could you please share a 
> bit more insights?

None of this has anything to do with TU-local statics and dynamic loaders. It 
only has to do with how to link shared libraries.

On ELF and MachO, you can link a shared library, with references that are 
undefined at link time. When loading the shared library at runtime, the linker 
then looks up and sees if those symbols are found somewhere in the global 
symbol name space of the process, and if not, it rejects loading it.

On PE-COFF, every shared library must have every symbol resolved at static link 
time, if not the linker errors out. There's no such lookup at runtime later.

On ELF, it's possible to add something like `-Wl,--no-undefined` to tell the 
linker to refuse to link a shared library if not all symbols are found at link 
time; this gets you something very similar to the PE-COFF model.

> We wanted our tool to support some shape or form of plugins even on Windows. 
> While that is not in the short term plans, after this I have doubts if that 
> is feasible.

It is totally possible to build plugins on Windows, but it requires you to link 
with dylibs.

When using dylibs, all the common shared state (such as `llvm::Registry`) is in 
one single copy, in libLLVM, and similarly all clang code is in a 
`libclang-cpp.{so,dylib,dll}`. When building with dylibs enabled, then the 
static LLVM libraries are not linked in, but instead the LLVM cmake machinery 
replaces linking the static llvm libraries with linking against libLLVM.

Then you'd have the main tool (clang etc) linking against 
libclang-cpp.{so,dylib,dll} and libLLVM.{so,dylib.dll}, and the plugin also 
linking against the same libclang-cpp and libLLVM; then plugins work just fine.

It _may_ also be possible to have plugins on ELF, where the plugins themselves 
don't link against libclang-cpp and libLLVM, but just have unresolved undefined 
symbols. In this case, the host executable (which may be e.g. a clang 
executable built with dylibs disabled, i.e. all the shared state is in the 
statically linked LLVM libraries inside the clang executable) provides the 
symbols, which fulfill the undefined symbols when loading the plugin.

AFAIK LLVM/Clang plugins work in at least the former (dylib mode), but it's 
possible that they also work in the latter form (undefined references). Plugins 
on Windows only work in the former mode.

But it seems like this test plugin tries to force things into explicitly 
linking in the latter style (not linking in libLLVM etc) with undefined 
references, even when building with dylibs enabled.

I would suggest looking at how other existing plugins are built. In my fresh 
build tree for Windows, I do see that I have 
`CheckerOptionHandlingAnalyzerPlugin.dll`, `SampleAnalyzerPlugin.dll` and 
`CheckerDependencyHandlingAnalyzerPlugin.dll` built just fine.


https://github.com/llvm/llvm-project/pull/191401
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to