Я пытаюсь понять, как написать библиотеку, которую можно было бы использовать, вызвав 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()
?
На данном этапе в вашем 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}>)
Вы должны указать файл заголовка вместе с .cpp в target_sources. Это имеет 2 эффекта:
в 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".
CMake теряется, когда вы указываете ${CMAKE_INSTALL_LIBDIR}/../ , он вычисляет 2 папки вместо корневого каталога. Если для PROJECT_CMAKE_CONFIG_DESTINATION установлено значение ${CMAKE_INSTALL_PREFIX}, это работает. Если вы читаете cmake.org/cmake/help/latest/module/…: «Если передан аргумент INSTALL_PREFIX, он используется в качестве базового пути для расчета всех относительных путей. Аргумент <path> должен быть абсолютным путем. Если этот аргумент не передан, будет использоваться переменная CMAKE_INSTALL_PREFIX. вместо." Вам следует подумать о том, чтобы не устанавливать в корневую папку.
Да! Вот оно. Большое спасибо
Я думаю, вы ищете не в той папке src, в папка src под lib есть заголовочный файл. Все остальные ваши пункты действительны, но моя главная проблема связана с установкой. Удаление
/
тоже не помогло.