OBJECT libraries and working around lake of target_link_libraries

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

OBJECT libraries and working around lake of target_link_libraries

davidhunter22
We recently converted some software, comprising about 300 projects, to use
OBJECT libraries from SHARED libraries so we could create "conveneince"
libraries that were cominations of some of the 300 projects. Not being
able to use target_link_libraries with thier transitive nature made this
very painful, many days of work. Supporting OBJECT libraries in
target_link_libraries calls was mentioned mentioned right back here
https://cmake.org/pipermail/cmake-developers/2012-March/015422.html but
sadly seems still to be on the back burner.

We are faced with a project hierarchy re-org and wanted to try to automate
generation of the dependencies. So we are thinking of doing the following.

1) Remove all the target_sources stuff from all CMakeLists.txt
2) Add add_dependencies calls to specify the project dependencies
3) run cmake with the --graphviz=graphviz.dot
4) Write a program that reads the resultant graphviz.dot and generate
   a file for each project that contain a target_sources call specifying
   all the dependencies for that project
5) In the CMakeLists.txt  for each project include the relevant generated
   target_sources file
6) Rerun cmake

Note the first time cmake gets run all the generated dependency files
are empty so the only dependencies are those specified by add_dependencies
calls.

Obviously the above is a bit convoluted, although we already have a
program to read and use the data in graphviz.dot file for other reason.
So my question is will the above approach work and is there a better one?
--

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:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: OBJECT libraries and working around lake of target_link_libraries

Chuck Atkins

Hi David,
 
Supporting OBJECT libraries in
target_link_libraries calls was mentioned mentioned right back here
https://cmake.org/pipermail/cmake-developers/2012-March/015422.html but
sadly seems still to be on the back burner.

It's not on the back burner!  There has been progress on desiging the rest of the implementation to make OBJECT libraries "first class citizens" and I  can't give you actual dates I do believe you can probably expect it some time this year.

 
Not being
able to use target_link_libraries with thier transitive nature made this
very painful, many days of work.

I actually just recently went through the exercise of creating a workaround for this in one of my projects so I can certainly understand the gaping hole that is currently present.  The workaround I ended up with was to create three seperate libraries: one for the objects, one for the usage requirements, and then a third that combines them.

add_library(foo_objects OBJECT foo_src1.cxx foo_src2.cxx ...)

add_library(foo_interface INTERFACE)
target_link_libraries(foo_interface INTERFACE FooDepend1 FooDepend2 ...)
target_include_directories(foo_interface INTERFACE
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR})>
  $<INSTALL_INTERFACE:include>)

add_library(foo INTERFACE)
target_sources(foo INTERFACE $<TARGET_OBJECTS:foo_objects>)
target_link_libraries(foo INTERFACE foo_interface)


The interface sources property on "foo" will populate the object files into whatever uses "foo" in its target_link_libraries and then the usage requirements in foo_interface will populate transitively.  The only problem with this approach, and the reason for creating three separate libraries instead of just adding the objects to the sources on foo_interface, is that INTERFACE_SOURCES will continue to get propagated transitively potentially causing duplicate symbols upstream, so it's really only appropriate for private linking so you want to link publically then add the objects manually and pass the interface publically.  This essentially means you need to use it like this:

// Use foo privately, so just put "foo" in TLL and it just works
add_library(bar1 bar1_src1.cxx bar1_src2.cxx)
target_link_libraries(bar1 PRIVATE foo)

// Use foo publicly so we need to separately grab the objects and
// their usage requirements.
add_library(bar2
  bar2_src1.cxx bar2_src2.cxx
  $<TARGET_OBJECTS:foo_objects>)
target_link_libraries(bar2 PUBLIC foo_interface)

This is effectively what the current plan is for the upstream implementation, just all rolled into one; i.e. the objects get added to whatever is explicitly linking with target_link_libraries, but all transitive linkage only uses the interface usage requirements.  Plans, of course, may change but that's what it's looking like right now, we just need to find the time and funding to implement it.

- Chuck


--

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:
http://public.kitware.com/mailman/listinfo/cmake
Loading...