动态库与静态库上 (3)

简介: 动态库与静态库上 (3)

动态库与静态库上 (3)


终端命令补充以及Common Symbol


扩展


1. 查看符号命令 man nm
   1. /[关键字] 去搜索,例:/-p
      1. n -> 去下一个搜索的选项
      2. N -> 去上一个搜索的选项
      3. q -> 退出搜索
2. 查看符号命令 nm --help
//不排序, 符号表中的顺序
nm -pa text.o


微信图片_20220509205900.png

image.png


  • Common Symbol : 未定义的全局符号


.a与.framework静态库详解


终端快捷键


常用库文件格式


.a静态 .dylib动态 .framework静态动态 .xcframework2018年推出不同架构的库


库 -> 说白了就是一段编译好的二进制代码, 加上头文件就可以供别人使用.


什么时候会用到库(Libraty)?


  1. 某些代码需要给你别人使用, 但是我们不希望别人看到代码, 就需要以库的形式进行封装, 只暴露出头文件.
  2. 对于某些不会进行大的改动的代码, 我们想减少编译的时间, 就可以把它打包成库, 因为库是已经编译好的二进制了, 编译的时候只需要Link一下, 不会浪费编译时间.


静态库


1. 链接静态库AFNetworking -> 进入AFNetworking -> file libAFNetworking.a
   1. libAFNetworking.a -> archive文档格式
   2. man ar 查看ar的意思 -> ar -t libAFNetworking.a -> 显示.o文件
2. 静态库AFNetworking 链接 test.m 生成目标文件
   1. man clang 查看clang定义
   2. clang -x objective-c \ //指定编译的语音
   -target x86_64-apple-macos11.1 \ //指定编译的平台
   -fobjc-arc \ //arc的环境
   -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \ //指定SDK的路径, 此处是使用的内置的基础库, 需要链接的基础库的路径
   -I./AFNetworking \ //指定链接的库头文件的路径
   -c test.m -o test.o //生成目标文件
3. 通过链接器 生成可执行文件
   1. clang -target x86_64-apple-macos11.1 
   -fobjc-arc
   -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk 
   -L./AFNetworking \ //.o文件的路径, 因为符号保存在.o文件里, -L指定库文件路径(.a.dylib库文件)-lAFNetworking \ //指定链接的库文件名称(.a.dylib库文件)test.o -o test
     1. -lAFNetworking 链接的名称为libTestExample/TestExample的动态库或者静态库,查找规则:先找lib+<library_name>的动态库,找不到,再去找lib+<library_name>的静态库,还找不到,就报错
链接一个库文件的三要素


-I<directory> 在指定目录寻找头文件 -> header search path
-L<dir> 指定库文件路径(.a.dylib库文件)-> library search path
-l<library_name> 指定链接的库文件名称(.a.dylib库文件)-> other link flags

链接静态库AFNetworking命令


命令详解


静态库,.o文件的合集(链接静态库生成可执行文件)


验证静态库是.o文件合集


1. TestExample.m -> TestExample.o
2. TestExample.o -> 改名字libTestExample.dylib(目的变成可执行文件) -> 改名字libTestExample
3. test.m 链接 libTestExample
   1. clang -target x86_64-apple-macos11.1 
      -fobjc-arc 
      -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk 
      -L./StaticLibrary 
      -lTestExample 
      test.o -o test
4. lldb -> 进入lldb的环境
5. file test -> 将test可执行文件包装Target\
6. r -> 证明静态库就是.o文件的合集
7. q -> 退出lldb

扩展


man objdump -> 输出文件信息
objdump --macho --private-header libTestExample.dylib

静态库合并


把所有的.o文件拿过来放在一个.o文件里面


1. man libtool
2. libtool -static -o <OUTPUT NAME> <LIBRARY_1> <LIBRARY_2>
   1. -static \ //合并类型
   2. libtool -static -o libCat.a 库A 库B -> 库A 库B分别解压, 然后合并
      1. 有关重复文件, libtool会帮助处理
      2. 头文件处理,问题所在,怎么处理

mudule


mudule 是clang提供, 来专门处理头文件的. mudule的作用, 预先将.h文件 -> 二进制, 然后缓存(那么每个引入的其他类的头文件,就不用每次都编译, 可以直接拿来用)


链接器的特性,Auto-Link。启用这个特性后,当我们import <模块>,不需要我们再去往链接器去配置链接参数。比如import <framework>我们在代码里使用这个是framework格式的库文件,那么在生成目标文件时,会自动在目标文件的Mach-O中,插入一个 load command格式是LC_LINKER_OPTION,存储这样一个链接器参数-framework <framework>


Framework


Framework 实际是一种打包方式, 将库的二进制文件, 头文件和有关资源打包到一起, 方便管理.

Framework和系统的UIKit.Framework还是有很大区别. 系统的Framework不需要拷贝到目标程序中, 我们自己做出来的Framework哪怕是动态的, 最后也还是要拷贝到APP中(APP和Extension的Bundle是共享的), 因此苹果又把这种Framework称为Embedded Framework.


Framework:


静态库 -> Header + .a + 签名 + 资源文件
动态库 -> Header + .dylib + 签名 + 资源文件
ar命令


