हमें Xcode में "लिंक्ड फ्रेमवर्क" के बजाय "एम्बेडेड बायनेरिज़" का उपयोग कब करना चाहिए?


140

उन दो विकल्पों के बीच अंतर के बारे में एक अच्छा सवाल है, जैसा कि लिंक वी.एस. एंबेड फ़्रेमवर्क के साथ लिंक बाइनरी में वर्णित है ।

लगता है कि हमारे पास उन दोनों का उपयोग करने के लिए विकल्प हैं, बस आश्चर्य है कि किस मामले में हमें एम्बेडेड बायनेरिज़ का बेहतर उपयोग करना चाहिए, या लिंक किए गए ढांचे के बजाय?

इसे और अधिक स्पष्ट करने के लिए कोई ठोस उदाहरण? धन्यवाद


जवाबों:


239

आपके द्वारा जुड़ा प्रश्न "लिंक बाइनरी विद लाइब्रेरीज़" कार्यक्षमता को संदर्भित करता है, जो कि एक एम्बेडेड बाइनरी से कुछ अलग है।

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

जब आप स्थैतिक पुस्तकालय के साथ जुड़ाव के बारे में सोचते हैं, तो जो होता है वह बहुत स्पष्ट होता है: लिंकर पुस्तकालय से कोड को कॉपी करता है (जैसेlibFoo.a ) को अपने आउटपुट बाइनरी में । आपकी आउटपुट फ़ाइल आकार में बढ़ती है, लेकिन रनटाइम पर किसी भी बाहरी निर्भरता को हल करने की आवश्यकता नहीं है। आपके द्वारा चलाए जाने के बाद आपके प्रोग्राम को चलाने के लिए (स्थैतिक पुस्तकालय के संबंध में) सब कुछ मौजूद है।

डायनेमिक लाइब्रेरी (.dylib, या सिस्टम-सप्लाई फ़्रेमवर्क) के साथ, उम्मीद यह है कि आप जिस लाइब्रेरी के खिलाफ लिंक कर रहे हैं, वह सिस्टम के डायनामिक-लाइब्रेरी लोडर पथ में कहीं मौजूद होगी जब आप अपना प्रोग्राम चलाते हैं। इस तरह से आपके पास सभी तृतीय पक्ष बाहरी पुस्तकालयों को अपने बाइनरी में कॉपी करने का ओवरहेड नहीं है, और कंप्यूटर पर सभी अलग-अलग प्रोग्राम जो उस लाइब्रेरी से लिंक करते हैं, वे इसे ढूंढने में सक्षम होंगे, जो न्यूनतम डिस्क स्थान बचाता है, लेकिन यह भी संभावित मेमोरी स्पेस, इस बात पर निर्भर करता है कि सिस्टम कैसे और कहां लाइब्रेरीज़ को कैश करता है।

एक ढांचा एक गतिशील पुस्तकालय की तरह होता है, लेकिन इसकी निर्देशिका संरचना (चित्र, ऑडियो, अन्य ढांचे, आदि) में संसाधन शामिल हो सकते हैं। इस स्थिति में एक साधारण स्टैटिक-लाइब्रेरी या .dylib फाइल नहीं कटेगी, इसलिए आपको किसी फ्रेमवर्क से लिंक करना पड़ सकता है, ताकि यह पता चल सके कि इसे ठीक से चलाने की आवश्यकता क्या है।

जब आप किसी थर्ड-पार्टी फ्रेमवर्क से लिंक करते हैं (ऐसा कुछ कहिए जिसे आपने गितूब से डाउनलोड किया है और खुद बनाया है), यह उस सिस्टम पर मौजूद नहीं हो सकता जिसे आप चलाने का इरादा रखते हैं। इस स्थिति में, आप केवल फ़्रेमवर्क से लिंक नहीं करेंगे, बल्कि "कॉपी फ्रेमवर्क" चरण का उपयोग करके इसे अपने एप्लिकेशन बंडल के अंदर एम्बेड करें। जब आपका प्रोग्राम चलता है, तो रनटाइम-लिंकर (उर्फ रिज़ॉल्वर) सिस्टम लोडर पथ के अलावा आपके बंडल के अंदर दिखेगा, एम्बेडेड फ्रेमवर्क ढूंढें, और इसे लिंक करें ताकि आपके ऐप में वह कोड हो जिसे चलाने के लिए इसकी आवश्यकता हो।

