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

3

5

*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

Siloxane answered 22/3, 2016 at 11:0 Comment(4)
If you know absolute path to the library file, it is better to use it directly in target_link_libraries call: target_link_libraries(xMemory ${PROJECT_SOURCE_DIR}/ExternalLibraries/cereal-1.1.2/<...>).Pastrami
Possible duplicate of Cmake linking to shared library cannot find library. What did you search? Google searchVaso
@Pastrami it worked! Write it as an answer so I can choose it as the actual one. Thank you.Siloxane
Possible duplicate of Link library with cmakePastrami
H
2

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

Harmonium answered 17/10, 2020 at 18:31 Comment(1)
Hey, thanks for the answer! Could you give a bit of explanation? It would help OP and future readers :)Vacant
O
5

You should use

link_directories(directory1 directory2 ...)

directive to specify library directories.

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

Odin answered 22/3, 2016 at 11:51 Comment(3)
Can we specify link_directories via a cache-entry or some other command line method?Phalan
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. #12984681Odin
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."Daedalus
D
3

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.

Daedalus answered 19/2, 2020 at 9:1 Comment(0)
H
2

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

Harmonium answered 17/10, 2020 at 18:31 Comment(1)
Hey, thanks for the answer! Could you give a bit of explanation? It would help OP and future readers :)Vacant

© 2022 - 2024 — McMap. All rights reserved.