Hi,
I have the following sample project.
cmake_minimum_required(VERSION 3.21)
project(proj LANGUAGES CXX)
include(GNUInstallDirs)
set(source_file "${CMAKE_CURRENT_BINARY_DIR}/lib.cpp")
file(WRITE "${source_file}" "int foo() {return 0;}")
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/utils")
add_library(Core SHARED "${source_file}")
target_include_directories(Core PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/utils>")
target_compile_definitions(Core PUBLIC "FEATURE1=ON")
target_compile_features(Core PUBLIC "cxx_std_23")
target_compile_options(Core PUBLIC "-Wall")
add_library(Gui STATIC "${source_file}")
# (1)
#target_link_libraries(Gui PRIVATE Core)
# This causes the ToolkitTargets.cmake file to contain
#set_target_properties(Toolkit::Gui PROPERTIES
#INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:Core>"
#)
# (2)
#target_link_libraries(Gui PRIVATE $<LINK_ONLY:Core>)
# This causes the ToolkitTargets.cmake file to contain
#set_target_properties(Toolkit::Gui PROPERTIES
#INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:\$<LINK_ONLY:Core>>"
#)
#(3) This achieves the desired effect, but is verbose and might not cover everything?
target_include_directories(Gui PRIVATE "$<TARGET_PROPERTY:Core,INTERFACE_INCLUDE_DIRECTORIES>")
target_compile_definitions(Gui PRIVATE "$<TARGET_PROPERTY:Core,INTERFACE_COMPILE_DEFINITIONS>")
target_compile_features(Gui PRIVATE "$<TARGET_PROPERTY:Core,INTERFACE_COMPILE_FEATURES>")
target_compile_options(Gui PRIVATE "$<TARGET_PROPERTY:Core,INTERFACE_COMPILE_OPTIONS>")
install(TARGETS Core Gui
EXPORT ToolkitTargets
BUNDLE DESTINATION .
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(EXPORT ToolkitTargets
NAMESPACE Toolkit::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Toolkit
)
$ cmake .. -DCMAKE_INSTALL_PREFIX=$PWD/installed -GNinja && ninja install
I would like to consume the usage requirements of the Core
shared lib when building the Gui
static lib, but not export the $<LINK_ONLY:Core>
requirement in the installed ToolkitTargets.cmake
file for the Gui
static lib, so that user projects that consume Gui
don’t need to link to the Core
target.
By consuming the usage requirements, I mean make sure Core
’s compile definitions, compile features, include paths, etc are used when building Gui
’s sources.
The explicit link requirement is not needed, because Core
will be dynamically loaded using dlopen()
by Gui
’s sources at an appropriate time.
I think I can achieve that using approach (3) as described in the project comment.
(1) and (2) don’t work because of $<LINK_ONLY:Core>
being automatically added to Gui
’s INTERFACE_LINK_LIBRARIES
.
I don’t like (3) because i’m not sure if it covers everything, and because in the future CMake might introduce new types of usage requirements.
Ideally I’d use something like (1), perhaps with a new generator expression like
target_link_libraries(Gui PRIVATE $<CONSUME_COMPILE_USAGE_REQUIREMENTS:Core>)
Does something like that exist already? Is there a better way of achieving what I want?
Thank you.