Установка CMake (ЦЕЛИ в подкаталогах)
Рассмотрим следующий файл CMakeLists.txt
:
add_subdirectory(execA)
add_subdirectory(libB)
install(TARGETS execA libB
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
Я получаю следующую ошибку:
install TARGETS given target "execA" which does not exist in this
directory
execA
и libB
имеют свои собственные файлы CMakeList.txt
и находятся в каталоге project
, а также в каталоге компоновки, с которым я работаю cmake
(cmake ..
):
project
|------ CMakeList.txt (the one with the code)
|----execA
| \- .cpp, .hpp and CMakelist.txt
|----libB
| \- .cpp, .hpp and CMakelist.txt
|---- lib
|---- bin
\---- build (where I´m commanding: $ cmake ..
Как мне исправить эту ошибку?
Ответы
Ответ 1
Согласно этому отчету об ошибках, поток команд install(TARGETS)
принимает только цели , созданные в одном каталоге.
Поэтому вам нужно либо переместить вызов add_library()
в каталог верхнего уровня, либо разделить вызов install(TARGETS)
на целевые и переместить каждый из них в соответствующий подкаталог.
Начиная с CMake 3.13 install(TARGETS)
может работать даже с целями, созданными в других каталогах.
install(TARGETS)
может устанавливать цели, созданные в других каталогах. При использовании таких правил установки между каталогами запуск make install
(или аналогичного) из подкаталога не гарантирует актуальность целей из других каталогов.
Ответ 2
Это все еще кажется проблемой в CMake 3.11.
В нашей кодовой базе у нас есть много целей, определенных в подкаталогах, и нам необходимо создать ассортимент инсталляторов с различными конфигурациями и (потенциально перекрывающимися) комбинациями целей.
Вот мое решение:
- Перед вызовом
add_subdirectory
в корневом файле CMakeLists.txt создайте свойство GLOBAL
с именами целей, которые вы хотите включить в свой установщик.
- Оберните функции создания цели (
add_executable
и т.д.) В свои собственные пользовательские функции. В этих функциях проверьте, присутствует ли цель в глобальном свойстве, и соответственно вызовите install
.
Такой подход позволяет централизовать настройку установщика.
Также: для поддержки создания нескольких установщиков мы заполняем наш глобальный список вместе с другими свойствами установщика в отдельных файлах .cmake. Когда мы вызываем cmake
, мы передаем имя файла конфигурации установщика CMake в качестве аргумента командной строки. Наш корневой файл CMakeLists.txt просто вызывает include
с этим файлом.
Ответ 3
Несмотря на то, что это поможет увидеть файлы CMakeLists.txt
содержащиеся в подкаталогах, я предполагаю, что они содержат add_executable
и/или add_library
для создания ваших вещей.
Кроме того, из-за вашего примера, я думаю, вы используете то же имя своих каталогов для своих целей.
Тем не менее, вы должны знать, что символы, определенные в файле CMakeLists.txt
в подкаталоге, по умолчанию не отображаются в контексте файла CMakeLists.txt
в родительском каталоге. Из-за этого вы должны перенести свои инструкции install
в файлы CMakeLists.txt
в свои подкаталоги.
Это должно решить проблему, если мои мысли были правильными. В противном случае я настоятельно рекомендую вам опубликовать в своем вопросе также содержимое других файлов, упомянутых выше.
Во всяком случае, ошибка довольно ясна.
Файл, содержащий инструкцию install
для объекта с именем X
, не содержит оператора создания цели (add_executable
и других), который рождает эту цель, поэтому он продолжает утверждать, что эта цель не существует в этом каталоге.
Ответ 4
Это решено в 3.13: установить: разрешить установку целей, созданных в другом каталоге