Codegen 选项

所有这些选项都通过 -C 标志传递给 rustc-C 是 "codegen" 的缩写。您可以通过运行 rustc -C help 来查看适用于您当前编译器的此列表版本。

ar

此选项已弃用,不起任何作用。

code-model

此选项允许您选择要使用的代码模型。
代码模型对程序及其符号可能使用的地址范围施加约束。
使用较小的地址范围,机器指令可能能够使用更紧凑的寻址模式。

具体范围取决于目标架构和可用于它们的寻址模式。
对于 x86,有关其代码模型的更详细描述可以在 System V 应用程序二进制接口 规范中找到。

此选项支持的值为

  • tiny - Tiny 代码模型。
  • small - Small 代码模型。这是大多数受支持目标的默认模型。
  • kernel - Kernel 代码模型。
  • medium - Medium 代码模型。
  • large - Large 代码模型。

也可以通过运行 rustc --print code-models 来发现支持的值。

codegen-units

此标志控制 crate 被拆分成的最大代码生成单元数。它接受一个大于 0 的整数。

当 crate 被拆分成多个 codegen 单元时,LLVM 能够并行处理它们。增加并行性可能会加快编译速度,但也可能产生较慢的代码。将其设置为 1 可能会提高生成代码的性能,但编译速度可能会较慢。

如果未指定,则非增量构建的默认值为 16。对于增量构建,默认值为 256,这允许更精细的缓存。

collapse-macro-debuginfo

此标志控制在为此 crate 生成 debuginfo 时,是否将宏定义中的代码位置折叠到与该宏调用站点关联的单个位置。

如果传递此选项,它将覆盖默认的折叠行为和代码中的 #[collapse_debuginfo] 属性。

  • yyesontrue:在 debuginfo 中折叠代码位置。
  • nnoofffalse:不在 debuginfo 中折叠代码位置。
  • external:仅当宏来自不同的 crate 时,才在 debuginfo 中折叠代码位置。

control-flow-guard

此标志控制 LLVM 是否启用 Windows Control Flow Guard 平台安全功能。对于非 Windows 目标,此标志当前被忽略。它接受以下值之一

  • yyesontruechecks 或无值:启用 Control Flow Guard。
  • nochecks:发出 Control Flow Guard 元数据,但不进行运行时强制检查(这仅应用于测试目的,因为它不提供安全强制)。
  • nnoofffalse:不启用 Control Flow Guard(默认值)。

debug-assertions

此标志允许您打开或关闭 cfg(debug_assertions) 条件编译。它接受以下值之一

  • yyesontrue 或无值:启用 debug-assertions。
  • nnoofffalse:禁用 debug-assertions。

如果未指定,则仅当 opt-level 为 0 时,才自动启用 debug assertions。

debuginfo

此标志控制调试信息的生成。它接受以下值之一

  • 0none:完全没有调试信息(默认值)。
  • line-directives-only:仅行信息指令。对于 nvptx* 目标,这将启用 性能分析。对于其他用例,line-tables-only 是更好、更兼容的选择。
  • line-tables-only:仅行表。生成最少量的调试信息,用于包含文件名/行号信息的回溯,但不包含任何其他信息,即没有变量或函数参数信息。
  • 1limited:不包含类型或变量级别信息的调试信息。
  • 2full:完整的调试信息。

注意:-g 标志-C debuginfo=2 的别名。

default-linker-libraries

此标志控制链接器是否包含其默认库。它接受以下值之一

  • yyesontrue:包含默认库。
  • nnoofffalse 或无值:排除默认库(默认值)。

例如,对于 gcc 风格的链接器,这将向链接器发出 -nodefaultlibs 标志。

dlltool

windows-gnu 目标上,当使用 raw-dylib 链接类型 时,此标志控制 rustc 调用哪个 dlltool 来生成导入库。它接受一个指向 dlltool 可执行文件 的路径。如果未指定此标志,则将根据主机环境和目标推断 dlltool 可执行文件。

embed-bitcode

此标志控制编译器是否将 LLVM bitcode 嵌入到目标文件中。它接受以下值之一

  • yyesontrue 或无值:将 bitcode 放入 rlibs 中(默认值)。
  • nnoofffalse:从 rlibs 中省略 bitcode。

当 rustc 执行链接时优化 (LTO) 时,需要 LLVM bitcode。嵌入的 bitcode 将出现在 rustc 生成的目标文件的某个节中,该节的名称由目标平台定义。大多数情况下,这是 .llvmbc

