CMake устанавливает цели с относительными путями - PullRequest
0 голосов
/ 12 июня 2019

Я пытаюсь выяснить, как написать библиотеку, которую можно использовать, вызвав 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 Ответ

1 голос
/ 12 июня 2019

На этом этапе в вашем файле 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в target_sources .Это имеет 2 эффекта:

    • когда вы делаете установку (TARGETS привет) , вы можете добавить ключевое слово PUBLIC_HEADER , чтобы установить все заголовки, принадлежащие цели$ {CMAKE_INSTALL_INCLUDEDIR}.Таким образом, вам не нужно делать установку (DIRECTORY) с регулярным выражением
    • 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 вычисляет относительный путь

То, что вы пытаетесь достичь с помощью "$ {CMAKE_INSTALL_LIBDIR} /../" фактически "«.поэтому базовый путь составляет $ {CMAKE_INSTALL_PREFIX}.В качестве альтернативы можно установить в подпапку, например, $ {CMAKE_INSTALL_LIBDIR} / cmake или просто "cmake"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...