it-swarm.xyz

usr/bin/ld: невозможно найти -l <nameOfTheLibrary>

Я пытаюсь скомпилировать мою программу, и она возвращает эту ошибку:

usr/bin/ld: cannot find -l<nameOfTheLibrary>

в моем make-файле я использую команду g++ и ссылку на мою библиотеку, которая является символической ссылкой на мою библиотеку, расположенную в другом каталоге.

Есть ли возможность добавить, чтобы он работал, пожалуйста?

327
ZoOo

Если ваша библиотека называется libxyz.so и находится по пути, скажите:

/home/user/myDir

затем связать его с вашей программой:

g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
148
Saurabh Bhola

Чтобы выяснить, что ищет компоновщик, запустите его в подробном режиме. 

Например, я столкнулся с этой проблемой, пытаясь скомпилировать MySQL с поддержкой ZLIB. Я получаю сообщение об ошибке во время компиляции:

/usr/bin/ld: cannot find -lzlib

Я занимался поиском в Google и продолжал сталкиваться с различными проблемами одного и того же типа, когда люди говорили, что файл .so действительно существует, а если нет, то создайте символическую ссылку на файл с версиями, например, zlib. so.1.2.8. Но когда я проверил, zlib.so DID существует. Итак, я подумал, конечно, это не может быть проблемой. 

Я наткнулся на другой пост в интернете, в котором предлагалось запустить make с LD_DEBUG = all:

LD_DEBUG=all make

Хотя я получил ТОННУ отладочной информации, это не помогло. Это добавило больше путаницы, чем что-либо еще. Итак, я собирался сдаться.

Затем у меня было прозрение. Я подумал проверить текст справки по команде ld:

ld --help

Из этого я понял, как запустить ld в подробном режиме (представьте, что):

ld -lzlib --verbose

Это вывод, который я получил:

==================================================
attempt to open /usr/x86_64-linux-gnu/lib64/libzlib.so failed
attempt to open /usr/x86_64-linux-gnu/lib64/libzlib.a failed
attempt to open /usr/local/lib64/libzlib.so failed
attempt to open /usr/local/lib64/libzlib.a failed
attempt to open /lib64/libzlib.so failed
attempt to open /lib64/libzlib.a failed
attempt to open /usr/lib64/libzlib.so failed
attempt to open /usr/lib64/libzlib.a failed
attempt to open /usr/x86_64-linux-gnu/lib/libzlib.so failed
attempt to open /usr/x86_64-linux-gnu/lib/libzlib.a failed
attempt to open /usr/local/lib/libzlib.so failed
attempt to open /usr/local/lib/libzlib.a failed
attempt to open /lib/libzlib.so failed
attempt to open /lib/libzlib.a failed
attempt to open /usr/lib/libzlib.so failed
attempt to open /usr/lib/libzlib.a failed
/usr/bin/ld.bfd.real: cannot find -lzlib

Дин, Дин, Дин ...

Итак, чтобы наконец это исправить, чтобы я мог скомпилировать MySQL с моей собственной версией ZLIB (а не в комплекте):

Sudo ln -s /usr/lib/libz.so.1.2.8 /usr/lib/libzlib.so

Вуаля!

363
dcarrith

Во время компиляции с g++ через make определите LIBRARY_PATH, если может быть нецелесообразно изменять Makefile с помощью опции -L. Я поместил свою дополнительную библиотеку в /opt/lib, поэтому я сделал: 

$ export LIBRARY_PATH=/opt/lib/

а затем запустил make для успешной компиляции и компоновки.

Для запуска программы с общей библиотекой определите:

$ export LD_LIBRARY_PATH=/opt/lib/

перед выполнением программы.

28
Finn Årup Nielsen

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

На платформах Debian, если libfoo отсутствует, вы можете часто устанавливать его с чем-то вроде

apt-get install libfoo-dev

Версия пакета -dev необходима для разработки, даже для тривиальной разработки, такой как компиляция исходного кода для ссылки на библиотеку.

Иногда для имени пакета требуются некоторые украшения (libfoo0-dev? foo-dev без префикса lib? И т.д.), Или вы можете просто использовать поиск пакетов вашего дистрибутива , чтобы точно определить, какие пакеты предоставляют определенный файл.

(Если их несколько, вам нужно выяснить, в чем их различия. Выбор наиболее крутого или самого популярного - это обычное сокращение, но не приемлемая процедура для любой серьезной работы по разработке.)

Для других архитектур (особенно RPM) применяются аналогичные процедуры, хотя детали будут другими.

25
tripleee

Время компиляции

Когда G ++ говорит cannot find -l<nameOfTheLibrary>, это означает, что G ++ искал файл lib{nameOfTheLibrary}.so, но не смог найти его в пути поиска в общей библиотеке, который по умолчанию указывает на /usr/lib и /usr/local/lib и, возможно, где-то еще.

