blob: 1860ecb9b6522a20d5e5a2266f521d87696d8f37 [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
130
131 if hod == HostAndDeviceSupported {
132 // Default to module to device supported, host not supported, can override in module
133 // properties
134 base.hostAndDeviceProperties.Device_supported = true
135 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
136 }
137
138 return InitArchModule(m, defaultMultilib, propertyStructs...)
139}
140
141// A AndroidModuleBase object contains the properties that are common to all Android
142// modules. It should be included as an anonymous field in every module
143// struct definition. InitAndroidModule should then be called from the module's
144// factory function, and the return values from InitAndroidModule should be
145// returned from the factory function.
146//
147// The AndroidModuleBase type is responsible for implementing the
148// GenerateBuildActions method to support the blueprint.Module interface. This
149// method will then call the module's GenerateAndroidBuildActions method once
150// for each build variant that is to be built. GenerateAndroidBuildActions is
151// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
152// AndroidModuleContext exposes extra functionality specific to the Android build
153// system including details about the particular build variant that is to be
154// generated.
155//
156// For example:
157//
158// import (
159// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700160// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800161// )
162//
163// type myModule struct {
164// common.AndroidModuleBase
165// properties struct {
166// MyProperty string
167// }
168// }
169//
170// func NewMyModule() (blueprint.Module, []interface{}) {
171// m := &myModule{}
172// return common.InitAndroidModule(m, &m.properties)
173// }
174//
175// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
176// // Get the CPU architecture for the current build variant.
177// variantArch := ctx.Arch()
178//
179// // ...
180// }
181type AndroidModuleBase struct {
182 // Putting the curiously recurring thing pointing to the thing that contains
183 // the thing pattern to good use.
184 module AndroidModule
185
186 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700187 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800188 hostAndDeviceProperties hostAndDeviceProperties
189 generalProperties []interface{}
190 archProperties []*archProperties
191
192 noAddressSanitizer bool
193 installFiles []string
194 checkbuildFiles []string
Colin Cross1f8c52b2015-06-16 16:38:17 -0700195
196 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
197 // Only set on the final variant of each module
198 installTarget string
199 checkbuildTarget string
200 blueprintDir string
Colin Cross3f40fa42015-01-30 17:27:36 -0800201}
202
203func (a *AndroidModuleBase) base() *AndroidModuleBase {
204 return a
205}
206
Colin Crossd3ba0392015-05-07 14:11:29 -0700207func (a *AndroidModuleBase) SetHostOrDevice(hod HostOrDevice) {
208 a.commonProperties.CompileHostOrDevice = hod
209}
210
Colin Cross3f40fa42015-01-30 17:27:36 -0800211func (a *AndroidModuleBase) SetArch(arch Arch) {
212 a.commonProperties.CompileArch = arch
213}
214
215func (a *AndroidModuleBase) HostOrDevice() HostOrDevice {
Colin Crossd3ba0392015-05-07 14:11:29 -0700216 return a.commonProperties.CompileHostOrDevice
Colin Cross3f40fa42015-01-30 17:27:36 -0800217}
218
219func (a *AndroidModuleBase) HostSupported() bool {
220 return a.commonProperties.HostOrDeviceSupported == HostSupported ||
221 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
222 a.hostAndDeviceProperties.Host_supported
223}
224
225func (a *AndroidModuleBase) DeviceSupported() bool {
226 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
227 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
228 a.hostAndDeviceProperties.Device_supported
229}
230
231func (a *AndroidModuleBase) Disabled() bool {
232 return a.commonProperties.Disabled
233}
234
235func (a *AndroidModuleBase) computeInstallDeps(
236 ctx blueprint.ModuleContext) []string {
237
238 result := []string{}
239 ctx.VisitDepsDepthFirstIf(isFileInstaller,
240 func(m blueprint.Module) {
241 fileInstaller := m.(fileInstaller)
242 files := fileInstaller.filesToInstall()
243 result = append(result, files...)
244 })
245
246 return result
247}
248
249func (a *AndroidModuleBase) filesToInstall() []string {
250 return a.installFiles
251}
252
253func (p *AndroidModuleBase) NoAddressSanitizer() bool {
254 return p.noAddressSanitizer
255}
256
Colin Cross3f40fa42015-01-30 17:27:36 -0800257func (a *AndroidModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
258 if a != ctx.FinalModule().(AndroidModule).base() {
259 return
260 }
261
262 allInstalledFiles := []string{}
Colin Cross9454bfa2015-03-17 13:24:18 -0700263 allCheckbuildFiles := []string{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800264 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Crossc9404352015-03-26 16:10:12 -0700265 a := module.(AndroidModule).base()
266 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
267 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800268 })
269
Colin Cross9454bfa2015-03-17 13:24:18 -0700270 deps := []string{}
271
Colin Cross3f40fa42015-01-30 17:27:36 -0800272 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700273 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800274 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700275 Rule: blueprint.Phony,
276 Outputs: []string{name},
277 Implicits: allInstalledFiles,
278 })
279 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700280 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700281 }
282
283 if len(allCheckbuildFiles) > 0 {
284 name := ctx.ModuleName() + "-checkbuild"
285 ctx.Build(pctx, blueprint.BuildParams{
286 Rule: blueprint.Phony,
287 Outputs: []string{name},
288 Implicits: allCheckbuildFiles,
289 Optional: true,
290 })
291 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700292 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700293 }
294
295 if len(deps) > 0 {
296 ctx.Build(pctx, blueprint.BuildParams{
297 Rule: blueprint.Phony,
298 Outputs: []string{ctx.ModuleName()},
299 Implicits: deps,
300 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800301 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700302
303 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800304 }
305}
306
Colin Cross6362e272015-10-29 15:25:03 -0700307func (a *AndroidModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
308 return androidBaseContextImpl{
309 arch: a.commonProperties.CompileArch,
310 hod: a.commonProperties.CompileHostOrDevice,
311 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800312 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800313}
314
315func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
316 androidCtx := &androidModuleContext{
Colin Cross6362e272015-10-29 15:25:03 -0700317 ModuleContext: ctx,
318 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
319 installDeps: a.computeInstallDeps(ctx),
320 installFiles: a.installFiles,
Colin Cross3f40fa42015-01-30 17:27:36 -0800321 }
322
323 if a.commonProperties.Disabled {
324 return
325 }
326
327 a.module.GenerateAndroidBuildActions(androidCtx)
328 if ctx.Failed() {
329 return
330 }
331
Colin Crossc9404352015-03-26 16:10:12 -0700332 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
333 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
334
Colin Cross3f40fa42015-01-30 17:27:36 -0800335 a.generateModuleTarget(ctx)
336 if ctx.Failed() {
337 return
338 }
339}
340
Colin Crossf6566ed2015-03-24 11:13:38 -0700341type androidBaseContextImpl struct {
Colin Cross1332b002015-04-07 17:11:30 -0700342 arch Arch
Colin Crossd3ba0392015-05-07 14:11:29 -0700343 hod HostOrDevice
Colin Cross1332b002015-04-07 17:11:30 -0700344 debug bool
345 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700346}
347
Colin Cross3f40fa42015-01-30 17:27:36 -0800348type androidModuleContext struct {
349 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700350 androidBaseContextImpl
Colin Cross06a931b2015-10-28 17:23:31 -0700351 installDeps []string
352 installFiles []string
353 checkbuildFiles []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800354}
355
356func (a *androidModuleContext) Build(pctx *blueprint.PackageContext, params blueprint.BuildParams) {
357 params.Optional = true
358 a.ModuleContext.Build(pctx, params)
359}
360
Colin Crossf6566ed2015-03-24 11:13:38 -0700361func (a *androidBaseContextImpl) Arch() Arch {
Colin Cross3f40fa42015-01-30 17:27:36 -0800362 return a.arch
363}
364
Colin Crossd3ba0392015-05-07 14:11:29 -0700365func (a *androidBaseContextImpl) HostOrDevice() HostOrDevice {
366 return a.hod
367}
368
Colin Crossf6566ed2015-03-24 11:13:38 -0700369func (a *androidBaseContextImpl) Host() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700370 return a.hod.Host()
Colin Crossf6566ed2015-03-24 11:13:38 -0700371}
372
373func (a *androidBaseContextImpl) Device() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700374 return a.hod.Device()
Colin Crossf6566ed2015-03-24 11:13:38 -0700375}
376
Colin Cross0af4b842015-04-30 16:36:18 -0700377func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700378 return a.hod.Host() && runtime.GOOS == "darwin"
Colin Cross0af4b842015-04-30 16:36:18 -0700379}
380
Colin Crossf6566ed2015-03-24 11:13:38 -0700381func (a *androidBaseContextImpl) Debug() bool {
382 return a.debug
383}
384
Colin Cross1332b002015-04-07 17:11:30 -0700385func (a *androidBaseContextImpl) AConfig() Config {
386 return a.config
387}
388
Colin Cross35cec122015-04-02 14:37:16 -0700389func (a *androidModuleContext) InstallFileName(installPath, name, srcPath string,
390 deps ...string) string {
391
Colin Cross1332b002015-04-07 17:11:30 -0700392 config := a.AConfig()
Colin Cross3f40fa42015-01-30 17:27:36 -0800393 var fullInstallPath string
Colin Crossd3ba0392015-05-07 14:11:29 -0700394 if a.hod.Device() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800395 // TODO: replace unset with a device name once we have device targeting
Colin Cross35cec122015-04-02 14:37:16 -0700396 fullInstallPath = filepath.Join(config.DeviceOut(), "system",
397 installPath, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800398 } else {
Colin Cross35cec122015-04-02 14:37:16 -0700399 fullInstallPath = filepath.Join(config.HostOut(), installPath, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800400 }
401
Colin Cross35cec122015-04-02 14:37:16 -0700402 deps = append(deps, a.installDeps...)
403
Colin Cross3f40fa42015-01-30 17:27:36 -0800404 a.ModuleContext.Build(pctx, blueprint.BuildParams{
405 Rule: Cp,
406 Outputs: []string{fullInstallPath},
407 Inputs: []string{srcPath},
Colin Cross35cec122015-04-02 14:37:16 -0700408 OrderOnly: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800409 })
410
411 a.installFiles = append(a.installFiles, fullInstallPath)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700412 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700413 return fullInstallPath
414}
415
416func (a *androidModuleContext) InstallFile(installPath, srcPath string, deps ...string) string {
417 return a.InstallFileName(installPath, filepath.Base(srcPath), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800418}
419
420func (a *androidModuleContext) CheckbuildFile(srcPath string) {
421 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
422}
423
Colin Cross3f40fa42015-01-30 17:27:36 -0800424type fileInstaller interface {
425 filesToInstall() []string
426}
427
428func isFileInstaller(m blueprint.Module) bool {
429 _, ok := m.(fileInstaller)
430 return ok
431}
432
433func isAndroidModule(m blueprint.Module) bool {
434 _, ok := m.(AndroidModule)
435 return ok
436}
Colin Crossfce53272015-04-08 11:21:40 -0700437
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700438func findStringInSlice(str string, slice []string) int {
439 for i, s := range slice {
440 if s == str {
441 return i
Colin Crossfce53272015-04-08 11:21:40 -0700442 }
443 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700444 return -1
445}
446
447func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) []string {
448 prefix := ModuleSrcDir(ctx)
449 for i, e := range excludes {
450 j := findStringInSlice(e, srcFiles)
451 if j != -1 {
452 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
453 }
454
455 excludes[i] = filepath.Join(prefix, e)
456 }
457
458 for i, srcFile := range srcFiles {
459 srcFiles[i] = filepath.Join(prefix, srcFile)
460 }
Colin Crossfce53272015-04-08 11:21:40 -0700461
Colin Cross8f101b42015-06-17 15:09:06 -0700462 if !hasGlob(srcFiles) {
463 return srcFiles
464 }
465
Colin Cross8f101b42015-06-17 15:09:06 -0700466 globbedSrcFiles := make([]string, 0, len(srcFiles))
467 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700468 if glob.IsGlob(s) {
Colin Crossa819f082015-07-14 18:26:10 -0700469 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", s, excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700470 } else {
471 globbedSrcFiles = append(globbedSrcFiles, s)
472 }
473 }
474
475 return globbedSrcFiles
476}
477
Colin Crossa819f082015-07-14 18:26:10 -0700478func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) []string {
479 ret, err := Glob(ctx, filepath.Join(ModuleOutDir(ctx), outDir), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700480 if err != nil {
481 ctx.ModuleErrorf("glob: %s", err.Error())
482 }
483 return ret
Colin Crossfce53272015-04-08 11:21:40 -0700484}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700485
Colin Cross463a90e2015-06-17 14:20:06 -0700486func init() {
487 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
488}
489
Colin Cross1f8c52b2015-06-16 16:38:17 -0700490func BuildTargetSingleton() blueprint.Singleton {
491 return &buildTargetSingleton{}
492}
493
494type buildTargetSingleton struct{}
495
496func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
497 checkbuildDeps := []string{}
498
499 dirModules := make(map[string][]string)
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700500 hasBPFile := make(map[string]bool)
501 bpFiles := []string{}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700502
503 ctx.VisitAllModules(func(module blueprint.Module) {
504 if a, ok := module.(AndroidModule); ok {
505 blueprintDir := a.base().blueprintDir
506 installTarget := a.base().installTarget
507 checkbuildTarget := a.base().checkbuildTarget
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700508 bpFile := ctx.BlueprintFile(module)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700509
510 if checkbuildTarget != "" {
511 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
512 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
513 }
514
515 if installTarget != "" {
516 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
517 }
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700518
519 if !hasBPFile[bpFile] {
520 hasBPFile[bpFile] = true
521 bpFiles = append(bpFiles, bpFile)
522 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700523 }
524 })
525
526 // Create a top-level checkbuild target that depends on all modules
527 ctx.Build(pctx, blueprint.BuildParams{
528 Rule: blueprint.Phony,
529 Outputs: []string{"checkbuild"},
530 Implicits: checkbuildDeps,
531 // HACK: checkbuild should be an optional build, but force it enabled for now
532 //Optional: true,
533 })
534
535 // Create a mm/<directory> target that depends on all modules in a directory
536 dirs := sortedKeys(dirModules)
537 for _, dir := range dirs {
538 ctx.Build(pctx, blueprint.BuildParams{
539 Rule: blueprint.Phony,
540 Outputs: []string{filepath.Join("mm", dir)},
541 Implicits: dirModules[dir],
542 Optional: true,
543 })
544 }
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700545
546 // Create Android.bp->mk translation rules
547 androidMks := []string{}
548 srcDir := ctx.Config().(Config).SrcDir()
549 intermediatesDir := filepath.Join(ctx.Config().(Config).IntermediatesDir(), "androidmk")
550 sort.Strings(bpFiles)
551 for _, origBp := range bpFiles {
552 bpFile := filepath.Join(srcDir, origBp)
553 mkFile := filepath.Join(srcDir, filepath.Dir(origBp), "Android.mk")
554
555 files, err := Glob(ctx, intermediatesDir, mkFile, nil)
556 if err != nil {
557 ctx.Errorf("glob: %s", err.Error())
558 continue
559 }
560
561 // Existing Android.mk file, use that instead
562 if len(files) > 0 {
Dan Willemsencdd1a992015-06-19 14:22:08 -0700563 for _, file := range files {
564 ctx.AddNinjaFileDeps(file)
565 }
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700566 continue
567 }
568
569 transMk := filepath.Join("androidmk", "Android_"+strings.Replace(filepath.Dir(origBp), "/", "_", -1)+".mk")
570 ctx.Build(pctx, blueprint.BuildParams{
571 Rule: androidbp,
572 Outputs: []string{transMk},
573 Inputs: []string{bpFile},
574 Implicits: []string{androidbpCmd},
575 Optional: true,
576 })
577
578 androidMks = append(androidMks, transMk)
579 }
580
581 ctx.Build(pctx, blueprint.BuildParams{
582 Rule: blueprint.Phony,
583 Outputs: []string{"androidmk"},
584 Implicits: androidMks,
585 Optional: true,
586 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700587}