自定义规则不构建依赖目标

Custom rule does not build dependent target

我想 运行 在 qemu 上进行单元测试。我创建了一个自定义规则,它使用规则中指定的参数调用 qemu。其中一个参数是 elf 文件(规则属性 "target"),它被 qemu 用作内核。
当我使用以下命令调用自定义规则时,elf 文件 ("kernel.elf") 未编译:

 bazel build //test:custom_rule

即使 bazel query 'deps(//test:custom_rule)' 将目标“:kernel.elf”列为依赖项,也会发生这种情况。

此外,自定义规则还有一个问题。当我手动构建“:kernel.elf”并在之后调用自定义规则时,qemu 告诉我,它无法加载内核文件。在 shell 中手动调用 qemu 命令确实有效,所以我猜问题不在 "kernel.elf" 文件中。

有人能解答我的问题吗?

提前致谢!

run_tests.bzl

def _impl(ctx):
  qemu = ctx.attr.qemu
  machine = ctx.attr.machine
  cpu = ctx.attr.cpu
  target = ctx.file.target.path
  output = ctx.outputs.out
  # The command may only access files declared in inputs.
  ctx.actions.run_shell(
      arguments = [qemu, machine, cpu, target],
      outputs=[output],
      command=" -M  -cpu  -nographic -monitor null 
               -serial null -semihosting -kernel  > %s" % (output.path))


run_tests = rule(
    implementation=_impl,
    attrs = {"qemu" : attr.string(),
             "machine" : attr.string(),
             "cpu" : attr.string(),
             "target" : attr.label(allow_files=True, single_file=True,
                        mandatory=True)},
    outputs={"out": "run_tests.log"}
)

建造

load("//make:run_tests.bzl", "run_tests")

run_tests(
    name = "custom_rule",
    qemu = "qemu-system-arm",
    machine = "xilinx-zynq-a9",
    cpu = "cortex-a9",
    target = ":kernel.elf"
)

cc_binary(
    name = "kernel.elf",
    srcs = glob(["*.cc"]),
    deps = ["//src:portos", 
            "@unity//:unity"],
    copts = ["-Isrc", 
             "-Iexternal/unity/src",
             "-Iexternal/unity/extras/fixture/src"] 
)

问题可能是需要为操作指定输入,请参阅 https://docs.bazel.build/versions/master/skylark/lib/actions.html#run_shell.inputs

您可能还需要为 qemu 创建一个标签,并将其作为操作的输入(如果 qemu 需要一个文件,机器也是如此)

例如类似于:

def _impl(ctx):
  qemu = ctx.attr.qemu
  machine = ctx.attr.machine
  cpu = ctx.attr.cpu
  target = ctx.file.target.path
  output = ctx.outputs.out
  # The command may only access files declared in inputs.
  ctx.actions.run_shell(
      inputs = [qemu, target],
      outputs=[output],
      arguments = [qemu, machine, cpu, target],
      command=" -M  -cpu  -nographic -monitor null 
               -serial null -semihosting -kernel  > %s" % (output.path))


run_tests = rule(
    implementation=_impl,
    attrs = {
        "qemu" : attr.label(allow_files=True, single_file=True,
                            mandatory=True),
        "machine" : attr.string(),
        "cpu" : attr.string(),
        "target" : attr.label(allow_files=True, single_file=True,
                              mandatory=True)
    },
    outputs={"out": "run_tests.log"}
)