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

Зачемexactly когда я создаю проект статической библиотеки iOS или проект фреймворка в Xcode, мне не нужно связывать какие-либо фреймворки iOS SDK с проектом, чтобы использовать их заголовки и объекты - например, я могу#import <AudioToolbox/AudioToolbox.h> и поместите код AudioToolbox в статическую библиотеку или фреймворк, фактически не добавляя AudioToolbox в разделе «Связать двоичные файлы с библиотеками». в настройках сборки или при наличии его в файловом навигаторе, и проект будет создаваться без проблем, что не сработает в проекте приложения - но когда разработчик затем использует статическую библиотеку или продукт платформы в приложении, он делает нужно ли ссылаться на фреймворк, чтобы использовать одинаковые заголовки и объекты?

У меня есть смутное представление о том, почему это так, но мне действительно было бы интересно услышать от кого-то, кто знает наверняка.

Ответы на вопрос(1)

Решение Вопроса

.o файлы. Они "не" связаны " любым значимым образом; просто соединены вместе. До тех пор, пока вы не выполните реальный шаг ссылки, символы не будут разрешены.

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

Следующее упражнение может быть образовательным:

Создайте следующееcomptest.c:

#include <stdio.h>

int main() {
   printf("Hello world.\n");
   return 0;
}

Посмотрите, что делает препроцессор:

gcc -E comptest.c > comptest-cpp.c

Это удаляет#include и заменяет его содержимым ссылочного файла. Этот файл - то, что фактически видит компилятор.

Теперь посмотрим, что делает компилятор (я использую> синтаксис здесь и ниже, так что все параллельно-E):

gcc -S comptest.c > comptest.s

Это сгенерированный язык ассемблера после предварительной обработки и компиляции. Теперь мы превращаем это в .o:

gcc -c comptest.c > comptest.o

Теперь давайте посмотрим, что в этом .o:

$ nm comptest.o
0000000000000040 s EH_frame0
000000000000002d s L_.str
0000000000000000 T _main
0000000000000058 S _main.eh
                 U _puts

Важные вещи здесь_main а также_puts. _main определяется в этом файле по адресу 0._puts не определено Таким образом, кое-что, с чем мы связываемся, должно было обеспечить это Давайте попробуем связать без чего-либо:

$ gcc -nodefaultlibs comptest.o
Undefined symbols for architecture x86_64:
  "_exit", referenced from:
      start in crt1.10.6.o
  "_puts", referenced from:
      _main in comptest.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

(_exit неявный из среды выполнения C; на него нет прямой ссылки в .o)

Хорошо, теперь мы готовы собрать все это вместе. Мы будем явными:

gcc -nodefaultlibs comptest.o /usr/lib/libc.dylib -o comptest

Это говорит, чтобы связать вместеcomptest.o и динамическая библиотекаlibc, Это обещает, что каждый символ, на который ссылаются, будет предоставлен одним из этих файлов. В полученном двоичном файле он отмечает, что он должен динамически загружать символы из/usr/lib/libc.dylib (это символическая ссылка на libSystem.B.dylib, которая сама по себе является «зонтичной платформой», а не правильной библиотекой, но в большинстве случаев это немного превосходит то, что вам нужно знать; вы можете сделать вид, чтоputs() находится в libSystem):

$ otool -L comptest
comptest:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

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

Обратите внимание, что на этапе связывания у нас просто есть файлы .o и .dylib (.a - это просто пакет .o). Нет .c файлов, нет .h файлов, нет .s файлов, нет исходного кода. Просто объектные файлы, которые требуют разрешения символов. Вот почему заголовочные файлы здесь не имеют значения, но имеют значение при компиляции.

 26 авг. 2014 г., 16:32
Привет ребята. Можете ли вы посмотреть на этот вопросstackoverflow.com/questions/25504973/… ?
 Halle30 апр. 2012 г., 16:40
Хорошо, но что мне пока не ясно на 100%, это то, что, например, если в исходном коде проекта отсутствует заголовок и файлы реализации в проекте ссылаются на него, сборка приведет к ошибке сборки из-за отсутствующего заголовка , Другая проблема заключается в том, что если я импортирую заголовок из одной из моих собственных платформ вместо iOS, я получу ошибку заголовка не найден, и сборка завершится неудачно.
 Halle30 апр. 2012 г., 18:48
Отличный пример, спасибо.
 30 апр. 2012 г., 18:14
Заголовки должны быть доступны во время предварительной обработки (до компиляции). Они не имеют ничего общего с компоновщиком. Статическая библиотека - это коллекция .o файлов. Они были предварительно обработаны и скомпилированы. Они не были связаны, однако. Связывание не требует или использует заголовочные файлы. Связывание разрешает символы.
 Halle30 апр. 2012 г., 16:41
Это потому, что где-то в настройках сборки проекта для платформ iOS есть путь поиска заголовка?

Ваш ответ на вопрос