动态库与静态库(一)

1,759 阅读10分钟

静态库

获取第三方静态库方法(参考)

以获取AFNetworking为例:

1.使用cocoaPods安装AFNetworking,在Podfile文件中target下添加

#use_frameworks!
pod 'AFNetworking'

注意#use_frameworks!前面的#号不能省略,否则用的就是动态库

2.终端执行安装命令成功后,打开xcworkspace文件,New Scheme,选中Pods下面的AFNetworking

3.command+B编译一下,找到变成黑色的libAFNetworking.a文件,右键show in Finder

4.将Pods目录下的AFNetworking文件里的AFNetworking文件拷贝出来备用

5.将刚才找到的libAFNetworking.a文件拷贝到备用的AFNetworking文件夹下

链接静态库

1.准备一个main.m文件,添加代码如下:

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

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

2.将AFNetworking文件夹和main.m放到同一个目录下,例如:

图片.png

3.使用clang命令将main.m文件编译成main.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

cd到main.m所在目录,执行下面命令,将main.m编译成main.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./AFNetworking \
-c main.m -o main.o

main.m编译成main.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.指定头文件路径
6.输出目标文件
 

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

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 \
main.o -o main

-lAFNetworking链接的名称为libAFNetworking/AFNetworking的动态库或者静态库

查找规则:先找lib+<library_name>的动态库,找不到,再去找lib+<library_name>的静态库,还找不到,就报错

生成了可执行文件main

双击执行: 打印出AFNetworking相关内容,链接成功

使用脚本文件编译链接

1.创建脚本文件

图片.png 2.将刚才使用过的编译连接命令放build.sh文件内:

echo "======将main.m编译成main.o======start"
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./AFNetworking \
-c main.m -o main.o
echo "======将main.m编译成main.o======end"

echo "======链接静态库生成可执行文件======start"
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 \
main.o -o main
echo "======链接静态库生成可执行文件======end"

3.cd到当前目录下执行

./build.sh

可能会出现

图片.png

这时候执行

chmod +x build.sh

之后再次执行

./build.sh

过程如下:

图片.png 执行结果

图片.png

静态库原理

通过ar命令能够看到libAFNetworking.a这个库文件是.o文件合集。 接下来通过一个例子链接一个.o文件改名的库文件

1.准备工程目录如下:

图片.png

TestStaticLib文件代码:

//TestStaticLib.h代码

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface TestStaticLib : NSObject
-(void)testStaticLib;

@end


//TestStaticLib.m文件代码

#import "TestStaticLib.h"

@implementation TestStaticLib
-(void)testStaticLib
{
    NSLog(@"---testStaticLib---");
}
@end


NS_ASSUME_NONNULL_END

main.m文件代码

#import <Foundation/Foundation.h>
#import "TestStaticLib.h"
int main() {
    TestStaticLib *lib = [TestStaticLib new];
    NSLog(@"test---%@",lib);
    return 0;
}

2.cdTestStaticLib.m所在目录,执行命令:

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 TestStaticLib.m -o TestStaticLib.o

图片.png 使用file查看文件类型

图片.png 3.根据库文件查找规则(先找lib+<library_name>的动态库,找不到,再去找lib+<library_name>的静态库,还找不到,就报错),将TestStaticLib.o文件进行改名为libTestStaticLib.dylib

图片.png 使用file查看文件类型

图片.png 改了名字,还是object类型的文件,如果被链接成功并成功执行,也就说明了静态库是.o文件的合集。

4.cdmain.m所在目录,执行命令:

编译

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./StaticLib \
-c main.m -o main.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./StaticLib \
-lTestStaticLib \
main.o -o main

图片.png 4.双击执行

图片.png 也能够成功执行

动态库

获取第三方动态库方法(参考)

和获取静态库的方式差不多,区别是将#use_frameworks!中的#号去掉

1.使用cocoPods安装AFNetworking,在Podfile文件中target下添加

use_frameworks!
pod 'AFNetworking'

2.终端执行安装命令成功后,打开xcworkspace文件,command+B编译一下,找到AFNetworking.framework

图片.png

3.右键show in Finder,找到AFNetworkingHeaders

图片.png

4.将AFNetworking文件改名为libAFNetworking.dylib,将Headers文件夹命名为AFNetworking,然后将libAFNetworking.dylib放到AFNetworking文件夹内。

