Buck2 编译 Rust 工程处理 feature 的问题
feature 是 Rust 开发过程中非常重要的特性,开发者可以通过 Feature 实现代码编码在不同条件下的行为,以下是一个简单的 Feature 示例:
fn main() {
#[cfg(feature = "debug")]
println!("Debug mode is enabled!");
#[cfg(feature = "release")]
println!("Release mode is enabled!");
println!("Hello, world!");
}
当编译我们使用 cargo build --release
编译时,会启用 release
Feature,输出如下:
cargo run --features="release"
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
Running `target/debug/buck2-build-rust-feature`
Release mode is enabled!
Hello, world!
当我们编写 BUCK 文件的时候如何处理呢,当然我们可以写几个目标任务,例如:
load("@prelude//toolchains:rust.bzl", "system_rust_toolchain")
rust_binary(
name = "main-release",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/main.rs",
features = ["release"],
)
rust_binary(
name = "main-debug",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/main.rs",
features = ["debug"],
)
这样 BUCK 文件非常臃肿,当 Feature 有多个且需要组合的时候, 这个方式就变得不再可行。所以我们要编写一个 rule 来处理外部传入的 Feature 参数,实现动态的构建:
# config.bzl
def get_rust_features():
features_config = read_config("rust", "features", "")
if features_config == "":
return []
return [f.strip() for f in features_config.split(",") if f.strip()]
load("@prelude//toolchains:rust.bzl", "system_rust_toolchain")
load("//:config.bzl", "get_rust_features")
rust_binary(
name = "rust-features",
srcs = glob(["src/**/*.rs"]),
crate_root = "src/main.rs",
features = get_rust_features(),
)
当执行 buck2 build
命令时,使用参数 --config
参数传入 Feature 即可:
buck2 run //:rust-features
Build ID: b28ffbd2-3244-453f-80fc-ffab59e4ee2c
Loading targets. Remaining 0/1 56 dirs read, 1 targets declared
Analyzing targets. Remaining 0/50 35 actions, 64 artifacts declared
Executing actions. Remaining 0/7 0.8s exec time total
Command: run. Finished 1 local
Time elapsed: 0.8s
BUILD SUCCEEDED
Starting RUN of `//:rust-features`
Running defined output located at: `/Users/eli/GitMono/buck2-build-rust-feature/buck-out/v2/gen/root/200212f73efcd57d/__rust-features__/rust_features`
Hello, world!
#---
buck2 run //:rust-features --config rust.features=debug
Build ID: daf63b18-34a0-4a1d-80cc-da10e64f7983
Loading targets. Remaining 0/1 1 targets declared
Analyzing targets. Remaining 0/1 35 actions, 64 artifacts declared
Executing actions. Remaining 0/5 0.4s exec time total
Command: run. Finished 1 local
Time elapsed: 0.4s
BUILD SUCCEEDED
Starting RUN of `//:rust-features`
Running defined output located at: `/Users/eli/GitMono/buck2-build-rust-feature/buck-out/v2/gen/root/200212f73efcd57d/__rust-features__/rust_features`
Debug mode is enabled!
Hello, world
#---
buck2 run //:rust-features --config rust.features=debug,release
File changed: root//README.md
Build ID: a6c85fd0-8e8e-44eb-9a60-48c9223d41e1
Loading targets. Remaining 0/1 1 targets declared
Analyzing targets. Remaining 0/1 35 actions, 64 artifacts declared
Executing actions. Remaining 0/5 0.4s exec time total
Command: run. Finished 1 local
Time elapsed: 0.4s
BUILD SUCCEEDED
Starting RUN of `//:rust-features`
Running defined output located at: `/Users/eli/GitMono/buck2-build-rust-feature/buck-out/v2/gen/root/200212f73efcd57d/__rust-features__/rust_features`
Debug mode is enabled!
Release mode is enabled!
Hello, world!
当然这只是简单的一个 Feature 示例,实际情况可能要比这个还要复杂,所以下一篇找一个实际项目来编写更复杂的 BUCK 文件。
代码托管在 GitHub 上,请访问 buck2-build-rust-feature 。