usr / bin / ld: -l <-nameOfTheLibrary> नहीं मिल सकता है


443

मैं अपने कार्यक्रम को संकलित करने की कोशिश कर रहा हूं और यह त्रुटि लौटाता है:

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

मेरे मेकफाइल में मैं g++अपनी लाइब्रेरी के लिए कमांड और लिंक का उपयोग करता हूं जो कि एक अन्य निर्देशिका पर स्थित मेरी लाइब्रेरी का प्रतीकात्मक लिंक है।

कृपया इसे काम करने के लिए जोड़ने का विकल्प है?


1
अधिक जानकारी चाहिए। आपने अपने कार्यक्रम को संकलित करने के लिए क्या आदेश जारी किया? आप मेक-एन-टारगेट का उपयोग कर सकते हैं, ताकि वह केवल उन कमांडों को प्रिंट कर सके, जो सामान्य रूप से लागू होंगे
djf

Makefile या आपके द्वारा निष्पादित कमांड को पोस्ट करें।
ऑर्टविन एंगर्मियर

मेरी कमांड यह एक है: g ++ - <options> objetc1.o objetc2.o objetc3.o objetc4.o -L <pathOfTheLibrary> -l <nameOfTheLibrary> -lpthread -o myexe
ZoOo

4
क्या आप जिस लाइब्रेरी को एक ही आर्किटेक्चर (जैसे 32/64 बिट) के साथ लिंक करना चाहते हैं? क्या वह लाइब्रेरी जिसे आप कस्टम लाइब्रेरी से जोड़ना चाहते हैं? लाइब्रेरी नाम मायने रखता है, क्योंकि इसे -lस्विच का उपयोग करते समय lib <name> से शुरू करना पड़ता है (जैसे। 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
सौरभ भोला

2
हाँ, लेकिन यह अभी भी काम नहीं करता है। मेरी लाइब्रेरी एक प्रतीकात्मक कड़ी है, मुझे लगता है कि समस्या इसी से आती है क्योंकि जब मैं लाइब्रेरी का उपयोग करता हूं तो यह दूसरी निर्देशिका में काम करता है!
ज़ोओ

2
क्या आपका प्रतीकात्मक लिंक वास्तविक स्थान पर पुस्तकालय की ओर सही ढंग से इंगित करता है ??। क्या आप प्रतीकात्मक लिंक पर "ll" का आउटपुट पोस्ट कर सकते हैं।
सौरभ भोला

451

यह जानने के लिए कि लिंकर किस चीज की तलाश कर रहा है, इसे वर्बोज मोड में चलाएं।

उदाहरण के लिए, मैंने ZLIB समर्थन के साथ MySQL संकलित करने की कोशिश करते हुए इस मुद्दे का सामना किया। संकलन के दौरान मुझे इस तरह एक त्रुटि प्राप्त हुई थी:

/usr/bin/ld: cannot find -lzlib

मैंने कुछ Googl'ing किया और एक ही तरह के विभिन्न मुद्दों पर आते रहे, जहां लोग यह सुनिश्चित करने के लिए कहेंगे कि .so फ़ाइल वास्तव में मौजूद है और यदि ऐसा नहीं है, तो संस्करण फ़ाइल के लिए एक सिमलिंक बनाएं, उदाहरण के लिए, zlib। so.1.2.8। लेकिन, जब मैंने जाँच की, तो zlib.so DID मौजूद है। तो, मैंने सोचा, निश्चित रूप से यह समस्या नहीं हो सकती है।

मैं एक और पोस्ट पर आया था जिसमें इंटनेट पर LD_DEBUG = सभी के साथ चलने का सुझाव दिया गया था:

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 का उपयोग करने वाले अन्य लोगों के लिए, आप -Xlinker --verbosegcc के कमांड-लाइन तर्कों में जोड़ सकते हैं, ताकि यह विकल्प ld में पास हो सके।

5
इससे मुझे भी मदद मिली। Makefile मैं केवल स्थैतिक पुस्तकालयों की उम्मीद कर रहा था इसलिए इसका इस्तेमाल किया -Wl,-Bstatic। यह केवल .a फ़ाइलों के लिए खोज को सीमित करता है। क्रिया विकल्प ने इसे स्पष्ट रूप से दिखाया। एक बार मैंने -Wl,-Bstaticसाझा पुस्तकालयों को हटा दिया था ।
micah94

2
मैं फ्रीबीएसडी 10 पर हूं। नया एलएलवीएम क्लैंग सीसी फॉर्म का एक तर्क लेता है -Wl,--verboseऔर --verboseलिंकर को पास करता है।
ईसाई कैम्पबेल

7
अब यही मैं एक सही जवाब कहता हूं! बहुत बहुत धन्यवाद। इसने बहुत समय बचाया। सिर्फ मेरे जैसे किसी व्यक्ति की मदद करने के लिए। इसका उपयोग पथ संबंधी समस्याओं को डीबग करने के लिए भी किया जा सकता है। सुनिश्चित करें कि आप कमांड के साथ -L <path to directory> ld -L <path> -l <लाइब्रेरी नाम> --verbose
sbhatt

2
@EdwardBlack इस उत्तर को देखें । अनिवार्य रूप से, जीसीसी के लिए, बस -Wl,--verboseलिंकर को वर्बोज़ पास करने के लिए जोड़ें ।
कीम्ब्राड सिप

46

ऐसा कोई उत्तर नहीं प्रतीत होता है जो पहली बार आवश्यक पुस्तकालय स्थापित करने में विफल होने की बहुत ही सामान्य शुरुआत समस्या को संबोधित करता है।

डेबियनिश प्लेटफार्मों पर, यदि libfooगायब है, तो आप अक्सर इसे कुछ के साथ स्थापित कर सकते हैं

apt-get install libfoo-dev

-devपैकेज के संस्करण में इस तरह के पुस्तकालय के लिए लिंक करने के लिए स्रोत कोड संकलन के रूप में विकास कार्य के लिए आवश्यक है, यहां तक कि तुच्छ विकास कार्य।

पैकेज का नाम कभी कभी कुछ सजावट की आवश्यकता होगी ( libfoo0-dev? foo-devबिना libउपसर्ग? आदि), या आप बस अपने distro के उपयोग कर सकते हैं पैकेज खोज ठीक पता लगाने के लिए जो पैकेज एक विशेष फ़ाइल प्रदान करते हैं।

(यदि एक से अधिक हैं, तो आपको यह पता लगाना होगा कि उनके अंतर क्या हैं। सबसे अच्छे या सबसे लोकप्रिय को चुनना एक सामान्य शॉर्टकट है, लेकिन किसी भी गंभीर विकास कार्य के लिए स्वीकार्य प्रक्रिया नहीं है।)

अन्य आर्किटेक्चर के लिए (सबसे विशेष रूप से आरपीएम) समान प्रक्रियाएं लागू होती हैं, हालांकि विवरण अलग-अलग होंगे।


3
यह सिर्फ मुझे एक ताजा सर्वर और पर्ल के साथ होने वाले मुद्दे के साथ मदद करता है। apt-get install libperl-devमेरे लिए इसे हल किया। धन्यवाद :)
एंड्रयू न्यूबी

