Include paths for header-only dependencies not propagating to non-header-only library targets.
cmake 3.25.3, gcc 12.2.0.
foo
:# foo CMakeLists.txt
add_library(foo INTERFACE)
foo
exists to provide some c++ header files
# foo CMakeLists.txt
target_include_directories(foo INTERFACE
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>)
install(
TARGETS foo
EXPORT fooTargets
LIBRARY DESTINATION lib COMPONENT Runtime
ARCHIVE DESTINATION lib COMPONENT Development
RUNTIME DESTINATION lib COMPONENT Runtime
PUBLIC_HEADER DESTINATION include COMPONENT Development
BUNDLE DESTINATION bin COMPONENT Runtime)
foo
generates+exports .cmake config files to drive find_package
# foo cmake/fooConfig.cmake.in
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/fooTargets.cmake")
check_required_components("@PROJECT_NAME@")
and
# foo CMakeLists.txt
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${PROJECT_BINARY_DIR}/fooConfigVersion.cmake"
VERSION 1.0
COMPATIBILITY AnyNewerVersion)
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/fooConfig.cmake.in"
"${PROJECT_BINARY_DIR}/fooConfigVersion.cmake
INSTALL_DESTINATION lib/cmake/foo)
install(
EXPORT fooTargets
DESTINATION lib/cmake/foo)
install(
FILES
"${PROJECT_BINARY_DIR}/fooConfigVersion.cmake"
"${PROJECT_BINARY_DIR}/fooConfig.cmake"
DESTINATION lib/cmake/foo)
bar
.bar
is in a separate codebase# bar CMakeLists.txt
find_package(foo CONFIG REQUIRED)
add_library(bar SHARED bar.cpp)
target_include_directories(bar PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
bar
needs foo
headers to compile:# bar CMakeLists.txt
target_link_libraries(bar INTERFACE foo)
bar.cpp
doesn't receive foo
headers:$ make VERBOSE=1
g++ -Ipath/to/bar/include path/to/bar.cpp ... # path/to/foo/include missing
This only happens for an INTERFACE dependency. If I make foo a SHARED target + use it in bar as a PUBLIC dependency, then foo headers get forwarded to the compiler
# bar CMakeLists.txt
get_target_property(tmp foo INTERFACE_INCLUDE_DIRECTORIES)
set_property(
TARGET bar
APPEND PROPERTY INCLUDE_DIRECTORIES ${tmp})
QUESTIONS
Is this necessary? Is there something wrong with my header-only packaging?
Some missing ingredient in fooConfig.cmake.in ?
From comments:
bar
depending on header-only library foo
:target_link_libraries(bar PUBLIC foo)
quux
depending on header-only library foo
:target_link_libraries(quux INTERFACE foo)