Cargo 为什么存在:从 `rustc` 到 Rust 包管理器的演进之路

发布时间:2026/9/22 19:11:24

Cargo 为什么存在:从 `rustc` 到 Rust 包管理器的演进之路 开发工具包管理器CLI构建工具【免费下载链接】cargoThe Rust package manager项目地址https://gitcode.com/gh_mirrors/car/cargo点击查看免费下载Cargo 是 Rust 的官方包管理器package manager本指南将带你理解它诞生的根本原因直接用rustc手工编译真实项目为何不可行以及 Cargo 如何通过两个元数据文件 自动获取依赖 统一构建调用 目录约定四件事让 Rust 包的构建变得可重复、可共享、可预测。读完本文你将掌握 crate / package / package manager 的核心概念理解Cargo.toml与Cargo.lock的分工并能在 Cargo 指南 的引导下开始你的第一个 Cargo 项目。预备知识crate 与rustc的直接调用在 Rust 中一个库或可执行程序被称为crate箱。crate 使用 Rust 编译器rustc编译。大多数 Rust 初学者接触到的第一段源码就是经典的 hello world 程序他们通过直接调用rustc来编译$ rustc hello.rs $ ./hello Hello, world!注意上面的命令要求你显式指定文件名。如果你想直接用rustc编译另一个程序就需要另一条完全不同的命令行调用如果你还需要指定某些编译器标志compiler flags或引入外部依赖那么所需的命令会变得更加特殊、更加复杂。从源码结构看crate 是 Cargo 世界中最基础的编译单元glossary 中明确指出crate 可能指目标target的源代码也可能指目标编译后产生的产物还可能指从注册表registry获取的压缩包。而artifact构建产物 则是编译过程产生的文件集合包括可链接的库、可执行二进制和生成的文档。更进一步大多数非平凡的程序都会依赖外部库因此还会传递性地依赖这些库的依赖。如果完全靠手工获取所有必要依赖的正确版本并保持它们更新将是困难且极易出错的。与其只和 crate 及rustc打交道你可以通过引入一个更高层的抽象——package包——并借助一个package manager包管理器 来避开上述手工操作的困难。Cargo 登场Rust 的包管理器Cargo就是 Rust 的包管理器。它是一个工具允许 Rustpackages声明它们的各种依赖并确保你总能得到一个可重复的构建repeatable build。为实现这一目标Cargo 主要做四件事引入两个元数据文件携带各种包信息即Cargo.toml与Cargo.lock获取并构建你的包的依赖以正确的参数调用rustc或其他构建工具来构建你的包引入约定conventions让 Rust 包的协作变得更加容易。从 glossary 的 Package manager 条目 可以看到包管理器是软件生态中自动完成获取、安装和升级产物的程序在编程语言生态中其核心功能是从中央仓库下载库产物及其依赖并常常与执行构建调用语言编译器的能力结合。Cargo 正是 Rust 生态中的那个角色它下载你的包依赖即称为 crate 的产物、编译你的包、制作可分发的包并可选择性地将它们上传到 crates.io——Rust 社区的package registry包注册表。统一构建命令一条命令构建所有项目Cargo 在很大程度上规范化了构建给定程序或库所需的命令——这就是上面提到的约定的一个侧面。正如后面会展示的同一条命令可以用来构建不同的artifacts产物无论它们的名字是什么。与其直接调用rustc你可以调用一个通用的命令例如cargo build让 Cargo 去操心如何构造正确的rustc调用。此外Cargo 会自动从registry注册表 获取你为产物定义的任何依赖并按需把它们加入构建。可以毫不夸张地说一旦你知道如何构建一个基于 Cargo 的项目你就知道如何构建所有基于 Cargo 的项目。实战验证从cargo new到cargo run用 Cargo 新建一个包并构建它只需三步详见 入门指南 与 创建新包$ cargo new hello_world --bin--bin表示创建一个二进制程序如果要创建库则传--lib。默认情况下该命令还会初始化一个 git 仓库若不需要可加--vcs none。生成的结构如下. ├── Cargo.toml └── src └── main.rsCargo.toml被称为manifest清单包含 Cargo 编译你的包所需的全部元数据采用 TOML 格式[package] name hello_world version 0.1.0 edition 2024 [dependencies]src/main.rs中是一个二进制 cratefn main() { println!(Hello, world!); }然后编译并运行$ cargo build Compiling hello_world v0.1.0 (file:///path/to/package/hello_world) $ ./target/debug/hello_world Hello, world!或者用cargo run一步完成编译加运行。发布时则使用cargo build --release优化产物会输出到target/release而非target/debug——这正是同一命令、不同目标产物的体现。构建结束后你会注意到多了一个Cargo.lock文件它记录依赖的精确信息。两个元数据文件Cargo.toml与Cargo.lockCargo 引入的两个元数据文件各有明确分工详见 Cargo.toml vs Cargo.lockCargo.toml宽泛地描述你的依赖由你编写。Cargo.lock包含依赖的精确信息由 Cargo 维护不应手工编辑。拿不定主意时请把Cargo.lock提交进版本控制系统如 Git关于原因与替代方案可参考 FAQ为什么要把 Cargo.lock 纳入版本控制并建议配合 持续集成中验证最新依赖 一起使用。为什么需要Cargo.lock可重复构建的关键假设你在Cargo.toml中声明了一个 Git 依赖[package] name hello_world version 0.1.0 [dependencies] regex { git https://github.com/rust-lang/regex.git }由于没有指定其他信息Cargo 会假定你使用默认分支上的最新提交来构建。问题在于你今天构建这个包然后把副本发给别人别人明天构建——期间regex可能又多了新提交于是构建结果就不同了。这违背了可重复构建的初衷。你也可以在Cargo.toml里写死rev[dependencies] regex { git https://github.com/rust-lang/regex.git, rev 9f9f693 }这样构建是一致的但代价是你必须每次手动维护 SHA-1——既繁琐又容易出错。Cargo.lock正是为此而生首次构建时Cargo 会把最新提交的精确信息写入Cargo.lock例如[[package]] name hello_world version 0.1.0 dependencies [ regex 1.5.0 (githttps://github.com/rust-lang/regex.git#9f9f693768c584971a4d53bc3c586c33ed3a6831), ] [[package]] name regex version 1.5.0 source githttps://github.com/rust-lang/regex.git#9f9f693768c584971a4d53bc3c586c33ed3a6831可见其中的信息远比 manifest 丰富包括你构建时使用的精确 revision。这样你把包交给别人时对方会使用完全相同的 SHA即使你没有在Cargo.toml中指定它。当你准备好升级到库的新版本时Cargo 可以帮你重新计算依赖并更新$ cargo update # 更新所有依赖 $ cargo update regex # 只更新 regex这会写出带新版本信息的Cargo.lock。注意cargo update的参数实际上是 Package ID Specification包 ID 规范regex只是它的一个简短形式。自动获取与传递依赖注册表的作用crates.io 是 Rust 社区的中央包注册表cargo默认配置为从中查找所需的包。要依赖 crates.io 上托管的库只需在Cargo.toml的[dependencies]段列出 crate 名称和版本[dependencies] time 0.1.12 regex 0.1.41版本字符串是 SemVer 版本要求。重新运行cargo buildCargo 会获取新依赖及其所有传递依赖、编译它们并更新Cargo.lock$ cargo build Updating crates.io index Downloading memchr v0.1.5 Downloading libc v0.1.10 Downloading regex-syntax v0.2.1 Downloading aho-corasick v0.3.0 Downloading regex v0.1.41 Compiling memchr v0.1.5 Compiling libc v0.1.10 Compiling regex-syntax v0.2.1 Compiling aho-corasick v0.3.0 Compiling regex v0.1.41 Compiling hello_world v0.1.0 (file:///path/to/package/hello_world)此后即使regex发布了新版本你仍会按Cargo.lock中的同一 revision 构建直到你主动运行cargo update。你可以在源码中直接使用该库use regex::Regex; fn main() { let re Regex::new(r^\d{4}-\d{2}-\d{2}$).unwrap(); println!(Did our date match? {}, re.is_match(2014-01-01)); }从 glossary 的 Registry 条目 可以看出注册表是一个包含可下载 crate 集合的服务默认注册表是 crates.io它带有一个 index索引列出所有 crate 并告诉 Cargo 如何下载所需内容。除注册表外Rust 生态还有本地注册表源、目录源、路径源如路径依赖和 Git 源如 Git 依赖等多种 source源。约定让项目一眼可读Cargo 使用文件放置约定让你能快速进入一个陌生的 Cargo 包详见 包布局. ├── Cargo.lock ├── Cargo.toml ├── src/ │ ├── lib.rs │ ├── main.rs │ └── bin/ │ ├── named-executable.rs │ ├── another-executable.rs │ └── multi-file-executable/ │ ├── main.rs │ └── some_module.rs ├── benches/ │ ├── large-input.rs │ └── multi-file-bench/ │ ├── main.rs │ └── bench_module.rs ├── examples/ │ ├── simple.rs │ └── multi-file-example/ │ ├── main.rs │ └── ex_module.rs └── tests/ ├── some-integration-tests.rs └── multi-file-test/ ├── main.rs └── test_module.rs约定要点Cargo.toml和Cargo.lock存放在包的根目录package root。源代码放在src目录默认库文件是src/lib.rs默认可执行文件是src/main.rs其他可执行文件可放在src/bin/。基准测试放benches、示例放examples、集成测试放tests。如果二进制、示例、基准或集成测试由多个源文件组成则在src/bin、examples、benches或tests的子目录中放置main.rs与其他模块可执行文件名取目录名。按惯例binaries、examples、benches 与 integration tests 采用kebab-case命名除非存在兼容性原因其中的模块则按 Rust 标准采用snake_case。配合 Cargo 指南目录 中的后续章节依赖、测试、持续集成、在 crates.io 上发布、Cargo Home、优化构建性能等你会发现从为何存在到如何用好Cargo 始终围绕同一个目标让 Rust 包的声明、获取、构建与分享标准化。小结Cargo 之所以存在是因为真实的 Rust 项目远不止一个文件、一条rustc命令那么简单rustc直接调用需要为每个程序、每组标志、每份依赖手工定制命令无法规模化依赖及其传递依赖的版本管理是手工几乎不可能完成的任务Cargo 用Cargo.toml你写的声明与Cargo.lockCargo 维护的精确快照两个元数据文件实现了可重复构建Cargo 通过自动获取依赖、以正确参数调用rustc或构建工具以及统一的目录约定把构建过程规范化为cargo build/cargo run这样的通用命令。这正是那句略带夸张却不失真谛的总结一旦你学会构建一个 Cargo 项目你就学会构建所有的 Cargo 项目。赞分享开发工具包管理器CLI构建工具【免费下载链接】cargoThe Rust package manager项目地址https://gitcode.com/gh_mirrors/car/cargo点击查看免费下载相关推荐N_m3u8DL-RE跨平台流媒体下载器5分钟搞定加密视频下载与直播录制N_m3u8DL RE跨平台流媒体下载器5分钟搞定加密视频下载与直播录制 N_m3u8DL RE 是一款免费开源的流媒体下载工具能把网页上以 MPD、M3UCLI音视频Rust Cargo包管理终极指南从依赖管理到生态系统演进Rust语言以其出色的包管理系统Cargo而闻名它为开发者提供了简单高效的依赖管理和项目构建体验。作为Rust生态系统的重要组成部分Cargo的持续改进通过文档TypeScript定义管理器从TSD到Typings的演进之路TypeScript定义管理器从TSD到Typings的演进之路 痛点TypeScript类型定义的混乱时代 你是否曾经在TypeScript项目中遇到过这上一篇KindEditor解决企业级富文本编辑需求的5大核心方案下一篇3分钟掌握Windows安卓应用安装器告别模拟器的终极解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/22 19:11:24

