1

I need to provide an SDK with a static library. Let's call it "libsdk.a". This library should hopefully be standalone, meaning a simple example "example.cpp" could link against it without any other library, except the system ones.

Here my configuration :

  • cmake for all my 10 dependencies libraries. There is a static library (.a) generated for each of my module. These libraries contain only object files .o of the given module. Dependency tree is not flat, some of them depends on others.
  • a simple example "example.cpp", with a cmake, which compiles and works. At this level, cmakes generates a very complex link command to deal with deps tree.
  • external dependencies such as boost (some static libraries too)

At the moment, I tried this :

  • make an archive of the different .a generated but it doesn't work because linking against this lib tells me the archive a no index (even after ranlib). Yet, I remembered I could add .a libraries inside .a files without problems.
  • extract all .o object (with ar -x) files from all *.a files and recreated a "libsdk.a" with all these object files. It doesn't work either (unresolved references). Moreover, it includes all objects even those which are not needed... My working example takes 3.7M. This library is around 35M.
  • make a .so shared library. It seems to work but I would prefer having a static library.
  • compile all statically but then linker complains it doesn't find -lgcc_s. Ok I want to compile in static but not that far, and just my own libs together !

So my final question : is there any way I can generate my static lib containing all my other libs, and not system ones ?

BTW, another interesting topic on that : Combining static libraries

Thank you for any piece of advice to open my mind !

Community
  • 1
  • 1
user734173
  • 11
  • 1
  • 2
  • You can add .a libraries inside .a files at will, because `ar` is just an "archiver". Like `tar` or zip or arj. It knows nothing about libraries, so it can't tell you that the created thing is not a valid library. – Jan Hudec May 02 '11 at 10:44
  • The "extract all the .o and pack them together" should be correct approach (and the linker should be able to only pick those objects from the library that are needed). I can't tell why it does not link for you. As for the size of binary, isn't it simply so that all that code is pulled in because the files in the library are too interdependent, so most of it gets pulled in anyway? – Jan Hudec May 02 '11 at 10:50

2 Answers2

1

What you are trying to do by hand is the job of the linker. While it's feasible, you shouldn't bother with it.

When you compile libsdk.a, make sure that all of its dependencies are linked statically. If you do this, libsdk.a should be standalone. Static linking means copying the code to the right places in the final executable, so anything that is linked statically will not need to be provided in an external file.

Tamás Szelei
  • 23,169
  • 18
  • 105
  • 180
  • Hi Tamás, thank you. Yes I know, but I can't definitely admit that the linker can compile my example, and that I cannot generate a static library with the same symbols. I'm afraid that if I compile all intermediate objects statically, there will be at best symbols redundancy, and at at worst multiple definitions of symbols which will prevent me from doing the example linking. Anyway, I keep on investigating – user734173 May 02 '11 at 10:35
  • 2
    The linker should take care of redundancy (and only pick the objects that are needed). You should post more specific information (e.g. your cmake scripts or the makefile cmake generates) so we can help you. – Tamás Szelei May 02 '11 at 11:11
0

See this post on CMake mailing list. libutils.cmake attached to the message has MERGE_STATIC_LIBS() macro that does the job. On Linux (and all other Unixes except OSX) it uses ar to pack and unpack objects files.

Vladislav Vaintroub
  • 5,308
  • 25
  • 31