c++ एक्ज़िक्यूटेबल बनाम ऑब्जेक्ट्स को लिंक करते समय जीएनयू लिंड को अलग-अलग क्यों हल करता है?




gcc linker (2)

मेरे प्रश्न का सीधा जवाब --[no-]allow-shlib-undefined विकल्प को एलडी में है, मुझे लगता है। मैन पेज से:

डिफ़ॉल्ट व्यवहार साझा पुस्तकालयों में संदर्भित किसी भी अनिर्धारित प्रतीकों की त्रुटियों की रिपोर्ट करना है, यदि लिंकर का उपयोग निष्पादन योग्य बनाने के लिए किया जा रहा है, लेकिन उन्हें साझा करने के लिए लिंकर का उपयोग साझा लाइब्रेरी बनाने के लिए किया जा रहा है।

इसलिए, जब मैं-साझा किए गए के साथ निर्माण करता हूं, boost_system में प्रतीकों को अनिर्धारित नहीं किया जाता है, लेकिन ld का डिफ़ॉल्ट व्यवहार ध्यान नहीं देता। यह देखभाल करने के लिए कहा जा सकता है:

$ g++ -fPIC -shared -Wl,--no-allow-shlib-undefined -o test test.cc -lboost_timer
/usr/bin/ld: /tmp/cc6j1de3.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv'
/usr/lib/libboost_system.so.1.54.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

इसी तरह, हम इसे निष्पादन योग्य बनाने पर ध्यान न दें:

$ g++ -Wl,--allow-shlib-undefined -o test test.cc -lboost_timer
/tmp/ccUHoCIU.o: In function `__static_initialization_and_destruction_0(int, int)':
test.cc:(.text+0x7a): undefined reference to `boost::system::generic_category()'
test.cc:(.text+0x86): undefined reference to `boost::system::generic_category()'
test.cc:(.text+0x92): undefined reference to `boost::system::system_category()'
collect2: error: ld returned 1 exit status

लेकिन उन प्रतीकों को परिभाषित करने में सक्षम होने के बिना द्विआधारी विफल हो जाता है

सही दिशा में मुझे इंगित करने के लिए धन्यवाद @ चार्ल्स बेली!

मेरे पास C ++ कोड का एक तुच्छ टुकड़ा है जो ऐसा कुछ दिखता है:

#include <boost/timer/timer.hpp>

int main(void) {
    boost::timer::auto_cpu_timer t;
    return 0;
}

मैंने इसे संकलित और लिंक करने की कोशिश की (जीसीसी 4.8.1 और जीएनयू लिंडीन 2.23.52.20130828 के साथ) निम्नानुसार है:

$ g++ -o test test.cc -lboost_timer
/usr/bin/ld: /tmp/cc2jP1jv.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv'
/usr/lib/libboost_system.so.1.54.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

एक समाधान स्पष्ट रूप से कमांड लाइन पर -lboost_system उल्लेख -lboost_system , और यह काम करता है। हालांकि, मैं यह भी कर सकता हूँ:

$ g++ -Wl,--copy-dt-needed-entries -o test test.cc -lboost_timer

एलडी प्रलेखन के अनुसार "कमांड लाइन पर वर्णित --कॉपी-डीटी-आवश्यक-प्रविष्टियों गतिशील लाइब्रेरीज को पुनः डायरेक्टरी लाइब्रेरीज़ की खोज की जाएगी, उनके डीटीएनडीईड टैग को अन्य पुस्तकालयों के अनुसार, आउटपुट द्विआधारी द्वारा आवश्यक प्रतीकों को हल करने के लिए," सभी समझ में आता है: ld boost_timer से पता लगा रहा है कि यह सभी संकेतों को हल करने के लिए boost_system के खिलाफ लिंक करने की आवश्यकता है

हालांकि, मुझे एहसास हुआ कि यह भी काम करता है:

$ g++ -fPIC -shared -o test test.cc -lboost_timer

जाहिर है, मैंने अब निष्पादन योग्य के बजाय एक साझा वस्तु उत्पन्न की है। जाहिर है, हालांकि, एलडी इसे समझने में सक्षम था कि इसे साझा किए गए ऑब्जेक्ट को boost_system के खिलाफ लिंक करने की आवश्यकता है:

$ ldd test | grep boost_system
        libboost_system.so.1.54.0 => /usr/lib/libboost_system.so.1.54.0 (0x00007f385246e000)

तो मेरा सवाल यह है: एक निष्पादन योग्य बनाम साझा वस्तु बनाते समय प्रतीक संकल्प अलग क्यों होता है? एलडी कैसे यह समझाने में सक्षम है कि मेरी साझा ऑब्जेक्ट को boost_system के विरूद्ध लिंक किया जाना चाहिए बिना मेरे निर्दिष्ट- --copy-dt-needed-entries ?


कलेक्ट 2 कमांड में मतभेद हैं जो प्रासंगिक हो सकते हैं। विभिन्न आदेशों की तुलना http://imgur.com/eMr2tY2 पर की जाती है दाहिनी ओर से साझा लाइब्रेरी (-फिपिक-शेयर्ड) बनाता है, बाएं सामान्य संकलन है।





binutils