summaryrefslogtreecommitdiffstats
path: root/third_party/protobuf/proto_library.gni
blob: 62efd7824d7c587fca7bcca9003b7c8975a32de4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# 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_in_dir (optional)
#       The path to the directory containing the .proto files. If left out, it
#       defaults to '.'.
#
#   proto_out_dir (optional)
#       Specifies the path suffix that output files are generated under.
#       Targets that gyp-depend on my_proto_lib 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.
#
#   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.
#
#   cc_include (optional)
#       String listing an extra include that should be passed.
#       Example: cc_include = "foo/bar.h"
#
# Parameters for compiling the generated code:
#
#   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")

  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

    # TODO(brettw) it would be better if this used the target gen dir.
    if (defined(invoker.proto_out_dir)) {
      proto_out_dir = invoker.proto_out_dir
    } else {
      # This computes the relative path inside the target_gen_dir that
      # we'd put the files in, which maps to the current directory path.
      # We'll insert "protoc_out" at the beginning for compatibility with GYP.
      proto_out_dir = rebase_path(target_gen_dir, root_gen_dir)
    }
    cc_dir = "$root_gen_dir/protoc_out/$proto_out_dir"
    py_dir = "$root_gen_dir/pyproto/$proto_out_dir"

    outputs = [
      "$py_dir/{{source_name_part}}_pb2.py",
      "$cc_dir/{{source_name_part}}.pb.cc",
      "$cc_dir/{{source_name_part}}.pb.h",
    ]

    args = []
    if (defined(invoker.cc_include)) {
      args += [ "--include", invoker.cc_include ]
    }

    args += [
      "--protobuf",
      rebase_path("$cc_dir/{{source_name_part}}.pb.h", root_build_dir),
    ]

    if (defined(invoker.proto_in_dir)) {
      proto_in_dir = invoker.proto_in_dir
    } else {
      # Extract the current source dir.
      proto_in_dir = get_label_info(":$target_name", "dir")
    }
    args += [
      "--proto-in-dir",
      rebase_path(proto_in_dir, root_build_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 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 += [
      "--cpp_out", cc_generator_options + rebase_path(cc_dir, root_build_dir),
      "--python_out", rebase_path(py_dir, root_build_dir),
    ]

    deps = [ protoc_label ]
  }

  source_set(target_name) {
    if (defined(invoker.visibility)) {
      visibility = invoker.visibility
    }

    sources = get_target_outputs(":$action_name")

    if (defined(invoker.defines)) {
      defines = invoker.defines
    }
    if (defined(invoker.extra_configs)) {
      configs += invoker.extra_configs
    }

    direct_dependent_configs = [ "//third_party/protobuf:using_proto" ]

    deps = [
      ":$action_name",
      "//third_party/protobuf:protobuf_lite",
    ]

    # The generated headers reference headers within protobuf_lite, so
    # dependencies must be able to find those headers too.
    forward_dependent_configs_from = [ "//third_party/protobuf:protobuf_lite" ]
  }
}