具有相对路径的 CMake 安装目标

2023-12-27

我试图弄清楚如何编写一个可以通过调用使用的库find_package()在另一个项目中。我正在尝试遵循 Catch2 存储库CMake文件 https://github.com/catchorg/Catch2/blob/master/CMakeLists.txt.

这是我想出的最小版本:(git repo 可用here https://gitlab.com/AliAskari/cmake_conan/blob/master/libs/hello/CMakeLists.txt)

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


在此阶段,您的 CMakeLists.txt 中存在一些问题:

  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. 您应该在 .cpp 中指定头文件目标源。这有两个效果:

    • 当你这样做时安装(目标你好), 你可以加PUBLIC_HEADER关键字将属于目标的每个标头安装到 ${CMAKE_INSTALL_INCLUDEDIR}。这样,您不需要使用正则表达式进行安装(目录)
    • IDE 将显示它们
  3. 在 helloConfig.cmake.in 中

if(NOT TARGET hello::hello)

我认为当您使用 configure_package_config_file() 时,生成的导出文件具有一些逻辑来防止多重包含。

最后,我认为你的主要问题是由于 PROJECT_CMAKE_CONFIG_DESTINATION 的位置引起的,如果你删除最后一个“/”,我认为它应该可以解决问题。

编辑13.06: 由于 PROJECT_CMAKE_CONFIG_DESTINATION 设置为“lib/../”,计算所有相对路径的基本路径是错误的一些关于 CMake 如何计算相对路径的文档 https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html#module:CMakePackageConfigHelpers

您尝试使用“${CMAKE_INSTALL_LIBDIR}/../”实现的目标实际上是“.”所以基本路径是${CMAKE_INSTALL_PREFIX}。 另一种方法是安装在 ${CMAKE_INSTALL_LIBDIR}/cmake 等子文件夹中,或者直接安装“cmake”也可以

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有相对路径的 CMake 安装目标 的相关文章

随机推荐