अंत में, क्या ठीक से "एम्बेडेड बाइनरी" एक निष्पादन योग्य है जिसे आप अपने एप्लिकेशन बंडल में एक कॉपी-फाइल चरण के माध्यम से एम्बेड करते हैं, और यह कि आप अपने आप को निष्पादित करते हैं, शायद एक कॉल के साथ popen()या इसी तरह। एम्बेडेड बाइनरी को आपके प्रोग्राम द्वारा बुलाया जा सकता है, लेकिन यह इसके साथ जुड़ा नहीं है। यह पूरी तरह से बाहरी इकाई है (जैसे /binनिर्देशिका में कार्यक्रम )।

व्यवहार में, सिस्टम द्वारा आपूर्ति की गई लाइब्रेरी और फ्रेमवर्क के लिए आप उनके खिलाफ लिंक करेंगे और आपको बस इतना करना होगा।

यदि आपको अपने द्वारा बनाए गए पुस्तकालय को लिंक करने की आवश्यकता है जो कि किसी भी एम्बेडेड संसाधनों की आवश्यकता नहीं है (यानी मौजूद होने के लिए एक रूपरेखा की आवश्यकता नहीं है), तो आप बस एक स्थैतिक पुस्तकालय के खिलाफ लिंक कर सकते हैं। यदि आप पाते हैं कि आपके प्रोग्राम में कई मॉड्यूल हैं जो एक ही लाइब्रेरी कोड का उपयोग करना चाहते हैं, तो इसे एक फ्रेमवर्क या डायनेमिक लाइब्रेरी में परिवर्तित करना और इसके खिलाफ लिंक करना अंतरिक्ष को बचा सकता है और सुविधाजनक हो सकता है (विशेषकर यदि मेमोरी उपयोग एक चिंता का विषय है)।

अंत में, फ्रेमवर्क में न केवल संसाधन, बल्कि हेडर और / या लाइसेंस फाइलें शामिल हो सकती हैं। इन फ़ाइलों को संप्रेषित करने के लिए एक फ्रेमवर्क का उपयोग करना वास्तव में एक सुविधाजनक वितरण तंत्र है इसलिए अक्सर आप एक फ्रेमवर्क को शामिल करना चाह सकते हैं ताकि ये चीजें आपके बाइनरी के साथ टैग हो सकें (यानी लाइसेंस की आवश्यकताएं इसे अनिवार्य बना सकती हैं)।

--- संपादित करें ---

एडम जॉन्स ने टिप्पणी के रूप में निम्नलिखित प्रश्न पोस्ट किया:

यह एक बेहतरीन जवाब है। हालाँकि, मैं अभी भी थोड़ा उलझन में हूँ। बाइनरी को स्वयं निष्पादित करने का क्या मतलब है? क्या आपका मतलब केवल एम्बेडेड फ्रेमवर्क कोड का उपयोग करना है? मुझे पता है कि आपने पोपेन () का उल्लेख किया है, लेकिन आप कह रहे हैं कि मेरा ऐप पोपेन () कह रहा है? मैं वास्तव में नहीं जानता कि इसका क्या मतलब है।

मैं कह रहा हूं कि एक एम्बेडेड बाइनरी आपके बंडल में सिर्फ एक ऑडियो फ़ाइल या छवि की तरह एक और संसाधन फ़ाइल है, हालांकि फ़ाइल एक निष्पादन योग्य कमांड-लाइन उपकरण है। popen()समारोह ( man popenअपने टर्मिनल से अधिक पढ़ने के लिए इसके बारे में) यदि आप किसी अन्य चल रहे प्रोग्राम से मनमाना कार्यक्रमों पर अमल करने देता है। system()समारोह एक और तरीका है। अन्य लोग भी हैं, और मैं यहां एक ऐतिहासिक उदाहरण दूंगा, जो एम्बेडेड बाइनरी के उपयोग को थोड़ा और स्पष्ट कर सकता है:

जैसा कि आप शायद जानते हैं, जब आप मैक ओएस एक्स पर एक ऐप लॉन्च करते हैं, तो इसे वर्तमान उपयोगकर्ता के उपयोगकर्ता आईडी के साथ लॉन्च किया जाता है। अधिकांश सामान्य इंस्टॉलेशन के तहत, डिफ़ॉल्ट उपयोगकर्ता-पर-डेस्कटॉप adminउपयोगकर्ता, जिसे उपयोगकर्ता आईडी दिया जाता है 501

