Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在安装语句中使用cmake文件(获取运行时依赖项)?_Cmake - Fatal编程技术网

如何在安装语句中使用cmake文件(获取运行时依赖项)?

如何在安装语句中使用cmake文件(获取运行时依赖项)?,cmake,Cmake,如何在cmake install脚本语句中使用?我在网上找不到这种用法的示例,并且我不清楚使用[[]]嵌入式自定义脚本的文档和错误消息中的语句 我得到的印象是,在安装时,这可以用来定位cmake目标的文件依赖项,并可能通过安装操作将它们带过来,使其以独立形式可用 例如,我的应用程序依赖于QT,如果配置正确,则该应用程序所需的QT DLL将被复制到bin中。(我只想确保我不会误解它在该上下文中的功能)。它可能不会直接复制文件,但我假设提供了要复制的文件列表,安装将随后处理这些文件(所有操作都在安装

如何在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)
或中会清楚说明此命令的用法