无Cargo的Rust Bazel项目如何配置特性门控可选依赖?
Bazel Rust项目实现特性门控可选依赖(无Cargo)
问题描述
我正在搭建一个不使用Cargo的Rust Bazel项目,需要为serde_json配置特性门控的可选依赖。已经完成crates_vendor配置:
crates_vendor( name = "crates_io", cargo_lockfile = ":Cargo.Bazel.lock", mode = "remote", packages = { "tonic": crate.spec(version = "*"), "serde": crate.spec(version = "1.0"), "serde_json": crate.spec(version = "1.0"), }, repository_name = "crates_io", tags = ["manual"], )
当前Rust库定义:
rust_library( name = "foo", srcs = glob("**/*.rs"), deps = [ "@crates_io//:serde", "@crates_io//:serde_json", ], )
希望实现类似Cargo中的特性门控效果:
[dependencies] serde_json = { version = "1.0", optional = true } [features] json = ["dep:serde_json"]
解决方案
通过Bazel的build_setting和select机制可以实现对应特性门控,步骤如下:
1. 定义特性开关
在BUILD文件中添加布尔型构建设置,作为特性的控制开关:
build_setting( name = "enable_json", kind = "bool", build_setting_default = False, # 默认关闭该特性 )
2. 配置带特性门控的rust_library
修改rust_library定义,通过select动态控制依赖和编译参数:
rust_library( name = "foo", srcs = glob("**/*.rs"), deps = [ "@crates_io//:serde", # 根据开关状态决定是否引入serde_json依赖 select({ ":enable_json": ["@crates_io//:serde_json"], "//conditions:default": [], }), ], # 向rustc传递cfg标志,对应代码中的特性条件编译 rustc_flags = select({ ":enable_json": ["--cfg", "feature=\"json\""], "//conditions:default": [], }), )
3. 在Rust代码中使用特性条件编译
在.rs文件里用#[cfg(feature = "json")]标记特性相关代码:
#[cfg(feature = "json")] pub fn serialize_to_json(data: &impl serde::Serialize) -> Result<String, serde_json::Error> { serde_json::to_string(data) }
4. 构建时切换特性状态
- 默认关闭特性构建:
bazel build :foo - 开启json特性构建:
bazel build --//:enable_json=true :foo
内容的提问来源于stack exchange,提问作者Victor
相关产品推荐
相关产品推荐

