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

252

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

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

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

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

  • 1
    Нужно больше информации. Какую команду вы использовали для компиляции вашей программы? Вы можете использовать make -n your-target, чтобы make просто печатал команды, которые он обычно вызывает
  • 0
    Отправьте make-файл или команду, которую вы выполняете.
Показать ещё 7 комментариев
Теги:
g++

9 ответов

108
Лучший ответ

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

/home/user/myDir

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

g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
  • 6
    моя библиотека не динамическая (.so), а статическая (.a). Проблема в этом?
  • 3
    @ZoOo, который обычно не имеет значения, компоновщик может работать с любым
Показать ещё 8 комментариев
298

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

Например, я столкнулся с этой проблемой при попытке скомпилировать 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!

  • 48
    Спасибо, это было полезно. Для других, использующих gcc для компиляции и компоновки своей программы (вместо непосредственного использования ld), вы можете добавить -Xlinker --verbose к аргументам командной строки gcc, чтобы он передавал эту опцию ld.
  • 5
    Это также помогло мне. Makefile, который у меня был, ожидал только статических библиотек, поэтому он использовал -Wl,-Bstatic . Это ограничивает поиск только .a файлами. Подробный вариант ясно показал это. После того как я удалил -Wl,-Bstatic были также найдены общие библиотеки -Wl,-Bstatic .
Показать ещё 19 комментариев
17

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

$ export LIBRARY_PATH=/opt/lib/

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

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

$ export LD_LIBRARY_PATH=/opt/lib/

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

15

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

Когда 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.


Runtime

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

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

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor
8

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

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

apt-get install libfoo-dev

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

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

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

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

  • 2
    Это только помогло мне решить проблему со свежим сервером и Perl. apt-get install libperl-dev отсортировал это для меня. Спасибо :)
  • 1
    Это! Нет необходимости возиться с Makefile
Показать ещё 2 комментария
2

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

1

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

g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
  • 1
    спасибо, я уже делаю это, но это не работает
  • 1
    Какое свойство мы должны изменить в ccmake чтобы Makefile создавался со связанным флагом? Я хочу связать свой флаг -lARToolkitPlus с путем.
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 + 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

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

В библиотеке, с которой я пытался ссылаться, оказалось нестандартное имя (т.е. не было префикс "lib" ), поэтому они рекомендовали использовать эту команду для ее компиляции -

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

  • 0
    Только префикс с "lib", чтобы получить стандартное имя, исправил это для меня

Ещё вопросы

Сообщество Overcoder
Наверх
Меню