【问题标题】:BAZEL + bash: execute bash/python script to do code generation and use them in bazel systemBAZEL + bash:执行 bash/python 脚本进行代码生成并在 bazel 系统中使用
【发布时间】:2022-01-02 01:31:25
【问题描述】:

我是 Bazel 的新手。我有一个用 Bazel 构建的项目。 但是一些源文件是预先编码生成的,然后用 Bazel 编译它们。 现在我可以独立运行 bash 脚本并运行 bazel 命令:

.
|-- project
|   |-- BUILD (will depend on temp_output:codegen)
|   |-- scripts
|   |   |-- codegen.sh (read config.yaml and generate codegen.cpp/hpp and a BUILD.bazel)
|   |-- config
|   |   |-- config.yaml
|   |-- temp_output
|   |   |-- codegen.cpp (not existed before running codegen.sh)
|   |   |-- codegen.hpp (not existed before running codegen.sh)
|   |   |-- BAZEL.build (not existed before running codegen.sh)
|-- WORKSPACE



$ ./scripts/codegen.sh
$ bazel build :project

codegen.sh 中做了什么:

  1. 阅读 config.yaml,其中包含一些其他 WORKSPACE 路径和名称。
  2. 查询该 WORKSPACE 中的目标。
  3. 创建 cpp/hpp 文件以包含一些头文件。
  4. 创建一个新的 BUILD 文件,添加依赖这些目标。

我的目标是将 bash 脚本嵌入到 bazel 系统中。我尝试使用规则 + action.run。但失败的原因是:

  1. 沙盒目录不可读写。
  2. 在沙盒中找不到输入文件。

有什么奇特的方法可以做到这一点吗?或者有什么可以参考的例子?

【问题讨论】:

    标签: bash bazel bazel-rules


    【解决方案1】:

    执行此操作的简单方法是使用genruleproject/BUILD 中的类似内容:

    genrule(
        name = "run_codegen",
        srcs = [
            "codegen.sh",
            "config.yaml",
        ],
        outs = [
            "codegen.cpp",
            "codegen.hpp",
        ],
        cmd = "$(location codegen.sh) --config $(location config.yaml) --cpp $(location codegen.cpp) --hpp $(location codegen.hpp)",
    )
    
    cc_library(
        name = "codegen",
        hdrs = [ "codegen.hpp" ],
        srcs = [ "codegen.cpp" ],
    )
    

    注意事项:

    • 使用$(location) 获取输入和输出文件的路径。如果脚本使用相对路径,我会修改它以将路径作为参数,或者编写一个包装脚本来创建一个临时目录并根据标志将内容移入/移出那里。创建路径的唯一其他可靠方法是使用 "make" variables,但这些方法通常更难使用,并且相对于对 genrule 的修改更脆弱。
    • 未生成BUILD 文件。您只能通过repository rule 执行此操作,并且它变得更加复杂。对于这个用例,我认为您不需要,只需将规则写入project/BUILD

    如果您出于某种原因想要将其嵌入规则而不是使用 genrule,请确保您使用 File.path 来获取要嵌入命令的所有路径。这相当于$(location)。如果没有看到它的副本,很难更具体地说明为什么您的规则不起作用。

    【讨论】:

    • 嗨@Brian 感谢您的帮助。关于BUILD文件,我要新建一个BUILD文件。 BUILD文件的内容也是codegen。
    • BUILD文件的哪些部分需要生成?根据需要更改的部分,有一些方法可以使用自定义规则。
    • 嗨@Brian Silverman 我试过了。但是失败了。 cc_library(name = "codegen", data = [":run_codegen"],) genrule(name = "run_codegen", srcs = ["codegen_test.sh", ], outs = ["tmp_output.cpp", ], cmd = "$(location codegen_test.sh) $(location tmp_output.cpp)", ) 我需要使用 codegen_test.sh 来生成 tmp_output.cpp 但它报告了 "bazel-out/k8-dbg/bin/tmp_output.cpp: No这样的文件或目录”。
    • 把它放在 cc_library.data 中意味着该规则中的文件可以在运行时加载 .cpp 文件,这是不寻常的。我想你想要它在 cc_library.srcs 中。在尝试使用该相对路径之前,codegen_test.sh 是否会更改为其他目录?
    • 嗨,是的。那是因为我换了另一条路。另一个问题是,在代码生成期间,我将调用“cd $AnotherWORKSPACE; bazel query xxxx”。然后我将进行字符串拆分并找出代码生成内容。看来我不能在脚本中再次调用“bazel 查询”。
    猜你喜欢
    • 2013-12-14
    • 2023-04-03
    • 2017-03-01
    • 2017-03-08
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    相关资源
    最近更新 更多