Reputation: 2868
I want to run unit tests on qemu. I have created a custom rule, that invokes qemu with arguments specified in the rule. One of those arguments is the elf file (rule attribute "target") which is used by qemu as kernel.
When I invoke my custom rule with the following command, the elf file ("kernel.elf") does not get compiled:
bazel build //test:custom_rule
This happens even though bazel query 'deps(//test:custom_rule)'
lists the target ":kernel.elf" as a dependency.
Furthermore I have another problem with the custom rule. When I manually build the ":kernel.elf" and call the custom rule afterwards qemu tells me, that it could not load the kernel file. Manually invoking the qemu command in the shell does work, so I guess the problem does not lie within the "kernel.elf" file.
Does anybody have an answer to my problems?
Thanks in advance!
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="$1 -M $2 -cpu $3 -nographic -monitor null
-serial null -semihosting -kernel $4 > %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"]
)
Upvotes: 2
Views: 1084
Reputation: 5016
The issue is probably that the inputs need to specified to the action, see https://docs.bazel.build/versions/master/skylark/lib/actions.html#run_shell.inputs
You'll also probably need to make qemu a label and make that an input to the action as well (And machine too, if that's a file that qemu needs)
E.g. something like:
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="$1 -M $2 -cpu $3 -nographic -monitor null
-serial null -semihosting -kernel $4 > %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"}
)
Upvotes: 5