链接动态库生成可执行文件

链接动态库.dylib生成可执行文件

1、将.m文件编译生成.o文件

将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/MacOSX.sdk \
-I./dylib \
-c test.m -o test.o

将TestExample.m 编译成TestExample.o

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

2、.o文件生成dylib动态库文件

clang -dynamiclib \
-target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk \
TestExample.o -o libTestExample.dylib

3、.o文件链接动态库,生成可执行文件

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

此时生成的test可执行文件无法执行,因为找不到动态库

4、尝试操作,还是不行

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/MacOSX.sdk \
-lsystem -framework Foundation \
-ObjC \
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/MacOSX.sdk \
-L./dylib \
-lTestExample \
test.o -o test
5、寻找问题原因

使用otool 命令查看test文件mach-header信息

otool -l test | grep 'dylib' -A 3 -I
image-20221208105102189

从上图发现libTestExample.dylib与别的动态库区别是没有路径。

继续使用otool命令查看libTestExample.dylib文件

otool -l libTestExample.dylib | grep 'LC_ID_DYLIB' -A 5
image-20221208110048659

从这里的name可以看出,问题出现在动态库身上

可以之生成dylib文件时加入 -install_name来解决这问题

6、修改dylib文件install_name,或者在生成dylib文件时指定 install_name

install_name_tool -id /Users/xyj/Documents/GitHub/ios_skill_tree/iOS进阶/动静态库原理/链接动态库.dylib文件/dylib/libTestExample.dylib libTestExample.dylib


ld -dylib -arch x86_64 \
-macosx_version_min 11.1 \
-syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk \
-lsystem -framework Foundation \
-ObjC \
-install_name  /Users/xyj/Documents/GitHub/ios_skill_tree/iOS进阶/动静态库原理/链接动态库.dylib文件/dylib/libTestExample.dylib \
libTestExample.a -o libTestExample.dylib

7、重新生成test可执行文件,执行文件

此时能够成功执行文件,但是存在问题是,上一步指定路径是固定路径,换个路径就不行了

使用RPATH对其进行优化

install_name_tool -id @rpath/dylib/libTestExample.dylib libTestExample.dylib

install_name_tool -add_rpath /Users/xyj/Documents/GitHub/ios_skill_tree/iOS进阶/动静态库原理/链接动态库.dylib文件 test

以上给test添加rpath为绝对路径,依然无法移动文件。可以使用executable_path进行优化

install_name_tool -add_rpath @executable_path  test

xcode工程中链接动态库,弱引用链接动态库

在xcconfig中设置几个属性:

  • FRAMEWORK_SEARCH_PATHS: -F ,frmaework 所在的目录
  • HEADER_SEARCH_PATHS: -I :头文件
  • LD_RUNPATH_SEARCH_PATHS: 静态库路径
  • OTHER_LDFLAGS: 静态库名称
// 2. -F: frmaework 所在的目录
FRAMEWORK_SEARCH_PATHS = $(inherited) ${SRCROOT}
// 1. -I :头文件
HEADER_SEARCH_PATHS = $(inherited) ${SRCROOT}/SYTimer.framework/Headers
// 指定 rpath
LD_RUNPATH_SEARCH_PATHS = $(inherited) ${SRCROOT}
// 3. 名称
OTHER_LDFLAGS = $(inherited) -Xlinker -weak_framework -Xlinker "SYTimer" 
//OTHER_LDFLAGS = $(inherited) -framework "SYTimer"

-weak_framework 表示弱引用动态库,设置弱引用后,运行时若找不到动态库实现,则自动置为nil

你可能感兴趣的:(链接动态库生成可执行文件)