| Index: third_party/protobuf/proto_library.gni
|
| diff --git a/third_party/protobuf/proto_library.gni b/third_party/protobuf/proto_library.gni
|
| index 8e8c130b95be64b66b124d8b0fe612b59ddf9b22..2cc463d7f774836fe7565969927625770e028d57 100644
|
| --- a/third_party/protobuf/proto_library.gni
|
| +++ b/third_party/protobuf/proto_library.gni
|
| @@ -6,15 +6,18 @@
|
| #
|
| # Protobuf parameters:
|
| #
|
| -# proto_out_dir (optional)
|
| -# Specifies the path suffix that output files are generated under. This
|
| -# path will be appended to the root_gen_dir.
|
| +# 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.
|
| #
|
| -# Targets that depend on the proto target will be able to include the
|
| -# resulting proto headers with an include like:
|
| -# #include "dir/for/my_proto_lib/foo.pb.h"
|
| -# If undefined, this defaults to matching the input directory for each
|
| -# .proto file (you should almost always use the default mode).
|
| +# 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.
|
| @@ -32,28 +35,23 @@
|
| # 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_suffix (required if generator_plugin_label set)
|
| +# generator_plugin_suffix (required if |generator_plugin_label| set)
|
| # Suffix (before extension) for generated .cc and .h files.
|
| #
|
| # generator_plugin_options (optional)
|
| # Extra flags passed to the plugin. See cc_generator_options.
|
| #
|
| -# json_converter (optional)
|
| -# The plugin executable to generate JSON converter.
|
| -#
|
| -# cc_include (optional)
|
| -# String listing an extra include that should be passed.
|
| -# Example: cc_include = "foo/bar.h"
|
| -#
|
| # deps (optional)
|
| # Additional dependencies.
|
| #
|
| -# inputs (optional)
|
| -# Additional inputs for dependency checking.
|
| -#
|
| # Parameters for compiling the generated code:
|
| #
|
| # component_build_force_source_set (Default=false)
|
| @@ -71,7 +69,7 @@
|
| # A list of config labels that will be appended to the configs applying
|
| # to the source set.
|
| #
|
| -# Example
|
| +# Example:
|
| # proto_library("mylib") {
|
| # sources = [
|
| # "foo.proto",
|
| @@ -80,6 +78,7 @@
|
|
|
| template("proto_library") {
|
| assert(defined(invoker.sources), "Need sources for proto_library")
|
| + proto_sources = invoker.sources
|
|
|
| # Don't apply OS-specific sources filtering to the assignments later on.
|
| # Platform files should have gotten filtered out in the sources assignment
|
| @@ -87,158 +86,236 @@ template("proto_library") {
|
| # this template shouldn't re-apply the filter.
|
| set_sources_assignment_filter([])
|
|
|
| - action_name = "${target_name}_gen"
|
| - source_set_name = target_name
|
| - action_foreach(action_name) {
|
| - visibility = [ ":$source_set_name" ]
|
| + if (defined(invoker.generate_cc)) {
|
| + generate_cc = invoker.generate_cc
|
| + } else {
|
| + generate_cc = true
|
| + }
|
|
|
| - script = "//tools/protoc_wrapper/protoc_wrapper.py"
|
| + if (defined(invoker.generate_python)) {
|
| + generate_python = invoker.generate_python
|
| + } else {
|
| + generate_python = true
|
| + }
|
| +
|
| + if (defined(invoker.generator_plugin_label)) {
|
| + generator_plugin_label = invoker.generator_plugin_label
|
| + generator_plugin_suffix = invoker.generator_plugin_suffix
|
| + generate_with_plugin = true
|
| +
|
| + # 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.
|
|
|
| - sources = invoker.sources
|
| + plugin_host_label = generator_plugin_label + "($host_toolchain)"
|
| + plugin_path = get_label_info(plugin_host_label, "root_out_dir") + "/" +
|
| + get_label_info(plugin_host_label, "name")
|
| + if (host_os == "win") {
|
| + plugin_path += ".exe"
|
| + }
|
| + plugin_path = rebase_path(plugin_path, root_build_dir)
|
| + } else {
|
| + generate_with_plugin = false
|
| + }
|
| +
|
| + # TODO(kraynov): Remove (in the next CL) merge conflict temporary workaround.
|
| + # This option along with |inputs| would be replaced by the following pattern:
|
| + # source_set("some_python_plugin") {
|
| + # sources = [
|
| + # "bar.py",
|
| + # ...
|
| + # ]
|
| + # }
|
| + # proto_library("some_proto_lib") {
|
| + # generator_plugin_label = ":some_python_plugin"
|
| + # generator_plugin_suffix = ".pb.foo"
|
| + # generator_plugin_script = "bar.py"
|
| + # }
|
| + if (defined(invoker.json_converter)) {
|
| + generator_plugin_suffix = "_json_converter"
|
| + plugin_path = rebase_path(invoker.json_converter)
|
| + invoker.generator_plugin_options = "output_dir=:"
|
| + generate_with_plugin = true
|
| + }
|
| +
|
| + if (defined(invoker.proto_in_dir)) {
|
| + proto_in_dir = invoker.proto_in_dir
|
| + has_nested_dirs = false
|
| + foreach(proto_source, proto_sources) {
|
| + if (get_path_info(proto_source, "dir") != proto_in_dir) {
|
| + has_nested_dirs = true
|
| + }
|
| + }
|
| + } else {
|
| + proto_in_dir = get_path_info(proto_sources[0], "dir")
|
| + has_nested_dirs = false
|
|
|
| - # Compute the output directory, both relative to the source root (for
|
| - # declaring "outputs") and relative to the build dir (for passing to the
|
| - # script).
|
| - if (defined(invoker.proto_out_dir)) {
|
| - proto_out_dir = invoker.proto_out_dir
|
| - } else {
|
| - proto_out_dir = "{{source_root_relative_dir}}"
|
| + # Sanity check, |proto_in_dir| should be defined to allow sub-directories.
|
| + foreach(proto_source, proto_sources) {
|
| + assert(get_path_info(proto_source, "dir") == proto_in_dir,
|
| + "Please define |proto_in_dir| to allow nested directories.")
|
| }
|
| - out_dir = "$root_gen_dir/" + proto_out_dir
|
| - rel_out_dir = rebase_path(out_dir, root_build_dir)
|
| + }
|
|
|
| - outputs = []
|
| + # Avoid absolute path because of the assumption that |proto_in_dir| is
|
| + # relative to the directory of current BUILD.gn file.
|
| + proto_in_dir = rebase_path(proto_in_dir, ".")
|
|
|
| - inputs = []
|
| - if (defined(invoker.inputs)) {
|
| - inputs += invoker.inputs
|
| + if (defined(invoker.proto_out_dir)) {
|
| + proto_out_dir = invoker.proto_out_dir
|
| + } else {
|
| + # Absolute path to the directory of current BUILD.gn file excluding "//".
|
| + proto_out_dir = rebase_path(".", "//")
|
| + if (proto_in_dir != ".") {
|
| + proto_out_dir += "/$proto_in_dir"
|
| }
|
| + }
|
|
|
| - args = []
|
| - if (defined(invoker.cc_include)) {
|
| - args += [
|
| - "--include",
|
| - invoker.cc_include,
|
| - "--protobuf",
|
| - "$rel_out_dir/{{source_name_part}}.pb.h",
|
| + # 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/" + proto_out_dir
|
| + rel_cc_out_dir = rebase_path(cc_out_dir, root_build_dir)
|
| + }
|
| + if (generate_python) {
|
| + py_out_dir = "$root_out_dir/pyproto/" + proto_out_dir
|
| + rel_py_out_dir = rebase_path(py_out_dir, root_build_dir)
|
| + }
|
| +
|
| + protos = rebase_path(invoker.sources, proto_in_dir)
|
| + protogens = []
|
| +
|
| + # List output files.
|
| + foreach(proto, protos) {
|
| + proto_dir = get_path_info(proto, "dir")
|
| + proto_name = get_path_info(proto, "name")
|
| + proto_path = proto_dir + "/" + proto_name
|
| +
|
| + if (generate_cc) {
|
| + protogens += [
|
| + "$cc_out_dir/$proto_path.pb.h",
|
| + "$cc_out_dir/$proto_path.pb.cc",
|
| ]
|
| }
|
| + if (generate_python) {
|
| + protogens += [ "$py_out_dir/${proto_path}_pb2.py" ]
|
| + }
|
| + if (generate_with_plugin) {
|
| + # TODO(kraynov): Remove merge conflict temporary workaround.
|
| + if (defined(invoker.json_converter)) {
|
| + protogens += [ "$cc_out_dir/${proto_path}$generator_plugin_suffix.h" ]
|
| + } else {
|
| + protogens += [
|
| + "$cc_out_dir/${proto_path}$generator_plugin_suffix.h",
|
| + "$cc_out_dir/${proto_path}$generator_plugin_suffix.cc",
|
| + ]
|
| + }
|
| + }
|
| + }
|
|
|
| - args += [
|
| - "--proto-in-dir",
|
| - "{{source_dir}}",
|
| - "--proto-in-file",
|
| - "{{source_file_part}}",
|
| + action_name = "${target_name}_gen"
|
| + source_set_name = target_name
|
|
|
| - # TODO(brettw) support system protobuf compiler.
|
| - "--use-system-protobuf=0",
|
| - ]
|
| + # Generate protobuf stubs.
|
| + action(action_name) {
|
| + visibility = [ ":$source_set_name" ]
|
| + script = "//tools/protoc_wrapper/protoc_wrapper.py"
|
| + sources = proto_sources
|
| + outputs = get_path_info(protogens, "abspath")
|
| + args = protos
|
| +
|
| + if (defined(invoker.inputs)) {
|
| + inputs = invoker.inputs
|
| + }
|
|
|
| protoc_label = "//third_party/protobuf:protoc($host_toolchain)"
|
| + protoc_out_dir = get_label_info(protoc_label, "root_out_dir")
|
| args += [
|
| - "--",
|
| -
|
| - # Prepend with "./" so this will never pick up the system one (normally
|
| - # when not cross-compiling, protoc's output directory will be the same
|
| - # as the build dir, so the relative location will be empty).
|
| - "./" +
|
| - rebase_path(get_label_info(protoc_label, "root_out_dir") + "/protoc",
|
| - root_build_dir),
|
| + # 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_out_dir, root_build_dir) + "/protoc",
|
| + "--proto-in-dir",
|
| + rebase_path(proto_in_dir, root_build_dir),
|
| ]
|
|
|
| - if (!defined(invoker.generate_python) || invoker.generate_python) {
|
| - py_out_dir = "$root_out_dir/pyproto/" + proto_out_dir
|
| - rel_py_out_dir = rebase_path(py_out_dir, root_build_dir)
|
| -
|
| - outputs += [ "$py_out_dir/{{source_name_part}}_pb2.py" ]
|
| + if (generate_cc) {
|
| args += [
|
| - "--python_out",
|
| - rel_py_out_dir,
|
| + "--cc-out-dir",
|
| + rel_cc_out_dir,
|
| ]
|
| - }
|
| -
|
| - if (!defined(invoker.generate_cc) || invoker.generate_cc) {
|
| - # If passed cc_generator_options should end in a colon, which will
|
| - # separate it from the directory when we concatenate them. The proto
|
| - # compiler understands this syntax.
|
| if (defined(invoker.cc_generator_options)) {
|
| - cc_generator_options = invoker.cc_generator_options
|
| - } else {
|
| - cc_generator_options = ""
|
| + args += [
|
| + "--cc-options",
|
| + invoker.cc_generator_options,
|
| + ]
|
| + }
|
| + if (defined(invoker.cc_include)) {
|
| + args += [
|
| + "--include",
|
| + invoker.cc_include,
|
| + ]
|
| }
|
| - outputs += [
|
| - "$out_dir/{{source_name_part}}.pb.cc",
|
| - "$out_dir/{{source_name_part}}.pb.h",
|
| - ]
|
| - args += [
|
| - "--cpp_out",
|
| - "$cc_generator_options$rel_out_dir", # Separated by colon.
|
| - ]
|
| }
|
|
|
| - if (defined(invoker.generator_plugin_label)) {
|
| - generator_plugin_label = invoker.generator_plugin_label
|
| - generator_plugin_suffix = invoker.generator_plugin_suffix
|
| - if (defined(invoker.generator_plugin_options)) {
|
| - generator_plugin_options = invoker.generator_plugin_options
|
| - } else {
|
| - generator_plugin_options = ""
|
| - }
|
| - outputs += [
|
| - "$out_dir/{{source_name_part}}$generator_plugin_suffix.cc",
|
| - "$out_dir/{{source_name_part}}$generator_plugin_suffix.h",
|
| + if (generate_python) {
|
| + args += [
|
| + "--py-out-dir",
|
| + rel_py_out_dir,
|
| ]
|
| + }
|
|
|
| - # 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 = generator_plugin_label + "($host_toolchain)"
|
| - plugin_path = get_label_info(plugin_host_label, "root_out_dir") + "/" +
|
| - get_label_info(plugin_host_label, "name")
|
| - if (host_os == "win") {
|
| - plugin_path += ".exe"
|
| - }
|
| -
|
| - # Need "./" for script to find plugin binary (working dir is not on PATH).
|
| + if (generate_with_plugin) {
|
| args += [
|
| "--plugin",
|
| - "protoc-gen-plugin=./" + rebase_path(plugin_path, root_build_dir),
|
| - "--plugin_out",
|
| - "$generator_plugin_options$rel_out_dir", # Separated by colon.
|
| + plugin_path,
|
| + "--plugin-out-dir",
|
| + rel_cc_out_dir,
|
| ]
|
| + if (defined(invoker.generator_plugin_options)) {
|
| + args += [
|
| + "--plugin-options",
|
| + invoker.generator_plugin_options,
|
| + ]
|
| + }
|
| }
|
|
|
| deps = [
|
| + # System protoc is not used so it's necessary to build a chromium one.
|
| protoc_label,
|
| ]
|
| if (defined(plugin_host_label)) {
|
| + # Action depends on generator plugin but for host toolchain only.
|
| deps += [ plugin_host_label ]
|
| }
|
| -
|
| - # The deps may have steps that have to run before running protobuf.
|
| if (defined(invoker.deps)) {
|
| + # The deps may have steps that have to run before running protoc.
|
| deps += invoker.deps
|
| }
|
| -
|
| - if (defined(invoker.json_converter)) {
|
| - args += [
|
| - "--plugin=protoc-gen-json_converter=" +
|
| - # It is required to use backslash on Windows for .bat files.
|
| - rebase_path(invoker.json_converter),
|
| - "--json_converter_out=output_dir=:$rel_out_dir",
|
| - ]
|
| - inputs += [ invoker.json_converter ]
|
| - outputs += [ "$out_dir/{{source_name_part}}_json_converter.h" ]
|
| - }
|
| }
|
|
|
| + # Option to disable building a library in component build.
|
| if (defined(invoker.component_build_force_source_set) &&
|
| - invoker.component_build_force_source_set && is_component_build) {
|
| + invoker.component_build_force_source_set &&
|
| + is_component_build) {
|
| link_target_type = "source_set"
|
| } else {
|
| link_target_type = "static_library"
|
| }
|
| +
|
| + # 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 (has_nested_dirs) {
|
| + config_name = "${target_name}_config"
|
| + config(config_name) {
|
| + include_dirs = [ cc_out_dir ]
|
| + }
|
| + }
|
| +
|
| + # Build generated protobuf stubs as libary or source set.
|
| target(link_target_type, target_name) {
|
| forward_variables_from(invoker,
|
| [
|
| @@ -254,14 +331,24 @@ template("proto_library") {
|
|
|
| public_configs = [ "//third_party/protobuf:using_proto" ]
|
|
|
| - # If using built-in cc generator the resulting headers reference headers
|
| - # within protobuf_lite, hence dependencies require those headers too.
|
| - # In case of generator plugin such issues should be resolved by invoker.
|
| - if (!defined(invoker.generate_cc) || invoker.generate_cc) {
|
| - public_deps = [
|
| - "//third_party/protobuf:protobuf_lite",
|
| - ]
|
| + if (generate_cc || generate_with_plugin) {
|
| + # Not necessary if all protos are located in the same directory.
|
| + if (has_nested_dirs) {
|
| + # It's not enough to set |include_dirs| for target since public imports
|
| + # expose corresponding includes to header files as well.
|
| + public_configs += [ ":$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) {
|
| + public_deps = [
|
| + "//third_party/protobuf:protobuf_lite",
|
| + ]
|
| + }
|
| }
|
| +
|
| deps = [
|
| ":$action_name",
|
| ]
|
|
|