这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

Rustc

Rustc

介绍

rustc是 Rust 编程语言的编译器,由项目组开发提供。编译器将您的源代码和生产二进制代码,变成一个或可执行文件。

大多数 Rust 程序员都不会直接调用rustc,而是通过Cargo来完成,虽然Cargo也是调用rustc流程!如果想看看 Cargo 如何调用rustc, 可以

$ cargo build --verbose

它会打印出每个rustc调用。

资料

  • The rustc book: 官方英文版
  • The rustc book: 中文翻译版。备注:经常打不开,需要科学上网。另外lint相关的内容和英文文档的内容有很大的偏差。

1 - Rustc的命令行参数

Rustc的命令行参数

英文原文地址: https://doc.rust-lang.org/rustc/command-line-arguments.html

这是 rustc 的命令行参数列表和他们的功能介绍:

-h/--help: 帮助

该标志将打印出rustc的帮助信息。

--cfg:配置编译环境

此标志可以打开或关闭各种#[cfg]设置。

该值可以是单个标识符,也可以是由=分隔两个标识符。

举例,--cfg 'verbose' 或者 --cfg 'feature="serde"'。分别对应#[cfg(verbose)]#[cfg(feature = "serde")]

-L:将目录添加到库搜索路径

查找外部crate或库时,将搜索传递到此标志的目录。

搜索路径的类型可以通过 -L KIND=PATH 方式制定,这是可选的,其中KIND可以是以下之一:

  • dependency —仅在此目录中搜索传递依赖项。
  • crate —仅在此目录中搜索此crate的直接依赖项。
  • native —仅在此目录中搜索原生类库。
  • framework —仅在此目录中搜索macOS框架。
  • all—在此目录中搜索所有库类型。这是KIND未指定时的默认值。

-l:将生成的包链接到一个原生库

使用此标志可以在构建crate时指定链接到特定的原生库。

可以使用以下形式之一指定库的类型,-l KIND=lib 其中KIND可以是:

类库的类型可以通过 -l KIND=lib 方式制定,这是可选的,其中KIND可以是以下之一:

  • dylib — 原生动态库。
  • static— 原生静态库(例如.a 包)。
  • framework — macOS框架。

可以在 #[link] 属性中指定库的类型。如果未在 link 属性或命令行中指定种类,它将链接动态库(如果可用),否则将使用静态库。如果在命令行上指定了种类,它将覆盖link属性中指定的种类。

在link属性中使用的 name 可以用 “-l ATTR_NAME:LINK_NAME” 的形式来覆盖,其中 ATTR_NAME 是在 link属性的 name ,而 LINK_NAME 是将被链接的实际库的名称。

--crate-type:编译器生成包的类型列表

指示rustc要构建的crate类型。该标志接受逗号分隔的值列表,并且可以多次指定。有效的crate类型为:

  • lib—生成编译器首选的库类型,当前默认为 rlib
  • rlib — Rust静态库。
  • staticlib —原生静态库。
  • dylib — Rust动态库。
  • cdylib —原生动态库。
  • bin —可运行的可执行程序。
  • proc-macro —生成适合于程序宏类库的格式,该格式可由编译器加载。

crate类型可以使用 crate_type 属性指定。该 --crate-type 命令行值将覆盖 crate_type 属性。

可以在参考文档的 linkage 章节 中找到更多详细信息。

--crate-name:指定构建的crate的名称

告诉rustc crate的名称。

--edition:指定要使用的版本

此标志的值为 2015 或 2018。默认值为2015。有关版本的更多信息,请参见 版本指南

--emit:指定要生成的输出文件的类型

该标志控制编译器生成的输出文件的类型。接受逗号分隔的值列表,并且可以多次指定。有效的生成种类有:

  • asm—生成带有crate的汇编代码的文件。默认输出文件名是CRATE_NAME.s
  • dep-info—生成具有Makefile语法的文件,该文件指示已经加载用来生成crate的所有源文件。默认输出文件名是CRATE_NAME.d
  • link—生成由--crate-type指定的crate。默认输出文件名取决于crate类型和平台。这是 --emit未指定时的默认值。
  • llvm-bc—生成包含LLVM 字节码的二进制文件。默认输出文件名是CRATE_NAME.bc
  • llvm-ir—生成包含LLVM IR的文件。默认输出文件名是CRATE_NAME.ll
  • metadata—生成包含有关crate元数据的文件。默认输出文件名是CRATE_NAME.rmeta
  • mir—生成包含rustc的中等中间表示形式(mid-level intermediate representation)的文件。默认输出文件名是CRATE_NAME.mir
  • obj—生成原生目标文件。默认输出文件名是 CRATE_NAME.o

可以使用 -o 标志设置输出的文件名。可以使用 -C extra-filename 标志添加后缀到文件名中。除非使用该 --out-dir 标志,否则文件将被写入当前目录。每种生成类型还可以使用KIND=PATH形式来指定输出的文件名,该文件名优先于-o标志。