改名原因:
链接库查找规则:先找lib+<library_name>的动态库,找不到,再去找lib+<library_name>的静态库,还找不到,就报错

链接动态库

rpath、executable_path的使用

主工程链接一个动态库演示:

1.将链接静态库的main.m文件拿过来和该AFNetworking文件夹放到同一目录下: 图片.png 2.cd到该目录下(这里是链接动态库),执行下面命令,将main.m编译成main.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./AFNetworking \
-c main.m -o main.o

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

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 \
main.o -o main

4.点击生成的可执行文件main,结果如下: 图片.png

从上面的报错可知,dyld @rpath/AFNetworking.framework/Versions/A/AFNetworking路径下找不到库

使用otool命令查看可执行文件main

otool -l main | grep 'DYLIB' -A 5

图片.png

分析:这个(LC_LOAD_DYLIB)路径和报错提示的一致,接下来需要修改这个路径。这个路径是libAFNetworking.dylib提供的,所以要先去修改libAFNetworking.dylib

cd AFNetworking文件夹下,使用otool命令查看可执行文件libAFNetworking.dylib

otool -l libAFNetworking.dylib | grep 'ID' -A 5

图片.png 能够看到main中的LC_LOAD_DYLIB就是libAFNetworking.dylib中的LC_ID_DYLIB,这个路径是默认路径,我们已经修改了文件目录,所以现在需要对其进行修改

5.cdAFNetworking文件夹下,使用install_name_tool命令修改路径。这里需要用到@rpath,可以这样理解,谁要链接动态库,谁就要提供@rpath,它就是自己所在位置,这里是main要链接,所以@rpath就代表main所在目录, 需要修改的路径就是@rpath/AFNetworking/libAFNetworking.dylib

终端执行:

install_name_tool -id @rpath/AFNetworking/libAFNetworking.dylib libAFNetworking.dylib

再次使用otool命令查看

otool -l libAFNetworking.dylib | grep 'ID' -A 5

图片.png 已经修改成功

6.这时候需要重新执行2.3两步,将刚才的修改关联的main上。然后双击可执行文件main

图片.png

发现依旧找不到库,但是路径已经修改过了。其实这里的路径只有后面的一段,还需要前面的一段拼在一起才是完整的路径。这个路径是存在main中的

7.cdmain所在目录,使用otool命令查看RPATH

otool -l main | grep 'RPATH' -A 5

图片.png

并没有内容输出,也就是没有,现在需要添加,添加命令

install_name_tool -add_rpath @executable_path main

@executable_path提供当前可执行文件main的之前的路径 再次使用otool命令查看RPATH

图片.png 已经添加成功了

7.最后双击执行可执行文件main 图片.png 注意点:

  1. 修改库文件中的LC_ID_DYLIB
  2. 编译链接生成主工程文件
  3. 修改主工程文件添加LC_LOAD_DYLIB

使用脚本文件编译链接

对应脚本文件代码:

#pushd到AFNetworking文件下
pushd ./AFNetworking
echo "======修改动态库路径======start"
install_name_tool -id @rpath/AFNetworking/libAFNetworking.dylib libAFNetworking.dylib
echo "======修改动态库路径======end"
#回到上一个目录
popd

echo "======将main.m编译成main.o======start"
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./AFNetworking \
-c main.m -o main.o
echo "======将main.m编译成main.o======end"

echo "======链接静态库生成可执行文件======start"
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 \
main.o -o main
echo "======链接静态库生成可执行文件======end"

echo "======修改可执行文件main路径======start"
install_name_tool -add_rpath @executable_path main
echo "======修改可执行文件main路径======end"

load_path的使用

主工程链接动态库A,动态库A链接动态库B演示:

1.创建工程目录

图片.png 2.添加测试文件及代码 main.m

#import <Foundation/Foundation.h>
#import "myLibA.h"
int main(){
    myLibA *libA = [myLibA new];
    NSLog(@"----libA:%@",libA);
    [libA mylibAClass];
    return 0;
}

myLibA

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

NS_ASSUME_NONNULL_BEGIN

@interface myLibA : NSObject
-(void)mylibAClass;
@end

NS_ASSUME_NONNULL_END

//myLibA.m
#import "myLibA.h"
#import "myLibB.h"
@implementation myLibA
-(void)mylibAClass
{
    NSLog(@"=====MylibAClass");
    myLibB *lib = [myLibB new];
    [lib MylibBClass];
}
@end

