2008-09-27 14 views
7

मुझे अपने कंपाइलर के साथ कोई समस्या है, मुझे बता रहा है कि एक लाइब्रेरी में एक फ़ंक्शन का उपयोग करने के लिए एक 'अनिर्धारित संदर्भ' है।लिंकर दुःख - अपरिभाषित संदर्भ

  • मैं सी
  • के लिए जीसीसी के साथ पार संकलन
  • मैं जो एक शामिल हैडर जो एक और शीर्ष लेख, जो प्रोटोटाइप शामिल होता माध्यम से पहुँचा है एक पुस्तकालय समारोह बोल रहा हूँ कर रहा हूँ: मुझे इस समस्या पर कुछ जानकारी साझा करते हैं ।
  • मैंने -इ का उपयोग करके हेडर निर्देशिका शामिल की है और मुझे यकीन है कि यह पाया जा रहा है।
  • मैं पहले .o फाइलें बना रहा हूं और फिर उन्हें एक अलग कमांड में जोड़ रहा हूं।

तो मेरा विचार यह है कि यह ऑर्डर हो सकता है जिसमें मैं लाइब्रेरी फाइलें शामिल करता हूं, लेकिन मुझे यकीन नहीं है कि उन्हें आदेश देने का सही तरीका क्या है। मैंने .o फ़ाइल के पहले और बाद में हेडर फ़ोल्डर को शामिल करने का प्रयास किया।

कुछ सुझाव महान होंगे, और शायद यह और स्पष्टीकरण कि लिंकर इसकी बात कैसे करता है।

धन्यवाद!


जवाब

  • के जवाब कोई .a पुस्तकालय फ़ाइल है, बस ज और पुस्तकालय में ग, तो -l उचित
  • एक पुस्तकालय फ़ाइल की मेरी समझ नहीं है यह है कि यह केवल हेडर और स्रोत फ़ाइलों का संग्रह है, लेकिन हो सकता है कि यह स्रोत से बनाई गई .o फ़ाइलों का संग्रह हो ?!
  • कोई लाइब्रेरी ऑब्जेक्ट फ़ाइल नहीं बनाई जा रही है, शायद वहां होना चाहिए ?? हां लगता है कि मैं शामिल और पुस्तकालयों के बीच अंतर को समझ नहीं पा रहा हूं ... मैं उस पर काम करूंगा :-)

सभी प्रतिक्रियाओं के लिए धन्यवाद! मैंने पुस्तकालयों के बारे में बहुत कुछ सीखा। मैं सभी प्रतिक्रियाओं को स्वीकृत उत्तर के रूप में रखना चाहता हूं :-)

उत्तर

5

ऐसा लगता है कि आप .o फ़ाइल बनाने के लिए लाइब्रेरी में .c फ़ाइल को संकलित नहीं कर रहे हैं। लिंकर लाइब्रेरी

संकलित करके उत्पादित .o फ़ाइल में प्रोटोटाइप के कार्यान्वयन की तलाश करेगा। क्या आपकी बिल्ड प्रक्रिया लाइब्रेरी .c फ़ाइल संकलित करती है?

यदि आप वास्तव में केवल स्रोत कोड हैं तो आप इसे "लाइब्रेरी" क्यों कहते हैं?

0

मुझे लगता है कि आपको उस पथ को जोड़ना होगा जहां लिंकर लाइब्रारे ढूंढ सकता है। जीसीसी/एलडी में आप -एल और लाइब्रारे के साथ -l के साथ ऐसा कर सकते हैं।

-Ldir, --library-पथ = मानक खोज निर्देशिका से पहले dir

खोजें निर्देशिका निर्देशिका (इस विकल्प -l विकल्प है कि कि निर्देशिका खोज पूर्व में होना चाहिए)।

-larch, --library = संग्रह

लिंक करने के लिए फ़ाइलों की सूची में संग्रह फ़ाइल मेहराब को शामिल करें। उत्तर देने के लिए


प्रतिक्रिया - कोई .a पुस्तकालय फ़ाइल है, बस ज और पुस्तकालय में ग, तो -l

तो फिर तुम हो सकता है approriate नहीं है पहले पुस्तकालय बनाने के लिए?

gcc -c mylib.c -o mylib.o 
ar rcs libmylib.a  mylib.o 
4

हेडर फ़ंक्शन घोषणाएं और कार्य परिभाषाएं प्रदान करते हैं। लिंकर को फ़ंक्शन के कार्यान्वयन को ढूंढने की अनुमति देने के लिए (और अपरिभाषित संदर्भ से छुटकारा पाएं) आपको विशिष्ट लाइब्रेरी को लिंक करने के लिए कंपाइलर ड्राइवर (जीसीसी) से पूछने की आवश्यकता है जहां फ़ंक्शन -एल ध्वज का उपयोग करके रहता है। उदाहरण के लिए, -एमएम गणित पुस्तकालय को लिंक करेगा। फ़ंक्शन का मैन्युअल पृष्ठ आमतौर पर निर्दिष्ट करता है कि फ़ंक्शन को ढूंढने के लिए कौन सी लाइब्रेरी, यदि कोई है, निर्दिष्ट किया जाना चाहिए।