--print:打印编译器信息

该标志输出有关编译器的各种信息。可以多次指定此标志,并按照指定标志的顺序打印信息。指定--print标志通常将禁用 --emit步骤,并且只会打印所请求的信息。有效的打印值类型为:

  • crate-name — crate的名称。
  • file-names—由link 生成种类创建的文件的名称。
  • sysroot — sysroot的路径。
  • cfg— CFG值列表。有关cfg值的更多信息,请参见条件编译
  • target-list—已知目标列表。可以使用--target标志选择目标 。
  • target-cpus—当前目标的可用CPU值列表。可以使用该-C target-cpu=val标志选择目标CPU 。
  • target-features—当前目标的可用目标功能列表。可以使用该-C target-feature=val 标志启用目标功能。该标志是不安全的。有关更多详细信息,请参见已知问题
  • relocation-models—重定位模型列表。可以使用-C relocation-model=val标志选择重定位模型。
  • code-models—代码模型列表。可以使用-C code-model=val标志选择代码模型 。
  • tls-models—支持的线程本地存储(Thread Local Storage)模型列表。可以通过-Z tls-model=val标志选择模型。
  • native-static-libs—在创建staticlib crate类型时可以使用它。如果这是唯一标志,它将执行完整编译并包含诊断说明,该诊断说明指示在链接生成的静态库时要使用的链接器标志。该注释以文本开头, native-static-libs:以使其更容易获取输出。

-g:包括调试信息

-C debuginfo=2的同义词,更多信息请参见这里

-O:优化代码

-C opt-level=2的同义词,更多信息请参见这里

-o:输出的文件名

该标志控制输出文件名。

--out-dir:写入输出的目录

输出的crate将被写入此目录。如果-o标志被使用,则忽略此标志。

--explain:提供错误消息的详细说明

rustc的每个错误都带有错误代码;这将打印出给定错误的详细说明。

--test:建立测试工具

编译此crate时,rustc将忽略main函数,而是产生一个测试工具。

--target:选择要构建的目标三元组

这可以控制要生产的目标

-W:设置lint warnings

此标志将设置应将哪些lint设置为 warn 级别 。

-A:设置lint allowed

此标志将设置应将哪些lint设置为 allow 级别 。

-D:设置lint denied

此标志将设置应将哪些lint设置为 deny 级别 。

-F:设置lint forbidden

此标志将设置应将哪些lint设置为 forbid 级别 。

-Z:设置不稳定的选项

此标志将允许您设置rustc的不稳定选项。为了设置多个选项,-Z标志可以多次使用。例如:rustc -Z verbose -Z time。使用-Z指定选项仅在nightly中可用。要查看所有可用选项,请运行:rustc -Z help

--cap-lints:设置最严格的lint等级

此标志使您可以“限制”lint,有关更多信息,请参见此处

-C/ --codegen:代码生成选项

此标志将允许您设置代码生成选项

-V/ --version:打印版本

此标志将打印出rustc的版本。

-v/ --verbose:使用详细输出

与其他标志结合使用时,该标志将产生额外的输出。

--extern:指定外部库的位置

此标志允许您传递将链接到要构建的crate的外部crate的名称和位置。可以多次指定此标志。值的格式应为CRATENAME=PATH

--sysroot:覆盖系统根目录

“ sysroot”是rustc寻找Rust发行版附带的crate的地方。该标志允许它被覆盖。

--error-format:控制错误的产生方式

该标志使您可以控制消息的格式。消息将打印到stderr。有效选项是:

  • human—可读的输出。这是默认值。
  • json—结构化JSON输出。有关更多详细信息,请参见JSON章节
  • short —短的单行消息。

--color:配置输出的颜色

此标志使您可以控制输出的颜色设置。有效选项是:

  • auto—如果输出发送到tty,则使用颜色。这是默认值。
  • always —始终使用颜色。
  • never —切勿使输出着色。

--remap-path-prefix:在输出中重新映射源名称

在所有输出中重新映射源路径前缀,包括编译器诊断,调试信息,宏扩展等。它从FROM=TO形式中获取值, 其中路径前缀等于FROM的 value 被重写为 TO的 value。在FROM自身也可以包含一个=符号,但TO价值不得。可以多次指定此标志。

这对于标准化生成产品很有用,例如通过从发出到目标文件中的路径名中删除当前目录。替换纯文本形式,不考虑当前系统的路径名语法。例如--remap-path-prefix foo=bar将匹配foo/lib.rs但不匹配 ./foo/lib.rs

--json:配置编译器打印的json消息

--error-format=json选项传递给rustc时,所有编译器的诊断输出将以JSON blob的形式发出。该 --json参数可与一起使用,--error-format=json以配置JSON Blob包含的内容以及发出的JSON Blob。

