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?
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.
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.
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.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With