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
pub
mod
use
as
visibility
- private(default)
pub(crate)
pub(in path)
pub use
xxx/mod.rs
vs 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
super
self
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
rand
crate (or any specified crate) as a binary and installs it in a location where it can be run globally (usually~/.cargo/bin
). - The
rand
crate doesn't provide binaries, so runningcargo install rand
would 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.toml
file. - Usage:
cargo add <crate-name>
- Example:
cargo add rand
- Effect:
- Modifies the
Cargo.toml
file of your Rust project to includerand
as a dependency. - Automatically resolves the latest version and adds the corresponding line in the
[dependencies]
section:[dependencies] rand = "0.8"
cargo add
is a command provided by thecargo-edit
crate, 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.toml
file with the new dependency.
Example Usage
Installing
cargo-edit
to usecargo add
:cargo install cargo-edit
Adding
rand
as 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 install
to install Rust command-line tools and binaries globally. - Use
cargo add
to add libraries as dependencies to your Rust project.