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

David Jobet djobet at tower-research.com
Fri Sep 21 12:05:54 EDT 2018


Hello,

glad that could help you.
For your newer problem, you don't describe them, so it's tough to know
what kind of problems you're facing.
Maybe a small example of your CMakeLists.txt + a capture of the error
cmake gives you could help ?

David
On Fri, Sep 21, 2018 at 4:52 PM Ke Gao <ke.gao.ut at gmail.com> wrote:
>
> Thank you all for the help.
>
> I finally use a way quite similar to David's first approach. I first generate all sub-projects into object libraries using add_library(lib1 OBJECT SOURCES). Then in the final library, I use add_library(single_static_lib STATIC SOURCES) and target_link_libraries( single_static_lib lib1 lib2 ...). Note that I didn't use " $<TARGET_OBJECTS:lib1>" in the final "add_library" and also didn't use "PUBLIC" keyword in the final "target_link_libraries". It works on CMake v3.12.2 and gives me a single static lib which combines all the objs I want.
>
> But currently I still have problems of further combining third party static libraries into the final generated static single_static_lib. Can anybody provide a solution for this?
>
> Thank you very much.
>
> Ke
>
> On Fri, Sep 21, 2018 at 6:15 AM Deniz Bahadir <dbahadir at benocs.com> wrote:
>>
>> 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
>>
>> --
>>
>> Powered by www.kitware.com
>>
>> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>>
>> Kitware offers various services to support the CMake community. For more information on each offering, please visit:
>>
>> CMake Support: http://cmake.org/cmake/help/support.html
>> CMake Consulting: http://cmake.org/cmake/help/consulting.html
>> CMake Training Courses: http://cmake.org/cmake/help/training.html
>>
>> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>>
>> Follow this link to subscribe/unsubscribe:
>> https://cmake.org/mailman/listinfo/cmake
>
>
>
> --
> ..............................................................................................................................................
> Ke Gao


More information about the CMake mailing list