Можно ли добавить команды после установки в 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 верхнего уровня?


person joast    schedule 03.04.2012    source источник


Ответы (2)


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

install (SCRIPT "${CMAKE_SOURCE_DIR}/PostInstall.cmake")

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

person sakra    schedule 03.04.2012
comment
Благодарю вас! Клянусь, я пробовал что-то подобное, и это не сработало. Попробовал еще раз, вроде работает. Думаю, у меня, должно быть, была опечатка (или что-то в этом роде), из-за которой он не работал. - person joast; 04.04.2012
comment
Это не работает для моей сборки с подкаталогами. Конец самого внешнего файла CMakeLists.txt выполняется до того, как все файлы cmake_install.cmake будут включены из подкаталогов. - person rickfoosusa; 25.02.2015
comment
Немного сложно, особенно в отношении указания путей установки подкаталогов и целей из корня, но в конечном итоге это заработало. - person taranaki; 13.06.2017

Чтобы добавить шаг после установки, вам нужно добавить каталог на верхнем уровне 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 после того, как все будет установлено.

person rickfoosusa    schedule 30.04.2015
comment
Я ничего не понимаю в программном префиксе. Это актуально? Или просто случайный пример кода того, как вы можете запустить скрипт после установки? - person Joakim; 02.04.2016
comment
Я хотел добавить функцию префикса программы, такую ​​​​как autoconf, в дереве, которое поддерживает сборки как autoconf, так и cmake. Префикс программы является лишь примером. Шаг после установки cmake можно использовать для чего угодно. - person rickfoosusa; 02.04.2016