Я пытаюсь скомпилировать свою программу и возвращает эту ошибку:
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
Я сделал некоторые Googl'ing и продолжал сталкиваться с различными проблемами того же типа, где люди говорили бы, чтобы убедиться, что файл .so действительно существует, а если нет, то создайте символическую ссылку на файл с версией, например, zlib.so.1.2.8. Но, когда я проверил, zlib.so DID существует. Поэтому я подумал, что это не может быть проблемой.
Я столкнулся с другим сообщением в Internet, которое предложило запустить make с LD_DEBUG = all:
LD_DEBUG=all make
Хотя я получил TON отладочного вывода, на самом деле это не помогло. Это добавило больше путаницы, чем что-либо еще. Итак, я собирался сдаться.
Тогда у меня было прозрение. Я решил проверить текст справки для команды 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
Ding, ding, ding...
Итак, чтобы окончательно исправить это, я мог бы скомпилировать MySQL с моей собственной версией ZLIB (а не в комплекте):
sudo ln -s /usr/lib/libz.so.1.2.8 /usr/lib/libzlib.so
Voila!
-Xlinker --verbose
к аргументам командной строки gcc, чтобы он передавал эту опцию ld.
-Wl,-Bstatic
. Это ограничивает поиск только .a файлами. Подробный вариант ясно показал это. После того как я удалил -Wl,-Bstatic
были также найдены общие библиотеки -Wl,-Bstatic
.
Во время компиляции с g++
через make
определите LIBRARY_PATH
, если может быть нецелесообразно изменять Makefile с опцией -L
. Я поместил свою дополнительную библиотеку в /opt/lib
, поэтому я сделал:
$ export LIBRARY_PATH=/opt/lib/
а затем выполнил make
для успешной компиляции и компоновки.
Для запуска программы с общей библиотекой определите:
$ export LD_LIBRARY_PATH=/opt/lib/
перед выполнением программы.
Когда 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
Кажется, что нет ответа, который бы затрагивал очень распространенную проблему начинающего с невозможностью установить требуемую библиотеку в первую очередь.
На платформах Debianish, если libfoo
отсутствует, вы можете часто устанавливать его с чем-то вроде
apt-get install libfoo-dev
Версия пакета -dev
требуется для работы по разработке, даже тривиальная разработка, такая как компиляция исходного кода для связи с библиотекой.
Название пакета иногда требует некоторых украшений (libfoo0-dev
? foo-dev
без префикса lib
и т.д.), или вы можете просто использовать свой дистрибутив пакетный поиск, чтобы узнать, какие именно пакеты предоставляют конкретный файл.
(Если их больше одного, вам нужно будет выяснить, каковы их отличия. Выбор самого крутого или самого популярного - это общий ярлык, но не приемлемая процедура для любой серьезной работы по разработке.)
Для других архитектур (в частности, RPM) применяются аналогичные процедуры, хотя детали будут разными.
apt-get install libperl-dev
отсортировал это для меня. Спасибо :)
Эта ошибка может также возникнуть, если символическая ссылка относится к динамической библиотеке .so, но по причинам, связанным с устаревшими, -static
появляется среди флагов ссылок. Если да, попробуйте удалить его.
При компиляции вашей программы вы должны указать путь к библиотеке; в g++ используйте параметр -L:
g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
ccmake
чтобы Makefile
создавался со связанным флагом? Я хочу связать свой флаг -lARToolkitPlus
с путем.
Во-первых, вам нужно знать правило именования 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
locate
работает, только если он установлен и работает регулярно. Необработанный обходной путь - запустить find
на всем диске, но, конечно, это займет время. Если вы делаете это часто, рассмотрите возможность установки locate
чтобы снизить (интерактивные, человеческие) затраты на эту операцию.
В библиотеке, с которой я пытался ссылаться, оказалось нестандартное имя (т.е. не было префикс "lib" ), поэтому они рекомендовали использовать эту команду для ее компиляции -
gcc test.c -Iinclude lib/cspice.a -lm