【问题标题】:Cmake: find_library doesn't work but find_path does (same path)Cmake:find_library 不起作用,但 find_path 起作用(相同的路径)
【发布时间】:2020-06-03 21:22:38
【问题描述】:

我正在尝试使用 CMake 用 C++ 构建一个跨平台的学校项目。我的项目需要使用 Irrlicht 库,并且必须在 Linux 和 Windows 10 下编译。

项目源路径包含一个lib 文件夹,其中包含Irrlicht 标头(在include 子文件夹中)、一个Irrlicht.dll、一个Irrlicht.lib 和一个FindIrrlicht.cmake 模块。

我设置CMAKE_MODULE_PATH指向这个目录,然后在我的CMakeLists.txt中调用find_package(Irrlicht REQUIRED)

当我尝试在 Linux 下编译时,一切正常。但是,当我尝试在 Windows 下使用 CMake(使用 CMake GUI)运行配置时,我拥有的 FindIrrlicht.cmake 模块不起作用(它应该,因为它是由学校提供的并且他们说它应该,我也知道其他人无需修改即可工作)。我相信我已经确定了问题的原因,但我不明白它发生的原因以及如何解决它。

FindIrrlicht.cmake 在某些标准 Linux 包含/库路径和CMAKE_MODULE_PATH 下查找include 目录和Irrlicht.lib(或Linux 下的libIrrlicht.so,使用前缀/后缀选项)。在 Windows 上编译时,它应该在 CMAKE_MODULE_PATH 中找到所有内容。 它像这样调用find_library

FIND_LIBRARY(Irrlicht_LIBRARIES
    NAMES
      Irrlicht
    PATHS
      "/usr/lib64/"
      "/usr/lib/"
      "/usr/lib/x86_64-linux-gnu/"
      "/usr/local/lib/"
      "/usr/local/lib64/"
      "${CMAKE_MODULE_PATH}/" #Should find in this path for Windows configuration
      "${Irrlicht_DIR}/"
)

问题是,CMAKE_MODULE_PATH 中的路径是正确的,因为find_path()(见下文)能够找到 Irrlicht 的包含目录。但它将Irrlicht_LIBRARIES 设置为NOTFOUND。我一次又一次地验证文件在那里并且文件在正确的位置。我还检查了文件的权限。

IF (NOT Irrlicht_INCLUDE_DIRS OR NOT Irrlicht_LIBRARIES)
  FIND_PATH(Irrlicht_INCLUDE_DIRS
    NAMES
      irrlicht.h
    PATHS
      "/usr/include/irrlicht/"
      "/usr/local/include/irrlicht/"
      "${CMAKE_MODULE_PATH}/include/" #Does find in Windows
      "${Irrlicht_DIR}/include/"
  )

另外,后来在CMakeLists.txt 中,我成功调用了file(COPY "${CMAKE_MODULE_PATH}/Irrlicht.dll" DESTINATION ${EXECUTABLE_OUTPUT_PATH}),并尝试使用Irrlicht.lib 也成功了。所以路径绝对不是这里的问题。

提前感谢您的帮助!

P.S.:这是我第一次在 StackOverflow 上提问,如果我做/写了不对的地方,请告诉我,我将不胜感激。

【问题讨论】:

  • 另外,我忘了提,但我查看了CMAKE_FIND_ROOT_PATH 并尝试了不同的组合,但也没有任何效果,所以我相信它不会有帮助。另外,就像我提到的,FindIrrlicht.cmake 模块是学校提供的,我不应该更改它。
  • 原始FindIrrlicht.cmake 实际上是否以您展示的方式使用CMAKE_MODULE_PATH 变量?这真的是奇怪的用法:这个变量被 CMake 自动用于定位 FindXXX.cmake 脚本和 include() 的脚本。但它不打算用作PATHS/HINTS 用于find_libraryfind_path。此外,general 变量可能包含路径列表,因此将其用作"${CMAKE_MODULE_PATH}/include/" 没有任何意义。
  • 如果FindXXX.cmake脚本要引用目录,无论脚本是否位于,那么CMAKE_CURRENT_LIST_DIR变量就可以很好地满足这个目的。
  • 我同意使用非常规,但正如我前面提到的,这是一个学校项目,学校提供了一个不应修改的“包”,其中包含 irrlicht 库(.dll & .lib) 用于 Windows,FindIrrlicht.cmake 也在其中。我猜他们这样做是为了使自动化测试更容易(他们使用脚本来测试每个学生项目的有效性)。
  • 是的,我知道FindIrrlicht.cmake 不是你写的,你也不想编辑它。这实际上是一个注释(给您和其他读者),最好不要使用FindIrrlicht.cmake 脚本作为您自己的此类脚本的示例。毕竟,Stack Overflow 是一个学习 网站,学习该做什么和该避免什么。再说一遍:我的 cmets 绝不打算告诉“你做错了”。

标签: c++ cmake irrlicht


【解决方案1】:

好吧,我发现了我的问题。不早点想到这个我觉得很愚蠢......

问题出在前/后缀中,通过一些调试输出,我意识到它们是为 Linux 而不是 Windows 设置的,因此没有找到库文件。

原因是在 CMakeLists.txt 中,对 find_package 的调用是在调用 project() 之前完成的,因此在调用 find_package 期间没有设置 MSVC 变量,这导致脚本认为它是在 Linux 下调用。

【讨论】:

    猜你喜欢
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 2015-08-30
    • 2011-03-17
    • 2014-06-25
    • 2018-09-15
    • 1970-01-01
    相关资源
    最近更新 更多