Cargo is Rust's build tool and package manager. It handles downloading dependencies, compiling code, running tests, generating documentation, and publishing crates. Cargo is one of Rust's greatest strengths, providing a consistent experience across the entire ecosystem.
Cargo là công cụ xây dựng và quản lý gói của Rust. Nó xử lý việc tải dependencies, biên dịch code, chạy test, tạo tài liệu, và xuất bản crate. Cargo là một trong những điểm mạnh lớn nhất của Rust, cung cấp trải nghiệm nhất quán cho toàn bộ hệ sinh thái.
Cargo.toml is the central configuration file for a Rust project. It declares metadata, dependencies, build profiles, features, and more. Understanding Cargo.toml gives you complete control over the build process and dependency management.
File Cargo.toml là file cấu hình trung tâm của một Rust project. Nó khai báo metadata, dependencies, build profiles, features, và nhiều thứ khác. Hiểu rõ Cargo.toml giúp bạn kiểm soát hoàn toàn quá trình build và quản lý phụ thuộc.
1[package]2name = "my_app"3version = "0.1.0"4edition = "2021"5authors = ["Alice <alice@example.com>"]6description = "A brief description of my app"7license = "MIT OR Apache-2.0"8repository = "https://github.com/alice/my_app"9keywords = ["cli", "tool"]10categories = ["command-line-utilities"]11readme = "README.md"12rust-version = "1.75" # minimum supported Rust versionWorkspaces let you manage multiple related crates in one repository. All crates in a workspace share a single Cargo.lock file and target/ directory, ensuring version consistency and avoiding duplicate compilation.
Workspace cho phép bạn quản lý nhiều crate liên quan trong một repository. Tất cả các crate trong workspace chia sẻ một file Cargo.lock duy nhất và thư mục target/, đảm bảo tính nhất quán về phiên bản và tránh biên dịch trùng lặp.
1# Root Cargo.toml (workspace manifest)2[workspace]3members = [4 "crates/core",5 "crates/cli",6 "crates/web",7]8resolver = "2"910# Shared dependency versions across workspace11[workspace.dependencies]12serde = { version = "1", features = ["derive"] }Cargo uses semantic versioning (SemVer). Versions have the form MAJOR.MINOR.PATCH. Increment PATCH for bug fixes, MINOR for backward-compatible new features, MAJOR for breaking API changes. Understanding version requirement syntax helps you manage dependencies effectively.
Cargo dùng semantic versioning (SemVer). Phiên bản có dạng MAJOR.MINOR.PATCH. Tăng PATCH khi sửa lỗi, tăng MINOR khi thêm tính năng tương thích ngược, tăng MAJOR khi có thay đổi phá vỡ API. Hiểu cú pháp yêu cầu phiên bản giúp bạn quản lý dependency hiệu quả.
1# Version requirement syntax in Cargo.toml23# Caret (default): compatible updates allowed4serde = "1" # means >=1.0.0, <2.0.05serde = "1.2" # means >=1.2.0, <2.0.06serde = "1.2.3" # means >=1.2.3, <2.0.078# Tilde: only patch updates for fully specified, minor+patch for major.minor9log = "~1.2" # means >=1.2.0, <1.3.010log = "~1.2.3" # means >=1.2.3, <1.3.01112# Wildcardcrates.io is Rust's official package registry. To publish a crate, you register an account, create an API token, and run cargo publish. Once published, versions cannot be deleted but can be yanked (marked as not recommended).
crates.io là registry chính thức của Rust. Để xuất bản một crate, bạn cần đăng ký tài khoản, tạo API token, và chạy cargo publish. Sau khi xuất bản, các phiên bản không thể xóa nhưng có thể bị yanked (đánh dấu không nên dùng).
1# Step 1: Login with your API token from crates.io2# cargo login <token>34# Step 2: Check your Cargo.toml has required fields:5[package]6name = "my_unique_crate_name"7version = "0.1.0"8edition = "2021"9description = "A clear description (required)"10license = "MIT" # or "Apache-2.0" or "MIT OR Apache-2.0"11# OR use a license file:12# license-file = "LICENSE"The Rust ecosystem has many high-quality crates. Below are the most widely used crates you will encounter in most real-world Rust projects.
Hệ sinh thái Rust có rất nhiều crate chất lượng cao. Dưới đây là các crate được sử dụng rộng rãi nhất mà bạn sẽ gặp trong hầu hết các dự án Rust thực tế.
- serde + serde_json: Serialization/deserialization for JSON, TOML, YAML, and many other formats
serde + serde_json: Serialization/deserialization cho JSON, TOML, YAML và nhiều định dạng khác
- tokio: Async runtime providing async I/O, timers, channels, and task scheduling
tokio: Async runtime, cung cấp I/O bất đồng bộ, timers, channels, và task scheduling
- reqwest: Async HTTP client with JSON support, TLS, and many features
reqwest: HTTP client bất đồng bộ với hỗ trợ JSON, TLS, và nhiều tính năng khác
- clap: Powerful CLI argument parser with derive macros and auto-generated help
clap: Parser CLI argument mạnh mẽ với derive macros và documentation tự động
- anyhow: Flexible error handling with rich context, ideal for applications
anyhow: Xử lý lỗi linh hoạt với ngữ cảnh phong phú, lý tưởng cho applications
- thiserror: Derive macro for defining custom error types, ideal for libraries
thiserror: Derive macro để định nghĩa error types tùy chỉnh, lý tưởng cho libraries
- tracing: Async-aware logging and diagnostics framework with structured events
tracing: Framework logging và diagnostics bất đồng bộ với structured events
- rayon: Easy data parallelism with parallel iterators
rayon: Data parallelism dễ sử dụng với parallel iterators
- axum / actix-web: High-performance async web frameworks for building HTTP servers
axum / actix-web: Web frameworks bất đồng bộ mạnh mẽ cho xây dựng HTTP servers
- sqlx / diesel: Database access with compile-time type safety
sqlx / diesel: Database access với type safety tại compile time
1// Example: using several popular crates together23// Cargo.toml:4// [dependencies]5// serde = { version = "1", features = ["derive"] }6// serde_json = "1"7// anyhow = "1"8// tokio = { version = "1", features = ["full"] }9// reqwest = { version = "0.11", features = ["json"] }1011use serde::{Deserialize, Serialize};12use anyhow::{Context, Result};Cargo provides many useful commands for everyday development tasks. Mastering these commands helps you work more efficiently with Rust.
Cargo cung cấp nhiều lệnh hữu ích cho các tác vụ phát triển hàng ngày. Nắm vững các lệnh này giúp bạn làm việc hiệu quả hơn với Rust.
1# Project creation2cargo new my_app # binary project3cargo new my_lib --lib # library project4cargo init # initialize in existing directory56# Building7cargo build # debug build8cargo build --release # optimized release build9cargo check # check for errors without compiling1011# Running12cargo run # build and runCargo has two default profiles: dev (used by cargo build) prioritizes fast compilation and debug experience, while release (used by cargo build --release) prioritizes runtime performance. You can customize and create additional profiles.
Cargo có hai profile mặc định: dev (dùng cho cargo build) ưu tiên tốc độ biên dịch và trải nghiệm debug, còn release (dùng cho cargo build --release) ưu tiên hiệu suất runtime. Bạn có thể tùy chỉnh và tạo thêm profile mới.
1# In Cargo.toml23[profile.dev]4opt-level = 0 # no optimization (fast compile)5debug = true # include debug info6overflow-checks = true # panic on integer overflow78[profile.release]9opt-level = 3 # maximum optimization10debug = false # no debug info11lto = true # link-time optimization (slower build, faster binary)12codegen-units = 1 # better optimization (slower parallel compile)Features allow you to conditionally compile parts of your code. This is useful for creating smaller binaries by excluding unneeded functionality, or for offering optional capabilities to library users.
Features cho phép bạn biên dịch có điều kiện các phần của code. Điều này hữu ích để tạo ra các binary nhỏ hơn bằng cách loại trừ chức năng không cần thiết, hoặc cung cấp các tính năng tùy chọn cho người dùng thư viện.
1# Cargo.toml2[features]3default = ["std"]4std = []5logging = ["dep:log"]6serde = ["dep:serde", "dep:serde_json"]7async = ["dep:tokio"]8full = ["logging", "serde", "async"]910[dependencies]11log = { version = "0.4", optional = true }12serde = { version = "1", optional = true, features = ["derive"] }#[cfg(...)] lets you conditionally compile code based on platform, feature flags, and custom flags. This is the mechanism for writing code that runs on multiple operating systems or architectures.
#[cfg(...)] cho phép bạn biên dịch có điều kiện code dựa trên platform, feature flags, và các cờ tùy chỉnh. Đây là cơ chế để viết code chạy được trên nhiều hệ điều hành hoặc kiến trúc khác nhau.
1// Platform-specific code2#[cfg(target_os = "windows")]3fn get_config_path() -> &'static str {4 "C:\Users\user\AppData\config.toml"5}67#[cfg(target_os = "linux")]8fn get_config_path() -> &'static str {9 "/home/user/.config/config.toml"10}1112#[cfg(target_os = "macos")]The Cargo ecosystem has many third-party plugins that extend its capabilities. These plugins are installed as Cargo subcommands and significantly boost development productivity.
Hệ sinh thái Cargo có nhiều plugin bên thứ ba mở rộng khả năng của nó. Các plugin này được cài đặt như các lệnh phụ của Cargo và tăng đáng kể năng suất phát triển.
1# Install a cargo plugin:2# cargo install <plugin-name>34# cargo-watch: rebuild on file changes5# cargo install cargo-watch6# cargo watch -x run7# cargo watch -x test8# cargo watch -x "run -- --port 8080"910# cargo-expand: show macro-expanded code11# cargo install cargo-expand12# cargo expand # expand all macrosRust Editions are the mechanism by which Rust introduces potentially breaking language changes without breaking existing code. Each crate declares its edition in Cargo.toml. Current editions are 2015, 2018, 2021, and 2024.
Rust Edition là cơ chế để Rust giới thiệu các thay đổi ngôn ngữ có thể phá vỡ tương thích mà không làm hỏng code hiện tại. Mỗi crate trong Cargo.toml khai báo edition của nó. Hiện tại có các edition 2015, 2018, 2021, và 2024.
1# Cargo.toml2[package]3name = "my_crate"4edition = "2021" # use the latest stable edition56---78// Key differences between editions:910// Edition 2015 (original Rust release)11// - extern crate declarations required12extern crate serde; // needed in 2015Tất cả các edition Rust đều tương thích với nhau — một crate edition 2015 và một crate edition 2021 có thể hoàn toàn phụ thuộc vào nhau. Edition chỉ ảnh hưởng đến cách biên dịch code trong crate đó.
Key Takeaways
Điểm Chính
- Cargo.toml defines dependencies with semantic versioningCargo.toml định nghĩa dependency với phiên bản ngữ nghĩa
- Workspaces manage multiple related packages in one repositoryWorkspace quản lý nhiều gói liên quan trong một kho lưu trữ
- Popular crates include serde, tokio, clap, and anyhowCác crate phổ biến bao gồm serde, tokio, clap và anyhow
- Cargo features enable conditional compilation of optional codeFeature của Cargo cho phép biên dịch có điều kiện code tùy chọn
Practice
Test your understanding of this chapter
What version range does the Cargo requirement serde = '1.2.3' (caret, the default) allow?
Yêu cầu phiên bản Cargo serde = '1.2.3' (caret, mặc định) cho phép phạm vi phiên bản nào?
What do all crates in a Cargo workspace share by default?
Tất cả các crate trong Cargo workspace chia sẻ gì theo mặc định?
A Rust library crate should commit its Cargo.lock file to version control so that downstream users get reproducible builds.
Crate thư viện Rust nên commit file Cargo.lock vào version control để đảm bảo người dùng downstream có bản build tái tạo được.
A crate using Rust edition 2021 and a crate using edition 2015 are fully interoperable and can depend on each other without any compatibility issues.
Một crate dùng Rust edition 2021 và một crate dùng edition 2015 hoàn toàn tương thích và có thể phụ thuộc vào nhau mà không có vấn đề tương thích nào.
Fill in the attribute to conditionally compile a module based on a feature flag
Điền vào thuộc tính để biên dịch có điều kiện một module dựa trên feature flag
#[(feature = "logging")] mod log_impl { pub fn log_message(msg: &str) { log::info!("{}", msg); } }