blob: 3d3ca59f7a32fb95b6fc89a950b4f73be38ca4c1 [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 (
18 "strings"
19
20 "github.com/google/blueprint"
21
22 "android/soong/android"
23)
24
25func init() {
26 pctx.HostBinToolVariable("protocCmd", "aprotoc")
27}
28
29var (
30 proto = pctx.AndroidStaticRule("protoc",
31 blueprint.RuleParams{
32 Command: "$protocCmd --cpp_out=$outDir $protoFlags $in",
33 CommandDeps: []string{"$protocCmd"},
34 Description: "protoc $out",
35 }, "protoFlags", "outDir")
36)
37
38// TODO(ccross): protos are often used to communicate between multiple modules. If the only
39// way to convert a proto to source is to reference it as a source file, and external modules cannot
40// reference source files in other modules, then every module that owns a proto file will need to
41// export a library for every type of external user (lite vs. full, c vs. c++ vs. java). It would
42// be better to support a proto module type that exported a proto file along with some include dirs,
43// and then external modules could depend on the proto module but use their own settings to
44// generate the source.
45
46func genProto(ctx android.ModuleContext, protoFile android.Path,
47 protoFlags string) (android.ModuleGenPath, android.ModuleGenPath) {
48
49 outDir := android.PathForModuleGen(ctx, "proto")
50 baseName := strings.TrimSuffix(protoFile.Base(), protoFile.Ext())
51
52 outFile := android.PathForModuleGen(ctx, "proto", ctx.ModuleDir(), baseName+".pb.cc")
53 headerFile := android.PathForModuleGen(ctx, "proto", ctx.ModuleDir(), baseName+".pb.h")
54 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
55 Rule: proto,
56 Outputs: android.WritablePaths{outFile, headerFile},
57 Input: protoFile,
58 Args: map[string]string{
59 "outDir": outDir.String(),
60 "protoFlags": protoFlags,
61 },
62 })
63
64 return outFile, headerFile
65}
66
67// protoDir returns the module's "gen/proto" directory
68func protoDir(ctx android.ModuleContext) android.ModuleGenPath {
69 return android.PathForModuleGen(ctx, "proto")
70}
71
72// protoSubDir returns the module's "gen/proto/path/to/module" directory
73func protoSubDir(ctx android.ModuleContext) android.ModuleGenPath {
74 return android.PathForModuleGen(ctx, "proto", ctx.ModuleDir())
75}
76
77type ProtoProperties struct {
78 Proto struct {
79 // Proto generator type (full, lite)
80 Type string
81 // Link statically against the protobuf runtime
82 Static bool
83 }
84}
85
86func protoDeps(ctx BaseModuleContext, deps Deps, p *ProtoProperties) Deps {
87 var lib string
88 var static bool
89
90 switch p.Proto.Type {
91 case "full":
92 if ctx.sdk() {
93 lib = "libprotobuf-cpp-full-ndk"
94 static = true
95 } else {
96 lib = "libprotobuf-cpp-full"
97 }
98 case "lite", "":
99 if ctx.sdk() {
100 lib = "libprotobuf-cpp-lite-ndk"
101 static = true
102 } else {
103 lib = "libprotobuf-cpp-lite"
104 if p.Proto.Static {
105 static = true
106 }
107 }
108 default:
109 ctx.PropertyErrorf("proto.type", "unknown proto type %q", p.Proto.Type)
110 }
111
112 if static {
113 deps.StaticLibs = append(deps.StaticLibs, lib)
114 deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, lib)
115 } else {
116 deps.SharedLibs = append(deps.SharedLibs, lib)
117 deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, lib)
118 }
119
120 return deps
121}
122
123func protoFlags(ctx ModuleContext, flags Flags, p *ProtoProperties) Flags {
124 flags.CFlags = append(flags.CFlags, "-DGOOGLE_PROTOBUF_NO_RTTI")
125 flags.GlobalFlags = append(flags.GlobalFlags,
126 "-I"+protoSubDir(ctx).String(),
127 "-I"+protoDir(ctx).String(),
128 )
129
130 return flags
131}