iOS 静态库(一)

作者: 木扬音 | 来源:发表于2021-07-12 23:12 被阅读0次

常见库文件格式

  • .a:静态库
  • .dylib:动态库
  • .framework:动、静态库
  • .xcframework:针对不同架构的动、静态库

静态库

静态库是.o文件的合集
我们可以通过ar -t命令来验证

image.png
  • 新建一个test.m文件,并在同级目录下放入AFNetworking静态库
#import <Foundation/Foundation.h>
#import <AFNetworking.h>

int main(){
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    NSLog(@"testApp----%@", manager);
    return 0;
}
image.png

.m文件编译成.o文件

我们通过clang命令来完成编译

  • 我们在生成目标文件的时候只需要头文件的路径,因为链接器会根据重定位符号去查找对应的符号
clang -x objective-c \    //指定oc语言
-target x86_64-apple-macos11.1 \     //指定生成的是X86_64_macOS架构的代码
-fobjc-arc \    //使用ARC
-isysroot     /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk \    //指定SDK的路径
-I./AFNetworking \    //在指定目录寻找头文件 header search path
-c test.m -o test.o      //输出目标文件.o

.o文件链接静态库 生成可以执行文件

clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk \
-L./AFNetworking \  //指定库文件路径(.a\.dylib库文件) library search path
-lAFNetworking \  //指定链接的库文件名称(.a\.dylib库文件)other link flags -lAFNetworking
test.o -o test
  • 生成的可执行文件,我们在终端通过lldb来执行
//1、
lldb
//2、
file test
//3、
run

.o文件转换成静态库

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

 ar -rc  bbb.a bbb.o   -- 将bbb.o转换成静态库bbb.a
     -r:                         -- 将bbb.a添加或者替换文件
     -c:                         -- 不输出任何信息
     -t:                         -- 列出包含的目标文件

静态库合并

libtool -static -o <输出的静态库名字> <需要合并的静态库> <需要合并的静态库>

Framework

Framework是一种打包方式,将库的二进制、头文件和资源文件打包到一起,方便管理和分发
Framework和系统的Framework有很大区别,系统的Framework不需要拷贝到目标程序,自己做的Framework最终都是要拷贝到App中(App和Extension的Bundle是共享的),因此又称为Extension Framework

Framework

手动创建一个Framework

  • 新建TestExample.hTestExample.m

    image.png
  • 通过下面命令将TestExample.m编译成TestExample.o

clang -x objective-c \
-target x86_64-apple-macos11.3 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk \
-c TestExample.m -o TestExample.o
image.png
  • 通过ar命令将TestExample.o转换成 静态库TestExample.a
ar -rc TestExample.a TestExample.o
image.png
  • 按照图中目录结构将文件添加进去


    image.png

下面我们通过链接Framework来测试是否成功

  • 新建test.m
#import <Foundation/Foundation.h>
#import "TestExample.h"

int main(){
    NSLog(@"testApp----");
//    TestExample *manager = [TestExample new];
//    [manager lg_test: nil];
    return 0;
}
image.png
  • 通过下面命令将test.m链接成test.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.3.sdk \
-I./Framework/TestExample.framework/Headers \
-c test.m -o test.o
  • test.o链接TestExample.framework生成可以执行文件
clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk \
-F./Framework \
-framework TestExample \
test.o -o test
image.png
  • 进入lldb环境,运行可执行文件
    image.png

总结

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

//静态库合并
 libtool -static -o <OUTPUT NAME> <LIBRARY_1> <LIBRARY_2>

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

 ar -rc a.a a.o
    -r: 像a.a添加or替换文件
    -c: 不输出任何信息
    -t: 列出包含的目标文件

shell脚本

SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.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}

相关文章

网友评论

    本文标题:iOS 静态库(一)

    本文链接:https://www.haomeiwen.com/subject/rwclpltx.html