Ошибка компиляции C++ CMake (/usr/bin/ld: невозможно найти ‹LIBRARY_NAME›)

* Я знаю, что есть много вопросов по этому поводу, но они просто не очень помогают, когда речь идет о CMake, поэтому я решил задать вопрос *

Итак, я работал над CLion, который использует CMake для импорта и передачи параметров компилятору, и успешно включил (импортировал) внешнюю библиотеку (зерновые: для сериализации классов в файлы json), расположенную в папке с именем «ExternalLibraries», которая находится на корень папки моего проекта. Он работал нормально, пока я не перезапустил IDE и не попытался снова запустить код... Он вернул ошибку компиляции (я думаю).

Мой файл CMake выглядит так:

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)

И когда я пытаюсь запустить/скомпилировать, оболочка выдает мне это:

/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

Я не уверен в том, что происходит, потому что библиотека, кажется, действительно импортирует код (при включении хлопьев нет красных букв), и, как я уже говорил, я думаю, что она просто перестала работать.

Может ли кто-нибудь сказать мне, что с моим файлом CMake что-то не так?

PD: Вот скриншот на всякий случай, если кому-то понадобится.

PD2: я использую elementary os: Freya (Ubuntu 14.04)

введите здесь описание изображения


person BlindHouse    schedule 22.03.2016    source источник
comment
Если вы знаете абсолютный путь к файлу библиотеки, лучше использовать его непосредственно в target_link_libraries вызове: target_link_libraries(xMemory ${PROJECT_SOURCE_DIR}/ExternalLibraries/cereal-1.1.2/<...>).   -  person Tsyvarev    schedule 22.03.2016
comment
Возможный дубликат Ссылка Cmake на общую библиотеку не может найти библиотеку. Что вы искали? Поиск Google   -  person Antonio    schedule 22.03.2016
comment
@Цыварев, это сработало! Напишите это как ответ, чтобы я мог выбрать его как фактический. Спасибо.   -  person BlindHouse    schedule 22.03.2016
comment
Возможный дубликат связать библиотеку с cmake   -  person Tsyvarev    schedule 23.03.2016


Ответы (3)


Вы должны использовать

link_directories(directory1 directory2 ...)

директива для указания каталогов библиотек.

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

person mustafagonul    schedule 22.03.2016
comment
Можем ли мы указать link_directories через кэш-запись или какой-либо другой метод командной строки? - person Ashutosh Baheti; 22.11.2017
comment
Извините за поздний ответ. Вы можете определить передачу переменной в link_directories в качестве параметра и установить эту переменную через командную строку, если это то, о чем вы просите. Вы можете сделать это для link_directories. stackoverflow.com/ вопросы/12984181/ - person mustafagonul; 19.12.2017
comment
Из cmake-commands(7): Если необходимо указать путь поиска библиотеки, предпочтительнее локализовать эффект, где это возможно, с помощью команды target_link_directories(), а не link_directories(). Целевая команда также может управлять тем, как каталоги поиска распространяются на другие зависимые цели. - person dmytro.poliarush; 19.02.2020

Я немного опоздал на вечеринку, но, возможно, это поможет кому-то. У меня была очень похожая проблема с 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$

Вот подход, который я использовал для его отладки:

Убедитесь, что вы можете создавать вручную:

скомпилировать:

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

и ссылка:

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

Убедитесь, что cmake правильно находит библиотеки на этапе генерации:

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$ 

Наконец, рин CMakeLists.txt, я обновил пути поиска каталогов компоновщика в соответствии с советом @mustafagonlu, используя target_link_directories() cmake-commands(7).

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

И это сработало.

person dmytro.poliarush    schedule 19.02.2020

это работает, если добавить:

target_link_libraries (xMemory /library_build_path/libcereal.a)

Детали:

ld ищет библиотеки в очень коротком списке папок, определенных в

/etc/ld.so.conf

и обычно это выглядит следующим образом:

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

и фактический список путей из этих файлов *.conf обычно выглядит так:

# 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

если библиотека компоновки вашего проекта не находится в папке этого списка, ld не найдет ее, если не задана специальная переменная компоновки LD_LIBRARY_PATH с путем к вашей библиотеке или полный путь/имя библиотеки, указанный в директива cmake target_link_libraries.

подробности о том, как правильно настроить переменную LD_LIBRARY_PATH, обсуждаемую здесь

person Oleg Kokorin    schedule 17.10.2020
comment
Эй, спасибо за ответ! Не могли бы вы дать небольшое пояснение? Это поможет ОП и будущим читателям :) - person xShirase; 18.10.2020