/usr/bin/ld: не удается найти -l<названиеБиблиотеки>
Я пытаюсь скомпилировать свою программу, и она возвращает следующую ошибку:
usr/bin/ld: cannot find -l<nameOfTheLibrary>
В моем makefile я использую команду g++
и связываю свою программу с библиотекой, которая является символической ссылкой на библиотеку, находящуюся в другой директории.
Есть ли опция, которую я могу добавить, чтобы это заработало?
5 ответ(ов)
Чтобы понять, что ищет компоновщик (linker), запустите его в режиме вербозности.
Например, я столкнулся с этой проблемой при попытке скомпилировать MySQL с поддержкой ZLIB. Во время компиляции я получал ошибку следующего вида:
/usr/bin/ld: cannot find -lzlib
Я немного поищал в Google и наткнулся на множество подобных сообщений, где люди рекомендовали убедиться, что файл <library>.so
действительно существует. Если его нет, то следует создать символьную ссылку на версию файла, например, zlib.so.1.2.8
. Но когда я проверил, zlib.so
ДЕЙСТВИТЕЛЬНО существовал. Поэтому я подумал, что это не может быть причиной.
Я наткнулся на другой пост в Интернете, который предложил запустить 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
Во呀!
Если название вашей библиотеки, скажем, libxyz.so
, и она находится по пути, например:
/home/user/myDir
то для того, чтобы связать её с вашей программой, используйте следующую команду:
g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
Время компиляции
Когда компилятор g++ выдает сообщение cannot find -l<nameOfTheLibrary>
, это означает, что он искал файл 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
Во время компиляции с помощью g++
через make
можно определить LIBRARY_PATH
, если нет возможности изменить Makefile с помощью опции -L
. Я разместил свою дополнительную библиотеку в /opt/lib
, поэтому я выполнил:
$ export LIBRARY_PATH=/opt/lib/
и затем запустил команду make
, что привело к успешной компиляции и линковке.
Для запуска программы с разделяемой библиотекой нужно определить:
$ export LD_LIBRARY_PATH=/opt/lib/
перед выполнением программы.
Сначала нужно понять правило именования 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
+ имя-библиотеки
+ .so
.
После того как мы узнали имя, мы можем использовать команду locate
, чтобы найти путь к файлу lxxx.so
.
$ locate libiconv.so
/home/user/anaconda3/lib/libiconv.so # <-- вот он
/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/
Готово!
Ссылка: https://i-pogo.blogspot.jp/2010/01/usrbinld-cannot-find-lxxx.html
Как изменить цвет вывода echo в Linux
В чём разница между g++ и gcc?
Сон на миллисекунды
Что такое Правило трёх?
Разница между const int*, const int * const и int * const?