blob: 10d3c624f5c0bf9a24bb7c07e643f6be90948aa5 [file] [log] [blame]
Colin Cross0c461f12016-10-20 16:11:43 -07001// Copyright 2016 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17import (
Colin Cross0c461f12016-10-20 16:11:43 -070018 "github.com/google/blueprint"
Colin Cross5ff51b52017-05-02 13:34:32 -070019 "github.com/google/blueprint/proptools"
Colin Cross0c461f12016-10-20 16:11:43 -070020
21 "android/soong/android"
22)
23
24func init() {
25 pctx.HostBinToolVariable("protocCmd", "aprotoc")
26}
27
28var (
29 proto = pctx.AndroidStaticRule("protoc",
30 blueprint.RuleParams{
31 Command: "$protocCmd --cpp_out=$outDir $protoFlags $in",
32 CommandDeps: []string{"$protocCmd"},
33 Description: "protoc $out",
34 }, "protoFlags", "outDir")
35)
36
37// TODO(ccross): protos are often used to communicate between multiple modules. If the only
38// way to convert a proto to source is to reference it as a source file, and external modules cannot
39// reference source files in other modules, then every module that owns a proto file will need to
40// export a library for every type of external user (lite vs. full, c vs. c++ vs. java). It would
41// be better to support a proto module type that exported a proto file along with some include dirs,
42// and then external modules could depend on the proto module but use their own settings to
43// generate the source.
44
45func genProto(ctx android.ModuleContext, protoFile android.Path,
46 protoFlags string) (android.ModuleGenPath, android.ModuleGenPath) {
47
Dan Willemsen21ec4902016-11-02 20:43:13 -070048 outFile := android.GenPathWithExt(ctx, "proto", protoFile, "pb.cc")
49 headerFile := android.GenPathWithExt(ctx, "proto", protoFile, "pb.h")
Colin Cross0c461f12016-10-20 16:11:43 -070050 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
51 Rule: proto,
52 Outputs: android.WritablePaths{outFile, headerFile},
53 Input: protoFile,
54 Args: map[string]string{
Dan Willemsen21ec4902016-11-02 20:43:13 -070055 "outDir": protoDir(ctx).String(),
Colin Cross0c461f12016-10-20 16:11:43 -070056 "protoFlags": protoFlags,
57 },
58 })
59
60 return outFile, headerFile
61}
62
63// protoDir returns the module's "gen/proto" directory
64func protoDir(ctx android.ModuleContext) android.ModuleGenPath {
65 return android.PathForModuleGen(ctx, "proto")
66}
67
68// protoSubDir returns the module's "gen/proto/path/to/module" directory
69func protoSubDir(ctx android.ModuleContext) android.ModuleGenPath {
70 return android.PathForModuleGen(ctx, "proto", ctx.ModuleDir())
71}
72
73type ProtoProperties struct {
74 Proto struct {
75 // Proto generator type (full, lite)
Colin Cross5ff51b52017-05-02 13:34:32 -070076 Type *string `android:"arch_variant"`
77
Colin Cross0c461f12016-10-20 16:11:43 -070078 // Link statically against the protobuf runtime
Colin Cross5ff51b52017-05-02 13:34:32 -070079 Static bool `android:"arch_variant"`
80
81 // list of directories that will be added to the protoc include paths.
82 Include_dirs []string
83
84 // list of directories relative to the Android.bp file that will
85 // be added to the protoc include paths.
86 Local_include_dirs []string
87 } `android:"arch_variant"`
Colin Cross0c461f12016-10-20 16:11:43 -070088}
89
90func protoDeps(ctx BaseModuleContext, deps Deps, p *ProtoProperties) Deps {
91 var lib string
92 var static bool
93
Colin Cross5ff51b52017-05-02 13:34:32 -070094 switch proptools.String(p.Proto.Type) {
Colin Cross0c461f12016-10-20 16:11:43 -070095 case "full":
96 if ctx.sdk() {
97 lib = "libprotobuf-cpp-full-ndk"
98 static = true
99 } else {
100 lib = "libprotobuf-cpp-full"
101 }
102 case "lite", "":
103 if ctx.sdk() {
104 lib = "libprotobuf-cpp-lite-ndk"
105 static = true
106 } else {
107 lib = "libprotobuf-cpp-lite"
108 if p.Proto.Static {
109 static = true
110 }
111 }
112 default:
Colin Cross5ff51b52017-05-02 13:34:32 -0700113 ctx.PropertyErrorf("proto.type", "unknown proto type %q",
114 proptools.String(p.Proto.Type))
Colin Cross0c461f12016-10-20 16:11:43 -0700115 }
116
117 if static {
118 deps.StaticLibs = append(deps.StaticLibs, lib)
119 deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, lib)
120 } else {
121 deps.SharedLibs = append(deps.SharedLibs, lib)
122 deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, lib)
123 }
124
125 return deps
126}
127
128func protoFlags(ctx ModuleContext, flags Flags, p *ProtoProperties) Flags {
129 flags.CFlags = append(flags.CFlags, "-DGOOGLE_PROTOBUF_NO_RTTI")
130 flags.GlobalFlags = append(flags.GlobalFlags,
131 "-I"+protoSubDir(ctx).String(),
132 "-I"+protoDir(ctx).String(),
133 )
134
Colin Cross5ff51b52017-05-02 13:34:32 -0700135 if len(p.Proto.Local_include_dirs) > 0 {
136 localProtoIncludeDirs := android.PathsForModuleSrc(ctx, p.Proto.Local_include_dirs)
137 flags.protoFlags = append(flags.protoFlags, includeDirsToFlags(localProtoIncludeDirs))
138 }
139 if len(p.Proto.Include_dirs) > 0 {
140 rootProtoIncludeDirs := android.PathsForSource(ctx, p.Proto.Include_dirs)
141 flags.protoFlags = append(flags.protoFlags, includeDirsToFlags(rootProtoIncludeDirs))
142 }
143
144 flags.protoFlags = append(flags.protoFlags, "-I .")
145
Colin Cross0c461f12016-10-20 16:11:43 -0700146 return flags
147}