.
+-- MyPack
| +-- Lib1
| | +-- include
| | | +-- Lib1.h
| | +-- src
| | | +-- Lib2.cpp
| | +-- CMakeLists.txt
| +-- Lib2
| | +-- include
| | | +-- Lib2.h
| | +-- src
| | | +-- Lib2.cpp
| | +-- CMakeLists.txt
| +-- CMakeLists.txt
+-- SubProject1
| +-- CMakeLists.txt
+-- SubProject2
| +-- CMakeLists.txt
+-- CMakeLists.txt
Всем привет.
Я новичок в CMake и пытаюсь получить что-то вроде следующего. Учитывая приведенное выше дерево каталогов моего проекта C++:
У меня есть каталог (скажем, "MyPack"), который содержит несколько подкаталогов (Lib1, Lib2...), и каждый из них представляет библиотеку C++, которую я написал.
Как я могу настроить все, чтобы я мог писать find_package(MyPack)
в других подпроектах?
Каждый подпроект является самостоятельным проектом и не зависит от других подпроектов, а только от библиотек в "MyPack".
Ваш рисунок немного сбивает с толку, потому что после Lib2 есть файл CMakeLists.txt, который не принадлежит ни одной папке... В любом случае: это Мой пакет
во 2-м случае:
Верхний каталог CMakeLists.txt дает вам доступ к целям Lib1 и Lib2, которые вы можете использовать в SubProject1 и SubProject2, если у вас есть что-то вроде этого:
project(MyPack)
add_subdirectory(Lib1) # Building Lib1
add_subdirectory(Lib2) # Building Lib2
add_subdirectory(SubProject1) # you can use Lib1 & Lib2 targets here
add_subdirectory(SubProject2) # you can use Lib1 & Lib2 targets here
Если это первый случай, Мой пакет — это только Lib1 и Lib2:
Использование find_package(MyPack) означает, что вам нужно создать файл конфигурации и установить() ваш проект:
project(MyPack)
add_subdirectory(Lib1)
add_subdirectory(Lib2)
в Lib1/CMakeLists.txt:
add_library(lib1 "")
add_library(MyPack::lib1 ALIAS lib1)
[...]
include(GNUInstallDirs)
install(
TARGET lib1
EXPORT MyPackTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
в Lib2/CMakeLists.txt:
add_library(lib2 "")
add_library(MyPack::lib2 ALIAS lib2)
[...]
include(GNUInstallDirs)
install(
TARGET lib2
EXPORT MyPackTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
Теперь у вас есть lib1 и lib2 в экспортных MyPackTargets. Вы также должны установить этот экспорт.
в любом месте после выше:
install(
EXPORT MyPackTargets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyPack
NAMESPACE MyPack::
FILE MyPackTargets.cmake # Not sure if this is still needed
)
include(CMakePackageConfigHelpers)
configure_package_config_file(
"Config.cmake.in"
"MyPackConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyPack
PATH_VARS
CMAKE_INSTALL_LIBDIR
)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/MyPackConfigVersion.cmake
VERSION 1.0.0
COMPATIBILITY SameMajorVersion
)
### Install Config and ConfigVersion files
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/MyPackConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/MyPackConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/MyPack"
)
создайте файл Config.cmake.in с:
@PACKAGE_INIT@
include( "${CMAKE_CURRENT_LIST_DIR}/MyPackTargets.cmake" )
Теперь, если вы создадите и установите свой проект MyPack, find_package(MyPack) из другого проекта должен найти его и импортировать созданные вами цели.
Вот некоторая документация: https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html
https://blog.kitware.com/cmake-superbuilds-git-submodules/
надеюсь, это поможет
Спасибо! Я до сих пор не могу заставить его работать так, как я хочу. Во-первых, дело первое, как вы поняли. Я поместил в lib1-2/CMakeLists.txt код, который вы предложили, экспортируя MyPackTargets. После этого я создал Config.cmake.in и CMakeLists.txt в MyPack/, куда добавил подкаталоги двух библиотек и поместил предложенный вами код (тот, который устанавливает MyPackTargets). Наконец, запустив cmake . в папке проекта (вне MyPack) он находит пакет MyPack, но не находит MyPack/MyPackTargets.cmake, который включен в MyPack/MyPackConfig.cmake. Любое дальнейшее предложение?
Это хороший знак, что ваш проект находит конфигурацию пакета MyPack. Теперь похоже, что путь в Config.cmake.in неверен, вы должны попытаться настроить его на расположение MyPackTargets.cmake в папке установки.
Проблема в том, что я нигде не могу найти файл MyPackTargets.cmake. Кстати, я решил поместить add_subdirectory для всех библиотек (в CMakeLists.txt MyPack) и add_subdirectory(MyPack) внутри CMakeLists.txt моего проекта (который находится внутри «MyPack»). Мне пришлось удалить директиву find_package, и теперь она работает нормально. Может быть, это не лучшая практика, но я мог делать то, что хотел. Так что спасибо тебе!
В основном вы использовали второе решение, которое я объяснил ранее: поскольку у вас есть весь исходный код, у вас есть доступ к целям внутри дерева сборки. Для вашей исходной проблемы MyPackTargets.cmake должен быть установлен путем установки (экспорт). проверьте эту команду, если она выполняет свою работу в правильном месте (вы можете проверить install_manifest.txt, чтобы увидеть, где установлен ваш файл)
Я считаю, что это «ЦЕЛИ», а не «ЦЕЛЬ», за исключением этой опечатки, решение работает потрясающе. Спасибо!
экспортируйте пакет в MyPack, а затем
-DCMAKE_PREFIX_PATH=../../MyPack