| # Copyright 2018 The ChromiumOS Authors | |
| # 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. | |
| # install_package | |
| # If true, install the static library and its headers. | |
| template("proto_library") { | |
| forward_variables_from(invoker, [ "install_package" ]) | |
| if (!defined(install_package)) { | |
| install_package = false | |
| } | |
| install_config_targets = [] | |
| if (install_package) { | |
| # Install the static library. Assume target_name does not have a lib prefix | |
| # which means we can't use static_library's install_path, so we have to | |
| # create the install_config target for it ourself. | |
| install_config_name = "_${target_name}-lib-install_config" | |
| install_config(install_config_name) { | |
| sources = [ "${root_build_dir}/lib${invoker.target_name}.a" ] | |
| install_path = "${libdir}" | |
| } | |
| install_config_targets += [ ":${install_config_name}" ] | |
| # Install the generated protobuf headers. | |
| install_config_name = "_${target_name}-headers-install_config" | |
| install_config(install_config_name) { | |
| sources = [] | |
| install_path = "" | |
| foreach(source, invoker.sources) { | |
| # NB: This path logic is synced with the protobuf action below. | |
| source = rebase_path(source, invoker.proto_in_dir) | |
| source = string_replace(source, ".proto", "") | |
| sources += [ "${root_gen_dir}/${invoker.proto_out_dir}/${source}.pb.h" ] | |
| source_install_path = | |
| "/usr/${invoker.proto_out_dir}/" + get_path_info(source, "dir") | |
| if (install_path == "") { | |
| install_path = source_install_path | |
| } else { | |
| # We can only install into one path, so double check all the source | |
| # files implicitly go to that. | |
| assert(install_path == source_install_path) | |
| } | |
| } | |
| } | |
| install_config_targets += [ ":${install_config_name}" ] | |
| } | |
| 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. | |
| "public_deps", | |
| "sources", | |
| ]) | |
| deps = install_config_targets | |
| if (defined(invoker.deps)) { | |
| deps += invoker.deps | |
| } | |
| 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 || use.proto_force_optimize_speed) { | |
| 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", | |
| ] | |
| } else { | |
| assert(!install_package, "install_package requires standalone=true") | |
| } | |
| 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. | |
| # TODO(crbug.com/1082873): Reenable deprecated declarations. | |
| "-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" ] | |
| } | |
| } | |
| } | |
| # Compile protocol buffers to Perfetto protozero (.pbzero.h) headers. | |
| # | |
| # Parameters: | |
| # proto_in_dir | |
| # Input directory. | |
| # proto_out_dir | |
| # Output directory. Relative to gen directory. | |
| # sources | |
| # The proto file paths. | |
| # | |
| template("protozero_library") { | |
| action(target_name) { | |
| forward_variables_from(invoker, | |
| [ | |
| "proto_in_dir", | |
| "proto_out_dir", | |
| "sources", | |
| ]) | |
| 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, | |
| "/usr/include/proto", | |
| ] | |
| args = [ "protoc" ] | |
| foreach(x, proto_lib_dirs) { | |
| args += [ | |
| "--proto_path", | |
| x, | |
| ] | |
| } | |
| args += [ | |
| "--plugin", | |
| "protoc-gen-plugin=/usr/libexec/protozero_plugin", | |
| "--plugin_out=wrapper_namespace=pbzero:${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}.pbzero.h" ] | |
| } | |
| } | |
| } |