blob: f3410bc2b1fbf4e84d54d4f133f888a52bcc3a07 [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 (
Dan Willemsenab9f4262018-02-14 13:58:34 -080018 "github.com/google/blueprint/pathtools"
Liz Kammer12615db2021-09-28 09:19:17 -040019 "github.com/google/blueprint/proptools"
Colin Cross0c461f12016-10-20 16:11:43 -070020
21 "android/soong/android"
Liz Kammer12615db2021-09-28 09:19:17 -040022 "android/soong/bazel"
23)
24
25const (
26 protoTypeDefault = "lite"
Colin Cross0c461f12016-10-20 16:11:43 -070027)
28
Colin Cross6af17aa2017-09-20 12:59:05 -070029// genProto creates a rule to convert a .proto file to generated .pb.cc and .pb.h files and returns
30// the paths to the generated files.
Colin Cross19878da2019-03-28 14:45:07 -070031func genProto(ctx android.ModuleContext, protoFile android.Path, flags builderFlags) (cc, header android.WritablePath) {
32 var ccFile, headerFile android.ModuleGenPath
Dan Willemsen60e62f02018-11-16 21:05:32 -080033
34 srcSuffix := ".cc"
35 if flags.protoC {
36 srcSuffix = ".c"
37 }
Colin Cross6af17aa2017-09-20 12:59:05 -070038
Colin Cross19878da2019-03-28 14:45:07 -070039 if flags.proto.CanonicalPathFromRoot {
Dan Willemsen60e62f02018-11-16 21:05:32 -080040 ccFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb"+srcSuffix)
Dan Willemsenab9f4262018-02-14 13:58:34 -080041 headerFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb.h")
42 } else {
43 rel := protoFile.Rel()
Dan Willemsen60e62f02018-11-16 21:05:32 -080044 ccFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb"+srcSuffix))
Dan Willemsenab9f4262018-02-14 13:58:34 -080045 headerFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb.h"))
46 }
Colin Cross6af17aa2017-09-20 12:59:05 -070047
Colin Crossfe17f6f2019-03-28 19:30:56 -070048 protoDeps := flags.proto.Deps
Dan Willemsen60e62f02018-11-16 21:05:32 -080049 if flags.protoOptionsFile {
50 optionsFile := pathtools.ReplaceExtension(protoFile.String(), "options")
Colin Cross19878da2019-03-28 14:45:07 -070051 optionsPath := android.PathForSource(ctx, optionsFile)
52 protoDeps = append(android.Paths{optionsPath}, protoDeps...)
Dan Willemsen60e62f02018-11-16 21:05:32 -080053 }
54
Colin Cross19878da2019-03-28 14:45:07 -070055 outDir := flags.proto.Dir
56 depFile := ccFile.ReplaceExtension(ctx, "d")
57 outputs := android.WritablePaths{ccFile, headerFile}
58
Colin Crossf1a035e2020-11-16 17:32:30 -080059 rule := android.NewRuleBuilder(pctx, ctx)
Colin Cross19878da2019-03-28 14:45:07 -070060
Colin Crossf1a035e2020-11-16 17:32:30 -080061 android.ProtoRule(rule, protoFile, flags.proto, protoDeps, outDir, depFile, outputs)
Colin Cross19878da2019-03-28 14:45:07 -070062
Colin Crossf1a035e2020-11-16 17:32:30 -080063 rule.Build("protoc_"+protoFile.Rel(), "protoc "+protoFile.Rel())
Colin Cross6af17aa2017-09-20 12:59:05 -070064
65 return ccFile, headerFile
66}
67
Colin Crossfe17f6f2019-03-28 19:30:56 -070068func protoDeps(ctx DepsContext, deps Deps, p *android.ProtoProperties, static bool) Deps {
Colin Cross0c461f12016-10-20 16:11:43 -070069 var lib string
Colin Cross0c461f12016-10-20 16:11:43 -070070
Colin Crossfe17f6f2019-03-28 19:30:56 -070071 if String(p.Proto.Plugin) == "" {
Liz Kammer12615db2021-09-28 09:19:17 -040072 switch proptools.StringDefault(p.Proto.Type, protoTypeDefault) {
Colin Crossfe17f6f2019-03-28 19:30:56 -070073 case "full":
74 if ctx.useSdk() {
75 lib = "libprotobuf-cpp-full-ndk"
76 static = true
77 } else {
78 lib = "libprotobuf-cpp-full"
79 }
Liz Kammer12615db2021-09-28 09:19:17 -040080 case "lite":
Colin Crossfe17f6f2019-03-28 19:30:56 -070081 if ctx.useSdk() {
82 lib = "libprotobuf-cpp-lite-ndk"
83 static = true
84 } else {
85 lib = "libprotobuf-cpp-lite"
86 }
87 case "nanopb-c":
88 lib = "libprotobuf-c-nano"
Colin Cross0c461f12016-10-20 16:11:43 -070089 static = true
Colin Crossfe17f6f2019-03-28 19:30:56 -070090 case "nanopb-c-enable_malloc":
91 lib = "libprotobuf-c-nano-enable_malloc"
Colin Cross0c461f12016-10-20 16:11:43 -070092 static = true
Colin Crossfe17f6f2019-03-28 19:30:56 -070093 case "nanopb-c-16bit":
94 lib = "libprotobuf-c-nano-16bit"
95 static = true
96 case "nanopb-c-enable_malloc-16bit":
97 lib = "libprotobuf-c-nano-enable_malloc-16bit"
98 static = true
99 case "nanopb-c-32bit":
100 lib = "libprotobuf-c-nano-32bit"
101 static = true
102 case "nanopb-c-enable_malloc-32bit":
103 lib = "libprotobuf-c-nano-enable_malloc-32bit"
104 static = true
105 default:
106 ctx.PropertyErrorf("proto.type", "unknown proto type %q",
107 String(p.Proto.Type))
Colin Cross0c461f12016-10-20 16:11:43 -0700108 }
Colin Cross0c461f12016-10-20 16:11:43 -0700109
Colin Crossfe17f6f2019-03-28 19:30:56 -0700110 if static {
111 deps.StaticLibs = append(deps.StaticLibs, lib)
112 deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, lib)
113 } else {
114 deps.SharedLibs = append(deps.SharedLibs, lib)
115 deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, lib)
116 }
Colin Cross0c461f12016-10-20 16:11:43 -0700117 }
118
119 return deps
120}
121
Colin Cross38f794e2017-09-07 10:53:07 -0700122func protoFlags(ctx ModuleContext, flags Flags, p *android.ProtoProperties) Flags {
Colin Cross4af21ed2019-11-04 09:37:55 -0800123 flags.Local.CFlags = append(flags.Local.CFlags, "-DGOOGLE_PROTOBUF_NO_RTTI")
Dan Willemsenab9f4262018-02-14 13:58:34 -0800124
Colin Cross19878da2019-03-28 14:45:07 -0700125 flags.proto = android.GetProtoFlags(ctx, p)
126 if flags.proto.CanonicalPathFromRoot {
Colin Cross4af21ed2019-11-04 09:37:55 -0800127 flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+flags.proto.SubDir.String())
Dan Willemsenab9f4262018-02-14 13:58:34 -0800128 }
Colin Cross4af21ed2019-11-04 09:37:55 -0800129 flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+flags.proto.Dir.String())
Colin Cross5ff51b52017-05-02 13:34:32 -0700130
Colin Crossfe17f6f2019-03-28 19:30:56 -0700131 if String(p.Proto.Plugin) == "" {
132 var plugin string
Dan Willemsen60e62f02018-11-16 21:05:32 -0800133
Colin Crossfe17f6f2019-03-28 19:30:56 -0700134 switch String(p.Proto.Type) {
135 case "nanopb-c", "nanopb-c-enable_malloc", "nanopb-c-16bit", "nanopb-c-enable_malloc-16bit", "nanopb-c-32bit", "nanopb-c-enable_malloc-32bit":
136 flags.protoC = true
137 flags.protoOptionsFile = true
138 flags.proto.OutTypeFlag = "--nanopb_out"
Ulf Adams82fd89b2020-11-25 22:37:22 +0100139 // Disable nanopb timestamps to support remote caching.
140 flags.proto.OutParams = append(flags.proto.OutParams, "-T")
Colin Crossfe17f6f2019-03-28 19:30:56 -0700141 plugin = "protoc-gen-nanopb"
142 case "full":
143 flags.proto.OutTypeFlag = "--cpp_out"
144 case "lite":
145 flags.proto.OutTypeFlag = "--cpp_out"
146 flags.proto.OutParams = append(flags.proto.OutParams, "lite")
147 case "":
148 // TODO(b/119714316): this should be equivalent to "lite" in
149 // order to match protoDeps, but some modules are depending on
150 // this behavior
151 flags.proto.OutTypeFlag = "--cpp_out"
152 default:
153 ctx.PropertyErrorf("proto.type", "unknown proto type %q",
154 String(p.Proto.Type))
155 }
Dan Willemsen60e62f02018-11-16 21:05:32 -0800156
Colin Crossfe17f6f2019-03-28 19:30:56 -0700157 if plugin != "" {
158 path := ctx.Config().HostToolPath(ctx, plugin)
159 flags.proto.Deps = append(flags.proto.Deps, path)
160 flags.proto.Flags = append(flags.proto.Flags, "--plugin="+path.String())
161 }
Joe Onorato09e94ab2017-11-18 18:23:14 -0800162 }
163
Colin Cross0c461f12016-10-20 16:11:43 -0700164 return flags
165}
Liz Kammer12615db2021-09-28 09:19:17 -0400166
167type protoAttributes struct {
168 Deps bazel.LabelListAttribute
169}
170
171type bp2buildProtoDeps struct {
172 wholeStaticLib *bazel.LabelAttribute
173 implementationWholeStaticLib *bazel.LabelAttribute
174 protoDep *bazel.LabelAttribute
175}
176
177func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute) bp2buildProtoDeps {
178 var ret bp2buildProtoDeps
179
180 protoInfo, ok := android.Bp2buildProtoProperties(ctx, m, protoSrcs)
181 if !ok {
182 return ret
183 }
184
185 var depName string
186 typ := proptools.StringDefault(protoInfo.Type, protoTypeDefault)
187 var rule_class string
188 suffix := "_cc_proto"
189 switch typ {
190 case "lite":
191 suffix += "_lite"
192 rule_class = "cc_lite_proto_library"
193 depName = "libprotobuf-cpp-lite"
194 case "full":
195 rule_class = "cc_proto_library"
196 depName = "libprotobuf-cpp-full"
197 default:
198 ctx.PropertyErrorf("proto.type", "cannot handle conversion at this time: %q", typ)
199 }
200
201 dep := android.BazelLabelForModuleDepSingle(ctx, depName)
202 ret.protoDep = &bazel.LabelAttribute{Value: &dep}
203
204 protoLabel := bazel.Label{Label: ":" + protoInfo.Name}
205 var protoAttrs protoAttributes
206 protoAttrs.Deps.SetValue(bazel.LabelList{Includes: []bazel.Label{protoLabel}})
207
208 name := m.Name() + suffix
209
210 ctx.CreateBazelTargetModule(
211 bazel.BazelTargetModuleProperties{
212 Rule_class: rule_class,
213 Bzl_load_location: "//build/bazel/rules:cc_proto.bzl",
214 },
215 android.CommonAttributes{Name: name},
216 &protoAttrs)
217
218 var privateHdrs bool
219 if lib, ok := m.linker.(*libraryDecorator); ok {
220 privateHdrs = !proptools.Bool(lib.Properties.Proto.Export_proto_headers)
221 }
222
223 labelAttr := &bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + name}}
224 if privateHdrs {
225 ret.implementationWholeStaticLib = labelAttr
226 } else {
227 ret.wholeStaticLib = labelAttr
228 }
229
230 return ret
231}