blob: 58812585b70ffbb46d20f554908fe811dfeb2534 [file] [log] [blame]
Jeongik Chada36d5a2021-01-20 00:43:34 +09001// Copyright (C) 2021 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 aidl
16
17import (
18 "android/soong/android"
19 "android/soong/cc"
20 "android/soong/java"
21 "android/soong/rust"
22
23 "path/filepath"
Jeongik Chada36d5a2021-01-20 00:43:34 +090024 "strings"
25
26 "github.com/google/blueprint/proptools"
27)
28
Jeongik Cha52e98022021-01-20 18:37:20 +090029func addLibrary(mctx android.LoadHookContext, i *aidlInterface, version string, lang string) string {
30 if lang == langJava {
31 return addJavaLibrary(mctx, i, version)
32 } else if lang == langRust {
33 return addRustLibrary(mctx, i, version)
34 }
35 return addCppLibrary(mctx, i, version, lang)
36}
37
38func addCppLibrary(mctx android.LoadHookContext, i *aidlInterface, version string, lang string) string {
39 cppSourceGen := i.versionedName(version) + "-" + lang + "-source"
40 cppModuleGen := i.versionedName(version) + "-" + lang
41
Jeongik Chada36d5a2021-01-20 00:43:34 +090042 srcs, aidlRoot := i.srcsForVersion(mctx, version)
43 if len(srcs) == 0 {
44 // This can happen when the version is about to be frozen; the version
45 // directory is created but API dump hasn't been copied there.
46 // Don't create a library for the yet-to-be-frozen version.
47 return ""
48 }
49
50 var overrideVndkProperties cc.VndkProperties
51
Jeongik Cha52e98022021-01-20 18:37:20 +090052 if !i.isModuleForVndk(version) {
Jeongik Chada36d5a2021-01-20 00:43:34 +090053 // We only want the VNDK to include the latest interface. For interfaces in
54 // development, they will be frozen, so we put their latest version in the
55 // VNDK. For interfaces which are already frozen, we put their latest version
56 // in the VNDK, and when that version is frozen, the version in the VNDK can
57 // be updated. Otherwise, we remove this library from the VNDK, to avoid adding
58 // multiple versions of the same library to the VNDK.
59 overrideVndkProperties.Vndk.Enabled = proptools.BoolPtr(false)
60 overrideVndkProperties.Vndk.Support_system_process = proptools.BoolPtr(false)
61 }
62
63 var commonProperties *CommonNativeBackendProperties
64 if lang == langCpp {
65 commonProperties = &i.properties.Backend.Cpp.CommonNativeBackendProperties
66 } else if lang == langNdk || lang == langNdkPlatform {
67 commonProperties = &i.properties.Backend.Ndk.CommonNativeBackendProperties
68 }
69
70 genLog := proptools.Bool(commonProperties.Gen_log)
71 genTrace := proptools.Bool(i.properties.Gen_trace)
72
73 mctx.CreateModule(aidlGenFactory, &nameProperties{
74 Name: proptools.StringPtr(cppSourceGen),
75 }, &aidlGenProperties{
Jeongik Chaa01447d2021-03-17 17:43:12 +090076 Srcs: srcs,
77 AidlRoot: aidlRoot,
Jooyung Han60699b52021-05-26 22:20:42 +090078 ImportsWithoutVersion: i.properties.ImportsWithoutVersion,
Jeongik Chaa01447d2021-03-17 17:43:12 +090079 Stability: i.properties.Stability,
80 Lang: lang,
81 BaseName: i.ModuleBase.Name(),
82 GenLog: genLog,
83 Version: i.versionForAidlGenRule(version),
84 GenTrace: genTrace,
85 Unstable: i.properties.Unstable,
86 Visibility: srcsVisibility(mctx, lang),
87 Flags: i.flagsForAidlGenRule(version),
Jeongik Chada36d5a2021-01-20 00:43:34 +090088 })
Jeongik Chada36d5a2021-01-20 00:43:34 +090089
Jeongik Cha52e98022021-01-20 18:37:20 +090090 importExportDependencies := []string{}
Jeongik Chada36d5a2021-01-20 00:43:34 +090091 var sharedLibDependency []string
92 var headerLibs []string
93 var sdkVersion *string
94 var minSdkVersion *string
95 var stl *string
96 var cpp_std *string
97 var hostSupported *bool
98 var addCflags []string
Jiyong Park6007f252021-07-16 17:59:19 +090099 targetProp := ccTargetProperties{
100 // Currently necessary for host builds
101 // TODO(b/31559095): bionic on host should define this
102 // TODO(b/146436251): default isn't applied because the module is created
103 // in PreArchMutators, when import behavior becomes explicit, the logic can
104 // be moved back to LoadHook
105 Host: hostProperties{Cflags: []string{
106 "-D__INTRODUCED_IN(n)=",
107 "-D__assert(a,b,c)=",
108 // We want all the APIs to be available on the host.
109 "-D__ANDROID_API__=10000"}},
110 Darwin: darwinProperties{Enabled: proptools.BoolPtr(false)},
111 }
Jeongik Chada36d5a2021-01-20 00:43:34 +0900112
113 if lang == langCpp {
114 importExportDependencies = append(importExportDependencies, "libbinder", "libutils")
115 if genTrace {
116 sharedLibDependency = append(sharedLibDependency, "libcutils")
117 }
118 hostSupported = i.properties.Host_supported
119 minSdkVersion = i.properties.Backend.Cpp.Min_sdk_version
Jiyong Park6007f252021-07-16 17:59:19 +0900120 } else if lang == langNdk || lang == langNdkPlatform {
Jeongik Chada36d5a2021-01-20 00:43:34 +0900121 importExportDependencies = append(importExportDependencies, "libbinder_ndk")
Jiyong Park6007f252021-07-16 17:59:19 +0900122 nonAppProps := imageProperties{
123 Cflags: []string{"-DBINDER_STABILITY_SUPPORT"},
124 }
Jeongik Chada36d5a2021-01-20 00:43:34 +0900125 if genTrace {
126 sharedLibDependency = append(sharedLibDependency, "libandroid")
Jiyong Park6007f252021-07-16 17:59:19 +0900127 nonAppProps.Exclude_shared_libs = []string{"libandroid"}
128 nonAppProps.Header_libs = []string{"libandroid_aidltrace"}
129 nonAppProps.Shared_libs = []string{"libcutils"}
Jeongik Chada36d5a2021-01-20 00:43:34 +0900130 }
Jiyong Park6007f252021-07-16 17:59:19 +0900131 targetProp.Platform = nonAppProps
132 targetProp.Vendor = nonAppProps
133 targetProp.Product = nonAppProps
Jeongik Chada36d5a2021-01-20 00:43:34 +0900134 minSdkVersion = i.properties.Backend.Ndk.Min_sdk_version
Jeongik Chada36d5a2021-01-20 00:43:34 +0900135 hostSupported = i.properties.Host_supported
Jiyong Park6007f252021-07-16 17:59:19 +0900136 if lang == langNdk && i.shouldGenerateAppNdkBackend() {
137 sdkVersion = proptools.StringPtr("current")
138 // Don't worry! This maps to libc++.so for the platform variant.
139 stl = proptools.StringPtr("c++_shared")
140 }
Jeongik Chada36d5a2021-01-20 00:43:34 +0900141 } else {
142 panic("Unrecognized language: " + lang)
143 }
144
145 vendorAvailable := i.properties.Vendor_available
Justin Yun08cb78a2021-01-25 17:24:24 +0900146 odmAvailable := i.properties.Odm_available
Jeongik Chada36d5a2021-01-20 00:43:34 +0900147 productAvailable := i.properties.Product_available
148 if lang == langCpp {
149 // Vendor and product modules cannot use the libbinder (cpp) backend of AIDL in a
150 // way that is stable. So, in order to prevent accidental usage of these library by
151 // vendor and product forcibly disabling this version of the library.
152 //
153 // It may be the case in the future that we will want to enable this (if some generic
154 // helper should be used by both libbinder vendor things using /dev/vndbinder as well
155 // as those things using /dev/binder + libbinder_ndk to talk to stable interfaces).
156 if "vintf" == proptools.String(i.properties.Stability) {
157 overrideVndkProperties.Vndk.Private = proptools.BoolPtr(true)
158 }
159 // As libbinder is not available for the product processes, we must not create
160 // product variant for the aidl_interface
161 productAvailable = nil
162 }
163
Jeongik Cha52e98022021-01-20 18:37:20 +0900164 mctx.CreateModule(aidlImplementationGeneratorFactory, &nameProperties{
165 Name: proptools.StringPtr(cppModuleGen + "-generator"),
166 }, &aidlImplementationGeneratorProperties{
167 Lang: lang,
168 AidlInterfaceName: i.ModuleBase.Name(),
169 Version: version,
170 ModuleProperties: []interface{}{
171 &ccProperties{
172 Name: proptools.StringPtr(cppModuleGen),
173 Vendor_available: vendorAvailable,
Justin Yun08cb78a2021-01-25 17:24:24 +0900174 Odm_available: odmAvailable,
Jeongik Cha52e98022021-01-20 18:37:20 +0900175 Product_available: productAvailable,
176 Host_supported: hostSupported,
177 Defaults: []string{"aidl-cpp-module-defaults"},
178 Double_loadable: i.properties.Double_loadable,
179 Generated_sources: []string{cppSourceGen},
180 Generated_headers: []string{cppSourceGen},
181 Export_generated_headers: []string{cppSourceGen},
182 Shared_libs: append(importExportDependencies, sharedLibDependency...),
183 Header_libs: headerLibs,
184 Export_shared_lib_headers: importExportDependencies,
185 Sdk_version: sdkVersion,
186 Stl: stl,
187 Cpp_std: cpp_std,
188 Cflags: append(addCflags, "-Wextra", "-Wall", "-Werror", "-Wextra-semi"),
189 Apex_available: commonProperties.Apex_available,
190 Min_sdk_version: minSdkVersion,
191 UseApexNameMacro: true,
Jiyong Park6007f252021-07-16 17:59:19 +0900192 Target: targetProp,
193 Tidy: proptools.BoolPtr(true),
Jeongik Cha52e98022021-01-20 18:37:20 +0900194 // Do the tidy check only for the generated headers
195 Tidy_flags: []string{"--header-filter=" + android.PathForOutput(mctx).String() + ".*"},
196 Tidy_checks_as_errors: []string{"*"},
197 }, &i.properties.VndkProperties,
198 &commonProperties.VndkProperties,
199 &overrideVndkProperties,
200 },
201 })
Jeongik Chada36d5a2021-01-20 00:43:34 +0900202
203 return cppModuleGen
204}
205
Jeongik Cha52e98022021-01-20 18:37:20 +0900206func addJavaLibrary(mctx android.LoadHookContext, i *aidlInterface, version string) string {
207 javaSourceGen := i.versionedName(version) + "-java-source"
208 javaModuleGen := i.versionedName(version) + "-java"
Jeongik Chada36d5a2021-01-20 00:43:34 +0900209 srcs, aidlRoot := i.srcsForVersion(mctx, version)
210 if len(srcs) == 0 {
211 // This can happen when the version is about to be frozen; the version
212 // directory is created but API dump hasn't been copied there.
213 // Don't create a library for the yet-to-be-frozen version.
214 return ""
215 }
216
217 sdkVersion := i.properties.Backend.Java.Sdk_version
218 if !proptools.Bool(i.properties.Backend.Java.Platform_apis) && sdkVersion == nil {
219 // platform apis requires no default
220 sdkVersion = proptools.StringPtr("system_current")
221 }
222
223 mctx.CreateModule(aidlGenFactory, &nameProperties{
224 Name: proptools.StringPtr(javaSourceGen),
225 }, &aidlGenProperties{
Jeongik Chaa01447d2021-03-17 17:43:12 +0900226 Srcs: srcs,
227 AidlRoot: aidlRoot,
Jooyung Han60699b52021-05-26 22:20:42 +0900228 ImportsWithoutVersion: i.properties.ImportsWithoutVersion,
Jeongik Chaa01447d2021-03-17 17:43:12 +0900229 Stability: i.properties.Stability,
230 Lang: langJava,
231 BaseName: i.ModuleBase.Name(),
232 Version: i.versionForAidlGenRule(version),
233 GenTrace: proptools.Bool(i.properties.Gen_trace),
234 Unstable: i.properties.Unstable,
235 Visibility: srcsVisibility(mctx, langJava),
236 Flags: i.flagsForAidlGenRule(version),
Jeongik Chada36d5a2021-01-20 00:43:34 +0900237 })
238
Jeongik Cha52e98022021-01-20 18:37:20 +0900239 mctx.CreateModule(aidlImplementationGeneratorFactory, &nameProperties{
240 Name: proptools.StringPtr(javaModuleGen + "-generator"),
241 }, &aidlImplementationGeneratorProperties{
242 Lang: langJava,
243 AidlInterfaceName: i.ModuleBase.Name(),
244 Version: version,
245 ModuleProperties: []interface{}{&javaProperties{
246 Name: proptools.StringPtr(javaModuleGen),
247 Installable: proptools.BoolPtr(true),
248 Defaults: []string{"aidl-java-module-defaults"},
249 Sdk_version: sdkVersion,
250 Platform_apis: i.properties.Backend.Java.Platform_apis,
251 Srcs: []string{":" + javaSourceGen},
252 Apex_available: i.properties.Backend.Java.Apex_available,
253 Min_sdk_version: i.properties.Backend.Java.Min_sdk_version,
254 }},
Jeongik Chada36d5a2021-01-20 00:43:34 +0900255 })
256
257 return javaModuleGen
258}
259
Jeongik Cha52e98022021-01-20 18:37:20 +0900260func addRustLibrary(mctx android.LoadHookContext, i *aidlInterface, version string) string {
261 rustSourceGen := i.versionedName(version) + "-rust-source"
262 rustModuleGen := i.versionedName(version) + "-rust"
Jeongik Chada36d5a2021-01-20 00:43:34 +0900263 srcs, aidlRoot := i.srcsForVersion(mctx, version)
264 if len(srcs) == 0 {
265 // This can happen when the version is about to be frozen; the version
266 // directory is created but API dump hasn't been copied there.
267 // Don't create a library for the yet-to-be-frozen version.
268 return ""
269 }
270
271 mctx.CreateModule(aidlGenFactory, &nameProperties{
272 Name: proptools.StringPtr(rustSourceGen),
273 }, &aidlGenProperties{
Jeongik Chaa01447d2021-03-17 17:43:12 +0900274 Srcs: srcs,
275 AidlRoot: aidlRoot,
Jooyung Han60699b52021-05-26 22:20:42 +0900276 ImportsWithoutVersion: i.properties.ImportsWithoutVersion,
Jeongik Chaa01447d2021-03-17 17:43:12 +0900277 Stability: i.properties.Stability,
278 Lang: langRust,
279 BaseName: i.ModuleBase.Name(),
280 Version: i.versionForAidlGenRule(version),
281 Unstable: i.properties.Unstable,
282 Visibility: srcsVisibility(mctx, langRust),
283 Flags: i.flagsForAidlGenRule(version),
Jeongik Chada36d5a2021-01-20 00:43:34 +0900284 })
285
Jeongik Cha52e98022021-01-20 18:37:20 +0900286 versionedRustName := fixRustName(i.versionedName(version))
287 rustCrateName := fixRustName(i.ModuleBase.Name())
Jeongik Chada36d5a2021-01-20 00:43:34 +0900288
289 mctx.CreateModule(aidlRustLibraryFactory, &rustProperties{
290 Name: proptools.StringPtr(rustModuleGen),
Jeongik Cha52e98022021-01-20 18:37:20 +0900291 Crate_name: rustCrateName,
Jeongik Chada36d5a2021-01-20 00:43:34 +0900292 Stem: proptools.StringPtr("lib" + versionedRustName),
293 Defaults: []string{"aidl-rust-module-defaults"},
294 Host_supported: i.properties.Host_supported,
Jiyong Park33690252021-02-16 13:21:40 +0900295 Apex_available: i.properties.Backend.Rust.Apex_available,
Jiyong Park6007f252021-07-16 17:59:19 +0900296 Target: rustTargetProperties{Darwin: darwinProperties{Enabled: proptools.BoolPtr(false)}},
Jeongik Chada36d5a2021-01-20 00:43:34 +0900297 }, &rust.SourceProviderProperties{
298 Source_stem: proptools.StringPtr(versionedRustName),
299 }, &aidlRustSourceProviderProperties{
Jeongik Cha52e98022021-01-20 18:37:20 +0900300 SourceGen: rustSourceGen,
301 Imports: i.properties.Imports,
302 Version: version,
303 AidlInterfaceName: i.ModuleBase.Name(),
Jeongik Chada36d5a2021-01-20 00:43:34 +0900304 })
305
306 return rustModuleGen
307}
308
309// This function returns module name with version. Assume that there is foo of which latest version is 2
310// Version -> Module name
311// "1"->foo-V1
312// "2"->foo-V2
Jeongik Cha52e98022021-01-20 18:37:20 +0900313// "3"->foo-V3
314// And assume that there is 'bar' which is an 'unstable' interface.
315// ""->bar
Jeongik Chada36d5a2021-01-20 00:43:34 +0900316func (i *aidlInterface) versionedName(version string) string {
317 name := i.ModuleBase.Name()
318 if version == "" {
319 return name
Jeongik Chada36d5a2021-01-20 00:43:34 +0900320 }
321 return name + "-V" + version
322}
323
Jooyung Handf94f0f2021-06-07 18:57:10 +0900324func (i *aidlInterface) srcsForVersion(mctx android.EarlyModuleContext, version string) (srcs []string, aidlRoot string) {
Jeongik Cha52e98022021-01-20 18:37:20 +0900325 if version == i.nextVersion() {
Jeongik Chada36d5a2021-01-20 00:43:34 +0900326 return i.properties.Srcs, i.properties.Local_include_dir
327 } else {
328 aidlRoot = filepath.Join(aidlApiDir, i.ModuleBase.Name(), version)
329 full_paths, err := mctx.GlobWithDeps(filepath.Join(mctx.ModuleDir(), aidlRoot, "**/*.aidl"), nil)
330 if err != nil {
331 panic(err)
332 }
333 for _, path := range full_paths {
334 // Here, we need path local to the module
335 srcs = append(srcs, strings.TrimPrefix(path, mctx.ModuleDir()+"/"))
336 }
337 return srcs, aidlRoot
338 }
339}
Jeongik Cha52e98022021-01-20 18:37:20 +0900340
341func (i *aidlInterface) versionForAidlGenRule(version string) string {
342 if !i.hasVersion() {
343 return ""
344 }
Jeongik Cha52e98022021-01-20 18:37:20 +0900345 return version
346}
347
Jooyung Han03b19c32021-02-09 10:08:19 +0900348func (i *aidlInterface) flagsForAidlGenRule(version string) (flags []string) {
349 flags = append(flags, i.properties.Flags...)
350 // For ToT, turn on "-Weverything" (enable all warnings)
351 if version == i.nextVersion() {
352 flags = append(flags, "-Weverything")
353 }
354 return
355}
356
Jeongik Cha52e98022021-01-20 18:37:20 +0900357func (i *aidlInterface) isModuleForVndk(version string) bool {
Jeongik Cha52e98022021-01-20 18:37:20 +0900358 if i.properties.Vndk_use_version != nil {
359 if !i.hasVersion() {
360 panic("does not make sense, vndk_use_version specififed")
361 }
362 // Will be exactly one of the version numbers
363 return version == *i.properties.Vndk_use_version
364 }
365
366 // For an interface with no versions, this is the ToT interface.
367 if !i.hasVersion() {
368 return version == i.nextVersion()
369 }
370
371 return version == i.latestVersion()
372}
373
374// importing aidl_interface's version | imported aidl_interface | imported aidl_interface's version
375// --------------------------------------------------------------------------------------------------
376// whatever | unstable | unstable version
377// ToT version(including unstable) | whatever | ToT version(unstable if unstable)
378// otherwise | whatever | the latest stable version
Jeongik Chaa01447d2021-03-17 17:43:12 +0900379// In the case that import specifies the version which it wants to use, use that version.
Jeongik Cha52e98022021-01-20 18:37:20 +0900380func (i *aidlInterface) getImportWithVersion(version string, anImport string, config android.Config) string {
Jeongik Chaa01447d2021-03-17 17:43:12 +0900381 if hasVersionSuffix(anImport) {
382 return anImport
383 }
Jeongik Cha52e98022021-01-20 18:37:20 +0900384 other := lookupInterface(anImport, config)
385 if proptools.Bool(other.properties.Unstable) {
386 return anImport
387 }
388 if version == i.nextVersion() || !other.hasVersion() {
389 return other.versionedName(other.nextVersion())
390 }
391 return other.versionedName(other.latestVersion())
392}
393
Jeongik Cha52e98022021-01-20 18:37:20 +0900394func aidlImplementationGeneratorFactory() android.Module {
395 g := &aidlImplementationGenerator{}
396 g.AddProperties(&g.properties)
397 android.InitAndroidModule(g)
398 return g
399}
400
401type aidlImplementationGenerator struct {
402 android.ModuleBase
403 properties aidlImplementationGeneratorProperties
404}
405
406type aidlImplementationGeneratorProperties struct {
407 Lang string
408 AidlInterfaceName string
409 Version string
410 ModuleProperties []interface{}
411}
412
413func (g *aidlImplementationGenerator) DepsMutator(ctx android.BottomUpMutatorContext) {
414}
415
416func (g *aidlImplementationGenerator) GenerateAndroidBuildActions(ctx android.ModuleContext) {
417}
418
419func (g *aidlImplementationGenerator) GenerateImplementation(ctx android.TopDownMutatorContext) {
420 i := lookupInterface(g.properties.AidlInterfaceName, ctx.Config())
421 version := g.properties.Version
422 lang := g.properties.Lang
Jeongik Cha50a1dfc2021-05-25 23:54:20 +0900423 imports := make([]string, len(i.properties.Imports))
424 for idx, anImport := range i.properties.Imports {
425 importModule, _ := parseModuleWithVersion(anImport)
426 if lookupInterface(importModule, ctx.Config()) == nil {
427 if ctx.Config().AllowMissingDependencies() {
428 continue
429 }
430 panic(anImport + " doesn't exist, it should be checked in 'checkImports' mutator.")
Jeongik Cha52e98022021-01-20 18:37:20 +0900431 }
Jeongik Cha50a1dfc2021-05-25 23:54:20 +0900432 imports[idx] = i.getImportWithVersion(version, anImport, ctx.Config()) + "-" + lang
433 }
434
435 if g.properties.Lang == langJava {
Jeongik Cha52e98022021-01-20 18:37:20 +0900436 if p, ok := g.properties.ModuleProperties[0].(*javaProperties); ok {
437 p.Static_libs = imports
438 }
439 ctx.CreateModule(java.LibraryFactory, g.properties.ModuleProperties...)
440 } else {
Jeongik Cha52e98022021-01-20 18:37:20 +0900441 if p, ok := g.properties.ModuleProperties[0].(*ccProperties); ok {
442 p.Shared_libs = append(p.Shared_libs, imports...)
443 p.Export_shared_lib_headers = append(p.Export_shared_lib_headers, imports...)
444 }
445 ctx.CreateModule(cc.LibraryFactory, g.properties.ModuleProperties...)
446 }
447}