Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Sanatan Rai
On 23 May 2011 00:53, Hendrik Sattler p...@hendrik-sattler.de wrote:
 Am Montag, 23. Mai 2011, 01:36:14 schrieb Sanatan Rai:
 After cmake, and make all, the libraries build as static archives, ie I get
 liblib1.a, liblib2.a, libhelper1.a, libhelper2.a and executable myProj in
 the appropriate locations. However, the executable myProj does not appear
 to have linked statically to libhelper1.a and libhelper2.a. These
 libraries contain global initialisers for certain objects: which doesn't
 happen when I run the executable.

 Most likely, the linker just drops those global initialisers when linking
 statically.  See the linker options in man ld to prevent that or give the
 library an initialisation method.

   I don't understand: so why does it work at all? I guess what I
don't understand is that
I don't see symbols from helper1 and helper2 in the final executable,
when I build them
as separate libraries, but I do when I express the dependencies thus:

  add_executable(myTarget target.cpp helpers/helper1.cpp helpers/helper2.cpp)

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: which
suggests that the library was not loaded in memory. On the other hand,
when I build
them with the executable, the lines are called and everything works as expected.
I am not sure what else I can tell the linker. The libraries are
static so should be linked
statically. As far as I can tell, somehow the two helper libraries are
not being linked
at all.

Sorry, but I am quite confused.

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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Hendrik Sattler

Zitat von Sanatan Rai sana...@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  resulting
   shared library.  This option may be used more than once.

   Two  notes when using this option from gcc: First, gcc doesn't know
   about this option, so you have to use -Wl,-whole-archive.   Second,
   don't  forget  to  use  -Wl,-no-whole-archive  after  your  list of
   archives, because gcc will add its own list  of  archives  to  your
   link and you may not want this flag to affect those as well.

HS


___
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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Michael Wild
On 05/23/2011 10:23 AM, Hendrik Sattler wrote:
 Zitat von Sanatan Rai sana...@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
Foreach  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  inthe 
 resulting
shared library.  This option may be used more than once.
 
Twonotes when using this option from gcc: First, gcc doesn't
 know
about this option, so you have to use -Wl,-whole-archive.   Second,
don't  forget  to  use  -Wl,-no-whole-archive  after your 
 list of
archives, because gcc will add its own listof  archives  to 
 your
link and you may not want this flag to affect those as well.
 
 HS

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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Sanatan Rai
On 23 May 2011 10:18, Michael Wild them...@gmail.com wrote:
 On 05/23/2011 10:23 AM, Hendrik Sattler wrote:
 Zitat von Sanatan Rai sana...@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.
___
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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Michael Jackson
You might want to take a look at the Factory design pattern.

-
Mike Jackson www.bluequartz.net
Principal Software Engineer   mike.jack...@bluequartz.net
BlueQuartz Software   Dayton, Ohio
Sent from my mobile device.

On May 23, 2011, at 5:51, Sanatan Rai sana...@gmail.com wrote:

 On 23 May 2011 10:18, Michael Wild them...@gmail.com wrote:
 On 05/23/2011 10:23 AM, Hendrik Sattler wrote:
 Zitat von Sanatan Rai sana...@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
Foreach  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  inthe
 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.
 ___
 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
___
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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Sanatan Rai
On 23 May 2011 12:54, Michael Jackson mike.jack...@bluequartz.net wrote:
 You might want to take a look at the Factory design pattern.


That's exactly what I use...

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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Michael Wild
On 05/23/2011 02:20 PM, Sanatan Rai wrote:
 On 23 May 2011 12:54, Michael Jackson mike.jack...@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.

Michael
___
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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Sanatan Rai
On 23 May 2011 13:38, Michael Wild them...@gmail.com wrote:
 On 05/23/2011 02:20 PM, Sanatan Rai wrote:
 On 23 May 2011 12:54, Michael Jackson mike.jack...@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
___
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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Michael Wild
On 05/23/2011 03:25 PM, Sanatan Rai wrote:
 On 23 May 2011 13:38, Michael Wild them...@gmail.com wrote:
 On 05/23/2011 02:20 PM, Sanatan Rai wrote:
 On 23 May 2011 12:54, Michael Jackson mike.jack...@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/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.

