1# Copyright (C) 2021 The Android Open Source Project 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 15load("@bazel_skylib//lib:paths.bzl", "paths") 16load("//build/bazel/rules:proto_file_utils.bzl", "proto_file_utils") 17load(":cc_library_common.bzl", "create_ccinfo_for_includes") 18load(":cc_library_static.bzl", "cc_library_static") 19 20_SOURCES_KEY = "sources" 21_HEADERS_KEY = "headers" 22PROTO_GEN_NAME_SUFFIX = "_proto_gen" 23 24def _cc_proto_sources_gen_rule_impl(ctx): 25 out_flags = [] 26 plugin_executable = None 27 out_arg = None 28 if ctx.attr.plugin: 29 plugin_executable = ctx.executable.plugin 30 else: 31 out_arg = "--cpp_out" 32 if ctx.attr.out_format: 33 out_flags.append(ctx.attr.out_format) 34 35 srcs = [] 36 hdrs = [] 37 includes = [] 38 proto_infos = [] 39 40 for dep in ctx.attr.deps: 41 proto_info = dep[ProtoInfo] 42 proto_infos.append(proto_info) 43 if proto_info.proto_source_root == ".": 44 includes.append(paths.join(ctx.label.name, ctx.label.package)) 45 includes.append(ctx.label.name) 46 47 outs = _generate_cc_proto_action( 48 proto_infos = proto_infos, 49 protoc = ctx.executable._protoc, 50 ctx = ctx, 51 is_cc = True, 52 out_flags = out_flags, 53 plugin_executable = plugin_executable, 54 out_arg = out_arg, 55 ) 56 srcs.extend(outs[_SOURCES_KEY]) 57 hdrs.extend(outs[_HEADERS_KEY]) 58 59 return [ 60 DefaultInfo(files = depset(direct = srcs + hdrs)), 61 create_ccinfo_for_includes(ctx, hdrs = hdrs, includes = includes), 62 ] 63 64_cc_proto_sources_gen = rule( 65 implementation = _cc_proto_sources_gen_rule_impl, 66 attrs = { 67 "deps": attr.label_list( 68 providers = [ProtoInfo], 69 doc = """ 70proto_library or any other target exposing ProtoInfo provider with *.proto files 71""", 72 mandatory = True, 73 ), 74 "_protoc": attr.label( 75 default = Label("//external/protobuf:aprotoc"), 76 executable = True, 77 cfg = "exec", 78 ), 79 "plugin": attr.label( 80 executable = True, 81 cfg = "exec", 82 ), 83 "out_format": attr.string( 84 doc = """ 85Optional argument specifying the out format, e.g. lite. 86If not provided, defaults to full protos. 87""", 88 ), 89 }, 90 toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], 91 provides = [CcInfo], 92) 93 94def _src_extension(is_cc): 95 if is_cc: 96 return "cc" 97 return "c" 98 99def _generate_cc_proto_action( 100 proto_infos, 101 protoc, 102 ctx, 103 plugin_executable, 104 out_arg, 105 out_flags, 106 is_cc): 107 type_dictionary = { 108 _SOURCES_KEY: ".pb." + _src_extension(is_cc), 109 _HEADERS_KEY: ".pb.h", 110 } 111 return proto_file_utils.generate_proto_action( 112 proto_infos, 113 protoc, 114 ctx, 115 type_dictionary, 116 out_flags, 117 plugin_executable = plugin_executable, 118 out_arg = out_arg, 119 mnemonic = "CcProtoGen", 120 ) 121 122def _cc_proto_library( 123 name, 124 deps = [], 125 plugin = None, 126 tags = [], 127 target_compatible_with = [], 128 out_format = None, 129 proto_dep = None, 130 **kwargs): 131 proto_lib_name = name + PROTO_GEN_NAME_SUFFIX 132 133 _cc_proto_sources_gen( 134 name = proto_lib_name, 135 deps = deps, 136 plugin = plugin, 137 out_format = out_format, 138 tags = ["manual"], 139 ) 140 141 cc_library_static( 142 name = name, 143 srcs = [":" + proto_lib_name], 144 deps = [ 145 proto_lib_name, 146 proto_dep, 147 ], 148 local_includes = ["."], 149 tags = tags, 150 target_compatible_with = target_compatible_with, 151 **kwargs 152 ) 153 154def cc_lite_proto_library( 155 name, 156 deps = [], 157 plugin = None, 158 tags = [], 159 target_compatible_with = [], 160 **kwargs): 161 _cc_proto_library( 162 name, 163 deps = deps, 164 plugin = plugin, 165 tags = tags, 166 target_compatible_with = target_compatible_with, 167 out_format = "lite", 168 proto_dep = "//external/protobuf:libprotobuf-cpp-lite", 169 **kwargs 170 ) 171 172def cc_proto_library( 173 name, 174 deps = [], 175 plugin = None, 176 tags = [], 177 target_compatible_with = [], 178 **kwargs): 179 _cc_proto_library( 180 name, 181 deps = deps, 182 plugin = plugin, 183 tags = tags, 184 target_compatible_with = target_compatible_with, 185 proto_dep = "//external/protobuf:libprotobuf-cpp-full", 186 **kwargs 187 ) 188