【问题标题】:CMake cannot resolve runtime directory pathCMake 无法解析运行时目录路径
【发布时间】:2014-03-20 14:47:49
【问题描述】:

运行cmake后的CMakeLists.txt

我收到以下警告

CMake Warning at src/CMakeLists.txt:32 (add_executable):
  Cannot generate a safe runtime search path for target MMPEditor because
  files in some directories may conflict with libraries in implicit
  directories:

runtime library [libQt5Widgets.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
  /home/ch/Qt/5.2.1/gcc_64/lib
runtime library [libQt5Core.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
  /home/ch/Qt/5.2.1/gcc_64/lib
runtime library [libQt5Gui.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
  /home/ch/Qt/5.2.1/gcc_64/lib
runtime library [libQt5OpenGL.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
  /home/ch/Qt/5.2.1/gcc_64/lib

其中一些库可能无法正确找到。

一个文件被另一个文件隐藏是什么意思?如何让 CMake 确定要链接到哪个文件夹?

【问题讨论】:

  • 这是一个警告,而不是错误。

标签: cmake


【解决方案1】:

如果您正在处理 find_library

find_library(LIBRARY_NAME PATHS "/usr/lib/x86_64-linux-gnu" NO_DEFAULT_PATH) 在哪里

  • PATHS 代表库的确切路径
  • NO_DEFAULT_PATH 表示,cmake 不会搜索其他任何地方

检查 lib 的值并包含 message(status, ${LIBRARY_NAME}) 的路径


如果你正在与find_package打交道:

比前面的例子稍微复杂一点,但本质上是一样的。

对于每个包,您必须运行find_package

  1. 创建名称为Find<Packagename>.cmake 的文件,例如。 G。如果您正在寻找 cppunit,则必须创建 FindCPPUNIT.cmake

  2. 在该文件中,您必须在包含文件上运行 find_path,在 lib 文件上运行 find_library,例如“如果您正在处理 find_library”。

    find_path(CPPUNIT_INCLUDE_DIR PATHS "/usr/include/x86_64-linux-gnu" NO_DEFAULT_PATH)       
    find_library(CPPUNIT_LIBRARY PATHS "/usr/lib/x86_64-linux-gnu" NO_DEFAULT_PATH)
    

    然后你必须将文件的路径添加到CMAKE_MODULE_PATH

【讨论】:

  • 该错误与查找错误库无关,因此为find_libraryfind_package 添加参数不会改变任何内容。您甚至可以硬编码库路径,但警告仍然存在。
【解决方案2】:

您的系统库与本地自定义构建 Qt 库发生冲突。这是一个警告,但您可能因此无法在您的应用程序中获得预期的结果。您需要告诉 CMake 在 CMakeModule 中搜索库时它应该排除系统路径。来自this documentation

如果指定了 NO_DEFAULT_PATH,则不会将其他路径添加到 搜索。

在同一文档中还提到了另一个标志NO_CMAKE_SYSTEM_PATH,它只包括特定于平台的默认路径。

【讨论】:

  • 那些是 find_library 的标志,对吧?如果您只是使用 find_package 怎么办 - 如何为特定目标设置搜索路径?
【解决方案3】:

警告的实际含义:

  1. 项目请求与共享库链接,该库包含在两个目录中。也就是说,这两个目录都有名为 foo.so.x.y 的文件。
  2. CMake 完全理解选择哪个库文件进行链接。也就是说,它可能会将“正确”目录传递给运行时加载器,因此加载器将在那里搜索库。
  3. 由于某种原因,CMake 无法阻止加载程序在“错误”目录下进行搜索。例如。默认情况下会搜索该目录,或者它包含同一可执行文件所需的其他库。
  4. 因此,CMake 不能保证当您运行可执行文件时,加载程序会找到正确的库。

例如,消息

runtime library [libQt5Widgets.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
  /home/ch/Qt/5.2.1/gcc_64/lib

表示项目请求链接到位于目录/usr/lib/x86_64-linux-gnu中的库libQt5Widgets.so.5

但是同名的库也存在于目录/home/ch/Qt/5.2.1/gcc_64/lib 中,CMake 将其视为“隐式目录”,加载程序无论如何都会在其中搜索。 (可能是因为这个目录列在变量LD_LIBRARY_PATH中)。

警告的后果:

  1. 项目可以配置而不会出现错误。
  2. 项目可以构建而不会出错。
  3. 但是在运行可执行文件时,加载的可能加载了错误的库。这可能会导致不可预测的结果

由于在运行时出现不可预测的结果很少被接受,因此最好修复警告。可能的方法包括:

  1. 确保 CMake 选择了您实际打算使用的库。

    例如您实际上可能打算在/home/ch/Qt/5.2.1/gcc_64 下使用QT 的自定义安装。在这种情况下,您需要向 CMake 暗示您的意图。例如。通过设置CMAKE_PREFIX_PATH 变量。

  2. 卸载位于“错误”目录中的库。

    例如如果您有较新版本的库并且从不打算使用旧版本,那么为避免混淆,最好卸载后者。

  3. 如果加载器搜索“错误”目录是因为它包含在变量LD_LIBRARY_PATH 中,则将此变量设置为不包含该目录。

    CMake 能够正确构建项目以在没有 LD_LIBRARY_PATH 设置的情况下运行。

  4. 如果加载器搜索“错误”目录是因为它包含一些其他库,则消除使用可执行文件中的这些库。

    如果您的 PC 上有两个库“存储库”,则库之间的兼容性只能在一个存储库中得到保证。混合使用库可能会导致运行时出现不兼容问题。

【讨论】:

    猜你喜欢
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 2019-01-28
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多