blob: 69da7c60164ae26291f07e5ca22fd57d1a945645 [file] [log] [blame]
Colin Cross3f40fa42015-01-30 17:27:36 -08001// Copyright 2015 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 common
16
17import (
Colin Cross463a90e2015-06-17 14:20:06 -070018 "android/soong"
Colin Cross3f40fa42015-01-30 17:27:36 -080019 "path/filepath"
Colin Cross0af4b842015-04-30 16:36:18 -070020 "runtime"
Dan Willemsenbf9207a2015-06-17 15:17:12 -070021 "sort"
22 "strings"
Colin Crossf6566ed2015-03-24 11:13:38 -070023
Colin Cross8f101b42015-06-17 15:09:06 -070024 "android/soong/glob"
25
Colin Crossf6566ed2015-03-24 11:13:38 -070026 "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -080027)
28
29var (
30 DeviceSharedLibrary = "shared_library"
31 DeviceStaticLibrary = "static_library"
32 DeviceExecutable = "executable"
33 HostSharedLibrary = "host_shared_library"
34 HostStaticLibrary = "host_static_library"
35 HostExecutable = "host_executable"
36)
37
Colin Crossf6566ed2015-03-24 11:13:38 -070038type androidBaseContext interface {
39 Arch() Arch
Colin Crossd3ba0392015-05-07 14:11:29 -070040 HostOrDevice() HostOrDevice
Colin Crossf6566ed2015-03-24 11:13:38 -070041 Host() bool
42 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070043 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070044 Debug() bool
Colin Cross1332b002015-04-07 17:11:30 -070045 AConfig() Config
Colin Crossf6566ed2015-03-24 11:13:38 -070046}
47
48type AndroidBaseContext interface {
49 blueprint.BaseModuleContext
50 androidBaseContext
51}
52
Colin Cross3f40fa42015-01-30 17:27:36 -080053type AndroidModuleContext interface {
54 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070055 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080056
Dan Willemsen2ef08f42015-06-30 18:15:24 -070057 ExpandSources(srcFiles, excludes []string) []string
Colin Crossa819f082015-07-14 18:26:10 -070058 Glob(outDir, globPattern string, excludes []string) []string
Colin Cross8f101b42015-06-17 15:09:06 -070059
Colin Cross35cec122015-04-02 14:37:16 -070060 InstallFile(installPath, srcPath string, deps ...string) string
61 InstallFileName(installPath, name, srcPath string, deps ...string) string
Colin Cross3f40fa42015-01-30 17:27:36 -080062 CheckbuildFile(srcPath string)
63}
64
65type AndroidModule interface {
66 blueprint.Module
67
68 GenerateAndroidBuildActions(AndroidModuleContext)
69
70 base() *AndroidModuleBase
71 Disabled() bool
72 HostOrDevice() HostOrDevice
73}
74
Colin Cross3f40fa42015-01-30 17:27:36 -080075type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -070076 Name string
77 Deps []string
78 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -080079
Colin Cross7d5136f2015-05-11 13:39:40 -070080 // don't emit any build rules for this module
Colin Cross3f40fa42015-01-30 17:27:36 -080081 Disabled bool `android:"arch_variant"`
82
Colin Cross7d5136f2015-05-11 13:39:40 -070083 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -080084 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
85 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
86 // platform
87 Compile_multilib string
88
Colin Crossd3ba0392015-05-07 14:11:29 -070089 // Set by HostOrDeviceMutator
90 CompileHostOrDevice HostOrDevice `blueprint:"mutated"`
91
Colin Cross3f40fa42015-01-30 17:27:36 -080092 // Set by ArchMutator
93 CompileArch Arch `blueprint:"mutated"`
94
95 // Set by InitAndroidModule
96 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
97}
98
99type hostAndDeviceProperties struct {
100 Host_supported bool
101 Device_supported bool
102}
103
Colin Crossc472d572015-03-17 15:06:21 -0700104type Multilib string
105
106const (
Colin Cross2fe66872015-03-30 17:20:39 -0700107 MultilibBoth Multilib = "both"
108 MultilibFirst Multilib = "first"
109 MultilibCommon Multilib = "common"
Colin Crossc472d572015-03-17 15:06:21 -0700110)
111
Colin Cross5049f022015-03-18 13:28:46 -0700112func InitAndroidModule(m AndroidModule,
Colin Cross3f40fa42015-01-30 17:27:36 -0800113 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
114
115 base := m.base()
116 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700117
Colin Cross7f64b6d2015-07-09 13:57:48 -0700118 propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700119
120 return m, propertyStructs
121}
122
123func InitAndroidArchModule(m AndroidModule, hod HostOrDeviceSupported, defaultMultilib Multilib,
124 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
125
126 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
127
128 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800129 base.commonProperties.HostOrDeviceSupported = hod
Colin Crosscfad1192015-11-02 16:43:11 -0800130 base.commonProperties.Compile_multilib = string(defaultMultilib)
Colin Cross3f40fa42015-01-30 17:27:36 -0800131
132 if hod == HostAndDeviceSupported {
133 // Default to module to device supported, host not supported, can override in module
134 // properties
135 base.hostAndDeviceProperties.Device_supported = true
136 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
137 }
138
Colin Crosscfad1192015-11-02 16:43:11 -0800139 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800140}
141
142// A AndroidModuleBase object contains the properties that are common to all Android
143// modules. It should be included as an anonymous field in every module
144// struct definition. InitAndroidModule should then be called from the module's
145// factory function, and the return values from InitAndroidModule should be
146// returned from the factory function.
147//
148// The AndroidModuleBase type is responsible for implementing the
149// GenerateBuildActions method to support the blueprint.Module interface. This
150// method will then call the module's GenerateAndroidBuildActions method once
151// for each build variant that is to be built. GenerateAndroidBuildActions is
152// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
153// AndroidModuleContext exposes extra functionality specific to the Android build
154// system including details about the particular build variant that is to be
155// generated.
156//
157// For example:
158//
159// import (
160// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700161// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800162// )
163//
164// type myModule struct {
165// common.AndroidModuleBase
166// properties struct {
167// MyProperty string
168// }
169// }
170//
171// func NewMyModule() (blueprint.Module, []interface{}) {
172// m := &myModule{}
173// return common.InitAndroidModule(m, &m.properties)
174// }
175//
176// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
177// // Get the CPU architecture for the current build variant.
178// variantArch := ctx.Arch()
179//
180// // ...
181// }
182type AndroidModuleBase struct {
183 // Putting the curiously recurring thing pointing to the thing that contains
184 // the thing pattern to good use.
185 module AndroidModule
186
187 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700188 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800189 hostAndDeviceProperties hostAndDeviceProperties
190 generalProperties []interface{}
191 archProperties []*archProperties
192
193 noAddressSanitizer bool
194 installFiles []string
195 checkbuildFiles []string
Colin Cross1f8c52b2015-06-16 16:38:17 -0700196
197 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
198 // Only set on the final variant of each module
199 installTarget string
200 checkbuildTarget string
201 blueprintDir string
Colin Cross3f40fa42015-01-30 17:27:36 -0800202}
203
204func (a *AndroidModuleBase) base() *AndroidModuleBase {
205 return a
206}
207
Colin Crossd3ba0392015-05-07 14:11:29 -0700208func (a *AndroidModuleBase) SetHostOrDevice(hod HostOrDevice) {
209 a.commonProperties.CompileHostOrDevice = hod
210}
211
Colin Cross3f40fa42015-01-30 17:27:36 -0800212func (a *AndroidModuleBase) SetArch(arch Arch) {
213 a.commonProperties.CompileArch = arch
214}
215
216func (a *AndroidModuleBase) HostOrDevice() HostOrDevice {
Colin Crossd3ba0392015-05-07 14:11:29 -0700217 return a.commonProperties.CompileHostOrDevice
Colin Cross3f40fa42015-01-30 17:27:36 -0800218}
219
220func (a *AndroidModuleBase) HostSupported() bool {
221 return a.commonProperties.HostOrDeviceSupported == HostSupported ||
222 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
223 a.hostAndDeviceProperties.Host_supported
224}
225
226func (a *AndroidModuleBase) DeviceSupported() bool {
227 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
228 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
229 a.hostAndDeviceProperties.Device_supported
230}
231
232func (a *AndroidModuleBase) Disabled() bool {
233 return a.commonProperties.Disabled
234}
235
236func (a *AndroidModuleBase) computeInstallDeps(
237 ctx blueprint.ModuleContext) []string {
238
239 result := []string{}
240 ctx.VisitDepsDepthFirstIf(isFileInstaller,
241 func(m blueprint.Module) {
242 fileInstaller := m.(fileInstaller)
243 files := fileInstaller.filesToInstall()
244 result = append(result, files...)
245 })
246
247 return result
248}
249
250func (a *AndroidModuleBase) filesToInstall() []string {
251 return a.installFiles
252}
253
254func (p *AndroidModuleBase) NoAddressSanitizer() bool {
255 return p.noAddressSanitizer
256}
257
Colin Cross3f40fa42015-01-30 17:27:36 -0800258func (a *AndroidModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
259 if a != ctx.FinalModule().(AndroidModule).base() {
260 return
261 }
262
263 allInstalledFiles := []string{}
Colin Cross9454bfa2015-03-17 13:24:18 -0700264 allCheckbuildFiles := []string{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800265 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Crossc9404352015-03-26 16:10:12 -0700266 a := module.(AndroidModule).base()
267 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
268 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800269 })
270
Colin Cross9454bfa2015-03-17 13:24:18 -0700271 deps := []string{}
272
Colin Cross3f40fa42015-01-30 17:27:36 -0800273 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700274 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800275 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700276 Rule: blueprint.Phony,
277 Outputs: []string{name},
278 Implicits: allInstalledFiles,
279 })
280 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700281 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700282 }
283
284 if len(allCheckbuildFiles) > 0 {
285 name := ctx.ModuleName() + "-checkbuild"
286 ctx.Build(pctx, blueprint.BuildParams{
287 Rule: blueprint.Phony,
288 Outputs: []string{name},
289 Implicits: allCheckbuildFiles,
290 Optional: true,
291 })
292 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700293 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700294 }
295
296 if len(deps) > 0 {
297 ctx.Build(pctx, blueprint.BuildParams{
298 Rule: blueprint.Phony,
299 Outputs: []string{ctx.ModuleName()},
300 Implicits: deps,
301 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800302 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700303
304 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800305 }
306}
307
Colin Cross6362e272015-10-29 15:25:03 -0700308func (a *AndroidModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
309 return androidBaseContextImpl{
310 arch: a.commonProperties.CompileArch,
311 hod: a.commonProperties.CompileHostOrDevice,
312 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800313 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800314}
315
316func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
317 androidCtx := &androidModuleContext{
Colin Cross6362e272015-10-29 15:25:03 -0700318 ModuleContext: ctx,
319 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
320 installDeps: a.computeInstallDeps(ctx),
321 installFiles: a.installFiles,
Colin Cross3f40fa42015-01-30 17:27:36 -0800322 }
323
324 if a.commonProperties.Disabled {
325 return
326 }
327
328 a.module.GenerateAndroidBuildActions(androidCtx)
329 if ctx.Failed() {
330 return
331 }
332
Colin Crossc9404352015-03-26 16:10:12 -0700333 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
334 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
335
Colin Cross3f40fa42015-01-30 17:27:36 -0800336 a.generateModuleTarget(ctx)
337 if ctx.Failed() {
338 return
339 }
340}
341
Colin Crossf6566ed2015-03-24 11:13:38 -0700342type androidBaseContextImpl struct {
Colin Cross1332b002015-04-07 17:11:30 -0700343 arch Arch
Colin Crossd3ba0392015-05-07 14:11:29 -0700344 hod HostOrDevice
Colin Cross1332b002015-04-07 17:11:30 -0700345 debug bool
346 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700347}
348
Colin Cross3f40fa42015-01-30 17:27:36 -0800349type androidModuleContext struct {
350 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700351 androidBaseContextImpl
Colin Cross06a931b2015-10-28 17:23:31 -0700352 installDeps []string
353 installFiles []string
354 checkbuildFiles []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800355}
356
357func (a *androidModuleContext) Build(pctx *blueprint.PackageContext, params blueprint.BuildParams) {
358 params.Optional = true
359 a.ModuleContext.Build(pctx, params)
360}
361
Colin Crossf6566ed2015-03-24 11:13:38 -0700362func (a *androidBaseContextImpl) Arch() Arch {
Colin Cross3f40fa42015-01-30 17:27:36 -0800363 return a.arch
364}
365
Colin Crossd3ba0392015-05-07 14:11:29 -0700366func (a *androidBaseContextImpl) HostOrDevice() HostOrDevice {
367 return a.hod
368}
369
Colin Crossf6566ed2015-03-24 11:13:38 -0700370func (a *androidBaseContextImpl) Host() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700371 return a.hod.Host()
Colin Crossf6566ed2015-03-24 11:13:38 -0700372}
373
374func (a *androidBaseContextImpl) Device() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700375 return a.hod.Device()
Colin Crossf6566ed2015-03-24 11:13:38 -0700376}
377
Colin Cross0af4b842015-04-30 16:36:18 -0700378func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700379 return a.hod.Host() && runtime.GOOS == "darwin"
Colin Cross0af4b842015-04-30 16:36:18 -0700380}
381
Colin Crossf6566ed2015-03-24 11:13:38 -0700382func (a *androidBaseContextImpl) Debug() bool {
383 return a.debug
384}
385
Colin Cross1332b002015-04-07 17:11:30 -0700386func (a *androidBaseContextImpl) AConfig() Config {
387 return a.config
388}
389
Colin Cross35cec122015-04-02 14:37:16 -0700390func (a *androidModuleContext) InstallFileName(installPath, name, srcPath string,
391 deps ...string) string {
392
Colin Cross1332b002015-04-07 17:11:30 -0700393 config := a.AConfig()
Colin Cross3f40fa42015-01-30 17:27:36 -0800394 var fullInstallPath string
Colin Crossd3ba0392015-05-07 14:11:29 -0700395 if a.hod.Device() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800396 // TODO: replace unset with a device name once we have device targeting
Colin Cross35cec122015-04-02 14:37:16 -0700397 fullInstallPath = filepath.Join(config.DeviceOut(), "system",
398 installPath, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800399 } else {
Colin Cross35cec122015-04-02 14:37:16 -0700400 fullInstallPath = filepath.Join(config.HostOut(), installPath, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800401 }
402
Colin Cross35cec122015-04-02 14:37:16 -0700403 deps = append(deps, a.installDeps...)
404
Colin Cross3f40fa42015-01-30 17:27:36 -0800405 a.ModuleContext.Build(pctx, blueprint.BuildParams{
406 Rule: Cp,
407 Outputs: []string{fullInstallPath},
408 Inputs: []string{srcPath},
Colin Cross35cec122015-04-02 14:37:16 -0700409 OrderOnly: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800410 })
411
412 a.installFiles = append(a.installFiles, fullInstallPath)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700413 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700414 return fullInstallPath
415}
416
417func (a *androidModuleContext) InstallFile(installPath, srcPath string, deps ...string) string {
418 return a.InstallFileName(installPath, filepath.Base(srcPath), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800419}
420
421func (a *androidModuleContext) CheckbuildFile(srcPath string) {
422 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
423}
424
Colin Cross3f40fa42015-01-30 17:27:36 -0800425type fileInstaller interface {
426 filesToInstall() []string
427}
428
429func isFileInstaller(m blueprint.Module) bool {
430 _, ok := m.(fileInstaller)
431 return ok
432}
433
434func isAndroidModule(m blueprint.Module) bool {
435 _, ok := m.(AndroidModule)
436 return ok
437}
Colin Crossfce53272015-04-08 11:21:40 -0700438
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700439func findStringInSlice(str string, slice []string) int {
440 for i, s := range slice {
441 if s == str {
442 return i
Colin Crossfce53272015-04-08 11:21:40 -0700443 }
444 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700445 return -1
446}
447
448func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) []string {
449 prefix := ModuleSrcDir(ctx)
450 for i, e := range excludes {
451 j := findStringInSlice(e, srcFiles)
452 if j != -1 {
453 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
454 }
455
456 excludes[i] = filepath.Join(prefix, e)
457 }
458
459 for i, srcFile := range srcFiles {
460 srcFiles[i] = filepath.Join(prefix, srcFile)
461 }
Colin Crossfce53272015-04-08 11:21:40 -0700462
Colin Cross8f101b42015-06-17 15:09:06 -0700463 if !hasGlob(srcFiles) {
464 return srcFiles
465 }
466
Colin Cross8f101b42015-06-17 15:09:06 -0700467 globbedSrcFiles := make([]string, 0, len(srcFiles))
468 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700469 if glob.IsGlob(s) {
Colin Crossa819f082015-07-14 18:26:10 -0700470 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", s, excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700471 } else {
472 globbedSrcFiles = append(globbedSrcFiles, s)
473 }
474 }
475
476 return globbedSrcFiles
477}
478
Colin Crossa819f082015-07-14 18:26:10 -0700479func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) []string {
480 ret, err := Glob(ctx, filepath.Join(ModuleOutDir(ctx), outDir), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700481 if err != nil {
482 ctx.ModuleErrorf("glob: %s", err.Error())
483 }
484 return ret
Colin Crossfce53272015-04-08 11:21:40 -0700485}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700486
Colin Cross463a90e2015-06-17 14:20:06 -0700487func init() {
488 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
489}
490
Colin Cross1f8c52b2015-06-16 16:38:17 -0700491func BuildTargetSingleton() blueprint.Singleton {
492 return &buildTargetSingleton{}
493}
494
495type buildTargetSingleton struct{}
496
497func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
498 checkbuildDeps := []string{}
499
500 dirModules := make(map[string][]string)
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700501 hasBPFile := make(map[string]bool)
502 bpFiles := []string{}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700503
504 ctx.VisitAllModules(func(module blueprint.Module) {
505 if a, ok := module.(AndroidModule); ok {
506 blueprintDir := a.base().blueprintDir
507 installTarget := a.base().installTarget
508 checkbuildTarget := a.base().checkbuildTarget
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700509 bpFile := ctx.BlueprintFile(module)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700510
511 if checkbuildTarget != "" {
512 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
513 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
514 }
515
516 if installTarget != "" {
517 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
518 }
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700519
520 if !hasBPFile[bpFile] {
521 hasBPFile[bpFile] = true
522 bpFiles = append(bpFiles, bpFile)
523 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700524 }
525 })
526
527 // Create a top-level checkbuild target that depends on all modules
528 ctx.Build(pctx, blueprint.BuildParams{
529 Rule: blueprint.Phony,
530 Outputs: []string{"checkbuild"},
531 Implicits: checkbuildDeps,
532 // HACK: checkbuild should be an optional build, but force it enabled for now
533 //Optional: true,
534 })
535
536 // Create a mm/<directory> target that depends on all modules in a directory
537 dirs := sortedKeys(dirModules)
538 for _, dir := range dirs {
539 ctx.Build(pctx, blueprint.BuildParams{
540 Rule: blueprint.Phony,
541 Outputs: []string{filepath.Join("mm", dir)},
542 Implicits: dirModules[dir],
543 Optional: true,
544 })
545 }
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700546
547 // Create Android.bp->mk translation rules
548 androidMks := []string{}
549 srcDir := ctx.Config().(Config).SrcDir()
550 intermediatesDir := filepath.Join(ctx.Config().(Config).IntermediatesDir(), "androidmk")
551 sort.Strings(bpFiles)
552 for _, origBp := range bpFiles {
553 bpFile := filepath.Join(srcDir, origBp)
554 mkFile := filepath.Join(srcDir, filepath.Dir(origBp), "Android.mk")
555
556 files, err := Glob(ctx, intermediatesDir, mkFile, nil)
557 if err != nil {
558 ctx.Errorf("glob: %s", err.Error())
559 continue
560 }
561
562 // Existing Android.mk file, use that instead
563 if len(files) > 0 {
Dan Willemsencdd1a992015-06-19 14:22:08 -0700564 for _, file := range files {
565 ctx.AddNinjaFileDeps(file)
566 }
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700567 continue
568 }
569
570 transMk := filepath.Join("androidmk", "Android_"+strings.Replace(filepath.Dir(origBp), "/", "_", -1)+".mk")
571 ctx.Build(pctx, blueprint.BuildParams{
572 Rule: androidbp,
573 Outputs: []string{transMk},
574 Inputs: []string{bpFile},
575 Implicits: []string{androidbpCmd},
576 Optional: true,
577 })
578
579 androidMks = append(androidMks, transMk)
580 }
581
582 ctx.Build(pctx, blueprint.BuildParams{
583 Rule: blueprint.Phony,
584 Outputs: []string{"androidmk"},
585 Implicits: androidMks,
586 Optional: true,
587 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700588}