Link to the shared library with -Wl, as needed (when only templates are provided)

I create only C ++ - a library for templates only. However, I would also like to provide an “empty” shared library, so that by controlling SONAME I can force the rebuilds of template consumers whenever templates change so that the ABI template is incompatible.

Unfortunately, if a particular user has -Wl,--as-needed in his LDFLAGS , the linker is about to remove my shared library from NEEDED because the compiled executable does not request any characters from it. How can I guarantee that the program will always be associated with my library, it is advisable not to introduce unnecessary fake function calls (or, if necessary, which makes them the least burdensome)?

Edit: As a note, a particular class of templates provides static methods, and usually only those static methods are used. Thus, you should not rely on anything placed in the constructor, and I really would like to avoid burdening all methods with some kind of coercion.


Inspired by @EmployedRussian, I achieved:

 extern int dummy; namespace { struct G { inline G() { dummy = 0; } }; static const G g; } 

But, unfortunately, this performs the assignment once for each unit, including the header file.

+7
source share
2 answers

However, I would also like to provide an “empty” shared library, so that by controlling SONAME, I can force template user rebuilds whenever the templates change so that the ABI template is incompatible.

This will result in a runtime error.

You can trivially achieve the same result (runtime error) without using SONAME . In one of the template headers, enter the global object that will be in runime

  • Take the address or call libmysolib_version_<N> or
  • Do dlopen(libmysolib.so, ...) and dlsym("libmysolib_version_<N>", ...)

Then just keep increasing N every time you break the ABI.

it is preferable not to introduce unnecessary dummy function calls

Taking the address libmysolib_version_<N> does not call the function; it just makes the runtime linker find this symbol once (at startup). You can at least confuse the garbage collector.

+3
source

I would recommend an alternative approach:

 myheader.h namespace mylib_1 { void foo(); //all the code goes there } namespace mylib = mylib_1; 

Custom Calls:

 mylib::foo() 

Code that uses a different version of myheader will not link because it will change the signature of the functions.

This approach is used by ICU

+2
source

All Articles