Чтобы решить эту проблему, вы должны предоставить библиотечный файл (lib{nameOfTheLibrary}.so) в этих путях поиска или использовать опцию команды -L. -L{path} указывает G ++ (на самом деле ld) найти библиотечные файлы по пути {path} в дополнение к путям по умолчанию.

Пример: Предполагая, что у вас есть библиотека в /home/taylor/libswift.so, и вы хотите связать свое приложение с этой библиотекой. В этом случае вы должны предоставить G++ со следующими опциями:

g++ main.cpp -o main -L/home/taylor -lswift
  • Примечание 1 : -l опция получает имя библиотеки безlib и .so в ее начале и конце.

  • Примечание 2 : В некоторых случаях после имени файла библиотеки следует его версия, например libswift.so.1.2. В этих случаях G ++ также не может найти файл библиотеки. Простой обходной путь для решения этой проблемы - создание символической ссылки на libswift.so.1.2 с именем libswift.so.


Время выполнения

Когда вы связываете свое приложение с общей библиотекой, требуется, чтобы библиотека оставалась доступной при каждом запуске приложения. Во время выполнения ваше приложение (фактически динамический компоновщик) ищет свои библиотеки в LD_LIBRARY_PATH. Это переменная окружения, которая хранит список путей.

Пример: В нашем примере libswift.so динамический компоновщик не может найти libswift.so в LD_LIBRARY_PATH (который указывает на пути поиска по умолчанию). Чтобы устранить проблему, вы должны добавить эту переменную с путем libswift.so.

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor
23
Hi I'm Frogatto

Во-первых, вам нужно знать правило именования lxxx:

/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lltdl
/usr/bin/ld: cannot find -lXtst

lc означает libc.so, lltdl означает libltdl.so, lXtst означает libXts.so.

Итак, это lib + lib-name + .so


Как только мы узнаем имя, мы можем использовать locate, чтобы найти путь к этому файлу lxxx.so.

$ locate libiconv.so
/home/user/anaconda3/lib/libiconv.so   # <-- right here
/home/user/anaconda3/lib/libiconv.so.2
/home/user/anaconda3/lib/libiconv.so.2.5.1
/home/user/anaconda3/lib/preloadable_libiconv.so
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so.2
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so.2.5.1
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/preloadable_libiconv.so

Если вы не можете найти его, вам нужно установить его с помощью yum (я использую CentOS). Обычно у вас есть этот файл, но он не ссылается на нужное место.


Ссылка на нужное место, обычно это /lib64 или /usr/lib64

$ Sudo ln -s /home/user/anaconda3/lib/libiconv.so /usr/lib64/

Готово!

ref: https://i-pogo.blogspot.jp/2010/01/usrbinld-cannot-find-lxxx.html

5
Belter

Когда вы компилируете свою программу, вы должны указать путь к библиотеке; в g ++ используйте опцию -L:

g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
4
koan

Проверьте местоположение вашей библиотеки, например, lxxx.so: 

locate lxxx.so

Если его нет в папке /usr/lib, введите:

Sudo cp yourpath/lxxx.so /usr/lib

Готово.

2
hua

Эта ошибка также может быть вызвана, если символическая ссылка на динамическую библиотеку, .so, но по старым причинам -static появляется среди флагов ссылки. Если это так, попробуйте удалить его.

2
Vzbux

Помимо ответов, которые уже были даны, может быть и так, что файл * .so существует, но не имеет правильного имени. Или может быть так, что файл * .so существует, но он принадлежит другому пользователю/root.

Результат 1: Неправильное имя 

Если вы связываете файл как -l<nameOfLibrary>, Тогда имя файла библиотеки ДОЛЖНО иметь форму lib<nameOfLibrary> Если у вас есть только файл <nameOfLibrary>.so, переименуйте его!

Результат 2: Неправильный владелец

Чтобы убедиться, что это не проблема - сделайте

ls -l /path/to/.so/file

Если файл принадлежит пользователю root или другому пользователю, вам нужно сделать

Sudo chown yourUserName:yourUserName /path/to/.so/file
1
user13107

Библиотека, на которую я пытался сослаться, оказалась с нестандартным именем (то есть без префикса 'lib'), поэтому они рекомендовали использовать такую ​​команду для ее компиляции - 

gcc test.c -Iinclude lib/cspice.a -lm

1
Brian Burns

Моя проблема заключалась в том, что я переименовал родительский каталог программы, которую я запускал (mpicc от MVAPICH), и это как-то испортило двоичный файл. Даже предварительного добавления LD_LIBRARY_PATH было недостаточно, и мне пришлось перекомпилировать его по правильному пути.

0
Alberto Chiusole