PS描边路径5大坑:从报错到修复的避坑指南

PS描边路径5大坑:从报错到修复的避坑指南 复制来的代码跑不通,报错信息一堆却不知从哪下手调?这种绝望感每个开发者都懂。今天这篇ps描边路径避坑指南,专治各种“看着对但跑不出结果”的疑难杂症。 坑一:路径坐标越界导致的静默失败 现象:…

2026/9/22 20:01:28

3个j3455性能优化陷阱:手写实现避坑指南

3个j3455性能优化陷阱:手写实现避坑指南 看了一堆教程还是不会写项目?别急,问题不在你笨,而在你没摸透底层逻辑。很多开发者卡在“j3455”这个概念上,以为它是某个特定框架或库,其实它是一个被过度神话的编码代号,常出现在老旧系统的性能优…

2026/9/22 20:01:28

苹果x电量监控手写实现:3步搞定环境配置痛点

苹果x电量监控手写实现:3步搞定环境配置痛点 配置环境就卡半天,是不是熟悉的感觉?很多刚入行的同学,想做个苹果x电量监控的小项目,结果卡在依赖安装、版本冲突或者API权限上,光折腾环境就花了一整天。别急,今天咱们不整那些虚的,直接上手,用…

2026/9/22 19:56:28

拒绝卡顿!2d网游帧率优化实战,从入门到精通

