objective-c – 为什么iOS框架依赖项在为应用程序项目执行时不需
为什么我在Xcode中创建iOS静态库项目或框架项目时,我不需要将任何iOS SDK框架链接到项目以便使用它们的头和对象 – 例如,我可以#import< AudioToolbox / AudioToolbox.h>并将AudioToolbox代码放在静态库或框架中,而无需在构建设置中的“Link Binary with Libraries”下添加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文件,没有源代码.只需要解析符号的目标文件.这就是头文件在这里无关紧要的原因,但在编译时要重要. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |