[CMake] Best way to combine generated static libraries into a single static library
Ke Gao
ke.gao.ut at gmail.com
Fri Sep 21 15:23:37 EDT 2018
So I guess in order to include the object-files from a third party static
library, the only way would be to first extract it's object-files and then
combine them?
On Fri, Sep 21, 2018 at 12:34 PM Deniz Bahadir <dbahadir at benocs.com> wrote:
> Am 21.09.2018 um 18:38 schrieb Ke Gao:
> > Hi David,
> >
> > It didn't give me error info. It can produce the final static library,
> > but the contents of third party static libraries are not included.
>
> Some clarification regarding STATIC and OBJECT library targets and how
> they interact with each other using `target_link_libraries`:
>
>
> A STATIC library target A can be linked (via `target_link_libraries`) to
> another STATIC library target B.
>
> `target_link_libraries(A STATIC PUBLIC B)`
>
> However, the resulting library file libB does not contain the
> information (aka object-files) of libA.
> Instead, CMake makes sure to link both static library files libB and
> libA when e.g. creating an executable exeC1 using target C1 which just
> links (via `target_link_libraries`) to target B.
>
> `target_link_libraries(C1 EXECUTABLE PUBLIC B)`
>
> (Instead of an executable exeC1 you could have created a shared library
> libC1 instead. The behavior is the same.)
>
>
> If you instead want to create a combined, single STATIC library libC2,
> which contains the object-files archived in both static library files
> libA and libB created from targets A and B, then you somehow need to
> extract the archived object-files from libA and libB. I am not sure if
> CMake provides a (simple) way to do this.
>
>
>
> For OBJECT libraries the behavior is like this:
>
>
> An OBJECT library target X can be linked (via `target_link_libraries`)
> to another OBJECT library target Y.
>
> `target_link_libraries(Y OBJECT PUBLIC X)`
>
> This, however, only transports the usage-requirements
> (preprocessor-defines, include-paths etc.) from X to Y. The object-files
> of X are in no way referenced by Y.
>
> So, if you then create a STATIC target Z1 that links (via
> `target_link_libraries`) to Y,...
>
> `target_link_libraries(Z1 STATIC PUBLIC Y)`
>
> ... Z1 will reference/contain the usage-requirements of X and Y and the
> object-files of Y, but not the object-files of X. (The static library
> file libZ1 resulting from Z1 will contain the object-libraries of Y but
> not of X.)
>
>
> What you should do instead is not to link the OBJECT targets X and Y
> together but instead only link them (explicitly) to the STATIC target Z2:
>
> `target_link_libraries(Z2 STATIC PUBLIC Y X)`
>
> Z2 then references the usage-requirements as-well-as object-files of
> both OBJECT targets X and Y and the resulting static library file libZ2
> will then contain the object-files of both library targets, X and Y.
>
>
> >
> > Also, sorry for the mistake I have made in my previous email. Deniz is
> > right, the keyword "PUBLIC" should be used in target_link_librarie().
> >
> > Thanks
>
> You're welcome.
>
> Deniz
>
>
> >
> > On Fri, Sep 21, 2018 at 10:06 AM David Jobet <djobet at tower-research.com
> > <mailto:djobet at tower-research.com>> wrote:
> >
> > 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
> > <mailto: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 <mailto: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
> > <mailto: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 <http://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
> > --
> >
> > Powered by www.kitware.com <http://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
> >
> >
> --
>
> 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20180921/7d7ec183/attachment-0001.html>
More information about the CMake
mailing list