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

444

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

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

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

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

ZoOo
источник
1
Нужно больше информации. Какую команду вы использовали для компиляции вашей программы? Вы можете использовать make -n your-target, чтобы make просто печатал команды, которые он обычно вызывает
djf
Разместите make-файл или команду, которую вы выполняете.
Ортвин Ангермейер
Вот моя команда: g ++ - <options> objetc1.o objetc2.o objetc3.o objetc4.o -L <pathOfTheLibrary> -l <nameOfTheLibrary> -lpthread -o myexe
ZoOo
4
Библиотека, с которой вы хотите связать, построена с той же архитектурой (например, 32/64 бит)? Библиотека, которую вы хотите связать с пользовательской библиотекой? Имя библиотеки имеет значение, так как оно должно начинаться с lib <name> при использовании -lпереключателя (например, libpthread.so, с которым вы уже связываетесь).
Ортвин Ангермейер
1
Проблема была в моей символической ссылке на библиотеку, которая не была хорошей! Спасибо за вашу помощь !
ZoOo

Ответы:

196

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

/home/user/myDir

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

g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
Саурабх Бхола
источник
11
моя библиотека не динамическая (.so), а статическая (.a). Проблема в этом?
ZoOo
3
@ZoOo, что обычно не имеет значения, компоновщик может работать с любым из них
djf
7
Другой способ связать вашу библиотеку - это то, что вы можете напрямую указать имя библиотеки с полным путем, например, g ++. /path/mylib.a
Bhola
2
Да, но это все еще не работает. Моя библиотека является символической ссылкой, я думаю, что проблема заключается в том, что, когда я использую библиотеку в другом каталоге, она работает!
ZoOo
2
Ваша символическая ссылка правильно указывает на библиотеку в фактическом местоположении ?? Вы можете опубликовать вывод "ll" по символической ссылке.
Саурабх Бхола
452

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

Например, я столкнулся с этой проблемой, пытаясь скомпилировать MySQL с поддержкой ZLIB. Я получаю сообщение об ошибке во время компиляции:

/usr/bin/ld: cannot find -lzlib

Я занимался поиском в Google и продолжал сталкиваться с разными проблемами одного и того же типа, когда люди говорили, чтобы убедиться, что файл .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

Вуаля!

dcarrith
источник
60
Спасибо, это было полезно. Для других, использующих gcc для компиляции и компоновки своей программы (вместо непосредственного использования ld), вы можете добавить -Xlinker --verboseаргументы командной строки gcc, чтобы он передавал эту опцию ld.
5
Это также помогло мне. Makefile, который я имел, ожидал только статических библиотек, поэтому он использовал -Wl,-Bstatic. Это ограничивает поиск только .a файлами. Подробный вариант ясно показал это. После того, как я удалил -Wl,-Bstaticобщие библиотеки, также был произведен поиск.
micah94
2
Я нахожусь на FreeBSD 10. Новый LLVM Clang cc принимает аргумент формы -Wl,--verboseи передает --verboseкомпоновщику.
Кристиан Кэмпбелл
7
Вот что я называю идеальным ответом! Большое спасибо. Это сэкономило много времени. Просто чтобы добавить, чтобы помочь кому-то, как я. Он также может быть использован для отладки проблем, связанных с путями. Убедитесь, что вы проверили путь с помощью -L <путь к каталогу> с помощью команды, ld -L <путь> -l <имя библиотеки> --verbose
sbhatt
2
@ EdwardBlack Посмотри этот ответ . По существу, для gcc, просто добавьте, -Wl,--verboseчтобы передать подробный компоновщик.
Чембрад
46

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

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

apt-get install libfoo-dev

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

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

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

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

tripleee
источник
3
Это только помогло мне решить проблему со свежим сервером и Perl. apt-get install libperl-devотсортировал это для меня. Спасибо :)
Эндрю Ньюби
1
Эта! Не нужно связываться с Makefile
Байрон Уитлок
Это, вероятно, наиболее распространенное решение, которое помогло мне собрать cacti-spine на CentOS 7. Простое yum install openssl-develрешение проблемы.
djluko
1
Это лучшее исправление, если вы обнаружите, что символическая ссылка, оканчивающаяся на .so, отсутствует, но у вас есть символическая ссылка, например libfoo.so.6 -> libfoo.so.6.0.2 (например), вместо того, чтобы сделать символическую ссылку рука. (имеется в виду, что у вас установлен пакет libfoo, но не libfoo-dev)
dmaestro12
39

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

Когда г ++ говорит 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
frogatto
источник
Спасибо за ваш пост! Я игнорировал все ответы до того момента, когда скопировал .soфайлы /usr/lib, но мне стало интересно, exportпоможет ли это. Несмотря на то, что процесс установки makeпродолжался дольше, произошла другая ошибка. На этот раз, .so.0файл не был найден, но , как .soи .so.0файл был в директории , где у меня есть сборки зависимого пакет от источника. Не могли бы вы помочь с этим?
А.Аметов
33

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

$ export LIBRARY_PATH=/opt/lib/

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

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

$ export LD_LIBRARY_PATH=/opt/lib/

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

Финн Оруп Нильсен
источник
14

Во-первых, вам нужно знать правило именования 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/

Выполнено!

ссылка: https://i-pogo.blogspot.jp/2010/01/usrbinld-cannot-find-lxxx.html

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

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

g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
коан
источник
1
Какое свойство нам нужно изменить, ccmakeчтобы Makefileоно создавалось с флагом привязки? Я хочу связать свой -lARToolkitPlusфлаг с путем.
Шашват
2

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

Vzbux
источник
2

Проверьте местоположение вашей библиотеки, например, lxxx.so:

locate lxxx.so

Если его нет в /usr/libпапке, введите:

sudo cp yourpath/lxxx.so /usr/lib

Выполнено.

хуа
источник
4
Вы должны соблюдать осторожность при копировании библиотек в системные каталоги.
Пол Флойд,
2

Помимо ответов, которые уже были даны, может быть и так, что файл * .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
user13107
источник
1

Библиотека, на которую я пытался сослаться, оказалась с нестандартным именем (то есть без префикса 'lib'), поэтому они рекомендовали использовать такую ​​команду для ее компиляции -

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

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

Вот информация об Ubuntu моего ноутбука.

lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.2 LTS
Release:    18.04
Codename:   bionic

Я использую locate, чтобы найти .so файлы для boost_filesystem и boost_system

locate libboost_filesystem
locate libboost_system

Затем свяжите .so файлы с / usr / lib и переименуйте в .so

sudo ln -s /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.65.1 /usr/lib/libboost_filesystem.so
sudo ln -s /usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 /usr/lib/libboost_system.so

Выполнено! R пакет velocyto.R был успешно установлен!

Шичэн Го
источник
1

Я столкнулся с тем же сообщением об ошибке.

Я построил cmockaкак soи попытался связать его с моим исполняемым файлом. Но ldвсегда жалуется ниже:

/ usr / bin / ld: не могу найти -lcmocka

Оказывается, после сборки создается 3 файла cmocka:

  1. libcmocka.so
  2. libcmocka.so.0
  3. libcmocka.so.0.7.0

1 и 2 - символьные ссылки, и только 3 - настоящий файл.

Я только скопировал 1 в мою папку библиотеки, где ldне удалось найти 3.

После того как я скопировал все 3, ldработает.

smwikipedia
источник
Скажите, пожалуйста, какую папку вы подразумеваете под "папкой моей библиотеки"?
А.Аметов