2011-09-27 13 views
16

में डिलिब फ़ाइलों के साथ एक कामकाजी ढांचा कैसे बना सकता हूं मैंने एक्सकोड में एक नया कोको फ्रेमवर्क बनाया है, सभी पुस्तकालयों और फ़ाइलों को हटा दिया है जो इसे सहायक फाइलों को छोड़कर शुरुआत में शामिल हैं।मैं एक्सकोड 4

add.h 

#ifndef add_add_h 
#define add_add_h 

void add(void); 

#endif 

और

add.c 
#include <stdio.h> 
#include "add.h" 

void add(void) 
{ 
    printf("adfding"); 

} 

निर्माण चरणों में मैं सार्वजनिक हेडर को संकलित करने के स्रोतों और add.h संकलित करने के लिए add.c जोड़ें:

मैं 2 फ़ाइलें है। परियोजना बिना किसी समस्या के निर्माण करती है लेकिन ढांचे में कोई डिलिब फ़ाइल नहीं होती है और जब मैं फ्रेमवर्क को किसी अन्य प्रोजेक्ट पर खींचता और छोड़ देता हूं तो यह कहता है कि डाइलिब फ़ाइल नहीं मिल सका।

dyld: Library not loaded: @rpath/add.framework/Versions/A/add 
    Referenced from: /Users/vjoukov/Desktop/Projects/test/build/Debug/test.app/Contents/MacOS/test 
    Reason: image not found 

मैं कैसे एक साधारण ढांचा बनाने के लिए और इसके अंदर फ़ाइलों dylib रख सकते हैं?

उत्तर

61

मुझे लगता है कि आप त्रुटि संदेश को गलत समझ रहे हैं।

एक गतिशील पुस्तकालय के रूप में एक .framework काम करता है, लेकिन वहाँ .framework फ़ोल्डर के अंदर एक वास्तविक .dylib फ़ाइल नाम एक्सटेंशन के साथ किसी भी मच-ओ लोड करने योग्य वस्तु फ़ाइल नहीं होगा।

रनटाइम पर dyld, गतिशील लिंक लाइब्रेरी लोडर से उस त्रुटि संदेश को प्राप्त करने के कुछ कारण हैं। पहला यह है कि आप निर्माण प्रक्रिया के दौरान निर्मित अनुप्रयोग बंडल में .frameworks को कॉपी करना भूल गए हैं। जबकि उन्हें ऐप बंडल के अंदर किसी भी स्थान पर कॉपी किया जा सकता है, पारंपरिक जगह AppName.app/Contents/Frameworks/ में है। यदि आपने पहले से ऐसा नहीं किया है, तो प्रोजेक्ट> नया बिल्ड चरण> नई कॉपी फ़ाइलें बनाएं चरण चुनें। नीचे दी गई छवि में गंतव्य पॉपअप को फ्रेमवर्क में बदलें।

enter image description here

फिर आप इतना है कि यह निर्माण प्रक्रिया के दौरान उन्हें कॉपी है फ़ोल्डर में ढांचे के आइकन खींचें होगा।

enter image description here

दूसरे और अधिक होने की संभावना कारण ढांचे रनटाइम पर नहीं पाया जा सकता है कि आप किसी भी runpath खोज अपने मुख्य निष्पादन के लिए पथ निर्दिष्ट नहीं किया है है। (इसकी आवश्यकता है, क्योंकि, जैसा कि हमने आपके त्रुटि संदेश से देखा है, आपका ढांचा पुराने शैली इंस्टॉल नाम (@rpath/add.framework/Versions/A/add) का उपयोग पुराने @executable_path/ या @loader_path/ शैलियों के बजाय बनाया गया था)।

बशर्ते आप स्थान ऊपर उल्लेख करने के लिए कस्टम चौखटे कॉपी, आप @loader_path/../Frameworks के runpath खोज पथ प्रविष्टि जोड़ने के हैं तो नीचे दिए चित्र में दर्शाया गया है जैसे:

enter image description here

निम्नलिखित अंश है कि कैसे बताते हैं

DYNAMIC लाइब्रेरी लोड हो

: गतिशील पुस्तकालयों क्रम में पाए जाते हैं dyld की मैनपेज से है

कई अन्य ऑपरेटिंग सिस्टम के विपरीत, डार्विन अपने गति फ़ाइल नाम के माध्यम से निर्भर गतिशील पुस्तकालयों का पता नहीं लगाता है। इसके बजाय प्रत्येक डाइलिब का पूरा पथ उपयोग किया जाता है (उदा। /usr/lib/libSystem.B.dylib)। लेकिन ऐसे समय होते हैं जब एक पूर्ण पथ उचित नहीं है; उदाहरण के लिए, हो सकता है कि आपकी बाइनरी डिस्क पर कहीं भी इंस्टॉल हो। इसका समर्थन करने के लिए, तीन @xxx/ चर हैं जिन्हें पथ उपसर्ग के रूप में उपयोग किया जा सकता है। रनटाइम dyld @xxx/ उपसर्ग के लिए गतिशील रूप से जेनरेट किए गए पथ को प्रतिस्थापित करता है।

@executable_path/

