Rust Bazel 项目中的可选依赖项

问题描述 投票:0回答:1

我将从 Rust 中的 Bazel 项目开始,没有 Cargo。我正在尝试设置一个功能门控的可选依赖项。

我设置了

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",
    ],
)

我想要功能门的是

@crates_io//:serde_json

Cargo.toml
代码是:

[dependencies]
serde_json = { version = "1.0", optional = true }

[features]
json = ["dep:serde_json"]

但是,正如我提到的,这是一个非 Cargo 项目。

实现这一目标的正确方法是什么?尝试通过文档进行挖掘,但无法弄清楚。

rust bazel
1个回答
0
投票

在 Bazel 中,您无法在库的使用者中选择库的功能,功能应在库本身中定义。

因此,就您的情况而言,您有两种选择。

1。为每个功能集定义不同的库。

您可以使用相同的源但具有不同的依赖项来定义库。

rust_library(
    name = "foo",
    srcs = glob("**/*.rs"),
    deps = [
        "@crates_io//:serde",
    ],
)

rust_library(
    name = "foo_json",
    crate_name = "foo",
    crate_features = ["foo_json"],
    srcs = glob("**/*.rs"),
    deps = [
        "@crates_io//:serde",
        "@crates_io//:serde_json",
    ],
)

注意,如果 Bazel 目标名称与 crate 名称不同,则需要传递

crate_name
。 另请注意,您可能还必须在库上设置功能,因为
rustc
也应该了解启用的功能。

这是使用功能的直接且相当稳健的方式。

2。使用可配置属性

这将允许您的库仅定义一次。并在构建时打开和关闭功能。 其缺点是这些功能只能全局启用。

foo
库的所有用法都将使用带或不带 json 的版本。

load("@rules_rust//rust:defs.bzl", "rust_library")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")

# Here we define a boolean flag, that can later use on command line
bool_flag(
    name = "use_json",
    build_setting_default = False,
)

# The flag from above turn on and off the named config setting
config_setting(
    name = "foo_json",
    flag_values = {":use_json": "true"},
)

# based on the config setting we can select features
# we will pass to the compiler...
foo_features = select({
    ":foo_json": ["json"],
    "//conditions:default": [],
})

# .. and the dependncies, that we need.
foo_optional_deps = select({
    ":foo_json": [
        # "@crates_io//:serde_json",
    ],
    "//conditions:default": [],
})

# After we selected features and dependencies, we
# define the library using them.
rust_library(
    name = "foo",
    srcs = ["src/lib.rs"],
    crate_features = foo_features,
    deps = [
    ] + foo_optional_deps
)

例如如果我有一个依赖于

foo
库的工具,

rust_binary(
    name = "tool",
    srcs = ["src/main.rs"],
    deps = [
        "//foo:foo",
    ],
)

此示例打开

json
功能,您可以使用命令行:

bazel run //tool:tool --//foo:use_json

如何选择?

如果您想为不同的下游项目使用

foo
的不同功能,那么第一种方法是可行的。

如果您构建的软件具有全局切换的某些功能(例如免费版本,禁用了某些功能),则第二种方法可能会更好。

© www.soinside.com 2019 - 2024. All rights reserved.