拒绝卡顿!2d网游帧率优化实战,从入门到精通 你是不是也遇到过这种情况:看了一堆教程,代码能跑通,Demo也做得花里胡哨,但一放到真机或者大地图场景里,帧率直接掉到20以下,玩家还没看清发生了什么就卡死了?这种“看了一堆教程还是不会写项目”…

2026/9/22 10:02:42

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/22 9:07:39

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/22 0:04:49

输电线路在线监测高频面试题拆解 3秒抓住官方文档重点

输电线路在线监测高频面试题拆解 3秒抓住官方文档重点 官方文档几百页翻到头还是懵?面试问到 输电线路在线监测 的数据链路时,脑子一片空白?别慌,这种 高频面试题 我整理了10年,专门治各种“文档太长抓不住重点”的毛病。…

2026/9/22 0:04:49

中介房源管理系统重构避坑:3个关键步骤搞定API变更

中介房源管理系统重构避坑:3个关键步骤搞定API变更 版本升级后 API 全变了,这种痛只有真做过的人懂。 很多团队在接手老旧房产项目时,最崩溃的不是代码烂,而是底层框架升级后,原本熟悉的接口调用方式彻底失效。 这份 保姆级教程…

2026/9/22 0:04:49

3个坑点带你一文搞懂55gg小游戏源码

3个坑点带你一文搞懂55gg小游戏源码 盯着控制台满屏的红色报错,看着那一长串 StackTrace ,是不是脑子瞬间宕机?别急,这种时候最忌讳的就是盲目改代码。很多刚入行的前端同学,面对 55gg 小游戏这类轻量级 H5…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码