Можно ли добавить команды после установки в Makefile верхнего уровня, созданный cmake?

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

Вы можете использовать вариант SCRIPT или CODE команды install. Если вы поместите необходимые команды в script PostInstall.cmake в корневой каталог проекта, добавьте следующий вызов к вашему внешнему CMakeLists.txt:

install (SCRIPT "${CMAKE_SOURCE_DIR}/PostInstall.cmake")
Команды

install добавляются в cmake_install.cmake script в порядке, поэтому вызов должен быть добавлен в конец CMakeLists.txt, чтобы он запускался после завершения всех других установок.

Ответ 2

Чтобы добавить шаг после установки, вам нужно добавить каталог на верхнем уровне CMakeLists.txt. У вас должен быть каталог с CMakeLists.txt в нем, чтобы настроить шаги после установки, которые будут выполняться последними в процессе установки.

Первым шагом является добавление переменных и значений, которые будут использоваться post install script. Ни одна из переменных, доступных во время сборки, не будет доступна после установки, поэтому все, что вам нужно, должно быть настроено здесь.

В верхнем уровне 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 в каталоге postinstall. Cmake выполнит этот файл в конце сборки. В это время мы устанавливаем SCRIPT, который выполняет эту работу во время post-установки.

# 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")

Теперь мы получим контроль во время post install в 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 после того, как все будет установлено.