3

I am struggling with linking the Assimp library with the find_package() function of CMake.

# 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)

My first question is why Cmake is not throwing an error for find_package() while compiling the project with gcc it says that -lassimp is not found. Ofcourse i can get it to fail when i remove the CMAKE_PREFIX_PATH for assimp directory. Somehow CMake fails to instruct the compile command to link it???

The second question is why the library cannot be linked. This is the compile command along with the ld linking error

/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

I just don't understand why isn't it linking properly I even used the link_directories directive to guide the library search.

Debugging the paths of the library i get the following

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

So I would presume the library location itself is correct and it would result in a library search I typed below?

${ASSIMP_LIBRARY_DIRS} + ${ASSIMP_LIBRARIES}

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

gcc --version yields the following

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

CMake version is 3.9.6

Biffen
  • 6,249
  • 6
  • 28
  • 36
Jointts
  • 121
  • 3
  • 11
  • 1
    `link_directories()` will only be applied to targets created **after** the call. So in your case it has no effect, since you first create your executable, then include `lib/CMakeLists.txt`. – thomas_f Mar 03 '18 at 11:39
  • So the order should be link_directories -> add_executable -> target_link_libraries? – Jointts Mar 03 '18 at 12:20
  • I guess I will make another FindAssimp.cmake file... Bullet seems to link fine with same style linking with find_package I guess assimp-config.cmake file is just broken – Jointts Mar 03 '18 at 12:30
  • Heres a FindASSIMP.cmake for anyone wanting to link the library with relative path without using the global /usr/include /usr/lib folders https://gist.github.com/Jointts/a02c15002252fea3dd2c6855bda9090b This can be in theory extended to any other library as well. I guess writing your own find scripts are a must for CMake ;( – Jointts Mar 03 '18 at 12:50
  • Possible duplicate of [Cmake cannot find library using "link\_directories"](https://stackoverflow.com/questions/31438916/cmake-cannot-find-library-using-link-directories) – Tsyvarev Mar 03 '18 at 14:33
  • Is not a duplicate, its just one of the solutions I tried... The question was not specifically for link_directories since I also used include_directories(${ASSIMP_INCLUDE_DIRS}) and target_link_libraries (NervousEngine ${ASSIMP_LIBRARIES}) – Jointts Mar 03 '18 at 20:03

1 Answers1

0

1: CMake is not throwing an error because it finds the package. You confirmed this by successfully verifying the values of the ASSIMP_*-variables. Those variables are initialized by assimp-config.cmake.

2: The linker receives this flag -lassimp, which requires that the linker knows where to look for the library. Since it's not installed in a standard location, it will fail. In the comments we discussed that link_libraries() must be called before any targets that depend on the library is created. If you use link_libraries() before the target is created, you should be able to simply pass assimp to target_link_libraries(), and it will forward it to the linker as -lassimp.

A better solution would be to provide target_link_libraries() with an absolute path to libassimp.so, target_link_libraries(<target> ${ASSIMP_LIBRARY_DIRS}/libassimp.so) (Note that we don't prefix the library with the -l flag here). However, keep reading.

Since assimp-config.cmake does not create any CMake targets, the cleanest solution would be to create one yourself if CMake is able to locate the package:

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)

Then link to it as usual: target_link_libraries(<target> ${ASSIMP_LIBRARY})

thomas_f
  • 1,854
  • 19
  • 27
  • 1
    Thanks :) Btw the if body of assimp_FOUND can be called in 1 function with find_library(ASSIMP_LIBRARY NAMES ${ASSIMP_LIBRARIES} PATH ${ASSIMP_LIBRARY_DIRS}) By doing this you can also avoid hardcoding the library file name – Jointts Mar 03 '18 at 19:57