Коли ми повинні використовувати "вбудовані бінарні файли", а не "Зв'язані рамки" в Xcode?


140

Існує хороше питання про різницю між цими двома варіантами, як описано в Link Binary з бібліотеками VS Embed Frameworks .

Здається, у нас є варіанти використовувати їх обоє, просто цікаво, у якому випадку нам слід краще використовувати вбудовані двійкові файли, а не пов'язані рамки?

Будь-які тверді приклади для вирішення цього питання більш чіткі? Дякую


Відповіді:


239

Питання, з яким ви пов’язали, посилається на функцію "Пов’язати бінарне з бібліотеками", яка дещо відрізняється від вбудованого двійкового файла.

"Пов’язати бінарне з бібліотеками" означає те, що ви очікуєте від нього щодо зв'язку: Незалежно від того, чи є бінарна статична бібліотека, динамічна бібліотека чи рамка, вона буде пов’язана з вашим об'єктним кодом у час посилання після компіляції.

Коли ви думаєте про зв'язок зі статичною бібліотекою, те, що відбувається, досить зрозуміло: лінкер копіює код з бібліотеки (наприклад libFoo.a) у свій вихідний бінарний файл. Ваш вихідний файл збільшується в розмірі, але не потребує усунення зовнішніх залежностей під час виконання. Все, що потрібно виконати вашій програмі (стосовно статичної бібліотеки), з’являється після її побудови.

За допомогою динамічної бібліотеки (.dylib або системи, що постачається системою) очікується, що бібліотека, до якої ви пов'язуєтесь, буде присутня десь у шляху завантаження динамічної бібліотеки системи під час запуску програми. Таким чином, у вас немає накладних витрат на копіювання всіх сторонніх бібліотек у вашу двійкову систему, і всі різні програми на комп'ютері, які також посилаються на цю бібліотеку, зможуть її знайти, що заощадить мінімально місця на диску, але також потенційно простору пам'яті, залежно від того, як і де система кешує бібліотеки.

Рамка схожа на динамічну бібліотеку, але може містити ресурси в її структурі каталогів (зображення, аудіо, інші рамки тощо). У цьому випадку проста статична бібліотека або .dylib файл не вирізатимуть її, тому вам, можливо, доведеться зв’язатись із рамкою, щоб вона змогла знайти те, що потрібно для належного виконання.

Коли ви посилаєтесь на сторонні рамки (скажіть щось, що ви завантажили з github і створили самі), воно може бути відсутнім у системі, в якій ви маєте намір працювати. У цьому випадку ви не тільки посилаєтесь на рамку, але вбудовуєте її всередину пакету додатків, використовуючи фазу "Копіювати рамки". Коли ваша програма запускається, програма-лінкер виконання (він же розв’язувач) загляне всередину вашого пакета на додаток до шляху завантаження системи, знайде вбудований фреймворк і зв’яже його, щоб ваш додаток отримав код, який йому потрібен для запуску.

Нарешті, те, що є належним чином "вбудованим двійковим кодом" - це виконуваний файл, який ви обидва вбудовуєте у свій пакет додатків через фазу "Копіювати файли", і ви виконуєте самостійно, можливо, з викликом до popen()або подібного. Ваша програма може викликати вбудований бінарний файл, але він не пов'язаний з ним. Це повністю зовнішня сутність (як програми в /binкаталозі).

На практиці для системних бібліотек і фреймворків ви пов'язуєте їх, і це все, що вам потрібно зробити.

