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’sINSTALL
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)