Reputation: 21
I have a library A
with public and private dependencies. The unit tests are contained in a separate executable ATests
which requires to link against both the private and the public dependencies of A
.
Currently, I explicitly link all private dependencies of A
to the unit tests ATest
. This results in a lot of code duplication which becomes increasingly difficult to understand/maintain.
add_library(A)
target_link_libraries(A PUBLIC Pub1 PRIVATE Priv1 Priv2)
add_executable(ATests)
target_link_libraries(ATests PRIVATE A Priv1 Priv2)
I thought about creating a separate interface library APrivDeps
for the private dependencies of A
, however, this looks like a hack. I have serious doubts that this is portable and will mess up the static linking due to the link dependency propagation. (I would have to export the helper library APrivDeps
.)
add_library(APrivDeps)
target_link_libraries(APrivDeps PUBLIC Priv1 Priv2)
add_library(A)
target_link_libraries(A PUBLIC Pub1 PRIVATE ADeps)
add_executable(ATests)
target_link_libraries(ATests PRIVATE A ADeps)
I expect some method that keeps the configuration short and free of code duplication while still following the target based principle of modern CMake.
Upvotes: 1
Views: 295
Reputation: 41
It is possible to explicitly propagate private dependencies. One way to do this is with the TARGET_PROPERTY generator expression.
add_library(A)
target_link_libraries(A PUBLIC Pub1 PRIVATE Priv1 Priv2)
add_executable(ATests)
target_link_libraries(ATests PRIVATE A $<TARGET_PROPERTY:A,LINK_LIBRARIES>)
It may also be necessary to propagate other properties like INCLUDE_DIRECTORIES
, COMPILE_OPTIONS
, and so on. This does feel a bit like breaking the target based principle of modern CMake so use judiciously. To me it seems to be a reasonable approach for unit tests.
Upvotes: 1