Skip to content

Instantly share code, notes, and snippets.

@rrbutani
Created October 6, 2021 17:16
Show Gist options
  • Save rrbutani/695281a21626d7aba18c27f431a94e78 to your computer and use it in GitHub Desktop.
Save rrbutani/695281a21626d7aba18c27f431a94e78 to your computer and use it in GitHub Desktop.
bazel playground: extract actions from
Probably not a good fit for `compdb` stuff (we'd need to aggregate the dumped args... which is actually literally what we already do.). Nevermind. This'd be perfect for compdb stuff.
Regardless – this kind of thing is useful as a way to compare actions generated by (for example) `rules_cc` and a non-native implementation.
nothing here is really of note if you've seen analysis tests using `skylib`; the only thing that might be interesting (or at least, was surprising to me) was that your rule doesn't need to be an `analysis_test` to poke at the actions generated for a target by another rule (even if that other rule isn't `_skylark_testable`)
this is what the commented out bits are; the first thing is just a regular use of `skylib`'s `analysistest` but this doesn't let us actually poke at the `Args` used by actions (since Args are opaque at analysis time). `analysis_test`s cannot declare actions so we ditch the skylib `analysistest` glue and write our own aspect – and we can still access the actions generated by the `cc_library`
I _think_ this, like the `bazel-compilation-database` approach of using the `cc_common` utilities to reconstruct the commandline, will work even if the underlying `cc_library` target is broken (i.e. would fail to build).
load("@rules_cc//cc:defs.bzl", "cc_library")
# load(":test.bzl", action_dump = "action_dump_test")
load(":test.bzl", action_dump = "action_dump")
cc_library(
name = "foo",
srcs = [":test.cc"],
)
cc_library(
name = "lib",
srcs = ["test.cc"],
deps = ["foo"],
)
action_dump(
name = "dump",
target_under_test = ":lib",
)
load("@bazel_skylib//lib:unittest.bzl", ana = "analysistest")
load("@bazel_skylib//lib:types.bzl", "types")
"""
def _action_dump_impl(ctx):
env = ana.begin(ctx)
tut = ana.target_under_test(env)
print(tut)
args = []
actions = ana.target_actions(env)
print(actions)
for a in actions:
print("\n\n")
# print(a)
# print(a.args)
# print(a.argv)
# print(a.content)
# print(a.env)
# print(a.inputs)
# print(a.outputs)
# print(a.substitutions)
# print("\n\n")
if a.args and types.is_list(a.args) and len(a.args) == 1 and type(a.args[0]) == "Args":
args.append((a.mnemonic.split(" ")[0].lower(), a.args[0]))
for n, args in args:
ctx.actions.write(ctx.actions.declare_file("dump-{}.out".format(n)), args)
return ana.end(env)
action_dump_test = ana.make(_action_dump_impl)
"""
def _action_dump_impl(ctx):
tut = ctx.attr.target_under_test
print(tut)
args = []
actions = tut[ActionInfo].actions
print(actions)
for a in actions:
print("\n\n")
# print(a)
# print(a.args)
# print(a.argv)
# print(a.content)
# print(a.env)
# print(a.inputs)
# print(a.outputs)
# print(a.substitutions)
# print("\n\n")
if a.args and types.is_list(a.args) and len(a.args) == 1 and type(a.args[0]) == "Args":
args.append((a.mnemonic.replace(" ", "_").lower(), a.args[0]))
action_map = {}
files = []
for n, args in args:
count = action_map.get(n, 0)
action_map[n] = count + 1
file = "dump-{}-{}.out".format(n, count)
print(file)
file = ctx.actions.declare_file(file)
files.append(file)
ctx.actions.write(file, args)
return DefaultInfo(
files = depset(files),
)
ActionInfo = provider(
fields = ["actions"],
)
def _action_grabbing_aspect_impl(target, _ctx):
return ActionInfo(
actions = target.actions,
)
action_grabbing_aspect = aspect(
attr_aspects = [],
implementation = _action_grabbing_aspect_impl,
)
action_dump = rule(
implementation = _action_dump_impl,
attrs = {
"target_under_test": attr.label(
aspects = [action_grabbing_aspect],
mandatory = True,
)
},
# test = True,
# analysis_test = True,
)
int foo() { return 4; }
workspace(name = "rules_cc_analysis_test")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "bazel_skylib",
urls = [
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz",
],
sha256 = "c6966ec828da198c5d9adbaa94c05e3a1c7f21bd012a0b29ba8ddbccb2c93b0d",
)
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment