Цели установки CMake с относительными путями

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
1 979
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

На данном этапе в вашем 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 эффекта:

    • когда вы делаете установить(цели привет) , вы можете добавить ключевое слово 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 вычисляет относительный путь

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

Я думаю, вы ищете не в той папке src, в папка src под lib есть заголовочный файл. Все остальные ваши пункты действительны, но моя главная проблема связана с установкой. Удаление / тоже не помогло.

Ali 12.06.2019 17:23

CMake теряется, когда вы указываете ${CMAKE_INSTALL_LIBDIR}/../ , он вычисляет 2 папки вместо корневого каталога. Если для PROJECT_CMAKE_CONFIG_DESTINATION установлено значение ${CMAKE_INSTALL_PREFIX}, это работает. Если вы читаете cmake.org/cmake/help/latest/module/…: «Если передан аргумент INSTALL_PREFIX, он используется в качестве базового пути для расчета всех относительных путей. Аргумент <path> должен быть абсолютным путем. Если этот аргумент не передан, будет использоваться переменная CMAKE_INSTALL_PREFIX. вместо." Вам следует подумать о том, чтобы не устанавливать в корневую папку.

Alkalyne 13.06.2019 06:40

Да! Вот оно. Большое спасибо

Ali 14.06.2019 16:34

Другие вопросы по теме