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

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.


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)