blob: 91503204f03369798041dfddc95b41da21da7f01 [file] [log] [blame]
# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/dart/dart_library.gni")
# Generates dart bindings for a set of protobuf files
#
# Parameters:
# sources (required)
# List of .proto files to generate bindings for.
#
# deps (optional)
# Other protobuf_dart() targets this depends on.
template("protobuf_dart") {
assert(defined(invoker.sources), "Need a list of .proto sources")
package_name =
exec_script("//build/dart/label_to_package_name.py",
[ get_label_info(target_name, "label_no_toolchain") ],
"trim string")
# This is the generated dart package'source root directory is (where the
# pubspec.yaml, etc. go).
package_root_dir = "$target_gen_dir/$target_name"
# This is where we put the generated files.
package_gen_dir = "$package_root_dir/lib"
# Compute the list of generated files.
proto_output_filepaths = []
foreach(source, invoker.sources) {
# Extract where the generated file will be.
gen_dir = []
gen_dir = process_file_template([ source ], "{{source_gen_dir}}")
# extract the non-extension part of the file.
name_part = []
name_part = process_file_template([ source ], "{{source_name_part}}")
source_prefix = "$package_gen_dir/" +
rebase_path(gen_dir[0], target_gen_dir) + "/${name_part[0]}"
proto_output_filepaths += [
"${source_prefix}.pb.dart",
"${source_prefix}.pbenum.dart",
"${source_prefix}.pbjson.dart",
"${source_prefix}.pbserver.dart",
]
}
protoc_label = "//third_party/protobuf:protoc($host_toolchain)"
protoc_gen_dart_label =
"//topaz/tools/protobuf/protoc_gen_dart($host_toolchain)"
protoc_path = get_label_info(protoc_label, "root_out_dir") + "/protoc"
proto_in_dir = get_path_info(".", "abspath")
proto_gen_target = target_name + "_generate_bindings"
copy_pubspec_target = target_name + "_copy_pubspec"
# We generate a `.protoc_option` suffixed file that contains the options our
# dependent targets would want to pass to their protoc_gen_tool. This file
# contains a mapping from this package's name => path to this package's root.
# This mapping is used by our dependent's bindings generator to translate the
# file-based proto imports pointing to this package into generated
# package-based imports in dart.
write_file(
"$target_gen_dir/${target_name}.protoc_option",
"$package_name|" + rebase_path(get_path_info(".", "abspath"), "//"),
"string")
# This target runs the protoc tool to generate dart sources
action(proto_gen_target) {
visibility = [ ":*" ]
script = "//third_party/protobuf/protoc_wrapper.py"
sources = invoker.sources
inputs = [ protoc_path ] + invoker.sources
outputs = proto_output_filepaths
# dart generator options are supplied to
# //topaz/tools/protobuf/protoc_gen_dart. We gather all of the options that
# our dependencies have outputted (in the write_file() above) and pass those
# along to protoc_gen_dart.
opts = ""
if (defined(invoker.deps)) {
foreach(dep, invoker.deps) {
if (opts != "") {
opts += ";"
}
dep_opt_path = get_label_info(dep, "target_gen_dir") + "/" +
get_label_info(dep, "name") + ".protoc_option"
opts += read_file(dep_opt_path, "trim string")
}
}
args = [
# path to compiler
"--protoc",
rebase_path(protoc_path, root_build_dir),
# the directory the supplied proto paths are in
"--proto-in-dir",
rebase_path(proto_in_dir, root_build_dir),
# extra import dir for .proto files: the root of fuchsia tree
"--import-dir=" + rebase_path("//"),
# the dart bindings generator
"--plugin",
rebase_path(get_label_info(protoc_gen_dart_label, "root_out_dir") +
"/dart-tools/protoc_gen_dart",
root_build_dir),
# output path of where bindings are generated
"--plugin-out-dir",
rebase_path(package_gen_dir),
]
if (opts != "") {
args += [
"--plugin-options",
# package mapping for our target and our dependencies.
"PackagePaths=${opts};${package_name}|" +
rebase_path(proto_in_dir, "//"),
]
}
# the proto files themselves
args += invoker.sources
deps = [
# dart plugin for the protobuf compiler
# protobuf compiler
protoc_gen_dart_label,
protoc_label,
]
}
copy(copy_pubspec_target) {
visibility = [ ":*" ]
sources = [
"//build/dart/empty_pubspec.yaml",
]
outputs = [
"$package_root_dir/pubspec.yaml",
]
}
# Using the dart sources generated from "gen" above, this constructs a dart
# library out of them.
dart_library(target_name) {
forward_variables_from(invoker, [ "deps" ])
disable_analysis = true
package_root = package_root_dir
package_name = package_name
sources = proto_output_filepaths
deps = [
"//third_party/dart-pkg/pub/protobuf",
]
if (defined(invoker.deps)) {
deps += invoker.deps
}
non_dart_deps = [
":$proto_gen_target",
":$copy_pubspec_target",
]
}
}