I am creating a template-only C++ library. However, I’d like to provide an ’empty’ shared library as well, so that through controlling SONAME I would be able to enforce rebuilds of the template consumers whenever the templates change in a way resulting in instantiated template ABI incompatibility.
Sadly, if a particular user has -Wl,--as-needed in his LDFLAGS, the linker is going to remove my shared library from NEEDED because the compiled executable is not requesting any symbols from it. How can I ensure that the program will always be linked against my library, preferably not introducing unnecessary dummy function calls (or if I have to, making them least burdening)?
Edit: as a note, the particular template class provides static methods, and usually only those static methods are used. Thus, it is not a good idea to rely on anything put in the constructor, and I’d really like to avoid burdening all the methods with some kind of enforcement.
Inspired by @EmployedRussian, I achieved:
extern int dummy;
namespace
{
struct G
{
inline G()
{
dummy = 0;
}
};
static const G g;
}
But sadly, that performs the assignment once for every unit including the header file.
This will force an error at runtime.
You can trivially achieve the same result (runtime error) without using
SONAME. In one of your template headers, put in a global object that will at runimelibmysolib_version_<N>, ordlopen(libmysolib.so, ...)anddlsym("libmysolib_version_<N>", ...)Then just keep incrementing
Nevery time you break the ABI.Taking address of
libmysolib_version_<N>does not call a function; it just forces the runtime linker to find that symbol once (at startup). You may though run afoul of the linker garbage collection.