cargo build使用指南,build编译后的target文件夹目录结构说明

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 runcargo 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 ,例如用于测试环境的 profiletest,用于预发环境的 profilepre-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

出于历史原因

  • devtest profile 的构建结果都存放在 debug 目录下
  • releasebench 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 配置项
相关推荐
加班是不可能的,除非双倍日工资4 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi5 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip5 小时前
vite和webpack打包结构控制
前端·javascript
excel5 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国6 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼6 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy6 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
ZXT6 小时前
promise & async await总结
前端
Jerry说前后端6 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化
画个太阳作晴天6 小时前
A12预装app
linux·服务器·前端