[CMake] Best way to combine generated static libraries into a single static library

Deniz Bahadir dbahadir at benocs.com
Fri Sep 21 08:07:12 EDT 2018


Am 21.09.2018 um 09:33 schrieb David Jobet:
> Hello,
> 
> I had a similar issue lately and wanted to "pack" several static libs
> into a dynamic one. (Not even talking about an INTERFACE lib since I
> really wanted that .so)
> I made it work with 3 different solutions, none of them being "clean"
> from my point of view.
> 
> 1- OBJECT libs on sub projects : add_library(lib1 OBJECT SOURCES) and
> for the single static lib : add_library(single_static_lib STATIC
> $<TARGET_OBJECTS:lib1> ...)
> Problem I faced : since OBJECT libs do not support
> target_link_libraries(), I had to remove the existing one and move
> them instead to the target_include_directories() using generators.

This is no longer true. Since CMake 3.12 `target_link_libraries` fully 
supports OBJECT libraries. You just need to pay attention to the special 
case of linking an OBJECT library with keyword "PUBLIC". (Object-files 
are always private and inherited object-files are therefore never 
further inherited. See: 
https://cmake.org/cmake/help/v3.12/command/target_link_libraries.html#linking-object-libraries)

> e.g : target_include_directories(lib1 PUBLIC
> $<TARGET_PROPERTY:another_lib,INCLUDE_DIRECTORIES>)
> Because I had a dependency to a protobuf generated lib, I also had to
> add manual add_dependencies to respect proper build order.
> Not clean at all
> 
> 2- add_library(mysharedlib STATIC CMakeLists.txt)
> target_linked_libraries(mysharedlib PUBLIC lib1 ...)
> Maybe the cleanest way I found.
> The trick with CMakeLists.txt is that add_library needs at least one
> source file. You can put any kind of files you want. CMakeLists.txt is
> not compilable, so no extra compilation step, no need for dummy empty
> source file and add_library is happy.
> It did not work in my case because of problems related to how our .so
> are used/generated. (problems at runtime with duplicated symbols in
> protobufs)
> 
> 3- a variation around 1
> instead of defining OBJECT libs, define a variable holding all the
> sources for lib1, another for lib2, ...
> then just do add_library(mysharedlib STATIC ${SOURCES_FOR_lib1}
> ${SOURCES_FOR_lib2})
> It works a little bit like 1) but does not have any of its problems
> (target_link, add_dependencies, generators, ...)
> It has new problems of its own though : if your libs live in different
> subfolders, the variables might not be visible from your
> add_library(mysharedlib...) call.
> To work around that, you can use PARENT_SCOPE (not sure if that works
> accross several levels), or includes (defines those variables into
> separate files living in each subfolders and include them in the
> parent CMakeLists).
> 
> Hope this helps (and I'd be happy to know of other ways)
> 
> David
> On Thu, Sep 20, 2018 at 5:45 PM Ke Gao <ke.gao.ut at gmail.com> wrote:
>>
>> Hi,
>>
>> I have a project which includes many sub-projects. Each sub-project generates a static library. In the main project, I want to combine the generated objs, generated static libraries from other sub-projects, and some other third party static libraries together into a single static library. Is there an elegant way to do this, or maybe an existing function?
>>
>> Thank you very much.
>>
>> --
>> ..............................................................................................................................................
>> Ke Gao


Hope that information was of value,
Deniz



More information about the CMake mailing list