iOS底层

iOS 动态库(一)

2021-07-15  本文已影响0人  木扬音

动态库是编译器链接的最终产物,系统的动态库是直接存放在手机里面的,一般为tbd格式,tbd文件里面存放了系统动态库具体的位置,通过install_name找到了这个动态库的位置,然后启动时候dyld就知道去哪里加载这个系统动态库。
而我们自己生成的动态库,是需要签名的。在审核中苹果不仅需要你动态库和app的签名一致,而且苹果会在你上架的时候再经过一次AppStore的签名,防止插件化在线更新动态库

什么是tdb格式

-tdb全称text-based stub libraries,本质上就是一个YAML描述文本文件
-作用是用于记录动态库的一些信息,包括导出符号动态库的架构信息动态库依赖信息

准备工作

#import <Foundation/Foundation.h>
#import <AFNetworking.h>

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

链接动态库

我们按照链接静态库的方式来尝试链接动态库

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./AFNetworking \
-c test.m -o 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 \
-L./AFNetworking \
-lAFNetworking
-c test.o -o test

手动生成动态库并链接

#import <Foundation/Foundation.h>

@interface TestExample : NSObject

- (void)lg_test:(_Nullable id)e;

@end


#import "TestExample.h"

@implementation TestExample

- (void)lg_test:(_Nullable id)e {
    NSLog(@"TestExample----");
}

@end
#import <Foundation/Foundation.h>
#import "TestExample.h"

int main(){
    NSLog(@"testApp----");
    TestExample *manager = [TestExample new];
    [manager lg_test: nil];
    return 0;
}
libtool -static -arch_only x86_64 TestExample.o -o libTestExample.a
ld -dylib -arch x86_64 \
-macosx_version_min 11.1 \
-syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk \
-lsystem -framework Foundation \
-all_load \    //导出所有符号
libTestExample.a -o libTestExample.dylib
clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk \
-L./dylib \
-lTestExample \
test.o -o test
脚本

echo "编译test.m --- test.o"
clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk \
-I./dylib \
-c test.m -o test.o

pushd ./dylib
echo "编译TestExample.m --- TestExample.o"
clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk \
-c TestExample.m -o TestExample.o

echo "编译TestExample.o --- libTestExample.a"

# Xcode->静态库
libtool -static -arch_only x86_64 TestExample.o -o libTestExample.a


echo "编译TestExample.m --- libTestExample.dylib"
# -dynamiclib: 动态库
# dylib 最终链接产物 -》
ld -dylib -arch x86_64 \
-macosx_version_min 11.1 \
-syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk \
-lsystem -framework Foundation \
-all_load \
libTestExample.a -o libTestExample.dylib

popd

echo "链接libTestExample.dylib -- test EXEC"
clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk \
-L./dylib \
-lTestExample \
test.o -o test

动态路径

//TestExample 动态库  
otool -l TestExample | grep 'DYLIB' -A 5
image.png
install_name_tool -id /Users/yangyangpeng/Downloads/动态库原理/dylib/TestExample  TestExample
image.png

@rpath

可执行文件会在自己的mach-o中保存@rpathload command,运行时dyld会根据@rpath路径查找动态库,保存一个或多个路径变量

install_name_tool -add_rpath  <路径>  <可执行文件>

@executable_path

@loader_path

动态库链接动态库

当一个可执行文件链接了一个动态库,然后动态库又链接了一个动态库,我们可以使用@loader_path

image.png

导出符号

-Xlinker -reexport_framework -Xlinker framework2
image.png
上一篇 下一篇

猜你喜欢

热点阅读