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

David Jobet djobet at tower-research.com
Fri Sep 21 03:33:44 EDT 2018


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


More information about the CMake mailing list