ar压缩目标文件,并对其进行编号和索引,形成静态库。同时也可以解压缩静态库,查看有哪些目标文件:

  • ar -rc a.a a.o

  • -r: 像a.a添加or替换文件(有就替换, 没有就添加)
  • -c: 不输出任何信息
  • -t: 列出包含的目标文件


  • ar -rc libTestExample.a libTestExample.o -> 生成.a文件(文中这样写,相当于改个格式)


手动创建Framework


1. 创建.framework结尾的文件夹,例TestFramework.framework
2. 新建的文件夹TestFramework.framework -> 创建Headers文件夹 -> 将.h头文件放入
3. 将编译好的库文件放入TestFramework.framework,并修改名字,去除lib开头(如果有),去除.后缀
4. 测试
   1. 将需要链接的文件生成目标.o文件
   2. clang -x objective-c -fmodules 
      -target x86_64-apple-macos11.1 
      -fobjc-arc 
      -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk 
      -I./Frameworks/TestExample.framework/Headers 
      -c test.m -o test.o
   3. 链接Framework
   4. clang -target x86_64-apple-macos11.1 
      -fobjc-arc 
      -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk 
      -F./Frameworks \ //-F+Frameworks所在的目录
      -framework TestExample \ //要链接的Frameworks的名字
      test.o -o test
   5. lldb
   6. file test
   7. r
   8. q
• -F<directory> 在指定目录寻找framework framework search path
• -framework <framework_name> 指定链接的framework名称 other link flags -framework AFNetworking

shell初探


.sh脚本创建

.sh解释型语言


build

记得给build.h加可执行权限 -> chmod +x ./build.sh -> 然后执行./build.sh

dead_strip与静态库


如果引入头文件, 没有使用, 那么生成的可执行文件, 里面是否包含导入的头文件?

1. objdump --macho -d test
   1. -d 查看__TEXT字段的
   2. 发现没有
2. 使用一下, 再用脚本再生成一下test, 发现有了
3. clang命令是默认dead_strip的
4. 分类会有问题 -> 运行时动态创建的
   1. 查看是否是静态库target -> build Setting -> mach
   2. dead_strip链接的时候生效的

workspace


  1. 可重用性, 多个模块可以在多个项目中使用, 节约开发和维护时间.
  2. 节省测试时间. 单独模块意味着每个模块都可以添加测试功能.
  3. 更好的理解模块化思想.


创建workspace


1. File -> Save As workspace -> TestDeadStrip
2. Add File to workspace -> 添加其他project项目到workspace
   1. 如果选中的有文件, 那么+号选项没有这个选项
   2. 重新从新创建的workspace进入项目
3. 记得先编译库, 再使用库的编译项目
4. 想编译项目的时候,同时编译库文件, 只需将库文件 + 项目的Targets -> General -> Frameworks,Libraries,andEmbedded Content
   1. Embed & sign -> Embed嵌入的意思, 即编译的时候把Framework拷贝到IPA包里
   2. Do Not Embed -> 不拷贝, 因为此处是静态库(链接的过程已经在一起了,不需要)

接上面分类流程, 会报错, 原因就是dead_strip把分类的代码脱离了.


解决办法:


Config.LGApp.Debug


.o文件的合并与.o文件链接静态库的区别


上节遗留问题

.o 和 .o 链接 : 先合并成一个大的.o, 再链接dead_strip生成可执行文件

.o 和 .a 链接 : 先dead_strip去掉多余的


解决:


Targets -> Build Setting -> LTO -> Link-Time Optimization -> Monolithic

编译命令


编译命令




目录
相关文章
|
2月前
|
Linux Windows
静态库和动态库
本文详细介绍了静态库和动态库的概念及使用方法。在 Linux 系统中,静态库以 `libxxx.a` 形式存在,而动态库则为 `libxxx.so`。文章分别讲解了如何创建和使用这两种库,并提供了具体的命令示例。此外,还介绍了将库文件添加到系统目录的方法,包括直接复制到默认库路径、修改环境变量以及编辑系统配置文件等方案。适合初学者了解库文件的基本操作。
|
6月前
|
Linux 编译器 开发者
C/C++动态库与静态库 的详细解析
C/C++动态库与静态库 的详细解析
664 0
|
6月前
|
消息中间件 NoSQL Linux
静态库与动态库
静态库与动态库
静态库与动态库
vs2019使用静态库
vs2019使用静态库
304 0
|
存储 Cloud Native Linux
C++ 动态库与静态库的区别?
C++ 动态库与静态库的区别?
|
存储 Linux 编译器
什么是链接库 | 动态库与静态库
什么是链接库 | 动态库与静态库
163 0
|
Shell 开发工具 iOS开发
动态库下(5)
动态库下(5)
374 0
动态库下(5)
|
Shell 开发工具 C语言
动态库与静态库
本文目标:⭐认识动态静态库,学会结合gcc选项,制作动静态库⭐⭐了解动态库加载过程⭐。
动态库与静态库
|
vr&ar C语言 索引
静态链接和静态库
静态链接和静态库
173 0
vs2019使用动态库
vs2019使用动态库
213 0