Page MenuHomePhabricator

[CMAKE] Specify all_load when exporting symbols from an executable (macOS)
Needs ReviewPublic

Authored by jranieri-grammatech on Oct 26 2018, 2:50 PM.

Details

Reviewers
beanz
Summary

This changes the CMake export_executable_symbols function to force all symbols pulled in from static libraries to be linked into the final executable, even if they weren't directly referenced by the executable. This is necessary for plugins that wish to link against the executable and use LLVM functionality that the executable itself doesn't use.

In my specific use case, I'm writing a Clang plugin that wishes to use LLVM's JSON libraries.

Diff Detail

Event Timeline

jranieri-grammatech edited the summary of this revision. (Show Details)Oct 26 2018, 2:51 PM
beanz added a comment.Oct 26 2018, 3:37 PM

I'm not really sure this is the best solution. This will result in bloating the clang binary substantially. An alternative approach would be to use linker order precedence, and pass the LLVM executable first, then LLVM static archives later on the link line. That would allow minimal tool binaries, and link the LLVM bits into your plugin.

I'm not really sure this is the best solution. This will result in bloating the clang binary substantially. An alternative approach would be to use linker order precedence, and pass the LLVM executable first, then LLVM static archives later on the link line. That would allow minimal tool binaries, and link the LLVM bits into your plugin.

I was able to get this to work by adding -bundle_loader /opt/clang/bin/clang-8 /opt/clang/lib/libLLVMSupport.a. Do you think adding -bundle_loader is something add_llvm_loadable_module should be responsible for doing?

Adding -bundle_loader in add_llvm_loadable_module doesn't work because LLVM modules can be loaded by lots of different tools, so they actually need to be fully self-contained. Obviously if a specific distribution is only supporting the module from one tool that distribution can do things differently, but as a general rule we can't make that assumption.

We could however add a new add_clang_plugin function to AddClang.cmake which could make the assumption that clang is your -bundle_loader. That would likely meet your needs.

Specify -bundle_loader when giving a PLUGIN_TOOL to add_llvm_loadable_module. This doesn't limit what executables can load the resulting shared library and just informs the static linker what functions will be present when the library is loaded.

rC345628 makes Clang depend on llvm::json, so this is no longer relevant for my purposes but I think it is a bit nicer to go this approach than always using -undefined suppress. I'd be okay with abandoning this revision if you'd prefer to keep things as-is.