[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