[CMake] Newbie question: Static linking

Michael Wild themiwi at gmail.com
Mon May 23 10:41:04 EDT 2011


On 05/23/2011 04:40 PM, aaron.meadows at thomsonreuters.com wrote:
>> -----Original Message-----
>> From: cmake-bounces at cmake.org [mailto:cmake-bounces at cmake.org] On
> Behalf Of Michael Wild
>> Sent: Monday, May 23, 2011 9:12 AM
>> To: cmake at cmake.org
>> Subject: Re: [CMake] Newbie question: Static linking
>>
>> On 05/23/2011 03:25 PM, Sanatan Rai wrote:
>>> On 23 May 2011 13:38, Michael Wild <themiwi at gmail.com> wrote:
>>>> On 05/23/2011 02:20 PM, Sanatan Rai wrote:
>>>>> On 23 May 2011 12:54, Michael Jackson <mike.jackson at bluequartz.net>
> wrote:
>>>>>> You might want to take a look at the Factory design pattern.
>>>>>>
>>>>>
>>>>> That's exactly what I use...
>>>>>
>>>>> --Sanatan
>>>>
>>>> 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.
>>>
>>> I am not trying to be difficult here---just that it is not clear to
> me
>>> that the solution to this problem is that straightforward.
>>>
>>> When all the code files are linked in one monolithic bloc, everything
>>> works correctly. It is when one starts dividing them into individual
>>> 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/227378f763d50b005b7dd2167e2cef
> 791054a30c.
>> 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.
>>
>> Michael
> 
> Couldn't you do:
> 
> 5) Add references to the global instances inside something within the
> same copilational unit which you know will be imported.  (Such as a
> static reference to the global instance inside a function you know will
> be called.)

That, effectively, is an explicit registration scheme.

Michael


More information about the CMake mailing list