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)