Rust构建系统插件库hakari的使用:优化Cargo工作区依赖管理与构建流程
hakari 是 cargo hakari 的底层库,一个用于管理工作区 hack 包的工具。
示例
use guppy::MetadataCommand;
use hakari::{HakariBuilder, HakariOutputOptions};
// 使用此工作区的 PackageGraph 进行这些测试。
let package_graph = MetadataCommand::new()
.build_graph()
.expect("obtained cargo-guppy's PackageGraph");
// HakariBuilder::new 的第二个参数指定一个 Hakari(workspace-hack)包。
// 在此存储库中,该包称为 "guppy-workspace-hack"。
let hakari_package = package_graph.workspace().member_by_name("guppy-workspace-hack").unwrap().id();
let hakari_builder = HakariBuilder::new(&package_graph, Some(hakari_package))
.expect("HakariBuilder was constructed");
// HakariBuilder 有许多配置选项。对于此示例,使用默认值。
let hakari = hakari_builder.compute();
// hakari 可用于构建构成 Cargo.toml 文件一部分的 TOML 表示。
// 可以使用 Hakari::read_toml 管理现有的 Cargo.toml 文件。
let toml = hakari.to_toml_string(&HakariOutputOptions::default()).expect("TOML output was constructed");
// toml 包含将进入 Hakari 包的 Cargo.toml [dependencies]。可以通过
// `HakariCargoToml`(由 Hakari::read_toml 返回)或手动写入。
println!("Cargo.toml contents:\n{}", toml);
cargo-guppy 存储库使用由 cargo hakari 管理的工作区 hack crate。
cargo-guppy 存储库还有许多展示 Hakari 输出的 fixture。
hakari 的工作原理
Hakari 遵循三步过程。
- 配置
HakariBuilder 提供选项来配置 Hakari 计算的方式。支持的选项包括:
- 工作区 hack 包的位置
- 模拟 Cargo 构建的平台
- 使用的 Cargo 解析器版本
- 计算期间要排除的包
- 最终输出中要排除的包
通过可选的 cli-support 功能,HakariBuilder 选项可以从文件读取或写入文件为 TOML 或其他格式。
- 计算
一旦配置了 HakariBuilder,可以调用其 compute 方法来创建 Hakari 实例。算法运行三个步骤:
- 使用 guppy 为每个工作区包和每个给定平台模拟 Cargo 构建,包括无功能、默认功能和所有功能。将结果收集到按每个依赖项及其构建的不同功能集索引的映射中。
- 扫描映射以找出哪些依赖项使用两个或更多不同功能集构建,将它们收集到输出映射中。
- 如果假设输出映射将通过下面的步骤 3 写入工作区 hack 包,可能会导致一些额外的包以第二种功能集构建。查找这些包,将它们添加到输出映射中,并迭代直到达到固定点且没有新包以多种方式构建。
此计算以并行方式完成,使用 Rayon 库。
此计算的结果是一个 Hakari 实例。
- 序列化
最后一步是将输出映射的内容序列化到工作区 hack 包的 Cargo.toml 文件中。
- Hakari::read_toml 读取磁盘上现有的 Cargo.toml 文件。此文件是部分生成的:
[package]
name = "workspace-hack"
version = "0.1.0"
# 更多选项...
### BEGIN HAKARI SECTION
...
### END HAKARI SECTION
BEGIN HAKARI SECTION 和 END HAKARI SECTION 行之外的内容可以手动编辑。此部分内的内容是自动生成的。
成功时,返回 HakariCargoToml。
-
Hakari::to_toml_string 返回自动生成部分的新内容。
-
HakariCargoToml::write_to_file 将内容写入磁盘。
HakariCargoToml 还支持将内容序列化到内存并生成差异。
未来工作
hakari 仍然缺少一些功能:
- 模拟交叉编译
- 平台特定的排除
- 仅在最终结果中包含包的子集(例如统一核心包如 syn 但不包括其他)
这些功能将在有时间时添加。
贡献
查看 CONTRIBUTING 文件了解如何提供帮助。
许可证
此项目根据 Apache 2.0 许可证或 MIT 许可证的条款提供。
完整示例代码:
use guppy::MetadataCommand;
use hakari::{HakariBuilder, HakariOutputOptions};
fn main() {
// 使用此工作区的 PackageGraph 进行这些测试。
let package_graph = MetadataCommand::new()
.build_graph()
.expect("obtained cargo-guppy's PackageGraph");
// HakariBuilder::new 的第二个参数指定一个 Hakari(workspace-hack)包。
// 在此存储库中,该包称为 "guppy-workspace-hack"。
let hakari_package = package_graph.workspace().member_by_name("guppy-workspace-hack").unwrap().id();
let hakari_builder = HakariBuilder::new(&package_graph, Some(hakari_package))
.expect("HakariBuilder was constructed");
// HakariBuilder 有许多配置选项。对于此示例,使用默认值。
let hakari = hakari_builder.compute();
// hakari 可用于构建构成 Cargo.toml 文件一部分的 TOML 表示。
// 可以使用 Hakari::read_toml 管理现有的 Cargo.toml 文件。
let toml = hakari.to_toml_string(&HakariOutputOptions::default()).expect("TOML output was constructed");
// toml 包含将进入 Hakari 包的 Cargo.toml [dependencies]。可以通过
// `HakariCargoToml`(由 Hakari::read_toml 返回)或手动写入。
println!("Cargo.toml contents:\n{}", toml);
}
Rust构建系统插件库hakari的使用:优化Cargo工作区依赖管理与构建流程
介绍
hakari是Rust生态中的一个构建系统插件库,专门用于优化Cargo工作区的依赖管理和构建流程。它通过自动化处理依赖版本冲突和构建缓存,显著提升大型Rust项目的构建效率。
主要特性
- 自动化依赖解析和冲突检测
- 智能构建缓存管理
- 工作区范围内的依赖优化
- 与Cargo原生工具链无缝集成
安装方法
cargo install cargo-hakari
基本使用方法
1. 初始化hakari配置
cargo hakari init
2. 生成依赖图
cargo hakari generate
3. 运行优化构建
cargo hakari build
配置示例
在Cargo.toml
中添加hakari配置:
[package.metadata.hakari]
# 启用所有工作区成员的依赖优化
enable = true
# 排除特定crate
exclude = ["example-crate"]
实际使用示例
// 在工作区根目录执行以下命令
// 1. 查看依赖分析
cargo hakari analyze
// 2. 应用优化建议
cargo hakari apply
// 3. 验证依赖一致性
cargo hakari verify
// 4. 使用优化后的构建
cargo hakari build --release
高级配置
创建hakari.toml
配置文件:
[hakari]
# 指定目标平台
target = "x86_64-unknown-linux-gnu"
# 构建特性配置
[features]
default = ["serde", "tokio"]
optional = ["logging", "metrics"]
常见问题解决
依赖冲突处理
# 显示依赖冲突详情
cargo hakari conflicts
# 自动解决冲突
cargo hakari resolve
缓存管理
# 清理构建缓存
cargo hakari clean
# 查看缓存统计
cargo hakari cache-stats
集成到CI/CD流程
在.github/workflows/ci.yml
中添加:
- name: Setup hakari
run: cargo install cargo-hakari
- name: Run hakari optimization
run: cargo hakari build --release
hakari通过智能的依赖管理和构建优化,能够显著减少大型Rust项目的构建时间,特别适合包含多个crate的工作区项目。
完整示例demo
以下是一个完整的hakari使用示例,展示如何在Rust工作区项目中配置和使用hakari:
项目结构:
my-workspace/
├── Cargo.toml
├── hakari.toml
├── member1/
│ └── Cargo.toml
├── member2/
│ └── Cargo.toml
└── member3/
└── Cargo.toml
工作区根目录 Cargo.toml:
[workspace]
members = ["member1", "member2", "member3"]
[package.metadata.hakari]
enable = true
exclude = ["member3"] # 排除member3 crate的优化
hakari.toml 配置文件:
[hakari]
target = "x86_64-unknown-linux-gnu"
[features]
default = ["serde", "tokio"]
optional = ["logging", "metrics"]
使用流程示例:
# 1. 安装hakari
cargo install cargo-hakari
# 2. 初始化配置
cargo hakari init
# 3. 生成依赖图和分析
cargo hakari generate
cargo hakari analyze
# 4. 查看和解决依赖冲突
cargo hakari conflicts
cargo hakari resolve
# 5. 应用优化配置
cargo hakari apply
# 6. 验证依赖一致性
cargo hakari verify
# 7. 执行优化构建
cargo hakari build --release
# 8. 缓存管理
cargo hakari cache-stats
cargo hakari clean
CI/CD集成示例 (.github/workflows/ci.yml):
name: CI Pipeline
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Setup hakari
run: cargo install cargo-hakari
- name: Run hakari optimization
run: cargo hakari build --release
- name: Run tests
run: cargo test --release
这个完整示例展示了hakari在实际项目中的完整使用流程,包括配置初始化、依赖分析、冲突解决、优化构建以及CI/CD集成。通过这种方式,可以显著提升大型Rust工作区项目的构建效率。