Is is possible to use aspects to add an additional validation stage into rules_cc bazel build?

437 views
Skip to first unread message

carpen...@gmail.com

unread,
Jan 27, 2022, 6:28:23 AM1/27/22
to bazel-discuss
I am reading up on validation actions which seems to be new in Bazel 5.0 https://docs.bazel.build/versions/main/skylark/rules.html#validation-actions

I wonderer if its possible to use Validation Actions to perform things like clang-format validation on all my rules_cc targets? It would seem like a natural fit. 

However what I would like to do is add in an additional action to the compilation stages to perform a validation? 

I have seen clang-format with using aspects, this however needs an explicit bazel invocation in addition to the regular bazel build. Instead I want to inject an additional validation stage into the rules_cc pipeline.

Can I use aspects to add to a build, instead of doing an alternative action? It may not be possible, until rules_cc is ported to Starlark.

Thanks

Alex Humesky

unread,
Feb 1, 2022, 8:45:57 PM2/1/22
to carpen...@gmail.com, bazel-discuss
Hi,
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 $*

Then usage:

$ bazel build main
INFO: Analyzed target //:main (37 packages loaded, 281 targets configured).
INFO: Found 1 target...
INFO: From Action lib2.validation:
validating lib2.c
INFO: From Action lib.validation:
validating lib.c
INFO: From Action main.validation:
validating main.c
Aspect //:defs.bzl%validation_aspect of //:main up-to-date (nothing to build)
INFO: Elapsed time: 0.529s, Critical Path: 0.07s
INFO: 14 processes: 7 internal, 7 linux-sandbox.
INFO: Build completed successfully, 14 total actions




--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/aa88ae0a-874b-4649-b499-5b7e5825a151n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages