CMake无法解析运行时目录路径

A1A*_*3A4 9 cmake

运行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
Run Code Online (Sandbox Code Playgroud)

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

一个文件被另一个文件隐藏是什么意思,我怎样才能让CMake确定哪个文件要链接到哪个文件夹?

Tsy*_*rev 16

该警告实际上意味着什么:

  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
Run Code Online (Sandbox Code Playgroud)

意味着该项目请求链接libQt5Widgets.so.5位于目录中的库/usr/lib/x86_64-linux-gnu

但是同名的库也存在于目录中/home/ch/Qt/5.2.1/gcc_64/lib,CMake将其视为“隐式目录”,加载器在任何情况下都会在其中搜索。(可能是因为该目录已在变量中列出LD_LIBRARY_PATH)。

警告的后果:

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

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

  1. 确保 CMake 选择您实际想要使用的库。

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

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

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

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

    CMake 能够正确构建无需LD_LIBRARY_PATH设置即可运行的项目。

  4. 如果加载程序搜索到“错误”目录,因为它包含一些其他库,请消除在可执行文件中使用该库。

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


Asa*_*lle 8

如果你正在处理 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. 创建具有 name 的文件Find<Packagename>.cmake,例如,如果您正在寻找 cppunit,则必须创建FindCPPUNIT.cmake.

  2. 在该文件中,您必须find_path在包含文件和find_librarylib 文件上运行,例如“如果您正在处理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)
    
    Run Code Online (Sandbox Code Playgroud)

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

  • 该错误与查找错误的库无关,因此为“find_library”或“find_package”添加参数不会改变任何内容。您甚至可以**硬编码**库的路径,但警告仍然存在。 (3认同)

Abh*_*sal 5

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

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

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

  • 这些是 find_library 的标志,对吗?如果您只是使用 find_package 该怎么办 - 如何设置特定目标的搜索路径? (5认同)