使用相对路径在CMake中安装目标

3

我正在尝试编写一个库,可以通过在另一个项目中调用find_package()来使用。我正试图遵循 Catch2 存储库的CMake文件

这是我想到的最小版本:(git存储库在此处可用)

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})

我使用以下方式进行安装:
- cmake -DCMAKE_INSTALL_PREFIX:PATH="C:\tmp\install"
- cmake --build . --install target

一切似乎都被复制到了正确的路径中。然而,当我尝试从另一个使用我的测试库的项目中使用 find_package() 时,出现以下错误:

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()使用?

1个回答

2

在CMakeLists.txt中,有几件事情是不寻常的:

"Original Answer"翻译成"最初的回答"

  1. 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}>)
    
  2. You should specify the header file along the .cpp in target_sources. This has 2 effects :

    • 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
  3. in helloConfig.cmake.in

if(NOT TARGET hello::hello)

我认为当你使用configure_package_config_file()时,生成的导出文件具有一些逻辑来防止多次包含。
编辑13.06:由于PROJECT_CMAKE_CONFIG_DESTINATION设置为"lib / .. /",计算所有相对路径的基本路径是错误的。有关CMake如何计算相对路径的一些文档
您尝试使用"${CMAKE_INSTALL_LIBDIR} / .. /"实现的目标实际上是".",因此基本路径为${CMAKE_INSTALL_PREFIX}。另一种选择是在子文件夹中安装,例如${CMAKE_INSTALL_LIBDIR} / cmake或只是"cmake"。

我认为你正在错误的src文件夹下查找,在源代码文件夹的lib文件夹下有一个头文件。虽然你提到的其他点都是正确的,但我的主要问题在于安装。删除“/”也没有帮助。 - Ali
1
当您指定 ${CMAKE_INSTALL_LIBDIR}/../ 时,CMake会迷失方向,它会计算两个文件夹而不是根目录。 如果将_PROJECT_CMAKE_CONFIG_DESTINATION_设置为 ${CMAKE_INSTALL_PREFIX},则可以解决此问题。 如果您阅读 https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html: "如果传递了INSTALL_PREFIX参数,则将其用作计算所有相对路径的基本路径。 <path>参数必须是绝对路径。 如果未传递此参数,则将使用CMAKE_INSTALL_PREFIX变量。" 您应该考虑不要安装在根文件夹中。 - Alkalyne
耶!就是这样了。非常感谢你。 - Ali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接