问题
I am trying to generate a config CMake file for a sample project I have. My example is made of two CMake projects: a library, which uses spdlog internally and eigen in its interface and an application, which uses the library. The idea is to learn how to create a Config.cmake file so the application can find the library. This is what I have:
cmake_minimum_required(VERSION 3.16)
project(tutorial-4 CXX)
set(CMAKE_CXX_STANDARD 14)
find_package(Eigen3 REQUIRED)
set(LIBRARY_SOURCES
Lib/lib.cpp)
set(LIBRARY_HEADERS
Lib/lib.h)
add_library(smalllib-4
SHARED
${LIBRARY_SOURCES}
${LIBRARY_HEADERS}
)
find_package(spdlog REQUIRED)
find_package(Eigen3 REQUIRED)
target_link_libraries(smalllib-4
PRIVATE spdlog::spdlog
PUBLIC Eigen3::Eigen)
target_include_directories(smalllib-4 PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)
set_target_properties(smalllib-4 PROPERTIES PUBLIC_HEADER ${LIBRARY_HEADERS})
install(TARGETS smalllib-4
EXPORT smalllib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static
PUBLIC_HEADER DESTINATION include/Lib)
install(EXPORT smalllib NAMESPACE smalllib:: DESTINATION share/smalllib)
include(CMakePackageConfigHelpers)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/smalllibConfig.cmake
INSTALL_DESTINATION share/smalllib
)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/smalllibConfig.cmake
DESTINATION share/smalllib
)
This generates succesfuly a smalllibConfig.cmake, but when I try to do find_package(smalllib REQUIRED)
, I get the following error:
CMake Error at CMakeLists.txt:10 (add_executable):
Target "smallapp" links to target "Eigen3::Eigen" but the target was not
found. Perhaps a find_package() call is missing for an IMPORTED target, or
an ALIAS target is missing?
This happens because in the generated smalllib.cmake, I have the following
add_library(smalllib::smalllib-4 SHARED IMPORTED) set_target_properties(smalllib::smalllib-4 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include" INTERFACE_LINK_LIBRARIES "Eigen3::Eigen" )
but Eigen3::Eigen
is not defined here.
Eigen is a dependency of the library, so adding it to the application doesn't seem to be the correct way to go using modern CMake. What is the generic way to create my config files for CMake?
回答1:
The config file for smalllib
package should define Eigen3::Eigen
target. The most direct approach is to use find_dependency macro for Eigen3 as you use find_package
in the CMakeLists.txt
for the package itself:
Config.cmake.in (this file is used as a template for the resulted config file):
# Get definition of 'find_dependency' macro
include(CMakeFindDependencyMacro)
# Find Eigen3. This will create 'Eigen3::Eigen' target
find_dependency(Eigen3)
# Include CMake-generated config file for the 'smalllib' target
# which uses 'Eigen3::Eigen' target.
include(${CMAKE_CURRENT_LIST_DIR}/smalllib.cmake)
This way is described in the CMake documentation about the packaging.
回答2:
From the description, it seems like the generated smalllibConfig.cmake
is missing a call to find_package(Eigen3 REQUIRED)
before the targets file gets included.
来源:https://stackoverflow.com/questions/62519433/create-config-file-for-cmake-project