[CMake] Newbie question: Static linking

Sanatan Rai sanatan at gmail.com
Mon May 23 05:50:56 EDT 2011


On 23 May 2011 10:18, Michael Wild <themiwi at gmail.com> wrote:
> On 05/23/2011 10:23 AM, Hendrik Sattler wrote:
>> Zitat von Sanatan Rai <sanatan at gmail.com>:
>>> The `global initialisation' stuff is just the following pattern:
>>>
>>> namespace {
>>>   helper1 *helper1Creator()
>>>   {
>>>     return (new helper1());
>>>   }
>>>   const bool helper1Registered = factory::instance().registerhelper
>>>     ("helper1", helper1Creator);
>>> }
>>>
>>> So when I put the helpers in a separate library, these lines are not
>>> called.
>>
>> Then you don't understand the implications of static libraries, yet.
>> Use the following from "man ld":
>>  --whole-archive
>>        For    each  archive  mentioned  on  the  command  line   after the
>>        --whole-archive option, include every object file in the archive in
>>        the link, rather than searching the archive for the required object
>>        files.  This is normally used to turn an archive file into a shared
>>        library, forcing every object  to  be  included  in    the
<snipped>

Thanks Hendrik, that works! For the record, I have added the following:

 target_link_libraries(myTarget
    "-Wl,-whole-archive -L./helpers -lhelper1 -Wl,-no-whole-archive"
    "-Wl,-whole-archive -L./helpers -lhelper2 -Wl,-no-whole-archive")

I am not happy about having to provide the search path explicitely, but hey.

> But this will only work when using GNU ld (or compatible). AFAIK the
> linker on APPLE uses a different option, and MSVC doesn't have an
> equivalent at all (you can only specify individual symbols that should
> be linked forcibly).
>
> The real solution is to ditch this whole idea of global, static
> initialization objects. It's usually a very bad solution, leading to all
> kinds of non-deterministic behavior. You'll be much better off with an
> explicit registration scheme.
>
> My 2c.
>
> Michael

I couldn't agree more. However, there does not appear to be an alternative
way of doing this registration. Briefly, here is the problem I am
trying to solve.

  * I have a base class (say) myBase.
  * I expect other users of my library to derive objects from myBase.
  * The application `creates' the derived objects as per the pattern above,
    based on which ones the user wants as per a config file.
 * So: if the user specifies an object that is not built, then the app
is going to
   throw an exception and abort.
 * The whole point of doing this is that the application is a
`framework' for the
   user `to host his derived class'.

This approach permits me to keep the application and the `framework' code
agnostic to the user's derived classes.

I'd be more than happy to find a better way of achieving the
framework's agnosticism
to the derived classes, while providing the user to derive whatever
objects he likes.

When I solved this problem on .NET I was forced to run through all the
assemblies
to find the relevant objects and then use reflection to instantiate
them. That was even
uglier.

Thanks all!

--Sanatan
-- 
Sanatan Rai
3, Admirals Court,
30, Horselydown Lane,
London, SE1 2LJ.
+44-20-7403-2479.


More information about the CMake mailing list