bigywater.tech
Rust · 15

Crate、Package 与 Workspace

crate、package、workspace 是三个常被混用的词。这篇用 cargo 的真实输出把它们分开:一个 package 里到底有几个 crate、workspace 共享什么、在成员目录里运行 cargo 会发生什么,以及包名和代码里的名字为什么不同。

2 个 crate
同一个 package 里的 lib 与 bin(cargo build -v 里的两次 rustc 调用)
1 份
workspace 只有根目录一份 Cargo.lock 与一个 target
my-pkg → my_pkg
包名连字符在代码里变下划线

package 与 crate

实测 · 本机执行输出
  $ 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

workspace

实测 · 本机执行输出
  根 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

包名与 crate 名

实测 · 本机执行输出
  包名 my-pkg → rustc 的 --crate-name: ['my_pkg']
  依赖里写 my-pkg,代码里用 my_pkg::f() → 1

分步演示

crate、package 与 workspace
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / rustc 1.98.1(brew)/ cargo 1.98.1;单个文件用 rustc 直接编译,需要依赖时用 cargo(经代理从 crates.io 下载);计时用 std::time::Instant,数字每次运行会有小幅抖动。项目在临时目录里;全部用路径依赖,没有访问 crates.io
    • 没有验证:workspace.dependencies 的版本继承、虚拟 workspace 与根 package 同时存在、成员的 default-members、resolver 的版本差别、发布到 crates.io 时的 package 规则
    京ICP备2026067502号-1京公网安备11010502063487号