静态库的本质
优质
小牛编辑
130浏览
2023-12-01
验证静态库是.o
文件的合集
相关工具介绍
clang
命令部分参数描述-x: 指定编译文件语言类型 -target: 指定指令集(-target arm64-apple-ios14.3 真机) -g: 生成调试信息 -c: 生成目标文件,只运行preprocess,compile,assemble,不链接 -o: 输出文件 -isysroot: 使用的SDK路径 1. -I<directory> 在指定目录寻找头文件 (header search path) 2. -L<dir> 指定库文件路径(.a\.dylib库文件) (library search path) 3. -l<library_name> 指定链接的库文件名称(.a\.dylib库文件)(other link flags -lAFNetworking) 4. -F<directory> 在指定目录寻找framework (framework search path) 5. -framework <framework_name> 指定链接的framework名称 (other link flags -framework AFNetworking)
在终端中直接进入
lldb
环境来运行可执行文件: 终端lldb环境运行可执行文件
探究.a
静态库
一、准备
在
OCStaticLib
文件夹下准备OCTest.h
和OCTest.m
文件, 代码如下.
h文件#import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface OCTest : NSObject - (void)test:(_Nullable id)example; @end NS_ASSUME_NONNULL_END
.m
文件#import "OCTest.h" @implementation OCTest - (void)test:(_Nullable id)example { NSLog(@"__TestExample"); } @end
外层的
test.m
文件代码#import <Foundation/Foundation.h> #import "OCTest.h" int main() { OCTest *test = [OCTest new]; [test test:nil]; NSLog(@"testApp ------"); return 0; }
代码说明
- 两个简单的
Objective-C
类文件:.h
和.m
- 定义了一个
test:
方法, 执行了一条NSLog
输出语句 .h
文件中对外声明了这个方法test.m
是用于验证能否链接手动修改文件生成的静态库
- 两个简单的
目录结构:
. ├── OCStaticLib │ ├── OCTest.h │ └── OCTest.m └── test.m
二、生成.o
目标文件
执行
clang
命令生成目标文件clang -x objective-c \ -target x86_64-apple-macos11.1 \ -fobjc-arc \ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \ -c OCTest.m \ -o OCTest.o
生成
.o
文件. ├── OCTest.h ├── OCTest.m └── OCTest.o
三、手动修改成静态库文件
即然静态库是
.o
文件的合集, 那么可以理解为一个.o
就是一个合集
在生成的
.o
文件基础上对齐执行以下两步操作- 去掉
.o
后缀 - 增加
lib
前缀 - 增加
.dylib
后缀后回车, 再将.dylib
后缀去掉回车 *
- 去掉
通过
file
命令验证其仍为.o
目标文件/Users/shenyj/Documents/CodeForTest/staticOCLib/OCStaticLib/libOCTest.o: Mach-O 64-bit object x86_64
四、链接这个静态库
链接
静态库
(将.o
手动改成静态库文件命名格式的, 我们模拟的静态库) 文件clang -x objective-c \ -target x86_64-apple-macos11.1 \ -fobjc-arc \ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \ -I./OCStaticLib \ -c test.m \ -o test.o
执行链接操作后, 并没有出现报错或警告, 并且生成了
test.o
目标文件
五、生成可执行文件
将
.o
目标文件生成可执行文件clang -target x86_64-apple-macos11.1 \ -fobjc-arc \ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \ -L./OCStaticLib \ -lOCTest \ test.o -o test
- 这里有个注意点, 在
手动修改成静态库文件-步骤1-3
中, 先为其增加后缀.dylib
确认, 然后在去掉.dylib
后缀, 否则在生成可执行文件时可能会报错 原理:
Big Sur
会保留文件的原始格式- 通过修改后缀让系统将原来的
.o
文件格式(object code
)识别成Unix可执行文件
- 再根据链接静态库的查找规则
先找lib+<library_name>的动态库,找不到,再去找lib+<library_name>的静态库,还找不到,就报错
, 来找到手动生成的静态库
ld: library not found for -lOCTest clang: error: linker command failed with exit code 1 (use -v to see invocation)
- 这里有个注意点, 在
六、终端下进入lldb
环境, 运行可执行文件
输出结果
Process 43324 launched: '/Users/shenyj/Documents/CodeForTest/staticOCLib/test' (x86_64) 2021-01-25 09:11:22.903357+0800 test[43324:1458614] __TestExample 2021-01-25 09:11:22.903693+0800 test[43324:1458614] testApp ------ Process 43324 exited with status = 0 (0x00000000) (lldb)
得出结论
.a
静态库就是.o
文件的集合