I have a setting that does not work, and I have no idea what I'm doing wrong here - I am trying to convert a project from handfileed Makefiles to autotools, and I think that most of it was configured for me correctly, since the application and everything its convenience libraries are built and linked correctly, but there are some problems with global state initializers convenient libraries.
Some of the libraries follow a pattern similar to this in the code:
// in global scope of somemodule.cpp namespace { bool registered = ModuleShare::registerModule<SomeModule>("SomeModule"); }
this code along with the actual source of the module is compiled into a convenience library using libtool
and this library is built and referenced in the Makefile.am application as follows:
// someapp Makefile.am bin_PROGRAMS = someapp someapp_SOURCES = someapp.c someapp.h someapp_CPPFLAGS = -I ${top_srcdir}/something someapp_LDADD = ${top_srcdir}/something/libsomething.la
I modified ModuleShare :: registerModule to make sure it is not being called:
template<typename T> static bool registerModule(const std::string &module){ printf("%s\n", module.c_str()); [ ... ] return true; }
What could be the reason for this?
EDIT:
At this point, I found out that this problem is related to the linker, which is allowed to delete unused characters during communication. If I contact manually using --whole-archive , everything will work as expected.
Based on background C, I also tried
static void __attribute__((constructor)) register (void) { ModuleShare::registerModule<SomeModule>("SomeModule"); }
but this also does not lead to the behavior that I expected, which is stranger, given that I rely a lot on this construct in my private C projects.
At this moment I am open to suggestions in any direction. I know that libtool does not provide flags for each library in LDADD, and I cannot and just do not want to compile everything with -whole-archive to get rid of these symptoms. I have limited control over the codebase, but I think I really need to ask what is a good and reliable way to initialize the state of a program in a convenience library using autotools?
EDIT2:
I think I'm one step closer - it seems that there are no calls to the convenience library in the application code, and therefore the linker omits it. An application is called to the library only with the help of the template function defined in the SomeModule header file, which relies on static initializers called in convenience libraries. This dependency replication bolts the entire assembly.
However, I'm not sure how to solve this: /
Thanks Andy