1
इस! मेकफाइल के साथ गड़बड़ करने की आवश्यकता नहीं है
बायरन व्हिटलॉक

यह शायद सबसे आम समाधान है और मुझे CentOS 7 पर कैक्टि-स्पाइन संकलित करने में मदद मिली। एक सरल yum install openssl-develसमाधान।
djluko

1
यह सबसे अच्छा फिक्स है यदि आप सिस्कोलि को अंत में पाते हैं, तो गायब है, लेकिन आपके पास लिम्फू .so.6 -> libfoo.so.6.0.2 (उदाहरण के लिए) जैसे सिमलिंक है, बजाय सिम्पीनल के हाथ। (आप पैकेज libfoo स्थापित है, लेकिन नहीं libfoo- देव)
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

आपकी पोस्ट के लिए धन्यवाद! मैं उस समय तक सभी उत्तरों को नजरअंदाज कर रहा हूं जब मैंने .soफाइलों को कॉपी किया था /usr/lib, लेकिन यह मेरे लिए दिलचस्प हो गया कि क्या exportमदद करेगा। स्थापना प्रक्रिया makeलंबे समय तक जारी रहने के बावजूद , एक और त्रुटि हुई। इस बार, .so.0फ़ाइल नहीं मिली, लेकिन दोनों फ़ाइल .soऔर .so.0निर्देशिका में थे जहां मैंने स्रोत से आश्रित पैकेज का निर्माण किया है। क्या आप इसके साथ मदद कर सकते हैं?
ए। अमातोव

