CMake генерирует что-то вроде следующего для правила установки:
# Special rule for the target install
install: preinstall
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
/usr/local/bin/cmake -P cmake_install.cmake
.PHONY : install
Что я хочу сделать, так это выполнить некоторые пользовательские команды после вызова cmake_install.cmake, чтобы это выглядело примерно так:
# Special rule for the target install
install: preinstall
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
/usr/local/bin/cmake -P cmake_install.cmake
post_install_command_1
...
post_install_command_n
.PHONY : install
Я могу делать то, что хочу, используя add_custom_command(TARGET ... POST_BUILD ...) для вещей, которые мы написали (6-10 макросов для обновления). Тем не менее, есть куча сторонних вещей, которые устанавливаются, и я действительно не хочу добавлять POST_BUILD пользовательских команд для всех из них (в настоящее время 19 проектов, и еще больше, и может быть сложно определить, что нужно обработать после сборки, а не после установки). Я думаю, было бы намного проще поддерживать, если бы пользовательские команды использовались только в одном месте (т. е. как последняя часть обработки установки) и где я знаю, что они сделают все, что необходимо.
Можно ли заставить CMake добавлять команды в правило установки Makefile верхнего уровня?
Ответ 1 · рейтинг 12 · sakra
Вы можете использовать вариант SCRIPT или CODE команды install. . Если вы поместите необходимые команды в скрипт PostInstall.cmake в корневой каталог проекта, добавьте следующий вызов в самый внешний CMakeLists.txt:
install (SCRIPT "${CMAKE_SOURCE_DIR}/PostInstall.cmake")
Команды install добавляются в сценарий cmake_install.cmake по порядку, поэтому вызов следует добавить в конец CMakeLists.txt, чтобы он запускался после завершения всех других установок.
Ответ 2 · рейтинг 6 · rickfoosusa
Чтобы добавить шаг после установки, вам нужно добавить каталог на верхнем уровне CMakeLists.txt. У вас должен быть каталог с файлом CMakeLists.txt, чтобы настроить выполнение шагов после установки последними при установке.
Первый шаг - добавить переменные и значения, которые будут использоваться сценарием после установки. Ни одна из переменных, доступных во время сборки, не будет доступна после установки, поэтому все, что вам нужно, должно быть настроено здесь.
В CMakeLists.txt верхнего уровня после выполнения всех предыдущих команд add_subdirectory добавьте что-то вроде этого.
# Workaround for the lack of post_install steps.
# add_subdirectory is executed in order, this one must be last.
if(CMAKE_PROGRAM_PREFIX)
# Make sure this is the LAST directory added.
add_subdirectory(${CMAKE_SOURCE_DIR}/cmake/postinstall)
# Add any variables you need during post install.
install(CODE "set(CMAKE_PROGRAM_PREFIX \"${CMAKE_PROGRAM_PREFIX}\")")
# Add any properties to your post install.
get_property(PROGRAM_PREFIX_FILES GLOBAL PROPERTY PROGRAM_PREFIX_FILES)
install(CODE "set(PROGRAM_PREFIX_FILES \"${PROGRAM_PREFIX_FILES}\")")
endif()
Теперь у нас есть переменные и свойства, преобразованные в переменные, доступные для использования после установки.
Далее нам нужен файл CMakeLists.txt в каталоге после установки. Cmake выполнит этот файл в конце сборки. В это время мы устанавливаем СЦЕНАРИЙ, который выполняет работу во время пост-установки.
# CMake will execute this last in the build.
# Install the script that does the post install work.
install(SCRIPT "${CMAKE_SOURCE_DIR}/cmake/postinstall/ProgramPrefix.cmake")
Теперь мы получим управление во время постустановки в ProgramPrefix.cmake. CMake добавит переменные, которые мы установили ранее.
# Make sure this was requested.
if(CMAKE_PROGRAM_PREFIX)
# CMake builds a manifest of all files it has installed.
foreach(file ${CMAKE_INSTALL_MANIFEST_FILES})
# Make a list of installed files to compare.
get_filename_component(nm ${file} NAME)
list(APPEND fileindex ${nm})
endforeach()
# Process program prefix files.
foreach(nm ${PROGRAM_PREFIX_FILES})
list(FIND fileindex ${nm} efound)
# Did we match a manifest file with our list of files?
if(NOT efound LESS 0)
# Process the file.
program_prefix_file(${efound})
endif()
endforeach()
endif()
Есть немного больше работы, чтобы на самом деле сделать префикс программы, но этот фреймворк позволит вам выполнять команды cmake после того, как все будет установлено.