मेरे पास एक सरल "हैलो वर्ल्ड!" c प्रोग्राम है, जिसका नाम मेरे डेस्कटॉप पर hello.c है:

#include <stdio.h>

int main() {
    printf("Hello world!\n");

    return 0;
}

मैं निम्नलिखित आदेश चलाता हूं।

  • मैं इसे इसके साथ पूर्व-संसाधित करता हूं: cpp hello.c> hello.i
  • मैं इसे इसके साथ संकलित करता हूं: gcc -S hello.i
  • मैं इसे इसके साथ इकट्ठा करता हूं: as -o hello.o hello.s

अब तक सब अच्छा। लेकिन, मैं इसे लिंक करने में असमर्थ हूं। मैंने कोशिश की है, अन्य आदेशों के बीच, ये:

ld -o hello.exe hello.o
ld -o hello.exe hello.o -lgcc
ld -o hello.exe hello.o -nostdlib -lgcc

कुछ भी काम नहीं करता है। हर एक मामले में मुझे मिलने वाली लिंक त्रुटियां हैं:

hello.o:hello.c:(.text+0x9): undefined reference to `__main'
hello.o:hello.c:(.text+0x15): undefined reference to `puts'

अंत में निष्पादन योग्य प्रोग्राम hello.exe उत्पन्न करने के लिए मैं इस इकट्ठे प्रोग्राम hello.o को कैसे लिंक कर सकता हूं? मुझे किसकी याद आ रही है? [विंडोज 8.1, मिंगव संस्करण 0.6.2 का उपयोग करना।] अग्रिम धन्यवाद।

4
KeyC0de 29 सितंबर 2016, 13:34
gcc -o hello.exe hello.c क्या करता है? "कुछ भी काम नहीं करता" एक त्रुटि स्थिति का बहुत उपयोगी विवरण नहीं है।
 – 
tofro
29 सितंबर 2016, 13:39
जीसीसी संकलक है। वह आदेश निष्पादन योग्य बनाने के लिए सभी काम करेगा। मैं कदम-कदम पर जा रहा था। अब मैं अंतिम चरण में हूं और मैं लिंकर (एलडी) से जुड़ना चाहता हूं।
 – 
KeyC0de
29 सितंबर 2016, 13:42
आप लिंक क्यों कर रहे हैं? क्या यहां कोई असेंबली फाइल है? और आपका समग्र लक्ष्य क्या है (असेंबली और सी फाइलों को जोड़ने के लिए?)?
 – 
amanuel2
29 सितंबर 2016, 13:44
@ amanuel2: असेंबली का इनमें से किसी से क्या लेना-देना है? आपको ऑब्जेक्ट कोड को लिंक करने की आवश्यकता है, भले ही इसे उत्पन्न करने वाली स्रोत भाषा कुछ भी हो। यह अच्छी तरह से सी हो सकता है।
 – 
IInspectable
29 सितंबर 2016, 13:46
मैंने उल्लेख किया है कि मैं क्या करना चाहता हूं। मैं निष्पादन योग्य बनाने के लिए hello.o को लिंक करना चाहता हूं। ऐसा नहीं है कि लिंकर को क्या करना है (सभी libs जमा करने के बाद)। वैसे नकारात्मक वोट क्यों?
 – 
KeyC0de
29 सितंबर 2016, 13:46

2 जवाब

सबसे बढ़िया उत्तर

भले ही स्पष्टीकरण प्रश्नों के आपके उत्तर विशेष रूप से उपयोगी न हों:

कुछ इस तरह का प्रयास करें

ld hello.o -lmsvcrt -entry=_main -subsystem=console -o hello.exe

यदि आप मानक जीसीसी द्वारा उपयोग की जाने वाली लिंकर कमांड लाइन देखना चाहते हैं, तो इस तरह जीसीसी का आह्वान करें:

gcc test.c -o test -Wl,-v

आखिरी लाइन आउटपुट वह है जिसका आपको उपयोग करना चाहिए ...

1
Clifford 28 मार्च 2021, 18:44
आउटपुट: ld: -lmsvcrt नहीं ढूंढ सकता। मुझे विश्वास नहीं हो रहा है कि यह इतना जटिल होना चाहिए। अभी तक ढुंढ रहा हूँ। अपडेट करेंगे।
 – 
KeyC0de
29 सितंबर 2016, 14:24
2
यह है इतना जटिल है। यदि आप जीसीसी, कंपाइलर फ्रंटएंड का उपयोग करते हैं, तो यह आपको उस जटिलताओं से राहत देगा। Mingw को MSC रनटाइम का उपयोग करने के लिए बनाया गया है। मेरी स्थापना में, libmsvcrt.a \MingW\lib में है - हो सकता है कि आपको उस dir की ओर -L जोड़ने की आवश्यकता हो जहां यह आपके पास है।
 – 
tofro
29 सितंबर 2016, 14:28
कंपाइलर फ्रंटएंड लिंकर को कैसे कॉल करता है, यह जानने के लिए उपरोक्त संपादन देखें।
 – 
tofro
29 सितंबर 2016, 15:41
तो, .. यदि हम वर्बोज़ फ्लैग -v निर्दिष्ट करते हैं, जैसा कि आपने बताया, हम टूलचैन द्वारा उपयोग किए जाने वाले सभी कमांड को तब तक देख सकते हैं जब तक कि यह निष्पादन योग्य न हो। और हाँ मुझे लिंकर (एलडी) को अंत में hello.exe फ़ाइल प्राप्त करने के लिए एक बड़ा आदेश निर्दिष्ट करना होगा। इसे हाथ से करना व्यावहारिक रूप से व्यर्थ है। हमारा सारा समय इसी में व्यतीत होगा। इसके बजाय ld कमांड को खोजना थोड़ा आसान होगा: gcc hello.o -o hello -v। यह hello.o ऑब्जेक्ट कोड को hello.exe में कनवर्ट करता है (यह केवल लिंकिंग करता है और संकलन नहीं करता है)। तो -v विकल्प जोड़कर हम देख सकते हैं। लिंकर कदम गन्दा है।
 – 
KeyC0de
29 सितंबर 2016, 18:23

यदि आप टूल के साथ प्रयोग करने के बजाय कुछ संकलित करना चाहते हैं, तो उसे सीधे लिंकर का उपयोग करके लिंक न करें। जीसीसी का प्रयोग करें, जो आपके लिए लिंकर को सही विकल्पों के साथ कॉल करेगा:

चरण संकलित करें:

gcc -c hello.c

लिंक चरण:

gcc -o hello.exe hello.o

या सभी एक में:

gcc -o hello.exe hello.c

आप एक साधारण मेकफ़ाइल का भी उपयोग कर सकते हैं, फिर make चला सकते हैं:

all: hello.exe
1
Sam Watkins 9 अक्टूबर 2021, 15:23