blob: dd85e6f09a8cceb22a01034fe29c809d39f91fc0 [file] [log] [blame]
Steven Morelandd56e5bb2017-07-18 22:04:16 -07001// Copyright (C) 2017 The Android Open Source Project
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 hidl
16
17import (
18 "strings"
19 "sync"
20
21 "github.com/google/blueprint/proptools"
22
23 "android/soong/android"
24 "android/soong/cc"
25 "android/soong/genrule"
26 "android/soong/java"
27)
28
29var (
30 hidlInterfaceSuffix = "_interface"
31)
32
33func init() {
34 android.RegisterModuleType("hidl_interface", hidlInterfaceFactory)
35}
36
37type hidlInterfaceProperties struct {
38 // Vndk properties for interface library only.
39 cc.VndkProperties
40
Steven Moreland89a9ebb2017-12-04 10:18:00 -080041 // The owner of the module
42 Owner *string
43
Steven Morelandd56e5bb2017-07-18 22:04:16 -070044 // List of .hal files which compose this interface.
45 Srcs []string
46
47 // List of hal interface packages that this library depends on.
48 Interfaces []string
49
50 // Package root for this package, must be a prefix of name
51 Root string
52
53 // List of non-TypeDef types declared in types.hal.
54 Types []string
55
56 // Whether to generate the Java library stubs.
57 // Default: true
58 Gen_java *bool
59
60 // Whether to generate a Java library containing constants
61 // expressed by @export annotations in the hal files.
62 Gen_java_constants bool
63
64 // Don't generate "android.hidl.foo@1.0" C library. Instead
65 // only generate the genrules so that this package can be
66 // included in libhidltransport.
67 Core_interface bool
68}
69
70type hidlInterface struct {
71 android.ModuleBase
72
73 properties hidlInterfaceProperties
74}
75
Steven Morelandd56e5bb2017-07-18 22:04:16 -070076func processSources(mctx android.LoadHookContext, srcs []string) ([]string, []string, bool) {
77 var interfaces []string
78 var types []string // hidl-gen only supports types.hal, but don't assume that here
79
80 hasError := false
81
82 for _, v := range srcs {
83 if !strings.HasSuffix(v, ".hal") {
84 mctx.PropertyErrorf("srcs", "Source must be a .hal file: "+v)
85 hasError = true
86 continue
87 }
88
89 name := strings.TrimSuffix(v, ".hal")
90
91 if strings.HasPrefix(name, "I") {
92 baseName := strings.TrimPrefix(name, "I")
93 interfaces = append(interfaces, baseName)
94 } else {
95 types = append(types, name)
96 }
97 }
98
99 return interfaces, types, !hasError
100}
101
102func processDependencies(mctx android.LoadHookContext, interfaces []string) ([]string, []string, bool) {
103 var dependencies []string
104 var javaDependencies []string
105
106 hasError := false
107
108 for _, v := range interfaces {
109 name, err := parseFqName(v)
110 if err != nil {
111 mctx.PropertyErrorf("interfaces", err.Error())
112 hasError = true
113 continue
114 }
115 dependencies = append(dependencies, name.string())
116 javaDependencies = append(javaDependencies, name.javaName())
117 }
118
119 return dependencies, javaDependencies, !hasError
120}
121
122func getRootList(mctx android.LoadHookContext, interfaces []string) ([]string, bool) {
123 var roots []string
124 hasError := false
125
126 for _, i := range interfaces {
127 interfaceObject := lookupInterface(i)
128 if interfaceObject == nil {
129 mctx.PropertyErrorf("interfaces", "Cannot find interface "+i)
130 hasError = true
131 continue
132 }
133 root := interfaceObject.properties.Root
134 rootObject := lookupPackageRoot(root)
135 if rootObject == nil {
Steven Morelande34b9df2017-11-29 14:40:50 -0800136 mctx.PropertyErrorf("interfaces", `Cannot find package root specification for package `+
137 `root '%s' needed for module '%s'. Either this is a mispelling of the package `+
138 `root, or a new hidl_package_root module needs to be added. For example, you can `+
139 `fix this error by adding the following to <some path>/Android.bp:
140
141hidl_package_root {
142 name: "%s",
143 path: "<some path>",
144}
145
146This corresponds to the "-r%s:<some path>" option that would be passed into hidl-gen.`, root, i, root, root)
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700147 hasError = true
148 continue
149 }
150
151 roots = append(roots, root+":"+rootObject.properties.Path)
152 }
153
154 return android.FirstUniqueStrings(roots), !hasError
155}
156
157func removeCoreDependencies(mctx android.LoadHookContext, dependencies []string) ([]string, bool) {
158 var ret []string
159 hasError := false
160
161 for _, i := range dependencies {
162 interfaceObject := lookupInterface(i)
163 if interfaceObject == nil {
164 mctx.PropertyErrorf("interfaces", "Cannot find interface "+i)
165 hasError = true
166 continue
167 }
168
169 if !interfaceObject.properties.Core_interface {
170 ret = append(ret, i)
171 }
172 }
173
174 return ret, !hasError
175}
176
177func hidlGenCommand(lang string, roots []string, name *fqName) *string {
Steven Moreland394af5c2018-02-09 14:41:46 -0800178 cmd := "$(location hidl-gen) -d $(depfile) -o $(genDir)"
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700179 cmd += " -L" + lang
180 cmd += " " + strings.Join(wrap("-r", roots, ""), " ")
181 cmd += " " + name.string()
182 return &cmd
183}
184
185func hidlInterfaceMutator(mctx android.LoadHookContext, i *hidlInterface) {
186 name, err := parseFqName(i.ModuleBase.Name())
187 if err != nil {
188 mctx.PropertyErrorf("name", err.Error())
189 }
190
191 if !name.inPackage(i.properties.Root) {
192 mctx.PropertyErrorf("root", "Root, "+i.properties.Root+", for "+name.string()+" must be a prefix.")
193 }
194
195 interfaces, types, _ := processSources(mctx, i.properties.Srcs)
196
197 if len(interfaces) == 0 && len(types) == 0 {
198 mctx.PropertyErrorf("srcs", "No sources provided.")
199 }
200
201 dependencies, javaDependencies, _ := processDependencies(mctx, i.properties.Interfaces)
Steven Moreland12ff1262017-11-13 13:35:37 -0800202 roots, _ := getRootList(mctx, append(dependencies, name.string()))
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700203 cppDependencies, _ := removeCoreDependencies(mctx, dependencies)
204
205 if mctx.Failed() {
206 return
207 }
208
209 shouldGenerateLibrary := !i.properties.Core_interface
210 // explicitly true if not specified to give early warning to devs
211 shouldGenerateJava := i.properties.Gen_java == nil || *i.properties.Gen_java
212 shouldGenerateJavaConstants := i.properties.Gen_java_constants
213
214 var libraryIfExists []string
215 if shouldGenerateLibrary {
216 libraryIfExists = []string{name.string()}
217 }
218
219 // TODO(b/69002743): remove filegroups
Pirama Arumuga Nainarf43bb1e2018-04-18 11:34:56 -0700220 mctx.CreateModule(android.ModuleFactoryAdaptor(android.FileGroupFactory), &fileGroupProperties{
Steven Moreland89a9ebb2017-12-04 10:18:00 -0800221 Name: proptools.StringPtr(name.fileGroupName()),
222 Owner: i.properties.Owner,
223 Srcs: i.properties.Srcs,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700224 })
225
226 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProperties{
Steven Moreland394af5c2018-02-09 14:41:46 -0800227 Name: proptools.StringPtr(name.sourcesName()),
228 Depfile: proptools.BoolPtr(true),
229 Owner: i.properties.Owner,
230 Tools: []string{"hidl-gen"},
231 Cmd: hidlGenCommand("c++-sources", roots, name),
232 Srcs: i.properties.Srcs,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700233 Out: concat(wrap(name.dir(), interfaces, "All.cpp"),
234 wrap(name.dir(), types, ".cpp")),
235 })
236 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProperties{
Steven Moreland394af5c2018-02-09 14:41:46 -0800237 Name: proptools.StringPtr(name.headersName()),
238 Depfile: proptools.BoolPtr(true),
239 Owner: i.properties.Owner,
240 Tools: []string{"hidl-gen"},
241 Cmd: hidlGenCommand("c++-headers", roots, name),
242 Srcs: i.properties.Srcs,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700243 Out: concat(wrap(name.dir()+"I", interfaces, ".h"),
244 wrap(name.dir()+"Bs", interfaces, ".h"),
245 wrap(name.dir()+"BnHw", interfaces, ".h"),
246 wrap(name.dir()+"BpHw", interfaces, ".h"),
247 wrap(name.dir()+"IHw", interfaces, ".h"),
248 wrap(name.dir(), types, ".h"),
249 wrap(name.dir()+"hw", types, ".h")),
250 })
251
252 if shouldGenerateLibrary {
253 mctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &ccProperties{
Jerry Zhangf2a93962018-05-30 17:16:05 -0700254 Name: proptools.StringPtr(name.string()),
255 Owner: i.properties.Owner,
256 Recovery_available: proptools.BoolPtr(true),
257 Vendor_available: proptools.BoolPtr(true),
258 Double_loadable: proptools.BoolPtr(isDoubleLoadable(name.string())),
259 Defaults: []string{"hidl-module-defaults"},
260 Generated_sources: []string{name.sourcesName()},
261 Generated_headers: []string{name.headersName()},
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700262 Shared_libs: concat(cppDependencies, []string{
263 "libhidlbase",
264 "libhidltransport",
265 "libhwbinder",
266 "liblog",
267 "libutils",
268 "libcutils",
269 }),
270 Export_shared_lib_headers: concat(cppDependencies, []string{
271 "libhidlbase",
272 "libhidltransport",
273 "libhwbinder",
274 "libutils",
275 }),
276 Export_generated_headers: []string{name.headersName()},
277 }, &i.properties.VndkProperties)
278 }
279
280 if shouldGenerateJava {
281 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProperties{
Steven Moreland394af5c2018-02-09 14:41:46 -0800282 Name: proptools.StringPtr(name.javaSourcesName()),
283 Depfile: proptools.BoolPtr(true),
284 Owner: i.properties.Owner,
285 Tools: []string{"hidl-gen"},
286 Cmd: hidlGenCommand("java", roots, name),
287 Srcs: i.properties.Srcs,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700288 Out: concat(wrap(name.sanitizedDir()+"I", interfaces, ".java"),
289 wrap(name.sanitizedDir(), i.properties.Types, ".java")),
290 })
Colin Crossf5536c32018-06-26 23:29:10 -0700291 mctx.CreateModule(android.ModuleFactoryAdaptor(java.LibraryFactory), &javaProperties{
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700292 Name: proptools.StringPtr(name.javaName()),
Steven Moreland89a9ebb2017-12-04 10:18:00 -0800293 Owner: i.properties.Owner,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700294 Defaults: []string{"hidl-java-module-defaults"},
295 No_framework_libs: proptools.BoolPtr(true),
Colin Crossf5536c32018-06-26 23:29:10 -0700296 Installable: proptools.BoolPtr(true),
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700297 Srcs: []string{":" + name.javaSourcesName()},
Steven Morelandfcfbeaf2018-01-29 19:34:52 -0800298 Static_libs: javaDependencies,
Colin Crossa5050552018-03-29 10:30:03 -0700299
300 // This should ideally be system_current, but android.hidl.base-V1.0-java is used
301 // to build framework, which is used to build system_current. Use core_current
302 // plus hwbinder.stubs, which together form a subset of system_current that does
303 // not depend on framework.
304 Sdk_version: proptools.StringPtr("core_current"),
305 Libs: []string{"hwbinder.stubs"},
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700306 })
307 }
308
309 if shouldGenerateJavaConstants {
310 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProperties{
Steven Moreland394af5c2018-02-09 14:41:46 -0800311 Name: proptools.StringPtr(name.javaConstantsSourcesName()),
312 Depfile: proptools.BoolPtr(true),
313 Owner: i.properties.Owner,
314 Tools: []string{"hidl-gen"},
315 Cmd: hidlGenCommand("java-constants", roots, name),
316 Srcs: i.properties.Srcs,
317 Out: []string{name.sanitizedDir() + "Constants.java"},
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700318 })
Colin Crossf5536c32018-06-26 23:29:10 -0700319 mctx.CreateModule(android.ModuleFactoryAdaptor(java.LibraryFactory), &javaProperties{
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700320 Name: proptools.StringPtr(name.javaConstantsName()),
Steven Moreland89a9ebb2017-12-04 10:18:00 -0800321 Owner: i.properties.Owner,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700322 Defaults: []string{"hidl-java-module-defaults"},
323 No_framework_libs: proptools.BoolPtr(true),
Colin Crossf5536c32018-06-26 23:29:10 -0700324 Installable: proptools.BoolPtr(true),
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700325 Srcs: []string{":" + name.javaConstantsSourcesName()},
326 })
327 }
328
329 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProperties{
Steven Moreland394af5c2018-02-09 14:41:46 -0800330 Name: proptools.StringPtr(name.adapterHelperSourcesName()),
331 Depfile: proptools.BoolPtr(true),
332 Owner: i.properties.Owner,
333 Tools: []string{"hidl-gen"},
334 Cmd: hidlGenCommand("c++-adapter-sources", roots, name),
335 Srcs: i.properties.Srcs,
336 Out: wrap(name.dir()+"A", concat(interfaces, types), ".cpp"),
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700337 })
338 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProperties{
Steven Moreland394af5c2018-02-09 14:41:46 -0800339 Name: proptools.StringPtr(name.adapterHelperHeadersName()),
340 Depfile: proptools.BoolPtr(true),
341 Owner: i.properties.Owner,
342 Tools: []string{"hidl-gen"},
343 Cmd: hidlGenCommand("c++-adapter-headers", roots, name),
344 Srcs: i.properties.Srcs,
345 Out: wrap(name.dir()+"A", concat(interfaces, types), ".h"),
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700346 })
347
348 mctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &ccProperties{
349 Name: proptools.StringPtr(name.adapterHelperName()),
Steven Moreland89a9ebb2017-12-04 10:18:00 -0800350 Owner: i.properties.Owner,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700351 Vendor_available: proptools.BoolPtr(true),
352 Defaults: []string{"hidl-module-defaults"},
353 Generated_sources: []string{name.adapterHelperSourcesName()},
354 Generated_headers: []string{name.adapterHelperHeadersName()},
Steven Moreland10d1ec42017-11-29 13:56:28 -0800355 Shared_libs: []string{
Steven Morelandd90bdaa2018-01-03 11:12:43 -0800356 "libbase",
Steven Morelandffa25282017-11-13 14:23:25 -0800357 "libcutils",
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700358 "libhidlbase",
359 "libhidltransport",
Steven Morelandffa25282017-11-13 14:23:25 -0800360 "libhwbinder",
361 "liblog",
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700362 "libutils",
Steven Morelandffa25282017-11-13 14:23:25 -0800363 },
364 Static_libs: concat([]string{
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700365 "libhidladapter",
366 }, wrap("", dependencies, "-adapter-helper"), cppDependencies, libraryIfExists),
Steven Morelandffa25282017-11-13 14:23:25 -0800367 Export_shared_lib_headers: []string{
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700368 "libhidlbase",
369 "libhidltransport",
Steven Morelandffa25282017-11-13 14:23:25 -0800370 },
371 Export_static_lib_headers: concat([]string{
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700372 "libhidladapter",
373 }, wrap("", dependencies, "-adapter-helper"), cppDependencies, libraryIfExists),
374 Export_generated_headers: []string{name.adapterHelperHeadersName()},
Steven Moreland10d1ec42017-11-29 13:56:28 -0800375 Group_static_libs: proptools.BoolPtr(true),
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700376 })
377 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProperties{
Steven Moreland394af5c2018-02-09 14:41:46 -0800378 Name: proptools.StringPtr(name.adapterSourcesName()),
379 Depfile: proptools.BoolPtr(true),
380 Owner: i.properties.Owner,
381 Tools: []string{"hidl-gen"},
382 Cmd: hidlGenCommand("c++-adapter-main", roots, name),
383 Srcs: i.properties.Srcs,
384 Out: []string{"main.cpp"},
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700385 })
386 mctx.CreateModule(android.ModuleFactoryAdaptor(cc.TestFactory), &ccProperties{
387 Name: proptools.StringPtr(name.adapterName()),
Steven Moreland89a9ebb2017-12-04 10:18:00 -0800388 Owner: i.properties.Owner,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700389 Generated_sources: []string{name.adapterSourcesName()},
Steven Moreland10d1ec42017-11-29 13:56:28 -0800390 Shared_libs: []string{
Steven Morelandd90bdaa2018-01-03 11:12:43 -0800391 "libbase",
Steven Morelandffa25282017-11-13 14:23:25 -0800392 "libcutils",
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700393 "libhidlbase",
394 "libhidltransport",
Steven Morelandffa25282017-11-13 14:23:25 -0800395 "libhwbinder",
396 "liblog",
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700397 "libutils",
Steven Morelandffa25282017-11-13 14:23:25 -0800398 },
399 Static_libs: concat([]string{
400 "libhidladapter",
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700401 name.adapterHelperName(),
Steven Morelandffa25282017-11-13 14:23:25 -0800402 }, wrap("", dependencies, "-adapter-helper"), cppDependencies, libraryIfExists),
403 Group_static_libs: proptools.BoolPtr(true),
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700404 })
405}
406
407func (h *hidlInterface) Name() string {
408 return h.ModuleBase.Name() + hidlInterfaceSuffix
409}
410func (h *hidlInterface) GenerateAndroidBuildActions(ctx android.ModuleContext) {
411}
412func (h *hidlInterface) DepsMutator(ctx android.BottomUpMutatorContext) {
413}
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700414
415var hidlInterfaceMutex sync.Mutex
416var hidlInterfaces []*hidlInterface
417
418func hidlInterfaceFactory() android.Module {
419 i := &hidlInterface{}
420 i.AddProperties(&i.properties)
421 android.InitAndroidModule(i)
422 android.AddLoadHook(i, func(ctx android.LoadHookContext) { hidlInterfaceMutator(ctx, i) })
423
424 hidlInterfaceMutex.Lock()
425 hidlInterfaces = append(hidlInterfaces, i)
426 hidlInterfaceMutex.Unlock()
427
428 return i
429}
430
431func lookupInterface(name string) *hidlInterface {
432 for _, i := range hidlInterfaces {
433 if i.ModuleBase.Name() == name {
434 return i
435 }
436 }
437 return nil
438}
Jiyong Parkd26759f2018-04-09 12:22:18 +0900439
Colin Crossf5536c32018-06-26 23:29:10 -0700440var doubleLoadablePackageNames = []string{
Jiyong Parkd26759f2018-04-09 12:22:18 +0900441 "android.hardware.configstore@",
442 "android.hardware.graphics.allocator@",
443 "android.hardware.graphics.bufferqueue@",
444 "android.hardware.media.omx@",
445 "android.hardware.media@",
446 "android.hardware.neuralnetworks@",
447 "android.hidl.allocator@",
448 "android.hidl.token@",
449}
450
451func isDoubleLoadable(name string) bool {
452 for _, pkgname := range doubleLoadablePackageNames {
453 if strings.HasPrefix(name, pkgname) {
454 return true
455 }
456 }
457 return false
458}