如何使用 bazel 从同一组输入文件生成多个文件

How do I use bazel to produce multiple files from the same set of input files

我有一个简单的项目,它使用 SWIG 使一个小型 C++ 库可用于 C#。 C++ 部分是一个源文件和一个头文件——此外还有一个 SWIG 接口文件。 SWIG 的输出包含 5 个 C# 源文件和 1 个 C++ 源文件。

使用 make 执行此操作相当简单,但我在思考 bazel 时遇到了一些问题。

我如何告诉 bazel 这 6 个文件是 所有 使用相同命令生成的?另外,当我在做的时候,我如何告诉 bazel 实际调用该命令。

我最终感兴趣的最终产品是一个 .net dll 文件,它只依赖于接口文件和原始 C++ 头文件。

Bazel 没有从 C++ 生成 SWIG 的内置规则,但您可以使用通用规则 (genrule) or teach Bazel how to build a SWIG library by writing your own rule.

如果使用 genrule,则在 outs 属性中指定所有预期输出。您的规则将如下所示:

genrule(
    name = "cc_swig",
    srcs = [
        "lib.cc",
        "lib.h",
    ],
    outs = [
        "file1.cs",
        ...
        "fileN.cc",
    ],
    tools = [
        "//path/to/swig/compiler:bin",
    ],
    cmd = "$(location //path/to/swig/compiler:bin) --src=$(location lib.cc) --header=$(location lib.h) --out1=$(location file1.cs) ... --outN=$(location fileN.cc)",
)

cmd 中的 $(location) 构造是必需的占位符,Bazel 将其替换为引用文件的 运行 时间路径。

(如果 SWIG 编译器不允许您指定将其输出放置在何处,您可以向 cmd 添加更多命令,使 mv 输出文件到达其最终位置,例如 cmd = "... && mv outputs/lib.cs $(location file1.cs)".)

编写自己的规则更高级,所以我不会在这里描述,您可以阅读它们 in the docs

关于如何让 Bazel 构建库——如果 SWIG 编译规则是您的顶级目标的依赖项(即无论您 "bazel build" 是什么),那么 Bazel 将构建它。例如参见 [​​=21=].