到底为什么是,当我在Xcode中创建一个iOS的静态库项目或框架项目,我不需要为了使用它们的标题和对象的任何iOS版SDK框架链接到项目-例如,我可以#import <AudioToolbox/AudioToolbox.h>
并把AudioToolbox代码静态库或框架,而不必实际AudioToolbox在构建设置下添加“链接二进制与库”或有它存在于文件导航,该项目将建立一个没有问题,东西不会在一个应用程序项目工作 - 但是当开发人员则使用静态库或框架产品在应用程序,他们必须以链接到框架,以使用相同的标题和对象?
我为什么这将是一个模糊的想法,但我会从别人谁确切知道听到很感兴趣。
静态库是只是一个捆绑.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文件中,没有源代码。 只是对象需要解析的符号文件。 这就是为什么头文件不事在这里,但做事情,当你编译。
文章来源: Why don't iOS framework dependencies need to be explicitly linked to a static library project or framework project when they do for an app project?