It's possible to do this. It's basically the same as in the documentation, but because the validation output group isn't automatically propagated from aspects, you'll have to do that manually. (feel free to file a bug on github about that)
.bazelrc:build --aspects=//:defs.bzl%validation_aspect
BUILD:cc_binary(
name = "main",
srcs = ["main.c"],
deps = [":lib"],
)
cc_library(
name = "lib",
srcs = ["lib.c"],
hdrs = ["lib.h"],
deps = [":lib2"],
)
cc_library(
name = "lib2",
srcs = ["lib2.c"],
hdrs = ["lib2.h"],
)
sh_binary(
name = "validator",
srcs = ["validator.sh"],
)
defs.bzl:def _validation_aspect_impl(target, ctx):
validation_output = ctx.actions.declare_file(ctx.rule.attr.name + ".validation")
args = ctx.actions.args()
args.add(validation_output)
inputs = []
for s in ctx.rule.attr.srcs:
for t in s.files.to_list():
inputs.append(t)
args.add(t.path)
ctx.actions.run(
inputs = inputs,
outputs = [validation_output],
arguments = [args],
executable = ctx.executable._validation_tool,
)
validation_outputs_in_deps = []
for d in ctx.rule.attr.deps:
validation_outputs_in_deps.append(d[OutputGroupInfo]._validation)
return [
OutputGroupInfo(
_validation = depset(
[validation_output],
transitive = validation_outputs_in_deps)),
]
validation_aspect = aspect(
implementation = _validation_aspect_impl,
attr_aspects = ['deps'],
attrs = {
"_validation_tool": attr.label(default = Label("//:validator"), executable = True, cfg = "exec"),
},
)
lib.c:#include "lib.h"
#include "lib2.h"
int lib() {
return 35 + lib2();
}
lib.h:int lib();
lib2.c:#include "lib2.h"
int lib2() {
return 7;
}
lib2.h:int lib2();
main.c:#include "stdio.h"
#include "lib.h"
int main() {
printf("hello world %d\n", lib());
}
validator.sh:touch "$1"
shift
echo validating $*