Cargo 是 Rust 工具链中内置的构建系统及包管理器。它可以处理众多诸如构建代码、下载编译依赖库等琐碎但重要的任务,绝大部分的Rust用户都会选择它来管理自己的Rust项目。

创建项目

管理 Rust 项目及其模块依赖(Crate)

检查 Cargo 版本

1
$ cargo --version

创建一个项目

1
$ cargo new hello_cargo

执行完以上命令后,Cargo 会以同样的名字创建项目目录并放置它生成的文件。进入 hello_cargo 文件夹,可以看到 Cargo 刚刚生成的两个文件与一个目录:一个名为 Cargo.toml 的文件,以及一个名为 main.rs 的源代码文件,该源代码文件被放置在 src 目录下。同时,Cargo 还会初始化一个新的 Git 仓库并生成默认的 .gitignore 文件

Cargo.toml

cargo.tlml 是生成的标准配置文件, 内容如下:

1
2
3
4
5
6
7
[package]
name = "hello_cargo"
version = "0.1.0"
authors = ["Your Name <you@example.com"]
edition = "2018"

[dependencies]

最后一行文本中的 [dependencies] 是一个区域标签,它表明随后的区域会被用来声明项目的依赖。

Cargo 会默认把所有的源代码文件保存到src目录下,而项目根目录只被用来存放诸如README文档、许可声明、配置文件等与源代码无关的文件。

构建和运行项目

编译程序

在当前的 hello_cargo 项目目录下, 执行编译:

1
2
3
$ cargo build
   Compiling hello_cargo v0.1.0 (/Users/Herbert/rust/projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.21s

会将可执行程序生成在路径 target/debug/hello_cargo

首次使用命令 cargo build 构建的时候,它还会在项目根目录下创建一个名为 Cargo.lock 的新文件,这个文件记录了当前项目所有依赖库的具体版本号。

也可以简单地使用 cargo run 命令来依次完成编译和运行任务:

1
2
3
4
$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/hello_cargo`
Hello, world!

如果源代码并没有被修改,会直接运行了生成的二进制可执行文件。

编译检查

通过 cargo check的命令,来快速检查当前的代码是否可以通过编译,而不需要花费额外的时间去真正生成可执行程序:

1
2
3
$ cargo check
    Checking hello_cargo v0.1.0 (/Users/Herbert/rust/projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s

cargo check 跳过了生成可执行程序的步骤。 在编码的过程中需要不断通过编译器检查错误,那么使用 cargo check 就会极大地加速通过编译的过程。

以 Release 模式进行构建

当准备好发布自己的项目时,你可以使用命令 cargo build --release 在优化模式下构建并生成可执行程序:

1
2
3
$ cargo build --release
   Compiling hello_cargo v0.1.0 (/Users/Herbert/rust/projects/hello_cargo)
    Finished release [optimized] target(s) in 0.15s

生成的可执行文件会被放置在 target/release 目录下。

这种模式会以更长的编译时间为代价来优化代码,从而使代码拥有更好的运行时性能。

依赖包管理

更新依赖

如果构建的程序依赖到第三方库,需要修改 Cargo.toml 添加依赖。 比如程序引入了 rand 包,在 Cargo 生成的 [dependencies] 区域下方添加依赖:

1
2
[dependencies]
rand = "0.3.14"

这里的 [dependencies] 区域被用来声明项目中需要用到的全部依赖包及其版本号。我们指定 rand 包版本号为0.3.14,这里的数字0.3.14实际上是^0.3.14的一个简写,它表示“任何与0.3.14版本公共API相兼容的版本”。

有了依赖后,Cargo 会从注册表(registry)中获取所有可用库的最新版本信息,而这些信息通常是从 crates.io 上复制过来的。它会在更新完注册表后开始逐条检查 [dependencies] 区域中的依赖,并下载当前缺失的依赖包。

Cargo.lock 文件锁

当第一次构建项目时,Cargo 会依次遍历我们声明的依赖及其对应的语义化版本,找到符合要求的具体版本号,并将它们写入 Cargo.lock 文件。

随后再次构建项目时,Cargo 就会优先检索 Cargo.lock,假如文件中存在已经指明具体版本的依赖库,那么它就会跳过计算版本号的过程,并直接使用文件中指明的版本。

升级依赖包

Cargo 提供了一个专用命令:update,它会强制 Cargo 忽略 Cargo.lock 文件,并重新计算出所有依赖包中符合 Cargo.toml 声明的最新版本。如果运行成功,Cargo 就会将更新后的版本号写入 Cargo.lock 文件,并覆盖之前的内容。

1
2
3
$ cargo update
	Updating registry `https://github.com/rust-lang/crates.io-index`
	Updating rand v0.3.14 -> v0.3.15

参考