如果您的编译实际上不需要 bitcode(例如,如果您不执行 LTO),则使用 -C embed-bitcode=no 可以显着提高编译速度并减小生成的文件大小。出于这些原因,Cargo 尽可能使用 -C embed-bitcode=no。同样,如果您直接使用 rustc 构建,我们建议您在不使用 LTO 时始终使用 -C embed-bitcode=no

如果与 -C lto 结合使用,-C embed-bitcode=no 将导致 rustc 在启动时中止,因为这种组合无效。

注意:如果您正在使用 LTO 构建 Rust 代码,那么您可能甚至不需要启用 embed-bitcode 选项。您可能需要使用 -Clinker-plugin-lto,它会跳过完全生成目标文件,而只是用 LLVM bitcode 替换目标文件。-Cembed-bitcode 的唯一用途是当您生成一个 rlib,该 rlib 同时用于 LTO 和非 LTO 时。例如,Rust 的标准库附带嵌入式 bitcode,因为用户在有 LTO 和没有 LTO 的情况下都链接到它。

这也可能让您想知道为什么此选项的默认值为 yes。原因是 rustc 1.44 及更早版本就是这样。在 1.45 版本中,添加了此选项以关闭一直是默认设置的功能。

extra-filename

此选项允许您在每个输出文件名中放置额外的数据。它接受一个字符串,作为后缀添加到文件名中。有关更多信息,请参阅 --emit 标志

force-frame-pointers

此标志强制使用帧指针。它接受以下值之一

  • yyesontrue 或无值:强制启用帧指针。
  • nnoofffalse:不强制启用帧指针。这并不一定意味着将删除帧指针。

如果未强制启用帧指针,则默认行为取决于目标。

force-unwind-tables

此标志强制生成展开表。它接受以下值之一

  • yyesontrue 或无值:强制生成展开表。
  • nnoofffalse:不强制生成展开表。如果目标需要展开表,则会发出错误。

如果未指定,则默认值取决于目标。

incremental

此标志允许您启用增量编译,这允许 rustc 在编译 crate 后保存信息,以便在重新编译 crate 时重用,从而缩短重新编译时间。它接受一个目录路径,用于存储增量文件。

inline-threshold

此选项已弃用,不起任何作用。

考虑使用 -Cllvm-args=--inline-threshold=...

instrument-coverage

此选项启用基于插桩的代码覆盖率支持。有关更多信息,请参阅关于 基于插桩的代码覆盖率 的章节。

请注意,虽然 -C instrument-coverage 选项是稳定的,但由此产生的插桩生成的配置文件数据格式可能会更改,并且可能不适用于编译器构建和发布的覆盖率工具以外的其他工具。

此标志允许您向链接器调用附加单个额外的参数。

"附加" 很重要;您可以多次传递此标志以添加多个参数。

此标志允许您向链接器调用附加多个额外的参数。选项应以空格分隔。

此标志控制链接器是否保留死代码。它接受以下值之一

  • yyesontrue 或无值:保留死代码。
  • nnoofffalse:删除死代码(默认值)。

此标志可能有用的一种情况是尝试构建代码覆盖率指标时。

windows-gnulinux-muslwasi 目标上,此标志控制链接器是否使用 Rust 附带的库和对象,而不是系统中的库和对象。它接受以下值之一

  • 无值:如果系统具有必要的工具,则 rustc 将使用启发式方法禁用自包含模式。
  • yyesontrue:仅使用 Rust 附带的库/对象。
  • nnoofffalse:依赖用户或链接器来提供非 Rust 库/对象。

这允许在检测失败或用户想要使用附带的库时覆盖这些情况。

linker

此标志控制 rustc 调用哪个链接器来链接您的代码。它接受一个指向链接器可执行文件的路径。如果未指定此标志,则将根据目标推断链接器。另请参阅 linker-flavor 标志以了解指定链接器的另一种方法。

linker-flavor

此标志控制 rustc 使用的链接器风格。如果使用 -C linker 标志 给出了链接器,则链接器风格将从提供的值中推断出来。如果未给出链接器,则链接器风格用于确定要使用的链接器。每个 rustc 目标默认为某种链接器风格。有效选项包括

  • em:使用 Emscripten emcc
  • gcc:使用 cc 可执行文件,这在许多系统上通常是 gcc 或 clang。
  • ld:使用 ld 可执行文件。
  • msvc:使用 Microsoft Visual Studio MSVC 中的 link.exe 可执行文件。
  • wasm-ld:使用 wasm-ld 可执行文件,这是 LLVM lld 为 WebAssembly 移植的版本。
  • ld64.lld:使用 LLVM lld 可执行文件,并带有用于 Apple 的 ld-flavor darwin 标志
  • ld.lld:使用 LLVM lld 可执行文件,并带有用于 GNU binutils 的 ld-flavor gnu 标志
  • lld-link:使用 LLVM lld 可执行文件,并带有用于 Microsoft 的 link.exe-flavor link 标志