Якщо вам потрібно зв’язати створену бібліотеку, яка не потребує вбудованих ресурсів (тобто не вимагає існування рамки), то ви можете просто зв’язатись зі статичною бібліотекою. Якщо у вашій програмі є кілька модулів, які хочуть використовувати один і той самий код бібліотеки, перетворення його в рамки або динамічну бібліотеку і посилання на це можуть заощадити місце і може бути зручним (особливо, якщо використання пам'яті викликає занепокоєння).

Нарешті, рамки можуть включати не лише ресурси, але файли заголовків та / або ліцензій. Використання рамки для передачі цих файлів насправді є зручним механізмом розповсюдження, тому часто вам може знадобитися включити рамку, щоб ці речі могли позначати разом із вашим бінарним (тобто ліцензійні вимоги можуть зробити це обов’язковим).

--- редагувати ---

Адам Джонс написав таке коментар як коментар:

Це чудова відповідь. Однак є щось, в чому я трохи розгублений. Що означає виконати двійковий файл самостійно? Ви маєте на увазі просто використання коду вбудованого фреймворку? Я знаю, ти згадав popen (), але ти кажеш, що моя програма викликає popen ()? Я не знаю, що це означає.

Я кажу, що вбудований двійковий файл - це лише інший файл ресурсу у вашому пакеті, як-от аудіо-файл чи зображення, хоча натомість файл є виконуваним інструментом командного рядка. popen()Функція ( man popenвід вашого терміналу , щоб дізнатися більше про це) дозволяє виконувати довільні програми з іншої запущеної програми. system()Функція є ще одним способом. Є й інші, і я наведу історичний приклад, який може зробити розуміння використання вбудованого двійкового файлу дещо зрозумілішим:

Як ви, напевно, знаєте, що при запуску програми на Mac OS X він запускається з ідентифікатором користувача поточного користувача. У більшості поширених установок це типовий користувач у adminкористувальницькому робочому столі , якому надається ідентифікатор користувача 501.

У операційних системах на базі Unix тільки rootкористувач (ідентифікатор користувача 0) має повний доступ до всієї файлової системи. Іноді трапляється, що програма-інсталятор, запущена користувачем Desktop, потребує встановлення файлів у привілейованому каталозі (наприклад, драйвери). У цьому випадку прикладній програмі потрібно ескалацію своїх привілеїв rootкористувачеві, щоб вона могла писати в цих обмежених каталогах.

Щоб полегшити це в операційних системах через OS X 10.7, Apple надала у своєму API служб авторизації функцію AuthorizationExecuteWithPrivileges () (це тепер застаріло, але все ще є корисним прикладом).

AuthorizationExecuteWithPrivileges()взяв за аргумент шлях до інструменту командного рядка для виконання як root. Інструмент командного рядка являв собою виконуваний скрипт оболонки або скомпільований двійковий файл, який ви написали для запуску логіки встановлення. Цей інструмент було встановлено всередині вашої програми, як і будь-який інший файл ресурсів.

Зателефонувавши, ОС встановив діалогове вікно авторизації із запитом пароля користувача (ви вже бачили це раніше!), І коли він буде введений, буде виконано програму, як rootвід вашого імені. Цей процес схожий лише на те, щоб виконати програму з popen()собою, хоча popen()поодинці не приносить користі ескалація привілеїв.


62
Як ти знаєш ці речі?
Ian Warburton

56
@IanWarburton Я програмував операційні системи Apple протягом 20+ років і взяв кілька кухонь тут і там. :)
пар

1
@JustAMartin Я маю на увазі link, але ви маєте рацію, що вам також доведеться вбудовувати його через фазу копіювання файлів (інакше як би ви їх використовували?). Метою використання або стороннього фреймворку, або вбудованого двійкового файлу є виконання коду, який надає сутність. З вбудованим двійковим файлом ніяких зв'язків не бере участь. Під час виконання роботи ви створюєте шлях до двійкового файлу, а потім виконуєте його вручну. За допомогою фреймворку час компіляції зв’яже його під час створення програми, тоді (якщо це стороннє середовище), ви вбудовуєте його через фазу копіювання файлів, і, нарешті, лінкер виконання часу знову з’єднує його під час запуску програми .
пар.

1
У дещо незрозуміло, що ти відповів на @JustAMartin. Метою використання або стороннього фреймворку, або вбудованого двійкового файлу є виконання коду, який надає сутність. Нині вбудовані двійкові файли також можуть бути сторонніми рамками. Я намагаюся зрозуміти, що ви тут маєте на увазі ... AFA Я зрозумів, що вбудовані двійкові файли означають, що окремий двійковий код вбудованої рамки буде введений у пакет додатків. І якщо ви просто зв’яжете той самий фреймворк, він поставить це в той самий бінарний додаток. Виправте мене, якщо я помиляюся ...
hariszaman

1
Можливо, є нова магія Xcode, яка завантажить вбудовану рамку. Минув час, коли мені потрібна ця функціональність. Якщо ви хочете вивчити, що відбувається більше, будь ласка, опублікуйте тут нове запитання на ТАК.
пар

35

Коротко,

  • системні бібліотеки, пов'язують їх;
  • Бібліотеки сторонніх партій, вбудовуйте їх.

чому?

  • якщо ви спробуєте вставити системні бібліотеки, ви не знайдете їх у спливаючому списку;
  • якщо ви зв’яжете сторонні бібліотеки, ви, ймовірно, отримаєте збій.

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 групі [About] ( Project Navigator -> <workspace/project> -> Frameworks), і до вашого проекту буде додано посилання на нього. Тоді ним буде користуватися Static Linker. Static 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[About] Якщо його не знайдено, станеться помилка [dyld: Бібліотека не завантажена]

[При використанні Link and Embed]

[Лексика]

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.