Mike van Dyke
Mike van Dyke

Reputation: 2858

Bazel: Run a command without an output

I am using bazel for building bare metal programs. I would like to run the unit tests generated by bazel on qemu.

qemu-system-* -some_args -kernel bazel-bin/whatever/generated.elf

I've tried to run those by creating my own rule in a '.bzl'-file, but it seems that outputs are mandatory on all the rule actions. Note, that I need to invoke different qemu commands with different arguments depending on the target architecture. I would like to pass those to the rule.

Is there a way to invoke a shell command without any outputs?

If needed, this is what I have so far (yet I'm not sure which parts are correct as bazel stops in the analysis phase):

# run_tests.bzl
===============
def _impl(ctx):
  qemu = ctx.attr.qemu
  machine = ctx.attr.machine
  cpu = ctx.attr.cpu
  target = ctx.attr.target
  # The command may only access files declared in inputs.
  ctx.actions.run_shell(
      arguments = [qemu, machine, cpu, target],
      command="$1 -M $2 -cpu $3 -nographic -monitor null -serial null -semihosting -kernel $4")

run_tests = rule(
    implementation=_impl,
    attrs = {"qemu" : attr.string(),
             "machine" : attr.string(),
             "cpu" : attr.string(),
             "target" : attr.string(),},
    executable = True
)

And my BUILD-File:

# BUILD
=======
load("//make:run_tests.bzl", "run_tests")

run_tests(
    name = "portos",
    qemu = "qemu-system-arm",
    machine = "realview-pbx-a9",
    cpu = "cortex-a9",
    target = ":test_portos.elf"
)

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

Upvotes: 1

Views: 4761

Answers (2)

ahumesky
ahumesky

Reputation: 5006

Skylark has support for writing test rules. Basically instead of setting executable = True, you would set test = True, and then your rule would create an executable that is the test, then you set ctx.outputs.executable to that executable. Then you can use the bazel test command with your rule.

See:

docs: https://docs.bazel.build/versions/master/skylark/rules.html#test-rules

example: https://github.com/bazelbuild/examples/tree/master/rules/test_rule

rule.test: https://docs.bazel.build/versions/master/skylark/lib/globals.html#rule.test

Upvotes: 1

rds
rds

Reputation: 26984

You are almost there: yes, you need outputs, otherwise bazel has nothing to do. For the rule output, you probably want the test logs or tests results.

Upvotes: 4

Related Questions