myLibB

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

NS_ASSUME_NONNULL_BEGIN

@interface myLibB : NSObject
-(void)MylibBClass;
@end

NS_ASSUME_NONNULL_END

//myLibB.m
#import "myLibB.h"

@implementation myLibB
-(void)MylibBClass
{
    NSLog(@"=====myLibB");
}
@end

3.编译连接myLibB.framework cdmyLibB.framework目录下,执行

编译:

clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-I./Headers \
-c myLibB.m -o myLibB.o

链接:

clang -dynamiclib  \
-target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-Xlinker -install_name -Xlinker @rpath/myLibB.framework/myLibB \
myLibB.o -o myLibB
参数解释:
-Xlinker 传参数给链接器

4.编译连接myLibA.framework cdmyLibA.framework目录下,执行 编译:

clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-I./Headers \
-I./Frameworks/myLibB.framework/Headers \
-c myLibA.m -o myLibA.o

链接:

clang -dynamiclib  \
-target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-Xlinker -install_name -Xlinker @rpath/myLibA.framework/myLibA \
-F./Frameworks \
-framework myLibB \
myLibA.o -o myLibA

这里留个坑,没有添加链接myLibB的执行者路径

5.cdmain.m所在目录,编译连接main.m 编译:

clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-I./Frameworks/myLibA.framework/Headers \
-c main.m -o main.o

链接:

clang   \
-target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-F./Frameworks \
-framework myLibA \
main.o -o main

main添加执行者路径:

install_name_tool -add_rpath @executable_path/Frameworks main

6.双击可执行文件main

图片.png 7.修改myLibALC_RPATH

install_name_tool -add_rpath  @executable_path/Frameworks/myLibA.framework/Frameworks myLibA

图片.png 8.重新执行第5步后双击main 图片.png 运行成功 @executable_path/Frameworks/myLibA.framework看起来比较长,可用@loader_path代替 第7步可改为

install_name_tool -add_rpath  @loader_path/Frameworks myLibA

使用脚本文件编译链接

echo '==========处理myLibB==========start'
pushd ./Frameworks/myLibA.framework/Frameworks/myLibB.framework

clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-I./Headers \
-c myLibB.m -o myLibB.o

clang -dynamiclib  \
-target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-Xlinker -install_name -Xlinker @rpath/myLibB.framework/myLibB \
myLibB.o -o myLibB

popd
echo '==========处理myLibB==========end'

echo '==========处理myLibA==========start'
pushd ./Frameworks/myLibA.framework

clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-I./Headers \
-I./Frameworks/myLibB.framework/Headers \
-c myLibA.m -o myLibA.o



clang -dynamiclib  \
-target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-Xlinker -install_name -Xlinker @rpath/myLibA.framework/myLibA \
-F./Frameworks \
-framework myLibB \
myLibA.o -o myLibA

install_name_tool -add_rpath @loader_path/Frameworks myLibA

popd
echo '==========处理myLibB==========end'

echo '==========处理main==========start'
clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-I./Frameworks/myLibA.framework/Headers \
-c main.m -o main.o

clang   \
-target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-F./Frameworks \
-framework myLibA \
main.o -o main

install_name_tool -add_rpath @executable_path/Frameworks main
echo '==========处理myLibB==========end'

-reexport_framework的使用

基于上个示例,我们知道它们的链接关系是这样的:main-myLibA-myLibB,如果main想调用myLibB里的方法改怎么办?只需要以下3步:

  1. 修改main.m的代码
