1. test.m编译链接libAFNetworking.dylib
#import <Foundation/Foundation.h>
#import <AFNetworking.h>
int main(){
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSLog(@"testApp----%@", manager);
return 0;
}
1.1 test.m -> test.o
-I 指定头文件查找路径
1.2 test.o 链接动态库
-l 指定需要链接的库的名称 -L 指定库所在的路径
1.3 运行报错:image not found
2. 链接自定义动态库
2.1 test.m
#import <Foundation/Foundation.h>
#import "TestExample.h"
int main(){
NSLog(@"testApp----");
TestExample *manager = [TestExample new];
[manager lg_test: nil];
return 0;
}
2.2 脚本build.sh
echo "编译test.m --- test.o"
clang -target x86_64-apple-macos10.15 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk \
-I./dylib \
-c test.m -o test.o
pushd ./dylib
echo "编译TestExample.m --- TestExample.o"
clang -target x86_64-apple-macos10.15 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.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.o --- libTestExample.dylib"
# -dynamiclib: 动态库
# dylib 最终链接产物 -》
ld -dylib -arch x86_64
-macosx_version_min 10.15
-syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk \
-lsystem -framework Foundation \
libTestExample.a -o libTestExample.dylib
popd
echo "链接libTestExample.dylib -- test EXEC"
clang -target x86_64-apple-macos10.15 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk \
-L./dylib \
-lTestExample \
test.o -o test
2.3 编译完成后编译,报错undfined
2.4 查看动态库的导出符号
2.5 编译器添加参数-all_load
没有导出符号,修改脚本,静态库链接生成动态库的时候给编译器添加参数-all_load
2.6 重新编译脚本build.sh ,运行 仍然报错 imag not found
3. 项目工程链接tdb库
3.1 xcconfig中配置动态库头文件路径
//-I 参数 动态库头文件路径
HEADER_SEARCH_PATHS = $(inherited) ${SRCROOT}/SYCSSColor/Headers
// -F
//FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking"
//-framework
//OTHER_LDFLAGS = $(inherited) -framework "AFNetworking"
3.2 将tdb动态库拖入工程,编译成功
3.3 运行时 需要找到符号的真实地址,找不到 会报错
4. 动态库与framework
4.1 TestExample.m编译生成动态库TestExample
clang -target x86_64-apple-macos10.15 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk \
-c TestExample.m -o TestExample.o
# -dynamiclib: 动态库
ld -dylib -arch x86_64
-macosx_version_min 10.15
-syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk \
-lsystem -framework Foundation \
TestExample.o -o TestExample
4.2 test.m 编译 链接TestExample动态库
clang -target x86_64-apple-macos10.15 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk \
-I./Frameworks/TestExample.framework/Headers \
-c test.m -o test.o
clang \
-target x86_64-apple-macos10.15 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk \
-F./Frameworks \
-framework TestExample \
test.o -o test
4.3 报错 image not found
4.4 查看test的macho中的LC_LOAD_DYLIB(加载的动态库)
//查找macho中的DYLIB,并显示找到符号之后的的三行
otool -l test | grep 'DYLIB' -A 3
4.5 查看文件类型 file命令
⚠️ 动态库的路径是保存在动态库自己的macho中的
4.6 查看TestExample保存到Macho中的路径
otool -l TestExample | grep 'ID' -A 5
4.7 install_name_tool指定动态库的路径
动态库的路径不完整时,可以通过外部的install_name_tool,在外部改变动态库的路径
修改TestExample动态库的路径(指定绝对路径)
install_name_tool -id /Users/mac/Downloads/动态库/上课代码/动态库与framework/Frameworks/TestExample.framework/TestExample TestExample
重新执行
otool -l TestExample | grep 'ID' -A 5
- test.m 重新链接
TestExample
动态库 ```bash clang -target x86_64-apple-macos10.15 \ -fobjc-arc \ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk \ -I./Frameworks/TestExample.framework/Headers \ -c test.m -o test.o
clang \ -target x86_64-apple-macos10.15 \ -fobjc-arc \ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk \ -F./Frameworks \ -framework TestExample \ test.o -o test
otool -l test | grep ‘DYLIB’ -A 3
![image.png](https://cdn.nlark.com/yuque/0/2021/png/1994311/1611715583205-8c17ffb2-50fc-4b92-bb14-ca81af0d92db.png#align=left&display=inline&height=319&originHeight=472&originWidth=907&size=84834&status=done&style=none&width=613)
> ⚠️ 生成动态库的时候,Macho会生成一个name,保存着动态库的路径到LC_ID_DYLIB,可执行文件去链接动态库的时候,动态库会将LC_ID_DYLIB中的name给到可执行文件,保存到可执行文件的Macho 的LC_LOAD_DYLIB
- 上述从外部修改install_name_tool的方式修改后的是绝对路径,工程修改了存储目录后,会有问题
> install_name_tool可以设置相对路径参数 `@rpath`
> `@rpath(Runpath search Paths)` ,dyld搜索路径,运行`@rpath` 指示 `dyld` 按顺序搜索路径列表,以找到动态库,`@rpath` 保存一个或多个路径变量
- test提供@rpath路径给TestExample
test.m链接TestExample动态库,test提供@rpath路径给TestExample
```bash
//修改LC_ID_DYLIB
install_name_tool -id @rpath/Frameworks/TestExample.framework/TestExample /Users/mac/Downloads/动态库/上课代码/动态库 与framework/Frameworks/TestExample.framework/TestExample
- 然后再test的macho中保存一个@rpath
@rpath使用绝对路径
//往test中添加添加rpath
install_name_tool -add_rpath /Users/mac/Downloads/动态库/上课代码/动态库与framework test
查看test的macho中的rpath
// -i 大小写不敏感
otool -l test | grep 'rpath' -A 3 -i
@rpath使用相对路径:
@executable_path
表示可执行程序所在的目录,解析为可执行文件的绝对路径。@loader_path
表示被加载的Mach-O 所在的目录,每次加载时,都可能被设置为不同的路径,由上层指定
1)@loader_path表示谁来链接动态库,就是谁的目录
install_name_tool -rpath /Users/mac/Downloads/动态库/上课代码/动态库与framework @executable_path test
- 运行 test
- 补充install_name_tool
- xcode中可执行文件的配置文件设置@rpath的路径
LD_RUNPATH_SEARCH_PATHS=$(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'