2012-03-21 29 views
10

मेरे पास परियोजनाओं का संग्रह है जो मैं गतिशील पुस्तकालयों के रूप में संकलित कर रहा हूं। इनमें से प्रत्येक .dylibs अन्य विभिन्न ddibibs पर निर्भर करता है जिसे मैं विभिन्न अन्य निर्देशिकाओं में रखना चाहता हूं (यानी कुछ निष्पादन योग्य पथ पर, कुछ लोडर पथ पर, कुछ निश्चित पथ पर)।रन पथ, खोज पथ, और नाम स्थापित करने के लिए सही तरीके से सेट कैसे करें?

जब मैं संकलित पुस्तकालयों पर otool -L चलाता हूं, तो मुझे उन निर्भरताओं के पथों की एक सूची मिलती है लेकिन मुझे पता है कि ये पथ कैसे सेट/निर्धारित किए जा रहे हैं। वे लगभग छद्म यादृच्छिक दिखाई देते हैं। मैंने इन पथों (w/@rpath, @executable_path, @loader_path, आदि) को आजमाने और बदलने के लिए एक्सकोड में "बिल्ड सेटिंग्स" के साथ गड़बड़ करने में घंटों बिताए हैं, लेकिन मुझे कुछ भी बदलने की प्रतीत नहीं होती है (जैसा कि otool -L चलाकर चेक किया गया है)। - "गतिशील लाइब्रेरी स्थापित नाम"
लिंकिंग - "Runpath खोजें पथ

लिंकिंग: मैं भी पूरी तरह से जहां इन झंडे को जोड़ने के लिए और वास्तव में निम्नलिखित या कैसे ठीक उन्हें इस्तेमाल करने के बीच का अंतर समझ में नहीं आता यकीन नहीं है "
लिंकिंग -" अन्य लिंक करना झंडे "
खोजें पथ -" लाइब्रेरी खोज पथ "

जब मैं विभिन्न पुस्तकालयों पर install_name_tool -change चलाने के लिए, मैं के रूप में चल द्वारा सत्यापित सफलतापूर्वक चलाने के पथ खोज पथ (पुन: परिवर्तित करने में सक्षम हूँ पुष्टि करने के लिए otool -L)।

मैं एक्सकोड 4.2 चला रहा हूं और मैं छोड़ने के लिए बहुत करीब हूं और केवल पोस्ट-बिल्ड स्क्रिप्ट का उपयोग कर रहा हूं जो परिवर्तन करने के लिए install_tool_name चलाता है। लेकिन यह एक क्लज हैक फिक्स और मैं इसे नहीं करना पसंद करूंगा।

मैं कहां देख सकता हूं कि डायलीब निर्भरताओं के लिए खोज/रन पथ कैसे सेट किए जा रहे हैं?
किसी के पास कोई विचार है कि मैं क्या गलत कर रहा हूं?

उत्तर

10

आमतौर पर, मेरे डिलिब के लक्ष्य में, मैंने INSTALL_PATH उर्फ ​​"स्थापना निर्देशिका" को उपसर्ग (उदा। @executable_path/../Frameworks) पर सेट किया है।

मैं LD_DYLIB_INSTALL_NAME उर्फ ​​"डायनामिक लाइब्रेरी इंस्टॉल नाम" को अपने डिफ़ॉल्ट मान पर सेट करता हूं, जो $(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH) है।

एक्सकोड आपके लक्ष्य के नाम पर आधारित है, इसलिए यह @executable_path/../Frameworks/MyFramework.framework/Versions/A/MyFramework हो सकता है, उदाहरण के लिए।

यह समझने की महत्वपूर्ण बात यह है कि स्थापित पथ में अपनी बिल्ड प्रक्रिया के हिस्से के रूप में डाइलिब में बनाया गया है। बाद में, जब आप B.dylib को लिंक करते हैं जो A.dylib को संदर्भित करता है, A.dylib का इंस्टॉल पथ B.dylib में कॉपी किया गया है। (यही otool आपको दिखा रहा है - उन इंस्टॉल किए गए पथों की प्रतिलिपि बनाई गई है।) तो पहले स्थान पर डाइलिब में निर्मित सही इंस्टॉल पथ प्राप्त करना सबसे अच्छा है।

