安装 CMake 组件时如何获取将要安装的文件列表
Posted
技术标签:
【中文标题】安装 CMake 组件时如何获取将要安装的文件列表【英文标题】:How to get the list of files that will be installed when installing a CMake component 【发布时间】: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
我想知道是否可以获取文件列表,以便我只能将这些文件明确包含在包中?或者可能将它们作为输出添加到自定义命令?
【问题讨论】:
【参考方案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)
【讨论】:
我能否以某种方式安装一个组件组,以便该组内的所有组件都编写其安装清单? 如果你想安装多个COMPONENT
s,你可以将COMMAND "$CMAKE_COMMAND" -DCOMPONENT=MyComponent2 -P cmake_install.cmake
添加到自定义目标调用中,为你想要的每个不同的组件组。您还可以扩展它以为COMPONENT
s 的不同分组创建多个自定义目标。希望这是有道理的。如果没有,我可以扩展我的答案。
@ziggystar 根据您尝试完成的自定义安装步骤,我还可以看到使用 bash 脚本(或者说,Python)来读取清单并进行进一步处理。您可以将其耦合到同一个自定义目标中这一事实是解决方案的关键;我只是提供了一个 CMake 脚本示例以保持一致。以上是关于安装 CMake 组件时如何获取将要安装的文件列表的主要内容,如果未能解决你的问题,请参考以下文章