часто необходимо для того, чтобы CMake строить проекты в конечном итоге в определенном месте после компиляции, а команда add_custom_command(..POST_BUILD...)
является общим шаблоном дизайна для достижения этой цели:альтернативы команды CMake POST_BUILD, когда цель находится в подкаталоге
add_custom_command(
TARGET mytarget
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:mytarget> ${CMAKE_BINARY_DIR}/final_destination
)
К сожалению, это не работает, когда рассматриваемая цель находится в подкаталоге относительно файла, содержащего вызов add_custom_command
, который был скомпилирован с помощью команды add_subdirectory()
. Попытка сделать это приводит к следующему сообщению об ошибке:
CMake Warning (dev) at CMakeLists.txt:4 (add_custom_command):
Policy CMP0040 is not set: The target in the TARGET signature of
add_custom_command() must exist. Run "cmake --help-policy CMP0040" for
policy details. Use the cmake_policy command to set the policy and
suppress this warning.
TARGET 'mytarget' was not created in this directory.
This warning is for project developers. Use -Wno-dev to suppress it.
Во многих случаях существует простой обходной путь: просто убедитесь, что add_custom_command()
вызова происходит в CMakeLists.txt
файле подкаталога, и все будет работать.
Однако это не всегда возможно! Подкаталог может быть проектом CMake внешней зависимости, над которым мы не контролируем. Например, довольно распространено комбинирование рекурсивных компиляций CMake с подмодулями Git, и в этом случае нет возможности постоянно сохранять модификации системы построения дочерних проектов.
Мой вопрос затем сводится к следующему: предлагает ли CMake другой механизм для создания цели, которая будет автоматически инициирована при восстановлении цели дочернего проекта и которая может быть использована для копирования окончательной исполняемой или разделяемой библиотеки на некоторые Другое место?
Моя цель заключается в том, что это происходит автоматически, без необходимости специально называть 'make'/'ninja' другой целью. Кроме того, копия должна выполняться только тогда, когда она действительно необходима (в соответствии с документами cmake некоторые команды add_custom_ * не отслеживают, нужно ли их фактически запускать и консервативно предположить, что цель всегда устарела).
Все ли файлы подкаталогов 'CMakeLists.txt' из того же самого/вашего проекта? И говорим ли мы обо всех объектах, например, или вы хотите применить это только к конкретным целям? В моем проекте я создал свою собственную функцию() 'для всех стандартных вызовов CMake, поэтому я могу изменить стандартное поведение, например. 'add_executable()' для моего проекта (например, автоматически добавляет шаг после сборки ко всем таким вызовам). – Florian
Подкаталоги обычно будут разделяемыми библиотеками, распространяемыми как git-подмодули, клонированные из github (например, '' pugixml''). Эти проекты имеют свои проекты CMake, которые я не могу (и не хочу) менять. Родительский проект может генерировать смесь исполняемых или разделяемых библиотек - я не утончаю, это особенно важно для этого вопроса. –