सभी dylibs एक साथ काम करने की कोशिश करने से पहले, प्रत्येक को व्यक्तिगत रूप से जांचें। इसे निर्मित करें, फिर निर्मित dylib पर otool -L। प्रत्येक आर्किटेक्चर के लिए पहली पंक्ति LD_DYLIB_INSTALL_NAME आपको दिखा रही थी।

एक बार जब आप संगठित हो जाते हैं, तो एक दूसरे के खिलाफ डाइलीब को जोड़ने का प्रयास करें। यह बहुत अधिक सरल होना चाहिए।

+3

हालांकि नहीं सटीक उत्तर मैं खोज रहा था, यह मुझे मेरी समस्या की पहचान करने में मदद की। 'otool -L' सभी इंस्टॉल नाम सूचीबद्ध करता है। सूचीबद्ध पहला 'इंस्टॉल नाम' लाइब्रेरी का ही है। सूचीबद्ध किसी भी अतिरिक्त पथ इसकी निर्भरताओं के लिए हैं। मान लें कि आपने स्रोत से निर्भरताओं को संकलित किया है, एक्सकोड में "गतिशील लाइब्रेरी इंस्टॉल नाम" सेट करना इन पथों को सही ढंग से सेट करेगा। हालांकि मेरे मामले में, निर्भरता तीसरे पक्षों से हैं इसलिए पथ पहले ही सेट किए गए थे। चूंकि मेरे पास तीसरे पक्ष के पुस्तकालयों के संकलन पर कोई नियंत्रण नहीं है, इसलिए मुझे 'install_name_tool -change' का उपयोग करने के लिए मजबूर होना पड़ता है। – BigMacAttack

+0

खुशी है कि आपने इसे समझ लिया। –

+2

बहुत उपयोगी उत्तर .. – Ahmed

1

install_name_tool नाम और पथ की स्थापना के लिए बहुत उपयोगी है। यह विशेष रूप से उपयोगी है यदि प्रोग्राम बिल्ड निर्देशिका में स्वयं परीक्षण करता है, और फिर make install के दौरान चीजें बदलती हैं।इस मामले में, आप एक अलग निर्माण की आवश्यकता के बिना install_name_tool का उपयोग कर सकते हैं।

install_name_tool भी उपयोगी है क्योंकि ऐप्पल का एलडी rpath लिनक्स/जीसीसी जैसे लिंकर विकल्पों का सम्मान नहीं करता है। यही है, आपको उन्हें सेट करने के लिए कमांड के एक अलग सेट का उपयोग करने की आवश्यकता है।

यहां इसके लिए मैन पेज है। इसकी पूरी तरह से शामिल है क्योंकि यह अन्य विकल्पों पर चर्चा करता है, जैसे -headerpad_max_install_names

INSTALL_NAME_TOOL(1)          INSTALL_NAME_TOOL(1) 

NAME 
     install_name_tool - change dynamic shared library install names 

SYNOPSIS 
     install_name_tool [-change old new ] ... [-rpath old new ] ... 
     [-add_rpath new ] ... [-delete_rpath new ] ... [-id name] file 

DESCRIPTION 
     Install_name_tool changes the dynamic shared library install names and 
     or adds, changes or deletes the rpaths recorded in a Mach-O binary. 
     For this tool to work when the install names or rpaths are larger the 
     binary should be built with the ld(1) -headerpad_max_install_names 
     option. 

     -change old new 
       Changes the dependent shared library install name old to new in 
       the specified Mach-O binary. More than one of these options can 
       be specified. If the Mach-O binary does not contain the old 
       install name in a specified -change option the option is 
       ignored. 

     -id name 
       Changes the shared library identification name of a dynamic 
       shared library to name. If the Mach-O binary is not a dynamic 
       shared library and the -id option is specified it is ignored. 

     -rpath old new 
       Changes the rpath path name old to new in the specified Mach-O 
       binary. More than one of these options can be specified. If 
       the Mach-O binary does not contain the old rpath path name in a 
       specified -rpath it is an error. 

     -add_rpath new 
       Adds the rpath path name new in the specified Mach-O binary. 
       More than one of these options can be specified. If the Mach-O 
       binary already contains the new rpath path name specified in 
       -add_rpath it is an error. 

     -delete_rpath old 
       deletes the rpath path name old in the specified Mach-O binary. 
       More than one of these options can be specified. If the Mach-O 
       binary does not contains the old rpath path name specified in 
       -delete_rpath it is an error. 

SEE ALSO 
     ld(1)