# Copyright 2014 The Chromium 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 a protocol buffer. # # 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. # # 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). # # generate_python (optional, default true) # Generate Python protobuf stubs. # # generate_cc (optional, default true) # Generate C++ protobuf stubs. # # cc_generator_options (optional) # List of extra flags passed to the protocol compiler. If you need to # add an EXPORT macro to a protobuf's C++ header, set the # 'cc_generator_options' variable with the value: # 'dllexport_decl=FOO_EXPORT:' (note trailing colon). # # It is likely you also need to #include a file for the above EXPORT # macro to work (see cc_include) and set # component_build_force_source_set = true. # # generator_plugin (optional) # Name of plugin executable which generates custom cc stubs. # Plugin itself should be dependency of the invoker. # # generator_plugin_suffix (required if generator_plugin set) # Suffix (before extension) for generated .cc and .h files. # # generator_plugin_options (optional) # Extra flags passed to the plugin. See cc_generator_options. # # cc_include (optional) # String listing an extra include that should be passed. # Example: cc_include = "foo/bar.h" # # deps (optional) # Additional dependencies. # # Parameters for compiling the generated code: # # component_build_force_source_set (Default=false) # When set true the generated code will be compiled as a source set in # the component build. This does not affect static builds. If you are # exporting symbols from a component, this is required to prevent those # symbols from being stripped. If you're not using dllexports in # cc_generator_options, it's usually best to leave this false. # # defines (optional) # Defines to supply to the source set that compiles the generated source # code. # # extra_configs (optional) # A list of config labels that will be appended to the configs applying # to the source set. # # Example # proto_library("mylib") { # sources = [ # "foo.proto", # ] # } template("proto_library") { assert(defined(invoker.sources), "Need sources for proto_library") # Don't apply OS-specific sources filtering to the assignments later on. # Platform files should have gotten filtered out in the sources assignment # when this template was invoked. If they weren't, it was on purpose and # 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" ] script = "//tools/protoc_wrapper/protoc_wrapper.py" sources = invoker.sources # 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}}" } out_dir = "$root_gen_dir/" + proto_out_dir rel_out_dir = rebase_path(out_dir, root_build_dir) outputs = [] args = [] if (defined(invoker.cc_include)) { args += [ "--include", invoker.cc_include, "--protobuf", "$rel_out_dir/{{source_name_part}}.pb.h", ] } args += [ "--proto-in-dir", "{{source_dir}}", "--proto-in-file", "{{source_file_part}}", # TODO(brettw) support system protobuf compiler. "--use-system-protobuf=0", ] protoc_label = "//third_party/protobuf:protoc($host_toolchain)" 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), ] 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" ] args += [ "--python_out", rel_py_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 = "" } 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)) { generator_plugin = invoker.generator_plugin 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", ] args += [ "--plugin", "protoc-gen-plugin=./$generator_plugin", "--plugin_out", "$generator_plugin_options$rel_out_dir", # Separated by colon. ] } deps = [ protoc_label, ] # The deps may have steps that have to run before running protobuf. if (defined(invoker.deps)) { deps += invoker.deps } } if (defined(invoker.component_build_force_source_set) && invoker.component_build_force_source_set && is_component_build) { link_target_type = "source_set" } else { link_target_type = "static_library" } target(link_target_type, target_name) { forward_variables_from(invoker, [ "visibility", "defines", ]) sources = get_target_outputs(":$action_name") if (defined(invoker.extra_configs)) { configs += invoker.extra_configs } 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", ] } deps = [ ":$action_name", ] # This will link any libraries in the deps (the use of invoker.deps in the # action won't link it). if (defined(invoker.deps)) { deps += invoker.deps } } }