| # Copyright 2018 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # Compile protocol buffers. |
| # |
| # Paramaeters: |
| # proto_in_dir |
| # Input directory. |
| # proto_out_dir |
| # Output directory. |
| # proto_lib_dirs (optional) |
| # Directories to search for protos a proto file depends on. |
| # proto_in_dir and "${sysroot}/usr/share/proto" are always included. |
| # sources |
| # The proto file paths. |
| # configs (optional) |
| # Configs applied to the generated library. |
| # deps (optional) |
| # Deps applied to the generated library. |
| # gen_python (optional) |
| # If true, generates Python binding. |
| # gen_grpc (optional) |
| # If true, generates C++ GRPC. |
| # gen_grpc_gmock (optional) |
| # If true, along with gen_grpc, generates C++ GRPC gmock objects as well. |
| # gen_cpp_mode (optional) |
| # If defined, ignores the OPTIMIZE_FOR lines in protos and generates code |
| # with the specified optimization mode (lite or speed). For fuzzer builds |
| # this defaults to speed to support libprotobuf-mutator. |
| # use_pic (optional) |
| # If true, generates a position independent code instead of position independent executable. |
| # standalone |
| # If true, generates a library that can be referred from other packages. |
| # Otherwise it generates a thin archive assuming it's used inside the same package only. |
| template("proto_library") { |
| action_name = "${target_name}_gen" |
| action(action_name) { |
| visibility = [ ":*" ] |
| |
| forward_variables_from(invoker, |
| [ |
| "proto_in_dir", |
| "proto_out_dir", |
| "gen_python", |
| "gen_grpc", |
| "gen_grpc_gmock", |
| "gen_cpp_mode", |
| |
| # Sources might be generated by actions in deps, |
| # which must be explicitly specified. |
| "deps", |
| "public_deps", |
| "sources", |
| ]) |
| |
| cc_dir = "${root_gen_dir}/${proto_out_dir}" |
| proto_in_dir = rebase_path(proto_in_dir) |
| proto_out_dir = rebase_path(proto_out_dir) |
| |
| proto_lib_dirs = [ |
| proto_in_dir, |
| "${sysroot}/usr/share/proto", |
| ] |
| if (defined(invoker.proto_lib_dirs)) { |
| proto_lib_dirs += rebase_path(invoker.proto_lib_dirs) |
| } |
| |
| if (!defined(gen_python)) { |
| gen_python = false |
| } |
| if (!defined(gen_grpc)) { |
| gen_grpc = false |
| } |
| if (gen_grpc && !defined(gen_grpc_gmock)) { |
| gen_grpc_gmock = false |
| } |
| if (defined(gen_cpp_mode)) { |
| gen_cpp_mode = "${gen_cpp_mode}:" |
| } else if (use.fuzzer) { |
| gen_cpp_mode = "speed:" |
| } else { |
| gen_cpp_mode = "" |
| } |
| |
| script = "//common-mk/file_generator_wrapper.py" |
| args = [ "protoc" ] |
| foreach(source, sources) { |
| args += [ rebase_path(source, proto_in_dir) ] |
| } |
| foreach(x, proto_lib_dirs) { |
| args += [ |
| "--proto_path", |
| x, |
| ] |
| } |
| outputs = [] |
| if (gen_python) { |
| python_dir = "${root_gen_dir}/${proto_out_dir}/py" |
| args += [ |
| "--python_out", |
| "${python_dir}", |
| ] |
| foreach(source, sources) { |
| source = rebase_path(source, proto_in_dir) |
| source = string_replace(source, ".proto", "") |
| outputs += [ "${python_dir}/${source}_pb.py" ] |
| } |
| } |
| if (gen_grpc) { |
| if (gen_grpc_gmock) { |
| args += [ "--grpc_out=generate_mock_code=true:${cc_dir}" ] |
| foreach(source, sources) { |
| source = rebase_path(source, proto_in_dir) |
| source = string_replace(source, ".proto", "") |
| outputs += [ "${cc_dir}/${source}_mock.grpc.pb.h" ] |
| } |
| } else { |
| args += [ "--grpc_out=${cc_dir}" ] |
| } |
| grpc_cpp_plugin = "/usr/bin/grpc_cpp_plugin" |
| args += [ |
| "--plugin=protoc-gen-grpc=${grpc_cpp_plugin}", |
| "--cpp_out=${gen_cpp_mode}${cc_dir}", |
| ] |
| foreach(source, sources) { |
| source = rebase_path(source, proto_in_dir) |
| source = string_replace(source, ".proto", "") |
| outputs += [ |
| "${cc_dir}/${source}.grpc.pb.cc", |
| "${cc_dir}/${source}.grpc.pb.h", |
| "${cc_dir}/${source}.pb.cc", |
| "${cc_dir}/${source}.pb.h", |
| ] |
| } |
| } |
| if (!gen_grpc && !gen_python) { |
| args += [ "--cpp_out=${gen_cpp_mode}${cc_dir}" ] |
| foreach(source, sources) { |
| source = rebase_path(source, proto_in_dir) |
| source = string_replace(source, ".proto", "") |
| outputs += [ |
| "${cc_dir}/${source}.pb.cc", |
| "${cc_dir}/${source}.pb.h", |
| ] |
| } |
| } |
| } |
| |
| all_dependent_config_name = "_${target_name}_all_dependent_config" |
| config(all_dependent_config_name) { |
| # Allows for dependents to include protoc-generated header files with relative path from |
| # root_gen_dir i.e. in the form of "${proto_out_dir}/<generated file basename>". |
| include_dirs = [ root_gen_dir ] |
| } |
| |
| static_library(target_name) { |
| forward_variables_from( |
| invoker, |
| [ |
| "defines", |
| "public_configs", |
| "public_deps", |
| "visibility", |
| "proto_out_dir", |
| |
| # TODO(oka): we should not have to use all_dependent_pkg_deps here, because there is no |
| # inherent reason that all users of this target should depend on some external |
| # dependency. Remove this after no user uses it. |
| "all_dependent_pkg_deps", |
| ]) |
| if (defined(invoker.configs)) { |
| configs += invoker.configs |
| } |
| if (defined(invoker.use_pic) && invoker.use_pic) { |
| configs -= [ "//common-mk:pie" ] |
| configs += [ "//common-mk:pic" ] |
| } |
| if (defined(invoker.standalone) && invoker.standalone) { |
| configs -= [ "//common-mk:use_thin_archive" ] |
| configs += [ |
| "//common-mk:nouse_thin_archive", |
| |
| # Generated code. Cannot modify individual symbol attributes there easily. |
| # gnlint: disable=GnLintVisibilityFlags |
| "//common-mk:visibility_default", |
| ] |
| } |
| all_dependent_configs = [ ":${all_dependent_config_name}" ] |
| if (defined(invoker.all_dependent_configs)) { |
| all_dependent_configs += invoker.all_dependent_configs |
| } |
| |
| sources = get_target_outputs(":${action_name}") |
| include_dirs = [ "${root_gen_dir}/${proto_out_dir}" ] |
| deps = [ ":${action_name}" ] |
| if (defined(invoker.deps)) { |
| deps += invoker.deps |
| } |
| |
| cflags_cc = [ |
| # Protobuf 3.7.0 introduced generated code that is sometimes unreachable. |
| "-Wno-unreachable-code", |
| |
| # Protobuf 3.11.4 generates deprecated declarations which lead to warnings |
| # that shouldn't be treated as errors in generated code. |
| "-Wno-deprecated-declarations", |
| ] |
| } |
| } |
| |
| # Compile protocol buffers to Go. |
| # |
| # Parameters: |
| # proto_in_dir |
| # Input directory. |
| # proto_out_dir |
| # Output directory. Relative to gen directory. |
| # sources |
| # The proto file paths. |
| # gen_grpc (optional) |
| # If true, generates Go GRPC. |
| # import_mapping (optional) |
| # List of mapping to convert imports in .proto file to go package names. |
| # The format is "foo/bar.proto=quux/shme". |
| # proto_lib_dirs (optional) |
| # Directories to search for protos a proto file depends on. |
| # proto_in_dir and "${sysroot}/usr/share/proto" are added by default. |
| template("goproto_library") { |
| action(target_name) { |
| forward_variables_from(invoker, |
| [ |
| "proto_out_dir", |
| "sources", |
| ]) |
| |
| # For go, it is necessary to generate the code in one command line, |
| # otherwise file descriptor var name will conflict. |
| # cf) https://github.com/golang/protobuf/issues/109 |
| |
| proto_in_dir = rebase_path(invoker.proto_in_dir) |
| |
| # Build protoc command line to run. |
| script = "//common-mk/file_generator_wrapper.py" |
| proto_lib_dirs = [ |
| proto_in_dir, |
| "${sysroot}/usr/share/proto", |
| ] |
| |
| if (defined(invoker.proto_lib_dirs)) { |
| proto_lib_dirs += rebase_path(invoker.proto_lib_dirs) |
| } |
| |
| go_plugin_parameters = [] |
| |
| if (defined(invoker.gen_grpc) && invoker.gen_grpc) { |
| go_plugin_parameters += [ "plugins=grpc" ] |
| } |
| |
| if (defined(invoker.import_mapping)) { |
| foreach(x, invoker.import_mapping) { |
| go_plugin_parameters += [ "M" + x ] |
| } |
| } |
| |
| go_out_prefix = string_join(",", go_plugin_parameters) |
| |
| args = [ "protoc" ] |
| |
| foreach(x, proto_lib_dirs) { |
| args += [ |
| "--proto_path", |
| x, |
| ] |
| } |
| |
| args += [ |
| "--go_out", |
| |
| # go_out_prefix can be empty, so we can always add a colon here. |
| "${go_out_prefix}:${root_gen_dir}/${proto_out_dir}", |
| ] |
| foreach(source, sources) { |
| args += [ rebase_path(source) ] |
| } |
| |
| # Output dependency. |
| outputs = [] |
| foreach(source, invoker.sources) { |
| name = get_path_info(source, "name") |
| outputs += [ "${root_gen_dir}/${proto_out_dir}/${name}.pb.go" ] |
| } |
| } |
| } |