kythe.io@v0.0.68-0.20240422202219-7225dbc01741/tools/build_rules/extra_aspects/cxx/config.bzl (about) 1 # Copyright 2023 The Kythe Authors. All rights reserved. 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 15 """C++ Extractor configuration.""" 16 17 load( 18 "//tools/build_rules/extra_aspects:extra_actions.bzl", 19 "ProtoWriterInfo", 20 "normalize_action", 21 ) 22 23 def _has_assembly_source(action, inputs): 24 for file in inputs: 25 if action.argv and file.path not in action.argv: 26 # If we have a usable argv, check that the input is present 27 # to ignore non-source input files. 28 # Prior to Starlarkification, argv was not useful. 29 # When extracting via the test transition, `inputs` contains 30 # some toolchain-specific assembly files that aren't actually 31 # used by the compilation, which will trigger false-positives below. 32 continue 33 if file.extension in ("s", "S"): 34 return True 35 return False 36 37 def _as_cpp_compile_info(target, action): 38 action = normalize_action(action) 39 inputs = action.inputs.to_list() 40 41 # Entirely skip compilations containing assembly. 42 if _has_assembly_source(action, inputs): 43 return None 44 45 return struct(**{ 46 "owner": str(target.label), 47 "mnemonic": action.mnemonic, 48 "[blaze.CppCompileInfo.cpp_compile_info]": struct( 49 variable = [struct(name = k, value = v) for k, v in action.env.items()], 50 sources_and_headers = [f.path for f in inputs], 51 output_file = [f.path for f in action.outputs.to_list()][0], 52 ), 53 }) 54 55 def _write_cpp_compile_info(executable, target, ctx, action_id, action): 56 cpp_info = _as_cpp_compile_info(target, action) 57 if not cpp_info: 58 return None 59 txtpb = ctx.actions.declare_file(action_id + ".xa.textproto") 60 ctx.actions.write( 61 output = txtpb, 62 content = proto.encode_text(cpp_info), 63 ) 64 output = ctx.actions.declare_file(action_id + ".xa") 65 args = ctx.actions.args() 66 args.add(txtpb) 67 args.add(output) 68 args.add("--") 69 70 ctx.actions.run( 71 outputs = [output], 72 inputs = depset([txtpb]), 73 arguments = [args] + action.args, 74 executable = executable, 75 mnemonic = "KytheWriteCppCompileInfo", 76 # In theory, the exact environment and inputs can change during execution. 77 # In order to record this, we shadow the original action when writing the proto. 78 shadowed_action = action, 79 toolchain = None, 80 ) 81 return output 82 83 def _cpp_compile_info_impl(ctx): 84 executable = ctx.executable._write_extra_action 85 86 def write_extra_action(target, ctx, action_id, action): 87 return ( 88 _write_cpp_compile_info(executable, target, ctx, action_id, action), 89 depset(), 90 ) 91 92 return [ 93 ProtoWriterInfo( 94 write_extra_action = write_extra_action, 95 ), 96 ] 97 98 cpp_compile_info_proto_writer = rule( 99 implementation = _cpp_compile_info_impl, 100 attrs = { 101 "_write_extra_action": attr.label( 102 default = Label("//kythe/go/util/tools/write_extra_action"), 103 executable = True, 104 cfg = "exec", 105 ), 106 }, 107 provides = [ProtoWriterInfo], 108 )