-
.a与.framework静态库详解
1. 常见库格式
.a .dylib .framework .xcframework
2. 执行顺序
源码 -》编译成目标文件 (.o文件) -》 通过链接器 -》 可执行文件
3. clang :工具合集 终端 man clang 查看具体使用说明。
4. clang 命令学习
生成目标文件 (.o文件)
/**
clang命令参数:
-x: 指定编译文件语言类型
-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
-F<directory> 在指定目录寻找framework framework search path
-framework <framework_name> 指定链接的framework名称 other link flags -framework AFNetworking
*/
/**
将test.m编译成test.o:
1. 使用OC
2. 生成的是X86_64_macOS架构的代码
Big Sur是:x86_64-apple-macos11.1,之前是:x86_64-apple-macos10.15
3. 使用ARC
4. 使用的SDK的路径在:
Big Sur是:/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk
之前是:/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk
5. 用到的其他库的头文件地址在./Frameworks
*/
#param mark 链接AFNetworking动态库
clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-I./AFNetworking \
-c test.m -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./AFNetworking \
-lAFNetworking \
test.o -o test
链接动静态库的三要素:
- -I<directory> 在指定目录寻找头文件 header search path
- -L<dir> 指定库文件路径(.a\.dylib库文件) library search path
- -l<library_name> 指定链接的库文件名称(.a\.dylib库文件)other link flags -lAFNetworking
实战:
证明静态库是.o文件的合集 (见强化2-3天)
objdump 使用 ;查看静态库文件的much_header
objdump --macho --private-header libTestExample.a
libtool 使用 多个.o文件合并成.a文件 。
libtool \
> -static \
> -o \
> libzgr.a \
> libAFNetworking.a \
> libSDWebImage.a
结果:
会出现一些问题: 后续在探究
ar 压缩目标文件, 解压缩静态库
/**
`ar`压缩目标文件,并对其进行编号和索引,形成静态库。同时也可以解压缩静态库,查看有哪些目标文件:
ar -rc a.a a.o
-r: 像a.a添加or替换文件
-c: 不输出任何信息
-t: 列出包含的目标文件
*/
Framework 动静态库组成:
动态库 = header + .dylib + 签名 + 资源文件
静态库 = header + .a + 签名 + 资源文件
shell 初探
通过shell 脚本自动化完成 编译.m文件 成 .o文件 ,.o文件合并链接成可执行文件。代码如下:build.sh
SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk
FILE_NAME=test
HEADER_SEARCH_PATH=./StaticLibrary
echo "-----开始编译test.m"
clang -x objective-c \
-target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot $SYSROOT \
-I${HEADER_SEARCH_PATH} \
-c ${FILE_NAME}.m -o ${FILE_NAME}.o
echo "-----开始进入StaticLibrary"
pushd ./StaticLibrary
clang -x objective-c \
-target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot $SYSROOT \
-c TestExample.m -o TestExample.o
ar -rc libTestExample.a TestExample.o
echo "-----开始退出StaticLibrary"
popd
echo "-----开始test.o to test EXEC"
clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot $SYSROOT \
-L./StaticLibrary \
-lTestExample \
${FILE_NAME}.o -o ${FILE_NAME}
./build.sh 执行脚本,就可以直接生成test执行文件,通过 objdump --macho -d test ,就可以查看test的组成。
分类是运行时动态创建的
dead_strip (也是链接器的一种优化方式)
Xlinker 相关选项了解
-all_load -》 全部都加载进来
-Objc -》 这个flag告诉链接器把库中定义的Objective-C类和Category都加载进来这样编译之后的app会变大(因为加载了其他的objc代码进来)
但是如果静态库中有类和category的话只有加入这个flag才行
-force_load 哪些静态库 -》 dead strip , 强制加载这个静态库
dead_strip : 对工程进行优化,可以指定目标文件加载,
LTO : link Time optimization 链接编译优化。 后期深入
注: _all_load -Objc -force_load 只针对静态库, dead_strip是针对链接的一种优化方式,有本质的不同
核心原理:
// 1. 入口点使用-》没有被使用就会被干掉
// 2. 导出符号使用-》 没有被使用就会被干掉
加上了dead strip优化的脚本代码:
SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk
FILE_NAME=test
HEADER_SEARCH_PATH=./StaticLibrary
echo "-----开始编译test.m"
clang -x objective-c \
-target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot $SYSROOT \
-I${HEADER_SEARCH_PATH} \
-c ${FILE_NAME}.m -o ${FILE_NAME}.o
echo "-----开始进入StaticLibrary"
pushd ./StaticLibrary
clang -x objective-c \
-target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot $SYSROOT \
-c TestExample.m -o TestExample.o
ar -rc libTestExample.a TestExample.o
echo "-----开始退出StaticLibrary"
popd
echo "-----开始test.o to test EXEC"
clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot $SYSROOT \
-Xlinker -dead_strip \
-Xlinker -all_load \
-Xlinker -why_live -Xlinker _global_function \
-L./StaticLibrary \
-lTestExample \
${FILE_NAME}.o -o ${FILE_NAME}