1# Copyright 2019 the V8 project authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import("//build_overrides/build.gni") 6 7# This file should not be pulled in chromium builds. 8assert(!build_with_chromium) 9 10template("proto_library") { 11 assert(defined(invoker.sources)) 12 proto_sources = invoker.sources 13 14 if (host_os == "win") { 15 host_executable_suffix = ".exe" 16 } else { 17 host_executable_suffix = "" 18 } 19 20 # All the proto imports should be relative to the project root. 21 proto_in_dir = "//" 22 if (defined(invoker.proto_in_dir)) { 23 proto_in_dir = invoker.proto_in_dir 24 } 25 assert(defined(invoker.proto_out_dir), 26 "proto_out_dir must be explicitly defined") 27 proto_out_dir = invoker.proto_out_dir 28 29 # We don't support generate_python in the standalone build, but still must 30 # check that the caller sets this to false. This is because when building in 31 # the chromium tree, chromium's proto_library.gni in chrome (!= this) defaults 32 # generate_python = true. 33 assert(defined(invoker.generate_python) && !invoker.generate_python) 34 35 # If false will not generate the default .pb.{cc,h} files. Used for custom 36 # codegen plugins. 37 generate_cc = true 38 if (defined(invoker.generate_cc)) { 39 generate_cc = invoker.generate_cc 40 } 41 42 generate_descriptor = "" 43 if (defined(invoker.generate_descriptor)) { 44 generate_descriptor = invoker.generate_descriptor 45 } 46 47 if (defined(invoker.generator_plugin_label)) { 48 plugin_host_label = invoker.generator_plugin_label + "($host_toolchain)" 49 plugin_path = 50 get_label_info(plugin_host_label, "root_out_dir") + "/" + 51 get_label_info(plugin_host_label, "name") + host_executable_suffix 52 generate_with_plugin = true 53 } else if (defined(invoker.generator_plugin_script)) { 54 plugin_path = invoker.generator_plugin_script 55 generate_with_plugin = true 56 } else { 57 generate_with_plugin = false 58 } 59 60 if (generate_with_plugin) { 61 if (defined(invoker.generator_plugin_suffix)) { 62 generator_plugin_suffixes = [ 63 "${invoker.generator_plugin_suffix}.h", 64 "${invoker.generator_plugin_suffix}.cc", 65 ] 66 } else { 67 generator_plugin_suffixes = invoker.generator_plugin_suffixes 68 } 69 } 70 71 cc_out_dir = "$root_gen_dir/" + proto_out_dir 72 rel_cc_out_dir = rebase_path(cc_out_dir, root_build_dir) 73 74 protos = rebase_path(proto_sources, proto_in_dir) 75 protogens = [] 76 77 if (generate_descriptor != "") { 78 protogens += [ "$root_gen_dir/" + generate_descriptor ] 79 } 80 81 foreach(proto, protos) { 82 proto_dir = get_path_info(proto, "dir") 83 proto_name = get_path_info(proto, "name") 84 proto_path = proto_dir + "/" + proto_name 85 86 if (generate_cc) { 87 protogens += [ 88 "$cc_out_dir/$proto_path.pb.h", 89 "$cc_out_dir/$proto_path.pb.cc", 90 ] 91 } 92 if (generate_with_plugin) { 93 foreach(suffix, generator_plugin_suffixes) { 94 protogens += [ "$cc_out_dir/${proto_path}${suffix}" ] 95 } 96 } 97 } 98 99 config_name = "${target_name}_config" 100 action_name = "${target_name}_gen" 101 source_set_name = target_name 102 103 config(config_name) { 104 include_dirs = [ cc_out_dir ] 105 } 106 107 # The XXX_gen action that generates the .pb.{cc,h} files. 108 action(action_name) { 109 visibility = [ ":$source_set_name" ] 110 script = "//build/gn_run_binary.py" 111 sources = proto_sources 112 outputs = get_path_info(protogens, "abspath") 113 114 protoc_label = "//:protoc($host_toolchain)" 115 protoc_path = get_label_info(protoc_label, "root_out_dir") + "/protoc" + 116 host_executable_suffix 117 args = [ 118 # Path should be rebased because |root_build_dir| for current toolchain 119 # may be different from |root_out_dir| of protoc built on host toolchain. 120 "./" + rebase_path(protoc_path, root_build_dir), 121 "--proto_path", 122 rebase_path(proto_in_dir, root_build_dir), 123 ] 124 if (generate_cc) { 125 cc_generator_options_ = "" 126 if (defined(invoker.cc_generator_options)) { 127 cc_generator_options_ = invoker.cc_generator_options 128 } 129 args += [ 130 "--cpp_out", 131 cc_generator_options_ + rel_cc_out_dir, 132 ] 133 } 134 if (generate_descriptor != "") { 135 args += [ 136 "--include_imports", 137 "--descriptor_set_out", 138 rebase_path("$root_gen_dir/" + generate_descriptor, root_build_dir), 139 ] 140 } 141 142 if (defined(invoker.import_dirs)) { 143 foreach(path, invoker.import_dirs) { 144 args += [ "--import-dir=" + rebase_path(path, root_build_dir) ] 145 } 146 } 147 148 if (generate_with_plugin) { 149 plugin_path_rebased = rebase_path(plugin_path, root_build_dir) 150 plugin_out_args = "" 151 if (defined(invoker.generator_plugin_options)) { 152 plugin_out_args += invoker.generator_plugin_options 153 } 154 plugin_out_args += ":$rel_cc_out_dir" 155 156 args += [ 157 "--plugin=protoc-gen-plugin=$plugin_path_rebased", 158 "--plugin_out=$plugin_out_args", 159 ] 160 } 161 162 args += rebase_path(proto_sources, root_build_dir) 163 164 inputs = [ protoc_path ] 165 166 deps = [ protoc_label ] 167 if (generate_with_plugin) { 168 inputs += [ plugin_path ] 169 if (defined(plugin_host_label)) { 170 # Action depends on native generator plugin but for host toolchain only. 171 deps += [ plugin_host_label ] 172 } 173 } 174 175 if (defined(invoker.proto_deps)) { 176 deps += invoker.proto_deps 177 } 178 if (defined(invoker.deps)) { 179 deps += invoker.deps 180 } 181 } # action "${target_name}_gen" 182 183 # The source_set that builds the generated .pb.cc files. 184 source_set(target_name) { 185 forward_variables_from(invoker, 186 [ 187 "defines", 188 "include_dirs", 189 "public_configs", 190 "testonly", 191 "visibility", 192 ]) 193 194 sources = get_target_outputs(":$action_name") 195 196 # configs -= [ "//gn/standalone:extra_warnings" ] 197 if (defined(invoker.extra_configs)) { 198 configs += invoker.extra_configs 199 } 200 201 if (!defined(invoker.public_configs)) { 202 public_configs = [] 203 } 204 205 public_configs += [ "//:protobuf_gen_config" ] 206 207 propagate_imports_configs = !defined(invoker.propagate_imports_configs) || 208 invoker.propagate_imports_configs 209 if (propagate_imports_configs) { 210 public_configs += [ ":$config_name" ] 211 } else { 212 # Embedder handles include directory propagation to dependents. 213 configs += [ ":$config_name" ] 214 } 215 216 # Use protobuf_full only for tests. 217 if (defined(invoker.use_protobuf_full) && 218 invoker.use_protobuf_full == true) { 219 deps = [ "//:protobuf_full" ] 220 } else { 221 deps = [ "//:protobuf_lite" ] 222 } 223 224 deps += [ ":$action_name" ] 225 if (defined(invoker.deps)) { 226 deps += invoker.deps 227 } 228 if (defined(invoker.link_deps)) { 229 deps += invoker.link_deps 230 } 231 } # source_set(target_name) 232} # template 233