Hi folks,
I’m having a hard time understanding how cmake should behave regarding installation of dependencies added with FetchContent so I’m sorry if this is a noob question, but I couldn’t find a satisfying answer so far.
I’m working with the C++ library xsimd and we’re having a discussion on how should behave the library in case of installing.
We’re including the library using FetchContent :
include(FetchContent)
FetchContent_Declare(
xsimd
GIT_REPOSITORY git@github.com:xtensor-stack/xsimd.git
GIT_TAG 11.1.0
GIT_SHALLOW ON
)
FetchContent_MakeAvailable(xsimd)
The library itself is an INTERFACE declared header-only library.
From what I understand, if the xsimd
library is declared as a PRIVATE dependency of my project, it should not be installed alongside my project (since its header-only) when installing. Whereas with PUBLIC/INTERFACE it should.
However with this library, it is always installed alongside the parent project.
Regarding current modern best practices, how do you think you it behave ?
If you think this is a bug, have you any ideas why does it behaves like that ?
Here is the CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(xsimd)
option(XSIMD_REFACTORING ON)
set(XSIMD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
# Versioning
# ==========
file(STRINGS "${XSIMD_INCLUDE_DIR}/xsimd/config/xsimd_config.hpp" xsimd_version_defines
REGEX "#define XSIMD_VERSION_(MAJOR|MINOR|PATCH)")
foreach(ver ${xsimd_version_defines})
if(ver MATCHES "#define XSIMD_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$")
set(XSIMD_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" CACHE INTERNAL "")
endif()
endforeach()
set(${PROJECT_NAME}_VERSION
${XSIMD_VERSION_MAJOR}.${XSIMD_VERSION_MINOR}.${XSIMD_VERSION_PATCH})
message(STATUS "xsimd v${${PROJECT_NAME}_VERSION}")
# Build
# =====
set(XSIMD_HEADERS
[...]
${XSIMD_INCLUDE_DIR}/xsimd/xsimd.hpp
)
add_library(xsimd INTERFACE)
target_include_directories(xsimd INTERFACE
$<BUILD_INTERFACE:${XSIMD_INCLUDE_DIR}>
$<INSTALL_INTERFACE:include>)
OPTION(ENABLE_XTL_COMPLEX "enables support for xcomplex defined in xtl" OFF)
OPTION(BUILD_TESTS "xsimd test suite" OFF)
if(ENABLE_XTL_COMPLEX)
find_package(xtl 0.7.0 REQUIRED)
target_compile_features(xsimd INTERFACE cxx_std_14)
target_compile_definitions(xsimd INTERFACE XSIMD_ENABLE_XTL_COMPLEX=1)
target_link_libraries(xsimd INTERFACE xtl)
else()
target_compile_features(xsimd INTERFACE cxx_std_11)
endif()
if(BUILD_TESTS)
enable_testing()
add_subdirectory(test)
endif()
OPTION(BUILD_BENCHMARK "xsimd benchmarks" OFF)
if(BUILD_BENCHMARK)
add_subdirectory(benchmark)
endif()
OPTION(BUILD_EXAMPLES "xsimd examples" OFF)
if(BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
# Installation
# ============
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(JoinPaths)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
install(TARGETS xsimd
EXPORT ${PROJECT_NAME}-targets)
# Makes the project importable from the build directory
export(EXPORT ${PROJECT_NAME}-targets
FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake")
install(DIRECTORY ${XSIMD_INCLUDE_DIR}/xsimd
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# GNUInstallDirs "DATADIR" wrong here; CMake search path wants "share".
set(XSIMD_CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" CACHE STRING "install path for xsimdConfig.cmake")
configure_package_config_file(${PROJECT_NAME}Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION ${XSIMD_CMAKECONFIG_INSTALL_DIR})
# xsimd is header-only and does not depend on the architecture.
# Remove CMAKE_SIZEOF_VOID_P from xtensorConfigVersion.cmake so that an xtensorConfig.cmake
# generated for a 64 bit target can be used for 32 bit targets and vice versa.
set(_XTENSOR_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
unset(CMAKE_SIZEOF_VOID_P)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
VERSION ${${PROJECT_NAME}_VERSION}
COMPATIBILITY SameMajorVersion)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
DESTINATION ${XSIMD_CMAKECONFIG_INSTALL_DIR})
install(EXPORT ${PROJECT_NAME}-targets
FILE ${PROJECT_NAME}Targets.cmake
DESTINATION ${XSIMD_CMAKECONFIG_INSTALL_DIR})
configure_file(${PROJECT_NAME}.pc.in
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
@ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/")