third_party.pigweed.src/pw_protobuf_compiler/proto.gni
Alexei Frolov c15a98852f
Download external Go dependencies in build
This change updates the Go GN integration to download external
dependencies for Go packages before running "go build". These
dependencies are listed in the pw_go_package template using build
metadata and collected to a "go get" invocation.

To support this, the pw_exec template is expanded to allow setting
positional arguments from a file.

Change-Id: If4f6c71f037b35bb041984da9982a1629d1d36b0
2019-12-26 10:39:48 -08:00

193 lines
6.1 KiB
Plaintext

# Copyright 2019 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
import("$dir_pw_build/python_script.gni")
# Python script that invokes protoc.
_gen_script_path =
"$dir_pw_protobuf_compiler/py/pw_protobuf_compiler/generate_protos.py"
# Generates C++ code for proto files, creating a source_set of the generated
# files. This is internal and should not be used outside of this file. Use
# pw_proto_library instead.
#
# Args:
# protos: List of input .proto files.
template("_pw_cc_proto_library") {
_proto_gen_dir = "$root_gen_dir/protos"
_outputs = process_file_template(
invoker.protos,
"$_proto_gen_dir/{{source_root_relative_dir}}/{{source_name_part}}.pb.h")
_gen_target = "${target_name}_gen"
pw_python_script(_gen_target) {
script = _gen_script_path
args = [
"--language",
"cc",
"--module-path",
"//",
"--out-dir",
_proto_gen_dir,
] + get_path_info(invoker.protos, "abspath")
inputs = invoker.protos
outputs = _outputs
if (defined(invoker.protoc_deps)) {
deps = invoker.protoc_deps
}
}
# For C++ proto files, the generated proto directory is added as an include
# path for the code. This requires using "all_dependent_configs" to force the
# include on any code that transitively depends on the generated protos.
_include_root = rebase_path(get_path_info(".", "abspath"), "//")
_include_config_target = "${target_name}_includes"
config(_include_config_target) {
include_dirs = [ "$_proto_gen_dir/$_include_root" ]
}
# Create a library with the generated source files.
# TODO(frolv): This currently only supports pw_protobuf, which is header-only.
# Figure out how to support .cc files.
source_set(target_name) {
all_dependent_configs = [ ":$_include_config_target" ]
deps = [ ":$_gen_target" ] + invoker.deps
sources = get_target_outputs(":$_gen_target")
}
}
# Generates Go code for proto files, listing the proto output directory in the
# metadata variable GOPATH. Internal use only.
#
# Args:
# protos: List of input .proto files.
template("_pw_go_proto_library") {
_proto_gopath = "$root_gen_dir/go"
_proto_gen_dir = "$_proto_gopath/src"
_rebased_gopath = rebase_path(_proto_gopath)
pw_python_script(target_name) {
metadata = {
gopath = [ "GOPATH+=$_rebased_gopath" ]
external_deps = [
"github.com/golang/protobuf/proto",
"google.golang.org/grpc",
]
}
script = _gen_script_path
args = [
"--language",
"go",
"--module-path",
"//",
"--out-dir",
_proto_gen_dir,
] + get_path_info(invoker.protos, "abspath")
inputs = invoker.protos
deps = invoker.deps
stamp = true
}
}
# Generates protobuf code from .proto definitions for various languages.
#
# The languages to generate are defined in the pw_protobuf_langs build variable.
# Each listed language creates a generated code target called
#
# <target_name>_<language>
#
# For example, with the following definitions:
#
# pw_protobuf_langs = [ "cc", "py" ]
#
# pw_proto_library("my_protos") {
# sources = [ "foo.proto" ]
# }
#
# Two build targets will be created for the declared "my_protos" target.
#
# "my_protos_cc" <-- C++ source_set containing generated proto code
# "my_protos_py" <-- Python module containing generated proto code
#
# Args:
# sources: List of input .proto files.
# deps: List of other pw_proto_library dependencies.
#
# TODO(frolv): Provide a way to set the protoc plugin for different languages.
template("pw_proto_library") {
assert(defined(invoker.sources) && invoker.sources != [],
"pw_proto_codegen requires .proto source files")
foreach(lang, pw_protobuf_langs) {
if (defined(invoker.deps)) {
_lang_deps = process_file_template(invoker.deps, "{{source}}_${lang}")
} else {
_lang_deps = []
}
_lang_target = "${target_name}_${lang}"
if (lang == "cc") {
_pw_cc_proto_library(_lang_target) {
protos = invoker.sources
deps = _lang_deps
# List the pw_protobuf plugin's files as a dependency to recompile
# generated code if they are modified.
#
# TODO(frolv): This check is currently true as pw_protobuf is the
# only supported plugin. It should be updated to support other proto
# libraries such as nanopb.
if (true) {
protoc_deps = [ "$dir_pw_protobuf:codegen_protoc_plugin" ]
}
}
} else if (lang == "go") {
_pw_go_proto_library(_lang_target) {
protos = invoker.sources
deps = _lang_deps
}
} else {
assert(false,
string_join(
" ",
[
"pw_proto_codegen doesn't know how to generate code for",
"language '$lang'. Please add support if you require it.",
]))
}
}
# If the user attempts to use the target directly instead of one of the
# language targets, run a script which prints a nice error message.
pw_python_script(target_name) {
script = string_join("/",
[
dir_pw_protobuf_compiler,
"py",
"pw_protobuf_compiler",
"proto_target_invalid.py",
])
args = [
"--target",
target_name,
"--dir",
get_path_info(".", "abspath"),
"--root",
"//",
] + pw_protobuf_langs
stamp = true
}
}