usr / bin / ld: не вдається знайти -l <nameOfTheLibrary>


443

Я намагаюся скласти свою програму, і вона повертає цю помилку:

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

у своєму makefile я використовую команду g++та посилання на свою бібліотеку, яка є символічним посиланням на мою бібліотеку, розташовану в іншому каталозі.

Чи є можливість додати, щоб він працював, будь ласка?


1
Потрібна додаткова інформація. Яку команду ви склали для складання програми? Ви можете використовувати make -n your target, щоб змусити просто надрукувати команди, до яких зазвичай
звертається

Опублікуйте makefile або виконану команду.
Ортвін Анжермейер

моя команда така: 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

Якщо ім’я вашої бібліотеки скажіть, 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
Saurabh Bhola,

2
Так, але це все ще не працює. Моя бібліотека є символічним посиланням, я думаю, що проблема виникла з цього, оскільки коли я використовую бібліотеку в іншому каталозі, вона працює!
ZoOo

2
Чи правильно вказано ваше символічне посилання на бібліотеку в фактичному місці ??. чи можете ви розмістити висновок "ll" на символічному посиланні.
Саураб Бхола

451

Щоб зрозуміти, що шукає лінкер, запустіть його у багатослівному режимі.

Наприклад, я зіткнувся з цим питанням під час спроби компілювати MySQL із підтримкою ZLIB. Я отримував подібну помилку під час компіляції:

/usr/bin/ld: cannot find -lzlib

Я робив деякий Googl'ing і постійно стикався з різними проблемами одного і того ж виду, де люди би сказали, щоб переконатися, що файл .so фактично існує, а якщо його немає, то створити символьне посилання на файл із версією, наприклад, zlib. так.1.2.8. Але, коли я перевірив, zlib.so DID існує. Отже, я подумав, це точно не може бути проблемою.

Я натрапив на ще одну посаду в Інтернеті, яка запропонувала запустити 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

Дін, дінь, дінь ...

Отже, щоб остаточно виправити це, щоб я міг компілювати MySQL із власною версією ZLIB (а не з пакетною версією):

sudo ln -s /usr/lib/libz.so.1.2.8 /usr/lib/libzlib.so

Вуаля!


60
Дякую, це було корисно. Для інших, хто використовує gcc для компіляції та посилання своєї програми (замість використання ld безпосередньо), ви можете додати -Xlinker --verboseдо аргументів командного рядка gcc, щоб вона передала цю опцію ld.

5
Це мені теж допомогло. Makefile, який я мав, очікував лише статичних бібліотек, тому він використовувався -Wl,-Bstatic. Це обмежує пошук лише до файлів .a. Докладний варіант показав це наочно. Після того, як я видалив -Wl,-Bstaticспільні бібліотеки, також шукали.
micah94

2
Я на FreeBSD 10. Новий куб-код LLVM Clang приймає аргумент форми -Wl,--verboseі переходить --verboseдо лінкера.
Крістіан Кемпбелл

7
Тепер це я називаю ідеальною відповіддю! Дуже дякую. Це заощадило багато часу. Просто додати, щоб допомогти комусь, як я. Він також може бути використаний для налагодження проблем, пов'язаних із шляхом. Переконайтесь, що ви перевіряєте шлях з -L <шлях до каталогу> з командою, ld -L <шлях> -l <назва бібліотеки> --verbose
sbhatt

2
@EdwardBlack Дивіться цю відповідь . По суті, для gcc просто додайте -Wl,--verboseдля передачі багатослівного посилання на лінкер.
chembrad

46

Здається, немає жодної відповіді, яка б вирішувала найпоширенішу проблему для початківців, коли не вдалося встановити потрібну бібліотеку.

На платформах Debianish, якщо libfooцього немає, ви можете часто встановлювати його з чимось подібним

apt-get install libfoo-dev

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

Ім'я пакета іноді потребує декору ( libfoo0-dev« foo-devбез libпрефікса» тощо), або ви можете просто скористатися пошуком пакета вашого дистрибутива, щоб точно з’ясувати, які пакети надають певний файл.

(Якщо їх більше, вам потрібно буде з’ясувати, в чому їх відмінності. Вибір найкрутішого чи найпопулярнішого - це звичайний ярлик, але не прийнятна процедура для будь-якої серйозної роботи з розробки.)

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


3
Це просто допомогло мені з проблемою, з якою у мене виник свіжий сервер та Perl. apt-get install libperl-devсортував це для мене. Дякую :)
Ендрю Ньюбі

1
Це! Не потрібно возитися з Makefile
Байрон Вітлок

Це, мабуть, найпоширеніше рішення і допомогло мені скласти кактуси-хребет на CentOS 7. Простий yum install openssl-develвирішив це.
djluko

1
Це найкраще виправлення, якщо ви виявите, що символьне посилання закінчується на .so відсутнє, але у вас є така посилання, як libfoo.so.6 -> libfoo.so.6.0.2 (наприклад), а не робити символьне посилання на рукою. (значить у вас встановлено пакет libfoo, але не libfoo-dev)
dmaestro12

39

Час компіляції

Коли 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

Дякуємо за ваш пост! Я ігнорував усі відповіді до моменту, коли я копіював .soфайли /usr/lib, але мені стало цікаво, чи exportдопоможу. Незважаючи на те, що процес встановлення makeтривав довше, сталася ще одна помилка. Цього разу .so.0файл не був знайдений, але обидва .soта .so.0файл знаходились у каталозі, де я маю залежний пакет від джерела. Чи можете ви допомогти у цьому?
А.Аметов

33

Під час компіляції з g++via makeвизначте, 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


4
locateпрацює лише в тому випадку, якщо він встановлюється та працює регулярно. Грубий спосіб вирішити findвесь диск, але, звичайно, це займе час. Якщо ви часто зустрічаєтеся з цим, подумайте про встановлення locateлише для зниження (інтерактивної, людської) вартості цієї операції.
трійка

5

Під час складання програми ви повинні подати шлях до бібліотеки; в g ++ використовуйте параметр -L:

g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar

1
Яку властивість ми повинні змінити, ccmakeщоб Makefileстворено позначення пов'язаного прапора? Я хочу прив’язати свій -lARToolkitPlusпрапор до шляху.
Шашват

2

Ця помилка також може виникнути, якщо символьне посилання на динамічну бібліотеку -static. Якщо так, спробуйте його видалити.


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

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

Виявляється, що після створення cmockaпобудовано 3 файли :

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

1 і 2 - це посилання символів, і лише 3 - це реальний файл.

Я лише скопіював 1 у свою папку бібліотеки, де ldне вдалося знайти 3.

Після того як я скопіював усі 3, ldпрацює.


Чи можете ви надати, скажіть, будь ласка, яку папку ви маєте на увазі під "моя папка бібліотеки"?
А.Аметов
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.