load("@bazel_skylib//lib:dicts.bzl", "dicts") load("@bazel_skylib//lib:sets.bzl", "sets") ActionArgsInfo = provider( fields = { "argv_map": "A dict with compile action arguments keyed by the target label", }, ) def _compile_action_argv_aspect_impl(target, ctx): argv_map = {} if ctx.rule.kind == "cc_library": cpp_compile_commands_args = [] for action in target.actions: if action.mnemonic == "CppCompile": cpp_compile_commands_args.extend(action.argv) if len(cpp_compile_commands_args): argv_map = dicts.add( argv_map, { target.label.name: cpp_compile_commands_args, }, ) elif ctx.rule.kind in ctx.attr._attr_aspect_dict.keys(): attrs = ctx.attr._attr_aspect_dict.get(ctx.rule.kind, []) for attr_name in attrs: for value in getattr(ctx.rule.attr, attr_name): argv_map = dicts.add( argv_map, value[ActionArgsInfo].argv_map, ) return ActionArgsInfo( argv_map = argv_map, ) def _get_attr_aspects_list(attr_aspects_dict): return sets.to_list( sets.make( [attr for rule in attr_aspects_dict.values() for attr in rule], ), ) # The aspects generated by this function are used to examine compile actions # from cc_library targets generated by our macros for the purpose of assessing # the results of transitions. Checking the targets directly using their names # gives info from before the transition is applied. # attr_aspects should be a dict where the keys are the names of rules and the # values are lists of attrs that should be traversed by the aspect looking for # cc_library targets. def compile_action_argv_aspect_generator(attr_aspects): return aspect( implementation = _compile_action_argv_aspect_impl, attr_aspects = _get_attr_aspects_list(attr_aspects), attrs = { "_attr_aspect_dict": attr.string_list_dict(default = attr_aspects), }, )