यह चर निर्देशिका प्रक्रिया के लिए मुख्य निष्पादन के लिए पथ जिसमें साथ बदल दिया है। यह एक .app निर्देशिका में एम्बेडेड लोडिंग dylibs/ढांचे के लिए उपयोगी है। मुख्य निष्पादन योग्य फ़ाइल /some/path/My.app/Contents/MacOS/My पर है और एक रूपरेखा dylib फ़ाइल
/some/path/My.app/Contents/Frameworks/Foo.framework/Versions/A/Foo, तो ढांचा लोड पथ @executable_path/../Frameworks/Foo.framework/Versions/A/Foo के रूप में एन्कोड किया जा सकता है पर है और .app निर्देशिका फाइल सिस्टम और dyld में चारों ओर ले जाया जा सकता है एम्बेडेड ढांचे को लोड करने के लिए अभी भी सक्षम हो जाएगा।

@loader_path/

यह चर निर्देशिका मच-ओ द्विआधारी जो @loader_path का उपयोग कर लोड आदेश होता है के लिए पथ जिसमें साथ बदल दिया है। इस प्रकार, प्रत्येक बाइनरी में, @loader_path अलग-अलग पथ तक हल करता है, जबकि @executable_path हमेशा उसी पथ पर हल करता है। @loader_path प्लग-इन में एम्बेडेड फ्रेमवर्क/डाइलिब के लिए लोड पथ के रूप में उपयोगी है, यदि अंतिम फ़ाइल सिस्टम प्लगइन का स्थान अज्ञात है (इसलिए पूर्ण पथ का उपयोग नहीं किया जा सकता है) या प्लग-इन का उपयोग किया जाता है एकाधिक अनुप्रयोगों द्वारा (इसलिए @executable_path का उपयोग नहीं किया जा सकता है)। प्लग में मच-ओ फ़ाइल /some/path/Myfilter.plugin/Contents/MacOS/Myfilter पर है और एक ढांचे dylib फ़ाइल /some/path/Myfilter.plugin/Contents/Frameworks/Foo.framework/Versions/A/Foo पर है, तो तो ढांचा लोड पथ @loader_path/../Frameworks/Foo.framework/Versions/A/Foo के रूप में एन्कोड किया जा सकता है और Myfilter.plugin निर्देशिका फाइल में चारों ओर ले जाया जा सकता है सिस्टम और dyld अभी भी एम्बेडेड ढांचे को लोड करने में सक्षम होंगे।

@rpath/

Dyld रास्तों में से एक मौजूदा ढेर रन पथ सूची भी कहा जाता रखता है। जब @rpath का सामना किया जाता है तो इसे रन 0 सूची में प्रत्येक पथ के साथ प्रतिस्थापित किया जाता है जब तक कि लोड होने योग्य डिलीब नहीं मिलता है। रन पथ स्टैक LC_RPATH डिस्पेंसेंसी श्रृंखला में लोड कमांड से बनाया गया है जो वर्तमान डिलिब लोड का कारण बनता है। आप लोड कमांड को -rpath विकल्प ld (1) के साथ एक छवि में लोड कमांड जोड़ सकते हैं। तुम भी है कि @loader_path/ साथ शुरू होता है एक LC_RPATH लोड आदेश पथ में जोड़ सकते हैं, और यह रन पथ ढेर पर एक रास्ता धक्का होगा कि LC_RPATH वाली छवि के सापेक्ष। @rpath का उपयोग सबसे उपयोगी है जब आपके पास जटिल प्रोग्राम और डाइलीब की निर्देशिका संरचना है जिसे कहीं भी इंस्टॉल किया जा सकता है, लेकिन उनकी सापेक्ष स्थिति रखें। यह परिदृश्य @loader_path का उपयोग करके कार्यान्वित किया जा सकता है, लेकिन dylib के प्रत्येक क्लाइंट को एक अलग लोड पथ की आवश्यकता हो सकती है क्योंकि फ़ाइल सिस्टम में इसकी सापेक्ष स्थिति अलग है। @rpath का उपयोग संकेतों का एक स्तर प्रस्तुत करता है जो चीजों का अनुपालन करता है। आप अपनी निर्देशिका संरचना में एक एंकर पॉइंट के रूप में एक स्थान चुनें। प्रत्येक डाइलीब को एक इंस्टॉल पथ मिलता है जो @rpath और से शुरू होता है जो एंकर पॉइंट के सापेक्ष डाइलिब का पथ है। प्रत्येक मुख्य निष्पादन योग्य -rpath @loader_path/zzz से जुड़ा हुआ है, जहां zzz निष्पादन योग्य से एंकर पॉइंट तक पथ है। रनटाइम dyld इसे एंकर पॉइंट होने के लिए पथ चलाता है, फिर एंकर पॉइंट के सापेक्ष पाए गए प्रत्येक डायलीब है।

+5

वाह! यह एक पूर्ण जवाब का एक बिल्ली है, यह भी एक समस्या हल हो गया था! धन्यवाद!! –

+0

बहुत गहन और पूरा जवाब ... अच्छा काम! –

+0

बिल्कुल सही जवाब! मैं कभी नहीं जानता था कि कैसे काम किया। अच्छा! – JackPearse