module system
- Packages: A Cargo feature that lets you build, test, and share crates
- Crates: A tree of modules that produces a library or executable
- Modules and use: Let you control the organization, scope, and privacy of paths
- Paths: A way of naming an item, such as a struct, function, or module
package
A package can contain multiple binary crates and optionally one library crate. At least on crate.
├── Cargo.lock
├── Cargo.toml
├── src
│ ├── bin
│ │ └── a.rs
│ │ └── b.rs
│ ├── lib.rs
│ └── main.rs
Crates
- binary crate
- library crate
Modules
pubmoduseas
visibility
- private(default)
pub(crate)pub(in path)pub use
xxx/mod.rsvs xxx.rs
- Inline, within curly brackets that replace the semicolon following mod garden
- In the file src/garden.rs
- In the file src/garden/mod.rs
├── Cargo.lock
├── Cargo.toml
├── src
│ ├── A.rs
│ ├── B
│ │ └── mod.rs
│ ├── bin
│ │ └── a.rs
│ ├── lib.rs
│ └── main.rs
details
use init_rust_project::echo;
mod A;
mod B;
fn main() {
println!("Hello, world!");
echo("Hi World");
A::a();
let one = A::ONE;
B::echo();
}
Path
- absolute path
crate - relative path
superself
details
use init_rust_project::echo;
use A::ONE;
use B::echo as echo2;
mod A;
mod B;
fn main() {
println!("Hello, world!");
echo("Hi World");
A::a();
crate::A::a();
let one = ONE;
B::echo();
self::B::echo();
echo2();
}
fn echo_from_main() {
//
}
mod MainModule {
fn test() {
super::echo_from_main();
}
}
workspace
multi packages
Root dir cargo.toml
[workspace]
lib_add = {path ="./lib_add"}
setup project
cargo new xxx- Fill out
cargo.toml - Split out module
- Add test
- unit
- integration
- doc
- bench
- examples
- Publish to
crates.io
target 目录分析
在 Rust 中使用 cargo build 命令时,生成的目标目录(通常是 target)包含了编译输出和构建过程中产生的各种文件。以下是 target/debug 目录结构的分析:
└── debug
├── build
├── deps
├── examples
├── incremental
├── liblib_add.d
├── liblib_add.rlib
├── rust-workspace
└── rust-workspace.d
目录与文件分析
build:
- 该目录包含了构建过程中生成的中间文件和依赖项信息。
build目录用于存放构建脚本(如build.rs)的输出及其依赖关系。
deps:
- 该目录包含编译后的库和二进制文件,通常是
.rlib和.d文件。 - 这些文件是构建过程中生成的所有依赖库的编译结果,命名格式通常为
lib{crate-name}-{hash}.rlib或{crate-name}-{hash}.d。
- 该目录包含编译后的库和二进制文件,通常是
examples:
- 该目录包含编译后的示例程序。
- Rust 项目可以在
examples目录下包含示例代码,这些示例代码会被单独编译并放在target/debug/examples目录中。
incremental:
- 该目录用于存放增量编译的缓存文件。
- Rust 的增量编译功能使得只重新编译发生变化的部分代码,从而加快编译速度。
incremental目录中存放的就是这些缓存文件。
liblib_add.d:
.d文件是依赖关系文件,通常包含了源文件之间的依赖关系信息,用于增量编译过程中决定哪些文件需要重新编译。
liblib_add.rlib:
.rlib文件是 Rust 编译生成的库文件,包含了编译后的中间代码,可以被其他 Rust 项目链接和使用。liblib_add.rlib是lib_add库的编译结果,包含了该库的所有代码。
rust-workspace:
- 该文件是编译后的
rust-workspace二进制文件。 - 如果
rust-workspace是一个可执行项目,这里存放的就是最终的可执行文件。
- 该文件是编译后的
rust-workspace.d: -
.d文件与前面的liblib_add.d类似,包含了rust-workspace可执行文件的依赖关系信息。
build.rs
details
A build.rs script in a Rust project is used to perform custom build steps before the main compilation. These steps might include generating code, compiling other languages, or setting environment variables. The output from build.rs can sometimes be confusing if it doesn't show up as expected. Here’s how to properly write and debug a build.rs file.
Example of a Basic build.rs File
Here’s a simple example of a build.rs file that prints messages and sets environment variables:
use std::env;
use std::fs::File;
use std::io::Write;
fn main() {
// Print messages to the build output
println!("Hello from build.rs!");
// Print a cargo directive to rerun the build script if build.rs changes
println!("cargo:rerun-if-changed=build.rs");
// Print a cargo directive to set an environment variable
println!("cargo:rustc-env=MY_ENV_VAR=Hello from build.rs!");
// Write to a file for debugging purposes
let mut file = File::create("build_output.txt").expect("Could not create file");
writeln!(file, "Hello from build.rs!").expect("Could not write to file");
// Example of setting an environment variable for the Rust compiler
env::set_var("MY_BUILD_VAR", "Some value");
}
创建 examples 目录及编写示例代码
details
examples 目录下的文件是用户在项目中专门为编写示例程序而创建的。这些示例程序可以用来展示如何使用你的库、验证特定功能或提供具体的使用案例。
1. 创建 examples 目录
首先,在你的项目根目录下创建一个名为 examples 的目录:
mkdir examples
2. 编写示例程序
在 examples 目录下,你可以创建多个 Rust 源文件,每个文件都代表一个独立的示例程序。例如,创建一个名为 hello_world.rs 的文件:
touch examples/hello_world.rs
在这个文件中编写你的示例代码:
fn main() {
println!("Hello, world!");
}
编译和运行示例程序
要编译和运行 examples 目录下的示例程序,可以使用 cargo run --example 命令。下面是一些常用的命令:
列出所有示例
cargo run --example
运行特定示例
运行 hello_world 示例:
cargo run --example hello_world
cargo test --example hello_world
cargo test --examples # run all of examples
setup project
cargo
cargo install cargo add
details
cargo install rand and cargo add rand serve different purposes in the Rust ecosystem. Here's a detailed comparison of the two commands:
cargo install rand
- Purpose: Installs a binary crate globally.
- Usage:
cargo install <crate-name> - Example:
cargo install rand - Effect:
- Downloads and compiles the
randcrate (or any specified crate) as a binary and installs it in a location where it can be run globally (usually~/.cargo/bin). - The
randcrate doesn't provide binaries, so runningcargo install randwould result in an error:error: specified package `rand` has no binaries - Useful for installing command-line tools written in Rust, such as
ripgrep,fd, orcargo-edit.
- Downloads and compiles the
cargo add rand
- Purpose: Adds a crate as a dependency to your project's
Cargo.tomlfile. - Usage:
cargo add <crate-name> - Example:
cargo add rand - Effect:
- Modifies the
Cargo.tomlfile of your Rust project to includerandas a dependency. - Automatically resolves the latest version and adds the corresponding line in the
[dependencies]section:[dependencies] rand = "0.8" cargo addis a command provided by thecargo-editcrate, which needs to be installed first usingcargo install cargo-edit.
- Modifies the
Key Differences
Installation Scope:
cargo install: Installs binaries globally.cargo add: Adds libraries as dependencies to your local project.
Use Case:
cargo install: Used for installing Rust-based tools and binaries.cargo add: Used for managing project dependencies.
Output:
cargo install: A binary available globally.cargo add: An updatedCargo.tomlfile with the new dependency.
Example Usage
Installing
cargo-editto usecargo add:cargo install cargo-editAdding
randas a dependency:cargo add rand
This will update your Cargo.toml file to include the rand crate as a dependency, allowing you to use it in your Rust project's code.
Summary
- Use
cargo installto install Rust command-line tools and binaries globally. - Use
cargo addto add libraries as dependencies to your Rust project.