linker-plugin-lto

此标志将 LTO 优化推迟到链接器。有关更多详细信息,请参阅 linker-plugin-LTO。它接受以下值之一

  • yyesontrue 或无值:启用链接器插件 LTO。
  • nnoofffalse:禁用链接器插件 LTO(默认值)。
  • 链接器插件的路径。

更具体地说,此标志将导致编译器将其典型的目标文件输出替换为 LLVM bitcode 文件。例如,使用 -Clinker-plugin-lto 生成的 rlib 仍然包含 *.o 文件,但它们都将是 LLVM bitcode 而不是实际的机器代码。预计本机平台链接器能够加载这些 LLVM bitcode 文件并在链接时生成代码(通常在执行优化之后)。

请注意,rustc 也可以读取其自身使用 -Clinker-plugin-lto 生成的目标文件。如果 rlib 仅在以后与 -Clto 编译一起使用,则可以传递 -Clinker-plugin-lto 以加快编译速度并避免生成未使用的目标文件。

llvm-args

此标志可用于将参数列表直接传递给 LLVM。

列表必须以空格分隔。

传递 --help 以查看选项列表。

lto

此标志控制 LLVM 是否使用 链接时优化 来生成更好的优化代码,使用程序整体分析,但代价是链接时间更长。它接受以下值之一

  • yyesontruefat 或无值:执行 “fat” LTO,它尝试跨依赖关系图中的所有 crate 执行优化。
  • nnoofffalse:禁用 LTO。
  • thin:执行 “thin” LTO。这与 “fat” 类似,但运行时间明显更少,同时仍能实现与 “fat” 类似的性能提升。

如果未指定 -C lto,则编译器将尝试执行 “thin local LTO”,它仅在其 codegen 单元 上对本地 crate 执行 “thin” LTO。当未指定 -C lto 时,如果 codegen 单元为 1 或禁用优化 (-C opt-level=0),则禁用 LTO。也就是说

  • 当未指定 -C lto
    • codegen-units=1:禁用 LTO。
    • opt-level=0:禁用 LTO。
  • 当指定 -C lto
    • lto:16 个 codegen 单元,跨 crate 执行 fat LTO。
    • codegen-units=1 + lto:1 个 codegen 单元,跨 crate 执行 fat LTO。

另请参阅 linker-plugin-lto 以了解跨语言 LTO。

metadata

此选项允许您控制用于符号修饰的元数据。这接受一个以空格分隔的字符串列表。修饰的符号将包含元数据的哈希值。例如,这可以用于区分链接的同一 crate 的两个不同版本之间的符号。

no-prepopulate-passes

此标志告诉 pass 管理器使用空的 pass 列表,而不是通常的预填充 pass 列表。

no-redzone

此标志允许您禁用 red zone。它接受以下值之一

  • yyesontrue 或无值:禁用 red zone。
  • nnoofffalse:启用 red zone。

如果未指定标志,则默认行为取决于目标。

no-stack-check

此选项已弃用,不起任何作用。

no-vectorize-loops

此标志禁用 循环向量化

no-vectorize-slp

此标志禁用使用 超字级并行 的向量化。

opt-level

此标志控制优化级别。

  • 0:不进行优化,还会启用 cfg(debug_assertions)(默认值)。
  • 1:基本优化。
  • 2:一些优化。
  • 3:所有优化。
  • s:为二进制文件大小进行优化。
  • z:为二进制文件大小进行优化,但也关闭循环向量化。

注意:-O 标志-C opt-level=2 的别名。

默认值为 0

overflow-checks

此标志允许您控制 运行时整数溢出 的行为。启用 overflow-checks 后,发生溢出时会发生 panic。此标志接受以下值之一

  • yyesontrue 或无值:启用溢出检查。
  • nnoofffalse:禁用溢出检查。

如果未指定,则如果启用了 debug-assertions,则启用溢出检查,否则禁用。

panic

此选项允许您控制代码 panic 时发生的情况。

  • abort:在 panic 时终止进程
  • unwind:在 panic 时展开堆栈

如果未指定,则默认值取决于目标。

passes

此标志可用于向编译添加额外的 LLVM passes

列表必须以空格分隔。

另请参阅 no-prepopulate-passes 标志。

prefer-dynamic

默认情况下,rustc 倾向于静态链接依赖项。如果静态和动态版本的库都可用,则此选项将指示应尽可能使用动态链接。

有一个 内部算法 用于确定是否可以静态或动态链接依赖项。