यूनिक्स-आधारित ऑपरेटिंग सिस्टम पर केवल root उपयोगकर्ता (यूजर आईडी 0) की पूरी फाइल सिस्टम तक पूरी पहुंच है। कभी-कभी ऐसा होता है कि डेस्कटॉप उपयोगकर्ता द्वारा लॉन्च किए गए इंस्टॉलर प्रोग्राम को विशेषाधिकार प्राप्त निर्देशिका (उदाहरण के लिए ड्राइवर) में फ़ाइलें स्थापित करने की आवश्यकता होती है। इस मामले में, एप्लिकेशन प्रोग्राम को अपने विशेषाधिकारों को rootउपयोगकर्ता तक पहुंचाने की आवश्यकता है ताकि वह इन प्रतिबंधित निर्देशिकाओं में लिख सके।

ओएस एक्स 10.7 के माध्यम से ऑपरेटिंग सिस्टम में इसे सुविधाजनक बनाने के लिए, ऐप्पल ने अपने प्राधिकरण सेवा एपीआई फ़ंक्शन को प्रदान किया ऑथराइजेशन एक्सक्यूट वाइटप्राइवेज () (यह अब पदावनत कर दिया है, लेकिन अभी भी एक उपयोगी उदाहरण है)।

AuthorizationExecuteWithPrivileges() एक तर्क के रूप में निष्पादित करने के लिए एक कमांड-लाइन टूल के लिए एक पथ के रूप में लिया गया root । कमांड लाइन टूल एक निष्पादन योग्य शेल स्क्रिप्ट या संकलित बाइनरी था जिसे आपने अपने इंस्टॉल लॉजिक को चलाने के लिए लिखा था। यह टूल किसी अन्य संसाधन फ़ाइल की तरह ही आपके एप्लिकेशन बंडल के अंदर स्थापित किया गया था।

जब कहा जाता है, तो ओएस ने उपयोगकर्ता के पासवर्ड के लिए पूछते हुए एक प्राधिकरण संवाद स्थापित किया है (आपने इसे पहले देखा है!) और जब दर्ज किया rootगया तो आपके ऐप की ओर से प्रोग्राम निष्पादित करेगा । यह प्रक्रिया केवल popen()स्वयं के साथ एक कार्यक्रम को निष्पादित करने के समान है , हालांकि popen()अकेले आपको विशेषाधिकार वृद्धि का लाभ नहीं देता है।


62
आप इन बातों को कैसे जानते हैं?
इयान वारबर्टन

56
@IanWarburton मैं 20+ वर्षों से Apple ऑपरेटिंग सिस्टम की प्रोग्रामिंग कर रहा हूँ और यहाँ और वहाँ कुछ tidbits उठा ली है। :)
बराबर

1
@JustAMartin मेरा मतलब है link, लेकिन आप सही हैं कि आपको इसे कॉपी-फाइल चरण के माध्यम से एम्बेड करना होगा (अन्यथा आप इसका उपयोग कैसे करेंगे?)। तीसरे पक्ष के ढांचे या एक एम्बेडेड बाइनरी का उपयोग करने का लक्ष्य उस कोड को निष्पादित करना है जो इकाई प्रदान करती है। एक एम्बेडेड बाइनरी के साथ कोई लिंकिंग शामिल नहीं है। रनटाइम पर आप बाइनरी के लिए एक पथ का निर्माण करते हैं फिर इसे मैन्युअल रूप से निष्पादित करते हैं। एक फ्रेमवर्क के साथ कंपाइल-टाइम लिंकर जब आप अपना ऐप बनाते हैं, तब इसे लिंक करेंगे, (यदि यह एक 3-पार्टी फ्रेमवर्क है) तो आप इसे कॉपी-फ़ाइल्स चरण के माध्यम से एम्बेड करते हैं, और अंत में रनटाइम लिंकर इसे तब लिंक करता है जब आप अपना ऐप चलाते हैं। ।
बराबर

