Static libraries and loadable modules

I am working on a library with a plugin system that currently works by having a plugin register itself on load. An app links with this library, as does the plugin. When BUILD_SHARED_LIBS=ON, the plugin loads correctly, but when set to OFF, it doesn’t crash or fail to load, it just doesn’t get registered.

I believe this is because when the library is static, the app and the plugin each get their own copy of everything, including the map of plugins.

On Linux, one can get around this using weak linkage, but there doesn’t appear to be much support for that in CMake (or on Windows, since it isn’t a standard language feature).

Here is a repository containing a minimal example:

Is there a portable way of allowing an application which uses a static library to load a plugin that uses that library?

The way Python ends up doing this is to just tell the linker to ignore the missing symbols when making the plugin. ELF platforms have various ways of spelling this (-Wl,--no-as-needed -Wl,--unresolved-symbols=ignore-in-shared-libs being the Linux way). macOS has -undefined dynamic_lookup. Better would be to mark the symbols as weak in the header and then doing a sanity check that some sentinel symbol is defined when the plugin loads (before it ends up calling other maybe-nullptr symbols).