Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to add post-install commands to top level Makefile generated by CMake?

Tags:

cmake

CMake generates something like the following for the install rule:

# 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

What I want to do is have some custom commands executed after cmake_install.cmake is invoked so it looks something like:

# 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

I can do what I want using add_custom_command(TARGET ... POST_BUILD ...) for things that we have written (6 - 10 macros to update). However, there are a bunch of third-party things that get installed and I really don't want to add POST_BUILD custom commands for all of them (currently 19 projects with more to come and it can be tough to identify what needs to be processed after building instead of after installing). I think it would be much easier to maintain if the custom commands are only used in one place (i.e. as last part of install handling) and where I know they will do everything that is necessary.

Is it possible to get CMake to add commands to the top-level Makefile's install rule?

like image 597
joast Avatar asked Apr 03 '12 17:04

joast


People also ask

What is install command in CMake?

CMake provides the install command to specify how a project is to be installed. This command is invoked by a project in the CMakeLists file and tells CMake how to generate installation scripts. The scripts are executed at install time to perform the actual installation of files.

What is Cmake_install CMake file?

cmake contains the commands generated by install command from your CMakeLists. txt . You can execute it by cmake -P cmake_install. cmake and it performs the installation of your project even on windows.

How do I change my path in CMake?

CMake will use whatever path the running CMake executable is in. Furthermore, it may get confused if you switch paths between runs without clearing the cache. So what you have to do is simply instead of running cmake <path_to_src> from the command line, run ~/usr/cmake-path/bin/cmake <path_to_src> .

What does CMake do in Linux?

CMake is a meta build system that uses scripts called CMakeLists to generate build files for a specific environment (for example, makefiles on Unix machines). When you create a new CMake project in CLion, a CMakeLists. txt file is automatically generated under the project root.


2 Answers

You can use the SCRIPT or CODE variant of the install command. If you put the required commands in a script PostInstall.cmake in the project root directory, add the following call to your outermost CMakeLists.txt:

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

install commands are added to the cmake_install.cmake script in order, thus the call should be added to the end of the CMakeLists.txt to have it run after all other installations have completed.

like image 173
sakra Avatar answered Oct 21 '22 08:10

sakra


To add a post install step, you need to add a directory at the top level CMakeLists.txt. You must have a directory with a CMakeLists.txt in it in order to set up the post install steps to be executed last in the install.

The first step is to add variables and values to be used by the post install script. None of the variables available during the build will be available post install, so everything you need must be set up here.

In the top level CMakeLists.txt, after all previous add_subdirectory commands have been executed, add something like this.

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

Now we have variables, and properties converted to variables available to use at post install.

Next we need a CMakeLists.txt file in the postinstall directory. Cmake will execute this file at the end of the build. At that time we install a SCRIPT that does the work during post install.

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

Now we will get control during post install in ProgramPrefix.cmake. CMake will add the variables we have set earlier.

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

There is a little more work to actually do the program prefix, but this framework will let you execute cmake commands after everything has been installed.

like image 36
rickfoosusa Avatar answered Oct 21 '22 06:10

rickfoosusa