使用 Buck2 编译构建 Rust 工程
最近觉得 FacebooK Meta 开源项目都挺良心, 从 React 到 Sapling, Buck2 等等, 更是有 AI 大模型的 Llama , 让多少国产大模型实现了自主可控。 当然我关注的点都集中在 Rust 开发的项目中, 先是 Monorepo 解决方案 Sapling 让我感到自己做 Mega 其实路还有很长; 再有 Buck2 (Rust 重写 Meta 的构建系统 Buck), 让我明白没有构建系统的 Monorepo & Monolithic 解决方案是不完整的。 之前因为参加 BazelCon 2023 临时加入了 Bazel 不完整的支持, 其实整个项目都还在 Demo 的状态。 春节前最后整理好第一版的数据库结果, 也确定了是使用 Buck2 作为构建系统, 让整个解决方案更加 Rusty 。
当边看文档边在 Mega 中加入 Buck2 的支持时, 发现还是有很多概念需要学习, 没办法只能从 Hello World 开始尝试构建, 并且记录对 Buck2 的学习。
按照 Buck2
首先是安装 Buck2 , 目前还在 pre-release 阶段, 我是直接从 GitHub 直接下载了 Buck2 的二进制文件, 并且放到了 /usr/local/bin
目录下。 开发环境是 Arch Linux, 我提前安装了 clang
和 lld
, 如果还有什么其他的依赖, 请自行安装。
$ paru -S clang lld
创建 Rust 项目, 初始化 Buck2 支持
首先使用 cargo
命令创建一个 Rust 项目:
$ cargo new rust-buck2
然后进入目录初始化 Buck2 支持:
$ cd rust-buck2
$ buck2 init --git --allow-dirty
Reinitialized existing Git repository in /home/eli/GitMono/rust-buck2/.git/
Cloning into '/home/eli/GitMono/rust-buck2/prelude'...
remote: Enumerating objects: 19987, done.
remote: Counting objects: 100% (15879/15879), done.
remote: Compressing objects: 100% (4026/4026), done.
remote: Total 19987 (delta 11767), reused 15823 (delta 11737), pack-reused 4108
Receiving objects: 100% (19987/19987), 5.50 MiB | 641.00 KiB/s, done.
Resolving deltas: 100% (15035/15035), done.
这个时候目录结构如下, 添加了 Buck2 的一些配置文件和 prelude
目录,
$tree -a -L 1
├── BUCK
├── .buckconfig
├── .buckroot
├── Cargo.toml
├── .git
├── .gitignore
├── .gitmodules
├── prelude
├── src
└── toolchains
编译
当前 BUCK
文件内容还是初始化的部分, 执行后会在 buck-out
目录下生成 out.txt
文件。
# A list of available rules and their signatures can be found here: https://buck2.build/docs/api/rules/
genrule(
name = "hello_world",
out = "out.txt",
cmd = "echo BUILT BY BUCK2> $OUT",
)
$ buck2 build //...
Could not connect to buck2 daemon, starting a new one...
Connected to new buck2 daemon.
Build ID: 20514717-e6cc-443e-bfa9-b375e5adabf8
Jobs completed: 42. Time elapsed: 0.0s.
Cache hits: 0%. Commands: 1 (cached: 0, remote: 0, local: 1)
BUILD SUCCEEDED
对 BUCK
文件进行修改, 使用编译 Rust ToolChain
编译代码,
rust_binary(
name = "rust-buck2",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/main.rs",
)
$ buck2 build //:rust-buck2
File changed: root//BUCK
Build ID: 5106983d-7d75-4a7b-ad91-c700a0633851
Jobs completed: 40. Time elapsed: 0.1s.
Cache hits: 0%. Commands: 1 (cached: 0, remote: 0, local: 1)
BUILD SUCCEEDED
$ buck2 run //:rust-buck2
Build ID: f407f0d4-b7b5-4309-960b-01e265a2a02b
Jobs completed: 3. Time elapsed: 0.0s.
BUILD SUCCEEDED
Hello, world!
修改 Toolchain 配置
使用 prelude
目录下的规则文件修改 toolchains
目录下的 BUCK
文件, 删除默认的 load("@prelude//toolchains:demo.bzl", "system_demo_toolchains")
和 system_demo_toolchains()
,
load("@prelude//toolchains:rust.bzl", "system_rust_toolchain")
load("@prelude//toolchains:genrule.bzl", "system_genrule_toolchain")
load("@prelude//toolchains:cxx.bzl", "system_cxx_toolchain")
load("@prelude//toolchains:python.bzl", "system_python_bootstrap_toolchain")
system_genrule_toolchain(
name = "genrule",
visibility = ["PUBLIC"],
)
system_rust_toolchain(
name = "rust",
default_edition = "2021",
visibility = ["PUBLIC"],
)
system_cxx_toolchain(
name = "cxx",
visibility = ["PUBLIC"],
)
system_python_bootstrap_toolchain(
name = "python_bootstrap",
visibility = ["PUBLIC"],
)
目前这个 Toolchain 可以用于更多的项目, 例如 C++ 项目, Python 项目等等。
测试的项目在 GitHub - Rust Buck2 Example , 后续会持续更新。
Rust Monorepo Template with Buck2 中, 正在持续尝试构建一个完整的
Rust Monorepo
工程模板, 通过Buck2
和Reindeer
管理整个工程的构建和测试, 可以从这个项目中开始你的Rust Monorepo
之旅。