命令行选项¶
为了与 cl.exe 兼容,clang-cl 支持大多数相同的命令行选项。这些选项可以以 / 或 - 开头。它还支持一些 Clang 的核心选项,例如 -W 选项。
已知 clang-cl 但目前不支持的选项将被忽略,并显示警告。例如
clang-cl.exe: warning: argument unused during compilation: '/AI'
要抑制有关未使用参数的警告,请使用 -Qunused-arguments 选项。
默认情况下,clang-cl 不认识的选项将被忽略。使用 -Werror=unknown-argument 选项将它们视为错误。如果这些选项以 / 开头,它们将被误认为是文件名
clang-cl.exe: error: no such file or directory: '/foobar'
请 提交错误报告,报告 clang-cl 不理解的任何有效的 cl.exe 标志。
执行 clang-cl /? 以查看支持的选项列表
CL.EXE COMPATIBILITY OPTIONS:
/? Display available options
/arch:
/Brepro- Emit an object file which cannot be reproduced over time
/Brepro Emit an object file which can be reproduced over time
/clang:
/C Don't discard comments when preprocessing
/c Compile only
/d1PP Retain macro definitions in /E mode
/d1reportAllClassLayout Dump record layout information
/diagnostics:caret Enable caret and column diagnostics (on by default)
/diagnostics:classic Disable column and caret diagnostics
/diagnostics:column Disable caret diagnostics but keep column info
/D
/EH
/EP Disable linemarker output and preprocess to stdout
/execution-charset:
Runtime encoding, supports only UTF-8
/E Preprocess to stdout
/FA Output assembly code file during compilation
/Fa
/Fe
/FI
/Fi
/Fo
/fp:except-
/fp:except
/fp:fast
/fp:precise
/fp:strict
/Fp
/GA Assume thread-local variables are defined in the executable
/Gd Set __cdecl as a default calling convention
/GF- Disable string pooling
/GF Enable string pooling (default)
/GR- Disable emission of RTTI data
/Gregcall Set __regcall as a default calling convention
/GR Enable emission of RTTI data
/Gr Set __fastcall as a default calling convention
/GS- Disable buffer security check
/GS Enable buffer security check (default)
/Gs Use stack probes (default)
/Gs
/guard:
or only the table with /guard:cf,nochecks.
Enable EH Continuation Guard with /guard:ehcont
/Gv Set __vectorcall as a default calling convention
/Gw- Don't put each data item in its own section
/Gw Put each data item in its own section
/GX- Disable exception handling
/GX Enable exception handling
/Gy- Don't put each function in its own section (default)
/Gy Put each function in its own section
/Gz Set __stdcall as a default calling convention
/help Display available options
/imsvc
/I
/J Make char type unsigned
/LDd Create debug DLL
/LD Create DLL
/link
/MDd Use DLL debug run-time
/MD Use DLL run-time
/MTd Use static debug run-time
/MT Use static run-time
/O0 Disable optimization
/O1 Optimize for size (same as /Og /Os /Oy /Ob2 /GF /Gy)
/O2 Optimize for speed (same as /Og /Oi /Ot /Oy /Ob2 /GF /Gy)
/Ob0 Disable function inlining
/Ob1 Only inline functions which are (explicitly or implicitly) marked inline
/Ob2 Inline functions as deemed beneficial by the compiler
/Ob3 Same as /Ob2
/Od Disable optimization
/Og No effect
/Oi- Disable use of builtin functions
/Oi Enable use of builtin functions
/Os Optimize for size (like clang -Os)
/Ot Optimize for speed (like clang -O3)
/Ox Deprecated (same as /Og /Oi /Ot /Oy /Ob2); use /O2 instead
/Oy- Disable frame pointer omission (x86 only, default)
/Oy Enable frame pointer omission (x86 only)
/O
/o
/P Preprocess to file
/Qvec- Disable the loop vectorization passes
/Qvec Enable the loop vectorization passes
/showFilenames- Don't print the name of each compiled file (default)
/showFilenames Print the name of each compiled file
/showIncludes Print info about included files to stderr
/source-charset:
/std:
/TC Treat all source files as C
/Tc
/TP Treat all source files as C++
/Tp
/utf-8 Set source and runtime encoding to UTF-8 (default)
/U
/vd
/vmb Use a best-case representation method for member pointers
/vmg Use a most-general representation for member pointers
/vmm Set the default most-general representation to multiple inheritance
/vms Set the default most-general representation to single inheritance
/vmv Set the default most-general representation to virtual inheritance
/volatile:iso Volatile loads and stores have standard semantics
/volatile:ms Volatile loads and stores have acquire and release semantics
/W0 Disable all warnings
/W1 Enable -Wall
/W2 Enable -Wall
/W3 Enable -Wall
/W4 Enable -Wall and -Wextra
/Wall Enable -Weverything
/WX- Do not treat warnings as errors
/WX Treat warnings as errors
/w Disable all warnings
/X Don't add %INCLUDE% to the include search path
/Y- Disable precompiled headers, overrides /Yc and /Yu
/Yc
/Yu
/Z7 Enable CodeView debug information in object files
/Zc:char8_t Enable C++20 char8_t type
/Zc:char8_t- Disable C++20 char8_t type
/Zc:dllexportInlines- Don't dllexport/dllimport inline member functions of dllexport/import classes
/Zc:dllexportInlines dllexport/dllimport inline member functions of dllexport/import classes (default)
/Zc:sizedDealloc- Disable C++14 sized global deallocation functions
/Zc:sizedDealloc Enable C++14 sized global deallocation functions
/Zc:strictStrings Treat string literals as const
/Zc:threadSafeInit- Disable thread-safe initialization of static variables
/Zc:threadSafeInit Enable thread-safe initialization of static variables
/Zc:trigraphs- Disable trigraphs (default)
/Zc:trigraphs Enable trigraphs
/Zc:twoPhase- Disable two-phase name lookup in templates
/Zc:twoPhase Enable two-phase name lookup in templates
/Zi Alias for /Z7. Does not produce PDBs.
/Zl Don't mention any default libraries in the object file
/Zp Set the default maximum struct packing alignment to 1
/Zp
/Zs Run the preprocessor, parser and semantic analysis stages
OPTIONS:
-### Print (but do not run) the commands to run for this compilation
--analyze Run the static analyzer
-faddrsig Emit an address-significance table
-fansi-escape-codes Use ANSI escape codes for diagnostics
-fblocks Enable the 'blocks' language feature
-fcf-protection=
-fcf-protection Enable cf-protection in 'full' mode
-fcolor-diagnostics Use colors in diagnostics
-fcomplete-member-pointers
Require member pointer base types to be complete if they would be significant under the Microsoft ABI
-fcoverage-mapping Generate coverage mapping to enable code coverage analysis
-fcrash-diagnostics-dir=
Put crash-report files in
-fdebug-macro Emit macro debug information
-fdelayed-template-parsing
Parse templated function definitions at the end of the translation unit
-fdiagnostics-absolute-paths
Print absolute paths in diagnostics
-fdiagnostics-parseable-fixits
Print fix-its in machine parseable form
-flto=
-flto Enable LTO in 'full' mode
-fmerge-all-constants Allow merging of constants
-fmodule-file=
Use the specified module file that provides the module
-fmodule-header=
Build
-fmodule-output=
Save intermediate module file results when compiling a standard C++ module unit.
-fms-compatibility-version=
Dot-separated value representing the Microsoft compiler version
number to report in _MSC_VER (0 = don't define it; default is same value as installed cl.exe, or 1933)
-fms-compatibility Enable full Microsoft Visual C++ compatibility
-fms-extensions Accept some non-standard constructs supported by the Microsoft compiler
-fmsc-version=
(0 = don't define it; default is same value as installed cl.exe, or 1933)
-fno-addrsig Don't emit an address-significance table
-fno-builtin-
-fno-builtin Disable implicit builtin knowledge of functions
-fno-complete-member-pointers
Do not require member pointer base types to be complete if they would be significant under the Microsoft ABI
-fno-coverage-mapping Disable code coverage analysis
-fno-crash-diagnostics Disable auto-generation of preprocessed source files and a script for reproduction during a clang crash
-fno-debug-macro Do not emit macro debug information
-fno-delayed-template-parsing
Disable delayed template parsing
-fno-sanitize-address-poison-custom-array-cookie
Disable poisoning array cookies when using custom operator new[] in AddressSanitizer
-fno-sanitize-address-use-after-scope
Disable use-after-scope detection in AddressSanitizer
-fno-sanitize-address-use-odr-indicator
Disable ODR indicator globals
-fno-sanitize-ignorelist Don't use ignorelist file for sanitizers
-fno-sanitize-cfi-cross-dso
Disable control flow integrity (CFI) checks for cross-DSO calls.
-fno-sanitize-coverage=
Disable specified features of coverage instrumentation for Sanitizers
-fno-sanitize-memory-track-origins
Disable origins tracking in MemorySanitizer
-fno-sanitize-memory-use-after-dtor
Disable use-after-destroy detection in MemorySanitizer
-fno-sanitize-recover=
Disable recovery for specified sanitizers
-fno-sanitize-stats Disable sanitizer statistics gathering.
-fno-sanitize-thread-atomics
Disable atomic operations instrumentation in ThreadSanitizer
-fno-sanitize-thread-func-entry-exit
Disable function entry/exit instrumentation in ThreadSanitizer
-fno-sanitize-thread-memory-access
Disable memory access instrumentation in ThreadSanitizer
-fno-sanitize-trap=
Disable trapping for specified sanitizers
-fno-standalone-debug Limit debug information produced to reduce size of debug binary
-fno-strict-aliasing Disable optimizations based on strict aliasing rules (default)
-fobjc-runtime=
-fprofile-exclude-files=
Instrument only functions from files where names don't match all the regexes separated by a semi-colon
-fprofile-filter-files=
Instrument only functions from files where names match any regex separated by a semi-colon
-fprofile-generate=
Generate instrumented code to collect execution counts into a raw profile file in the directory specified by the argument. The filename uses default_%m.profraw pattern
(overridden by LLVM_PROFILE_FILE env var)
-fprofile-generate
Generate instrumented code to collect execution counts into default_%m.profraw file
(overridden by '=' form of option or LLVM_PROFILE_FILE env var)
-fprofile-instr-generate=
Generate instrumented code to collect execution counts into the file whose name pattern is specified as the argument
(overridden by LLVM_PROFILE_FILE env var)
-fprofile-instr-generate
Generate instrumented code to collect execution counts into default.profraw file
(overridden by '=' form of option or LLVM_PROFILE_FILE env var)
-fprofile-instr-use=
Use instrumentation data for coverage testing or profile-guided optimization
-fprofile-use=
Use instrumentation data for profile-guided optimization
-fprofile-remapping-file=
Use the remappings described in
-fprofile-list=
Filename defining the list of functions/files to instrument
-fsanitize-address-field-padding=
Level of field padding for AddressSanitizer
-fsanitize-address-globals-dead-stripping
Enable linker dead stripping of globals in AddressSanitizer
-fsanitize-address-poison-custom-array-cookie
Enable poisoning array cookies when using custom operator new[] in AddressSanitizer
-fsanitize-address-use-after-return=
Select the mode of detecting stack use-after-return in AddressSanitizer: never | runtime (default) | always
-fsanitize-address-use-after-scope
Enable use-after-scope detection in AddressSanitizer
-fsanitize-address-use-odr-indicator
Enable ODR indicator globals to avoid false ODR violation reports in partially sanitized programs at the cost of an increase in binary size
-fsanitize-ignorelist=
Path to ignorelist file for sanitizers
-fsanitize-cfi-cross-dso
Enable control flow integrity (CFI) checks for cross-DSO calls.
-fsanitize-cfi-icall-generalize-pointers
Generalize pointers in CFI indirect call type signature checks
-fsanitize-coverage=
Specify the type of coverage instrumentation for Sanitizers
-fsanitize-hwaddress-abi=
Select the HWAddressSanitizer ABI to target (interceptor or platform, default interceptor)
-fsanitize-memory-track-origins=
Enable origins tracking in MemorySanitizer
-fsanitize-memory-track-origins
Enable origins tracking in MemorySanitizer
-fsanitize-memory-use-after-dtor
Enable use-after-destroy detection in MemorySanitizer
-fsanitize-recover=
Enable recovery for specified sanitizers
-fsanitize-stats Enable sanitizer statistics gathering.
-fsanitize-thread-atomics
Enable atomic operations instrumentation in ThreadSanitizer (default)
-fsanitize-thread-func-entry-exit
Enable function entry/exit instrumentation in ThreadSanitizer (default)
-fsanitize-thread-memory-access
Enable memory access instrumentation in ThreadSanitizer (default)
-fsanitize-trap=
-fsanitize-undefined-strip-path-components=
Strip (or keep only, if negative) a given number of path components when emitting check metadata.
-fsanitize=
behavior. See user manual for available checks
-fsplit-lto-unit Enables splitting of the LTO unit.
-fstandalone-debug Emit full debug info for all types used by the program
-fstrict-aliasing Enable optimizations based on strict aliasing rules
-fsyntax-only Run the preprocessor, parser and semantic analysis stages
-fwhole-program-vtables Enables whole-program vtable optimization. Requires -flto
-gcodeview-ghash Emit type record hashes in a .debug$H section
-gcodeview Generate CodeView debug information
-gline-directives-only Emit debug line info directives only
-gline-tables-only Emit debug line number tables only
-miamcu Use Intel MCU ABI
-mllvm
-nobuiltininc Disable builtin #include directories
-Qunused-arguments Don't emit warning for unused driver arguments
-R
--target=
--version Print version information
-v Show commands to run and use verbose output
-W
-Xclang
/clang: 选项¶
当 clang-cl 使用一组 /clang:
/Zc:dllexportInlines- 选项¶
这将导致类级别的 dllexport 和 dllimport 属性不应用于内联成员函数,因为它们通常会应用。例如,在下面的代码中,S::foo() 通常将由 DLL 定义和导出,但在使用 /Zc:dllexportInlines- 标志时,它不会被导出
struct __declspec(dllexport) S {
void foo() {}
}
这有以下好处:编译器不需要在包含声明的每个翻译单元中生成 S::foo() 的定义,否则它会这样做,以确保 DLL 中存在定义,即使它在那里没有使用。如果声明出现在广泛使用的头文件中,这可以节省大量的编译时间和输出大小。它还减少了 DLL 导出的函数数量,类似于 -fvisibility-inlines-hidden 对 ELF 和 Mach-O 上的共享对象所做的操作。由于函数声明带有内联定义,库用户可以直接使用该定义,而不是从 DLL 中导入它。
请注意,Microsoft Visual C++ 编译器不支持此选项,如果 DLL 中的代码使用 /Zc:dllexportInlines- 编译,则使用 DLL 的代码必须以相同的方式编译,以确保它不会尝试 dllimport 内联成员函数。但是,反向场景通常应该可以工作:使用此标志编译的 DLL(例如,使用 Visual C++ 编译的系统库)可以从使用此标志编译的代码中引用,这意味着引用代码将使用内联定义而不是从 DLL 中导入它们。
还要注意,就像使用 -fvisibility-inlines-hidden 一样,S::foo() 的地址在 DLL 内部和外部将不同,这违反了 C/C++ 标准要求函数具有唯一地址的要求。
此标志不适用于显式类模板实例化定义或声明,因为这些定义通常用于在 DLL 中显式提供单个定义(dllexported 实例化定义),或者用于指示定义在其他地方可用(dllimport 实例化声明)。它也不适用于具有静态局部变量的内联成员,以确保在 DLL 内部和外部使用相同实例的变量。
使用此标志可能会导致问题,当内联函数(否则将被 dllexported)引用 DLL 的内部符号时。例如
void internal();
struct __declspec(dllimport) S {
void foo() { internal(); }
}
通常,对 S::foo() 的引用将使用它从其导出的 DLL 中的定义,该 DLL 也可能包含 internal() 的定义。但是,当使用 /Zc:dllexportInlines- 时,将直接使用 S::foo() 的内联定义,导致链接错误,因为 internal() 不可用。更糟糕的是,如果存在 internal() 的内联定义,其中包含一个静态局部变量,我们现在将引用与 DLL 中不同的实例的该变量
inline int internal() { static int x; return x++; }
struct __declspec(dllimport) S {
int foo() { return internal(); }
}
这可能会导致非常微妙的错误。使用 -fvisibility-inlines-hidden 可能会导致相同的问题。为了避免这种情况,请将 S::foo() 或 internal() 设置为非内联,或显式地标记它们为 dllimport/dllexport。
查找 Clang 运行时库¶
clang-cl 支持几个需要运行时库支持的功能
地址清理器 (ASan):-fsanitize=address
未定义行为清理器 (UBSan):-fsanitize=undefined
代码覆盖率:-fprofile-instr-generate -fcoverage-mapping
配置文件引导优化 (PGO):-fprofile-generate
某些数学运算(int128 除法)需要内置库
为了使用这些功能,用户必须将正确的运行时库链接到他们的程序中。这些库与 Clang 一起分发在库资源目录中。Clang 通过搜索相对于 Clang 可执行文件的位置来搜索资源目录。例如,如果 LLVM 安装在 C:\Program Files\LLVM 中,则配置文件运行时库将位于路径 C:\Program Files\LLVM\lib\clang\11.0.0\lib\windows\clang_rt.profile-x86_64.lib。
对于 UBSan、PGO 和覆盖率,Clang 将生成自动链接相应运行时库的对象文件,但用户通常需要帮助链接器(无论是 lld-link.exe 还是 MSVC link.exe)找到库资源目录。使用上面的示例安装,这意味着将 /LIBPATH:C:\Program Files\LLVM\lib\clang\11.0.0\lib\windows 传递给链接器。如果用户使用 clang 或 clang-cl 驱动程序链接程序,驱动程序将为他们传递此标志。
可以使用 -fno-rtlib-defaultlib 禁用自动链接。如果使用该标志,请像下面针对 ASan 描述的那样,将完整的标志传递给所需库。
如果链接器找不到合适的库,它将发出类似以下错误
$ clang-cl -c -fsanitize=undefined t.cpp
$ lld-link t.obj -dll
lld-link: error: could not open 'clang_rt.ubsan_standalone-x86_64.lib': no such file or directory
lld-link: error: could not open 'clang_rt.ubsan_standalone_cxx-x86_64.lib': no such file or directory
$ link t.obj -dll -nologo
LINK : fatal error LNK1104: cannot open file 'clang_rt.ubsan_standalone-x86_64.lib'
要修复错误,请在链接行中添加适当的 /libpath: 标志。
对于 ASan,截至撰写本文时,用户还负责链接到正确的 ASan 库。
如果用户使用动态 CRT (/MD),则他们应该在链接行中添加 clang_rt.asan_dynamic-x86_64.lib 作为常规输入。对于其他体系结构,请将 x86_64 替换为此处和下面相应的名称。
如果用户使用静态 CRT (/MT),则使用不同的运行时来生成 DLL 和 EXE。要链接 DLL,请传递 clang_rt.asan_dll_thunk-x86_64.lib。要链接 EXE,请传递 -wholearchive:clang_rt.asan-x86_64.lib。
Windows 系统头文件和库查找¶
clang-cl 使用一组不同的方法来定位在构建代码时要链接的正确系统库。Windows 环境使用来自三个不同来源的库
Windows SDK
UCRT(通用 C 运行时)
Visual C++ 工具(VCRuntime)
Windows SDK 提供了针对 Windows 系统包构建程序所需的导入库和头文件。Windows SDK 的基础是 UCRT,即通用 C 运行时。
这种区别可以通过在不同类别中找到的各种头文件来最好地说明。WinSDK 将包含诸如 WinSock2.h 之类的头文件,它是 Windows API 表面的一部分,提供了用于网络的 Windows 套接字接口。UCRT 提供 C 库头文件,包括例如 stdio.h。最后,Visual C++ 工具提供了基础的 Visual C++ 运行时头文件,例如 stdint.h 或 crtdefs.h。
有一些控制允许用户控制 clang-cl 将在哪里定位这些头文件。Windows SDK 和 UCRT 的默认行为如下
查询命令行。
用户指定的任何内容都始终优先。以下扩展是 clang-cl 工具集的一部分
/winsysroot
/winsysroot: 用作 Unix 环境中 -sysroot 的等效项。它允许控制将备用位置视为系统根。指定时,它将用作 Windows Kits 所在的根目录。
/winsdkversion
/winsdkdir
如果未指定 /winsysroot:,则将查询 /winsdkdir: 参数作为位置来识别 Windows SDK 所在的位置。与 /winsysroot: 相反,/winsdkdir: 预计是完整路径,而不是找到 Windows Kits 的根目录。
/winsdkversion: 标志允许用户指定要优先使用的 SDK 的版本标识符。指定此版本后,不会执行其他验证,并将优先使用此版本。如果未指定版本,将使用检测到的最高版本号。
查询环境。
TODO:尚未实现。
这将查询环境变量
WindowsSdkDir
UCRTVersion
回退到注册表。
如果没有使用任何参数来指示 SDK 所在的位置,并且编译器在 Windows 上运行,则将查询注册表以找到安装位置。
Visual C++ 工具集具有稍微更复杂的检测机制。
查询命令行。
/winsysroot
/winsysroot: 用作 Unix 环境中 -sysroot 的等效项。它允许控制将备用位置视为系统根。指定时,它将用作 VC 目录所在的根目录。
/vctoolsdir
/vctoolsversion
如果未指定 /winsysroot:,则将查询 /vctoolsdir: 参数作为位置来识别 Visual C++ 工具所在的位置。如果指定了 /vctoolsversion:,则优先使用该版本,否则,将使用检测到的最高版本。
查询环境。
/external:[VARIABLE]
这指定了一个用户识别的环境变量,该变量被视为路径分隔符 (;) 分隔的路径列表,以映射到 -imsvc 参数中,这些参数被视为 -isystem。
INCLUDE 和 EXTERNAL_INCLUDE
路径分隔符 (;) 分隔的路径列表将被映射到 -imsvc 参数中,这些参数被视为 -isystem。
LIB(间接)
链接器 link.exe 或 lld-link.exe 将遵循环境变量 LIB,该变量是路径分隔符 (;) 设置的路径集,用于在链接最终目标时查询要使用的导入库。
将查询以下环境变量,并使用它们来形成路径,以便根据需要验证和加载内容
VCToolsInstallDir
VCINSTALLDIR
Path
查询 ISetupConfiguration [仅限 Windows]
假设工具链是在定义了 USE_MSVC_SETUP_API 的情况下构建的,并且在 Windows 上运行,则将使用 Visual Studio COM 接口 ISetupConfiguration 来找到 MSVC 工具集的安装位置。
回退到注册表 [已弃用]
注册表信息用于帮助找到安装位置作为最后的回退。这仅适用于 VS2017 之前的安装,并且被认为已弃用。