CMake Wildcard for TARGET_OBJECTS

2019-04-15 05:02发布

问题:

I have the following directory structure

-  CMakeLists.txt
-  include
    -  a.hh
-  lib
    -  CMakeLists.txt
    -  a.cc
-  src
    -  CMakeLists.txt
    -  main.cc
-  test
    -  CMakeLists.txt
    -  test.cc

I am using CMake for compiling test.cc using the command

add_executable(test test.cc $<TARGET_OBJECTS:A>)

and the object file A.o is compiled as

add_library(A OBJECT A.cc)

but the $<TARGET_OBJECTS:A> command becomes ugly very quickly. Is there any way to tell CMake to include all .o files in the lib folder for linking everything?

回答1:

Turning my comment into an answer

There is no build-in syntax like wildcards to simplify your add_executable(test test.cc $<TARGET_OBJECTS:A>) command.

Actually - to improve the convenience of handling object libraries in my current project - I've gone all the way of modifying my CMake version's source code to extend the target_link_libraries() to accept object libraries the same way it does static or shared libraries.

But there are other ways that may help you handling large amounts of object libraries:

  1. You could group object libraries into intermediate static libraries (but that somehow negates the effect of using object libraries):

    add_library(A OBJECT a.cc)
    add_library(B OBJECT b.cc)
    add_library(AB $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>) 
    
  2. You could "extend" the functionality of add_executable() e.g. with a function like:

    function(my_add_executable _target)
        foreach(_source IN ITEMS ${ARGN})
            if (NOT TARGET "${_source}")
                list(APPEND _source_list "${_source}")
            else()
                get_target_property(_type "${_source}" TYPE)
                if (_type STREQUAL "OBJECT_LIBRARY")
                    list(APPEND _source_list "$<TARGET_OBJECTS:${_source}>")
                else()
                    message(SEND_ERROR "my_add_executable: '${_source}' given as parameter is not a object-library target.")
                endif()
            endif()
        endforeach()
        add_executable(${_target} ${_source_list})
    endfunction(my_add_executable)
    

    Then you could mix your source files with names of object libraries. To prevent to much confusion I would recommend using more descriptive object library names (e.g. by adding a "Objs" suffix):

    add_library(AObjs OBJECT a.cc)
    ...
    my_add_executable(testA test.cc AObjs)
    

References

  • CMake properties and expanding generator expressions


标签: c++ cmake