Я пытаюсь скомпилировать мою программу, и она возвращает эту ошибку:
usr/bin/ld: cannot find -l<nameOfTheLibrary>
в моем make-файле я использую команду g++
и ссылку на мою библиотеку, которая является символической ссылкой на мою библиотеку, расположенную в другом каталоге.
Есть ли возможность добавить, чтобы он работал, пожалуйста?
Если ваша библиотека называется libxyz.so
и находится по пути, скажите:
/home/user/myDir
затем связать его с вашей программой:
g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
Чтобы выяснить, что ищет компоновщик, запустите его в подробном режиме.
Например, я столкнулся с этой проблемой, пытаясь скомпилировать 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
Вуаля!
Во время компиляции с g++
через make
определите LIBRARY_PATH
, если может быть нецелесообразно изменять Makefile с помощью опции -L
. Я поместил свою дополнительную библиотеку в /opt/lib
, поэтому я сделал:
$ export LIBRARY_PATH=/opt/lib/
а затем запустил make
для успешной компиляции и компоновки.
Для запуска программы с общей библиотекой определите:
$ export LD_LIBRARY_PATH=/opt/lib/
перед выполнением программы.
Кажется, что нет никакого ответа, который решает очень распространенную проблему новичка в том, что сначала не удалось установить необходимую библиотеку.
На платформах Debian, если libfoo
отсутствует, вы можете часто устанавливать его с чем-то вроде
apt-get install libfoo-dev
Версия пакета -dev
необходима для разработки, даже для тривиальной разработки, такой как компиляция исходного кода для ссылки на библиотеку.
Иногда для имени пакета требуются некоторые украшения (libfoo0-dev
? foo-dev
без префикса lib
? И т.д.), Или вы можете просто использовать поиск пакетов вашего дистрибутива , чтобы точно определить, какие пакеты предоставляют определенный файл.
(Если их несколько, вам нужно выяснить, в чем их различия. Выбор наиболее крутого или самого популярного - это обычное сокращение, но не приемлемая процедура для любой серьезной работы по разработке.)
Для других архитектур (особенно RPM) применяются аналогичные процедуры, хотя детали будут другими.
Когда 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
Во-первых, вам нужно знать правило именования 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
Когда вы компилируете свою программу, вы должны указать путь к библиотеке; в g ++ используйте опцию -L:
g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
Проверьте местоположение вашей библиотеки, например, lxxx.so:
locate lxxx.so
Если его нет в папке /usr/lib
, введите:
Sudo cp yourpath/lxxx.so /usr/lib
Готово.
Эта ошибка также может быть вызвана, если символическая ссылка на динамическую библиотеку, .so, но по старым причинам -static
появляется среди флагов ссылки. Если это так, попробуйте удалить его.
Помимо ответов, которые уже были даны, может быть и так, что файл * .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
Библиотека, на которую я пытался сослаться, оказалась с нестандартным именем (то есть без префикса 'lib'), поэтому они рекомендовали использовать такую команду для ее компиляции -
gcc test.c -Iinclude lib/cspice.a -lm
Моя проблема заключалась в том, что я переименовал родительский каталог программы, которую я запускал (mpicc
от MVAPICH), и это как-то испортило двоичный файл. Даже предварительного добавления LD_LIBRARY_PATH было недостаточно, и мне пришлось перекомпилировать его по правильному пути.