Michael
___
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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Michael Jackson
On May 23, 2011, at 10:11 AM, Michael Wild wrote:

 On 05/23/2011 03:25 PM, Sanatan Rai wrote:
 On 23 May 2011 13:38, Michael Wild them...@gmail.com wrote:
 On 05/23/2011 02:20 PM, Sanatan Rai wrote:
 On 23 May 2011 12:54, Michael Jackson mike.jack...@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/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.
 
 Michael


I use 4 in my own code and everything just works and I have the same type 
of setup as the original poster. I have a few of my own concrete classes and 
the user can create new ones. They just have to register their own new 
classes in addition to calling the RegisterKnowFactories() method first. This 
ensures everything links correctly and is not that much to ask your programmers 
to do. I think VTK/ITK/ParaView may also use these types of design patterns.
___
Mike Jackson  www.bluequartz.net
Principal Software Engineer   mike.jack...@bluequartz.net 
BlueQuartz Software   Dayton, Ohio


___
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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Michael Wild
On 05/23/2011 04:40 PM, aaron.mead...@thomsonreuters.com wrote:
 -Original Message-
 From: cmake-boun...@cmake.org [mailto:cmake-boun...@cmake.org] On
 Behalf Of Michael Wild
 Sent: Monday, May 23, 2011 9:12 AM
 To: cmake@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 them...@gmail.com wrote:
 On 05/23/2011 02:20 PM, Sanatan Rai wrote:
 On 23 May 2011 12:54, Michael Jackson mike.jack...@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
___
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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread aaron . meadows
-Original Message-
From: cmake-boun...@cmake.org [mailto:cmake-boun...@cmake.org] On
Behalf Of Michael Wild
Sent: Monday, May 23, 2011 9:12 AM
To: cmake@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 them...@gmail.com wrote:
 On 05/23/2011 02:20 PM, Sanatan Rai wrote:
 On 23 May 2011 12:54, Michael Jackson mike.jack...@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.)


Aaron

This email was sent to you by Thomson Reuters, the global news and information 
company. Any views expressed in this message are those of the individual 
sender, except where the sender specifically states them to be the views of 
Thomson Reuters.
___
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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Sanatan Rai
On 23 May 2011 15:11, Michael Wild them...@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?

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.

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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Michael Wild
On 05/23/2011 04:51 PM, Sanatan Rai wrote:
 On 23 May 2011 15:11, Michael Wild them...@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?
 
 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.
 
 --Sanatan

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.

Michael
___
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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Sanatan Rai
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.

   Ok, got you. However, would this not imply a monolithic build? How is
main to know that an object of a type belonging to a base class of interest
exists in linked library?

   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.

 * The factory was a singleton, and had a static method that could be
called. The method loaded
   all linked assemblies, and picked out classes that were derived
from the base class.

  * Then it explicitly registered the class with the factory.

This seems to me to be a hybrid between implicit and explicit
registration. The actual mechanics
as one might imagine relied heavily on .NET reflection calls. One of
the ugliest bits of code I have
ever written.

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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Michael Jackson

On May 23, 2011, at 11:09 AM, 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.
 
   Ok, got you. However, would this not imply a monolithic build? How is
 main to know that an object of a type belonging to a base class of interest
 exists in linked library?
 
   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.
 
 * The factory was a singleton, and had a static method that could be
 called. The method loaded
   all linked assemblies, and picked out classes that were derived
 from the base class.
 
  * Then it explicitly registered the class with the factory.
 
 This seems to me to be a hybrid between implicit and explicit
 registration. The actual mechanics
 as one might imagine relied heavily on .NET reflection calls. One of
 the ugliest bits of code I have
 ever written.
 
 --Sanatan

Take a look at 
http://scm.bluequartz.net/mxa/mxadatamodel/trees/master/Code/MXA/DataImport for 
an example of how I did this in one of my older projects.

The code that ties this together is then in 
http://scm.bluequartz.net/mxa/mxadatamodel/blobs/master/Examples/DataImport/main.cpp

This should short enough for you to follow along. I am not saying mine is the 
utopian example but it does work.

Mike Jackson


___
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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread David Cole
On Mon, May 23, 2011 at 10:51 AM, Sanatan Rai sana...@gmail.com wrote:

 On 23 May 2011 15:11, Michael Wild them...@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

