2010-07-01 18 views
7

जीसीसी के साथ संकलन/लिंकिंग प्रक्रिया को समझने के मेरे प्रयास में यह मेरी दूसरी पोस्ट है। जब मैं निष्पादन योग्य बनाने की कोशिश करता हूं, लिंक समय पर प्रतीकों को हल करने की आवश्यकता होती है, लेकिन जब मैं साझा लाइब्रेरी बनाने का प्रयास करता हूं, तो इस लाइब्रेरी के लिंक समय पर प्रतीक हल नहीं होते हैं। जब मैं इस साझा लाइब्रेरी का उपयोग करके निष्पादन योग्य बनाने की कोशिश कर रहा हूं तो उन्हें शायद हल किया जाएगा। हाथों पर:लिंक समय पर साझा लाइब्रेरी के प्रतीकों का समाधान क्यों नहीं किया जाता है?

bash$ cat printhello.c 
#include <stdio.h> 
//#include "look.h" 

void PrintHello() 
{ 
look(); 
printf("Hello World\n"); 
} 

bash$ cat printbye.c 
#include <stdio.h> 
//#include "look.h" 

void PrintBye() 
{ 
look(); 
printf("Bye bye\n"); 
} 

bash$ cat look.h 
void look(); 

bash$ cat look.c 
#include <stdio.h> 

void look() 
{ 
printf("Looking\n"); 
} 

bash$ gcc printhello.c printbye.c 
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crt1.o: In function `_start': 
(.text+0x18): undefined reference to `main' 
/tmp/cck21S0u.o: In function `PrintHello': 
printhello.c:(.text+0x7): undefined reference to `look' 
/tmp/ccNWbCnd.o: In function `PrintBye': 
printbye.c:(.text+0x7): undefined reference to `look' 
collect2: ld returned 1 exit status 

bash$ gcc -Wall -shared -o libgreet printhello.c printbye.c 
printhello.c: In function 'PrintHello': 
printhello.c:6: warning: implicit declaration of function 'look' 
printbye.c: In function 'PrintBye': 
printbye.c:5: warning: implicit declaration of function 'look' 

तो मेरे सवाल यही वजह है कि इसका समाधान नहीं किया जब मैं एक शेयर की गई लाइब्रेरी जोड़ने हूँ प्रतीक हैं। जब मैं इस लाइब्रेरी को निष्पादन योग्य बनाने के लिए उपयोग करूंगा, तो यह काम (डाउनस्ट्रीम के प्रतीकों को हल करने) की आवश्यकता होगी, लेकिन इसका मतलब है कि हमें यह जानने की जरूरत है कि इस पुस्तकालय का उपयोग करते समय यह पुस्तकालय किस पर निर्भर करता है, लेकिन क्या यह अवांछनीय नहीं है?

धन्यवाद, Jagrati

उत्तर

6

-z defs जोड़ने जब निर्माण पुस्तकालय तुम क्या चाहते हो रहा है? यदि नहीं, तो एलडी मैन पेजों की जांच करें, अपरिभाषित प्रतीकों के संचालन पर कुछ विकल्प हैं।

0

जुड़ा हुआ जानने का कोई तरीका नहीं है, ELF में कम से कम है, जहां प्रतीक हैं (अर्थात जो में पुस्तकालय)। दूसरी ओर, ओएस एक्स में, आपको पुस्तकालयों को आपके द्वारा वर्णित तरीके से लिंक करने की आवश्यकता है। अंत में, यह डिजाइन का सवाल है। एक और अधिक लचीला है, दूसरा, अधिक कठोर।

+0

यह क्यों डाउनवॉट किया गया था? ध्यान दें कि ओएसएक्स पर आप अन्य ऑपरेटिंग सिस्टम जैसे व्यवहार करने के लिए '-flat_namespace' विकल्प का उपयोग कर सकते हैं। लिनक्स। – Troubadour

0

जब भी आप साझा लाइब्रेरी बनाते हैं तो इसे सभी निर्भरताओं को हल करना होगा।

इस प्रकार एक साझा पुस्तकालय संकलन समय यह जानता है कि क्या अन्य साझा पुस्तकालयों रनटाइम पर लोड करने के लिए इतना है कि यह अन्य निर्भरता हल कर सकते हैं पर लोड किया जाता है जब।

