blob: 1a23a97ad1bff0aacb071a6332c06c0c611b8b67 [file] [log] [blame]
Primiano Tuccifd484232017-10-25 00:15:39 +01001# Copyright (C) 2017 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
Joel Fernandes80fc3cd2020-04-01 18:02:57 -040015import("../perfetto.gni")
16
Primiano Tucci42433ab2020-11-30 18:42:01 +010017if (host_os == "win") {
18 _host_executable_suffix = ".exe"
19} else {
20 _host_executable_suffix = ""
21}
22
Primiano Tuccifd484232017-10-25 00:15:39 +010023template("proto_library") {
24 assert(defined(invoker.sources))
25 proto_sources = invoker.sources
Primiano Tuccifd484232017-10-25 00:15:39 +010026
Primiano Tucci2ee254a2017-11-15 00:38:48 +000027 # All the proto imports should be relative to the project root.
28 proto_in_dir = "//"
29 if (defined(invoker.proto_in_dir)) {
30 proto_in_dir = invoker.proto_in_dir
Primiano Tuccifd484232017-10-25 00:15:39 +010031 }
Primiano Tucci782374f2017-11-27 16:25:20 +000032 assert(defined(invoker.proto_out_dir),
33 "proto_out_dir must be explicitly defined")
34 proto_out_dir = invoker.proto_out_dir
Oystein Eftevaag51e06e52018-01-18 11:28:49 -080035
36 # We don't support generate_python in the standalone build, but still must
37 # check that the caller sets this to false. This is because when building in
38 # the chromium tree, chromium's proto_library.gni in chrome (!= this) defaults
39 # generate_python = true.
40 assert(defined(invoker.generate_python) && !invoker.generate_python)
Primiano Tuccifd484232017-10-25 00:15:39 +010041
Lalit Maganti3b09a3f2020-09-14 13:28:44 +010042 import_dirs = []
43 if (defined(invoker.import_dirs)) {
44 import_dirs = invoker.import_dirs
45 }
46
Hector Dearman37e05532017-11-14 15:35:22 +000047 # If false will not generate the default .pb.{cc,h} files. Used for custom
48 # codegen plugins.
49 generate_cc = true
50 if (defined(invoker.generate_cc)) {
51 generate_cc = invoker.generate_cc
52 }
53
Florian Mayerab55e3d2018-04-19 11:56:01 +010054 generate_descriptor = ""
55 if (defined(invoker.generate_descriptor)) {
56 generate_descriptor = invoker.generate_descriptor
Andrew Shulaeve6c4a5c2021-01-29 11:07:39 +000057
58 # Include imports to descriptor by default, but use exclude_imports to omit
59 # them if needed.
60 if (defined(invoker.exclude_imports)) {
61 exclude_imports = invoker.exclude_imports
62 } else {
63 exclude_imports = false
64 }
Florian Mayerab55e3d2018-04-19 11:56:01 +010065 }
66
Primiano Tuccifd484232017-10-25 00:15:39 +010067 if (defined(invoker.generator_plugin_label)) {
68 plugin_host_label = invoker.generator_plugin_label + "($host_toolchain)"
Primiano Tucci42433ab2020-11-30 18:42:01 +010069 plugin_path =
70 get_label_info(plugin_host_label, "root_out_dir") + "/" +
71 get_label_info(plugin_host_label, "name") + _host_executable_suffix
Primiano Tuccifd484232017-10-25 00:15:39 +010072 generate_with_plugin = true
73 } else if (defined(invoker.generator_plugin_script)) {
74 plugin_path = invoker.generator_plugin_script
75 generate_with_plugin = true
76 } else {
77 generate_with_plugin = false
78 }
79
80 if (generate_with_plugin) {
81 if (defined(invoker.generator_plugin_suffix)) {
82 generator_plugin_suffixes = [
83 "${invoker.generator_plugin_suffix}.h",
84 "${invoker.generator_plugin_suffix}.cc",
85 ]
86 } else {
87 generator_plugin_suffixes = invoker.generator_plugin_suffixes
88 }
89 }
90
Lalit Maganti45d8eb82020-09-12 16:32:18 +010091 out_dir = "$root_gen_dir/" + proto_out_dir
92 rel_out_dir = rebase_path(out_dir, root_build_dir)
Primiano Tuccifd484232017-10-25 00:15:39 +010093
Lalit Magantifc7b0582019-05-22 23:52:08 +010094 # Prevent unused errors when generating descriptor only.
95 if (generate_descriptor != "") {
Lalit Maganti45d8eb82020-09-12 16:32:18 +010096 not_needed([ "rel_out_dir" ])
Lalit Magantifc7b0582019-05-22 23:52:08 +010097 }
98
Primiano Tuccifd484232017-10-25 00:15:39 +010099 protos = rebase_path(proto_sources, proto_in_dir)
100 protogens = []
101
Florian Mayerab55e3d2018-04-19 11:56:01 +0100102 if (generate_descriptor != "") {
Lalit Maganti45d8eb82020-09-12 16:32:18 +0100103 protogens += [ "$out_dir/${generate_descriptor}" ]
Florian Mayerab55e3d2018-04-19 11:56:01 +0100104 }
105
Primiano Tuccifd484232017-10-25 00:15:39 +0100106 foreach(proto, protos) {
107 proto_dir = get_path_info(proto, "dir")
108 proto_name = get_path_info(proto, "name")
109 proto_path = proto_dir + "/" + proto_name
110
Lalit Magantifc7b0582019-05-22 23:52:08 +0100111 # Prevent unused errors when generating descriptor only.
112 if (generate_descriptor != "") {
113 not_needed([ "proto_path" ])
114 }
115
Hector Dearman37e05532017-11-14 15:35:22 +0000116 if (generate_cc) {
117 protogens += [
Lalit Maganti45d8eb82020-09-12 16:32:18 +0100118 "$out_dir/$proto_path.pb.h",
119 "$out_dir/$proto_path.pb.cc",
Hector Dearman37e05532017-11-14 15:35:22 +0000120 ]
121 }
Primiano Tuccifd484232017-10-25 00:15:39 +0100122 if (generate_with_plugin) {
123 foreach(suffix, generator_plugin_suffixes) {
Lalit Maganti45d8eb82020-09-12 16:32:18 +0100124 protogens += [ "$out_dir/${proto_path}${suffix}" ]
Primiano Tuccifd484232017-10-25 00:15:39 +0100125 }
126 }
127 }
128
129 config_name = "${target_name}_config"
Lalit Magantif9799c62019-05-28 20:01:08 +0100130 if (generate_descriptor == "") {
131 action_name = "${target_name}_gen"
132 source_set_name = target_name
133 } else {
134 action_name = target_name
135 }
Primiano Tuccifd484232017-10-25 00:15:39 +0100136
137 config(config_name) {
Lalit Maganti45d8eb82020-09-12 16:32:18 +0100138 include_dirs = [ out_dir ]
Primiano Tuccifd484232017-10-25 00:15:39 +0100139 }
140
141 # The XXX_gen action that generates the .pb.{cc,h} files.
142 action(action_name) {
Lalit Magantif9799c62019-05-28 20:01:08 +0100143 if (generate_descriptor == "") {
144 visibility = [ ":$source_set_name" ]
145 }
Primiano Tuccifd484232017-10-25 00:15:39 +0100146 sources = proto_sources
147 outputs = get_path_info(protogens, "abspath")
148
Joel Fernandes80fc3cd2020-04-01 18:02:57 -0400149 if (perfetto_use_system_protobuf) {
Primiano Tucci42433ab2020-11-30 18:42:01 +0100150 protoc_rebased_path = "protoc" + _host_executable_suffix # from PATH
Joel Fernandes80fc3cd2020-04-01 18:02:57 -0400151 } else {
152 protoc_label = "//gn:protoc($host_toolchain)"
Primiano Tucci42433ab2020-11-30 18:42:01 +0100153 protoc_path = get_label_info(protoc_label, "root_out_dir") + "/protoc" +
154 _host_executable_suffix
Joel Fernandes80fc3cd2020-04-01 18:02:57 -0400155 protoc_rebased_path = "./" + rebase_path(protoc_path, root_build_dir)
156 }
Primiano Tucci42433ab2020-11-30 18:42:01 +0100157 script = "//gn/standalone/protoc.py"
Primiano Tuccifd484232017-10-25 00:15:39 +0100158 args = [
159 # Path should be rebased because |root_build_dir| for current toolchain
160 # may be different from |root_out_dir| of protoc built on host toolchain.
Joel Fernandes80fc3cd2020-04-01 18:02:57 -0400161 protoc_rebased_path,
Primiano Tuccifd484232017-10-25 00:15:39 +0100162 "--proto_path",
163 rebase_path(proto_in_dir, root_build_dir),
Primiano Tuccifd484232017-10-25 00:15:39 +0100164 ]
Lalit Maganti3b09a3f2020-09-14 13:28:44 +0100165
166 foreach(path, import_dirs) {
167 args += [
168 "--proto_path",
169 rebase_path(path, root_build_dir),
170 ]
171 }
172
Daniele Di Proiettof6f6e782024-04-29 14:21:48 +0000173 metadata = {
174 proto_import_dirs = import_dirs
175 }
176
Hector Dearman37e05532017-11-14 15:35:22 +0000177 if (generate_cc) {
Primiano Tucci7b6a7882020-01-20 22:34:31 +0000178 cc_generator_options_ = ""
179 if (defined(invoker.cc_generator_options)) {
180 cc_generator_options_ = invoker.cc_generator_options
181 }
Hector Dearman37e05532017-11-14 15:35:22 +0000182 args += [
183 "--cpp_out",
Lalit Maganti45d8eb82020-09-12 16:32:18 +0100184 cc_generator_options_ + rel_out_dir,
Hector Dearman37e05532017-11-14 15:35:22 +0000185 ]
186 }
Florian Mayerab55e3d2018-04-19 11:56:01 +0100187 if (generate_descriptor != "") {
Lalit Maganti45d8eb82020-09-12 16:32:18 +0100188 depfile = "$root_gen_dir/$generate_descriptor.d"
Andrew Shulaeve6c4a5c2021-01-29 11:07:39 +0000189
190 if (!exclude_imports) {
191 args += [ "--include_imports" ]
192 }
Florian Mayerab55e3d2018-04-19 11:56:01 +0100193 args += [
194 "--descriptor_set_out",
Lalit Maganti45d8eb82020-09-12 16:32:18 +0100195 rebase_path("$root_gen_dir/$generate_descriptor", root_build_dir),
Lalit Magantie87838f2019-06-25 18:31:49 +0100196 "--dependency_out",
Hector Dearman7a9ffa72019-08-13 16:00:10 +0100197 rebase_path(depfile, root_build_dir),
Florian Mayerab55e3d2018-04-19 11:56:01 +0100198 ]
199 }
Primiano Tuccifd484232017-10-25 00:15:39 +0100200
201 if (generate_with_plugin) {
202 plugin_path_rebased = rebase_path(plugin_path, root_build_dir)
203 plugin_out_args = ""
204 if (defined(invoker.generator_plugin_options)) {
205 plugin_out_args += invoker.generator_plugin_options
206 }
Lalit Maganti45d8eb82020-09-12 16:32:18 +0100207 plugin_out_args += ":$rel_out_dir"
Primiano Tuccifd484232017-10-25 00:15:39 +0100208
209 args += [
210 "--plugin=protoc-gen-plugin=$plugin_path_rebased",
211 "--plugin_out=$plugin_out_args",
212 ]
213 }
214
Primiano Tuccie8a77602018-01-16 00:14:08 +0000215 args += rebase_path(proto_sources, root_build_dir)
Primiano Tuccifd484232017-10-25 00:15:39 +0100216
Joel Fernandes80fc3cd2020-04-01 18:02:57 -0400217 if (!perfetto_use_system_protobuf) {
218 inputs = [ protoc_path ]
219 deps = [ protoc_label ]
220 } else {
Primiano Tucci5cbeadf2020-04-03 22:28:40 +0100221 inputs = []
222 deps = []
Joel Fernandes80fc3cd2020-04-01 18:02:57 -0400223 }
Hector Dearman71256632019-03-11 16:39:34 +0000224
225 # TODO(hjd): Avoid adding to deps here this.
226 # When we generate BUILD files we need find the transitive proto,
227 # dependencies, so also add link_deps to actual deps so they show up
228 # in gn desc.
229 if (defined(invoker.link_deps)) {
230 deps += invoker.link_deps
231 }
Primiano Tuccifd484232017-10-25 00:15:39 +0100232 if (generate_with_plugin) {
233 inputs += [ plugin_path ]
234 if (defined(plugin_host_label)) {
235 # Action depends on native generator plugin but for host toolchain only.
236 deps += [ plugin_host_label ]
237 }
238 }
Eric Secklere0e19142019-03-25 10:14:18 +0000239
240 if (defined(invoker.deps)) {
241 deps += invoker.deps
242 }
Lalit Magantif9799c62019-05-28 20:01:08 +0100243 } # action(action_name)
Primiano Tuccifd484232017-10-25 00:15:39 +0100244
245 # The source_set that builds the generated .pb.cc files.
Lalit Magantif9799c62019-05-28 20:01:08 +0100246 if (generate_descriptor == "") {
247 source_set(source_set_name) {
248 forward_variables_from(invoker,
249 [
250 "defines",
251 "include_dirs",
252 "public_configs",
253 "testonly",
254 "visibility",
255 ])
Primiano Tuccifd484232017-10-25 00:15:39 +0100256
Lalit Magantif9799c62019-05-28 20:01:08 +0100257 sources = get_target_outputs(":$action_name")
Primiano Tuccifd484232017-10-25 00:15:39 +0100258
Lalit Magantif9799c62019-05-28 20:01:08 +0100259 configs -= [ "//gn/standalone:extra_warnings" ]
260 if (defined(invoker.extra_configs)) {
261 configs += invoker.extra_configs
262 }
Primiano Tuccifd484232017-10-25 00:15:39 +0100263
Lalit Magantif9799c62019-05-28 20:01:08 +0100264 if (!defined(invoker.public_configs)) {
265 public_configs = []
266 }
Primiano Tucci4e313b82017-11-02 12:16:58 +0000267
Lalit Maganti76905222022-05-20 14:24:14 +0100268 public_configs += [ ":$config_name" ]
269
270 # Only include the protobuf_gen_config when generating .pb.cc files.
271 # Note that |generate_cc| is false for .{pbzero,ipc,gen etc.}.cc
272 if (generate_cc) {
273 public_configs += [ "//gn:protobuf_gen_config" ]
274 }
Primiano Tucci782374f2017-11-27 16:25:20 +0000275
Eric Secklerd7fd6c22020-01-22 18:46:35 +0000276 # By default, propagate the config for |include_dirs| to dependent
277 # targets, so that public imports can be resolved to corresponding header
278 # files. In some cases, the embedder target handles include directory
279 # propagation itself, e.g. via a common config.
280 propagate_imports_configs = !defined(invoker.propagate_imports_configs) ||
281 invoker.propagate_imports_configs
282 if (propagate_imports_configs) {
283 public_configs += [ ":$config_name" ]
284 } else {
285 configs += [ ":$config_name" ]
286 }
287
Lalit Magantif9799c62019-05-28 20:01:08 +0100288 # Use protobuf_full only for tests.
289 if (defined(invoker.use_protobuf_full) &&
290 invoker.use_protobuf_full == true) {
Primiano Tucci2925e9d2020-01-27 10:15:58 +0000291 deps = [ "//gn:protobuf_full" ]
Lalit Maganti4e7b5772019-06-13 13:36:33 +0100292 } else if (generate_cc) {
Primiano Tucci2925e9d2020-01-27 10:15:58 +0000293 deps = [ "//gn:protobuf_lite" ]
Lalit Maganti4e7b5772019-06-13 13:36:33 +0100294 } else {
295 deps = []
Lalit Magantif9799c62019-05-28 20:01:08 +0100296 }
297
298 deps += [ ":$action_name" ]
299 if (defined(invoker.deps)) {
300 deps += invoker.deps
301 }
302 } # source_set(source_set_name)
303 }
Primiano Tuccifd484232017-10-25 00:15:39 +0100304} # template