1 # Copyright 2014 The Chromium Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 # Compile a protocol buffer. 6 # 7 # Protobuf parameters: 8 # 9 # proto_in_dir (optional) 10 # The path to the directory containing the .proto files. If left out, it 11 # defaults to '.'. 12 # 13 # proto_out_dir (optional) 14 # Specifies the path suffix that output files are generated under. 15 # Targets that gyp-depend on my_proto_lib will be able to include the 16 # resulting proto headers with an include like: 17 # #include "dir/for/my_proto_lib/foo.pb.h" 18 # If undefined, this defaults to matching the input directory. 19 # 20 # cc_generator_options (optional) 21 # List of extra flags passed to the protocol compiler. If you need to 22 # add an EXPORT macro to a protobuf's C++ header, set the 23 # 'cc_generator_options' variable with the value: 24 # 'dllexport_decl=FOO_EXPORT:' (note trailing colon). 25 # 26 # It is likely you also need to #include a file for the above EXPORT 27 # macro to work. See cc_include. 28 # 29 # cc_include (optional) 30 # String listing an extra include that should be passed. 31 # Example: cc_include = "foo/bar.h" 32 # 33 # Parameters for compiling the generated code: 34 # 35 # defines (optional) 36 # Defines to supply to the source set that compiles the generated source 37 # code. 38 # 39 # extra_configs (optional) 40 # A list of config labels that will be appended to the configs applying 41 # to the source set. 42 # 43 # Example: 44 # proto_library("mylib") { 45 # sources = [ 46 # "foo.proto", 47 # ] 48 # } 49 50 template("proto_library") { 51 assert(defined(invoker.sources), "Need sources for proto_library") 52 53 action_name = "${target_name}_gen" 54 source_set_name = target_name 55 action_foreach(action_name) { 56 visibility = ":$source_set_name" 57 58 script = "//tools/protoc_wrapper/protoc_wrapper.py" 59 60 sources = invoker.sources 61 62 # TODO(brettw) it would be better if this used the target gen dir. 63 if (defined(invoker.proto_out_dir)) { 64 proto_out_dir = invoker.proto_out_dir 65 } else { 66 # This computes the relative path inside the target_gen_dir that 67 # we'd put the files in, which maps to the current directory path. 68 # We'll insert "protoc_out" at the beginning for compatibility with GYP. 69 proto_out_dir = rebase_path(target_gen_dir, root_gen_dir) 70 } 71 cc_dir = "$root_gen_dir/protoc_out/$proto_out_dir" 72 py_dir = "$root_gen_dir/pyproto/$proto_out_dir" 73 74 outputs = [ 75 "$py_dir/{{source_name_part}}_pb2.py", 76 "$cc_dir/{{source_name_part}}.pb.cc", 77 "$cc_dir/{{source_name_part}}.pb.h", 78 ] 79 80 args = [] 81 if (defined(invoker.cc_include)) { 82 args += [ "--include", invoker.cc_include ] 83 } 84 85 args += [ 86 "--protobuf", 87 rebase_path("$cc_dir/{{source_name_part}}.pb.h", root_build_dir), 88 ] 89 90 if (defined(invoker.proto_in_dir)) { 91 proto_in_dir = invoker.proto_in_dir 92 } else { 93 # Extract the current source dir. 94 proto_in_dir = get_label_info(":$target_name", "dir") 95 } 96 args += [ 97 "--proto-in-dir", 98 rebase_path(proto_in_dir, root_build_dir), 99 "--proto-in-file", "{{source_file_part}}", 100 # TODO(brettw) support system protobuf compiler. 101 "--use-system-protobuf=0", 102 ] 103 104 protoc_label = "//third_party/protobuf:protoc($host_toolchain)" 105 args += [ 106 "--", 107 # Prepend with "./" so this will never pick up the system one (normally 108 # when not cross-compiling, protoc's output directory will be the same 109 # as the build dir, so the relative location will be empty. 110 "./" + rebase_path(get_label_info(protoc_label, "root_out_dir") + 111 "/protoc", root_build_dir), 112 ] 113 114 # If passed cc_generator_options should end in a colon, which will separate 115 # it from the directory when we concatenate them. The proto compiler 116 # understands this syntax. 117 if (defined(invoker.cc_generator_options)) { 118 cc_generator_options = invoker.cc_generator_options 119 } else { 120 cc_generator_options = "" 121 } 122 args += [ 123 "--cpp_out", cc_generator_options + rebase_path(cc_dir, root_build_dir), 124 "--python_out", rebase_path(py_dir, root_build_dir), 125 ] 126 127 deps = [ protoc_label ] 128 } 129 130 source_set(target_name) { 131 if (defined(invoker.visibility)) { 132 visibility = invoker.visibility 133 } 134 135 sources = get_target_outputs(":$action_name") 136 137 if (defined(invoker.defines)) { 138 defines = invoker.defines 139 } 140 if (defined(invoker.extra_configs)) { 141 configs += invoker.extra_configs 142 } 143 144 direct_dependent_configs = [ "//third_party/protobuf:using_proto" ] 145 146 deps = [ 147 ":$action_name", 148 "//third_party/protobuf:protobuf_lite", 149 ] 150 151 # The generated headers reference headers within protobuf_lite, so 152 # dependencies must be able to find those headers too. 153 forward_dependent_configs_from = [ "//third_party/protobuf:protobuf_lite" ] 154 } 155 } 156