Cargo 的 build 和 rustc 命令有什么区别?

What's the difference between Cargo's build and rustc commands?

我是 Rust 的新手,我刚刚通过 cargo new my_project 创建了一个新项目。我注意到 cargo 提供了这两个命令行选项:

我了解到后者可以用于编译我机器上的任何项目,而前者只能在当前工作目录中使用。那是对的吗?还有其他区别吗? 运行 没有附加参数的两个命令给出完全相同的输出。

工作目录没有区别。区别在于如何将编译器选项传递给 rustc,其中许多 Cargo 不知道 about/expose:

cargo build [OPTIONS]: If you want to pass a flag to rustc, generally you cannot do that on the command line, you need to .

cargo rustc [OPTIONS] [-- ARGS]:可用的 OPTIONScargo build 大致相同,但参数传递给 rustc。所以你可以写 cargo rustc --release -- -C overflow-checks=yes.

差异

为了更好地理解这些命令在较高层次上的不同之处,我们可以比较这些命令的实现。所以我们首先克隆 cargo repo

git clone https://github.com/rust-lang/cargo.git

然后比较cargo build and cargo rustc

的实现
diff -u -w cargo/src/bin/cargo/commands/build.rs cargo/src/bin/cargo/commands/rustc.rs

由此,很容易看出 cargo buildcargo rustc 都是 this 内部 cargo 函数的薄包装:

pub fn compile<'a>(ws: &Workspace<'a>, options: &CompileOptions) -> CargoResult<Compilation<'a>> {
    // ...
}

但公开的选项类型不同。事实上,可以阅读 cargo_compile.rs 顶部定义该函数的注释:

//! This module contains the entry point for starting the compilation process
//! for commands like `build`, `test`, `doc`, `rustc`, etc.

换句话说,cargo buildcargo rustc 并不是围绕同一编译入口点的唯一薄包装器。

为什么有不同的命令?

那么,为什么cargo背后的人会选择这样做呢?为什么不使用带有大量标志的单个 cargo compile 命令来完全公开底层实现?

显然必须以一种易于记录和理解 Rust 生态系统的各种目标受众的方式来组织事物。

例如,大多数 Rust 生态系统的新手都不想接触到调整编译器标志的可能性。因此,在开始时仅将它们暴露给 cargo build 及其文档是有意义的,具有其特殊的编译选项。

一旦他们成为更高级的用户,他们会发现他们可以通过 cargo rustc 对编译过程产生更详细的影响。

在这个问题和拉取请求中添加:

据我了解,添加它是为了能够将编译器参数传递给构建。它主要用于调试目的。