I understand the reason why target_link_libraries
accepts raw library names that aren’t known targets to CMake. However, it can often lead to surprises and wasted time. What sometimes happens is this:
- a developer adds a
target_link_libraries
to use a library in one of his existing targets - developer starts a build job, which runs for quite a while, before failing because the include dir is wrong
- the developer adds the missing
find_package
- everything recompiles because now the include dirs have changed
I am aware of the fact that so-called namespaced targets provide this functionality. However, there are still many targets out there that do not support this. Ideally I think we’d have a flag for target_link_libaries
which makes it accept targets only. Perhaps a syntax like this:
target_link_libraries(MyExecutable TARGET_ONLY PUBLIC MyLibrary)
Right now we use a wrapper function I wrote that works around this problem by checking for targets and then calling target_link_libraries
:
function(target_link_target LINK_TO)
set(OPTIONS)
set(SINGLE_VALUE)
set(MULTI_VALUE PRIVATE PUBLIC INTERFACE)
cmake_parse_arguments(TLT "${OPTIONS}" "${SINGLE_VALUE}" "${MULTI_VALUE}" ${ARGN})
# ensure we got at least one thing to link
if (NOT TLT_PRIVATE AND NOT TLT_PUBLIC AND NOT TLT_INTERFACE)
message(FATAL_ERROR "No targets given for linking, specify at least one of PUBLIC, PRIVATE or INTERFACE")
endif()
foreach(ITEM ${TLT_PRIVATE})
if (NOT TARGET ${ITEM})
message(FATAL_ERROR "Linking to target ${ITEM}, which is not found")
endif()
target_link_libraries(${LINK_TO} PRIVATE ${ITEM})
endforeach()
foreach(ITEM ${TLT_PUBLIC})
if (NOT TARGET ${ITEM})
message(FATAL_ERROR "Linking to target ${ITEM}, which is not found")
endif()
target_link_libraries(${LINK_TO} PUBLIC ${ITEM})
endforeach()
foreach(ITEM ${TLT_INTERFACE})
if (NOT TARGET ${ITEM})
message(FATAL_ERROR "Linking to target ${ITEM}, which is not found")
endif()
target_link_libraries(${LINK_TO} INTERFACE ${ITEM})
endforeach()
endfunction()
But it’s kind of a crude solution for a problem I believe others can also run into.