-
脑补一下:
- 预处理:预处理相当于根据预处理命令组装成新的C程序,不过常以i为扩展名。
- 编译: 将得到的i文件翻译成汇编代码。s文件。
- 汇编: 将汇编文件翻译成机器指令,并打包成可重定位目标程序的O文件。该文件是二进制文件,字节编码是机器指令。
- 链接: 将引用的其他O文件并入到我们程序所在的o文件中,处理得到最终的可执行文件。
静态库&&动态库
库分为静态库和动态库两类。在动态库里,又分为动态链接库和动态加载库。
动态库
对于动态链接库而言,build可执行文件的时候需要指定它依赖哪些库,当可执行文件运行时,如果操作系统没有加载过这些库,那就会把这些库随着可执行文件的加载而加载进内存中,供可执行程序运行。如果多个可执行文件依赖同一个动态链接库,那么内存中只会有一份动态链接库的代码,然后把它共享给所有相关可执行文件的进程使用,所以它也叫共享库(shared library)。比如pthread就是一个这样的库。
对于动态加载库而言,build可执行文件的时候就不需要指定它依赖哪些库,当可执行文件运行时,如果需要加载某个库,就用dlopen、dlsym、dlclose等函数来动态地把库加载到内存,并调用库里面的函数。各大软件的插件模块基本上就都是这样的库。事实上,静态库和动态链接库也可以被动态加载,只是由于使用方式的不同,才多了一个动态加载库这样的类别。
linux中静态库和动态库区别:
库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库两种。
- 静态库:这类库的名字一般是
libxxx.a;
利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。 - 动态库:这类库的名字一般是
libxxx.so;
相对于静态函数库,动态函数库在编译的时候 并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。
iOS开发中静态库和动态库区别
- 1.静态库和动态库是相对编译期和运行期的:
- 2.静态库在程序编译时会被链接到目标代码中,程序运行时将不再需要改静态库;
- 3.而动态库在程序编译时并不会被链接到目标代码中,只是在程序运行时才被载入,因为在程序运行期间还需要动态库的存在。
优劣对比
静态库优点:
- i.模块化,分工合作,提高了代码的复用及核心技术的保密程度。
- ii.避免少量改动经常导致大量的重复编译连接。
- iii.也可以重用,注意不是共享使用。
动态库优点:
- i.使用动态库,可以将最终可执行文件体积缩小,将整个应用程序分模块,团队合作,进行分工,影响比较小。
- ii.使用动态库,多个应用程序共享内存中得同一份库文件,节省资源。
- iii.使用动态库,可以不重新编译连接可执行程序的前提下,更新动态库文件达到更新应用程序的目的。
- iv.应用插件化:这个牛逼
- v.软件版本实时模块升级
- vi.共享可执行文件 在其它大部分平台上,动态库都可以用于不同应用间共享,这就大大节省了内存。从目前来看,
iOS
仍然不允许进程间共享动态库,即iOS
上的动态库只能是私有的,因为我们仍然不能将动态库文件放置在除了自身沙盒以外的其它任何地方。不过iOS8
上开放了App Extension功能,可以为一个应用创建插件,这样主app和插件之间共享动态库还是可行的。
Xcode中.framework和.a
语言支持情况
库类型/语言类型 | OC | Swift |
---|---|---|
静态库 | iOS7+ | 不支持 |
动态库 | iOS8+ | iOS8+ |
使用Swift开发动态库的方式提供SDK,所以只能支持到iOS8+。但这意味着所有使用我的SDK的客户的APP都必须到iOS8+,这点需要斟酌一下。
所以假如需要支持iOS7的话,只有使用OC语言开发.a静态库的一条路。
集成第三方库
原本SDK已经作为别人APP工程里的第三方了,假如SDK中需要引用AFNetworking类似的三方库。
库类型/引用 | 内部引用 | 外部引用 |
---|---|---|
静态库 | 静态库无法再包含其他的.a静态库。只能把源码放进去一起编译。 | 静态库无法把第三方放在外部,否则就不叫“静态”了。只能打包进SDK内部,并修改类名,防止外部冲突。 |
动态库 | 如果用Swift 可以直接引入源码,由于Swift 含有命名空间,所以不会有冲突。 |
第三方库不打进去,放在外部,比如cocoapods 的方式。别人编译的时候需要在他的环境里有该第三方依赖库。当提供给别人SDK的时候,你还需要给别人一个podfile。
|
创建静态库
-
1、创建静态库工程
-
2、创建静态库文件
-
3、将头文件暴露出来:将头文件添加到Copy Files中去
-
4、编译静态库:注意:需要修改
Build Settings
中的Build Active Architecture Only
以满足运行不同CPU环境的模拟器。 将此设置为NO。
在不同编译环境下编译会生成四种静态库,debug模拟器,debug真机,release模拟器,release真机,我们需要将运行环境调至不同的状态并生成如上四种形式的静态库。
5、最后不要忘了按住
command+b
编译啊!(分别在模拟器和真机的环境下编译才能生成所对应环境的静态库)-
6、你会看到如下四个目录,这个就成功啦
查看静态库所支持的CPU环境
每一个手机都有属于自己的架构,不同CPU采用的是不同的CPU架构。 任何一个静态库都有它支持的CPU架构,如果是跑在不支持的CPU架构上面,那么就会报错。比如基于iPhone 6sPlus的架构来创建的静态库,如果运行在4s上 就会报错。
修改
Build Settings -- >Build Active Architecture Only
为NO
就解决了这个问题。
在终端中使用 lipo -info
静态库文件 查看文件支持的运行环境
合并静态库
lipo -create 静态库1 静态库2 -output 新静态库名称.a
最后
使用静态库
静态库使用中的一些注意点
如果直接拖拽的是一个项目,并将项目当做一个静态库引用需要这样处理:在
Build Phases
中的Target Dependencies
和Link Binary With Libraries
中分别添加项目。如果仅仅是一个静态库的话,那么
Link Binary WithLibraries
是必须添加的。如果编译的静态库中有分类的话必须在
Build Settings --> Other Linker Flags
中加 -Objc 如果还崩溃,还得加上-all_load
关于在静态库中添加资源,一般使用的是
bundle
文件夹,如何创建呢?很简单先创建一个文件夹,然后将所需资源扔进去,最后将文件夹名称加上后缀bundle
就ok了。注意,默认的静态库编辑是不会将bundle一起编译进去的,所以这个文件夹需要我们手动添加到使用静态库的工程中去。
动态库
1、制作、编译的过程与静态库相同,只不过创建工程的时候选择的是framework库。
-
2、注意:动态库可以使用但是不能上架! 而且使用的时候必须在添加动态库的工程中的
General-->Embedded Binaries
中添加一下,具体如图所示:
-
3、那么如何想使用动态库上架呢? 我们只需要在制作的时候将其编译成静态库。在
Buid Settins-->Mach-O Type--> Static Library
具体如图
动态库的查看与合并
这里有个注意点就是,我们所要查看和合并的并不是xxx.framework
,而是xxx.framework
目录下的xxx
,以下图为例,我们想要查看或合并的文件就是libframework
,对这个文件进行操作就可以了。
参考
制作篇
iOS XCode7制作.Framework动态库和.a静态库的总结
iOS:Xcode7下创建 .a静态库 和 .framework静态库
使用Swift打造动态库SDK和DemoAPP时所遇到的(Xcode7.3)
原理篇