【问题标题】:How to get the list of files that will be installed when installing a CMake component安装 CMake 组件时如何获取将要安装的文件列表
【发布时间】:2014-09-18 04:14:05
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: cmake installation cpack


    【解决方案1】:

    知道它的唯一方法似乎是阅读install_manifest_${component}.txt,其中将包含我们安装 CMake 组件时将安装的所有文件列表。

    【讨论】:

    • 我找不到这个文件。这个答案适用于哪个 cmake 版本?
    • ‘cmake -P cmake_install.cmake’或‘make install’将创建该文件。 @ziggystar
    • 我认为它只是为一个组件X创建的,如果你安装了这个组件。这意味着它不会被创建,如果您通过例如安装所有组件。 make install。你能确认一下吗?
    • 使用make install会生成一个名为install_manifest.txt的文件。
    【解决方案2】:

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

    一般来说,COMPONENT 选项通常与install() 一起指定,以将目标分类到特定的安装组中。这些“组件”分组通常与CPack 一起使用:

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

    但是,如果您不使用 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)
    

    【讨论】:

    • 我能否以某种方式安装一个组件组,以便该组内的所有组件都编写其安装清单?
    • 如果你想安装多个COMPONENTs,你可以将COMMAND "${CMAKE_COMMAND}" -DCOMPONENT=MyComponent2 -P cmake_install.cmake添加到自定义目标调用中,为你想要的每个不同的组件组。您还可以扩展它以为COMPONENTs 的不同分组创建多个自定义目标。希望这是有道理的。如果没有,我可以扩展我的答案。
    • @ziggystar 根据您尝试完成的自定义安装步骤,我还可以看到使用 bash 脚本(或者说,Python)来读取清单并进行进一步处理。您可以将其耦合到同一个自定义目标中这一事实是解决方案的关键;我只是提供了一个 CMake 脚本示例以保持一致。
    猜你喜欢
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多