iOS 静态库&动态库依赖问题

2022-04-13  本文已影响0人  whlpkk

一、库简介

1.1 库的形式

iOS这边库可以分为静态库(Static Library)动态库(Dynamic Library)

1.2 库的区别

下文默认读者具有静态链接&动态链接相关知识,如有不明,请翻阅 mach-o分析 参考

相同点

两种库在构建的过程中,都需要经过编译,会将对应的 .m 文件编译成 .o 文件。这样也就造成了一个问题,任何编译配置宏等已经被展开后编译完成。也就是说,生成库时使用的 Debug 环境生成。即使将来被集成进项目中时,项目内配置 Release 环境出包,不会影响到库的逻辑。因为库中的代码是在生成是已经编译完成的,不随项目代码一起编译。

不同点

  1. 动态库在构建的过程中,需要经过静态链接。这里你没有看错,动态库的生成需要静态链接。而静态库的生成,不需要经过静态链接,仅仅只是简单的将对应的 .o 文件压缩。所以这里也可以通过命令行工具将 .o 文件重新解压缩出来。

    这里我们重点说一下动态库,动态库和我们项目产出的主工程可执行文件对比,其编译、链接等过程是完全一样的。换句话说,动态库是一个没有 main 函数的可执行文件。

  2. 在使用上,动态库是在程序启动运行时,被动态链接后执行调用的。而静态库则参与程序的静态链接,被链入主工程的二进制可执行文件中。这也就是为什么,动态库需要被拷贝内嵌 (embed) 到包内,静态库不需要的原因。

    同样,动态库 A 在被程序动态链接后,动态库 A 如果依赖动态库 B,也会动态链接 B。所以动态库 B 也需要被内嵌到包内,否则会报错“Library not loaded xxx”

1.3 总结

动态库和静态库,在生成时,因为其是否经过静态链接,产生了差异。动态库经过静态链接后,会经过符号决议、重定位等流程,会将依赖的静态库链接进来,也就是说,动态库会吸附静态库。如果依赖的是动态库,则走动态链接的流程。

在使用时,因为动态库只需要动态链接,所以不会在主工程编译阶段报错,但可能在运行阶段报找不到库。静态库则需要被主工程静态链接,所以当缺少符号或者符号重复冲突时,会在编译阶段报错。

这里注意区分库的生成时机、库被主工程引入编译的时机、主工程启动运行后的动态链接时机。

下面列出了库依赖及冲突的各种场景,尝试不看原因,看看是否能独立分析出,出现这种现象的原因。

二、库依赖场景下的符号冲突问题

2.1 两个静态库

2.1.1 两个静态库有相同符号:

2.1.2 静态库 A 依赖静态库 B:

2.2 两个动态库

2.2.1 两个动态库包含相同的符号:

2.2.2 动态库 A 依赖动态库 B:

2.3 一动一静

2.3.1 静态库和动态库包含相同符号:

2.3.2 静态库依赖动态库:

2.3.3 动态库依赖静态库:

上一篇 下一篇

猜你喜欢

热点阅读