1) एक साझा (देखो बनाएँ। < sharedLib>) देखो()
2) एक साझा (Hg बिल्ड के साथ पुस्तकालय। < sharedLib>) नमस्ते() अलविदा() नज़र के खिलाफ कड़ी के साथ पुस्तकालय। < साझा लिब>
3) मुख्य() के साथ एप्लिकेशन बनाएं जो एचजी के खिलाफ लिंक है। < sharedlib>

क्रम आवेदन तो एचजी लोड होगा पर। < साझालिब> जो साझा लाइब्रेरी लुक को लोड करेगा। < sharedlib>

2

मुझे लगता है कि लिंकर विकल्प -Bsymbolic आप जो खोज रहे हैं है।

+0

अपने आप से पर्याप्त नहीं है। मेरे पास यहाँ एक-बिस्मिबॉलिक साझा है जो रन-टाइम पर बारफ है। – Kaz

0

एक निष्पादन योग्य को entry point की आवश्यकता होती है। लेकिन एक साझा लाइब्रेरी प्रविष्टि बिंदु के बिना बनाया जा सकता है और बाद में निष्पादन योग्य इस साझा पुस्तकालय के साथ संकलित किया जा सकता है।

3

आप समझते हैं कि आप क्या संकलक ड्राइवर (जीसीसी) के पहले आदेश में करने के लिए कहा नहीं है। चूंकि आपने -c (केवल संकलन) विकल्प नहीं दिया है, इसलिए आपने दो स्रोत फ़ाइलों को संकलित करने के लिए जीसीसी से अनुरोध किया है और उन्हें मानक लाइब्रेरी (libc) और सी रन-टाइम स्टार्टअप (crt0, आमतौर पर) को चलाने के लिए लिंक करने का अनुरोध किया है कार्यक्रम। crt0 मुख्य() को कॉल करके अपने प्रोग्राम में प्रवेश करने का प्रयास करता है, जो कि अनिश्चित प्रतीक है जो लिंकर नहीं ढूंढ सकता है। यह नहीं मिल रहा है क्योंकि आपके पास आपकी .c फ़ाइलों में से कोई भी मुख्य() नहीं है, है ना?

तो, अपने वास्तविक सवाल है, के लिए पर "क्यों किसी साझा लाइब्रेरी के प्रतीक लिंक समय में समाधान नहीं होता?" जवाब यह है कि, "लिंक समय" से आपका क्या मतलब है? निश्चित रूप से, गतिशील रूप से जुड़े प्रोग्राम "लिंक" नहीं होता है जब तक कि यह शुरू नहीं होता है (या शायद तब भी नहीं, आपके सिस्टम के आधार पर।)

लिनक्स सिस्टम पर, आप देख सकते हैं कि कौन सा गतिशील पुस्तकालय एक प्रोग्राम ldd कमांड (मैक ओएस उपयोग 'otool -L' पर निर्भर करता है) पर निर्भर करता है। Ldd का आउटपुट आपको बताएगा कि कौन सा गतिशील पुस्तकालय एक प्रोग्राम पर निर्भर करता है, जहां लाइब्रेरी खोज पथ में पाया जाता है, और कौन से नहीं मिल सकते हैं (यदि कोई हो)।

जब आप गतिशील प्रोग्राम शुरू होता है, उसमें डायनामिक लिंकर जो उसमें जुड़ा हुआ था, गतिशील पुस्तकालयों को रेखांकित करता है और लोड करता है, प्रोग्राम बाहरी प्रतीकों के संदर्भों को संदर्भित करता है और "ठीक करता है"। यदि इनमें से कोई भी असफल हो जाता है, तो आपका प्रोग्राम शुरू करने में विफल रहेगा। पहले सभी अनसुलझे प्रतीकों का समाधान किया गया है, गतिशील लिंकर रिटर्न और सी रनटाइम आपके मुख्य() फ़ंक्शन को कॉल करेगा। (यह मैक ओएस पर कुछ अलग है, लेकिन असल में, आपके प्रोग्राम शुरू होने के बाद लिंकिंग होती है।)

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