Clang编译命令

298 阅读4分钟

Clang编译命令

生成目标文件

目标文件包含了机器指令代码、数据,链接时需要的信息,符号表、调试信息,字符串表。
  1. 不指定target,默认时Mach-O 64-bit object x86_64
 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

clang -o是将.c源文件编译成为一个可执行的二进制代码(-o选项其实是指定输出文件文件名,如果不加-c选项,clang默认会编译生成可执行文件,文件的名称由-o选项指定)。 clang -c是使用lLVM汇编器将源文件转换成目标代码。 2.指定生成Mach-O 64-bit x86_64目标文件格式

clang -x c -target x86_64-apple-macos10.15 -g -c a.c -o a.o

3. 如果指定target不带apple系统版本(包括macOS,ipadOS,iOS,真机和模拟器)。例如x86_64,那么生成的目标文件是Linux的ELF 64-bit:

clang -x c -target x86_64 -g -c a.c -o a.o

4. 编译.m

/**
    将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-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-I./StaticLibrary \
-c test.m -o test.o

5. 编译

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

/**
    test.o链接libTestExample.a生成test可执行文件
    -L./StaticLibrary 在当前目录的子目录StaticLibrary查找需要的库文件
    -lTestExample 链接的名称为libTestExample/TestExample的动态库或者静态库
    查找规则:先找lib+<library_name>的动态库,找不到,再去找lib+<library_name>的静态库,还找不到,就报错
 */
clang -target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-L./StaticLibrary \
-lTestExample \
test.o -o test

/**
    test.o链接libTestExample.a生成test可执行文件
    -L./StaticLibrary 在当前目录的子目录StaticLibrary查找需要的库文件
    -lTestExample 链接的名称为libTestExample/TestExample的动态库或者静态库
    查找规则:先找lib+<library_name>的动态库,找不到,再去找lib+<library_name>的静态库,还找不到,就报错
    -syslibroot: 系统库文件的目录
 */
ld -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk -lsystem -framework Foundation -lTestExample -L./StaticLibrary test.o -o test


/**
    将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/TestExample.framework/Headers
 */
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./Frameworks/TestExample.framework/Headers \
-c test.m -o test.o


/**
    test.o链接TestExample.framework生成test可执行文件
    -F./Frameworks 在当前目录的子目录Frameworks查找需要的库文件
    -framework TestExample 链接的名称为TestExample.framework的动态库或者静态库
    查找规则:先找TestExample.framework的动态库,找不到,再去找TestExample.framework的静态库,还找不到,就报错
 */
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 TestExample \
test.o -o test

clang -x objective-c -fmodules \
-target x86_64-apple-macos11.1 \
-fobjc-arc \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
-I./Frameworks/TestExample.framework/Headers \
-c test.m -o test.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 TestExample \
test.o -o test

/**
 LC_LINKER_OPTION

链接器的特性,`Auto-Link`。启用这个特性后,当我们`import <模块>`,不需要我们再去往链接器去配置链接参数。比如`import <framework>`我们在代码里使用这个是framework格式的库文件,那么在生成目标文件时,会自动在目标文件的`Mach-O`中,插入一个 `load command`格式是`LC_LINKER_OPTION`,存储这样一个链接器参数`-framework <framework>`。
 */

/**
 `ar`压缩目标文件,并对其进行编号和索引,形成静态库。同时也可以解压缩静态库,查看有哪些目标文件:
 ar -rc a.a a.o
    -r: 像a.a添加or替换文件
    -c: 不输出任何信息
    -t: 列出包含的目标文件
 */

/**
    libtool -static -o <OUTPUT NAME> <LIBRARY_1> <LIBRARY_2>
 */

生成目标文件的过程中发生了什么?
  • 编译器(clang-cl) --> 汇编器(llvm-as)
  • 链接器(llvm-ld)并没有被执行
  • 所以输出的目标文件不会包含Unix程序在被装载和执行时所必须包含信息,但它以后可以被链接到一个程序。
Mach-O File Format
  • 一个Mach-O文件有两部分组成:header和data。
  • header:代表了文件的映射,描述了文件的内容以及文件所有内容所在的位置。
  • data: 紧跟header之后,由多个二进制组成,one by one

快捷键

截屏2025-05-15 21.28.51.png

截屏2025-05-15 21.30.09.png

截屏2025-05-15 21.30.28.png