Cargo 主命令完全指南:cargo(1) 命令体系、全局选项与源码级原理解析
【免费下载链接】cargoThe Rust package manager项目地址: https://gitcode.com/gh_mirrors/car/cargo
本文以 Cargo 官方手册的cargo(1)主命令手册页(doc/book/src/commands/cargo.md)为骨架,系统讲解cargo命令的调用语法、六类内置命令、全局选项的语义与优先级,并结合当前仓库的 CLI 实现源码揭示其底层运行机制。读完本文,你将能熟练运用cargo的全局选项(--locked、--offline、--config等)、理解内建命令/别名/外部子命令三者的调度规则、看懂 Cargo 的目录与退出码约定,并具备独立排查命令问题的能力。
命令语法(SYNOPSIS)
cargo是一个同时承担**包管理器(package manager)与构建工具(build tool)**职责的单一可执行程序,其通用调用形式如下:
cargo [options] command [args] cargo [options] --version cargo [options] --list cargo [options] --help cargo [options] --explain code要点说明:
command可以是内置命令(见下文 COMMANDS 全表)、别名(alias)或外部子命令(external subcommand);- 全局选项(
--version、--list、--help、--explain)可独立于子命令直接使用; - 从源码看,CLI 解析由 clap 完成(见 src/bin/cargo/cli.rs),全局选项统一挂在
Command::new("cargo")上并标记global(true),因此既可以写在子命令之前,也可以跟在子命令之后。
cargo 是什么:命令调度的三层结构
手册中明确:command可能是以下三种之一,对应的解析顺序可以从 src/bin/cargo/main.rs 与 src/bin/cargo/cli.rs 中验证:
- 内置命令(built-in):编译进 cargo 二进制,注册在 src/bin/cargo/commands/mod.rs 的
builtin()列表中; - 别名(alias):来自配置文件
[alias]表(参见 doc/book/src/reference/config.md 的 alias 一节),其中b、c、d、r、t、rm六个别名由 Cargo 内置,见源码中的BUILTIN_ALIASES常量(src/bin/cargo/main.rs); - 外部子命令(external subcommand):形如
cargo-<name>的可执行文件,Cargo 会在PATH与$CARGO_HOME/bin中查找(见find_external_subcommand与third_party_subcommands,src/bin/cargo/main.rs)。
Exec::infer(src/bin/cargo/cli.rs)明确了三者解析的优先级:内置命令 > 清单命令(manifest command)> 外部子命令;用户自定义别名若与内置命令同名会被忽略并给出警告。Cargo 对内置命令的查找还支持 dash 连接形式(如cargo build--release这类嵌套命令的自动匹配),相关逻辑在find_builtin_cmd_dash_joined与try_match_cmd(src/bin/cargo/commands/help.rs)中实现。
内置命令全景(COMMANDS)
手册按用途将全部内置命令划分为六类。这些命令的 CLI 定义均由 src/bin/cargo/commands/mod.rs 的builtin()统一注册,每个子命令一个模块,cli()声明参数、exec()执行逻辑。
构建类命令(Build Commands)
| 命令 | 用途 |
|---|---|
| cargo-bench(1) | 执行包的基准测试(benchmarks) |
| cargo-build(1) | 编译一个包 |
| cargo-check(1) | 检查本地包及其全部依赖是否存在错误(不产出目标文件) |
| cargo-clean(1) | 移除 Cargo 此前生成的构建产物 |
| cargo-doc(1) | 构建包的文档 |
| cargo-fetch(1) | 从网络获取包的依赖(离线前预取依赖的标准方式) |
| cargo-fix(1) | 自动修复 rustc 报告的 lint 警告 |
| cargo-run(1) | 运行本地包中的二进制程序或示例 |
| cargo-rustc(1) | 编译包,并透传额外选项给编译器 |
| cargo-rustdoc(1) | 使用自定义 flags 构建包的文档 |
| cargo-test(1) | 执行包的单元测试与集成测试 |
清单类命令(Manifest Commands)
| 命令 | 用途 |
|---|---|
| cargo-add(1) | 向Cargo.toml清单文件添加依赖 |
| cargo-generate-lockfile(1) | 为项目生成Cargo.lock |
| cargo-info(1) | 显示注册表中某个包的信息(默认注册表为 crates.io) |
| cargo-locate-project(1) | 以 JSON 形式输出Cargo.toml的位置 |
| cargo-metadata(1) | 以机器可读格式输出包已解析的依赖 |
| cargo-pkgid(1) | 输出完全限定的包规格(package spec) |
| cargo-remove(1) | 从Cargo.toml清单文件移除依赖 |
| cargo-tree(1) | 以树状图展示依赖图 |
| cargo-update(1) | 按本地锁文件记录更新依赖 |
| cargo-vendor(1) | 将所有依赖本地化(vendor)到本地目录 |
包类命令(Package Commands)
| 命令 | 用途 |
|---|---|
| cargo-init(1) | 在已存在的目录中创建新的 Cargo 包 |
| cargo-install(1) | 构建并安装 Rust 二进制程序 |
| cargo-new(1) | 创建新的 Cargo 包 |
| cargo-search(1) | 在 crates.io 中搜索包 |
| cargo-uninstall(1) | 移除已安装的 Rust 二进制程序 |
发布类命令(Publishing Commands)
| 命令 | 用途 |
|---|---|
| cargo-login(1) | 在本地保存注册表的 API token |
| cargo-logout(1) | 从本地移除注册表的 API token |
| cargo-owner(1) | 管理 crate 在注册表上的所有者 |
| cargo-package(1) | 将本地包打包为可分发的 tarball |
| cargo-publish(1) | 将包上传到注册表 |
| cargo-yank(1) | 从索引中撤回已发布的 crate 版本 |
报告类命令(Report Commands)
| 命令 | 用途 |
|---|---|
| cargo-report(1) | 生成并展示多种类型的报告 |
| cargo-report-future-incompatibilities(1) | 报告将来会停止编译的 crate |
通用类命令(General Commands)
| 命令 | 用途 |
|---|---|
| cargo-help(1) | 显示 Cargo 的帮助信息 |
| cargo-version(1) | 显示版本信息 |
值得注意的是,源码注册表(builtin(),src/bin/cargo/commands/mod.rs)中还包含config、git-checkout、read-manifest、verify-project等命令,其中部分偏内部/调试用途,未列入公开手册的命令清单;cargo help本身也是一个内置子命令,其exec会从内置的压缩 man 归档(include_bytes!的man.tgz)中提取对应手册页并用man/less/more分页显示(见 src/bin/cargo/commands/help.rs),这正是cargo help clean这类命令的工作方式。
命令扩展机制:别名与外部子命令
内置别名
Cargo 出厂自带 6 个快捷别名(src/bin/cargo/main.rs):
b → build c → check d → doc r → run t → test rm → remove它们与普通命令完全等价,例如cargo t等价于cargo test。
用户自定义别名
在配置文件的[alias]表中可定义自己的别名,例如:
[alias] b = "build" my-cmd = "run --release --"源码中aliased_command(src/bin/cargo/main.rs)的解析链是:先从GlobalContext读取alias.<name>(字符串或字符串数组),找不到再回退到BUILTIN_ALIASES;别名解析是递归的,若形成环(如a -> b -> a)会报“unresolvable recursive definition”错误。配置文件的详细语法见 doc/book/src/reference/config.md。
外部子命令
任何名为cargo-<name>的可执行文件放入PATH或$CARGO_HOME/bin后,即可通过cargo <name>调用。查找逻辑在find_external_subcommand与search_directories(src/bin/cargo/main.rs)中:先扫描PATH,再保证$CARGO_HOME/bin优先。cargo --list会列出所有这些可用的命令(见print_list,src/bin/cargo/cli.rs)。关于编写自定义子命令的约定,可参考 doc/book/src/reference/external-tools.md。当输入的命令不存在时,Cargo 会提示“no such command”并给出cargo --list与cargo search cargo-<name>的修复建议,同时尝试给出最接近的命令名(closest_msg)。
全局选项(OPTIONS)
特殊选项
| 选项 | 说明 |
|---|---|
-V/--version | 打印版本信息后退出;配合--verbose时输出额外信息 |
--list | 列出所有已安装的 Cargo 子命令;配合--verbose时输出额外信息(例如外部命令的完整路径) |
--explain code | 执行rustc --explain CODE,输出某条错误信息的详细解释(例如E0004) |
源码侧:get_version_string(src/bin/cargo/cli.rs)在 verbose 模式下会追加 release 版本、commit-hash、commit-date、host 目标以及 libgit2/libcurl/openssl 等关键依赖库的版本信息(add_libgit2/add_curl/add_ssl);--explain则直接构造rustc --explain <code>子进程执行(src/bin/cargo/cli.rs)。
显示选项
| 选项 | 说明 |
|---|---|
-v/--verbose | 使用详细输出;指定两次(-vv)为“非常详细”,会包含依赖警告与 build script 输出。也可通过配置值term.verbose指定 |
-q/--quiet | 不打印 cargo 日志消息。也可通过配置值term.quiet指定 |
--color when | 控制何时使用彩色输出,取值:auto(默认,自动检测终端是否支持颜色)、always(始终显示颜色)、never(从不显示颜色)。也可通过配置值term.color指定 |
源码侧:-v使用 clap 的ArgAction::Count计数(src/bin/cargo/cli.rs),因此可以叠加;configure_gctx(src/bin/cargo/cli.rs)会合并命令行、全局参数与配置值,统一调用gctx.configure(verbose, quiet, color, ...)生效。
清单选项(Manifest Options)
| 选项 | 说明 |
|---|---|
--locked | 断言依赖解析与现有Cargo.lock完全一致。当满足以下任一场景时 Cargo 直接报错退出:① 锁文件缺失;② Cargo 因依赖解析结果不同而试图修改锁文件。适合需要确定性构建的环境,如 CI 流水线 |
--offline | 禁止 Cargo 以任何理由访问网络。不加该标志时,若 Cargo 需要网络而网络不可用,会直接报错;加上后,Cargo 会尽量在无网络情况下继续。注意:这可能产生与在线模式不同的依赖解析结果——Cargo 只使用本地已下载的 crate,即便本地索引副本显示存在更新版本。建议先用 cargo-fetch(1) 预取依赖再离线。也可通过配置值net.offline指定 |
--frozen | 等价于同时指定--locked与--offline |
源码侧:--locked、--offline、--frozen均标记global(true)(src/bin/cargo/cli.rs),并在configure_gctx中与来自别名的global_args做“或”合并(src/bin/cargo/cli.rs),即任意一处指定即生效。
通用选项(Common Options)
| 选项 | 说明 |
|---|---|
+toolchain | 若 cargo 由 rustup 安装,且第一个参数以+开头,则被解释为 rustup 工具链名(如+stable、+nightly),用于覆盖默认工具链 |
--config KEY=VALUE 或 PATH | 覆盖一个 Cargo 配置值。参数为 TOML 语法的KEY=VALUE,或指向额外配置文件的路径;该选项可多次指定。详细说明见 doc/book/src/reference/config.md |
-C PATH | 在执行任何操作前切换当前工作目录,影响诸如默认查找项目清单(Cargo.toml)的位置以及发现.cargo/config.toml的搜索目录。必须出现在命令名之前,例如cargo -C path/to/my-project build。该选项目前仅在nightly 通道可用,且需-Z unstable-options启用 |
-h/--help | 打印帮助信息 |
-Z flag | 传给 Cargo 的不稳定(仅 nightly)flags,运行cargo -Z help查看详情 |
源码侧:-C在 nightly 且带-Z unstable-options时才执行std::env::set_current_dir并reload_cwd(src/bin/cargo/cli.rs);--config支持KEY=VALUE与 TOML 文件路径两种形式,配置覆盖的解析入口在gctx.configure(..., &config_args, ...);-Z选项在 nightly 通道才会完整生效,print_zhelp(src/bin/cargo/cli.rs)会列出所有可用不稳定 flags;rustup 环境下+toolchain的候选列表来自rustup toolchain list -q(get_toolchains_from_rustup,src/bin/cargo/cli.rs),并同时用于 shell 补全候选。
环境变量(ENVIRONMENT)
Cargo 会读取一系列环境变量来影响其行为,包括CARGO_HOME、CARGO_TARGET_DIR、RUSTC、CARGO_INCREMENTAL等。完整清单与逐项说明见 doc/book/src/reference/environment-variables.md。例如手册的 FILES 一节就明确指出:Cargo 的 home 目录默认位于~/.cargo/,且位置可通过CARGO_HOME环境变量更改。
退出状态(EXIT STATUS)
| 退出码 | 含义 |
|---|---|
0 | Cargo 执行成功 |
101 | Cargo 执行失败 |
源码侧,CliError统一携带退出码,默认失败即101(见 src/util/errors.rs 中CliError::new(err, 101)的调用),入口处cargo::exit_with_error(src/lib.rs)负责以该码退出进程。测试场景下更明显:cargo test遇到测试失败时统一返回标准错误码101(见 src/ops/cargo_test.rs 的相关注释与101常量),且使用--no-fail-fast时 Cargo 总是使用101退出码。
Cargo 相关文件与目录(FILES)
| 路径 | 说明 |
|---|---|
~/.cargo/ | Cargo 的 home 目录默认位置,存放各类文件;可用CARGO_HOME环境变量更改 |
$CARGO_HOME/bin/ | cargo-install(1) 安装的二进制程序所在目录;若使用 rustup,随 Rust 分发的可执行文件也在此处 |
$CARGO_HOME/config.toml | 全局配置文件,详见 doc/book/src/reference/config.md |
.cargo/config.toml | Cargo 会自动在当前目录及所有父目录中搜索该文件,并与全局配置合并 |
$CARGO_HOME/credentials.toml | 登录注册表所需的私有认证信息 |
$CARGO_HOME/registry/ | 注册表索引与已下载依赖的缓存目录 |
$CARGO_HOME/git/ | git 依赖的缓存下载目录 |
注意:手册特别提醒,$CARGO_HOME目录的内部结构尚不稳定,可能随版本调整,依赖其内部布局的脚本需要谨慎。源码侧,$CARGO_HOME/bin会被自动加入外部子命令的搜索目录(见前文search_directories),且为避免重复,若PATH中已包含该目录则不会再次添加,用户可借此用PATH控制命令优先级。
典型用法示例(EXAMPLES)
手册给出的 6 个经典示例,覆盖从构建、测试到新建项目的日常高频操作:
构建本地包及其全部依赖:
cargo build以优化模式构建包(发布版):
cargo build --release为交叉编译目标运行测试:
cargo test --target i686-unknown-linux-gnu创建可构建可执行文件的新包:
cargo new foobar在当前目录创建包:
mkdir foo && cd foo cargo init .查看某个命令的选项与用法:
cargo help clean
第 6 条的内部机制前面已剖析:cargo help <cmd>通过 src/bin/cargo/commands/help.rs 先从内置压缩手册中取出对应 man 页,再调用系统的man/less/more分页展示;未内置 man 页时回退到对应子命令的--help输出。也可以直接写cargo clean --help获得同样效果。
组合实战:构建、测试与发布的关键用法
将全局选项与子命令组合,可以覆盖 CI 与离线开发两大高频场景:
# CI 中的确定性构建:锁文件必须与解析一致,且不访问网络 cargo build --frozen # 等价写法 cargo build --locked --offline # 预取依赖后完全离线工作 cargo fetch cargo build --offline # 不写进配置文件的临时覆盖:修改镜像索引或目标目录 cargo build --config 'registries.crates-io.index = "sparse+https://example.com/index/"' # 查看所有可用子命令(含外部工具) cargo --list -v值得强调的是--frozen在 CI 中的意义:它同时保证“锁文件不被悄悄改动”与“不触碰网络”,让构建结果可复现;而--offline与在线模式的解析差异、net.offline配置值的存在,意味着这两种模式在 CI 与本地开发间切换时可能得到不同依赖版本,需要留意。
故障排查与获取更多帮助
当遇到问题时,按以下顺序排查最有效率:
cargo --list:确认命令是否已安装(内置命令、别名、外部子命令都会列出);cargo help <cmd>或<cmd> --help:查看该命令的全部选项与用法;cargo -Z help:查看 nightly-only 的不稳定 flags(仅 nightly 通道可用);cargo --explain <错误码>:获取 rustc 错误码(如E0004)的详细解释;- 程序本身若需报告问题,可提交到官方 issue 跟踪(见手册 BUGS 一节),手册 SEE ALSO 一节还指向
rustc(1)与rustdoc(1)文档,便于联动查阅编译器与文档生成器的行为。
小结
cargo以“单入口 + 多子命令 + 可扩展”的设计统一了 Rust 的构建、测试、依赖管理与发布流程。本文从手册原文出发,梳理了六类内置命令、四组全局选项、三层命令调度(内置/别名/外部)以及0/101退出码与$CARGO_HOME文件布局,并逐一对照 src/bin/cargo/cli.rs、src/bin/cargo/main.rs 与 src/bin/cargo/commands/mod.rs 等源码验证了文档描述与实现的对应关系。掌握这些约定后,无论是日常开发、CI 流水线搭建还是自定义子命令扩展,都能更加得心应手。
【免费下载链接】cargoThe Rust package manager项目地址: https://gitcode.com/gh_mirrors/car/cargo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考