clang编译器
此文档基于clang的版本(版本比较低是因为这个笔记是在17年写的)是:
Apple LLVM version 9.0.0 (clang-900.0.38)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
clang是C,C ++和Objective-C编译器,包括预处理,解析,优化,代码生成,汇编和链接。通过模式设置(参考阶段选择选项),Clang将在完成链接之前停止。虽然Clang是高度集成的,但重要的是要了解编译的阶段,以了解如何调用它。这些阶段是:
- 驱动程序: clang可执行文件实际上是一个小的驱动程序,它控制其他工具(如编译器,汇编器和链接器)的总体执行。 通常你不需要与驱动程序交互,但你需要通过它来使用其他工具。
- 预处理: 该阶段处理输入源文件的标记化,宏扩展,#include扩展和处理其他预处理指令。这个阶段的输出通常称为a.ia(对于C),a.iia(对于C++),a.mia(用于Objective-C)或a.miia(用于Objective-C++文件)。
- 解析和语义分析: 此阶段解析输入文件,将预处理器令牌转换为解析树。一旦采用解析树的形式,它也将语义分析应用于表达式的计算类型,并确定代码是否形成良好。此阶段负责生成大多数编译器警告以及解析错误。该阶段的输出是抽象语法树(AST)。
- 代码生成和优化: 此阶段将AST转换为低级中间代码(称为LLVM IR),最终将机器代码转换为低级中间代码。此阶段负责优化生成的代码并处理特定于目标的代码生成。此阶段的输出通常称为a.sa文件或汇编文件。Clang还支持使用集成汇编器,代码生成器直接生成对象文件。这避免了生成a.sa文件和调用目标汇编程序的开销。
- 汇编: 此阶段运行目标汇编器将编译器的输出转换为目标对象文件。此阶段的输出通常称为a.oa文件或对象文件。
- 链接: 此阶段运行目标链接器以将多个对象文件合并到可执行文件或动态库中。此阶段的输出通常称为aa.outa,a.dyliba或a.soa文件。
- Clang静态分析器: 它是一个通过扫描代码并找出其中的Bug的静态分析工具。这个工具被Clang驱动器内的其他工具广泛使用。想要知道更多如何使用此工具请点击这里
clang选项
阶段选择选项
选项 | 说明 |
---|
-E | 运行预处理器阶段 |
-fsyntax-only | 运行预处理器,解析器和类型检查阶段 |
-S | 运行以前的阶段以及LLVM生成和优化阶段以及特定于目标的代码生成,生成一个汇编文件 |
-c | 运行上面所有的,加上汇编器,生成一个目标a.oa对象文件 |
-(不选择任何选项) | 如果没有指定阶段选择选项,则运行上述所有阶段,并运行链接器以将结果合并到可执行文件或共享库中 |
语言选择和模式选项
选项 | 说明 |
---|
-x <language> | 将后续输入文件视为具有类型语言 |
-std=<language> | 指定要编译的语言标准 |
-stdlib=<library> | 指定要使用的C ++标准库; 支持的选项是libstdc++和libc++。 如果未指定,将使用平台默认值 |
-rtlib=<library> | 指定要使用的编译器运行时库; 支持的选项是libgcc和compiler-rt。如果未指定,将使用平台默认值 |
-ansi | 与-std=c89 一个意思 |
-ObjC, -ObjC++ | 将源输入文件分别处理为Objective-C和Object-C++输入 |
-trigraphs | 启用trigraphs |
-ffreestanding | 指示该文件应该编译为独立的,而不是托管的环境 |
-fno-builtin | 禁用特殊处理和优化内置函数,如strlen和malloc |
-fmath-errno | 表示数学函数应该被视为更新errno |
-fpascal-strings | 开启支持pascl风格的字符串 |
-fms-extensions | 开启微软扩展 |
-fmsc-version= | 设置_MSC_VER ,在Windows上默认为1300。 否则不设置 |
-fborland-extensions | 开启borland扩展 |
-fwritable-strings | 使所有字符串文字默认为可写。这将禁用字符串和其他优化的定义 |
-flax-vector-conversions | 允许隐式向量转换的松散类型检查规则 |
-fblocks | 启用块语言功能 |
-fobjc-abi-version=version | 选择要使用的Objective-C ABI版本。可用版本为1(遗传性bragilea ABI),2(nonfragile ABI 1)和3(nonfragile ABI 2) |
-fobjc-nonfragile-abi-version=<version> | 选择默认使用的Objective-C nonfragile ABI版本 |
-fobjc-nonfragile-abi, -fno-objc-nonfragile-abi | 使用Objective-C nonfragile ABI(默认)。可以使用-fno-objc-nonfragile-abi禁用它 |
目标选择选项
Clang完全支持交叉编译作为其设计的固有部分。根据您的Clang版本的配置方式,它可能支持多个交叉编译器,也可能仅支持本机目标。
选项 | 说明 |
---|
-arch <architecture> | 指定要构建的体系结构 |
-mmacosx-version-min=<version> | 构建MacOSX时,请指定应用程序支持的最低版本 |
-miphoneos-version-min | 在构建iPhone操作系统时,请指定应用程序支持的最低版本 |
-march=<cpu> | 指定Clang应该为特定的处理器及之后家族成员生成代码。例如如果指定-march=i486 ,则允许编译器生成在i486和更高版本的处理器上有效的指令,但在较早版本中可能不支持 |
代码生成选项
选项 | 说明 |
---|
-fexceptions | 启用展开信息的生成。 这允许通过Clang编译的堆栈帧抛出异常,x86-64平台默认开启 |
-ftrapv | 生成代码来捕获整数溢出错误。有符号的整数溢出在C中未定义。使用此标志会生成额外的代码来检测此异常并在发生时中止 |
-fvisibility | 此标志设置默认可见性级别(符号) |
-fcommon, -fno-common | 该标志指定没有初始化的变量获得默认值,可以使用-fno-common禁用它 |
-ftls-model=<model> | 设置用于线程局部变量的默认线程本地存储(TLS)模型。 有效值为:global-dynamic,local-dynamic,initial-exec和local-exec。 默认值为全局动态。 可以使用tls_model属性覆盖默认模型。 如果可能,编译器将尝试选择一个更有效的模型 |
-O0, -O1, -O2, -O3, -Ofast, -Os, -Oz, -Og, -O, -O4
选项 | 说明 |
---|
-O0 | 意味着没有优化:这个级别编译最快,并生成最可调试的代码 |
-O1 | -O0和-O2之间 |
-O2 | 适中的优化级别,可实现大多数优化 |
-O3 | 像-O2一样,除了它能够执行更长时间的优化或可能生成更大的代码(为了使程序运行更快) |
-Ofast | 启用-O3的所有优化以及可能违反严格遵守语言标准的其他积极优化 |
-Os | 像-O2一样,可以额外优化以减少代码大小 |
-Oz | 像-Os(因此-O2),但是进一步减少代码大小 |
-Og | 像-O1,在将来的版本中为了提高可调试性此选项可能会禁用不同的优化 |
-O | 相当于-O2 |
-O4 | 跟高的优化,目前相当于-O3 |
-g, -gline-tables-only, -gmodules
控制调试信息输出。需要注意的是,Clang调试信息最好结合-O0使用。当出现多个-g选项时选择最后一个。当构建静态库以分发给其他机器时,不应使用此选项,因为调试信息将包含对机器上的模块缓存的引用,该库是建立在库中的对象文件。
选项 | 说明 |
---|
-g | 生成调试信息 |
-gline-tables-only | 仅生成线表调试信息。 这允许具有内联信息的符号回溯,但不包括关于变量、位置或类型的任何信息 |
-gmodules | 生成包含对Clang模块或预编译头文件中定义的类型的外部引用的调试信息,而不是将冗余调试类型信息发送到每个对象文件中。此选项将Clang模块格式透明地转换为将Clang模块与调试信息一起保存的对象文件容器。当编译使用Clang模块或预编译头的程序时,此选项将生成完整的调试信息,具有更快的编译时间和更小的对象文件 |
-fstandalone-debug -fno-standalone-debug
Clang支持一些优化来减少二进制文件中调试信息的大小。 它们基于假设调试类型信息可以分布在多个编译单元上来工作。例如Clang不会为模块不需要的类型发布类型定义,并且可以用forward声明替换。此外Clang只会在包含该类表的模块中发送动态C++类的类型信息
-fstandalone-debug选项关闭这些优化。当使用不带调试信息的第三方库时,这是非常有用的。这是Darwin系统的默认值。需要注意的是Clang将永远不会针对程序没有引用的类型发布类型信息。
-flto, -flto=full, -flto=thin, -emit-llvm
生成LLVM格式的输出文件,适合链接时间优化。当与-S一起使用时,它会生成LLVM中间语言汇编文件,否则会生成LLVM位代码格式对象文件(根据阶段选择选项可将其传递到链接器)。
-flto的默认值为full,其中LLVM位代码适用于单片链路时间优化(LTO),其中链接器将所有这些模块合并到单个组合模块中进行优化。使用Thin,ThinLTO编译代替。
驱动程序选项
选项 | 说明 |
---|
-### | 打印(但不要运行)要编译的命令 |
–help | 显示可用的选项 |
-Qunused-arguments | 不要对未使用的驱动程序参数发出任何警告 |
-Wa,<args> | 传递参数(args)给汇编器 |
-Wl,<args> | 传递参数(args)给连接器 |
-Wp,<args> | 传递参数(args)给预处理器 |
-Xanalyzer <args> | 传递参数(args)静态分析器 |
-Xassembler <args> | 传递参数(args)给汇编器 |
-Xlinker <args> | 传递参数(args)给连接器 |
-Xpreprocessor <args> | 传递参数(args)给预处理器 |
-o <file> | 将输出写入指定文件(file) |
-print-file-name=<file> | 打印这文件(file)完整的库路径 |
-print-libgcc-file-name | 打印当前使用的编译器运行时库的库路径(alibgcc.aa或alibclang_rt.builtins。*.aa) |
-print-prog-name=<name> | 打印(name)完整的程序路径 |
-print-search-dirs | 打印用于查找库和程序的路径 |
-save-temps | 保存中间编译结果 |
-save-stats, -save-stats=cwd, -save-stats=obj | 将内部代码生成(LLVM)统计信息保存到当前目录中的文件(-save-stats/-save-stats=cwd)或输出文件的目录(-save-state=obj) |
-integrated-as, -no-integrated-as | 用于分别启用和禁用集成汇编程序的使用。默认情况下集成汇编程序处于开启状态 |
-time | 时间个人命令 |
-ftime-report | 打印每个阶段编译的总时间 |
-v | 显示运行和使用详细输出的命令(常用于检测命令的正确性) |
诊断选项
这些选项控制Clang如何打印有关诊断(错误和警告)的信息。 有关详细信息,请参阅Clang用户手册
-fshow-column
-fshow-source-location
-fcaret-diagnostics
-fdiagnostics-fixit-info
-fdiagnostics-parseable-fixits
-fdiagnos-tics-print-source-range-info
-fprint-source-range-info
-fdiagnostics-show-option
-fmessage-length
预处理器选项
选项 | 说明 |
---|
-D<macroname>=<value> | 在预处理源文件之前读取的预定义缓冲区中添加隐式#define |
-U<macroname> | 在预处理源文件之前读取的预定义缓冲区中添加一个隐式#undef |
-include <filename> | 在预处理源文件之前读取的预定义缓冲区中添加隐式#include |
-I<directory> | 将指定的目录添加到包含文件的搜索路径 |
-F<directory> | 将指定的目录添加到框架包含文件的搜索路径 |
-nostdinc | 不要在标准系统目录或编译器内置目录中搜索包含文件 |
-nostdlibinc | 不要在标准系统目录中搜索包含文件,而是搜索编译器内置的include目录 |
-nobuiltininc | 不要在clang内置目录搜索包含文件 |
环境变量
选项 | 说明 |
---|
TMPDIR, TEMP, TMP | 这些环境变量按顺序进行检查,以便编写编译过程中使用的临时文件的位置 |
CPATH | 如果此环境变量存在,则将其视为要添加到默认系统包含路径列表的路径分隔列表。分隔符是平台依赖的分隔符,在PATH环境变量中使用 |
C_INCLUDE_PATH, OBJC_INCLUDE_PATH, CPLUS_INCLUDE_PATH, OBJCPLUS_INCLUDE_PATH | 这些环境变量指定了额外的路径,和CPATH一样的功能,不过这些仅用于相应的语言 |
MACOSX_DEPLOYMENT_TARGET | 如果未指定-mmacosx-version-min,则从此环境变量读取默认部署目标。 此选项仅影响Darwin目标 |