问题描述
我试图弄清楚如何编写一个库,该库可以通过在另一个项目中调用 find_package()
来使用.我正在尝试遵循Catch2存储库 CMake文件.
I am trying to figure out how to write a library that could be consumed by calling find_package()
in another project. I am trying to follow the Catch2 repo CMake file.
这是我想出的最低版本:( git repo可用此处)
This is a minimal version that I have come up with: (the git repo is available here)
cmake_minimum_required(VERSION 3.14.4)
set(project_name "hello")
project(${project_name} LANGUAGES CXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
add_library(${project_name} STATIC)
target_sources(${project_name} PRIVATE "src/hello.cpp")
target_include_directories(${project_name}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/src/>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
install(
DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/src/
DESTINATION include
FILES_MATCHING REGEX "src/.+\.h"
PERMISSIONS
OWNER_READ
GROUP_READ
WORLD_READ)
set(PROJECT_CMAKE_CONFIG_DESTINATION ${CMAKE_INSTALL_LIBDIR}/../)
configure_package_config_file(
${CMAKE_CURRENT_LIST_DIR}/cmake/${project_name}Config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/${project_name}Config.cmake
INSTALL_DESTINATION
${PROJECT_CMAKE_CONFIG_DESTINATION})
install(
TARGETS
${project_name}
EXPORT
${project_name}Targets
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
install(
EXPORT
${project_name}Targets
NAMESPACE
${project_name}::
DESTINATION
${PROJECT_CMAKE_CONFIG_DESTINATION})
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/${project_name}Config.cmake"
DESTINATION
${PROJECT_CMAKE_CONFIG_DESTINATION})
然后我安装时正在使用:
I then install is using:
- cmake -DCMAKE_INSTALL_PREFIX:PATH="C:\tmp\install"
- cmake --build . --install target
,所有内容似乎都被复制到正确的路径.但是,当我尝试从另一个消耗我的测试库的项目中使用 find_package()
时,出现以下错误:
and everything seems to get copied to the right path. However, when I try to use find_package()
from another project thats consumes my test library, I get the following error:
CMake Error at C:/tmp/install/helloTargets.cmake:76 (message):
The imported target "hello::hello" references the file
"C://lib/hello.lib"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
"C:/tmp/install/helloTargets.cmake"
but not all the files it references.
Call Stack (most recent call first):
C:/tmp/install/helloConfig.cmake:33 (include)
CMakeLists.txt:15 (find_package)
似乎缺少cmake安装目录的路径.如何修改安装功能,以便 find_package()
可以使用生成的配置文件?
it appears it is missing the path to the cmake install directory. How can I modify the install functions so that the generated config file could be consumed by find_package()
?
推荐答案
在此阶段,您的CMakeLists.txt中有些事情很奇怪:
There are few things that are odds at this stage in your CMakeLists.txt :
target_include_directories(${project_name}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/src/>
# there is no header in this folder so this has no effect
# maybe create a include/ folder to make it more "legit"
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
您应该在 target_sources 中的.cpp中指定头文件.这有2种效果:
You should specify the header file along the .cpp in target_sources. This has 2 effects :
- 执行 install(TARGETS hello)时,可以添加 PUBLIC_HEADER 关键字,将属于目标的每个标头安装到$ {CMAKE_INSTALL_INCLUDEDIR}.这样,您无需使用正则表达式进行安装(目录)
- IDE将向他们显示
- when you do install(TARGETS hello) , you can add PUBLIC_HEADER keyword to install every headers that belong to the target to ${CMAKE_INSTALL_INCLUDEDIR}. That way, you don't need to do a install(DIRECTORY) with the regex
- IDE will show them
在helloConfig.cmake.in
in helloConfig.cmake.in
if(NOT TARGET hello::hello)
我认为,当您使用configure_package_config_file()时,生成的导出文件具有一定的逻辑以防止多重包含.
I think when you use configure_package_config_file() the export file generated has some logic to protect against multiple inclusion.
编辑13.06:由于PROJECT_CMAKE_CONFIG_DESTINATION设置为"lib/../",因此计算所有相对路径的基本路径是错误的有关CMake如何计算相对路径的一些文档
EDIT 13.06 :The base path to calculate all the relative paths is wrong due to PROJECT_CMAKE_CONFIG_DESTINATION set to "lib/../"some doc about how CMake computes the relative path
您尝试使用"$ {CMAKE_INSTALL_LIBDIR}/../"实现的实际上是."因此基本路径为$ {CMAKE_INSTALL_PREFIX}.另一种方法是安装在$ {CMAKE_INSTALL_LIBDIR}/cmake这样的子文件夹中,或者也可以只在"cmake"文件中安装
What you try to achieve with "${CMAKE_INSTALL_LIBDIR}/../" is actually "." so the base path is ${CMAKE_INSTALL_PREFIX}.An alternative, is to install in a subfolder like ${CMAKE_INSTALL_LIBDIR}/cmake or just "cmake" work as well
这篇关于带有相对路径的CMake安装目标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!