动态库和静态库

1. 对 库 格式的探究
2. 对framework 格式的探究,什么是Embed
3. 通过Workspace 实现测试工程
4. dyld 对动态库 查找流程探究 @roath分析
5. 解决冬天哭路径问题
6. 动静态库的链接
复制代码

1. 静态库 和 动态库 区别

最大的区别:

链接方式:(动态链接 、 静态链接)

编译产物:

静态库: 只编译产生 .o 文件的合集

如何链接:静态库.o + App.o => app exec (App的可执行文件)

动态库:
编译产生 .o => 进一步链接 => 最终产生的链接产物(动态库 + 可执行文件)

如何链接:

动态库 和 可执行文件 同级,动态库 -> 在运行的时候 ->通过 路径 + 加载 动态库 (不允许上架)
动态库是允许上架的, 动态库是 framework 格式的, 在于 签名,不能路径替换动态库 实现热更新

动态库(dylib、framework)

如何设置动/静态库:

1. build Settings:  Mach-O Type : Dynamick Library 或者 static Library
2. Podfile : use_frameworks! 动态    #use_frameworks! 静态
复制代码

2.动静态库的链接

  • 动态库 链接 静态库

      已知 cocospods 导入的是源码,编译组件的源码,
      .xcconfig 文件,当前buildSetting,设置编辑器和链接器的参数,通过文件控制buildSetting
    
      主工程 -> header -> public 
      组件   -> header -> public
    复制代码
  • 动态库链接静态库:

      App +  动态库组件(引用  「静态库」 )  
    
      分析:
      动态库 -> .o  经过链接 产生 可执行文件exec
      静态库 .o + app.o  => app . exec
      
      动态库 .o  + 静态库.o => 链接 产生 动态库
    复制代码

问题:符号冲突

		app内 
			void cat_test(){
				nslog(@"cat_test111");
			}

		库内
			void cat_test(){
				nslog(@"cat_test222");
			}
		动态库, 编译链接的过程中冲突的
                编译 、 运行 正常
复制代码

动态库 二级命名空间 -> 当访问符号是 先访问动态库 再访问符号。 再到符号。二级命名空间默认开启

静态库:编译 、 运行 正常
独立的.o 与 app.o 有重名 就冲突
为什么没冲突。
(已知 分类 是动态创建)
ld- 链接静态库 只链接用到的代码,用不到的不链接。没有import文件不会冲突

xcfonfig 配置 -all_load
dumplicate symbol for archive
静态库符号冲突 产生,解决:冲突的符号一个 加前缀

  • 静态库 链接 静态库

App -> (静态库A (静态库B))
App使用 静态库A组件,引用了静态库B
报错undefined B-方法

方法 1
链接成功;

  1. header (api)
  2. 库path xcconfig library_search_path =
  3. 库名称 xcconfig OTHER_lDFLags =

方法2
静态库合并 静态库.o文件的合集
App -> (静态库A .o 静态库B .o)

  • 动态库 链接 动态库

App -> (动态库A (动态库B))

App运行时使用, 通过路径。
报错: dyld 工具
dyld:Library not loaded

Reason: image not found

App 连接 动态库 A 没问题, A链接 动态库B 访问异常
@Rpath
@executable_path 表示可执行程序所在目录
@loader_path mach_o

3. 动态库的 – 反向依赖 :-> 向上依赖 A upword dependency

App使用组件代码,组件里面使用App的代码

原理:真正调起动态库 是在运行的时候,去查找符号,
复制代码
  • dyld :将app的 和 动态库的 间接符号 放到一个位置,
  • 编译过程中 编译成二进制 + 符号分类(没有分配虚拟内存地址),
  • 在链接时 将符号表合并。

所以 动态库也可以通过dyld 去App里查找符号

App内 ZZAppObject.h
如何实现:
xcconfig:header_search_path = (inherited)(inherited) “{SRCROOT}/../XXAPP/”
此时可以查找到

动态库A 定义符号 [[XXAppObject new] testApp];
此时就无法编译 undifine

如何处理
动态库 添加忽略, 运行起来自己处理
OTHER_LDFAGS = (inherited) -Xlinker -U -Xlinker _OBJC_CLASS_XXAppObject

(-U 标记符号 动态查找符号,使dyld 查找动态库和App的镜像)
复制代码

4. 其他

  1. 动态库的符号 ( 懒加载和 非懒加载)不会影响编译,用到去search

  2. oc的动态性体现在 1. 动态创建 2. mach-o 类通过 dylb runtime

  3. 比较

    1. 动态库为什么会影响启动速度,dyld 通过path 加载 动态库(耗时),
    2. App体积:大,
    3. 共享缓存:

    1. 静态库快,是因为与APP结合一起,
    2. App体积:小,链接器 在 链接静态库 时,扫描如果App没有使用到,
    可以在链接时不加载(按需加载)    
    3. 共享缓存
    
复制代码

符号
App在上架时要脱符号,除了间接符号 干掉(全局符号、本地符号)。
动态库 (调试符号、本地符号) 除了全局符号 都可以干掉
静态库

build Setting => Strip Style
App 的 – ( All symbols ) 除了间接符号 干掉(全局符号、本地符号)。
动态库的 Non-Global symbol 除了全局符号 其他的全部脱掉
静态库的 Debuging symbol 只脱掉 debug 符号

*静态库 比 动态库 大的是 链接之后的产物

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享