Search code examples
cmakeassimp

Linking assimp library with find_package


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


Solution

  • 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})