Прежде всего, вы правы в том, что статическая библиотека не может включать в себя ни фреймворк, ни другие статические библиотеки, это просто набор всех объектных файлов (* .obj), которые составляют эту конкретную статическую библиотеку.
Кто-нибудь знает, как скомпилировать только необходимые исходные файлы для проекта?
Компоновщик по умолчанию будет связывать только в объектных файлах из статической библиотеки, которые содержат символы, на которые ссылается приложение. Таким образом, если у вас есть два файла a.m
и b.m
в вашей статической библиотеке и вы используете только символы из a.m
в своей основной программе, то b.o
(объектный файл, сгенерированный из b.c
) не появится в ваш окончательный исполняемый файл. В качестве дополнительного случая, если b.m
использует функцию / класс c
, которая только объявлена (не реализована), вы не получите никаких ошибок компоновщика. Как только вы включите некоторые символы из b.m
в свою программу, b.o
также будет связан, и вы получите ошибки компоновщика из-за отсутствующей реализации c
.
Если вы хотите, чтобы этот вид выделения происходил на уровне символа, а не на уровне детализации на уровне объекта, включите очистку мертвого кода в XCode. Это соответствует опции gcc -Wl, -dead_strip (= опция компоновщика -dead_strip в информационной панели настроек сборки для вашего проекта). Это обеспечит дальнейшую оптимизацию.
В вашем случае, однако, как вы правильно сказали, именно использование компоновщика "-ObjC" побеждает этот механизм. Так что это на самом деле зависит от вас. Если вы уберете флаг -Objc, вы получите бесплатное поведение, в то же время потеряв более строгую проверку селекторов.
И запретить включение всех фреймворков во все проекты, использующие мою статическую библиотеку?
Xcode / GCC поддерживают опцию связывания, которая называется " слабое связывание ", которая позволяет лениво загружать фреймворк или статическую библиотеку, т. Е. Только когда фактически используется один из его символов.
«Слабое связывание» может быть включено либо через флаг компоновщика (см. выше документ Apple), либо через пользовательский интерфейс Xcode (Цель -> Информация -> Общие -> Связанные библиотеки).
Во всяком случае, фреймворк или библиотека должны быть доступны во всех случаях во время компиляции / компоновки: опция «слабый» влияет только на момент первой загрузки фреймворка во время выполнения. Таким образом, я не думаю, что это полезно для вас, так как вам в любом случае нужно будет включить фреймворк во все ваши проекты, чего вы не хотите.
В качестве примечания, weak_linking
- это опция, которая в основном имеет смысл при использовании функций, доступных только в более новой версии SDK (скажем, 4.3.2), а также поддерживает развертывание в более старых версиях SDK (скажем, 3.1.3). В этом случае вы полагаетесь на тот факт, что более новые платформы SDK будут фактически доступны на новых устройствах развертывания, и вы условно компилируете функции, требующие этого, так что на старых устройствах они не потребуются (и не будут производить таким образом попытка загрузки более новой версии фреймворка и сбой).
Что еще хуже, GCC не поддерживает функцию, известную как «автоматическое связывание» с компиляторами Microsoft, которая позволяет указать, какую библиотеку связывать, с помощью комментария #pragma в исходном файле. Это может предложить обходной путь, но его там нет.
Итак, мне очень жаль говорить, что вы должны использовать другой подход, который мог бы в равной степени удовлетворить ваши потребности:
убрать флаг -ObjC;
разбить вашу статическую библиотеку на две или более частей в соответствии с их зависимостями от внешних платформ;
прибегнуть к непосредственному включению исходных файлов.