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

  • 编译:编译一个本地包及其所有依赖项
  • rustc:编译一个包及其所有依赖项

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

推荐答案

Differences

我们可以比较不同命令的执行情况.所以我们先用

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

然后将cargo buildcargo 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>> {
    // ...
}

但在expose 的选项方面存在差异.事实上,你可以在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并不是围绕同一编译入口点的唯一薄包装.

Why have different commands?

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

显然,这必须是以一种易于记录和理解的方式来组织事情的问题,以满足Rust生态系统的各种目标受众.

例如,大多数Rust生态系统的新手都不想expose 在调整编译器标志的可能性之下.因此,在一开始只向cargo build及其文档公开它们是有意义的,因为它具有特殊的编译选项风格.

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

Rust相关问答推荐

如何处理对打包字段的引用是未对齐错误?

为什么我们不能通过指针算法将Rust原始指针指向任意地址?'

为什么这是&q;,而让&q;循环是无限循环?

S,一般性状和联想型性状有什么不同?

我可以在不收集或克隆的情况下,将一个带有Item=(key,val)的迭代器拆分成单独的key iter和val iter吗?

无法实现整型类型的泛型FN

为什么HashMap::get和HashMap::entry使用不同类型的密钥?

如何获取光标下的像素 colored颜色 ?

存储返回 impl Trait 作为特征对象的函数

unwrap 选项类型出现错误:无法移出共享引用后面的*foo

如何限制通用 const 参数中允许的值?

一个函数调用会产生双重borrow 错误,而另一个则不会

不能将 `*self` borrow 为不可变的,因为它也被borrow 为可变的 - 编译器真的需要如此严格吗?

无法理解 Rust 对临时值的不可变和可变引用是如何被删除的

当 T 不是副本时,为什么取消引用 Box 不会抱怨移出共享引用?

为什么拥有 i32 所有权的函数需要它是可变的?

如何在 Rust 中编写修改 struct 的函数

为什么 no_std crate 可以依赖于使用 std 的 crate?

TcpStream::connect - 匹配武器具有不兼容的类型

如果返回类型是通用的,我可以返回 &str 输入的一部分吗?