如何在安装语句中使用cmake文件(获取运行时依赖项)?
如何在cmake install脚本语句中使用?我在网上找不到这种用法的示例,并且我不清楚使用[[]]嵌入式自定义脚本的文档和错误消息中的语句 我得到的印象是,在安装时,这可以用来定位cmake目标的文件依赖项,并可能通过安装操作将它们带过来,使其以独立形式可用 例如,我的应用程序依赖于QT,如果配置正确,则该应用程序所需的QT DLL将被复制到bin中。(我只想确保我不会误解它在该上下文中的功能)。它可能不会直接复制文件,但我假设提供了要复制的文件列表,安装将随后处理这些文件(所有操作都在安装时完成) 我天真地试图从一开始就朝它扔东西:如何在安装语句中使用cmake文件(获取运行时依赖项)?,cmake,Cmake,如何在cmake install脚本语句中使用?我在网上找不到这种用法的示例,并且我不清楚使用[[]]嵌入式自定义脚本的文档和错误消息中的语句 我得到的印象是,在安装时,这可以用来定位cmake目标的文件依赖项,并可能通过安装操作将它们带过来,使其以独立形式可用 例如,我的应用程序依赖于QT,如果配置正确,则该应用程序所需的QT DLL将被复制到bin中。(我只想确保我不会误解它在该上下文中的功能)。它可能不会直接复制文件,但我假设提供了要复制的文件列表,安装将随后处理这些文件(所有操作都在安装
set(TARGET_NAME "myapp")
# installation settings
install(TARGETS ${TARGET_NAME}
[[
file(GET_RUNTIME_DEPENDENCIES
RESOLVED_DEPENDENCIES_VAR RES
UNRESOLVED_DEPENDENCIES_VAR UNRES
CONFLICTING_DEPENDENCIES_PREFIX CONFLICTING_DEPENDENCIES
EXECUTABLES ${TARGET_NAME}
)]]
RUNTIME DESTINATION "${INSTALL_X_BIN}" COMPONENT libraries
LIBRARY DESTINATION "${INSTALL_X_LIB}" COMPONENT libraries
)
然而,这当然给了我:
CMake Error at applications/CMakeLists.txt:117 (install):
install TARGETS given target " file(GET_RUNTIME_DEPENDENCIES
RESOLVED_DEPENDENCIES_VAR RES
UNRESOLVED_DEPENDENCIES_VAR UNRES
CONFLICTING_DEPENDENCIES_PREFIX CONFLICTING_DEPENDENCIES
EXECUTABLES ${TARGET_NAME}
)" which does not exist.
-- Configuring incomplete, errors occurred!
我觉得这很傻,好像我错过了一些非常基本的东西。首先,要注意一点
您提到了Qt。无论您在这里做什么,此方法都不可能单独适用于Qt,因为您无法仅使用程序/库的运行时依赖项来发现安装所需的任何Qt插件或其他组件。Qt的依赖项比库更复杂
(My以macOS上的QCocoaIntegrationPlugin
QPA为例,演示了如何获取用于捆绑目的的Qt插件信息。在最新版本中,所有Qt插件都由自己的IMPORTED
CMake目标表示,因此通常可以编写install(code…)
脚本,它使用生成器表达式以与以下代码类似的方式拾取这些目标。)
文件(获取运行时依赖项)
正如Tsyvarev在评论中指出的那样,GET_RUNTIME_DEPENDENCIES
用于安装阶段,而不是配置阶段。因此,它需要放在install(code…
或install(SCRIPT…
语句中,这将导致代码评估延迟到构建完成之后。(事实上,install(code…
将给定代码直接插入当前目录的cmake_install.cmake
脚本中。您只需查看该文件即可检查结果,甚至无需运行安装。)
延迟的评估也带来了一些问题。主要是:代码不理解目标。目标在安装阶段不再存在。因此,要包含任何目标信息,必须使用生成器表达式插入正确的值
虽然CMake文档表明变量引用和转义不会在括号参数内进行计算,但生成器表达式是。因此,您可以将代码
包装在[[[
]]
中,以避免转义所有内容
您仍然必须小心变量扩展/转义。大多数变量(包括您创建的任何变量)在安装上下文中都不可用-只有少数变量可用,如CMAKE\u install\u PREFIX
。您必须扩展或设置任何其他变量
在AFAICT中,没有用于访问任意变量的生成器表达式。有一些用于特定变量/值,但不能使用类似于$
或$
的语句来组合变量和括号参数
因此,如果您想在code
中使用configure上下文中的变量,在安装时将对这些变量进行评估,最简单的方法是通过set()
-在code
中调用一个变量,将它们“转移”到安装脚本中
文件(安装类型共享\u库)
要安装共享库依赖项,可以使用相同的文件(安装)
CMake本身在CMake\u安装中使用的命令。如果您构建共享库目标,CMake
。它使用键入共享库
选项添加一些额外的处理。FOLLOW\u SYMLINK\u CHAIN
选项也特别方便。它们一起将生成文件(安装)
都解析源文件中的符号链接,并在目标路径中自动重新创建它们
示例代码
总之,你会想做这样的事情:
set(MY_DEPENDENCY_PATHS /path/one /path/two)
# Transfer the value of ${MY_DEPENDENCY_PATHS} into the install script
install(CODE "set(MY_DEPENDENCY_PATHS \"${MY_DEPENDENCY_PATHS}\")")
install(CODE [[
file(GET_RUNTIME_DEPENDENCIES
LIBRARIES $<TARGET_FILE:mylibtarget>
EXECUTABLES $<TARGET_FILE:myprogtarget>
RESOLVED_DEPENDENCIES_VAR _r_deps
UNRESOLVED_DEPENDENCIES_VAR _u_deps
DIRECTORIES ${MY_DEPENDENCY_PATHS}
)
foreach(_file ${_r_deps})
file(INSTALL
DESTINATION "${CMAKE_INSTALL_PREFIX}/lib"
TYPE SHARED_LIBRARY
FOLLLOW_SYMLINK_CHAIN
FILES "${_file}"
)
endforeach()
list(LENGTH _u_deps _u_length)
if("${_u_length}" GREATER 0)
message(WARNING "Unresolved dependencies detected!")
endif()
]])
set(我的依赖关系路径/path/one/path/two)
#将${MY_DEPENDENCY_PATHS}的值传输到安装脚本中
安装(代码“设置(我的依赖关系路径\“${我的依赖关系路径}\”)
安装(代码[[
文件(获取运行时依赖项)
图书馆$
可执行文件$
已解决的\u依赖项\u变量\u r\u deps
未解决的\u依赖项\u变量\u deps
目录${MY\u DEPENDENCY\u path}
)
foreach(_文件${u r_deps})
文件(安装)
目标“${CMAKE\u INSTALL\u PREFIX}/lib”
类型共享库
follow\u符号链接\u链
文件“${u file}”
)
endforeach()
列表(长度、深度、长度)
如果(“${u\u length}”大于0)
消息(警告“检测到未解析的依赖项!”)
endif()
]])
*–(请注意,在非Windows系统上使用DIRECTORIES
参数将导致CMake发出警告,因为文件的依赖关系应该只能使用当前环境解决。)
如果代码太复杂,总是可以选择在
${cmake\u CURRENT\u SOURCE\u DIR}
中创建一个单独的脚本文件copy\u deps.cmake
,并使用install(script copy\u deps.cmake)
(此答案的早期版本建议使用文件(GENERATE…)
生成脚本-这不会起作用,因为文件在处理CMakeLists.txt
后才会写入。如果您在中找到了该命令,则在安装(code)
或中会清楚说明此命令的用法