1*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:dicts.bzl", "dicts") 2*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:sets.bzl", "sets") 3*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") 4*7594170eSAndroid Build Coastguard Worker 5*7594170eSAndroid Build Coastguard WorkerActionArgsInfo = provider( 6*7594170eSAndroid Build Coastguard Worker fields = { 7*7594170eSAndroid Build Coastguard Worker "argv_map": "A dict with compile action arguments keyed by the target label", 8*7594170eSAndroid Build Coastguard Worker }, 9*7594170eSAndroid Build Coastguard Worker) 10*7594170eSAndroid Build Coastguard Worker 11*7594170eSAndroid Build Coastguard Workerdef _action_argv_aspect_impl(target, ctx): 12*7594170eSAndroid Build Coastguard Worker argv_map = {} 13*7594170eSAndroid Build Coastguard Worker if ctx.rule.kind == ctx.attr._target_rule: 14*7594170eSAndroid Build Coastguard Worker _cpp_commands_args = [] 15*7594170eSAndroid Build Coastguard Worker for action in target.actions: 16*7594170eSAndroid Build Coastguard Worker if action.mnemonic == ctx.attr._action: 17*7594170eSAndroid Build Coastguard Worker _cpp_commands_args.extend(action.argv) 18*7594170eSAndroid Build Coastguard Worker 19*7594170eSAndroid Build Coastguard Worker if len(_cpp_commands_args): 20*7594170eSAndroid Build Coastguard Worker argv_map = dicts.add( 21*7594170eSAndroid Build Coastguard Worker argv_map, 22*7594170eSAndroid Build Coastguard Worker { 23*7594170eSAndroid Build Coastguard Worker target.label.name: _cpp_commands_args, 24*7594170eSAndroid Build Coastguard Worker }, 25*7594170eSAndroid Build Coastguard Worker ) 26*7594170eSAndroid Build Coastguard Worker elif ctx.rule.kind in ctx.attr._attr_aspect_dict.keys(): 27*7594170eSAndroid Build Coastguard Worker attrs = ctx.attr._attr_aspect_dict.get(ctx.rule.kind, []) 28*7594170eSAndroid Build Coastguard Worker for attr_name in attrs: 29*7594170eSAndroid Build Coastguard Worker value = getattr(ctx.rule.attr, attr_name) 30*7594170eSAndroid Build Coastguard Worker vlist = value if type(value) == type([]) else [value] 31*7594170eSAndroid Build Coastguard Worker for value in vlist: 32*7594170eSAndroid Build Coastguard Worker argv_map = dicts.add( 33*7594170eSAndroid Build Coastguard Worker argv_map, 34*7594170eSAndroid Build Coastguard Worker value[ActionArgsInfo].argv_map, 35*7594170eSAndroid Build Coastguard Worker ) 36*7594170eSAndroid Build Coastguard Worker return ActionArgsInfo( 37*7594170eSAndroid Build Coastguard Worker argv_map = argv_map, 38*7594170eSAndroid Build Coastguard Worker ) 39*7594170eSAndroid Build Coastguard Worker 40*7594170eSAndroid Build Coastguard Workerdef _get_attr_aspects_list(attr_aspects_dict): 41*7594170eSAndroid Build Coastguard Worker return sets.to_list( 42*7594170eSAndroid Build Coastguard Worker sets.make( 43*7594170eSAndroid Build Coastguard Worker [attr for rule in attr_aspects_dict.values() for attr in rule], 44*7594170eSAndroid Build Coastguard Worker ), 45*7594170eSAndroid Build Coastguard Worker ) 46*7594170eSAndroid Build Coastguard Worker 47*7594170eSAndroid Build Coastguard Worker# The aspects generated by this function are used to examine compile actions 48*7594170eSAndroid Build Coastguard Worker# from cc_library targets generated by our macros for the purpose of assessing 49*7594170eSAndroid Build Coastguard Worker# the results of transitions. Checking the targets directly using their names 50*7594170eSAndroid Build Coastguard Worker# gives info from before the transition is applied. 51*7594170eSAndroid Build Coastguard Worker# attr_aspects should be a dict where the keys are the names of rules and the 52*7594170eSAndroid Build Coastguard Worker# values are lists of attrs that should be traversed by the aspect looking for 53*7594170eSAndroid Build Coastguard Worker# cc_library targets. 54*7594170eSAndroid Build Coastguard Workerdef compile_action_argv_aspect_generator(attr_aspects): 55*7594170eSAndroid Build Coastguard Worker return aspect( 56*7594170eSAndroid Build Coastguard Worker implementation = _action_argv_aspect_impl, 57*7594170eSAndroid Build Coastguard Worker attr_aspects = _get_attr_aspects_list(attr_aspects), 58*7594170eSAndroid Build Coastguard Worker attrs = { 59*7594170eSAndroid Build Coastguard Worker "_attr_aspect_dict": attr.string_list_dict(default = attr_aspects), 60*7594170eSAndroid Build Coastguard Worker "_action": attr.string(default = "CppCompile"), 61*7594170eSAndroid Build Coastguard Worker "_target_rule": attr.string(default = "cc_library"), 62*7594170eSAndroid Build Coastguard Worker }, 63*7594170eSAndroid Build Coastguard Worker ) 64*7594170eSAndroid Build Coastguard Worker 65*7594170eSAndroid Build Coastguard Workerdef link_action_argv_aspect_generator(attr_aspects, target_rule): 66*7594170eSAndroid Build Coastguard Worker return aspect( 67*7594170eSAndroid Build Coastguard Worker implementation = _action_argv_aspect_impl, 68*7594170eSAndroid Build Coastguard Worker attr_aspects = _get_attr_aspects_list(attr_aspects), 69*7594170eSAndroid Build Coastguard Worker attrs = { 70*7594170eSAndroid Build Coastguard Worker "_attr_aspect_dict": attr.string_list_dict(default = attr_aspects), 71*7594170eSAndroid Build Coastguard Worker "_action": attr.string(default = "CppLink"), 72*7594170eSAndroid Build Coastguard Worker "_target_rule": attr.string(default = target_rule), 73*7594170eSAndroid Build Coastguard Worker }, 74*7594170eSAndroid Build Coastguard Worker ) 75*7594170eSAndroid Build Coastguard Worker 76*7594170eSAndroid Build Coastguard Workerdef transition_deps_test_impl(ctx): 77*7594170eSAndroid Build Coastguard Worker env = analysistest.begin(ctx) 78*7594170eSAndroid Build Coastguard Worker target_under_test = analysistest.target_under_test(env) 79*7594170eSAndroid Build Coastguard Worker argv_map = target_under_test[ActionArgsInfo].argv_map 80*7594170eSAndroid Build Coastguard Worker 81*7594170eSAndroid Build Coastguard Worker for target in ctx.attr.targets_with_flag: 82*7594170eSAndroid Build Coastguard Worker asserts.true( 83*7594170eSAndroid Build Coastguard Worker env, 84*7594170eSAndroid Build Coastguard Worker target in argv_map, 85*7594170eSAndroid Build Coastguard Worker "can't find {} in argv map".format(target), 86*7594170eSAndroid Build Coastguard Worker ) 87*7594170eSAndroid Build Coastguard Worker if target in argv_map: 88*7594170eSAndroid Build Coastguard Worker argv = argv_map[target] 89*7594170eSAndroid Build Coastguard Worker for flag in ctx.attr.flags: 90*7594170eSAndroid Build Coastguard Worker asserts.true( 91*7594170eSAndroid Build Coastguard Worker env, 92*7594170eSAndroid Build Coastguard Worker flag in argv, 93*7594170eSAndroid Build Coastguard Worker "Action of {} didn't have {} flag but it was expected".format( 94*7594170eSAndroid Build Coastguard Worker target, 95*7594170eSAndroid Build Coastguard Worker flag, 96*7594170eSAndroid Build Coastguard Worker ), 97*7594170eSAndroid Build Coastguard Worker ) 98*7594170eSAndroid Build Coastguard Worker for target in ctx.attr.targets_without_flag: 99*7594170eSAndroid Build Coastguard Worker asserts.true( 100*7594170eSAndroid Build Coastguard Worker env, 101*7594170eSAndroid Build Coastguard Worker target in argv_map, 102*7594170eSAndroid Build Coastguard Worker "can't find {} in argv map".format(target), 103*7594170eSAndroid Build Coastguard Worker ) 104*7594170eSAndroid Build Coastguard Worker if target in argv_map: 105*7594170eSAndroid Build Coastguard Worker argv = argv_map[target] 106*7594170eSAndroid Build Coastguard Worker for flag in ctx.attr.flags: 107*7594170eSAndroid Build Coastguard Worker asserts.true( 108*7594170eSAndroid Build Coastguard Worker env, 109*7594170eSAndroid Build Coastguard Worker flag not in argv, 110*7594170eSAndroid Build Coastguard Worker "Action of {} had {} flag but it wasn't expected".format( 111*7594170eSAndroid Build Coastguard Worker target, 112*7594170eSAndroid Build Coastguard Worker flag, 113*7594170eSAndroid Build Coastguard Worker ), 114*7594170eSAndroid Build Coastguard Worker ) 115*7594170eSAndroid Build Coastguard Worker return analysistest.end(env) 116*7594170eSAndroid Build Coastguard Worker 117*7594170eSAndroid Build Coastguard Workertransition_deps_test_attrs = { 118*7594170eSAndroid Build Coastguard Worker "targets_with_flag": attr.string_list(), 119*7594170eSAndroid Build Coastguard Worker "targets_without_flag": attr.string_list(), 120*7594170eSAndroid Build Coastguard Worker "flags": attr.string_list(), 121*7594170eSAndroid Build Coastguard Worker} 122