【问题标题】:Linking assimp library with find_package将 assimp 库与 find_package 链接
【发布时间】:2018-03-03 09:02:06
【问题描述】:

我正在努力将 Assimp 库与 CMake 的 find_package() 函数链接起来。

# ASSIMP search path
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${CMAKE_CURRENT_LIST_DIR}/assimp/)

find_package(assimp REQUIRED)
if (assimp_FOUND)
    link_directories(${ASSIMP_LIBRARY_DIRS})
    include_directories(${ASSIMP_INCLUDE_DIRS})
    target_link_libraries (NervousEngine ${ASSIMP_LIBRARIES})
endif(assimp_FOUND)

我的第一个问题是为什么 Cmake 在使用 gcc 编译项目时没有为 find_package() 抛出错误,它说找不到 -lassimp。当然,当我删除 assimp 目录的 CMAKE_PREFIX_PATH 时,我可以让它失败。不知何故,CMake 无法指示编译命令链接它???

第二个问题是为什么无法链接库。这是编译命令以及 ld 链接错误

/usr/bin/c++   -std=gnu++11 -g sourceFiles... o NervousEngine -Wl,-rpath,/home/jointts/CLionProjects/OpenGL/lib/bullet/lib ../lib/bullet/lib/libBulletDynamics.so ../lib/bullet/lib/libBulletCollision.so ../lib/bullet/lib/libLinearMath.so ../lib/bullet/lib/libBulletSoftBody.so -lassimp -lfreetype 
/usr/bin/ld: cannot find -lassimp
collect2: error: ld returned 1 exit status

我只是不明白为什么它不能正确链接我什至使用了 link_directories 指令来指导图书馆搜索。

调试库的路径我得到以下内容

message(${ASSIMP_LIBRARY_DIRS}) -> /home/jointts/CLionProjects/OpenGL/lib/assimp/lib
message(${ASSIMP_LIBRARIES}) -> assimp

所以我会假设图书馆位置本身是正确的,它会导致我在下面键入的图书馆搜索?

${ASSIMP_LIBRARY_DIRS} + ${ASSIMP_LIBRARIES}

/home/jointts/CLionProjects/OpenGL/lib/assimp/lib/libassimp.so

gcc --version 产生以下结果

gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

CMake 版本为 3.9.6

【问题讨论】:

  • link_directories() 只会应用于调用之后创建的目标。所以在你的情况下它没有效果,因为你首先创建你的可执行文件,然后包含lib/CMakeLists.txt
  • 所以顺序应该是link_directories -> add_executable -> target_link_libraries?
  • 我想我会制作另一个 FindAssimp.cmake 文件... Bullet 似乎可以很好地链接到与 find_package 链接的相同样式我猜 assimp-config.cmake 文件刚刚损坏
  • 这是一个 FindASSIMP.cmake,适用于任何想要将库与相对路径链接而不使用全局 /usr/include /usr/lib 文件夹gist.github.com/Jointts/a02c15002252fea3dd2c6855bda9090b 理论上可以扩展到任何其他库的人好吧。我想编写自己的查找脚本对于 CMake 来说是必须的;(

标签: cmake assimp


【解决方案1】:

1: CMake 没有抛出错误,因为它找到了包。您通过成功验证ASSIMP_*-变量的值确认了这一点。这些变量由assimp-config.cmake初始化。

2:链接器接收到这个标志-lassimp,它要求链接器知道去哪里寻找库。由于它没有安装在标准位置,它会失败。在我们讨论的 cmets 中,必须在创建任何依赖于库的目标之前调用 link_libraries()。如果您在创建目标之前使用link_libraries(),您应该能够简单地将assimp 传递给target_link_libraries(),它会将其作为-lassimp 转发给链接器。

更好的解决方案是为target_link_libraries() 提供到libassimp.sotarget_link_libraries(<target> ${ASSIMP_LIBRARY_DIRS}/libassimp.so) 的绝对路径(请注意,我们不会在此处为库添加-l 标志前缀)。但是,请继续阅读。

由于assimp-config.cmake 没有创建任何CMake 目标,如果CMake 能够找到包,最干净的解决方案是自己创建一个:

if (assimp_FOUND)
    set(ASSIMP_LIBRARY "assimp")
    add_library(${ASSIMP_LIBRARY} SHARED IMPORTED)
    set_target_properties(${ASSIMP_LIBRARY} PROPERTIES IMPORTED_LOCATION "${ASSIMP_LIBRARY_DIRS}/libassimp.so")
endif(assimp_FOUND)

然后像往常一样链接到它:target_link_libraries(<target> ${ASSIMP_LIBRARY})

【讨论】:

  • 谢谢 :) 顺便说一句,assimp_FOUND 的 if 主体可以在 1 个函数中调用 find_library(ASSIMP_LIBRARY NAMES ${ASSIMP_LIBRARIES} PATH ${ASSIMP_LIBRARY_DIRS}) 通过这样做,您还可以避免对库文件名进行硬编码
猜你喜欢
  • 2014-03-15
  • 1970-01-01
  • 2015-09-21
  • 1970-01-01
  • 2014-06-23
  • 2015-06-28
  • 2018-02-06
  • 1970-01-01
  • 2021-10-25
相关资源
最近更新 更多