1
बातें थोड़ी स्पष्ट नहीं हैं कि आपने @JustAMartin को क्या जवाब दिया। तीसरे पक्ष के ढांचे या एक एम्बेडेड बाइनरी का उपयोग करने का लक्ष्य उस कोड को निष्पादित करना है जो इकाई प्रदान करती है। आजकल एंबेडेड बायनेरिज़ भी थर्ड पार्टी फ्रेमवर्क हो सकते हैं। मैं यह समझने की कोशिश कर रहा हूं कि आपके यहां क्या मतलब है ... AFA मैं समझ गया, एम्बेडेड बायनेरिज़ का मतलब है, एम्बेडेड फ्रेमवर्क के अलग बाइनरी को ऐप बंडल में पेश किया जाएगा, और यदि आप बस उसी फ्रेमवर्क को लिंक करते हैं तो यह उसी बाइनरी में डाल देगा उस एप्लिकेशन का। कृपया मुझे सही करें अगर मैं गलत हूँ ...
hariszaman

1
शायद नया Xcode जादू है जो एक एम्बेडेड फ्रेमवर्क को लोड करेगा। यह एक समय हो गया है क्योंकि मुझे उस कार्यक्षमता की आवश्यकता है। यदि आप यह पता लगाना चाहते हैं कि क्या चल रहा है तो कृपया एसओ पर एक नया प्रश्न पोस्ट करें।
बराबर

35

संक्षेप में,

  • सिस्टम लाइब्रेरी, उन्हें लिंक करें;
  • 3 पार्टी पुस्तकालय, उन्हें एम्बेड करें।

क्यों?

  • यदि आप सिस्टम लाइब्रेरी को एम्बेड करने का प्रयास करते हैं, तो आप उन्हें पॉपअप सूची में नहीं पाएंगे;
  • यदि आप तृतीय पक्ष के पुस्तकालयों को लिंक करते हैं, तो संभवतः आपको एक दुर्घटना हो जाएगी।

7

यह Dependencyप्रबंधन का एक हिस्सा है [बारे में]

कृपया ध्यान दें कि टैब Xcode 11में केवल Frameworks, Libraries, and Embedded Contentअनुभाग हैGeneral

लिंक बाइनरी

Build Phases -> Link Binary With Librariesका दर्पण है General -> Linked Frameworks and Libraries

स्टेटिक लाइब्रेरी और फ्रेमवर्क

यदि आप Static Library or Static Frameworkइस अनुभाग में एक जोड़ते हैं तो यह Frameworks समूह [अब]] ( Project Navigator -> <workspace/project> -> Frameworks) में दिखाई देगा और इसके लिए आपकी परियोजना में एक संदर्भ जोड़ा जाएगा। तब इसका उपयोग किया जाएगा Static LinkerStatic Linkerसंकलन के समय में लाइब्रेरी से निष्पादन योग्य ऑब्जेक्ट फ़ाइल में सभी कोड शामिल / कॉपी होंगे । Static linkerके साथ जोड़ी में काम करता हैBuild Settings -> <Library/Framework> Search Paths

Static Library

Static Framework

  • Build Settings -> Framework Search Paths। यदि आप static frameworkइस खंड में कोई जोड़ नहीं देते हैं तो आपको एक संकलन त्रुटि मिलेगी [ऐसा कोई मॉड्यूल नहीं]

बाइनरी एम्बेड करें

स्टेटिक लाइब्रेरी और स्टेटिक फ्रेमवर्क

एंबेडिंग के लिए कोई मतलब नहीं होगा Static Libraryऔर Static Frameworkक्योंकि उनमें से प्रतीकों को निष्पादन योग्य बाइनरी में संकलित किया गया है। Xcode आपको static libraryएंबेड अनुभाग के तहत ड्रॉप नहीं होने देगा ।

गतिशील ढांचा

Build Phases -> Embed Frameworksका दर्पण है General -> Embedded Binaries। एंबेडिंग वास्तव में आपके एप्लिकेशन बंडल में फ्रेमवर्क की एक प्रति जोड़ता है । परिणामस्वरूप, जब किसी Embedखंड को जोड़ा जाता है / खंड में हटाया जाता है तो यह स्वचालित रूप से Linkedअनुभाग में जोड़ा / हटा दिया जाएगा । डिफ़ॉल्ट रूप से बंडल का फ़ोल्डर है, Frameworksलेकिन आप इसे Destinationफ़ील्ड का उपयोग करके बदल सकते हैं । इसके अलावा आप एक निर्दिष्ट कर सकते हैं Subpath

Dynamic linker :dyldपर भार या रन टाइम की तलाश करेगा एम्बेडेड ढांचे का उपयोग कर @rpath[बारे में] यदि यह नहीं पाया जाता है त्रुटि हो जाएगा [dyld: लाइब्रेरी लोड नहीं]

[जब लिंक और एंबेड का उपयोग करें]

[शब्दावली]

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.