cargo build 的结果会被放入项目根目录下的 target 文件夹中,当然,这个位置可以三种方式更改:设置 CARGO_TARGET_DIR 环境变量、build.target-dir 配置项以及 --target-dir 命令行参数。
cargo build编译
cargo run
首先对项目进行编译,然后再运行,因此它实际上等同于运行了两个指令,下面我们手动试一下编译和运行项目:
scss
cargo build
Finished dev [unoptimized + debuginfo] target(s) in 0.00s
运行编译后的文件:
shell
$ ./target/debug/world_hello
Hello, world!
行云流水,但谈不上一气呵成。 细心的读者可能已经发现,在调用的时候,路径 ./target/debug/world_hello
中有一个明晃晃的 debug
字段,没错我们运行的是 debug
模式,在这种模式下,代码的编译速度会非常快 ,可是福兮祸所伏,运行速度就慢了 . 原因是,在 debug
模式下,Rust 编译器不会做任何的优化,只为了尽快的编译完成,让你的开发流程更加顺畅。
作为尊贵的读者,咱自然可以要求更多,比如你想要高性能的代码怎么办? 简单,添加 --release
来编译:
cargo run --release
cargo build --release
试着运行一下我们高性能的 release
程序:
shell
$ ./target/release/world_hello
Hello, world!
cargo check
当项目大了后,cargo run
和 cargo build
不可避免的会变慢,那么有没有更快的方式来验证代码的正确性呢?大杀器来了,接着!
cargo check
是我们在代码开发过程中最常用的命令,它的作用很简单:快速的检查一下代码能否编译通过。因此该命令速度会非常快,能节省大量的编译时间。
scss
$ cargo check
Checking world_hello v0.1.0 (/Users/sunfei/development/rust/world_hello) Finished dev [unoptimized + debuginfo] target(s) in 0.06s
Rust 虽然编译速度还行,但是还是不能与 Go 语言相提并论,因为 Rust 需要做很多复杂的编译优化和语言特性解析,甚至连如何优化编译速度都成了一门学问: 优化编译速度。
target 目录结构
target 目录的结构取决于是否使用 --target 标志为特定的平台构建。
若 --target 标志没有指定,Cargo 会根据宿主机架构进行构建,构建结果会放入项目根目录下的 target 目录中,target 下每个子目录中包含了相应的 发布配置profile 的构建结果,例如 release、debug 是自带的profile,前者往往用于生产环境,因为会做大量的性能优化,而后者则用于开发环境,此时的编译效率和报错信息是最好的。
除此之外我们还可以定义自己想要的 profile
,例如用于测试环境的 profile
: test
,用于预发环境的 profile
:pre-prod
等。
目录 | 描述 |
---|---|
target/debug/ | 包含了 dev profile 的构建输出(cargo build 或 cargo build --debug) |
target/release | release profile 的构建输出,cargo build --release |
target/foo/ | 自定义 foo profile 的构建输出,cargo build --profile=foo |
出于历史原因
dev
和test
profile 的构建结果都存放在debug
目录下release
和bench
profile 则存放在release
目录下- 用户定义的 profile 存在同名的目录下
使用--target
当使用 --target XXX
为特定的平台编译后,输出会放在 target/XXX/
目录下:
目录 | 示例 |
---|---|
target/<triple>/debug | target/thumbv7em-none-eabihf/debug/ |
target/<triple>/release | target/thumbv7em-none-eabihf/release/ |
注意:,当没有使用 --target 时,Cargo 会与构建脚本和过程宏一起共享你的依赖包,对于每个 rustc 命令调用而言,RUSTFLAGS 也将被共享。
而使用 --target 后,构建脚本、过程宏会针对宿主机的CPU架构进行各自构建,且不会共享 RUSTFLAGS。
target子目录说明
在 profile 文件夹中(例如 debug 或 release),包含编译后的最终成果:
target/debug/ : 包含编译后的输出,例如二进制可执行文件、库对象( library target )
target/debug/examples/: 包含示例对象( example target )
还有一些命令会在 target 下生成自己的独立目录:
target/doc/: 包含通过 cargo doc 生成的文档
target/package/: 包含 cargo package 或 cargo publish 生成的输出
Cargo 还会创建几个用于构建过程的其它类型目录,它们的目录结构只应该被 Cargo 自身使用,因此可能会在未来发生变化:
target/debug/deps: 依赖和其它输出成果
target/debug/incremental : rustc增量编译的输出,该缓存可以用于提升后续的编译速度
target/debug/build/: 构建脚本的输出
依赖信息文件
在每一个编译成果的旁边,都有一个依赖信息文件,文件后缀是 .d
。该文件的语法类似于 Makefile
,用于说明构建编译成果所需的所有依赖包。
该文件往往用于提供给外部的构建系统,这样它们就可以判断 Cargo
命令是否需要再次被执行。
文件中的路径默认是绝对路径,你可以通过 build.dep-info-basedir 配置项来修改为相对路径。
lua
# 关于 `.d` 文件的一个示例 : target/debug/foo.d
/path/to/myproj/target/debug/foo: /path/to/myproj/src/lib.rs /path/to/myproj/src/main.rs
共享缓存
sccache 是一个三方工具,可以用于在不同的工作空间中共享已经构建好的依赖包。
为了设置 sccache
,首先需要使用 cargo install sccache
进行安装,然后在调用 Cargo
之前将 RUSTC_WRAPPER
环境变量设置为 sccache
。
- 如果用的
bash
,可以将export RUSTC_WRAPPER=sccache
添加到.bashrc
中 - 也可以使用 build.rustc-wrapper 配置项