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

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

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

Какие-нибудь убедительные примеры, чтобы решить эту проблему более четко? Спасибо

2 ответа

Решение

Вопрос, который вы связали, относится к функциональности "Связать двоичный файл с библиотеками", которая несколько отличается от встроенного двоичного файла.

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

Когда вы думаете о связи со статической библиотекой, то, что происходит, довольно ясно: компоновщик копирует код из библиотеки (например, 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() одиночество не дает вам возможности повышения привилегий.

Короче,

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

Зачем?

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

Это часть Dependencyменеджмент [О компании]

Обратите внимание, что Xcode 11 содержит только Frameworks, Libraries, and Embedded Content раздел в General вкладка

[Xcode v11]

Ссылка двоичный

General -> Linked Frameworks and Libraries это зеркало Build Phases -> Link Binary With Libraries.

Статическая библиотека и фреймворк

Если вы добавите Static Library or Static Framework в этот раздел он появится по адресу Frameworks группа [О себе](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 в разделе "Встроить".

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

General -> Embedded Binaries это зеркало Build Phases -> Embed Frameworks.

Встраивание фактически добавляет копию фреймворка в пакет вашего приложения.

По умолчанию папка пакета Frameworks но вы можете изменить его, используя Destinationполе. Кроме того, вы можете указатьSubpath.

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

Результат:

  • Static Library - Link
  • Static Framework - Link
  • Dynamic Framework - Embed

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

[Словарь]

Другие вопросы по тегам