[CMake] Newbie question: Static linking

Michael Wild themiwi at gmail.com
Mon May 23 11:00:58 EDT 2011


On 05/23/2011 04:51 PM, Sanatan Rai wrote:
> On 23 May 2011 15:11, Michael Wild <themiwi at gmail.com> wrote:
>>>> Yes, but you are registering the concrete factories implicitly instead
>>>> of explicitly, which is causing you the trouble you experience.
>>>>
>>>> Better have your user provide a function registering his/her classes
>>>> explicitly.
>>>
>>> I guess this is getting to be off topic, but indeed the
>>> anonymous namespace trick is supposed to do exactly that.
> <snipped>
>>> libraries that this problem occurs. I haven't seen a solution to this
>>> problem either in books or via google.
>>>
>>> --Sanatan
>>
>> The problem is, that when you link a static library to another binary
>> (be it shared library or executable) only the *required* symbols are
>> used, all others get discarded. Since nothing in your code actually
>> references those global instances in the anonymous namespace (the linker
>> doesn't care about that, BTW), they are ignored.
>>
>> Four solutions:
>>
>> 1. Only do monolithic builds.
>> 2. Use shared libraries/DLLs
>> 3. Use --whole-archive or similar and hack your way through MSVC (I did
>> it once. It was ugly. Very ugly. See
>> https://github.com/themiwi/cppcheck/tree/227378f763d50b005b7dd2167e2cef791054a30c.
>> Especially lib/CMakeLists.txt and lib/generateStaticLinkFlags.cmake. I
>> replaced it with an explicit registration scheme now...)
>> 4. Use an explicit registration scheme.
>>
>> For sanity's sake, go with 4.
> 
>    Ok: you've lost me here. Are you saying a trick like:
> 
>    namespace {
>      helper1 *createHelper1() { return (new Helper1());}
>      const bool isRegistered =
> factory::instance().registerHelper("helper1", createHelper1);
> }
> isn't explicit?
> 
> I could do the following: create a global object in the cpp, that
> belongs to a type that would
> do the registration. Would you regard this also as implicit?
> 
> The problem with either of these approaches is the same: if the code
> lives in a separate library
> that is loaded only when needed, then these registrations don't take
> place. So the framework doesn't
> know that the objects can be available.
> 
> Apologies for seeming obtuse but I don't follow what you mean by
> `explicit registration' here.
> 
> --Sanatan

Everything that relies on static/global initialization to register
factories is an implicit scheme. An explicit scheme is where the
dependent code (e.g. the main() function) calls a function to do the
registration.

Michael


More information about the CMake mailing list