使用--error-format=json编译器时,始终会以JSON blob的形式发出任何编译器错误,但是该--json标志还可以使用以下选项来自定义输出:

  • diagnostic-short-诊断消息的json blob应该使用“简短”呈现,而不是常规的“人为”呈现。这意味着的输出 --error-format=short将嵌入到JSON诊断程序中,而不是默认的--error-format=human
  • diagnostic-rendered-ansi-默认情况下,其rendered字段中的JSON Blob 将包含诊断的纯文本呈现。该选项改为指示诊断程序应具有嵌入的ANSI颜色代码,该颜色代码打算用于rustc通常已经用于终端输出的方式来对消息进行着色。请注意,此选项可与板条箱有效地结合使用,例如 fwdansi将Windows上的这些ANSI代码转换为控制台命令,或者 strip-ansi-escapes如果您以后希望有选择地去除ansi颜色的话。
  • artifacts-这指示rustc为每个发出的工件发出JSON Blob。工件与--emitCLI参数中的请求相对应,并且该工件在文件系统上可用时,将立即发出通知。

请注意,它是无效的结合--json论点与--color 论据,并且需要结合起来--json使用--error-format=json

有关更多详细信息,请参见JSON章节

@path:从路径加载命令行标志

如果@path在命令行上指定,则它将打开path并从中读取命令行选项。这些选项是每行一个。空行表示空选项。该文件可以使用Unix或Windows样式的行尾,并且必须编码为UTF-8。

2 - Rustc的条件编译

Rustc的条件编译

介绍

什么是条件编译?

条件编译是指根据某些条件来决定特性代码是否被视为源代码的一部分。

可以使用属性 cfg 和 cfg_attr,还有内置 cfg 宏来有条件地编译源代码。这些条件基于:已编译的crate的目标体系结构,传递给编译器的任意值,以及其他一些杂项。

配置谓词

条件编译的每种形式都采用评估加过为 true 或 false 的配置谓词(configuration predicate)。谓词是以下之一:

  • 配置选项。如果设置了该选项,则为true;如果未设置,则为false。
  • all() 用逗号分隔的配置谓词列表。只要有一个谓词为false,则为false。如果没有谓词,那就是true。
  • any() 用逗号分隔的配置谓词列表。如果至少一个谓词为true,则为true。如果没有谓词,则为false。
  • not() 带有配置谓词。如果其谓词为false,则为true;如果其谓词为true,则为false。

配置选项

配置选项是已设置或未设置的 name 和 key-value 对。name 被写为单个标识符,例如 unix。key-value 对被写为标识符,=,然后是字符串。例如,target_arch = "x86_64" 是一个配置选项。

注意:等号周围的空格将被忽略。foo="bar"foo = "bar" 是等同的配置选项。

键在键值配置选项集中不是唯一的。例如,feature = "std"feature = "serde" 可以同时设置。

设置配置选项

设置哪些配置选项是在板条箱的编译过程中静态确定的。某些选项在编译器集合根据有关统计数据。其他选项是任意设置,基于代码外传递给编译器的输入进行设置。无法从正在编译的板条箱的源代码中设置配置选项。

注意:对于rustc,可以使用--cfg标志设置任意设置的配置选项 。

警告:任意设置的配置选项可能与编译器设置的配置选项具有相同的值。例如,可以rustc --cfg "unix" program.rs在编译到Windows目标时进行,并同时设置unixwindows配置选项。实际执行此操作是不明智的。

#[cfg] 是 Rust 的特殊属性,,允许基于传递给编译器的标记来编译代码。有两种形式:

#[cfg(foo)]

#[cfg(bar = "baz")]

所有的条件编译都由通过cfg配置实现,cfg支持any、all、not等逻辑谓词组合。

它还有一些帮助选项:

#[cfg(any(unix, windows))]

#[cfg(all(unix, target_pointer_width = "32"))]

#[cfg(not(foo))]

这些选项可以任意嵌套:

#[cfg(any(not(unix), all(target_os="macos", target_arch = "powerpc")))]

至于如何启用和禁用这些开关,如果使用Cargo的话,可以在 Cargo.toml中的[features\]部分设置:

[features]
# no features by default
default = []

# The “secure-password” feature depends on the bcrypt package.
secure-password = ["bcrypt"]

这时,Cargo会传递给 rustc 一个标记:

--cfg feature="${feature_name}"

这些cfg标记集合会决定哪些功能被启用,哪些代码会被编译。让我们看看这些代码:

#[cfg(feature = "foo")]
mod foo {
}

如果你用cargo build --features "foo"编译,他会向rustc传递--cfg feature="foo"标记,并且输出中将会包含mod foo。如果我们使用常规的cargo build编译,则不会传递额外的标记,因此,(输出)不会存在foo模块。

cfg_attr

你也可以通过一个基于cfg变量的cfg_attr来设置另一个属性:

#[cfg_attr(a, b)]

如果a通过cfg属性设置了的话这与#[b]相同,否则不起作用。

cfg!

cfg!语法扩展也让你可以在你的代码中使用这类标记:

if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
    println!("Think Different!");
}

这会在编译时被替换为一个truefalse,依配置设定而定。

参考资料