blob: 1fa096666dad9f84691b4100f10a89c225ead4ca [file] [log] [blame]
Steven Moreland81079f92018-07-06 16:15:53 -07001// Copyright (C) 2018 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 (
Jiyong Park965c5b92018-11-21 13:37:15 +090018 "android/soong/android"
19 "android/soong/cc"
20 "android/soong/genrule"
21 "android/soong/java"
22 "android/soong/phony"
Jiyong Park44837012018-08-07 00:37:34 +090023 "fmt"
24 "io"
Steven Moreland81079f92018-07-06 16:15:53 -070025 "path/filepath"
Jiyong Park69c14932018-08-06 21:36:46 +090026 "strconv"
Steven Moreland81079f92018-07-06 16:15:53 -070027 "strings"
28 "sync"
29
30 "github.com/google/blueprint"
Jiyong Park69c14932018-08-06 21:36:46 +090031 "github.com/google/blueprint/pathtools"
Steven Moreland81079f92018-07-06 16:15:53 -070032 "github.com/google/blueprint/proptools"
Steven Moreland81079f92018-07-06 16:15:53 -070033)
34
35var (
36 aidlInterfaceSuffix = "_interface"
Jiyong Park03e055a2018-08-27 15:24:36 +090037 aidlApiSuffix = "-api"
Jiyong Park69c14932018-08-06 21:36:46 +090038 langCpp = "cpp"
39 langJava = "java"
Steven Morelandc26d8142018-09-17 14:25:33 -070040 langNdk = "ndk"
Steven Morelandcfc85f42018-12-13 12:11:11 -080041 langNdkPlatform = "ndk_platform"
Jiyong Park965c5b92018-11-21 13:37:15 +090042 futureVersion = "10000"
Steven Moreland81079f92018-07-06 16:15:53 -070043
44 pctx = android.NewPackageContext("android/aidl")
45
Jiyong Parkb8dceed2019-04-07 00:08:13 +090046 aidlDirPrepareRule = pctx.StaticRule("aidlDirPrepareRule", blueprint.RuleParams{
47 Command: `rm -rf "${outDir}" && mkdir -p "${outDir}" && ` +
48 `touch ${out}`,
49 Description: "create ${out}",
50 }, "outDir")
51
Steven Moreland81079f92018-07-06 16:15:53 -070052 aidlCppRule = pctx.StaticRule("aidlCppRule", blueprint.RuleParams{
Jiyong Parkb8dceed2019-04-07 00:08:13 +090053 Command: `mkdir -p "${headerDir}" && ` +
Jiyong Parkce50e262018-10-29 09:54:20 +090054 `${aidlCmd} --lang=${lang} ${optionalFlags} --structured --ninja -d ${out}.d ` +
Jiyong Park69c14932018-08-06 21:36:46 +090055 `-h ${headerDir} -o ${outDir} ${imports} ${in}`,
Steven Moreland81079f92018-07-06 16:15:53 -070056 Depfile: "${out}.d",
57 Deps: blueprint.DepsGCC,
Jiyong Park69c14932018-08-06 21:36:46 +090058 CommandDeps: []string{"${aidlCmd}"},
Steven Morelandc26d8142018-09-17 14:25:33 -070059 Description: "AIDL ${lang} ${in}",
Jiyong Parkce50e262018-10-29 09:54:20 +090060 }, "imports", "lang", "headerDir", "outDir", "optionalFlags")
Jiyong Park69c14932018-08-06 21:36:46 +090061
62 aidlJavaRule = pctx.StaticRule("aidlJavaRule", blueprint.RuleParams{
Jiyong Parkb8dceed2019-04-07 00:08:13 +090063 Command: `${aidlCmd} --lang=java ${optionalFlags} --structured --ninja -d ${out}.d ` +
Jiyong Park69c14932018-08-06 21:36:46 +090064 `-o ${outDir} ${imports} ${in}`,
65 Depfile: "${out}.d",
66 Deps: blueprint.DepsGCC,
67 CommandDeps: []string{"${aidlCmd}"},
Jiyong Parkfce159b2018-09-20 15:24:52 +090068 Description: "AIDL Java ${in}",
Jiyong Park965c5b92018-11-21 13:37:15 +090069 }, "imports", "outDir", "optionalFlags")
Jiyong Park44837012018-08-07 00:37:34 +090070
71 aidlDumpApiRule = pctx.StaticRule("aidlDumpApiRule", blueprint.RuleParams{
Dan Willemsen50be4dd2019-05-16 02:10:27 +000072 Command: `rm -rf "${outDir}" && mkdir -p "${outDir}" && ` +
73 `${aidlCmd} --dumpapi --structured ${imports} --out ${outDir} ${in}`,
Jiyong Park44837012018-08-07 00:37:34 +090074 CommandDeps: []string{"${aidlCmd}"},
Dan Willemsen50be4dd2019-05-16 02:10:27 +000075 }, "imports", "outDir")
Jiyong Park44837012018-08-07 00:37:34 +090076
Andrei Onea8714b022019-02-01 18:55:54 +000077 aidlDumpMappingsRule = pctx.StaticRule("aidlDumpMappingsRule", blueprint.RuleParams{
78 Command: `rm -rf "${outDir}" && mkdir -p "${outDir}" && ` +
79 `${aidlCmd} --apimapping ${outDir}/intermediate.txt ${in} ${imports} && ` +
80 `${aidlToJniCmd} ${outDir}/intermediate.txt ${out}`,
81 CommandDeps: []string{"${aidlCmd}"},
82 }, "imports", "outDir")
83
Jiyong Parkfce159b2018-09-20 15:24:52 +090084 aidlFreezeApiRule = pctx.AndroidStaticRule("aidlFreezeApiRule",
Jiyong Park44837012018-08-07 00:37:34 +090085 blueprint.RuleParams{
Steven Morelandb86abdd2018-12-17 14:14:52 -080086 Command: `mkdir -p ${to} && rm -rf ${to}/* && ` +
87 `${bpmodifyCmd} -w -m ${name} -parameter versions -a ${version} ${bp} && ` +
Dan Willemsen50be4dd2019-05-16 02:10:27 +000088 `cp -rf ${apiDir}/* ${to} && touch ${out}`,
Steven Morelandb86abdd2018-12-17 14:14:52 -080089 CommandDeps: []string{"${bpmodifyCmd}"},
Dan Willemsen50be4dd2019-05-16 02:10:27 +000090 }, "to", "name", "version", "bp", "apiDir")
Jiyong Park49473512018-08-16 16:49:07 +090091
92 aidlCheckApiRule = pctx.StaticRule("aidlCheckApiRule", blueprint.RuleParams{
Jiyong Parke59c3682018-09-11 23:10:25 +090093 Command: `${aidlCmd} --checkapi ${old} ${new} && touch ${out}`,
Jiyong Park49473512018-08-16 16:49:07 +090094 CommandDeps: []string{"${aidlCmd}"},
Jiyong Parkfce159b2018-09-20 15:24:52 +090095 Description: "AIDL CHECK API: ${new} against ${old}",
Jiyong Parke59c3682018-09-11 23:10:25 +090096 }, "old", "new")
Jiyong Park7c3c11c2019-04-23 00:06:47 +090097
98 aidlDiffApiRule = pctx.StaticRule("aidlDiffApiRule", blueprint.RuleParams{
99 Command: `diff -r ${old} ${new} && touch ${out}`,
100 Description: "Check equality of ${new} and ${old}",
101 }, "old", "new")
Steven Moreland81079f92018-07-06 16:15:53 -0700102)
103
104func init() {
Jiyong Park69c14932018-08-06 21:36:46 +0900105 pctx.HostBinToolVariable("aidlCmd", "aidl")
Steven Morelandb86abdd2018-12-17 14:14:52 -0800106 pctx.HostBinToolVariable("bpmodifyCmd", "bpmodify")
Andrei Onea8714b022019-02-01 18:55:54 +0000107 pctx.SourcePathVariable("aidlToJniCmd", "system/tools/aidl/build/aidl_to_jni.py")
Steven Moreland81079f92018-07-06 16:15:53 -0700108 android.RegisterModuleType("aidl_interface", aidlInterfaceFactory)
Andrei Onea8714b022019-02-01 18:55:54 +0000109 android.RegisterModuleType("aidl_mapping", aidlMappingFactory)
Jiyong Park09e8cb42019-05-31 09:38:19 +0900110 android.RegisterMakeVarsProvider(pctx, allAidlInterfacesMakeVars)
Steven Moreland81079f92018-07-06 16:15:53 -0700111}
112
113// wrap(p, a, s) = [p + v + s for v in a]
114func wrap(prefix string, strs []string, suffix string) []string {
115 ret := make([]string, len(strs))
116 for i, v := range strs {
117 ret[i] = prefix + v + suffix
118 }
119 return ret
120}
121
122// concat(a...) = sum((i for i in a), [])
123func concat(sstrs ...[]string) []string {
124 var ret []string
125 for _, v := range sstrs {
126 ret = append(ret, v...)
127 }
128 return ret
129}
130
131func isRelativePath(path string) bool {
132 if path == "" {
133 return true
134 }
135 return filepath.Clean(path) == path && path != ".." &&
136 !strings.HasPrefix(path, "../") && !strings.HasPrefix(path, "/")
137}
138
139type aidlGenProperties struct {
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900140 Srcs []string
Jiyong Park69c14932018-08-06 21:36:46 +0900141 AidlRoot string // base directory for the input aidl file
142 Imports []string
Steven Morelandc26d8142018-09-17 14:25:33 -0700143 Lang string // target language [java|cpp|ndk]
Jiyong Park03e055a2018-08-27 15:24:36 +0900144 BaseName string
Jiyong Parkce50e262018-10-29 09:54:20 +0900145 GenLog bool
Jiyong Park965c5b92018-11-21 13:37:15 +0900146 Version string
Steven Moreland81079f92018-07-06 16:15:53 -0700147}
148
149type aidlGenRule struct {
150 android.ModuleBase
151
152 properties aidlGenProperties
153
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900154 implicitInputs android.Paths
155 importFlags string
156
157 genOutDir android.ModuleGenPath
Jiyong Park69c14932018-08-06 21:36:46 +0900158 genHeaderDir android.ModuleGenPath
Steven Moreland81079f92018-07-06 16:15:53 -0700159 genOutputs android.WritablePaths
160}
161
162var _ android.SourceFileProducer = (*aidlGenRule)(nil)
163var _ genrule.SourceFileGenerator = (*aidlGenRule)(nil)
164
165func (g *aidlGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900166 genDirTimestamp := android.PathForModuleGen(ctx, "timestamp")
167 g.implicitInputs = append(g.implicitInputs, genDirTimestamp)
Steven Moreland81079f92018-07-06 16:15:53 -0700168
169 var importPaths []string
170 ctx.VisitDirectDeps(func(dep android.Module) {
Jiyong Park03e055a2018-08-27 15:24:36 +0900171 if importedAidl, ok := dep.(*aidlInterface); ok {
Jeongik Chabe31ab42019-03-20 11:09:17 +0900172 importPaths = append(importPaths, importedAidl.properties.Full_import_paths...)
Jiyong Park03e055a2018-08-27 15:24:36 +0900173 } else if api, ok := dep.(*aidlApi); ok {
Jiyong Parkfce159b2018-09-20 15:24:52 +0900174 // When compiling an AIDL interface, also make sure that each
175 // version of the interface is compatible with its previous version
176 for _, path := range api.checkApiTimestamps {
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900177 g.implicitInputs = append(g.implicitInputs, path)
Jiyong Park03e055a2018-08-27 15:24:36 +0900178 }
179 }
Steven Moreland81079f92018-07-06 16:15:53 -0700180 })
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900181 g.importFlags = strings.Join(wrap("-I", importPaths, ""), " ")
Steven Moreland81079f92018-07-06 16:15:53 -0700182
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900183 srcs := android.PathsWithModuleSrcSubDir(ctx, android.PathsForModuleSrc(ctx, g.properties.Srcs), g.properties.AidlRoot)
184
185 g.genOutDir = android.PathForModuleGen(ctx)
186 g.genHeaderDir = android.PathForModuleGen(ctx, "include")
187 for _, src := range srcs {
188 g.genOutputs = append(g.genOutputs, g.generateBuildActionsForSingleAidl(ctx, src))
189 }
190
191 // This is to clean genOutDir before generating any file
192 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
193 Rule: aidlDirPrepareRule,
194 Implicits: srcs,
195 Output: genDirTimestamp,
196 Args: map[string]string{
197 "outDir": g.genOutDir.String(),
198 },
199 })
200}
201
202func (g *aidlGenRule) generateBuildActionsForSingleAidl(ctx android.ModuleContext, src android.Path) android.WritablePath {
203 var outFile android.WritablePath
204 if g.properties.Lang == langJava {
205 outFile = android.PathForModuleGen(ctx, pathtools.ReplaceExtension(src.Rel(), "java"))
206 } else {
207 outFile = android.PathForModuleGen(ctx, pathtools.ReplaceExtension(src.Rel(), "cpp"))
208 }
Steven Moreland81079f92018-07-06 16:15:53 -0700209
Jiyong Park965c5b92018-11-21 13:37:15 +0900210 var optionalFlags []string
211 if g.properties.Version != "" {
212 optionalFlags = append(optionalFlags, "--version "+g.properties.Version)
213 }
214
Jiyong Park69c14932018-08-06 21:36:46 +0900215 if g.properties.Lang == langJava {
Steven Moreland81079f92018-07-06 16:15:53 -0700216 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Jiyong Park03e055a2018-08-27 15:24:36 +0900217 Rule: aidlJavaRule,
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900218 Input: src,
219 Implicits: g.implicitInputs,
220 Output: outFile,
Steven Moreland81079f92018-07-06 16:15:53 -0700221 Args: map[string]string{
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900222 "imports": g.importFlags,
223 "outDir": g.genOutDir.String(),
Jiyong Park965c5b92018-11-21 13:37:15 +0900224 "optionalFlags": strings.Join(optionalFlags, " "),
Steven Moreland81079f92018-07-06 16:15:53 -0700225 },
226 })
227 } else {
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900228 typeName := strings.TrimSuffix(filepath.Base(src.Rel()), ".aidl")
229 packagePath := filepath.Dir(src.Rel())
Jiyong Park69c14932018-08-06 21:36:46 +0900230 baseName := typeName
Steven Morelandc26d8142018-09-17 14:25:33 -0700231 // TODO(b/111362593): aidl_to_cpp_common.cpp uses heuristics to figure out if
Jiyong Park69c14932018-08-06 21:36:46 +0900232 // an interface name has a leading I. Those same heuristics have been
233 // moved here.
234 if len(baseName) >= 2 && baseName[0] == 'I' &&
235 strings.ToUpper(baseName)[1] == baseName[1] {
236 baseName = strings.TrimPrefix(typeName, "I")
237 }
Steven Moreland7c933372018-10-11 15:20:04 -0700238
239 prefix := ""
Steven Morelandcfc85f42018-12-13 12:11:11 -0800240 if g.properties.Lang == langNdk || g.properties.Lang == langNdkPlatform {
Steven Moreland7c933372018-10-11 15:20:04 -0700241 prefix = "aidl"
242 }
243
Jiyong Park69c14932018-08-06 21:36:46 +0900244 var headers android.WritablePaths
Steven Moreland7c933372018-10-11 15:20:04 -0700245 headers = append(headers, g.genHeaderDir.Join(ctx, prefix, packagePath,
Jiyong Park69c14932018-08-06 21:36:46 +0900246 typeName+".h"))
Steven Moreland7c933372018-10-11 15:20:04 -0700247 headers = append(headers, g.genHeaderDir.Join(ctx, prefix, packagePath,
Jiyong Park69c14932018-08-06 21:36:46 +0900248 "Bp"+baseName+".h"))
Steven Moreland7c933372018-10-11 15:20:04 -0700249 headers = append(headers, g.genHeaderDir.Join(ctx, prefix, packagePath,
Jiyong Park69c14932018-08-06 21:36:46 +0900250 "Bn"+baseName+".h"))
Jiyong Parkce50e262018-10-29 09:54:20 +0900251
Jiyong Parkce50e262018-10-29 09:54:20 +0900252 if g.properties.GenLog {
253 optionalFlags = append(optionalFlags, "--log")
254 }
Jiyong Park965c5b92018-11-21 13:37:15 +0900255
Steven Morelandcfc85f42018-12-13 12:11:11 -0800256 aidlLang := g.properties.Lang
257 if aidlLang == langNdkPlatform {
258 aidlLang = "ndk"
259 }
260
Steven Moreland81079f92018-07-06 16:15:53 -0700261 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Jiyong Park69c14932018-08-06 21:36:46 +0900262 Rule: aidlCppRule,
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900263 Input: src,
264 Implicits: g.implicitInputs,
265 Output: outFile,
Jiyong Park69c14932018-08-06 21:36:46 +0900266 ImplicitOutputs: headers,
Steven Moreland81079f92018-07-06 16:15:53 -0700267 Args: map[string]string{
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900268 "imports": g.importFlags,
Steven Morelandcfc85f42018-12-13 12:11:11 -0800269 "lang": aidlLang,
Jiyong Parkce50e262018-10-29 09:54:20 +0900270 "headerDir": g.genHeaderDir.String(),
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900271 "outDir": g.genOutDir.String(),
Jiyong Parkce50e262018-10-29 09:54:20 +0900272 "optionalFlags": strings.Join(optionalFlags, " "),
Steven Moreland81079f92018-07-06 16:15:53 -0700273 },
274 })
275 }
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900276
277 return outFile
Steven Moreland81079f92018-07-06 16:15:53 -0700278}
279
280func (g *aidlGenRule) GeneratedSourceFiles() android.Paths {
281 return g.genOutputs.Paths()
282}
283
284func (g *aidlGenRule) Srcs() android.Paths {
285 return g.genOutputs.Paths()
286}
287
288func (g *aidlGenRule) GeneratedDeps() android.Paths {
289 return g.genOutputs.Paths()
290}
291
292func (g *aidlGenRule) GeneratedHeaderDirs() android.Paths {
293 return android.Paths{g.genHeaderDir}
294}
295
296func (g *aidlGenRule) DepsMutator(ctx android.BottomUpMutatorContext) {
297 ctx.AddDependency(ctx.Module(), nil, wrap("", g.properties.Imports, aidlInterfaceSuffix)...)
Jiyong Park03e055a2018-08-27 15:24:36 +0900298 ctx.AddDependency(ctx.Module(), nil, g.properties.BaseName+aidlApiSuffix)
Steven Moreland81079f92018-07-06 16:15:53 -0700299}
300
301func aidlGenFactory() android.Module {
302 g := &aidlGenRule{}
303 g.AddProperties(&g.properties)
304 android.InitAndroidModule(g)
305 return g
306}
307
Jiyong Park44837012018-08-07 00:37:34 +0900308type aidlApiProperties struct {
Jiyong Parkfce159b2018-09-20 15:24:52 +0900309 BaseName string
Jiyong Parke59c3682018-09-11 23:10:25 +0900310 Inputs []string
311 Imports []string
312 Api_dir *string
Jiyong Parkfce159b2018-09-20 15:24:52 +0900313 Versions []string
Jiyong Parke59c3682018-09-11 23:10:25 +0900314 AidlRoot string // base directory for the input aidl file
Jiyong Park44837012018-08-07 00:37:34 +0900315}
316
317type aidlApi struct {
318 android.ModuleBase
319
320 properties aidlApiProperties
321
Jiyong Parkfce159b2018-09-20 15:24:52 +0900322 // for triggering api check for version X against version X-1
323 checkApiTimestamps android.WritablePaths
324
325 // for triggering freezing API as the new version
326 freezeApiTimestamp android.WritablePath
Jiyong Park44837012018-08-07 00:37:34 +0900327}
328
Jiyong Parkfce159b2018-09-20 15:24:52 +0900329func (m *aidlApi) apiDir() string {
330 if m.properties.Api_dir != nil {
331 return *(m.properties.Api_dir)
332 } else {
333 return "api"
334 }
335}
336
Steven Moreland1ef3c362018-12-20 13:07:05 -0800337// Version of the interface at ToT if it is frozen
338func (m *aidlApi) validateCurrentVersion(ctx android.ModuleContext) string {
Jiyong Parkfce159b2018-09-20 15:24:52 +0900339 if len(m.properties.Versions) == 0 {
Steven Moreland1ef3c362018-12-20 13:07:05 -0800340 return "1"
Jiyong Parkfce159b2018-09-20 15:24:52 +0900341 } else {
Steven Moreland1ef3c362018-12-20 13:07:05 -0800342 latestVersion := m.properties.Versions[len(m.properties.Versions)-1]
343
344 i, err := strconv.ParseInt(latestVersion, 10, 64)
345 if err != nil {
346 ctx.PropertyErrorf("versions", "must be integers")
347 return ""
348 }
349
350 return strconv.FormatInt(i+1, 10)
Jiyong Parkfce159b2018-09-20 15:24:52 +0900351 }
352}
353
354func (m *aidlApi) createApiDumpFromSource(ctx android.ModuleContext) (apiDir android.WritablePath, apiFiles android.WritablePaths) {
Jiyong Park44837012018-08-07 00:37:34 +0900355 var importPaths []string
356 ctx.VisitDirectDeps(func(dep android.Module) {
Jiyong Park03e055a2018-08-27 15:24:36 +0900357 if importedAidl, ok := dep.(*aidlInterface); ok {
Jeongik Chabe31ab42019-03-20 11:09:17 +0900358 importPaths = append(importPaths, importedAidl.properties.Full_import_paths...)
Jiyong Park03e055a2018-08-27 15:24:36 +0900359 }
Jiyong Park44837012018-08-07 00:37:34 +0900360 })
361
Jiyong Parkfce159b2018-09-20 15:24:52 +0900362 var srcs android.Paths
Jiyong Parke59c3682018-09-11 23:10:25 +0900363 for _, input := range m.properties.Inputs {
Colin Cross28a41d92019-03-06 12:30:32 -0800364 path := android.PathForModuleSrc(ctx, input)
365 path = android.PathWithModuleSrcSubDir(ctx, path, m.properties.AidlRoot)
366 srcs = append(srcs, path)
Jiyong Parke59c3682018-09-11 23:10:25 +0900367 }
368
Jiyong Parkfce159b2018-09-20 15:24:52 +0900369 apiDir = android.PathForModuleOut(ctx, "dump")
370 for _, src := range srcs {
371 apiFiles = append(apiFiles, android.PathForModuleOut(ctx, "dump", src.Rel()))
Jiyong Parke59c3682018-09-11 23:10:25 +0900372 }
Jiyong Park44837012018-08-07 00:37:34 +0900373 imports := strings.Join(wrap("-I", importPaths, ""), " ")
374 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Dan Willemsen50be4dd2019-05-16 02:10:27 +0000375 Rule: aidlDumpApiRule,
376 Outputs: apiFiles,
377 Inputs: srcs,
Jiyong Park44837012018-08-07 00:37:34 +0900378 Args: map[string]string{
379 "imports": imports,
Dan Willemsen50be4dd2019-05-16 02:10:27 +0000380 "outDir": apiDir.String(),
Jiyong Park44837012018-08-07 00:37:34 +0900381 },
382 })
Jiyong Parkfce159b2018-09-20 15:24:52 +0900383 return apiDir, apiFiles
384}
Jiyong Park44837012018-08-07 00:37:34 +0900385
Jiyong Parkfce159b2018-09-20 15:24:52 +0900386func (m *aidlApi) freezeApiDumpAsVersion(ctx android.ModuleContext, apiDumpDir android.Path, apiFiles android.Paths, version string) android.WritablePath {
387 timestampFile := android.PathForModuleOut(ctx, "freezeapi_"+version+".timestamp")
Steven Morelandb86abdd2018-12-17 14:14:52 -0800388
389 modulePath := android.PathForModuleSrc(ctx).String()
390
Jiyong Park44837012018-08-07 00:37:34 +0900391 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Jiyong Parkfce159b2018-09-20 15:24:52 +0900392 Rule: aidlFreezeApiRule,
393 Description: "Freezing AIDL API of " + m.properties.BaseName + " as version " + version,
Jiyong Parkfce159b2018-09-20 15:24:52 +0900394 Implicits: apiFiles,
395 Output: timestampFile,
Jiyong Park44837012018-08-07 00:37:34 +0900396 Args: map[string]string{
Steven Morelandb86abdd2018-12-17 14:14:52 -0800397 "to": filepath.Join(modulePath, m.apiDir(), version),
Dan Willemsen50be4dd2019-05-16 02:10:27 +0000398 "apiDir": apiDumpDir.String(),
Steven Morelandb86abdd2018-12-17 14:14:52 -0800399 "name": m.properties.BaseName,
400 "version": version,
401 "bp": android.PathForModuleSrc(ctx, "Android.bp").String(),
Jiyong Park44837012018-08-07 00:37:34 +0900402 },
403 })
Jiyong Parkfce159b2018-09-20 15:24:52 +0900404 return timestampFile
405}
Jiyong Park49473512018-08-16 16:49:07 +0900406
Jiyong Parkfce159b2018-09-20 15:24:52 +0900407func (m *aidlApi) checkCompatibility(ctx android.ModuleContext, oldApiDir android.Path, oldApiFiles android.Paths, newApiDir android.Path, newApiFiles android.Paths) android.WritablePath {
408 newVersion := newApiDir.Base()
409 timestampFile := android.PathForModuleOut(ctx, "checkapi_"+newVersion+".timestamp")
Jiyong Parke59c3682018-09-11 23:10:25 +0900410 var allApiFiles android.Paths
Jiyong Parkfce159b2018-09-20 15:24:52 +0900411 allApiFiles = append(allApiFiles, oldApiFiles...)
412 allApiFiles = append(allApiFiles, newApiFiles...)
Jiyong Park49473512018-08-16 16:49:07 +0900413 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
414 Rule: aidlCheckApiRule,
Jiyong Parke59c3682018-09-11 23:10:25 +0900415 Implicits: allApiFiles,
Jiyong Parkfce159b2018-09-20 15:24:52 +0900416 Output: timestampFile,
Jiyong Park49473512018-08-16 16:49:07 +0900417 Args: map[string]string{
Jiyong Parkfce159b2018-09-20 15:24:52 +0900418 "old": oldApiDir.String(),
Jiyong Parke59c3682018-09-11 23:10:25 +0900419 "new": newApiDir.String(),
Jiyong Park49473512018-08-16 16:49:07 +0900420 },
421 })
Jiyong Parkfce159b2018-09-20 15:24:52 +0900422 return timestampFile
423}
424
Jiyong Park7c3c11c2019-04-23 00:06:47 +0900425func (m *aidlApi) checkEquality(ctx android.ModuleContext, oldApiDir android.Path, oldApiFiles android.Paths, newApiDir android.Path, newApiFiles android.Paths) android.WritablePath {
426 newVersion := newApiDir.Base()
427 timestampFile := android.PathForModuleOut(ctx, "checkapi_"+newVersion+".timestamp")
428 var allApiFiles android.Paths
429 allApiFiles = append(allApiFiles, oldApiFiles...)
430 allApiFiles = append(allApiFiles, newApiFiles...)
431 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
432 Rule: aidlDiffApiRule,
433 Implicits: allApiFiles,
434 Output: timestampFile,
435 Args: map[string]string{
436 "old": oldApiDir.String(),
437 "new": newApiDir.String(),
438 },
439 })
440 return timestampFile
441}
442
Jiyong Parkfce159b2018-09-20 15:24:52 +0900443func (m *aidlApi) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Steven Moreland1ef3c362018-12-20 13:07:05 -0800444 currentVersion := m.validateCurrentVersion(ctx)
445
446 if ctx.Failed() {
447 return
448 }
449
450 currentDumpDir, currentApiFiles := m.createApiDumpFromSource(ctx)
451 m.freezeApiTimestamp = m.freezeApiDumpAsVersion(ctx, currentDumpDir, currentApiFiles.Paths(), currentVersion)
452
453 apiDirs := make(map[string]android.Path)
Jiyong Parkfce159b2018-09-20 15:24:52 +0900454 apiFiles := make(map[string]android.Paths)
455 for _, ver := range m.properties.Versions {
Steven Moreland1ef3c362018-12-20 13:07:05 -0800456 apiDir := android.PathForModuleSrc(ctx, m.apiDir(), ver)
457 apiDirs[ver] = apiDir
Colin Cross28a41d92019-03-06 12:30:32 -0800458 apiFiles[ver] = ctx.Glob(filepath.Join(apiDir.String(), "**/*.aidl"), nil)
Jiyong Parkfce159b2018-09-20 15:24:52 +0900459 }
Steven Moreland1ef3c362018-12-20 13:07:05 -0800460 apiDirs[currentVersion] = currentDumpDir
461 apiFiles[currentVersion] = currentApiFiles.Paths()
Jiyong Parkfce159b2018-09-20 15:24:52 +0900462
Jiyong Park7c3c11c2019-04-23 00:06:47 +0900463 // Check that version X is backward compatible with version X-1
464 for i, newVersion := range m.properties.Versions {
Steven Morelandb86abdd2018-12-17 14:14:52 -0800465 if i != 0 {
Jiyong Parkfce159b2018-09-20 15:24:52 +0900466 oldVersion := m.properties.Versions[i-1]
Jiyong Parkfce159b2018-09-20 15:24:52 +0900467 checkApiTimestamp := m.checkCompatibility(ctx, apiDirs[oldVersion], apiFiles[oldVersion], apiDirs[newVersion], apiFiles[newVersion])
468 m.checkApiTimestamps = append(m.checkApiTimestamps, checkApiTimestamp)
469 }
470 }
Jiyong Park7c3c11c2019-04-23 00:06:47 +0900471
472 // ... and that the currentVersion (ToT) is backwards compatible with or
473 // equal to the latest frozen version
474 if len(m.properties.Versions) >= 1 {
475 latestVersion := m.properties.Versions[len(m.properties.Versions)-1]
476 var checkApiTimestamp android.WritablePath
477 if ctx.Config().DefaultAppTargetSdkInt() != android.FutureApiLevel {
478 // If API is frozen, don't allow any change to the API
479 checkApiTimestamp = m.checkEquality(ctx, apiDirs[latestVersion], apiFiles[latestVersion], apiDirs[currentVersion], apiFiles[currentVersion])
480 } else {
481 // If not, allow backwards compatible changes to the API
482 checkApiTimestamp = m.checkCompatibility(ctx, apiDirs[latestVersion], apiFiles[latestVersion], apiDirs[currentVersion], apiFiles[currentVersion])
483 }
484 m.checkApiTimestamps = append(m.checkApiTimestamps, checkApiTimestamp)
485 }
Jiyong Park44837012018-08-07 00:37:34 +0900486}
487
488func (m *aidlApi) AndroidMk() android.AndroidMkData {
489 return android.AndroidMkData{
490 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
491 android.WriteAndroidMkData(w, data)
Jiyong Parkfce159b2018-09-20 15:24:52 +0900492 targetName := m.properties.BaseName + "-freeze-api"
493 fmt.Fprintln(w, ".PHONY:", targetName)
Steven Morelandb86abdd2018-12-17 14:14:52 -0800494 fmt.Fprintln(w, targetName+":", m.freezeApiTimestamp.String())
Jiyong Park44837012018-08-07 00:37:34 +0900495 },
496 }
497}
498
499func (m *aidlApi) DepsMutator(ctx android.BottomUpMutatorContext) {
500 ctx.AddDependency(ctx.Module(), nil, wrap("", m.properties.Imports, aidlInterfaceSuffix)...)
501}
502
503func aidlApiFactory() android.Module {
504 m := &aidlApi{}
505 m.AddProperties(&m.properties)
506 android.InitAndroidModule(m)
507 return m
508}
509
Steven Moreland81079f92018-07-06 16:15:53 -0700510type aidlInterfaceProperties struct {
511 // Vndk properties for interface library only.
512 cc.VndkProperties
513
514 // Whether the library can be installed on the vendor image.
515 Vendor_available *bool
Jeongik Chabe31ab42019-03-20 11:09:17 +0900516 // Top level directories for includes.
517 // TODO(b/128940869): remove it if aidl_interface can depend on framework.aidl
518 Include_dirs []string
Steven Moreland81079f92018-07-06 16:15:53 -0700519 // Relative path for includes. By default assumes AIDL path is relative to current directory.
520 // TODO(b/111117220): automatically compute by letting AIDL parse multiple files simultaneously
521 Local_include_dir string
522
523 // The owner of the module
524 Owner *string
525
Steven Morelandc2ac35c2018-10-05 09:21:46 -0700526 // List of .aidl files which compose this interface. These may be globbed.
Steven Moreland81079f92018-07-06 16:15:53 -0700527 Srcs []string
528
529 Imports []string
530
Steven Moreland81079f92018-07-06 16:15:53 -0700531 // Used by gen dependency to fill out aidl include path
Jeongik Chabe31ab42019-03-20 11:09:17 +0900532 Full_import_paths []string `blueprint:"mutated"`
Jiyong Park44837012018-08-07 00:37:34 +0900533
534 // Directory where API dumps are. Default is "api".
535 Api_dir *string
Jiyong Parkfce159b2018-09-20 15:24:52 +0900536
537 // Previous API versions that are now frozen. The version that is last in
538 // the list is considered as the most recent version.
539 Versions []string
Jiyong Parkde141b02018-10-15 22:25:32 +0900540
541 Backend struct {
542 Java struct {
543 // Whether to generate Java code using Java binder APIs
544 // Default: true
545 Enabled *bool
Jeongik Chaea68d6f2019-03-18 11:53:53 +0900546 // Set to the version of the sdk to compile against
547 // Default: system_current
548 Sdk_version *string
Jiyong Parkde141b02018-10-15 22:25:32 +0900549 }
550 Cpp struct {
551 // Whether to generate C++ code using C++ binder APIs
552 // Default: true
553 Enabled *bool
Jiyong Parkce50e262018-10-29 09:54:20 +0900554 // Whether to generate additional code for gathering information
555 // about the transactions
556 // Default: false
557 Gen_log *bool
Jiyong Parkde141b02018-10-15 22:25:32 +0900558 }
559 Ndk struct {
560 // Whether to generate C++ code using NDK binder APIs
561 // Default: true
562 Enabled *bool
Jeongik Cha37e2ad52019-04-18 13:44:26 +0900563 // Whether to generate additional code for gathering information
564 // about the transactions
565 // Default: false
566 Gen_log *bool
Jiyong Parkde141b02018-10-15 22:25:32 +0900567 }
568 }
Steven Moreland81079f92018-07-06 16:15:53 -0700569}
570
571type aidlInterface struct {
572 android.ModuleBase
573
574 properties aidlInterfaceProperties
575
Steven Morelandc2ac35c2018-10-05 09:21:46 -0700576 // Unglobbed sources
577 rawSrcs []string
Steven Moreland81079f92018-07-06 16:15:53 -0700578}
579
Jiyong Parkde141b02018-10-15 22:25:32 +0900580func (i *aidlInterface) shouldGenerateJavaBackend() bool {
Steven Moreland81079f92018-07-06 16:15:53 -0700581 // explicitly true if not specified to give early warning to devs
Jiyong Parkde141b02018-10-15 22:25:32 +0900582 return i.properties.Backend.Java.Enabled == nil || *i.properties.Backend.Java.Enabled
583}
584
585func (i *aidlInterface) shouldGenerateCppBackend() bool {
586 // explicitly true if not specified to give early warning to devs
587 return i.properties.Backend.Cpp.Enabled == nil || *i.properties.Backend.Cpp.Enabled
588}
589
590func (i *aidlInterface) shouldGenerateNdkBackend() bool {
591 // explicitly true if not specified to give early warning to devs
592 return i.properties.Backend.Ndk.Enabled == nil || *i.properties.Backend.Ndk.Enabled
Steven Moreland81079f92018-07-06 16:15:53 -0700593}
594
595func (i *aidlInterface) checkAndUpdateSources(mctx android.LoadHookContext) {
Steven Morelandc2ac35c2018-10-05 09:21:46 -0700596 prefix := mctx.ModuleDir()
597 for _, source := range i.properties.Srcs {
598 if pathtools.IsGlob(source) {
599 globbedSrcFiles, err := mctx.GlobWithDeps(filepath.Join(prefix, source), nil)
600 if err != nil {
601 mctx.ModuleErrorf("glob: %s", err.Error())
602 }
603 for _, globbedSrc := range globbedSrcFiles {
604 relativeGlobbedSrc, err := filepath.Rel(prefix, globbedSrc)
605 if err != nil {
606 panic(err)
607 }
608
609 i.rawSrcs = append(i.rawSrcs, relativeGlobbedSrc)
610 }
611 } else {
612 i.rawSrcs = append(i.rawSrcs, source)
613 }
614 }
615
616 if len(i.rawSrcs) == 0 {
Steven Moreland81079f92018-07-06 16:15:53 -0700617 mctx.PropertyErrorf("srcs", "No sources provided.")
618 }
619
Steven Morelandc2ac35c2018-10-05 09:21:46 -0700620 for _, source := range i.rawSrcs {
Steven Moreland81079f92018-07-06 16:15:53 -0700621 if !strings.HasSuffix(source, ".aidl") {
622 mctx.PropertyErrorf("srcs", "Source must be a .aidl file: "+source)
623 continue
624 }
625
Steven Moreland81079f92018-07-06 16:15:53 -0700626 relativePath, err := filepath.Rel(i.properties.Local_include_dir, source)
627 if err != nil || !isRelativePath(relativePath) {
628 mctx.PropertyErrorf("srcs", "Source is not in local_include_dir: "+source)
629 }
Steven Moreland81079f92018-07-06 16:15:53 -0700630 }
631}
632
633func (i *aidlInterface) checkImports(mctx android.LoadHookContext) {
634 for _, anImport := range i.properties.Imports {
635 other := lookupInterface(anImport)
636
637 if other == nil {
638 mctx.PropertyErrorf("imports", "Import does not exist: "+anImport)
639 }
640
Jiyong Parkde141b02018-10-15 22:25:32 +0900641 if i.shouldGenerateCppBackend() && !other.shouldGenerateCppBackend() {
642 mctx.PropertyErrorf("backend.cpp.enabled",
643 "C++ backend not enabled in the imported AIDL interface %q", anImport)
644 }
645
646 if i.shouldGenerateNdkBackend() && !other.shouldGenerateNdkBackend() {
647 mctx.PropertyErrorf("backend.ndk.enabled",
648 "NDK backend not enabled in the imported AIDL interface %q", anImport)
Steven Moreland81079f92018-07-06 16:15:53 -0700649 }
650 }
651}
652
Jiyong Parkfce159b2018-09-20 15:24:52 +0900653func (i *aidlInterface) versionedName(version string) string {
654 name := i.ModuleBase.Name()
Jiyong Park965c5b92018-11-21 13:37:15 +0900655 if version != futureVersion && version != "" {
Jiyong Parkfce159b2018-09-20 15:24:52 +0900656 name = name + "-V" + version
657 }
658 return name
659}
660
661func (i *aidlInterface) srcsForVersion(mctx android.LoadHookContext, version string) (srcs []string, base string) {
Jiyong Park965c5b92018-11-21 13:37:15 +0900662 if version == futureVersion || version == "" {
Steven Morelandc2ac35c2018-10-05 09:21:46 -0700663 return i.rawSrcs, i.properties.Local_include_dir
Jiyong Parkfce159b2018-09-20 15:24:52 +0900664 } else {
665 var apiDir string
666 if i.properties.Api_dir != nil {
667 apiDir = *(i.properties.Api_dir)
668 } else {
669 apiDir = "api"
670 }
671 base = filepath.Join(apiDir, version)
Steven Morelandc2ac35c2018-10-05 09:21:46 -0700672 full_paths, err := mctx.GlobWithDeps(filepath.Join(mctx.ModuleDir(), base, "**/*.aidl"), nil)
673 if err != nil {
674 panic(err)
675 }
Jiyong Parkfce159b2018-09-20 15:24:52 +0900676 for _, path := range full_paths {
677 // Here, we need path local to the module
678 srcs = append(srcs, strings.TrimPrefix(path, mctx.ModuleDir()+"/"))
679 }
680 return srcs, base
681 }
682}
683
Steven Moreland81079f92018-07-06 16:15:53 -0700684func aidlInterfaceHook(mctx android.LoadHookContext, i *aidlInterface) {
685 if !isRelativePath(i.properties.Local_include_dir) {
686 mctx.PropertyErrorf("local_include_dir", "must be relative path: "+i.properties.Local_include_dir)
687 }
Jeongik Chabe31ab42019-03-20 11:09:17 +0900688 var importPaths []string
689 importPaths = append(importPaths, filepath.Join(mctx.ModuleDir(), i.properties.Local_include_dir))
690 importPaths = append(importPaths, i.properties.Include_dirs...)
Steven Moreland81079f92018-07-06 16:15:53 -0700691
Jeongik Chabe31ab42019-03-20 11:09:17 +0900692 i.properties.Full_import_paths = importPaths
Steven Moreland81079f92018-07-06 16:15:53 -0700693
694 i.checkAndUpdateSources(mctx)
695 i.checkImports(mctx)
696
697 if mctx.Failed() {
698 return
699 }
700
701 var libs []string
702
Jiyong Park965c5b92018-11-21 13:37:15 +0900703 currentVersion := ""
704 if len(i.properties.Versions) > 0 {
705 currentVersion = futureVersion
706 }
707
Jiyong Parkde141b02018-10-15 22:25:32 +0900708 if i.shouldGenerateCppBackend() {
Jiyong Park965c5b92018-11-21 13:37:15 +0900709 libs = append(libs, addCppLibrary(mctx, i, currentVersion, langCpp))
Jiyong Parkfce159b2018-09-20 15:24:52 +0900710 for _, version := range i.properties.Versions {
Steven Morelandc26d8142018-09-17 14:25:33 -0700711 addCppLibrary(mctx, i, version, langCpp)
Jiyong Parkde141b02018-10-15 22:25:32 +0900712 }
713 }
714
715 if i.shouldGenerateNdkBackend() {
Steven Morelandbaab7f42019-02-11 12:38:56 -0800716 // TODO(b/119771576): inherit properties and export 'is vendor' computation from cc.go
717 if !proptools.Bool(i.properties.Vendor_available) {
718 libs = append(libs, addCppLibrary(mctx, i, currentVersion, langNdk))
719 for _, version := range i.properties.Versions {
720 addCppLibrary(mctx, i, version, langNdk)
721 }
Jiyong Parkfce159b2018-09-20 15:24:52 +0900722 }
Steven Morelandbaab7f42019-02-11 12:38:56 -0800723 // TODO(b/121157555): combine with '-ndk' variant
Steven Morelandcfc85f42018-12-13 12:11:11 -0800724 libs = append(libs, addCppLibrary(mctx, i, currentVersion, langNdkPlatform))
725 for _, version := range i.properties.Versions {
726 addCppLibrary(mctx, i, version, langNdkPlatform)
727 }
Steven Moreland81079f92018-07-06 16:15:53 -0700728 }
729
Jiyong Park965c5b92018-11-21 13:37:15 +0900730 libs = append(libs, addJavaLibrary(mctx, i, currentVersion))
Jiyong Parkfce159b2018-09-20 15:24:52 +0900731 for _, version := range i.properties.Versions {
732 addJavaLibrary(mctx, i, version)
733 }
Steven Moreland81079f92018-07-06 16:15:53 -0700734
Jiyong Park03e055a2018-08-27 15:24:36 +0900735 addApiModule(mctx, i)
Jiyong Park44837012018-08-07 00:37:34 +0900736
Steven Moreland81079f92018-07-06 16:15:53 -0700737 // Reserve this module name for future use
738 mctx.CreateModule(android.ModuleFactoryAdaptor(phony.PhonyFactory), &phonyProperties{
739 Name: proptools.StringPtr(i.ModuleBase.Name()),
740 Required: libs,
741 })
742}
743
Steven Morelandc26d8142018-09-17 14:25:33 -0700744func addCppLibrary(mctx android.LoadHookContext, i *aidlInterface, version string, lang string) string {
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900745 cppSourceGen := i.versionedName(version) + "-" + lang + "-source"
Steven Morelandc26d8142018-09-17 14:25:33 -0700746 cppModuleGen := i.versionedName(version) + "-" + lang
Jiyong Parkfce159b2018-09-20 15:24:52 +0900747
748 srcs, base := i.srcsForVersion(mctx, version)
749 if len(srcs) == 0 {
750 // This can happen when the version is about to be frozen; the version
751 // directory is created but API dump hasn't been copied there.
752 // Don't create a library for the yet-to-be-frozen version.
753 return ""
754 }
Steven Moreland81079f92018-07-06 16:15:53 -0700755
Jiyong Parkce50e262018-10-29 09:54:20 +0900756 genLog := false
757 if lang == langCpp {
758 genLog = proptools.Bool(i.properties.Backend.Cpp.Gen_log)
Jeongik Cha37e2ad52019-04-18 13:44:26 +0900759 } else if lang == langNdk || lang == langNdkPlatform {
760 genLog = proptools.Bool(i.properties.Backend.Ndk.Gen_log)
Jiyong Parkce50e262018-10-29 09:54:20 +0900761 }
762
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900763 mctx.CreateModule(android.ModuleFactoryAdaptor(aidlGenFactory), &nameProperties{
764 Name: proptools.StringPtr(cppSourceGen),
765 }, &aidlGenProperties{
766 Srcs: srcs,
767 AidlRoot: base,
768 Imports: concat(i.properties.Imports, []string{i.ModuleBase.Name()}),
769 Lang: lang,
770 BaseName: i.ModuleBase.Name(),
771 GenLog: genLog,
772 Version: version,
773 })
Steven Moreland81079f92018-07-06 16:15:53 -0700774
Steven Morelandc26d8142018-09-17 14:25:33 -0700775 importExportDependencies := wrap("", i.properties.Imports, "-"+lang)
Jeongik Chae072e6c2019-02-22 18:36:33 +0900776 var libJSONCppDependency []string
Jeongik Cha37e2ad52019-04-18 13:44:26 +0900777 var staticLibDependency []string
Steven Morelandc26d8142018-09-17 14:25:33 -0700778 var sdkVersion *string
779 var stl *string
Steven Moreland63492e62018-11-14 14:36:13 -0800780 var cpp_std *string
Steven Morelandc26d8142018-09-17 14:25:33 -0700781 if lang == langCpp {
782 importExportDependencies = append(importExportDependencies, "libbinder", "libutils")
Jiyong Parkce50e262018-10-29 09:54:20 +0900783 if genLog {
Jeongik Chae072e6c2019-02-22 18:36:33 +0900784 libJSONCppDependency = []string{"libjsoncpp"}
Jiyong Parkce50e262018-10-29 09:54:20 +0900785 }
Steven Morelandc26d8142018-09-17 14:25:33 -0700786 sdkVersion = nil
787 stl = nil
Steven Moreland63492e62018-11-14 14:36:13 -0800788 cpp_std = nil
Steven Morelandc26d8142018-09-17 14:25:33 -0700789 } else if lang == langNdk {
790 importExportDependencies = append(importExportDependencies, "libbinder_ndk")
Jeongik Cha37e2ad52019-04-18 13:44:26 +0900791 if genLog {
792 staticLibDependency = []string{"libjsoncpp_ndk"}
793 }
Steven Morelandc26d8142018-09-17 14:25:33 -0700794 sdkVersion = proptools.StringPtr("current")
795 stl = proptools.StringPtr("c++_shared")
Steven Morelandcfc85f42018-12-13 12:11:11 -0800796 } else if lang == langNdkPlatform {
797 importExportDependencies = append(importExportDependencies, "libbinder_ndk")
Jeongik Cha37e2ad52019-04-18 13:44:26 +0900798 if genLog {
799 libJSONCppDependency = []string{"libjsoncpp"}
800 }
Steven Morelandc26d8142018-09-17 14:25:33 -0700801 } else {
802 panic("Unrecognized language: " + lang)
803 }
Steven Moreland81079f92018-07-06 16:15:53 -0700804
805 mctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &ccProperties{
806 Name: proptools.StringPtr(cppModuleGen),
807 Owner: i.properties.Owner,
808 Vendor_available: i.properties.Vendor_available,
809 Defaults: []string{"aidl-cpp-module-defaults"},
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900810 Generated_sources: []string{cppSourceGen},
811 Generated_headers: []string{cppSourceGen},
812 Export_generated_headers: []string{cppSourceGen},
Jeongik Chae072e6c2019-02-22 18:36:33 +0900813 Static: staticLib{Whole_static_libs: libJSONCppDependency},
814 Shared: sharedLib{Shared_libs: libJSONCppDependency, Export_shared_lib_headers: libJSONCppDependency},
Jeongik Cha37e2ad52019-04-18 13:44:26 +0900815 Static_libs: staticLibDependency,
Steven Moreland81079f92018-07-06 16:15:53 -0700816 Shared_libs: importExportDependencies,
817 Export_shared_lib_headers: importExportDependencies,
Steven Morelandc26d8142018-09-17 14:25:33 -0700818 Sdk_version: sdkVersion,
819 Stl: stl,
Steven Moreland63492e62018-11-14 14:36:13 -0800820 Cpp_std: cpp_std,
Steven Moreland92b3a852018-12-12 13:08:49 -0800821 Cflags: []string{"-Wextra", "-Wall", "-Werror"},
Steven Moreland81079f92018-07-06 16:15:53 -0700822 }, &i.properties.VndkProperties)
823
824 return cppModuleGen
825}
826
Jiyong Parkfce159b2018-09-20 15:24:52 +0900827func addJavaLibrary(mctx android.LoadHookContext, i *aidlInterface, version string) string {
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900828 javaSourceGen := i.versionedName(version) + "-java-source"
Jiyong Parkfce159b2018-09-20 15:24:52 +0900829 javaModuleGen := i.versionedName(version) + "-java"
830
831 srcs, base := i.srcsForVersion(mctx, version)
832 if len(srcs) == 0 {
833 // This can happen when the version is about to be frozen; the version
834 // directory is created but API dump hasn't been copied there.
835 // Don't create a library for the yet-to-be-frozen version.
836 return ""
837 }
Steven Moreland81079f92018-07-06 16:15:53 -0700838
Jeongik Chaea68d6f2019-03-18 11:53:53 +0900839 sdkVersion := proptools.StringDefault(i.properties.Backend.Java.Sdk_version, "system_current")
Steven Moreland81079f92018-07-06 16:15:53 -0700840
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900841 mctx.CreateModule(android.ModuleFactoryAdaptor(aidlGenFactory), &nameProperties{
842 Name: proptools.StringPtr(javaSourceGen),
843 }, &aidlGenProperties{
844 Srcs: srcs,
845 AidlRoot: base,
846 Imports: concat(i.properties.Imports, []string{i.ModuleBase.Name()}),
847 Lang: langJava,
848 BaseName: i.ModuleBase.Name(),
849 Version: version,
850 })
Steven Moreland81079f92018-07-06 16:15:53 -0700851
852 mctx.CreateModule(android.ModuleFactoryAdaptor(java.LibraryFactory), &javaProperties{
853 Name: proptools.StringPtr(javaModuleGen),
854 Owner: i.properties.Owner,
855 Installable: proptools.BoolPtr(true),
856 Defaults: []string{"aidl-java-module-defaults"},
857 No_framework_libs: proptools.BoolPtr(true),
Jeongik Chaea68d6f2019-03-18 11:53:53 +0900858 Sdk_version: proptools.StringPtr(sdkVersion),
Steven Moreland81079f92018-07-06 16:15:53 -0700859 Static_libs: wrap("", i.properties.Imports, "-java"),
Jiyong Parkb8dceed2019-04-07 00:08:13 +0900860 Srcs: []string{":" + javaSourceGen},
Steven Moreland81079f92018-07-06 16:15:53 -0700861 })
862
863 return javaModuleGen
864}
865
Jiyong Park03e055a2018-08-27 15:24:36 +0900866func addApiModule(mctx android.LoadHookContext, i *aidlInterface) string {
867 apiModule := i.ModuleBase.Name() + aidlApiSuffix
Jiyong Park44837012018-08-07 00:37:34 +0900868 mctx.CreateModule(android.ModuleFactoryAdaptor(aidlApiFactory), &nameProperties{
Jiyong Park03e055a2018-08-27 15:24:36 +0900869 Name: proptools.StringPtr(apiModule),
Jiyong Park44837012018-08-07 00:37:34 +0900870 }, &aidlApiProperties{
Jiyong Parkfce159b2018-09-20 15:24:52 +0900871 BaseName: i.ModuleBase.Name(),
Steven Morelandc2ac35c2018-10-05 09:21:46 -0700872 Inputs: i.rawSrcs,
Jiyong Parke59c3682018-09-11 23:10:25 +0900873 Imports: concat(i.properties.Imports, []string{i.ModuleBase.Name()}),
874 Api_dir: i.properties.Api_dir,
875 AidlRoot: i.properties.Local_include_dir,
Jiyong Parkfce159b2018-09-20 15:24:52 +0900876 Versions: i.properties.Versions,
Jiyong Park44837012018-08-07 00:37:34 +0900877 })
Jiyong Park03e055a2018-08-27 15:24:36 +0900878 return apiModule
Jiyong Park44837012018-08-07 00:37:34 +0900879}
880
Steven Moreland81079f92018-07-06 16:15:53 -0700881func (i *aidlInterface) Name() string {
882 return i.ModuleBase.Name() + aidlInterfaceSuffix
883}
884func (i *aidlInterface) GenerateAndroidBuildActions(ctx android.ModuleContext) {
885}
886func (i *aidlInterface) DepsMutator(ctx android.BottomUpMutatorContext) {
887}
888
889var aidlInterfaceMutex sync.Mutex
890var aidlInterfaces []*aidlInterface
891
892func aidlInterfaceFactory() android.Module {
893 i := &aidlInterface{}
894 i.AddProperties(&i.properties)
895 android.InitAndroidModule(i)
896 android.AddLoadHook(i, func(ctx android.LoadHookContext) { aidlInterfaceHook(ctx, i) })
897
898 aidlInterfaceMutex.Lock()
899 aidlInterfaces = append(aidlInterfaces, i)
900 aidlInterfaceMutex.Unlock()
901
902 return i
903}
904
905func lookupInterface(name string) *aidlInterface {
906 for _, i := range aidlInterfaces {
907 if i.ModuleBase.Name() == name {
908 return i
909 }
910 }
911 return nil
912}
Andrei Onea8714b022019-02-01 18:55:54 +0000913
914type aidlMappingProperties struct {
915 // Source file of this prebuilt.
916 Srcs []string `android:"arch_variant"`
917 Output string
918}
919
920type aidlMapping struct {
921 android.ModuleBase
922 properties aidlMappingProperties
923 outputFilePath android.WritablePath
924}
925
926func (s *aidlMapping) DepsMutator(ctx android.BottomUpMutatorContext) {
927 android.ExtractSourcesDeps(ctx, s.properties.Srcs)
928}
929
Andrei Onea8714b022019-02-01 18:55:54 +0000930func (s *aidlMapping) GenerateAndroidBuildActions(ctx android.ModuleContext) {
931 var srcs android.Paths
Colin Crosse782c9e2019-06-03 15:44:25 -0700932 var allImportDirs []string
933 seenImportDirs := make(map[string]bool)
934
935 addImportDirs := func(dirs ...string) {
936 for _, dir := range dirs {
937 if !seenImportDirs[dir] {
938 allImportDirs = append(allImportDirs, dir)
939 seenImportDirs[dir] = true
940 }
941 }
942 }
Andrei Onea8714b022019-02-01 18:55:54 +0000943
944 ctx.VisitDirectDeps(func(module android.Module) {
945 for _, property := range module.GetProperties() {
946 if jproperty, ok := property.(*java.CompilerProperties); ok {
947 for _, src := range jproperty.Srcs {
948 if strings.HasSuffix(src, ".aidl") {
949 full_path := android.PathForModuleSrc(ctx, src)
950 srcs = append(srcs, full_path)
Colin Crosse782c9e2019-06-03 15:44:25 -0700951 addImportDirs(filepath.Dir(full_path.String()))
Andrei Onea8714b022019-02-01 18:55:54 +0000952 } else if pathtools.IsGlob(src) {
953 globbedSrcFiles, err := ctx.GlobWithDeps(src, nil)
954 if err == nil {
955 for _, globbedSrc := range globbedSrcFiles {
956 full_path := android.PathForModuleSrc(ctx, globbedSrc)
Colin Crosse782c9e2019-06-03 15:44:25 -0700957 addImportDirs(full_path.String())
Andrei Onea8714b022019-02-01 18:55:54 +0000958 }
959 }
960 }
961 }
962 } else if jproperty, ok := property.(*java.CompilerDeviceProperties); ok {
Colin Crosse782c9e2019-06-03 15:44:25 -0700963 addImportDirs(jproperty.Aidl.Include_dirs...)
Andrei Onea8714b022019-02-01 18:55:54 +0000964 for _, include_dir := range jproperty.Aidl.Export_include_dirs {
965 var full_path = filepath.Join(ctx.ModuleDir(), include_dir)
Colin Crosse782c9e2019-06-03 15:44:25 -0700966 addImportDirs(full_path)
Andrei Onea8714b022019-02-01 18:55:54 +0000967 }
968 for _, include_dir := range jproperty.Aidl.Local_include_dirs {
969 var full_path = filepath.Join(ctx.ModuleSubDir(), include_dir)
Colin Crosse782c9e2019-06-03 15:44:25 -0700970 addImportDirs(full_path)
Andrei Onea8714b022019-02-01 18:55:54 +0000971 }
972 }
973 }
974 })
975
Colin Crosse782c9e2019-06-03 15:44:25 -0700976 imports := strings.Join(wrap("-I", allImportDirs, ""), " ")
Andrei Onea8714b022019-02-01 18:55:54 +0000977 s.outputFilePath = android.PathForModuleOut(ctx, s.properties.Output)
978 outDir := android.PathForModuleGen(ctx)
979 ctx.Build(pctx, android.BuildParams{
980 Rule: aidlDumpMappingsRule,
981 Inputs: srcs,
982 Output: s.outputFilePath,
983 Args: map[string]string{
984 "imports": imports,
985 "outDir": outDir.String(),
986 },
987 })
988}
989
990func InitAidlMappingModule(s *aidlMapping) {
991 s.AddProperties(&s.properties)
992}
993
994func aidlMappingFactory() android.Module {
995 module := &aidlMapping{}
996 InitAidlMappingModule(module)
997 android.InitAndroidModule(module)
998 return module
999}
1000
1001func (m *aidlMapping) AndroidMk() android.AndroidMkData {
1002 return android.AndroidMkData{
1003 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
1004 android.WriteAndroidMkData(w, data)
1005 targetName := m.Name()
1006 fmt.Fprintln(w, ".PHONY:", targetName)
1007 fmt.Fprintln(w, targetName+":", m.outputFilePath.String())
1008 },
1009 }
1010}
Jiyong Park09e8cb42019-05-31 09:38:19 +09001011
1012func allAidlInterfacesMakeVars(ctx android.MakeVarsContext) {
1013 names := []string{}
1014 ctx.VisitAllModules(func(module android.Module) {
1015 if ai, ok := module.(*aidlInterface); ok {
1016 names = append(names, ai.Name())
1017 }
1018 })
1019 ctx.Strict("ALL_AIDL_INTERFACES", strings.Join(names, " "))
1020}