Hi everyone,
This is a follow-up to my previous e-mail about linkers, now that I
understand the problem that I'm dealing with well enough to describe it :)
I'm trying to enable LTO in a large, heavily templated C++ codebase,
whose developers made a lot of effort to improve compilation efficiency.
To this end...
* Significant effort is expended in separating class declarations and
definitions in regular OO code
* C++11's "extern template" and explicit template instantiations are
extensively used to reduce template-induced duplicate work.
* Shared libraries are also used, sometimes in a cascading fashion
where an executable depends on library A, which depends on another
library B
When I enable LTO, I notice that many weak function template symbols
turn into local symbols, and are thus not available anymore to clients
of a shared library. This is a somewhat expected side-effect of LTO,
since AFAIK one of its design goals is to discard unused symbols.
My problem is that this weak symbol pruning process is in my case a
little bit too agressive. For example, in the "cascading" scenario
above, I end up in a situation where library A fails to link because it
cannot find the function symbols associated with "extern template class"
declarations in the headers of library B. Note that this only happens
with extern template classes: extern template functions keep working as
expected.
I can work around this by providing library A with the definitions of
the relevant templates instead of the declarations, falling back to a
classic duplicate instantiation model, but I am curious if there is a
better way. Can I somehow structure or annotate the C++ code so that the
linker knows that the explicit template instantiations of library B are
used by its clients (like library A) and must be kept around as weak or
global symbols of the output shared library?
Cheers,
Hadrien