有没有办法以编程方式(在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
我想知道是否有可能获取文件列表,以便我只能在包中明确地包含这些文件?或者可能将它们作为输出添加到自定义命令?
答案 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)