如何获取安装CMake组件时将安装的文件列表

时间:2014-09-18 04:14:05

标签: cmake cpack

有没有办法以编程方式(在cmake中)知道如果安装了COMPONENT将会安装哪些文件(类似于组件的get_property)?

目前我正在将COMPONENT安装到临时位置进行打包(不使用CPack进行打包),然后使用自定义命令打包。在Cmake打包期间调用以下命令。

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

我想知道是否有可能获取文件列表,以便我只能在包中明确地包含这些文件?或者可能将它们作为输出添加到自定义命令?

2 个答案:

答案 0 :(得分:2)

了解它的唯一方法似乎是通过阅读install_manifest _ $ {component} .txt,它将包含我们安装cmake组件时将安装的所有文件列表。

答案 1 :(得分:2)

对于get_property()描述符,CMake没有COMPONENT函数(或类似的等效函数); CMake属性保留给目标,目录,源文件等(完整列表here)。但是,有一些方法可以以编程方式列出与COMPONENT关联的文件。

通常,COMPONENT选项通常与install()一起指定,以便从本质上将目标分类为特定的安装组。这些“组件”分组通常与CPack一起使用:

  

对于某些类型的二进制安装程序(包括macOS和Windows上的图形安装程序),CPack会生成安装程序,允许用户选择要安装的单个应用程序组件。每个组件的内容均由CMake的COMPONENT命令的INSTALL参数标识。

但是,如果您不使用CPack,则CMake仍然会尊重COMPONENT分组;他们很难管理。您可以遍历cmake_install.cmake文件中的每个安装规则,并过滤掉与特定COMPONENT相关的安装规则。此操作必须在CMake生成阶段之后(在生成cmake_install.cmake文件之后)进行,因为在配置时尚无法知道每个目标的完整路径。正如上面的问题所建议的那样,您可以创建一个自定义目标来自己调用generated CMake install script,并根据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}
)

建立此自定义目标(例如make MyInstallTarget)后,将创建清单文件install_manifest_MyComponent.txt,其中包含与该COMPONENT相关的所有文件的列表。 (不一定是通过构建CMake预定义的INSTALL目标来创建的。)

但是,此清单文件本身并不是很有用。要以编程方式使用它,我们可以扩展自定义目标,以将这些特定于组件的文件读取到CMake变量中。

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}
)

my_install_script.cmake内部,逻辑很大程度上取决于您要对文件列表执行的操作。下面的脚本会将文件读入CMake列表变量,然后使用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)