यदि लिंकर निर्दिष्ट लाइब्रेरी नहीं ढूंढ सकता है तो आप -L स्विच (उदाहरण के लिए, -एल/​​usr/local/lib) का उपयोग करके लाइब्रेरी खोज पथ जोड़ सकते हैं। आप LIBRARY_PATH पर्यावरण चर के माध्यम से लाइब्रेरी पथ को स्थायी रूप से प्रभावित भी कर सकते हैं।

आपकी समस्या को डीबग करने में आपकी सहायता के लिए यहां कुछ अतिरिक्त विवरण दिए गए हैं। सम्मेलन द्वारा पुस्तकालय फ़ाइलों के नाम lib के साथ prefixed हैं और (उनके स्थिर रूप में) एक। ए एक्सटेंशन है। इस प्रकार, सिस्टम की डिफ़ॉल्ट गणित लाइब्रेरी (जिसे आप -lm से लिंक करते हैं) का सांख्यिकीय रूप से लिंक किया गया संस्करण आमतौर पर /usr/lib/libm.a में रहता है। यह देखने के लिए कि किसी दिए गए लाइब्रेरी को कौन से प्रतीक परिभाषित करते हैं, आप केवल पुस्तकालय फ़ाइल पर एनएम - डिफाईन चला सकते हैं। मेरे सिस्टम पर, libm.a पर कमांड चलाने से मुझे निम्न की तरह आउटपुट मिलता है।

e_atan2.o: 
00000000 T atan2 

e_asinf.o: 
00000000 T asinf 

e_asin.o: 
00000000 T asin 

पुस्तकालय रास्ता है कि अपने संकलक का उपयोग करता है और जो पुस्तकालय यह डिफ़ॉल्ट रूप से लोड करता है आप -v विकल्प के साथ जीसीसी आह्वान कर सकते हैं देखने के लिए। फिर से मेरे सिस्टम पर यह निम्नलिखित आउटपुट देता है।

GNU assembler version 2.15 [FreeBSD] 2004-05-23 (i386-obrien-freebsd) 
using BFD version 2.15 [FreeBSD] 2004-05-23 
/usr/bin/ld -V -dynamic-linker /libexec/ld-elf.so.1 /usr/lib/crt1.o 
/usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib /var/tmp//ccIxJczl.o -lgcc -lc 
-lgcc /usr/lib/crtend.o /usr/lib/crtn.o 
+0

एक हेडर फ़ाइल (डिफ़ॉल्ट रूप से '.h') _can_ में किसी भी प्रकार का स्रोत शामिल है, लेकिन यह _strongly_ को मैक्रो परिभाषाओं और _declarations_ में कुछ भी जगह देने के लिए निराश किया गया है। – vonbrand

1

मुझे डर है कि आपने लाइब्रेरी और हेडर अवधारणाओं को मिश्रित किया है। मान लें कि आपके पास लाइब्रेरी libmylib.a है जिसमें फ़ंक्शन myfunc() और संबंधित हेडर mylib.h है जो इसके प्रोटोटाइप को परिभाषित करता है। आपकी स्रोत फ़ाइल myapp.c में आप हेडर को सीधे या अन्य हेडर समेत शामिल करते हैं जिसमें इसे शामिल किया गया है। उदाहरण के लिए:

/* myapp.h 
** Here I will include and define my stuff 
*/ 
... 
#include "mylib.h" 
... 

अपने स्रोत फ़ाइल की तरह दिखता है:

gcc -c -I../mylib/includes myapp.c 

ध्यान दें कि मैं सिर्फ जीसीसी जहां हेडर बताता है:

/* myapp.c 
** Here is my real code 
*/ 
... 
#include "myapp.h" 
... 
/* Here I can use the function */ 
myfunc(3,"XYZ"); 

अब आप प्राप्त करने के लिए myapp.o यह संकलन कर सकते हैं फाइलें हैं, उनके पास पुस्तकालय के साथ कुछ भी नहीं है! कि -L स्विच जीसीसी जहां पुस्तकालय है बताता है

gcc -o myapp -L../mylib/libs myapp.o -lmylib 

ध्यान दें, और -l यह पुस्तकालय के लिए अपने कोड से जोड़ने के लिए बताता है:

अब आप असली लाइब्रेरी के साथ अपने आवेदन लिंक कर सकते हैं।

यदि आप यह अंतिम चरण नहीं करते हैं, तो आपको बताई गई समस्या का सामना करना पड़ सकता है।

अन्य जटिल मामले हो सकते हैं लेकिन आपके प्रश्न से, मुझे उम्मीद है कि यह आपकी समस्या को हल करने के लिए पर्याप्त होगा।

1

अपनी मेकफ़ाइल पोस्ट करें, और लाइब्रेरी फ़ंक्शन जिसे आप कॉल करने का प्रयास कर रहे हैं। यहां तक ​​कि साधारण जीसीसी makefiles आम तौर पर इस तरह की एक पंक्ति है:

LIBFLAGS = -lc -lpthread -lrt -lstdC++ -lShared एल ../ साझा

इस मामले में, यह मानक सी पुस्तकालय लिंक, के बीच का मतलब अन्य

0

जीसीसी के नए संस्करण के साथ प्रोग्राम बनाने के दौरान मुझे इस समस्या का सामना करना पड़ा है। समस्या को gcc को -std = gnu89 विकल्प के साथ कॉल करके तय किया गया था। जाहिर है यह इनलाइन फ़ंक्शन घोषणाओं के कारण था। मुझे यह समाधान https://gcc.gnu.org/gcc-5/porting_to.html

संबंधित मुद्दे