代码生成选项
所有这些选项都通过 -C
标志传递给 rustc
,-C
是 "codegen" 的缩写。您可以通过运行 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]
属性。
y
、yes
、on
、true
:折叠调试信息中的代码位置。n
、no
、off
或false
:不折叠调试信息中的代码位置。external
:仅当宏来自不同的 crate 时才折叠调试信息中的代码位置。
control-flow-guard
此标志控制 LLVM 是否启用 Windows 控制流保护 平台安全功能。此标志目前对于非 Windows 目标将被忽略。它接受以下值之一
y
、yes
、on
、true
、checks
或无值:启用控制流保护。nochecks
:发出不带运行时强制检查的控制流保护元数据(这仅应用于测试目的,因为它不提供安全强制)。n
、no
、off
、false
:不启用控制流保护(默认)。
debug-assertions
此标志允许您打开或关闭 cfg(debug_assertions)
条件编译。它接受以下值之一
y
、yes
、on
、true
或无值:启用调试断言。n
、no
、off
或false
:禁用调试断言。
如果未指定,则仅当 opt-level 为 0 时才自动启用调试断言。
debuginfo
此标志控制调试信息的生成。它接受以下值之一
0
或none
:完全没有调试信息(默认)。line-directives-only
:仅限行信息指令。对于 nvptx* 目标,这将启用 性能分析。对于其他用例,line-tables-only
是更好、更兼容的选择。line-tables-only
:仅限行表。生成具有文件名/行号信息的反向追踪所需的最小调试信息,但不包括任何其他信息,即不包括变量或函数参数信息。1
或limited
:没有类型或变量级信息的调试信息。2
或full
:完整的调试信息。
注意:-g
标志 是 -C debuginfo=2
的别名。
default-linker-libraries
此标志控制链接器是否包含其默认库。它接受以下值之一
y
、yes
、on
、true
:包含默认库。n
、no
、off
或false
或无值:排除默认库(默认)。
例如,对于 gcc 风格的链接器,这会向链接器发出 -nodefaultlibs
标志。
dlltool
在 windows-gnu
目标上,当使用 raw-dylib
链接类型 时,此标志控制 rustc
调用哪个 dlltool 来生成导入库。它接受 dlltool 可执行文件 的路径。如果未指定此标志,则将根据主机环境和目标推断 dlltool 可执行文件。
embed-bitcode
此标志控制编译器是否将 LLVM 位代码嵌入到目标文件中。它接受以下值之一
y
、yes
、on
、true
或无值:将位代码放入 rlibs 中(默认)。n
、no
、off
或false
:从 rlibs 中省略位代码。
当 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 一起使用又没有 LTO 一起使用的 rlib 时。例如,Rust 的标准库附带嵌入的位代码,因为用户在有和没有 LTO 的情况下都会链接到它。这也可能让您想知道为什么此选项的默认值为
yes
。原因是它是 rustc 1.44 及更早版本的方式。在 1.45 中,添加了此选项来关闭一直是默认值的选项。
extra-filename
此选项允许您在每个输出文件名中放入额外的数据。它接受一个字符串作为后缀添加到文件名中。有关更多信息,请参阅 --emit
标志。
force-frame-pointers
此标志强制使用帧指针。它接受以下值之一
y
、yes
、on
、true
或无值:强制启用帧指针。n
、no
、off
或false
:不强制启用帧指针。这并不一定意味着帧指针将被删除。
如果未强制启用帧指针,则默认行为取决于目标。
force-unwind-tables
此标志强制生成展开表。它接受以下值之一
y
、yes
、on
、true
或无值:强制生成展开表。n
、no
、off
或false
:不强制生成展开表。如果目标需要展开表,则会发出错误。
如果未指定,则默认值取决于目标。
incremental
此标志允许您启用增量编译,这允许 rustc
在编译 crate 后保存信息,以便在重新编译 crate 时重复使用,从而缩短重新编译时间。这需要一个存储增量文件的目录的路径。
inline-threshold
此选项已弃用,不起作用。
请考虑使用 -Cllvm-args=--inline-threshold=...
。
instrument-coverage
此选项启用基于插桩的代码覆盖率支持。有关更多信息,请参阅有关 基于插桩的代码覆盖率 的章节。
请注意,虽然 -C instrument-coverage
选项是稳定的,但生成的插桩产生的配置文件数据格式可能会发生变化,并且可能无法与编译器构建和随附的覆盖率工具之外的其他工具一起使用。
link-arg
此标志允许您向链接器调用附加单个额外参数。
"附加" 很重要;您可以多次传递此标志以添加多个参数。
link-args
此标志允许您向链接器调用附加多个额外参数。这些选项应该用空格分隔。
link-dead-code
此标志控制链接器是否保留死代码。它接受以下值之一
y
、yes
、on
、true
或无值:保留死代码。n
、no
、off
或false
:删除死代码(默认)。
此标志可能有用的一种情况是在尝试构造代码覆盖率指标时。
link-self-contained
在 windows-gnu
、linux-musl
和 wasi
目标上,此标志控制链接器是否使用 Rust 附带的库和对象,而不是系统中的库和对象。它接受以下值之一
- 无值:如果系统具有必要的工具,则 rustc 将使用启发式方法禁用自包含模式。
y
、yes
、on
、true
:仅使用 Rust 附带的库/对象。n
、no
、off
或false
:依赖用户或链接器提供非 Rust 库/对象。
这允许覆盖检测失败或用户想要使用附带库的情况。
linker
此标志控制 rustc
调用哪个链接器来链接您的代码。它接受链接器可执行文件的路径。如果未指定此标志,则将根据目标推断链接器。另请参阅 linker-flavor 标志,了解指定链接器的另一种方法。
linker-flavor
此标志控制 rustc
使用的链接器类型。如果使用 -C linker
标志 指定了链接器,则链接器类型将从提供的值推断得出。如果没有指定链接器,则使用链接器类型来确定要使用的链接器。每个 rustc
目标都默认使用某种链接器类型。有效的选项包括:
em
:使用 Emscriptenemcc
。gcc
:使用cc
可执行文件,它在许多系统上通常是 gcc 或 clang。ld
:使用ld
可执行文件。msvc
:使用来自 Microsoft Visual Studio MSVC 的link.exe
可执行文件。wasm-ld
:使用wasm-ld
可执行文件,它是 LLVMlld
的 WebAssembly 移植版本。ld64.lld
:使用 LLVMlld
可执行文件,并带有-flavor darwin
标志,用于 Apple 的ld
。ld.lld
:使用 LLVMlld
可执行文件,并带有-flavor gnu
标志,用于 GNU binutils 的ld
。lld-link
:使用 LLVMlld
可执行文件,并带有-flavor link
标志,用于 Microsoft 的link.exe
。
linker-plugin-lto
此标志将 LTO 优化推迟到链接器。有关更多详细信息,请参阅 linker-plugin-LTO。它接受以下值之一:
y
、yes
、on
、true
或不提供值:启用链接器插件 LTO。n
、no
、off
或false
:禁用链接器插件 LTO(默认值)。- 链接器插件的路径。
更具体地说,此标志将导致编译器将其典型的目标文件输出替换为 LLVM 位代码文件。例如,使用 -Clinker-plugin-lto
生成的 rlib 仍然会包含 *.o
文件,但它们都将是 LLVM 位代码,而不是实际的机器代码。期望本地平台链接器能够加载这些 LLVM 位代码文件并在链接时生成代码(通常在执行优化之后)。
请注意,rustc 还可以读取使用 -Clinker-plugin-lto
生成的自己的目标文件。如果一个 rlib 仅在以后与 -Clto
编译一起使用,则可以传递 -Clinker-plugin-lto
以加快编译速度并避免生成未使用的目标文件。
llvm-args
此标志可用于将参数列表直接传递给 LLVM。
列表必须以空格分隔。
传递 --help
可查看选项列表。
lto
此标志控制 LLVM 是否使用链接时优化,以在更长的链接时间为代价的情况下,使用整体程序分析生成更好的优化代码。它接受以下值之一:
y
、yes
、on
、true
、fat
或不提供值:执行“胖” LTO,它尝试在依赖关系图中的所有 crate 中执行优化。n
、no
、off
、false
:禁用 LTO。thin
:执行 “瘦” LTO。这与“胖” LTO 类似,但运行时间明显更短,同时仍能获得与“胖” LTO 类似的性能提升。
如果未指定 -C lto
,则编译器将尝试执行“瘦局部 LTO”,它仅在其代码生成单元上对本地 crate 执行“瘦” LTO。当未指定 -C lto
时,如果代码生成单元为 1 或禁用了优化(-C opt-level=0
),则会禁用 LTO。也就是说:
- 当未指定
-C lto
时:codegen-units=1
:禁用 LTO。opt-level=0
:禁用 LTO。
- 当指定
-C lto
时:lto
:16 个代码生成单元,在 crate 之间执行胖 LTO。codegen-units=1
+lto
:1 个代码生成单元,在 crate 之间执行胖 LTO。
另请参阅 linker-plugin-lto 以了解跨语言 LTO。
metadata
此选项允许您控制用于符号修饰的元数据。它接受一个以空格分隔的字符串列表。修饰的符号将包含元数据的哈希值。例如,这可以用于区分链接的同一 crate 的两个不同版本之间的符号。
no-prepopulate-passes
此标志告诉 pass 管理器使用空的 pass 列表,而不是通常预先填充的 pass 列表。
no-redzone
此标志允许您禁用红区。它接受以下值之一:
y
、yes
、on
、true
或不提供值:禁用红区。n
、no
、off
或false
:启用红区。
如果未指定此标志,则默认行为取决于目标。
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。此标志接受以下值之一:
y
、yes
、on
、true
或不提供值:启用溢出检查。n
、no
、off
或false
:禁用溢出检查。
如果未指定,则如果启用 debug-assertions,则启用溢出检查,否则禁用。
panic
此选项允许您控制代码发生 panic 时的行为。
abort
:发生 panic 时终止进程unwind
:发生 panic 时展开堆栈
如果未指定,则默认值取决于目标。
passes
此标志可用于向编译添加额外的 LLVM pass。
列表必须以空格分隔。
另请参阅 no-prepopulate-passes
标志。
prefer-dynamic
默认情况下,rustc
倾向于静态链接依赖项。如果同时提供库的静态版本和动态版本,则此选项将指示应尽可能使用动态链接。
有一个内部算法用于确定是否可以静态或动态链接依赖项。
此标志接受以下值之一:
y
、yes
、on
、true
或不提供值:倾向于动态链接。n
、no
、off
或false
:倾向于静态链接(默认值)。
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
。ropi
、rwpi
和ropi-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
此标志允许您打印优化 pass 的备注。
pass 列表应以空格分隔。
all
将在每个 pass 上添加备注。
rpath
此标志控制是否启用rpath
。它接受以下值之一:
y
、yes
、on
、true
或不提供值:启用 rpath。n
、no
、off
或false
:禁用 rpath(默认值)。
save-temps
此标志控制在编译完成后是否删除编译期间生成的临时文件。它接受以下值之一:
y
、yes
、on
、true
或不提供值:保存临时文件。n
、no
、off
或false
:删除临时文件(默认值)。
soft-float
此选项控制 rustc
是否生成在软件中模拟浮点指令的代码。它接受以下值之一:
y
、yes
、on
、true
或不提供值:使用软件浮点数。n
、no
、off
或false
:使用硬件浮点数(默认值)。
split-debuginfo
此选项控制 rustc
生成的调试信息的“拆分调试信息”的输出。此选项的默认行为是平台特定的,并且并非此选项的所有可能值都适用于所有平台。可能的值包括:
-
off
- 这是 ELF 二进制文件和 windows-gnu 平台的默认值(不是 Windows MSVC 和 macOS)。这通常意味着 DWARF 调试信息可以在可执行文件的最终工件的各个部分中找到。Windows MSVC 不支持此选项。在 macOS 上,此选项会阻止最终执行dsymutil
来生成调试信息。 -
packed
- 这是 Windows MSVC 和 macOS 的默认值。这里的“packed”一词意味着所有调试信息都被打包到与主可执行文件分开的文件中。在 Windows MSVC 上,这是一个*.pdb
文件,在 macOS 上,这是一个*.dSYM
文件夹,而在其他平台上,这是一个*.dwp
文件。 -
unpacked
- 这意味着调试信息将在每个编译单元(目标文件)的单独文件中找到。Windows MSVC 不支持此功能。在 macOS 上,这意味着原始目标文件将包含调试信息。在其他 Unix 平台上,这意味着*.dwo
文件将包含调试信息。
请注意,所有三个选项都支持 Linux 和 Apple 平台,packed
支持 Windows-MSVC,而所有其他平台都支持 off
。尝试使用不支持的选项需要使用 nightly 通道和 -Z unstable-options
标志。
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 目标有效。