6

/usr/bin/ld: не удается найти -l<названиеБиблиотеки>

2

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

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

В моем makefile я использую команду g++ и связываю свою программу с библиотекой, которая является символической ссылкой на библиотеку, находящуюся в другой директории.

Есть ли опция, которую я могу добавить, чтобы это заработало?

5 ответ(ов)

6

Чтобы понять, что ищет компоновщик (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

Во呀!

2

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

/home/user/myDir

то для того, чтобы связать её с вашей программой, используйте следующую команду:

g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
0

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

Когда компилятор 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
0

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

$ export LIBRARY_PATH=/opt/lib/

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

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

$ export LD_LIBRARY_PATH=/opt/lib/

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

0

Сначала нужно понять правило именования 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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь