Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the list of files that will be installed when installing a CMake component

Is there any way to know programmatically (in CMake) what files will be installed if a COMPONENT is installed (something like a get_property of component)?

Currently, I am installing a COMPONENT to a temporary location for packaging (not using CPack for packaging) and then packaging using custom commands. I'm invoking the following command during packaging in CMake.

cmake -DCOMPONENT=my_test_component 
-DCMAKE_INSTALL_PREFIX=${TMP_PACKAGING_ROOT}
-P ${CMAKE_BINARY_DIR}/cmake_install.cmake

I wanted to know if it is possible to get the list of files so that I can only include those files explicitly in the package? Or possibly add them as outputs to the custom command?

like image 980
k0n3ru Avatar asked Sep 18 '14 04:09

k0n3ru


People also ask

Where does CMake install files?

Install directory used by install. If “make install” is invoked or INSTALL is built, this directory is prepended onto all install directories. This variable defaults to /usr/local on UNIX and c:/Program Files on Windows.

What is CMake install command?

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.

Can CMake install dependencies?

Any complex software will have its dependencies – be it system API calls or other libraries calls either statically or dynamically linked to it. As a build system generator CMake will help you manage these dependencies in the most natural way possible.

What is Cmake_install CMake file?

As previous answer tells, the cmake_install. 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.


2 Answers

The only way to know it seems to be by reading the install_manifest_${component}.txt which will have all the list of files that will be installed when we install a CMake component.

like image 187
k0n3ru Avatar answered Oct 07 '22 12:10

k0n3ru


CMake does not have a get_property() function (or similar equivalent) for the COMPONENT descriptor; CMake properties are reserved for targets, directories, source files, etc. (full list here). However, there are ways to programmatically list the files associated with a COMPONENT.

In general, the COMPONENT option is often specified with install() to essentially categorize targets into specific install groups. These "component" groupings are typically used with CPack:

For certain kinds of binary installers (including the graphical installers on macOS and Windows), CPack generates installers that allow users to select individual application components to install. The contents of each of the components are identified by the COMPONENT argument of CMake’s INSTALL command.

However, if you're not using CPack, CMake still honors the COMPONENT groupings; they are just harder to manage. You can iterate through each install rule in the cmake_install.cmake file, and filter out those that pertain a specific COMPONENT. This must be done after the CMake generate stage (after the cmake_install.cmake file is generated), as the full path to each target is not known at configure time. As the question above suggests, you can create a custom target to call the generated CMake install script yourself, filtering based on COMPONENT:

# Define install rule for MyExecutable target (grouping it in MyComponent).
install(TARGETS MyExecutable
    DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/installation
    CONFIGURATIONS Release
    COMPONENT MyComponent
)

# Add custom target to filter and install MyComponent files.
add_custom_target(MyInstallTarget
    COMMAND "${CMAKE_COMMAND}" -DCOMPONENT=MyComponent -P cmake_install.cmake
    DEPENDS MyExecutable
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)

After building this custom target (e.g. make MyInstallTarget), the manifest file install_manifest_MyComponent.txt will be created, containing a list of all the files associated with that COMPONENT. (It is not necessarily created by building the CMake-predefined INSTALL target.)

However, this manifest file is not very useful by itself. To use it programmatically, we can expand our custom target to read these component-specific files into a CMake variable.

add_custom_target(MyInstallTarget
    COMMAND "${CMAKE_COMMAND}" -DCOMPONENT=MyComponent -P cmake_install.cmake
    COMMAND "${CMAKE_COMMAND}" -DCOMPONENT=MyComponent -P ../my_install_script.cmake
    DEPENDS MyExecutable
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)

Inside my_install_script.cmake, the logic is largely dependent on what you want to do with the list of files. The script below will read the files into a CMake list variable, then copies them to an install destination using configure_file():

# Check if an install COMPONENT was provided.
if(COMPONENT)
    # Read the manifest file.
    file(READ "install_manifest_${COMPONENT}.txt" MY_INSTALL_FILES)
    # Create a list from the component files.
    string(REPLACE "\n" ";" MY_INSTALL_FILES ${MY_INSTALL_FILES})
    # Loop through each file, placing it in the installation directory.
    foreach(curFile ${MY_INSTALL_FILES})
        message("Installing file: " ${curFile})
        configure_file(${curFile} /your/final/install/folder COPYONLY)
    endforeach()
endif(COMPONENT)
like image 34
Kevin Avatar answered Oct 07 '22 12:10

Kevin