crate、package、workspace 是三个常被混用的词。这篇用 cargo 的真实输出把它们分开:一个 package 里到底有几个 crate、workspace 共享什么、在成员目录里运行 cargo 会发生什么,以及包名和代码里的名字为什么不同。
$ cargo build -v 里的 rustc 调用(crate 名与类型): [('pkg2', 'lib'), ('pkg2', 'bin')]
目录: ['Cargo.lock', 'Cargo.toml', 'src/', 'src/lib.rs', 'src/main.rs']
$ cargo run -q → 来自 lib crate 根 Cargo.toml: [workspace] ⏎ members = ["app", "core"] ⏎ resolver = "3" ⏎
app/Cargo.toml 的依赖: core_lib = { path = "../core" }
$ cargo build(在 workspace 根):
Compiling core_lib v0.1.0 (<实验目录>/proj/ws/core)
Compiling app v0.1.0 (<实验目录>/proj/ws/app)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.26s
目录(不含 target): ['Cargo.lock', 'Cargo.toml', 'app/', 'app/Cargo.toml', 'app/src/', 'app/src/main.rs', 'core/', 'core/Cargo.toml', 'core/src/', 'core/src/lib.rs']
只有根目录有 Cargo.lock: True | app/Cargo.lock 存在: False
不设 CARGO_TARGET_DIR、在 app/ 子目录里 cargo build 之后:ws/target 存在 = True | ws/app/target 存在 = False (target 在 workspace 根)workspace 的依赖统一管理见Workspace 依赖管理;Cargo.lock 的作用见Cargo.lock 的作用。
$ cargo run -q -p app → answer = 42
$ (cd app && cargo run -q) → answer = 42
$ cargo tree
app v0.1.0 (<实验目录>/proj/ws/app)
└── core_lib v0.1.0 (<实验目录>/proj/ws/core)
core_lib v0.1.0 (<实验目录>/proj/ws/core)
cargo metadata:workspace_members 共 2 个;packages = ['app', 'core_lib'] | workspace_root = <实验目录>/proj/ws包名 my-pkg → rustc 的 --crate-name: ['my_pkg'] 依赖里写 my-pkg,代码里用 my_pkg::f() → 1