C++ CMake compilation error (/usr/bin/ld: cannot find <LIBRARY_NAME>)

19,340

Solution 1

You should use

link_directories(directory1 directory2 ...)

directive to specify library directories.

https://cmake.org/cmake/help/v3.0/command/link_directories.html

Solution 2

I'm a bit late to the party, but maybe this will help someone. I had a very similar issue with googletest:

dpoliaru@host:~/Documents/test/gtest/build$ make
Scanning dependencies of target s1
[ 50%] Building CXX object CMakeFiles/s1.dir/s1.cpp.o
[100%] Linking CXX executable s1
/usr/bin/ld: cannot find -lgtest
/usr/bin/ld: cannot find -lgmock
/usr/bin/ld: cannot find -lgtest
/usr/bin/ld: cannot find -lgmock
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/s1.dir/build.make:84: s1] Error 1
make[1]: *** [CMakeFiles/Makefile2:73: CMakeFiles/s1.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
dpoliaru@host:~/Documents/test/gtest/build$

Here is an approach I used to debug it:

Make sure you can build manually:

compile:

g++ -c -m64 -I/home/dpoliaru/.local/lib/pkgconfig/../../include s1.cpp                                                                                 

and link:

g++ -L/home/dpoliaru/.local/lib/pkgconfig/../../lib s1.o -o s1 -lgtest -lgmock -lpthread

Make sure cmake properly locates libraries during generation stage:

dpoliaru@host:~/Documents/test/gtest/build$ cmake -L .. -D CMAKE_BUILD_TYPE=Debug
-- The C compiler identification is GNU 9.2.1
-- The CXX compiler identification is GNU 9.2.1
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1") 
-- Checking for module 'gtest'
--   Found gtest, version 1.10.0
-- Checking for module 'gmock'
--   Found gmock, version 1.10.0
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dpoliaru/Documents/test/gtest/build
-- Cache values
CMAKE_BUILD_TYPE:STRING=Debug
CMAKE_INSTALL_PREFIX:PATH=/usr/local
pkgcfg_lib_GMOCK_gmock:FILEPATH=/home/dpoliaru/.local/lib/libgmock.a
pkgcfg_lib_GMOCK_gtest:FILEPATH=/home/dpoliaru/.local/lib/libgtest.a
pkgcfg_lib_GMOCK_pthread:FILEPATH=/usr/lib/x86_64-linux-gnu/libpthread.so
pkgcfg_lib_GTEST_gtest:FILEPATH=/home/dpoliaru/.local/lib/libgtest.a
pkgcfg_lib_GTEST_pthread:FILEPATH=/usr/lib/x86_64-linux-gnu/libpthread.so
dpoliaru@host:~/Documents/test/gtest/build$ 

Finally, rin CMakeLists.txt, I updated linker directory search paths per @mustafagonlu advice using target_link_directories() cmake-commands(7).

target_link_directories(${PROJECT_NAME} PUBLIC ${GTEST_LIBRARY_DIRS} ${GMOCK_LDFLAGS})

And it worked.

Solution 3

it works if adding:

target_link_libraries (xMemory /library_build_path/libcereal.a)

details:

ld is looking for the libraries in a very short list of folders defined in

/etc/ld.so.conf

and it usually looks like following:

include /etc/ld.so.conf.d/*.conf

and actual paths list from those *.conf files usually is like:

# Legacy biarch compatibility support
/lib32
/usr/lib32
# Multiarch support
/usr/local/lib/x86_64-linux-gnu
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu

if your project linking library is not in the folder of this list, ld won't find it unless either a special linking variable set LD_LIBRARY_PATH with the path to your library or a complete path/library name provided in cmake target_link_libraries directive.

details on how to proper setup LD_LIBRARY_PATH variable discussed here

Share:
19,340
BlindHouse
Author by

BlindHouse

Updated on June 04, 2022

Comments

  • BlindHouse
    BlindHouse about 2 years

    *I know there are lots of questions about this, but they simply don't help much when talking about CMake, hence my decision of making the question *

    So I was working on CLion which uses CMake in order to import and give parameters to the compiler, and successfully included (imported) an external library (cereal: to serialize classes into json files) located on a folder called "ExternalLibraries" which is on the root of my project folder. It was working just fine, untill I restarted the IDE and tried to ran the code again... It returned a compilation error (I think).

    My CMake file looks like this:

    cmake_minimum_required(VERSION 3.3)
    project(xMemory)
    
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
    
    include_directories ("${PROJECT_SOURCE_DIR}/ExternalLibraries/cereal-1.1.2/include/")
    
    set(SOURCE_FILES main.cpp xObject.cpp xObject.h)
    add_executable(xMemory ${SOURCE_FILES})
    target_link_libraries (xMemory cereal)
    

    And when I try to run/compile the shell gives me this:

    /home/lunaticsoul/Documents/clion-1.2.4/bin/cmake/bin/cmake --build /home/lunaticsoul/.CLion12/system/cmake/generated/95701c38/95701c38/Debug0 --target xMemory -- -j 4
    Scanning dependencies of target xMemory
    [ 33%] Building CXX object CMakeFiles/xMemory.dir/xObject.cpp.o
    [ 66%] Building CXX object CMakeFiles/xMemory.dir/main.cpp.o
    [100%] Linking CXX executable xMemory
    /usr/bin/ld: cannot find -lcereal
    collect2: error: ld returned 1 exit status
    make[3]: *** [xMemory] Error 1
    make[2]: *** [CMakeFiles/xMemory.dir/all] Error 2
    make[1]: *** [CMakeFiles/xMemory.dir/rule] Error 2
    make: *** [xMemory] Error 2
    

    I'm not sure about what is happening cause the library seems to actually import into the code (There are no red letters when including cereal) and as I said before, I think it just stopped working.

    Can someone tell me if there is something wrong with my CMake file?

    PD: Here's a screenshot just in case anyone need it.

    PD2: I'm using elementary os: Freya (Ubuntu 14.04)

    enter image description here

  • Ashutosh Baheti
    Ashutosh Baheti over 6 years
    Can we specify link_directories via a cache-entry or some other command line method?
  • mustafagonul
    mustafagonul over 6 years
    Sorry for the late response. You can define a variable pass to link_directories as a parameter and set this variable via command line if that is what you are asking. You can make this for link_directories. stackoverflow.com/questions/12984181/…
  • dmytro.poliarush
    dmytro.poliarush over 4 years
    From cmake-commands(7): " If a library search path must be provided, prefer to localize the effect where possible by using the target_link_directories() command rather than link_directories(). The target-specific command can also control how the search directories propagate to other dependent targets."
  • xShirase
    xShirase over 3 years
    Hey, thanks for the answer! Could you give a bit of explanation? It would help OP and future readers :)