___
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

Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Michael Wild
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.
 
Ok, got you. However, would this not imply a monolithic build? How is
 main to know that an object of a type belonging to a base class of interest
 exists in linked library?
 
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.
 
  * The factory was a singleton, and had a static method that could be
 called. The method loaded
all linked assemblies, and picked out classes that were derived
 from the base class.
 
   * Then it explicitly registered the class with the factory.
 
 This seems to me to be a hybrid between implicit and explicit
 registration. The actual mechanics
 as one might imagine relied heavily on .NET reflection calls. One of
 the ugliest bits of code I have
 ever written.
 
 --Sanatan


If it is acceptable to have just one hook, just require your user to
define a specific function, e.g. registerUserFactories which you then
call. Otherwise it becomes more tricky.

Michael
___
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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Michael Hertling
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.
 
Ok, got you. However, would this not imply a monolithic build? How is
 main to know that an object of a type belonging to a base class of interest
 exists in linked library?

In order to further clarify things, look at the following project:

# 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)
TARGET_LINK_LIBRARIES(main helper)

// main.cxx:
int main(void){return 0;}

// helper.cxx:
#include iostream

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);
}

If I'm not mistaken, this is roughly what you do in your project.

Although the main target is linked against libhelper.a, the object file
helper.cxx.o is dropped because none of its entities is referred to by
main.cxx, or in other words: Which reason the linker should have to
include helper.cxx.o in the final binary? To make helper.cxx.o be
included, a single reference from main.cxx usually suffices:

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

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)

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.
 
  * The factory was a singleton, and had a static method that could be
 called. The method loaded
all linked assemblies, and picked out classes that were derived
 from the base class.
 
   * Then it explicitly registered the class with the factory.
 
 This seems to me to be a hybrid between implicit and explicit
 registration. The actual mechanics
 as one might imagine relied heavily on .NET reflection calls. One of
 the ugliest bits of code I have
 ever written.

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.

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 

Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Sanatan Rai
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


Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Rolf Eike Beer
Sanatan Rai wrote:

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

What about your application calling an initStaticLibs() function which is 
defined in an header. That header is written by CMake using FILE(WRITE ...) 
because CMake knows which libs are there and by this which init functions need 
to be called. They just have to be somehow related to the library name.

Eike

signature.asc
Description: This is a digitally signed message part.
___
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

Re: [CMake] Newbie question: Static linking

2011-05-23 Thread Michael Hertling
On 05/23/2011 08:42 PM, Sanatan Rai wrote:
 On 23 May 2011 17:46, Michael Hertling mhertl...@online.de wrote:

 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.

Please don't get me wrong on this point: Far be it from me to criticise
your concern as off-topic; on a build system's mailing list, it rather
isn't, IMO. Instead, I just wanted to point out that this issue is not
immediately related to CMake or C++ but to the implications of static
libraries. Of course, we can frankly discuss it here, especially how
to address it with the means of CMake.

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

In this thread, you have spoken about loading a library, library
loaded when needed and library loaded in memory, e.g., but static
libraries aren't loaded in this sense; they're examined at link time,
and that's it. May it be possible that shared libraries are what you
actually want, i.e. is there any reason why the libraries in question
must be static? Note that shared libraries don't have the limitations
of static ones; say, they are not cherry-picked w.r.t. object files.

If you really want to have actions performed at the program's startup
without any explicit ado, you might take a look at GCC's constructor/
destructor attributes, but be aware that this is highly dependent on
the underlying binary format and the corresponding development tools.

Regards,

Michael
___
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


Re: [CMake] Newbie question: Static linking

2011-05-22 Thread Hendrik Sattler
Am Montag, 23. Mai 2011, 01:36:14 schrieb Sanatan Rai:
 After cmake, and make all, the libraries build as static archives, ie I get
 liblib1.a, liblib2.a, libhelper1.a, libhelper2.a and executable myProj in
 the appropriate locations. However, the executable myProj does not appear
 to have linked statically to libhelper1.a and libhelper2.a. These
 libraries contain global initialisers for certain objects: which doesn't
 happen when I run the executable.

Most likely, the linker just drops those global initialisers when linking 
statically.  See the linker options in man ld to prevent that or give the 
library an initialisation method.

HS
___
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