On 23 May 2011 17:46, Michael Hertling <mhertl...@online.de> wrote: > On 05/23/2011 05:09 PM, Sanatan Rai wrote: >> On 23 May 2011 16:00, Michael Wild <them...@gmail.com> wrote: >>> 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.
<snipped> > > # CMakeLists.txt: > CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) > PROJECT(GLOBALS CXX) > SET(CMAKE_VERBOSE_MAKEFILE ON) > ADD_LIBRARY(helper STATIC helper.cxx) > ADD_EXECUTABLE(main main.cxx) <snipped> > helper *helperCreator() > { > return (new helper()); > } > const bool helperRegistered = registerhelper("helper", helperCreator); > } > > If I'm not mistaken, this is roughly what you do in your project. Indeed. <snipped> > // helper.cxx: > #include <iostream> > > int h; // <-- For external reference. > > class helper {}; > > namespace { > > bool registerhelper(const char *ident, helper *(*creator)()) > { > std::cout << ident << "=" << (void *)creator << std::endl; > } > > helper *helperCreator() > { > return (new helper()); > } > const bool helperRegistered = registerhelper("helper", helperCreator); > } > > // main.cxx: > extern int h; > int h0 = h; > int main(void){return 0;} > > Now, the entities from helper.cxx.o are included in the final binary, > i.e. you'll see the "ident=..." message. Of course, the same happens > when you include helper.cxx.o immediately in the main executable by > mentioning helper.cxx among main's source files, i.e. a monolithic > build. However, be aware that advanced linkers and, in particular, > optimising compiler back-ends may feel free to remove entities that > seem to be unnecessary for the program to run, as David has remarked > in the meantime. Absolutely. > Michael's advice to explicitly register your factory classes means that > there will be an external reference to the concerned object files, so > they'll be included and the registration will be done via the boolean > constants' initialisation, and that's what I'd advise, too. ATM, you > try to have some actions performed in your program without referring > to these actions by any means, and this simply does not work. > > Besides, when using --[no-]whole-archive in order to force the linker > to include all of a static library's object files - be aware of the > already mentioned limitations and the fact that you will get *all* > object files, not just the ones you need - you might intersperse > these flags immediately in TARGET_LINK_LIBRARIES() without -L/-l: > > target_link_libraries(myTarget > -Wl,--whole-archive helper1 helper2 -Wl,--no-whole-archive) > Yup, interspersing these flags is the approach I am taking at the moment. >> As I mentioned earlier, I did this a little more explicitly in a >> .NET project in the following >> manner: >> >> * I had a factory object, whose job it was to hold creator functions >> for objects of classes >> derived from a base class of interest. <snipped> > If the object file holding the factory is placed in a static library, > and if there's no reference to any of this object file's entities from > anywhere, the above-noted approach would also fail on *nix, but you say > "...a static method that could be called.": Calling this method *is* a > reference to the factory's object file from outside, so it would be > included in the final binary, and everything works fine. Quite. > In summary, this whole issue is not related to C++ or even to CMake, > but to the manner static libraries are handled: The linker - at least > the GNU one - picks out entire object files, or drops them if they are > not referred to. This is something one must keep in mind, particularly > when dealing with global objects for initialisation purposes. BTW, also > keep in mind that the order of initialisations, i.e. constructor calls, > among global objects is unspecified; this might become important when > such global objects refer to each other. I do realise that it was off-topic, but people very kindly offered suggestions! So one had to go on! Many thanks to all for a careful and useful discussion. Unfortunately, I am stuck with the paradigm of having to kludge loading an entire library. For various reasons the one may not have a reference to the hosted object in main, which must remain agnostic. Indeed, in my particular line of business (finance), this happens to be a `standard' pattern. Whether good or bad is a discussion that'd be too off topic...(though am happy to continue the discussion off/on list if people are so inclined!). --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