मेरे सॉफ़्टवेयर में सामान्य उपयोग के लिए एक मुख्य और यूनिट परीक्षणों के लिए एक अलग है। यदि मैं निर्दिष्ट करने के लिए "मुख्य" फ़ंक्शन निर्दिष्ट करने के लिए gcc का कोई विकल्प था तो मैं इसे बस पसंद करूंगा।क्या मुख्य नाम बदलने के लिए कोई जीसीसी कंपाइलर/लिंकर विकल्प है?
उत्तर
उन्हें अलग फ़ाइलों में रखें, और सामान्य उपयोग के लिए एक .c फ़ाइल निर्दिष्ट करें, और परीक्षण के लिए एक .c फ़ाइल निर्दिष्ट करें।
वैकल्पिक रूप से, कमांडलाइन परीक्षण का उपयोग पर #define
परीक्षण बनाता है और की तरह कुछ का उपयोग करें:
int main(int argc, char *argv[])
{
#ifdef TESTING
return TestMain(argc, argv);
#else
return NormalMain(argc, argv);
#endif
}
int TestMain(int argc, char *argv[])
{
// Do testing in here
}
int NormalMain(int argc, char *argv[])
{
//Do normal stuff in here
}
इसके अलावा, ओपी को केवल एफवाईआई, जीसीसी में तर्कों की सूची में केवल '-DTESTING' जोड़ें। –
प्रवेश बिंदु या स्ट्रिप - स्ट्रिप-प्रतीक –
@Alex के लिए उपयोग करने के लिए बेहतर है: "आप एक स्वीकृत उत्तर को हटा नहीं सकते हैं" :( –
संपादित करें: बिली मुझे जवाब देने के लिए हरा, लेकिन यहां थोड़ा और पृष्ठभूमि
अधिक सीधे है, मुख्य रूप से मानक पुस्तकालय का एक समारोह है। main
पर कॉल करने वाली चीज़ सी नहीं है, बल्कि मानक लाइब्रेरी है। ओएस एप्लिकेशन लोड करता है, पुस्तकालय के प्रवेश बिंदु (_start
जीसीसी में नियंत्रण) पर नियंत्रण स्थानांतरित करता है, और लाइब्रेरी अंततः main
पर कॉल करती है। यही कारण है कि एक विंडोज़ अनुप्रयोग के लिए प्रवेश बिंदु WinMain
हो सकता है, और सामान्य नहीं। एम्बेडेड प्रोग्रामिंग एक ही तरह की चीज हो सकती है। यदि आपके पास मानक लाइब्रेरी नहीं है, तो आपको उस प्रविष्टि बिंदु को लिखना होगा जो लाइब्रेरी सामान्य रूप से प्रदान करता है (अन्य चीजों के साथ), और आप इसे जो कुछ भी चाहते हैं उसका नाम दे सकते हैं।
जीसीसी टूलचेन में, आप -e
विकल्प का उपयोग करके लाइब्रेरी के एंट्री पॉइंट को अपने आप से बदल सकते हैं। (उस बात के लिए, आप भी पुस्तकालय पूरी तरह से निकाल सकते हैं।)
को अपनी बनाएं: आप ifdef
पसंद नहीं है, तो दो मुख्य मॉड्यूल है कि केवल मुख्य होते हैं लिखने
int main(int argc, char *argv[])
{
#if defined(BUILD_UNIT_TESTS)
return main_unittest(argc, argv);
#endif
#if defined(BUILD_RUNTIME)
return main_run(argc, argv);
#endif
}
। यूनिट परीक्षणों के लिए एक और दूसरे को सामान्य उपयोग के लिए लिंक करें।
मुझे लगता है कि आप मेक या कुछ इसी तरह का उपयोग कर रहे हैं। मैं दो फाइलें बनाउंगा जिनमें मुख्य फ़ंक्शन के विभिन्न कार्यान्वयन होते हैं, फिर मेकफ़ाइल में, दो अलग-अलग लक्ष्यों को परिभाषित करते हैं जिनके पास आपकी शेष फ़ाइलों पर समान निर्भरताएं होती हैं, सिवाय इसके कि कोई आपके "यूनिट टेस्ट मेन" का उपयोग करता है और दूसरा आपका "सामान्य मुख्य" "। कुछ इस तरह:
normal: main_normal.c file1.c file2.c
unittest: main_unittest.c file1.c file2.c
जब तक "सामान्य" लक्ष्य के रूप में makefile के शीर्ष के पास है, तो टाइप "बनाने के" डिफ़ॉल्ट रूप से यह चयन करेंगे। आपको अपने परीक्षण लक्ष्य को बनाने के लिए "अनजान बनाएं" टाइप करना होगा।
autotools –
+1 के साथ बनाता है: मैं इस दोनों दृष्टिकोणों को क्रैक करने की कोशिश करने के लिए इस दृष्टिकोण को काफी पसंद करता हूं वही मुख्य दिनचर्या है और प्रीप्रोसेसर परिभाषित करता है या लिंकर विकल्प उनके बीच स्विच करते हैं। –
#ifdef TESTING
int main()
{
/* testing code here */
}
#else
int main()
{
/* normal code here */
}
#endif
$ gcc -DTESTING=1 -o a.out filename.C#building for testing
$ gcc -UTESTING -o a.out filename.C#building for normal purposes
man gcc
मुझे डी और यू
इसका एकमात्र नकारात्मक पक्ष यह है कि आपको 'परिभाषित' के अंदर 'मुख्य' का पूरा कोड होना चाहिए ... कुछ आईडीई के कुछ सिंटैक्स रंग ग्रे होंगे सभी परीक्षण कोड (क्योंकि इसे सामान्य रूप से परिभाषित नहीं किया जाता है) जो काफी परेशान हो सकता है। –
आप मुख्य करने के लिए एक समारोह का नाम बदलने के मैक्रो का उपयोग कर सकते हैं पता चला है।
#ifdef TESTING
#define test_main main
#else
#define real_main main
#endif
int test_main(int argc, char *argv[]) { ... }
int real_main(int argc, char *argv[]) { ... }
यहाँ अन्य उत्तर काफी उचित हैं, लेकिन सख्ती से समस्या आप बोल वास्तव में जीसीसी के साथ एक नहीं है, बल्कि सी क्रम के साथ। आप -e
ध्वज ld
पर अपने प्रोग्राम में एक प्रविष्टि बिंदु निर्दिष्ट कर सकते हैं।मेरे प्रलेखन कहते हैं:
-e symbol_name
एक मुख्य निष्पादन के प्रवेश बिंदु निर्दिष्ट करता है। डिफ़ॉल्ट रूप से प्रविष्टि का नाम "प्रारंभ" होता है जो crt1.o में पाया जाता है जिसमें गोंद कोड को स्थापित करने और मुख्य() को कॉल करने की आवश्यकता होती है।
इसका मतलब है कि यदि आप चाहें तो आप प्रवेश बिंदु ओवरराइड कर सकते हैं, लेकिन आप ऐसा करने के लिए, एक सी कार्यक्रम आप अपने मशीन पर सामान्य रूप से चलाना चाहते हैं के लिए है कि चूंकि start
ओएस विशिष्ट सामान है कि सभी प्रकार की हो सकती नहीं चाहते हो सकता है आपके कार्यक्रम चलाने से पहले आवश्यक है। यदि आप अपना खुद का start
कार्यान्वित कर सकते हैं, तो आप जो भी चाहते हैं वह कर सकते हैं।
लिनक्स पर: 1) आपको जीसीसी के लिए 'नोस्टार्टफाइल' की भी आवश्यकता है, या फिर 'crt1.o' में 'मुख्य' अपरिभाषित होगा और यह लिंक नहीं करेगा 2) आपको एक स्पष्ट 'निकास() 'से बाहर निकलना होगा, या फिर' वापसी 'कहीं भी segfault 3 नहीं होगा)' argv' आपके लिए –
आप हो सकता है उन्हें प्रयोग करने के लिए अलग से ld
चलाने के लिए है, लेकिन ld कई (प्रवेश बिंदु भी शामिल है) आउटपुट फ़ाइल के पहलुओं को परिभाषित करने के scripts का समर्थन करता है।
सेटअप नहीं होगा लेकिन 'मुख्य' प्रविष्टि नहीं है बिंदु (कम से कम मो पर सेंट सिस्टम)। –
मैं अलग फ़ाइलों का उपयोग और परीक्षण के लिए बना देती हैं चाहते हैं और उत्पादन बनाता है, पर यदि आप एक का चयन करने
int test_main (int argc, char*argv[])
और
int prod_main (int argc, char*argv[])
तो संकलक विकल्पों के साथ एक फ़ाइल है या दूसरा मुख्य रूप से -Dtest_main=main
और -Dprod_main=main
शायद यह इंगित करने लायक है कि यदि आप किसी कारण से उत्पादन फ़ाइल में मुख्य नाम का नाम नहीं बदल सकते हैं (जैसा कि मेरे मामले में हुआ), तो आप-डी स्विच में प्रतीक नामों को स्वैप कर सकते हैं, यानी इसे '-Dmain = ignored_main' उत्पादन मुख्य संकलन करते समय। – ttreitlinger
सबसे पहले, आपके पास main
नामक दो फ़ंक्शन नहीं हो सकते हैं ompilation, तो या तो स्रोत विभिन्न फाइलों में हैं या आप सशर्त संकलन का उपयोग कर रहे हैं। किसी भी तरह से आपको दो अलग-अलग फाइलें मिलनी होंगी। इसलिए, आपको एक लिंकर विकल्प की आवश्यकता नहीं है; आप बस उस फ़ाइल को पास करते हैं जिसे आप तर्क के रूप में चाहते हैं।
यदि आपको यह पसंद नहीं है, तो आप dlopen()
के साथ main
को किसी भी ऑब्जेक्ट फ़ाइल से गतिशील रूप से खींचने के लिए फैंसी चीजें कर सकते हैं। मैं परिस्थितियों की कल्पना कर सकता हूं जहां यह उपयोगी हो सकता है — कहता है, आप यूनिट परीक्षणों के लिए व्यवस्थित दृष्टिकोण लेते हैं, बस उन्हें सभी निर्देशिका में रखें, और आपका कोड निर्देशिका चलाता है, प्रत्येक ऑब्जेक्ट फ़ाइल को पकड़ता है, गतिशील रूप से इसे लोड करता है, और इसके परीक्षण चलाता है। लेकिन शुरू करने के लिए, शायद कुछ आसान संकेत दिया गया है।
आप में उपयोग करते हैं LD "-e symbol_name"
(जहां symbol_name, अपने मुख्य कार्य है निश्चित रूप से) आप भी जरूरत "-nostartfiles"
अन्यथा "undefined reference to main"
की त्रुटि का उत्पादन किया जाएगा।
मुझे नहीं लगता कि इससे ओपी की समस्या में मदद मिलेगी। स्टार्ट फाइलों को छोड़कर आपको एक टूटे हुए वातावरण के साथ छोड़ दिया जाएगा जिसमें मानक लाइब्रेरी ठीक से काम नहीं करेगी। मुझे लगता है कि सिर्फ '-मेमेन' और इसी तरह की आवश्यकता है। –
मुझे आज भी यही समस्या थी: m1.c और m2.c दोनों में एक मुख्य कार्य था, लेकिन उन्हें जोड़ने और उनमें से एक चलाने की आवश्यकता थी। समाधान: उपयोगकर्ता पट्टी संकलन के बाद, लेकिन लिंक करने से पहले उनमें से एक से मुख्य प्रतीक दूर करने के लिए:
gcc -c m1.c m2.c; strip --strip-symbol main m1.o; gcc m1.o m2.o; ./a.out
एम 2 से मुख्य चलेंगे
gcc -c m1.c m2.c; strip --strip-symbol main m2.o; gcc m1.o m2.o; ./a.out
एम 1
से मुख्य चलेंगे पट्टी के बिना :
gcc - m1.c m2.c
m2.o: In function `main':
m2.c:(.text+0x0): multiple definition of `main'
m1.o:m1.c:(.text+0x0): first defined here
collect2: ld returned 1 exit status
- 1. क्या printf के लिए कोई विकल्प है?
- 2. क्या जीसीसी के विकल्प "-Wl, विकल्प" में विकल्प है
- 3. - जीसीसी के लिए स्टेटिक विकल्प?
- 4. क्या '#' + div_id के लिए कोई विकल्प है?
- 5. क्या जीसीसी में निर्यात नाम मैंगलिंग योजना को बदलने के लिए कुछ भी है?
- 6. svn नाम बदलने के बजाय प्रत्यक्ष नाम बदलने के लिए
- 7. नाम स्थान का नाम बदलने के बाद मुख्य विधि के लिए निर्दिष्ट 'WindowsFormsAplication1.Program' नहीं मिला
- 8. फ़ाइल नाम बदलने के लिए
- 9. सेमेक में जीसीसी के -विंडोज़ विकल्प के बराबर क्या है?
- 10. क्या जीसीसी में स्टडकॉल के लिए कोई समकक्ष है?
- 11. क्या XmlUnit के लिए कोई विकल्प हैं?
- 12. क्या jsPlumb के लिए कोई विकल्प हैं?
- 13. क्या emacs colorcheme बदलने के लिए कोई गाइड है?
- 14. क्या समाधान एक्सप्लोरर में फ़ाइल का नाम बदलने के लिए कोई विजुअल स्टूडियो कीबोर्ड शॉर्टकट है?
- 15. हाइचार्ट्स: श्रृंखला का नाम बदलने के लिए
- 16. जीसीसी विकल्प जो जीडीबी
- 17. जीसीसी -Wshadow विकल्प
- 18. एंड्रॉइड एप्लिकेशन का नाम बदलने के लिए
- 19. कैसे साजिश में मुख्य शीर्षक का फ़ॉन्ट बदलने के लिए()
- 20. मॉडल का नाम बदलने के लिए
- 21. नाम बदलने के लिए कैसे JSON कुंजी
- 22. क्या GDI GetPixel() के लिए कोई तेज विकल्प है?
- 23. क्या Google Analytics के लिए कोई तेज़ विकल्प है?
- 24. क्या रीडलाइन के लिए कोई आसान विकल्प है?
- 25. क्या Python sandboxing के लिए rexec का कोई विकल्प है?
- 26. क्या वेबएसवीएन के लिए कोई अच्छा विकल्प है?
- 27. क्या Runtime.getRuntime() के लिए कोई विकल्प है। Exec()
- 28. क्या एमएएमपी प्रो के लिए कोई मुफ्त विकल्प है?
- 29. क्या factory_girl के लिए कोई अच्छा विकल्प है?
- 30. क्या लिनक्स सिस्टम के लिए जीडीबी का कोई विकल्प है?
क्या यह एक कंपाइलर पास के साथ किया जा सकता है? यानी "मेक-डी परीक्षण के बिना; साफ करें; बनाना"? मुझे "उसी कोड" को शिपिंग में कुछ आराम मिलता है जिसे मैंने परीक्षण किया था। –
आपको केवल उस फ़ाइल के लिए '-D' की आवश्यकता है जिसमें आपके मुख्य भाग हों। मेरे पास एक मेकफ़ाइल होगा जो मुख्य फ़ाइल को दो बार समेत बनाता है (एक बार बिना और एक बार-डी ... ध्यान दें कि इसे दो अलग-अलग आउटपुट फ़ाइल नामों के साथ संकलित करना होगा)। फिर इसे दो बार एक साथ लिंक करें: परीक्षण के निर्माण के लिए, एक बार सामान्य निर्माण के लिए। – mschaef