• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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