[CMake] Newbie question: Static linking

David Cole david.cole at kitware.com
Mon May 23 11:19:58 EDT 2011


On Mon, May 23, 2011 at 10:51 AM, Sanatan Rai <sanatan at gmail.com> 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?
>

That's correct. It's not explicit. Because if nothing references the bool
variable "isRegistered" then the linker is free to (possibly) throw away
it's initialization because it's not referenced. This code may work with
some compilers; but it is not guaranteed to work.



>
> 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.
>

Explicit registration is having a method as mentioned earlier, something
like "RegisterKnownFactories" and then asking clients to make sure they call
that method first before calling anything that requires a factory to create
something.

HTH,
David



>
> --Sanatan
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the CMake FAQ at:
> http://www.cmake.org/Wiki/CMake_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20110523/cd9d85c3/attachment.htm>


More information about the CMake mailing list