#import <Foundation/Foundation.h>
#import "myLibA.h"
#import "myLibB.h"
int main(){
    myLibA *libA = [myLibA new];
    NSLog(@"----libA:%@",libA);
    [libA mylibAClass];
    myLibB *libB = [myLibB new];
    NSLog(@"----libB:%@",libB);
    [libB MylibBClass];
    return 0;
}

  1. 将myLibB的符号路径加入myLibA,使用 -reexport_framework`

cd到myLibA.framework文件夹下,执行

clang -dynamiclib  \
-target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-Xlinker -install_name -Xlinker @rpath/myLibA.framework/myLibA \
-Xlinker -reexport_framework -Xlinker myLibB \
-F./Frameworks \
-framework myLibB \
myLibA.o -o myLibA

图片.png main会通过LC_REEXPORT_DYLIB找到myLibB 1.将myLibB的头文件查找路径告诉编译器后,生成新的main cdmain所在目录下执行: 编译:

clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-I./Frameworks/myLibA.framework/Headers \
-I./Frameworks/myLibA.framework/Frameworks/myLibB.framework/Headers \
-c main.m -o main.o

链接:

clang   \
-target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-F./Frameworks \
-framework myLibA \
main.o -o main

main添加执行者路径:

install_name_tool -add_rpath @executable_path/Frameworks main

最后查看程序运行结果:

图片.png

动态库原理

1.准备工程目录

图片.png TestDyLib代码

//TestDyLib.h代码

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface TestDyLib : NSObject
-(void)TestDyLib;

@end

//TestDyLib.m代码

#import "TestDyLib.h"

@implementation TestDyLib
-(void)TestDyLib
{
    NSLog(@"---TestDyLib---");
}
@end

main.m代码

#import <Foundation/Foundation.h>
#import "TestDyLib.h"
int main() {
    TestDyLib *lib = [TestDyLib new];
    NSLog(@"test---%@",lib);
    return 0;
}

2.cd到TestDyLib.m文件所在目录,将TestDyLib.m编译成目标文件:

clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-c TestDyLib.m -o TestDyLib.o

3.使用libtoolTestDyLib.o编译成静态库

libtool -static -arch_only x86_64 TestDyLib.o -o libTestDyLib.a
参数解释:
-static:编译静态库
-arch_only x86_64:架构

4.使用ld链接器将libTestDyLib.a链接成动态库

ld -dylib -arch x86_64 \
-macosx_version_min 11.1 \
-syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-lsystem -framework Foundation \
libTestDyLib.a -o libTestDyLib.dylib
参数解释:
-dylib:链接动态库
-arch_only x86_64:架构
-macosx_version_min 11.1:最小支持版本
syslibroot:使用的SDK路径
-lsystem:依赖系统框架

5.cdmain.m所在目录,编译成目标文件

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

6.链接生成可执行文件

clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-L./dylib \
-lTestDyLib \
main.o -o main

图片.png 发现报错,找不到这个符号。 7.回到dylib目录下,修改链接器参数,再执行

ld -dylib -arch x86_64 \
-macosx_version_min 11.1 \
-syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-lsystem -framework Foundation \
-all_load
libTestDyLib.a -o libTestDyLib.dylib
参数解释:
-all_load:告诉编译器,不管符号有没有被用到,全部都载入

8.执行第6步,成功生成可执行文件main,双击执行

图片.png 出现这个错误就是路径问题,具体见上面的链接动态库部分 解决:

  • 修改库文件中的LC_ID_DYLIB

图片.png

  • 编译链接生成主工程文件,执行第5、6两步

  • 修改主工程文件添加LC_LOAD_DYLIB

图片.png

  • 双击可执行文件main 图片.png 能够看到,能够将静态库链接成动态库。

结论:动态库是.o文件链接过后的产物,是链接的最终产物,它比静态库要多走一次链接的过程。

使用脚本文件编译链接

脚本文件代码:

pushd ./dylib
echo "======TestDyLib编译成目标文件======start"
clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-c TestDyLib.m -o TestDyLib.o
echo "======TestDyLib编译成目标文件======end"


echo "======将TestDyLib.o编译成静态库======start"
# Xcode->静态库
libtool -static -arch_only x86_64 TestDyLib.o -o libTestDyLib.a
echo "======将TestDyLib.o编译成静态库======end"

echo "======将TestDyLib.a链接成动态库======start"
ld -dylib -arch x86_64 \
-macosx_version_min 11.1 \
-syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-lsystem -framework Foundation \
-all_load \
libTestDyLib.a -o libTestDyLib.dylib
echo "======将TestDyLib.a链接成动态库======end"
install_name_tool -id @rpath/dylib/libTestDyLib.dylib libTestDyLib.dylib
popd

echo "======main编译成目标文件======start"
clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-I./dylib \
-c main.m -o main.o
echo "======main编译成目标文件======end"

echo "======链接lTestDyLib.dylib======start"
clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-L./dylib \
-lTestDyLib \
main.o -o main
echo "======链接lTestDyLib.dylib======end"
install_name_tool -add_rpath @executable_path main