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