Когда мы должны использовать "встроенные двоичные файлы", а не "Связанные рамки" в Xcode?

Существует хороший вопрос о различии между этими двумя опциями, описанными в Link Binary с библиотеками VS Embed Frameworks.

Похоже, что у нас есть варианты использования их обоих, просто задайтесь вопросом, в каком случае мы должны лучше использовать встроенные бинарные файлы, а не привязанные рамки?

Какие-нибудь твердые примеры для решения этой проблемы более ясны? Благодаря

Ответ 1

Связанный с вами вопрос ссылается на функциональность Link Binary With Libraries, которая несколько отличается от встроенного двоичного файла.

"Link Binary With Libraries" означает то, что вы ожидаете от него в отношении привязки: независимо от того, является ли бинарный файл статической библиотекой, динамической библиотекой или фреймворком, она будет связана с вашим объектным кодом во время ссылки после компиляции.

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

С динамической библиотекой (.dylib или системной базой) ожидается, что библиотека, с которой вы связываете, будет присутствовать где-нибудь в пути загрузки динамической библиотеки системы при запуске вашей программы. Таким образом, у вас нет накладных расходов на копирование всех внешних сторонних библиотек в ваш двоичный файл, и все различные программы на компьютере, которые также ссылаются на эту библиотеку, смогут найти его, что экономит минимальное дисковое пространство, но также потенциально пространство памяти, в зависимости от того, как и где система кэширует библиотеки.

Структура похожа на динамическую библиотеку, но может содержать ресурсы в структуре каталогов (изображения, аудио, другие фреймворки и т.д.). В этом случае простой файл static-library или .dylib не будет вырезать его, поэтому вам может потребоваться ссылка на структуру, чтобы он мог найти, что нужно для правильной работы.

Когда вы ссылаетесь на стороннюю структуру (скажите что-то, что вы загрузили из github и создали самостоятельно), она может отсутствовать в системе, которую вы собираетесь запускать. В этом случае вы не только привязываетесь к инфраструктуре, но также встраиваете ее в свой пакет приложений, используя фазу "Копирование фреймворков". Когда ваша программа запускается, runtime-linker (ака резольвер) будет заглядывать в ваш комплект в дополнение к пути загрузчика системы, найти встроенную инфраструктуру и связать ее, чтобы ваше приложение получило необходимый код для запуска.

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

На практике для системных библиотек и фреймворков вы свяжетесь с ними и все, что вам нужно сделать.

Если вам нужно связать библиотеку, которую вы создали, которая не нуждается в каких-либо встроенных ресурсах (т.е. не требует существования фреймворка), вы можете просто связать ее со статической библиотекой. Если вы обнаружите, что у вас есть несколько модулей в вашей программе, которые хотят использовать один и тот же код библиотеки, то преобразование его в структуру или динамическую библиотеку и привязку к ней может сэкономить место и может быть удобным (особенно, если использование памяти является проблемой).

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

--- EDIT ---

Адам Джонс написал следующий вопрос в качестве комментария:

Это отличный ответ. Однако я кое-что немного запутался. Что значит выполнять сам бинар? Вы имеете в виду просто использование встроенного кода рамки? Я знаю, что вы упомянули popen(), но вы говорите, что мое приложение вызывает popen()? Я действительно не знаю, что это значит.

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

Как вам известно, при запуске приложения в Mac OS X он запускается с идентификатором пользователя текущего пользователя. В большинстве обычных установок пользователь user-at-the-Desktop admin по умолчанию, которому присваивается идентификатор пользователя 501.

В операционных системах на базе Unix только пользователь root (идентификатор пользователя 0) имеет полный доступ ко всей файловой системе. Иногда бывает, что программа установки, запускаемая пользователем Desktop, должна устанавливать файлы в привилегированном каталоге (например, драйверы). В этом случае прикладная программа должна эскалировать свои привилегии пользователю root, чтобы он мог писать в этих ограниченных каталогах.

Чтобы облегчить это в операционных системах через OS X 10.7, Apple предоставила в Авторизованных сервисах API функцию AuthorizationExecuteWithPrivileges() (теперь это устарело, но по-прежнему является полезным примером).

AuthorizationExecuteWithPrivileges() принял в качестве аргумента путь к инструменту командной строки для выполнения как root. Инструмент командной строки представлял собой исполняемую оболочку script или скомпилированный двоичный файл, который вы написали для запуска вашей логики установки. Этот инструмент был установлен внутри вашего пакета приложений так же, как и любой другой файл ресурсов.

При вызове ОС выдает диалог авторизации с запросом пароля пользователя (вы видели это раньше!), и при вводе будет выполняться программа как root в вашем приложении. Этот процесс похож на выполнение самой программы с помощью popen() самостоятельно, хотя popen() сам по себе не дает вам преимуществ эскалации привилегий.

Ответ 2

Короче говоря,

  • системные библиотеки, свяжите их;
  • Сторонние библиотеки, внедряйте их.

почему?

  • Если вы попытаетесь внедрить системные библиотеки, вы не найдете их во всплывающем списке,
  • Если вы связываете сторонние библиотеки, вы, вероятно, получите сбой.

Ответ 3

Это часть управления Dependency [About]

Обратите внимание, что 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 group, и в ваш проект будет добавлена ссылка на него. Затем он будет использован Static Linker. Static Linker во время компиляции включает/копирует весь код из библиотеки в исполняемый объектный файл.

Static Library

  • Если вы не добавите static library в этот раздел, вы получите ошибку компоновщика[ld: symbol(s) not found]. Также Static linker работает в паре с Build Settings -> Library Search Paths[library not found]

Framework

Должно работать с Build Settings -> Framework Search Paths[No such module]

  • Если вы не добавите static framework в этот раздел, вы получите ошибку компиляции[No such module].
  • Вы можете пропустить этот раздел для dynamic framework.

Вставить двоичный файл

Статическая библиотека и статическая структура

Встраивание не имеет никакого смысла для Static Library и Static Framework, потому что символы из них скомпилированы в исполняемый файл. XCode не позволит вам сбросить static library в разделе Embed.

Динамическая структура

Build Phases -> Embed Frameworks является зеркалом General -> Embedded Binaries. Внедрение фактически добавляет копию фреймворка в ваш пакет приложений. В результате, когда фреймворк добавляется/удаляется в секцию Embed, он автоматически добавляется/удаляется в секцию Linked. По умолчанию папка комплекта - Frameworks, но вы можете изменить ее, используя поле Destination. Кроме того, вы можете указать Subpath.

Dynamic linker :dyld при загрузке или времени выполнения попытается найти встроенную платформу, используя @rpath[About] Если она не найдена, произойдет ошибка [dyld: Library not loaded]

[При использовании Link и Embed]

[Словарь]

Источник здесь.