此标志接受以下值之一

  • yyesontrue 或无值:首选动态链接。
  • nnoofffalse:首选静态链接(默认值)。

profile-generate

此标志允许创建插桩二进制文件,这些文件将收集性能分析数据,以用于配置文件引导的优化 (PGO)。该标志接受一个可选参数,该参数是目录的路径,插桩二进制文件将向该目录发出收集的数据。有关更多信息,请参阅关于 配置文件引导的优化 的章节。

profile-use

此标志指定用于配置文件引导的优化 (PGO) 的性能分析数据文件。该标志接受一个强制性参数,该参数是有效 .profdata 文件的路径。有关更多信息,请参阅关于 配置文件引导的优化 的章节。

relocation-model

此选项控制 位置无关代码 (PIC) 的生成。

此选项支持的值为

主要重定位模型

  • static - 不可重定位的代码,机器指令可以使用绝对寻址模式。

  • pic - 完全可重定位的位置无关代码,机器指令需要使用相对寻址模式。
    相当于其他编译器中的 “大写” -fPIC-fPIE 选项,具体取决于生成的 crate 类型。
    这是大多数受支持目标的默认模型。

  • pie - 位置无关可执行文件,可重定位的代码,但不支持符号拦截(使用 LD_PRELOAD 和类似方法按名称替换符号)。相当于其他编译器中的 “大写” -fPIE 选项。pie 代码无法链接到共享库中(尝试这样做会收到链接错误)。

特殊重定位模型

  • dynamic-no-pic - 可重定位的外部引用,不可重定位的代码。
    仅在 Darwin 上有意义,并且很少使用。
    如果 StackOverflow 告诉您使用此选项作为 PIC 或 PIE 的退出选项,请不要相信它,请改用 -C relocation-model=static
  • ropirwpiropi-rwpi - 分别是可重定位的代码和只读数据、可重定位的读写数据以及两者的组合。
    仅对某些嵌入式 ARM 目标有意义。
  • default - 重定位模型默认为当前目标。
    仅当作为先前在命令行上设置的某些其他显式指定的重定位模型的覆盖时才有意义。

也可以通过运行 rustc --print relocation-models 来发现支持的值。

链接效果

除了 codegen 效果外,relocation-model 在链接期间也有效。

如果重定位模型为 pic 并且当前目标支持位置无关可执行文件 (PIE),则将指示链接器 (-pie) 生成一个。
如果目标不支持位置无关和静态链接的可执行文件,则 -C target-feature=+crt-static “胜过” -C relocation-model=pic,并且指示链接器 (-static) 生成静态链接但非位置无关的可执行文件。

relro-level

此标志控制启用的 RELRO(重定位只读)级别。RELRO 是一种漏洞缓解措施,它使全局偏移表 (GOT) 变为只读。

此选项支持的值为

  • off:动态链接的函数会被延迟解析,并且 GOT 是可写的。
  • partial:动态链接的函数会被延迟解析,并写入 GOT 的过程链接表 (PLT) 部分 (.got.plt)。GOT 的非 PLT 部分 (.got) 将变为只读,并且两者都会移动以防止缓冲区溢出写入。
  • full:动态链接的函数会在程序执行开始时解析,全局偏移表 (.got/.got.plt) 会被急切地填充,然后变为只读。GOT 也会移动以防止缓冲区溢出写入。Full RELRO 会使用更多内存并增加进程启动时间。

在不支持 RELRO 的平台(不使用 ELF 二进制格式的目标),例如 Windows 或 macOS 上,此标志将被忽略。每个 rustc 目标都有其自己的 RELRO 默认值。rustc 在支持 Full RELRO 的平台上默认启用它。

remark

此标志允许您打印优化 passes 的备注。

pass 列表应以空格分隔。

all 将备注每个 pass。

rpath

此标志控制是否启用 rpath。它接受以下值之一

  • yyesontrue 或无值:启用 rpath。
  • nnoofffalse:禁用 rpath(默认值)。

save-temps

此标志控制编译期间生成的临时文件在编译完成后是否删除。它接受以下值之一

  • yyesontrue 或无值:保存临时文件。
  • nnoofffalse:删除临时文件(默认值)。

soft-float

此选项控制 rustc 是否生成在软件中模拟浮点指令的代码。它接受以下值之一

  • yyesontrue 或无值:使用软浮点。
  • nnoofffalse:使用硬件浮点(默认值)。

split-debuginfo

