2

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?

  • I would say there is nothing like wildcards that isn't at least as long as the command you are currently using (and which would still be cross-platform compatible). Can you elaborate a little on what you mean with "getting ugly"? There is maybe a solution that hides if you are using object libraries in a macro, but I'm not sure if this is the direction you want to go. – Florian Feb 29 '16 at 09:49
  • By getting ugly, I mean, the list of linked libraries grows long enough to be untrackable and hence error prone. Object A, Object B and so on, and may be you forgot C in list of 5 and you didn't notice. –  Feb 29 '16 at 09:54
  • 1
    You may collect all references to your static libraries in list variable, and use it for create executable: `set(my_source_libs)`, `list(APPEND my_source_libs $)`, `list(APPEND my_source_libs $)`, ...,`add_executable(test test.cc ${my_libs})`. There are many other *programming* ways to achive similar effect. – Tsyvarev Feb 29 '16 at 10:39

1 Answers1

3

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

Community
  • 1
  • 1
Florian
  • 39,996
  • 9
  • 133
  • 149
  • do you have any plans to upstream your code to cmake for your modified `target_link_libraries`, that would be immensely useful. – therealjumbo Dec 14 '16 at 20:18
  • second option of appening target_objects to a list does not seem to work. Atleast for 3.17. Is there a better way ? By the way, I was creating a library rather than an executable. – user2914066 Jul 20 '20 at 16:40