将test.m编译成test.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
*/
/**
将test.m编译成test.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. 用到的其他库的头文件地址在./Frameworks
*/
➜ 静态库原理 clang -x objective-c \
-target x86_64-apple-macos12.0 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk \
-I./StaticLibrary \
-c test.m -o test.o
/* 将TestExample.m编译成TestExample.o文件 */
➜ StaticLibrary clang -x objective-c \
-target x86_64-apple-macos12.0 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk \
-I./StaticLibrary \
-c TestExample.m -o TestExample.o
➜ StaticLibrary
编译成.o 文件(目标文件)只需要包含头文件,并且能找到头文件路径即可
之后需要把编译好的TestExample.o
名称修改为libTestExample.a
,直接当做静态库使用(静态库.a文件实际上是.o文件的合集)
或者使用下面的命令把.o打包成静态库
/*
ar 命令用来制作、合并、替换静态库的.o文件
*/
ar -r libTestExample.a TestExample.o
然后开始链接成可执行文件,mach-o文件
/**
test.o链接libTestExample.a生成test可执行文件
-L./StaticLibrary 在当前目录的子目录StaticLibrary查找需要的库文件
-lTestExample 链接的名称为libTestExample/TestExample的动态库或者静态库
查找规则:先找lib+<library_name>的动态库,找不到,再去找lib+<library_name>的静态库,还找不到,就报错
*/
➜ 静态库原理 clang -target x86_64-apple-macos12.0 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk \
-L./StaticLibrary \
-lTestExample \
test.o -o test
➜ 静态库原理 lldb
链接成功后,执行mach-o
lldb
(lldb) file test
Current executable set to '/Users/joe.cheng/Video/静态库/上课代码/静态库原理/test' (x86_64).
(lldb) r
Process 3047 launched: '/Users/joe.cheng/Video/静态库/上课代码/静态库原理/test' (x86_64)
2021-12-30 09:40:07.014602+0800 test[3047:42327] testApp----
2021-12-30 09:40:07.014792+0800 test[3047:42327] TestExample----
Process 3047 exited with status = 0 (0x00000000)
看到打印,运行成功!
使用objdump 命令查看
objdump --macho --private-header test
objdump --private-headers test
test: file format mach-o 64-bit x86-64
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC_64 X86_64 ALL 0x00 EXECUTE 19 2424 NOUNDEFS DYLDLINK TWOLEVEL PIE
Load command 0
整个编译过程脚本:
LANGUAGE=objective-c
TAREGT=x86_64-apple-macos12.0
SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk
FILE_NAME=test
STATICLIBRARY=TestExample
HEAD_PATH=./StaticLibrary
LIBRARY_PATH=./StaticLibrary
echo "-------------编译test.m to test.o------------------"
clang -x $LANGUAGE \
-target $TAREGT \
-fobjc-arc \
-isysroot $SYSROOT \
-I${HEAD_PATH} \
-c ${FILE_NAME}.m -o ${FILE_NAME}.o
echo "-------------进入到StaticLibrary目录------------------"
pushd ${HEAD_PATH}
echo "-------------编译TestExample.m to TestExample.o------------------"
clang -x $LANGUAGE \
-target $TAREGT \
-fobjc-arc \
-isysroot $SYSROOT \
-c ${STATICLIBRARY}.m -o ${STATICLIBRARY}.o
echo "-------------编译TestExample.o to libTestExample.a------------------"
ar -rc lib${STATICLIBRARY}.a ${STATICLIBRARY}.o
echo "-------------退出StaticLibrary目录------------------"
popd
echo "-------------test.o链接libTestExample.a to test EXEC------------------"
clang -target $TAREGT \
-fobjc-arc \
-isysroot $SYSROOT \
-L${LIBRARY_PATH} \
-l${STATICLIBRARY} \
$FILE_NAME.o -o $FILE_NAME
echo "-------------查看 EXEC 文件------------------"
objdump --macho --private-header $FILE_NAME
echo "-------------运行 test EXEC------------------"
# lldb
# file test
# r
网友评论