1load("@bazel_skylib//lib:dicts.bzl", "dicts") 2load("@bazel_skylib//lib:sets.bzl", "sets") 3 4ActionArgsInfo = provider( 5 fields = { 6 "argv_map": "A dict with compile action arguments keyed by the target label", 7 }, 8) 9 10def _compile_action_argv_aspect_impl(target, ctx): 11 argv_map = {} 12 if ctx.rule.kind == "cc_library": 13 cpp_compile_commands_args = [] 14 for action in target.actions: 15 if action.mnemonic == "CppCompile": 16 cpp_compile_commands_args.extend(action.argv) 17 18 if len(cpp_compile_commands_args): 19 argv_map = dicts.add( 20 argv_map, 21 { 22 target.label.name: cpp_compile_commands_args, 23 }, 24 ) 25 elif ctx.rule.kind in ctx.attr._attr_aspect_dict.keys(): 26 attrs = ctx.attr._attr_aspect_dict.get(ctx.rule.kind, []) 27 for attr_name in attrs: 28 for value in getattr(ctx.rule.attr, attr_name): 29 argv_map = dicts.add( 30 argv_map, 31 value[ActionArgsInfo].argv_map, 32 ) 33 return ActionArgsInfo( 34 argv_map = argv_map, 35 ) 36 37def _get_attr_aspects_list(attr_aspects_dict): 38 return sets.to_list( 39 sets.make( 40 [attr for rule in attr_aspects_dict.values() for attr in rule], 41 ), 42 ) 43 44# The aspects generated by this function are used to examine compile actions 45# from cc_library targets generated by our macros for the purpose of assessing 46# the results of transitions. Checking the targets directly using their names 47# gives info from before the transition is applied. 48# attr_aspects should be a dict where the keys are the names of rules and the 49# values are lists of attrs that should be traversed by the aspect looking for 50# cc_library targets. 51def compile_action_argv_aspect_generator(attr_aspects): 52 return aspect( 53 implementation = _compile_action_argv_aspect_impl, 54 attr_aspects = _get_attr_aspects_list(attr_aspects), 55 attrs = { 56 "_attr_aspect_dict": attr.string_list_dict(default = attr_aspects), 57 }, 58 ) 59