此选项控制为 rustc 生成的调试信息发出 “split debuginfo”。此选项的默认行为特定于平台,并非此选项的所有可能值都适用于所有平台。可能的值为

  • off - 这是具有 ELF 二进制文件和 windows-gnu 的平台的默认设置(不是 Windows MSVC,也不是 macOS)。这通常意味着可以在可执行文件的节中的最终工件中找到 DWARF 调试信息。Windows MSVC 不支持此选项。在 macOS 上,此选项可防止最终执行 dsymutil 以生成 debuginfo。

  • packed - 这是 Windows MSVC 和 macOS 的默认设置。“packed” 在这里的意思是所有调试信息都被打包到一个与主可执行文件分开的文件中。在 Windows MSVC 上,这是一个 *.pdb 文件,在 macOS 上,这是一个 *.dSYM 文件夹,在其他平台上,这是一个 *.dwp 文件。

  • unpacked - 这意味着将在每个编译单元(目标文件)的单独文件中找到调试信息。Windows MSVC 不支持此选项。在 macOS 上,这意味着原始目标文件将包含调试信息。在其他 Unix 平台上,这意味着 *.dwo 文件将包含调试信息。

请注意,Linux 和 Apple 平台支持所有三个选项,Windows-MSVC 支持 packed,所有其他平台都支持 off。尝试使用不受支持的选项需要使用 nightly channel 和 -Z unstable-options 标志。

strip

选项 -C strip=val 控制在链接期间从二进制文件中剥离 debuginfo 和类似的辅助数据。

此选项支持的值为

  • none - debuginfo 和符号未被修改。
  • debuginfo - debuginfo 节和符号表节中的 debuginfo 符号在链接时被剥离,并且不会复制到生成的可执行文件中。这应该使回溯基本保持完整,但可能会使使用 gdb 或 lldb 等调试器无效。在 1.79 之前的版本中,这无意中禁用了在 MSVC 上生成 *.pdb 文件,导致缺少符号。
  • symbols - 与 debuginfo 相同,但符号表节的其余部分也会被剥离,具体取决于平台支持。在依赖此符号表进行回溯、性能分析和类似操作的平台上,这可能会对它们产生负面影响,以至于使跟踪变得难以理解。可能与其他程序(例如 CLI 管道和开发者工具)组合的程序,甚至任何想要崩溃报告的程序,通常应避免使用 -Cstrip=symbols

请注意,在任何级别,删除 debuginfo 仅必然会影响 “友好的” 内省。-Cstrip 不能作为有意义的安全或混淆措施来依赖,因为即使在没有符号的情况下,反汇编程序和反编译器也可以提取大量信息。

symbol-mangling-version

此选项控制用于编码 Rust 项目名称以生成目标代码和链接的 名称修饰 格式。

此选项支持的值为

  • v0 — “v0” 修饰方案。

如果未指定,则默认值将使用编译器选择的默认值,该默认值将来可能会更改。

有关符号修饰和修饰格式的详细信息,请参阅 符号修饰 章节。

target-cpu

这指示 rustc 为特定处理器生成代码。

您可以运行 rustc --print target-cpus 以查看要传递的有效选项以及当前构建目标的默认目标 CPU。每个目标都有一个默认的基础 CPU。特殊值包括

  • 可以传递 native 以使用主机处理器的处理器。
  • generic 指的是具有最少功能但具有现代调优的 LLVM 目标。

target-feature

各个目标将支持不同的功能;此标志使您可以控制启用或禁用功能。每个功能应以 + 为前缀以启用它,或以 - 为前缀以禁用它。

来自多个 -C target-feature 选项的功能被组合在一起。
可以在单个选项中指定多个功能,方法是用逗号分隔它们 - -C target-feature=+x,-y
如果使用 +- 多次指定了某个功能,则稍后传递的值将覆盖先前传递的值。
例如,-C target-feature=+x,-y,+z -Ctarget-feature=-x,+y 等效于 -C target-feature=-x,+y,+z

要查看有效选项和使用示例,请运行 rustc --print target-features

使用此标志是不安全的,可能会导致 未定义的运行时行为

另请参阅 target_feature 属性,以了解如何控制每个功能的功能。

这也支持功能 +crt-static-crt-static,以控制 静态 C 运行时链接

每个目标和 target-cpu 都有默认的启用功能集。

tune-cpu

这指示 rustc 为特定处理器调度代码。这不会影响兼容性(指令集或 ABI),但应使您的代码在选定的 CPU 上稍微更有效率。

有效选项与 target-cpu 的选项相同。默认值为 None,LLVM 将其转换为 target-cpu

这是一个不稳定的选项。使用 -Z tune-cpu=machine 来指定一个值。

由于 LLVM (12.0.0-git9218f92) 中的限制,此选项目前仅对 x86 目标有效。