Reputation: 1819
A somewhat similar question was asked here, Transitive target_include_directories on OBJECT libraries, but there was no real solution.
If I have a project b that depends on a project a I can build them as follows
add_library(a OBJECT ${a_srcs})
add_library(b OBJECT ${b_srcs})
When I want to build an excutable using I them I can write
add_executable(p ${p_srcs} $<TARGET_OBJECTS:b> $<TARGET_OBJECTS:a>)
Is there any way to not have to specify $<TARGET_OBJECTS:a>
? I assume this means telling CMake in some way that there is a dependency. If I was building SHARED libraries rather than OBJECT ones the b project would contain
target_link_libraries(b a)
which creates this dependency, but I can't find some equivalent way for OBJECT libraries.
Upvotes: 2
Views: 920
Reputation: 1972
The best way I have found to do this is to wrap the OBJECT
library in an INTERFACE
library.
add_library(a-objects OBJECT ${a_srcs})
add_library(b-objects OBJECT ${b_srcs})
add_library(a INTERFACE)
add_library(b INTERFACE)
target_link_libraries(a INTERFACE a-objects)
target_link_libraries(b INTERFACE b-objects)
target_sources(a INTERFACE $<TARGET_OBJECTS:a-objects>)
target_sources(b INTERFACE $<TARGET_OBJECTS:b-objects>)
My rule is to use the OBJECT
library to set requirements, but only ever link against the INTERFACE
library.
target_link_libraries(b-objects INTERFACE a)
Setting it up this way should allow you to link against both libraries like this:
add_executable(p ${p_srcs})
target_link_libraries(p PRIVATE b)
Upvotes: 0
Reputation: 863
Insofar as I understand it, in the current setup, no. The add_executable
for target p
can either
You have chosen (2). The only other option I see here is create a third library c
that merges in a
and b
into a full-blown library (see Usage
section at the bottom, which is likely where you were already looking).
When you do that, you could then target_link_libraries(c)
. The compiled OBJECT
s cannot be linked against on their own. You have to merge the sources into either an executable or a library for them to be used.
Your add_executable
call could be thought of basically doing add_executable(p ${p_srcs} ${a_srcs} ${b_srcs})
, only instead of compiling a_srcs
and b_srcs
(which has been done previously), just copy in the compiled objects instead of redoing the work. That's a really simple / bad explanation, but that's the general idea.
Upvotes: 1