Когда мы должны использовать "встроенные двоичные файлы", а не "связанные структуры" в 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
вкладка
Ссылка двоичный
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
Build Settings -> Library Search Paths
[библиотека не найдена] Если вы не добавитеstatic library
в этом разделе вы получите ошибку компоновщика [ld: symbol(s) not found]
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