代码生成选项

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

ar

此选项已弃用,没有任何作用。

code-model

此选项允许您选择要使用的代码模型。

代码模型对程序及其符号可以使用的地址范围施加了限制。

使用较小的地址范围,机器指令可能能够使用更紧凑的寻址模式。

具体范围取决于目标架构和可用的寻址模式。

对于 x86,可以在 System V 应用程序二进制接口 规范中找到对其代码模型的更详细描述。

此选项支持的值为

  • tiny - 微型代码模型。
  • small - 小型代码模型。这是大多数受支持目标的默认模型。
  • kernel - 内核代码模型。
  • medium - 中型代码模型。
  • large - 大型代码模型。

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

codegen-units

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

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

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

collapse-macro-debuginfo

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

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

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

control-flow-guard

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

  • yyesontruechecks 或无值:启用控制流保护。
  • nochecks:发出没有运行时强制检查的控制流保护元数据(这应该仅用于测试目的,因为它不提供安全强制)。
  • nnoofffalse:不启用控制流保护(默认)。

debug-assertions

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

  • yyesontrue 或无值:启用调试断言。
  • nnoofffalse:禁用调试断言。

如果未指定,则仅当 opt-level 为 0 时,才会自动启用调试断言。

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

embed-bitcode

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

  • yyesontrue 或无值:将位码放入 rlib 中(默认)。
  • nnoofffalse:从 rlib 中省略位码。

当 rustc 执行链接时优化 (LTO) 时,需要 LLVM 位码。在某些目标(如 iOS)上也需要它,因为供应商会查找 LLVM 位码。嵌入式位码将出现在 rustc 生成的目标文件中,该文件位于目标平台定义的名称的部分内。大多数情况下,这是 .llvmbc

如果您的编译实际上不需要位码(例如,如果您没有为 iOS 进行编译,或者您没有执行 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 位码替换目标文件。-Cembed-bitcode 的唯一用途是当您生成一个同时使用和不使用 LTO 的 rlib 时。例如,Rust 的标准库附带了嵌入式位码,因为用户可以使用和不使用 LTO 链接到它。

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

extra-filename

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

force-frame-pointers

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

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

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

force-unwind-tables

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

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

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

incremental

此标志允许您启用增量编译,这允许 rustc 在编译板条箱后保存信息,以便在重新编译板条箱时重复使用,从而缩短重新编译时间。这需要一个目录路径,增量文件将存储在该目录中。

inline-threshold

此选项允许您设置内联函数的默认阈值。它采用一个无符号整数作为值。内联基于成本模型,更高的阈值将允许更多内联。

默认值取决于 opt-level

opt-level阈值
0N/A,仅内联始终内联的函数
1N/A,仅内联始终内联的函数和 LLVM 生命周期内在函数
2225
3275
s75
z25

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 可执行文件与 -flavor darwin 标志 一起用于 Apple 的 ld
  • ld.lld:将 LLVM lld 可执行文件与 -flavor gnu 标志 一起用于 GNU binutils 的 ld
  • lld-link:将 LLVM lld 可执行文件与 -flavor link 标志 一起用于 Microsoft 的 link.exe

linker-plugin-lto

此标志将 LTO 优化延迟到链接器。有关更多详细信息,请参阅 链接器插件 LTO。它采用以下值之一

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

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

请注意,rustc 还可以读取使用 -Clinker-plugin-lto 生成的自己的目标文件。如果 rlib 以后只会在 -Clto 编译中使用,那么您可以传递 -Clinker-plugin-lto 以加快编译速度,并避免生成未使用的目标文件。

llvm-args

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

列表必须用空格分隔。

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

lto

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

  • yyesontruefat 或无值:执行“fat”LTO,它尝试对依赖关系图中的所有板条箱执行优化。
  • nnoofffalse:禁用 LTO。
  • thin:执行 “thin”LTO。这与“fat”类似,但运行时间要短得多,同时仍然可以实现与“fat”类似的性能提升。

如果未指定 -C lto,则编译器将尝试执行“thin local LTO”,它仅在本地板条箱的 代码生成单元 中执行“thin”LTO。如果未指定 -C lto,则如果代码生成单元为 1 或禁用了优化(-C opt-level=0),则禁用 LTO。也就是说

  • 如果未指定 -C lto
    • codegen-units=1:禁用 LTO。
    • opt-level=0:禁用 LTO。
  • 如果指定了 -C lto
    • lto:16 个代码生成单元,在板条箱之间执行 fat LTO。
    • codegen-units=1 + lto:1 个代码生成单元,在板条箱之间执行 fat LTO。

另请参阅 链接器插件 lto,了解跨语言 LTO。

metadata

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

no-prepopulate-passes

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

no-redzone

此标志允许您禁用 红色区域。它采用以下值之一

  • yyesontrue 或无值:禁用红色区域。
  • nnoofffalse:启用红色区域。

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

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

此标志允许您控制 运行时整数溢出 的行为。当启用溢出检查时,溢出会导致程序恐慌(panic)。此标志接受以下值之一

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

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

panic

此选项允许您控制代码发生恐慌(panic)时的行为。

  • abort:发生恐慌时终止进程
  • unwind:发生恐慌时展开堆栈

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

passes

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

列表必须用空格分隔。

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

prefer-dynamic

默认情况下,rustc 倾向于静态链接依赖项。如果同时存在库的静态版本和动态版本,则此选项将指示尽可能使用动态链接。有一个内部算法用于确定是否可以静态或动态链接依赖项。例如,cdylib crate 类型可能只能使用静态链接。此标志接受以下值之一

  • 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 来发现支持的值。

链接效果

除了代码生成效果之外,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 也被移动以防止缓冲区溢出写入。完全 RELRO 使用更多内存并增加进程启动时间。

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

remark

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

过程列表应该用空格分隔。

all 将对每个过程进行备注。

rpath

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

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

save-temps

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

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

soft-float

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

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

split-debuginfo

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

  • off - 这是 ELF 二进制文件和 windows-gnu(不是 Windows MSVC,也不是 macOS)平台的默认值。这通常意味着可以在最终产物的可执行文件的各个部分中找到 DWARF 调试信息。Windows MSVC 不支持此选项。在 macOS 上,此选项会阻止最终执行 dsymutil 来生成调试信息。

  • packed - 这是 Windows MSVC 和 macOS 的默认值。这里的“打包”一词意味着所有调试信息都打包到与主可执行文件不同的文件中。在 Windows MSVC 上,这是一个 *.pdb 文件,在 macOS 上,这是一个 *.dSYM 文件夹,而在其他平台上,这是一个 *.dwp 文件。

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

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

strip

选项 -C strip=val 控制在链接期间从二进制文件中删除调试信息和类似的辅助数据。

此选项支持的值为

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

请注意,在任何级别,删除调试信息都只会影响“友好”的内省。-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 目标有效。