Not sure what exactly you are after, but essentially, you can write a custom rule you pass cc_* target as a source into and try to pick its actions apart only getting outputs of the ones you are interest in, e.g.:
def _impl(ctx):
outs = []
for src in ctx.attr.srcs:
if hasattr(src, "actions"):
for action in src.actions:
if action.mnemonic == "CppCompile":
outs.append(action.outputs)
return DefaultInfo(files = depset(transitive = outs))
just_compile = rule(
_impl,
attrs = {
"srcs": attr.label_list(mandatory = True),
},
)
If I then have the following BUILD file:
load("//:just_compile.bzl", "just_compile")
just_compile(
name = "compile_hello",
srcs = [":hello"],
)
cc_binary(
name = "hello",
srcs = ["hello.cpp"],
)
And you run (you can add -s to watch):
bazel build compile_hello
You will get just the compilation step executed (because we did not actually request hello target and there is nothing else needing linking in the tree as requested) and results it produced:
bazel-bin/
bazel-bin/_objs
bazel-bin/_objs/hello
bazel-bin/_objs/hello/hello.pic.d
bazel-bin/_objs/hello/hello.pic.o
Linking mnemonic is CppLink.
So, yes, you can attach yourself to specific actions. And for the sake of debate, this would be at least one option I am aware to do that. But again, I am not entirely sure what exactly are you actually after, what problem are you trying to solve.