Problems with exported targets inside namespace which are linked with a generator expression.
I stumbled upon an issue (newest CMake Version 3.14):
Take this example where I am adding three libraries.
All of them are exported into namespace my::
.
On of them links to the other two, and in one case a generator expression is used for the target_link_libraries
command.
cmake_minimum_required(VERSION 3.13)
project(my)
add_library(dependency_incorrect dependency_incorrect.cpp)
add_library(dependency_correct dependency_correct.cpp)
add_library(lib lib.cpp)
set(condition TRUE)
target_link_libraries(lib PUBLIC
$<$<BOOL:${condition}>:dependency_incorrect>
dependency_correct
)
install (TARGETS dependency_incorrect dependency_correct lib)
EXPORT my_targets
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
install(EXPORT my_targets
FILE my_targets.cmake
DESTINATION lib/cmake/my
NAMESPACE my::
)
The generated my_targets.cmake
file then declares all 3 libraries and sets the target properties for INTERFACE_LINK_LIBRARIES
# Create imported target my::dependency_incorrect
add_library(my::dependency_incorrect STATIC IMPORTED)
# Create imported target my::dependency_correct
add_library(my::dependency_correct STATIC IMPORTED)
# Create imported target my::lib
add_library(my::lib STATIC IMPORTED)
set_target_properties(my::lib PROPERTIES
INTERFACE_LINK_LIBRARIES "\$<\$<BOOL:TRUE>:dependency_incorrect>;my::dependency_correct"
)
However, the generated code for the library which is linked in the generator expression is wrong, it is not prefixed with the namespace! I expect the following to be generated:
set_target_properties(my::lib PROPERTIES
INTERFACE_LINK_LIBRARIES "\$<\$<BOOL:TRUE>:my::dependency_incorrect>;my::dependency_correct"
)
Is this a bug? Or can't we use target_link_libraries
with generator expressions on targets which will later be exported?
(You can easily work around this problem by creating ALIAS targets in the exporting namespace and linking those).
add_library(dependency_incorrect dependency_incorrect.cpp)
add_library(dependency_correct dependency_correct.cpp)
add_library(my::dependency_incorrect ALIAS dependency_incorrect)
add_library(my::dependency_correct ALIAS dependency_correct)
add_library(lib lib.cpp)
set(condition TRUE)
target_link_libraries(lib PUBLIC
$<$<BOOL:${condition}>:my::dependency_incorrect>
my::dependency_correct
)
Please find the complete working example here cmake_sample.7z