| # Copyright 2014 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # Compile a protocol buffer. |
| # |
| # Protobuf parameters: |
| # |
| # proto_in_dir (optional) |
| # Specifies the path relative to the current BUILD.gn file where |
| # proto files are located and the directory structure of |
| # this proto library starts. |
| # |
| # This option can be calculated automatically but it will raise an |
| # assertion error if any nested directories are found. |
| # |
| # proto_out_dir (optional) |
| # Specifies the path suffix that output files are generated under. |
| # This path will be appended to |root_gen_dir|, but for python stubs |
| # it will be appended to |root_build_dir|/pyproto. |
| # |
| # generate_python (optional, default true) |
| # Generate Python protobuf stubs. |
| # |
| # generate_cc (optional, default true) |
| # Generate C++ protobuf stubs. |
| # |
| # generate_javascript (optional, default false) |
| # Generate Javascript protobuf stubs. |
| # |
| # generate_library (optional, default true) |
| # Generate a "static_library" target for linking with the generated code. |
| # |
| # generate_py_runtime (optional, default false) |
| # Generates a "_py_runtime"-suffixed target for test targets that need the |
| # Python stubs available at runtime. |
| # |
| # cc_generator_options (optional) |
| # List of extra flags passed to the protocol compiler. If you need to |
| # add an EXPORT macro to a protobuf's C++ header, set the |
| # 'cc_generator_options' variable with the value: |
| # 'dllexport_decl=FOO_EXPORT:' (note trailing colon). |
| # |
| # It is likely you also need to #include a file for the above EXPORT |
| # macro to work (see cc_include) and set |
| # component_build_force_source_set = true. |
| # |
| # cc_include (optional) |
| # String listing an extra include that should be passed. |
| # Example: cc_include = "foo/bar.h" |
| # |
| # generator_plugin_label (optional) |
| # GN label for plugin executable which generates custom cc stubs. |
| # Don't specify a toolchain, host toolchain is assumed. |
| # |
| # generator_plugin_script (optional) |
| # Path to plugin script. Mutually exclusive with |generator_plugin_label|. |
| # |
| # generator_plugin_script_deps (optional) |
| # List of additional files required for generator plugin script. |
| # |
| # generator_plugin_suffix[es] (required if using a plugin) |
| # Suffix (before extension) for generated .cc and .h files |
| # or list of suffixes for all files (with extensions). |
| # |
| # generator_plugin_options (optional) |
| # Extra flags passed to the plugin. See cc_generator_options. |
| # |
| # deps (optional) |
| # This is used to specify deps to other proto_library targets containing |
| # imported proto files as sources from proto files in this target. |
| # |
| # link_deps (optional) |
| # Additional deps for the generated C++ library. |
| # |
| # link_public_deps (optional) |
| # Additional public_deps for the generated C++ library. |
| # |
| # proto_deps (optional) |
| # Additional dependencies required before running protoc. |
| # e.g. proto file generating action. |
| # |
| # use_protobuf_full (optional) |
| # If adding protobuf library would be required, adds protobuf_full to deps |
| # instead of protobuf_lite. |
| # |
| # import_dirs (optional) |
| # A list of extra import directories to be passed to protoc compiler. |
| # WARNING: This circumvents proto checkdeps, and should only be used when |
| # needed, typically when proto files cannot cleanly import through |
| # absolute paths, such as for third_party or generated .proto files. |
| # http://crbug.com/691451 tracks fixing this. |
| # |
| # Parameters for compiling the generated code: |
| # |
| # force_source_set (Default=false) |
| # When set true the generated code will be compiled as a source set. |
| # This can be useful if you need to export the generated symbols from a |
| # shared library. You should use this carefully, as you probably only |
| # want this if your dependencies are *always* shared libraries. Most |
| # of the time, you probably want `component_build_force_source_set` |
| # instead (see the next option). |
| # component_build_force_source_set (Default=false) |
| # When set true the generated code will be compiled as a source set in |
| # the component build. This does not affect static builds. If you are |
| # exporting symbols from a component, this is required to prevent those |
| # symbols from being stripped. If you're not using dllexports in |
| # cc_generator_options, it's usually best to leave this false. |
| # |
| # defines (optional) |
| # Defines to supply to the source set that compiles the generated source |
| # code. |
| # |
| # extra_configs (optional) |
| # A list of config labels that will be appended to the configs applying |
| # to the source set. |
| # |
| # remove_configs (optional) |
| # A list of config labels that will be removed from the configs apllying |
| # to the source set. |
| # |
| # propagate_imports_configs (optional) |
| # A boolean value (defaults to true) that specifies whether the config |
| # generated for the library's import directories will be propagated to |
| # dependents as one of the library target's public_configs. See |
| # crbug.com/1043279#c11 and crbug.com/gn/142 for why this option exists. |
| # WARNING: If set to false, the embedder target is responsible for |
| # propagating a suitable config, so that any dependent headers can resolve |
| # includes generated by proto imports. |
| # |
| # Example: |
| # proto_library("mylib") { |
| # sources = [ |
| # "foo.proto", |
| # ] |
| # } |
| |
| import("//build_overrides/protobuf.gni") |
| |
| import("//build/config/compiler/compiler.gni") |
| import("//build/config/cronet/config.gni") |
| import("//build/config/sanitizers/sanitizers.gni") |
| import("//build/toolchain/kythe.gni") |
| |
| declare_args() { |
| # Allows subprojects to omit javascript dependencies (e.g.) closure_compiler |
| # and google-closure-library. |
| enable_js_protobuf = !is_cronet_build |
| } |
| |
| declare_args() { |
| # Allows embedders to provide an alternate path to abseil-cpp. (Used |
| # by Dawn & Skia in stand alone builds) |
| if (!defined(protobuf_abseil_dir)) { |
| protobuf_abseil_dir = "//third_party/abseil-cpp" |
| } |
| } |
| |
| if (enable_js_protobuf) { |
| import("//third_party/closure_compiler/compile_js.gni") |
| } |
| |
| proto_python_root = "$root_out_dir/pyproto" |
| proto_js_root = "$root_out_dir/jsproto" |
| proto_ts_root = "$root_gen_dir/tsproto" |
| |
| if (host_os == "win") { |
| _host_executable_suffix = ".exe" |
| } else { |
| _host_executable_suffix = "" |
| } |
| |
| # TODO(https://crbug.com/337736622): V8 shares this dependency and stores |
| # it in a different location. Hence, all references to this folder should |
| # use this variable instead of hard-coding //third_party/protobuf. |
| # This can be switched back to //third_party/protobuf in M129, or earlier in |
| # case crbug.com/338008085 is resolved. |
| _this_dir = get_path_info(".", "abspath") |
| |
| _protoc_label = "$_this_dir:protoc($host_toolchain)" |
| _protoc_path = get_label_info(_protoc_label, "root_out_dir") + "/protoc" + |
| _host_executable_suffix |
| _protoc_gen_js_label = |
| "//third_party/protobuf-javascript:protoc-gen-js($host_toolchain)" |
| _protoc_gen_js_path = get_label_info(_protoc_gen_js_label, "root_out_dir") + |
| "/protoc-gen-js" + _host_executable_suffix |
| if (host_os == "win") { |
| _protoc_gen_ts_path = "//tools/protoc_wrapper/protoc-gen-ts_proto.bat" |
| } else { |
| _protoc_gen_ts_path = "//tools/protoc_wrapper/protoc-gen-ts_proto.py" |
| } |
| |
| _protoc_gen_ts_runtime_deps = [ |
| "//third_party/node/node.py", |
| "//third_party/node/node_modules.py", |
| "//third_party/node/node_modules.tar.gz.sha1", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/create.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/descriptors.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/from-binary.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/is-message.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/package.json", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/proto-int64.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/reflect/error.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/reflect/guard.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/reflect/reflect-check.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/reflect/reflect.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/reflect/scalar.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/reflect/unsafe.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/to-binary.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/wire/base64-encoding.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/wire/binary-encoding.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/wire/index.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/wire/size-delimited.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/wire/text-encoding.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/wire/text-format.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/wire/varint.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/dist/cjs/wkt/wrappers.js", |
| "//third_party/node/node_modules/@bufbuild/protobuf/package.json", |
| "//third_party/node/node_modules/case-anything/dist/cjs/index.cjs", |
| "//third_party/node/node_modules/case-anything/package.json", |
| "//third_party/node/node_modules/ts-poet/build/Code.js", |
| "//third_party/node/node_modules/ts-poet/build/ConditionalOutput.js", |
| "//third_party/node/node_modules/ts-poet/build/Import.js", |
| "//third_party/node/node_modules/ts-poet/build/Literal.js", |
| "//third_party/node/node_modules/ts-poet/build/Node.js", |
| "//third_party/node/node_modules/ts-poet/build/index.js", |
| "//third_party/node/node_modules/ts-poet/build/is-plain-object.js", |
| "//third_party/node/node_modules/ts-poet/build/saveFiles.js", |
| "//third_party/node/node_modules/ts-poet/build/utils.js", |
| "//third_party/node/node_modules/ts-poet/package.json", |
| "//third_party/node/node_modules/ts-proto-descriptors/dist/google/protobuf/compiler/plugin.js", |
| "//third_party/node/node_modules/ts-proto-descriptors/dist/google/protobuf/descriptor.js", |
| "//third_party/node/node_modules/ts-proto-descriptors/dist/index.js", |
| "//third_party/node/node_modules/ts-proto-descriptors/package.json", |
| "//third_party/node/node_modules/ts-proto/build/src/case.js", |
| "//third_party/node/node_modules/ts-proto/build/src/context.js", |
| "//third_party/node/node_modules/ts-proto/build/src/encode.js", |
| "//third_party/node/node_modules/ts-proto/build/src/enums.js", |
| "//third_party/node/node_modules/ts-proto/build/src/generate-async-iterable.js", |
| "//third_party/node/node_modules/ts-proto/build/src/generate-generic-service-definition.js", |
| "//third_party/node/node_modules/ts-proto/build/src/generate-grpc-js.js", |
| "//third_party/node/node_modules/ts-proto/build/src/generate-grpc-web.js", |
| "//third_party/node/node_modules/ts-proto/build/src/generate-nestjs.js", |
| "//third_party/node/node_modules/ts-proto/build/src/generate-nice-grpc.js", |
| "//third_party/node/node_modules/ts-proto/build/src/generate-services.js", |
| "//third_party/node/node_modules/ts-proto/build/src/generate-struct-wrappers.js", |
| "//third_party/node/node_modules/ts-proto/build/src/generate-type-registry.js", |
| "//third_party/node/node_modules/ts-proto/build/src/main.js", |
| "//third_party/node/node_modules/ts-proto/build/src/options.js", |
| "//third_party/node/node_modules/ts-proto/build/src/options.js", |
| "//third_party/node/node_modules/ts-proto/build/src/plugin.js", |
| "//third_party/node/node_modules/ts-proto/build/src/schema.js", |
| "//third_party/node/node_modules/ts-proto/build/src/sourceInfo.js", |
| "//third_party/node/node_modules/ts-proto/build/src/types.js", |
| "//third_party/node/node_modules/ts-proto/build/src/utils.js", |
| "//third_party/node/node_modules/ts-proto/build/src/visit.js", |
| "//third_party/node/node_modules/ts-proto/package.json", |
| "//third_party/node/node_modules/ts-proto/protoc-gen-ts_proto", |
| ] |
| |
| # When use_remoteexec=true, node actions may run on remote |
| # Linux worker. So it should include linux node binary in inputs. |
| if (is_linux || is_chromeos || use_remoteexec) { |
| _protoc_gen_ts_runtime_deps += |
| [ "//third_party/node/linux/node-linux-x64/bin/node" ] |
| } |
| if (is_win && host_os == "win") { |
| _protoc_gen_ts_runtime_deps += [ "//third_party/node/win/node.exe" ] |
| } |
| if (is_mac && host_os == "mac") { |
| if (host_cpu == "arm64") { |
| _protoc_gen_ts_runtime_deps += |
| [ "//third_party/node/mac_arm64/node-darwin-arm64/bin/node" ] |
| } else { |
| _protoc_gen_ts_runtime_deps += |
| [ "//third_party/node/mac/node-darwin-x64/bin/node" ] |
| } |
| } |
| |
| template("proto_library") { |
| forward_variables_from(invoker, [ "testonly" ]) |
| |
| # TODO(agrieve): Remove perfetto instances of this. |
| not_needed(invoker, [ "generator_visibility" ]) |
| |
| _generate_cc = !defined(invoker.generate_cc) || invoker.generate_cc |
| _generate_py_runtime = |
| defined(invoker.generate_py_runtime) && invoker.generate_py_runtime |
| _generate_python = !defined(invoker.generate_python) || |
| invoker.generate_python || _generate_py_runtime |
| _generate_javascript = defined(invoker.generate_javascript) && |
| invoker.generate_javascript && enable_js_protobuf |
| _generate_typescript = defined(invoker.generate_typescript) && |
| invoker.generate_typescript && enable_js_protobuf |
| _generate_with_plugin = defined(invoker.generator_plugin_label) || |
| defined(invoker.generator_plugin_script) |
| |
| # Whether source code bindings should be generated (alternative is to just |
| # build the descriptor). |
| _generate_sources = |
| _generate_cc || _generate_with_plugin || _generate_python || |
| _generate_javascript || _generate_typescript |
| _generate_descriptor = defined(invoker.generate_descriptor) |
| assert(_generate_sources || _generate_descriptor || !enable_js_protobuf, |
| "Not generating anything...") |
| |
| if (_generate_with_plugin) { |
| if (defined(invoker.generator_plugin_suffix)) { |
| _generator_plugin_suffixes = [ |
| "${invoker.generator_plugin_suffix}.h", |
| "${invoker.generator_plugin_suffix}.cc", |
| ] |
| } else { |
| _generator_plugin_suffixes = invoker.generator_plugin_suffixes |
| } |
| } |
| |
| _sources = invoker.sources |
| |
| if (defined(invoker.proto_in_dir)) { |
| _proto_in_dir = invoker.proto_in_dir |
| _has_nested_dirs = false |
| foreach(_source, _sources) { |
| if (get_path_info(_source, "dir") != _proto_in_dir) { |
| _has_nested_dirs = true |
| } |
| } |
| } else { |
| # Use the directory of the first source. |
| _proto_in_dir = get_path_info(_sources[0], "dir") |
| _has_nested_dirs = false |
| |
| # Consistency check: |proto_in_dir| should be defined to allow sub-directories. |
| foreach(_source, _sources) { |
| assert(get_path_info(_source, "dir") == _proto_in_dir, |
| "Please define |proto_in_dir| to allow nested directories.") |
| } |
| } |
| |
| # Ensure it's a relative path. |
| _proto_in_dir = rebase_path(_proto_in_dir, ".") |
| |
| if (defined(invoker.proto_out_dir)) { |
| _package_subdir = invoker.proto_out_dir |
| } else { |
| # Path to the directory of current BUILD.gn. |
| _package_subdir = rebase_path(".", "//") |
| if (_proto_in_dir != ".") { |
| _package_subdir += "/$_proto_in_dir" |
| } |
| } |
| |
| # We need both absolute path to use in GN statements and a relative one |
| # to pass to external script. |
| if (_generate_cc || _generate_with_plugin) { |
| _cc_out_dir = "$root_gen_dir/$_package_subdir" |
| _cc_outputs = [] |
| } |
| if (_generate_python) { |
| _py_out_dir = "$proto_python_root/$_package_subdir" |
| _py_outputs = [] |
| } |
| if (_generate_javascript) { |
| _js_out_dir = "$proto_js_root/$_package_subdir" |
| _js_outputs = [] |
| } |
| if (_generate_typescript) { |
| _ts_out_dir = "$proto_ts_root/$_package_subdir" |
| _ts_outputs = [] |
| } |
| |
| # List output files. |
| _relative_sources = rebase_path(_sources, _proto_in_dir) |
| if (_generate_sources) { |
| foreach(_source, _relative_sources) { |
| _proto_path = |
| get_path_info(_source, "dir") + "/" + get_path_info(_source, "name") |
| |
| if (_generate_cc) { |
| _cc_outputs += [ |
| "$_cc_out_dir/$_proto_path.pb.h", |
| "$_cc_out_dir/$_proto_path.pb.cc", |
| ] |
| } |
| if (_generate_python) { |
| _py_outputs += [ "$_py_out_dir/${_proto_path}_pb2.py" ] |
| } |
| if (_generate_with_plugin) { |
| foreach(_suffix, _generator_plugin_suffixes) { |
| _cc_outputs += [ "$_cc_out_dir/$_proto_path$_suffix" ] |
| } |
| } |
| if (_generate_javascript) { |
| _js_outputs += [ "$_js_out_dir/$_proto_path.js" ] |
| } |
| if (_generate_typescript) { |
| _ts_outputs += [ "$_ts_out_dir/$_proto_path.ts" ] |
| } |
| } |
| } |
| |
| # Generated files may include other generated headers. These includes always |
| # use relative paths starting at |_cc_out_dir|. |
| # However there is no necessity to add an additional directory, if all protos |
| # are located in the same directory which is in the search path by default. |
| if (_generate_cc || _generate_with_plugin) { |
| # Not necessary if all protos are located in the same directory. |
| if (_has_nested_dirs || defined(invoker.import_dirs)) { |
| _include_dir_config_name = "${target_name}_config" |
| config("$_include_dir_config_name") { |
| include_dirs = [] |
| if (_has_nested_dirs) { |
| include_dirs += [ _cc_out_dir ] |
| } |
| if (defined(invoker.import_dirs)) { |
| foreach(path, invoker.import_dirs) { |
| include_dirs += [ "$root_gen_dir/" + rebase_path(path, "//") ] |
| } |
| } |
| } |
| } |
| } else { |
| not_needed([ "_has_nested_dirs" ]) |
| } |
| |
| # Allows proto_library() targets that depend on this one to import its |
| # .proto files without declaring them as inputs. |
| _input_config_name = "${target_name}__inputs_config" |
| config(_input_config_name) { |
| inputs = _sources |
| } |
| _input_group_name = "${target_name}_input_group" |
| group(_input_group_name) { |
| public_configs = [ ":$_input_config_name" ] |
| public_deps = [] |
| |
| # The deps may have steps that have to run before running protoc. |
| if (defined(invoker.proto_deps)) { |
| public_deps += invoker.proto_deps |
| } |
| if (defined(invoker.deps)) { |
| # This is to propagate input deps for imported proto to ancestor targets. |
| foreach(_dep, invoker.deps) { |
| _dep = get_label_info(_dep, "label_no_toolchain") |
| |
| # TODO(agrieve): Update perfetto to follow naming scheme. |
| if (filter_exclude([ _dep ], [ "//third_party/perfetto/*" ]) == []) { |
| # Protozero does not follow the naming scheme. |
| public_deps += [ |
| "${_dep}_input_group", |
| _dep, |
| ] |
| } else { |
| # Depend directly on the _gen targets so as to not unnecessarily block |
| # on compile (by depending on source_set targets). |
| public_deps += [ "${_dep}_gen" ] |
| } |
| } |
| } |
| } |
| |
| # Generate protobuf stubs. |
| _action_name = "${target_name}_gen" |
| action(_action_name) { |
| script = "//tools/protoc_wrapper/protoc_wrapper.py" |
| sources = _sources |
| inputs = [ |
| # System protoc is not used so it's necessary to build a chromium one. |
| _protoc_path, |
| ] |
| outputs = [] |
| if (_generate_cc || _generate_with_plugin) { |
| outputs += _cc_outputs |
| } |
| if (_generate_python) { |
| outputs += _py_outputs |
| } |
| if (_generate_javascript) { |
| outputs += _js_outputs |
| } |
| if (_generate_typescript) { |
| outputs += _ts_outputs |
| } |
| |
| deps = [ _protoc_label ] |
| if (host_toolchain_is_msan) { |
| deps += [ "//third_party/instrumented_libs:ld-linux($host_toolchain)" ] |
| configs = [ |
| "//third_party/instrumented_libs:msan_runtime_libs($host_toolchain)", |
| ] |
| } |
| |
| public_deps = [ ":$_input_group_name" ] |
| |
| args = _relative_sources + [ |
| # Wrapper should never pick a system protoc. |
| # Path should be rebased because |root_build_dir| for current toolchain |
| # may be different from |root_out_dir| of protoc built on host toolchain. |
| "--protoc", |
| "./" + rebase_path(_protoc_path, root_build_dir), |
| "--proto-in-dir", |
| rebase_path(_proto_in_dir, root_build_dir), |
| ] |
| |
| # TODO(crbug.com/409484308): Enable in fuzzer builds too. |
| if (treat_warnings_as_errors && !fuzzing_engine_supports_custom_main) { |
| args += [ "--fatal_warnings" ] |
| } |
| |
| if (_generate_cc) { |
| args += [ |
| "--cc-out-dir", |
| rebase_path(_cc_out_dir, root_build_dir), |
| ] |
| if (enable_kythe_annotations) { |
| args += [ "--enable-kythe-annotation" ] |
| } |
| if (defined(invoker.cc_generator_options)) { |
| args += [ |
| "--cc-options", |
| invoker.cc_generator_options, |
| ] |
| } |
| if (defined(invoker.cc_include)) { |
| args += [ |
| "--include", |
| invoker.cc_include, |
| ] |
| } |
| } |
| |
| if (_generate_python) { |
| args += [ |
| "--py-out-dir", |
| rebase_path(_py_out_dir, root_build_dir), |
| ] |
| } |
| |
| if (_generate_javascript) { |
| args += [ |
| "--js-out-dir", |
| rebase_path(_js_out_dir, root_build_dir), |
| "--protoc-gen-js", |
| "./" + rebase_path(_protoc_gen_js_path, root_build_dir), |
| ] |
| inputs += [ _protoc_gen_js_path ] |
| deps += [ _protoc_gen_js_label ] |
| } |
| |
| if (_generate_typescript) { |
| args += [ |
| "--ts-out-dir", |
| rebase_path(_ts_out_dir, root_build_dir), |
| "--protoc-gen-ts", |
| "./" + rebase_path(_protoc_gen_ts_path, root_build_dir), |
| ] |
| inputs += [ |
| _protoc_gen_ts_path, |
| "//tools/protoc_wrapper/protoc-gen-ts_proto.py", |
| ] + _protoc_gen_ts_runtime_deps |
| deps += [ "//third_party/node:check_version" ] |
| } |
| |
| if (_generate_with_plugin) { |
| if (defined(invoker.generator_plugin_label)) { |
| # Straightforward way to get the name of executable doesn't work because |
| # |root_out_dir| and |root_build_dir| may differ in cross-compilation and |
| # also Windows executables have .exe at the end. |
| |
| _plugin_host_label = |
| "${invoker.generator_plugin_label}($host_toolchain)" |
| _plugin_path = |
| get_label_info(_plugin_host_label, "root_out_dir") + "/" + |
| get_label_info(_plugin_host_label, "name") + _host_executable_suffix |
| deps += [ _plugin_host_label ] |
| } else { |
| _plugin_path = invoker.generator_plugin_script |
| } |
| inputs += [ _plugin_path ] |
| if (defined(invoker.generator_plugin_script_deps)) { |
| # Additional scripts for plugin. |
| inputs += invoker.generator_plugin_script_deps |
| } |
| if (defined(plugin_host_label)) { |
| # Action depends on native generator plugin but for host toolchain only. |
| deps += [ plugin_host_label ] |
| } |
| args += [ |
| "--plugin", |
| rebase_path(_plugin_path, root_build_dir), |
| "--plugin-out-dir", |
| rebase_path(_cc_out_dir, root_build_dir), |
| ] |
| if (defined(invoker.generator_plugin_options)) { |
| args += [ |
| "--plugin-options", |
| invoker.generator_plugin_options, |
| ] |
| } |
| } |
| |
| if (_generate_descriptor) { |
| depfile = |
| "$root_gen_dir/$_package_subdir/${invoker.generate_descriptor}.d" |
| |
| if (defined(invoker.exclude_imports) && invoker.exclude_imports) { |
| args += [ "--exclude-imports" ] |
| } |
| |
| _descriptor_out = |
| "$root_gen_dir/$_package_subdir/${invoker.generate_descriptor}" |
| outputs += [ _descriptor_out ] |
| |
| args += [ |
| "--descriptor-set-out", |
| rebase_path(_descriptor_out, root_build_dir), |
| "--descriptor-set-dependency-file", |
| rebase_path(depfile, root_build_dir), |
| ] |
| } |
| |
| # Some protos import descriptor.proto directly or indirectly. This is |
| # required for the creation of FieldOptions and MessageOptions for |
| # consumption by protoc plugins. To facilitate this, the descriptor must |
| # both be an input and have it be accessible on the include path for the |
| # proto_library target using it AND every library that transitively includes |
| # it. To prevent having massive side-effects to build files on changes, this |
| # simply adds the input and import_dir for descriptor.proto to all targets. |
| # The import_dirs modification can be removed if http://crbug.com/691451 is |
| # fixed. |
| inputs += [ "//third_party/protobuf/src/google/protobuf/descriptor.proto" ] |
| _import_dirs = [ "//third_party/protobuf/src" ] |
| if (defined(invoker.import_dirs)) { |
| _import_dirs += invoker.import_dirs |
| } |
| foreach(_path, _import_dirs) { |
| args += [ "--import-dir=" + rebase_path(_path, root_build_dir) ] |
| } |
| } |
| |
| if ((defined(invoker.generate_library) && !invoker.generate_library) || |
| !_generate_sources) { |
| # If only descriptor is required, just generate a group wrapper for action output. |
| _library_type = "group" |
| } else if ((defined(invoker.force_source_set) && invoker.force_source_set) || |
| (defined(invoker.component_build_force_source_set) && |
| invoker.component_build_force_source_set && is_component_build)) { |
| # Option to disable building a library in component build. |
| _library_type = "source_set" |
| } else { |
| _library_type = "static_library" |
| } |
| |
| # Build generated protobuf stubs as libary or source set. |
| target(_library_type, target_name) { |
| forward_variables_from(invoker, |
| [ |
| "defines", |
| "visibility", |
| ]) |
| deps = [ ":$_action_name" ] |
| public_deps = [] |
| |
| # This will link any libraries in the deps (the use of invoker.deps in the |
| # action won't link it). |
| if (defined(invoker.deps)) { |
| deps += invoker.deps |
| } |
| if (defined(invoker.link_deps)) { |
| deps += invoker.link_deps |
| } |
| if (defined(invoker.link_public_deps)) { |
| public_deps += invoker.link_public_deps |
| } |
| |
| if (defined(_cc_outputs)) { |
| sources = _cc_outputs |
| |
| if (defined(invoker.remove_configs)) { |
| configs -= invoker.remove_configs |
| } |
| |
| if (defined(invoker.extra_configs)) { |
| configs += invoker.extra_configs |
| } |
| |
| # Remove Sanitizer and coverage instrumentation for a performance boost when |
| # fuzzing, since the only fuzzers that use protobuf are libprotobuf-mutator |
| # based fuzzers, and they don't actually target protobuf code. |
| configs -= not_fuzzed_remove_configs |
| configs += [ "//build/config/sanitizers:not_fuzzed" ] |
| } |
| |
| if (_generate_cc || _generate_with_plugin) { |
| public_configs = [ "$_this_dir:using_proto" ] |
| |
| # By default, propagate the config for |include_dirs| to dependent |
| # targets, so that public imports can be resolved to corresponding |
| # header files. In some cases, the embedder target handles include |
| # directory propagation itself, e.g. via a common config. |
| if (defined(_include_dir_config_name)) { |
| if (!defined(invoker.propagate_imports_configs) || |
| invoker.propagate_imports_configs) { |
| public_configs += [ ":$_include_dir_config_name" ] |
| } else { |
| # Embedder handles include directory propagation to dependents. |
| configs += [ ":$_include_dir_config_name" ] |
| } |
| } |
| |
| # If using built-in cc generator, the resulting headers reference headers |
| # within protobuf_lite. Hence, dependencies require those headers too. |
| # If using generator plugin, extra deps should be resolved by the invoker. |
| if (_generate_cc) { |
| if (defined(invoker.use_protobuf_full) && invoker.use_protobuf_full) { |
| public_deps += [ "$_this_dir:protobuf_full" ] |
| } else { |
| public_deps += [ "$_this_dir:protobuf_lite" ] |
| } |
| |
| if (is_win) { |
| cflags = [ |
| # disable: C4125 decimal digit terminates octal escape sequence |
| # Protoc generates such sequences frequently, there's no obvious |
| # superior replacement behavior. Since this code is autogenerated, |
| # the warning would never catch a legitimate bug. |
| "/wd4125", |
| ] |
| } |
| } |
| } |
| } |
| |
| # Build generated javascript stubs. |
| if (_generate_javascript) { |
| js_library("${target_name}_js") { |
| forward_variables_from(invoker, [ "visibility" ]) |
| sources = _js_outputs |
| deps = [ "$_this_dir:js_proto" ] |
| extra_deps = [ ":$_action_name" ] |
| } |
| } |
| |
| if (_generate_py_runtime) { |
| group("${target_name}_py_runtime") { |
| forward_variables_from(invoker, [ "visibility" ]) |
| data = _py_outputs |
| deps = [ |
| ":$_action_name", |
| "$_this_dir:py_proto_runtime", |
| ] |
| } |
| } |
| } |
| |
| # Convert a protocol buffer between text and binary formats. |
| # This can be used to run protoc with the --encode or --decode options. |
| # Parameters: |
| # |
| # sources: list of string |
| # The sources to loop over and run protoc on |
| # |
| # inputs: list of string |
| # The file dependencies for the action. This should be the list of .proto |
| # files involved in the conversion operation. |
| # |
| # output_pattern: string |
| # A path pattern with source expansion variables (like source_name_part) |
| # for where the result of conversion should be placed. |
| # |
| # deps: (optional) list of label |
| # Additional dependencies for the target. |
| # |
| # args: list of string |
| # Arguments to pass to the protoc tool. This could include -I for include |
| # paths, as well as the name of the proto file. |
| # |
| # |
| # Example to convert a .textproto to a .binarybp: |
| # protoc_convert("convert_foo") { |
| # sources = [ |
| # "test/data/example1.textproto", |
| # "test/data/example2.textproto", |
| # ] |
| # inputs = [ |
| # "//component/core/foo.proto", |
| # ] |
| # output_pattern = "$target_gen_dir/foo_data/{{source_name_part}}.binarypb" |
| # args = [ |
| # "--encode=foo.FooMessage", |
| # "-I", |
| # rebase_path("//", root_build_dir), |
| # "component/core/foo.proto", |
| # ] |
| # } |
| template("protoc_convert") { |
| action_foreach(target_name) { |
| script = "//tools/protoc_wrapper/protoc_convert.py" |
| |
| sources = invoker.sources |
| |
| inputs = invoker.inputs |
| |
| deps = [ _protoc_label ] |
| if (defined(invoker.deps)) { |
| deps += invoker.deps |
| } |
| |
| if (defined(invoker.testonly)) { |
| testonly = invoker.testonly |
| } |
| |
| outputs = [ invoker.output_pattern ] |
| |
| args = [ |
| "--protoc", |
| "./" + rebase_path(_protoc_path, root_build_dir), |
| "--infile", |
| "{{source}}", |
| "--outfile", |
| rebase_path(invoker.output_pattern, root_build_dir), |
| ] |
| |
| if (treat_warnings_as_errors) { |
| args += [ "--fatal_warnings" ] |
| } |
| |
| args += invoker.args |
| } |
| } |