2016-09-28 12 views
6

मैं "जीसीसी का परिचय" नामक पुस्तक पढ़ रहा हूं और कुछ स्पष्टीकरण चाहूंगा। पुस्तक इंगित करता है कि कोड के नीचे एक त्रुटि कारण होगा लेकिन जब मैं संकलन, यह बनाता है और पूरी तरह से चलाता है:स्थिर पुस्तकालयों के साथ जीसीसी लिंकिंग

#include <math.h> 
#include <stdio.h> 
int main (void) { 
    double x = sqrt (2.0); 
    printf ("The square root of 2.0 is %f\n", x); 
    return 0; 
} 

मैं किताब से बोली "इस स्रोत अकेले फ़ाइल से एक निष्पादन योग्य बनाने के लिए कोशिश कर रहा है लिंक चरण में एक त्रुटि देने के लिए संकलक का कारण बनता है: "

$ gcc -Wall calc.c -o calc 
/tmp/ccbR6Ojm.o: In function `main': 
/tmp/ccbR6Ojm.o(.text+0x19): undefined reference 
    to `sqrt' 

समाधान है कि इस पुस्तक देता है कि आप गणित पुस्तकालय 'libm.a लिए पथ शामिल करने की अपेक्षा की जाती है 'के रूप में इस प्रकार है:

$ gcc -Wall calc.c /usr/lib/libm.a -o calc 

यह पथ पुस्तकालयों है कि हम अपने कार्यक्रमों में उपयोग में बनाया करने के लिए निर्दिष्ट करने के लिए बहुत असुविधाजनक होगा। मैं अपने स्वयं के कस्टम पुस्तकालयों को पथ जोड़ने का कारण समझ सकता हूं, लेकिन libm.a जीसीसी में बनाया गया है। और हालांकि पुस्तक काफी पुरानी है (2004 में प्रकाशित), जीसीसी के अधिक आधुनिक संस्करणों के साथ क्या बदल गया है, ताकि हमें libm.a पर पथ शामिल करने की आवश्यकता न हो?

* अद्यतन *

मैंने देखा है कि इस सवाल का जवाब taskinoor द्वारा दिए गए कोड की आवश्यकता है कि है कि मैं -lm ध्वज का उपयोग करता है, तो() मान sqrt के लिए पारित संकलन समय पर नहीं जाना जाता है अद्यतन दर्शाता।

मैंने वीएस का उपयोग करके सी/सी ++ सीखा लेकिन मेरा लक्ष्य अब जीसीसी सीखना और उपयोग करना है। मेरे पास विजुअल स्टूडियो 2013 है और वीएस कंपाइलर/लिंकर इतना picky प्रतीत नहीं होता है। उदाहरण के लिए, मैं रहस्यमय कंपाइलर झंडे निर्दिष्ट किए बिना किसी भी साधारण कार्यक्रम के बारे में संकलित करने में सक्षम हूं। मैं

मैं जीसीसी संस्करण 5.4 कि Kubuntu 16.04.1

+4

सबसे पहले, एक अलग पुस्तक आज़माएं क्योंकि दशकों से, गणित पुस्तकालय को जोड़ने का मानक तरीका पुस्तकालय के पूर्ण पथ के बजाय -lm का उपयोग करना है। दूसरा, https://gcc.gnu.org/releases.html में रिलीज़ परिवर्तन शामिल हैं। –

+1

@ जॉन ग्रिफिन: एक ही पुस्तक से: * "कमांड लाइन पर लंबे पथ निर्दिष्ट करने की आवश्यकता से बचने के लिए, कंपाइलर पुस्तकालयों के खिलाफ जोड़ने के लिए एक शॉर्ट-कट विकल्प '-l' प्रदान करता है। उदाहरण के लिए, निम्न आदेश, ' $ gcc -Wall calc.c -lm -o calc' मूल कमांड के समतुल्य है ... "* –

+0

ध्यान दें कि इन दिनों डिफ़ॉल्ट डायनामिक लाइब्रेरी से लिंक करना है, न कि स्थिर पुस्तकालयों। शायद आप के बारे में पूछने के लिए क्या मतलब था * मानक * पुस्तकालयों से जुड़ा हुआ था? – Barmar

उत्तर

6

sqrt (2.0);

आधुनिक जीसीसी निर्धारित करने के लिए है कि आप एक निरंतर का वर्गमूल खोजने की कोशिश कर रहे हैं अच्छी तरह से करने में सक्षम है और इस तरह यह है संकलन समय में गणना करने में सक्षम है। आपके ऑब्जेक्ट कोड में sqrt पर वास्तविक कॉल नहीं है।

यदि आप एक चर का उपयोग करते हैं जो scanf के माध्यम से इनपुट पर इनपुट है तो यह libm के बिना लिंक नहीं होगा।

int main() { 
    double x; 

    scanf("%lf", &x); 
    printf("%lf\n", sqrt(x)); 

    return 0; 
} 

libm बिना जीसीसी 4.8.4 उबंटू 14 पर।04 इस परिणाम:

/tmp/ccVO2fRY.o: In function `main': 
sqrt.c:(.text+0x2c): undefined reference to `sqrt' 
collect2: error: ld returned 1 exit status 

लेकिन अगर मैं x अपने उदाहरण की तरह के बजाय एक निरंतर डाल तो यह libm बिना ठीक से जोड़ता है।

पीएस: जब मैं जीसीसी ऐसा करने में सक्षम हूं तब से मुझे सटीक संस्करण नहीं पता है। उम्मीद है कि कोई और उस पर इंगित कर सकता है।

+0

दिलचस्प ... मुझे इसे देखना होगा ... –

+0

मुझे लिनक्स पर भी यह त्रुटि मिलती है, लेकिन ओएस एक्स – Barmar

+0

@ बाड़मेर नो पर कोई त्रुटि नहीं है ओएस एक्स पर वेरिएबल्स के साथ लिंकर त्रुटि जिसे संकलित समय पर हल नहीं किया जा सकता है? क्षमा करें, मुझे ओएस एक्स के बारे में पता नहीं है। शायद कुछ और चल रहा है। – taskinoor

2

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

बेशक

, इस बल्कि स्थिर जोड़ने से गतिशील के लिए आम तौर पर है ...

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