动态库与静态库(一)

静态库

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

以获取AFNetworking为例:c++

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

#use_frameworks!
pod 'AFNetworking'
复制代码

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

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

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

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

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放到同一个目录下,例如:ui

图片.png

3.使用clang命令将main.m文件编译成main.o文件spa

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

  • 编译连接生成主工程文件,执行第五、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

复制代码
相关文章
相关标签/搜索