33

यदि यह विकल्प के साथ Makefile को बदलने के लिए उपयुक्त नहीं हो सकता है, तो परिभाषित के g++माध्यम से संकलन के दौरान । मैंने अपनी अतिरिक्त लाइब्रेरी को इसमें रखा था:makeLIBRARY_PATH-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

जब आप अपने कार्यक्रम को संकलित करते हैं, तो आपको पुस्तकालय को पथ की आपूर्ति करनी चाहिए; जी ++ में -L विकल्प का उपयोग करें:

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

1
हमें कौन सी संपत्ति में बदलाव करना है ccmakeताकि Makefileजुड़ा हुआ झंडा के साथ बनाया जाए ? मैं अपने -lARToolkitPlusझंडे को एक रास्ते से जोड़ना चाहता हूं ।
शशवत

2

यह त्रुटि इस बारे में भी हो सकती है कि क्या प्रतीकात्मक लिंक एक गतिशील पुस्तकालय, .so के लिए है, लेकिन -staticलिंक झंडे के बीच विरासत कारणों से दिखाई देता है। यदि ऐसा है, तो इसे हटाने का प्रयास करें।


2

अपने पुस्तकालय के स्थान की जाँच करें, उदाहरण के लिए lxxx.so:

locate lxxx.so

यदि यह /usr/libफ़ोल्डर में नहीं है, तो इसे टाइप करें:

sudo cp yourpath/lxxx.so /usr/lib

किया हुआ।


4
आपको लाइब्रेरी को सिस्टम निर्देशिका में कॉपी करने में सावधानी बरतने की आवश्यकता है।
पॉल फ्लॉयड

2

पहले से दिए गए उत्तरों के अलावा, यह भी मामला हो सकता है कि * .so फ़ाइल मौजूद है लेकिन ठीक से नाम नहीं दिया गया है। या यह मामला हो सकता है कि * .so फ़ाइल मौजूद है, लेकिन यह किसी अन्य उपयोगकर्ता / रूट के स्वामित्व में है।

अंक 1: अनुचित नाम

यदि आप फ़ाइल को लिंक कर रहे हैं -l<nameOfLibrary> तो लाइब्रेरी फ़ाइल का नाम फॉर्म का होना चाहिए। lib<nameOfLibrary> यदि आपके पास केवल <nameOfLibrary>.soफ़ाइल है, तो उसका नाम बदलें!

अंक 2: गलत मालिक

यह सत्यापित करने के लिए कि यह समस्या नहीं है - करते हैं

ls -l /path/to/.so/file

यदि फ़ाइल रूट या किसी अन्य उपयोगकर्ता के स्वामित्व में है, तो आपको करने की आवश्यकता है

sudo chown yourUserName:yourUserName /path/to/.so/file

1

जिस लाइब्रेरी को मैं एक गैर-मानक नाम से जोड़ने की कोशिश कर रहा था (यानी 'लिबास' के साथ उपसर्ग नहीं था), इसलिए उन्होंने इसे संकलित करने के लिए इस तरह की कमांड का उपयोग करने की सिफारिश की -

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


केवल "लिब" के साथ एक मानक नाम प्राप्त करने के लिए प्रीफ़िक्स करना मेरे लिए तय है
el_technic0

1

यहाँ मेरे लैपटॉप की उबंटू जानकारी है।

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

मैं बूस्ट_फाइलसिस्टम और बूस्ट_सिस्टम के लिए .so फाइलों को खोजने के लिए फाइंड का उपयोग करता हूं

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

किया हुआ! पैकेज 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 को अपने लाइब्रेरी फ़ोल्डर में कॉपी किया है, जहां ld3 खोजने में विफल रहा।

के बाद मैं सभी 3, ldकाम करता है की नकल की ।


क्या आप यह कह सकते हैं कि कृपया "मेरे पुस्तकालय फ़ोल्डर" के अंतर्गत आपका क्या फ़ोल्डर है?
ए। अमातोव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.