blob: feaba83d43ed600966c30b9a662d40be4aad33aa [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
75type AndroidDynamicDepender interface {
76 AndroidDynamicDependencies(ctx AndroidDynamicDependerModuleContext) []string
77}
78
79type AndroidDynamicDependerModuleContext interface {
80 blueprint.DynamicDependerModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070081 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080082}
83
84type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -070085 Name string
86 Deps []string
87 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -080088
Colin Cross7d5136f2015-05-11 13:39:40 -070089 // don't emit any build rules for this module
Colin Cross3f40fa42015-01-30 17:27:36 -080090 Disabled bool `android:"arch_variant"`
91
Colin Cross7d5136f2015-05-11 13:39:40 -070092 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -080093 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
94 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
95 // platform
96 Compile_multilib string
97
Colin Crossd3ba0392015-05-07 14:11:29 -070098 // Set by HostOrDeviceMutator
99 CompileHostOrDevice HostOrDevice `blueprint:"mutated"`
100
Colin Cross3f40fa42015-01-30 17:27:36 -0800101 // Set by ArchMutator
102 CompileArch Arch `blueprint:"mutated"`
103
104 // Set by InitAndroidModule
105 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
106}
107
108type hostAndDeviceProperties struct {
109 Host_supported bool
110 Device_supported bool
111}
112
Colin Crossc472d572015-03-17 15:06:21 -0700113type Multilib string
114
115const (
Colin Cross2fe66872015-03-30 17:20:39 -0700116 MultilibBoth Multilib = "both"
117 MultilibFirst Multilib = "first"
118 MultilibCommon Multilib = "common"
Colin Crossc472d572015-03-17 15:06:21 -0700119)
120
Colin Cross5049f022015-03-18 13:28:46 -0700121func InitAndroidModule(m AndroidModule,
Colin Cross3f40fa42015-01-30 17:27:36 -0800122 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
123
124 base := m.base()
125 base.module = m
Colin Cross28d76592015-03-26 16:14:04 -0700126 base.extendedProperties = make(map[string]struct{})
Colin Cross5049f022015-03-18 13:28:46 -0700127
Colin Cross7f64b6d2015-07-09 13:57:48 -0700128 propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700129
130 return m, propertyStructs
131}
132
133func InitAndroidArchModule(m AndroidModule, hod HostOrDeviceSupported, defaultMultilib Multilib,
134 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
135
136 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
137
138 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800139 base.commonProperties.HostOrDeviceSupported = hod
140
141 if hod == HostAndDeviceSupported {
142 // Default to module to device supported, host not supported, can override in module
143 // properties
144 base.hostAndDeviceProperties.Device_supported = true
145 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
146 }
147
148 return InitArchModule(m, defaultMultilib, propertyStructs...)
149}
150
151// A AndroidModuleBase object contains the properties that are common to all Android
152// modules. It should be included as an anonymous field in every module
153// struct definition. InitAndroidModule should then be called from the module's
154// factory function, and the return values from InitAndroidModule should be
155// returned from the factory function.
156//
157// The AndroidModuleBase type is responsible for implementing the
158// GenerateBuildActions method to support the blueprint.Module interface. This
159// method will then call the module's GenerateAndroidBuildActions method once
160// for each build variant that is to be built. GenerateAndroidBuildActions is
161// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
162// AndroidModuleContext exposes extra functionality specific to the Android build
163// system including details about the particular build variant that is to be
164// generated.
165//
166// For example:
167//
168// import (
169// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700170// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800171// )
172//
173// type myModule struct {
174// common.AndroidModuleBase
175// properties struct {
176// MyProperty string
177// }
178// }
179//
180// func NewMyModule() (blueprint.Module, []interface{}) {
181// m := &myModule{}
182// return common.InitAndroidModule(m, &m.properties)
183// }
184//
185// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
186// // Get the CPU architecture for the current build variant.
187// variantArch := ctx.Arch()
188//
189// // ...
190// }
191type AndroidModuleBase struct {
192 // Putting the curiously recurring thing pointing to the thing that contains
193 // the thing pattern to good use.
194 module AndroidModule
195
196 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700197 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800198 hostAndDeviceProperties hostAndDeviceProperties
199 generalProperties []interface{}
200 archProperties []*archProperties
Colin Cross28d76592015-03-26 16:14:04 -0700201 extendedProperties map[string]struct{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800202
203 noAddressSanitizer bool
204 installFiles []string
205 checkbuildFiles []string
Colin Cross1f8c52b2015-06-16 16:38:17 -0700206
207 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
208 // Only set on the final variant of each module
209 installTarget string
210 checkbuildTarget string
211 blueprintDir string
Colin Cross3f40fa42015-01-30 17:27:36 -0800212}
213
214func (a *AndroidModuleBase) base() *AndroidModuleBase {
215 return a
216}
217
Colin Crossd3ba0392015-05-07 14:11:29 -0700218func (a *AndroidModuleBase) SetHostOrDevice(hod HostOrDevice) {
219 a.commonProperties.CompileHostOrDevice = hod
220}
221
Colin Cross3f40fa42015-01-30 17:27:36 -0800222func (a *AndroidModuleBase) SetArch(arch Arch) {
223 a.commonProperties.CompileArch = arch
224}
225
226func (a *AndroidModuleBase) HostOrDevice() HostOrDevice {
Colin Crossd3ba0392015-05-07 14:11:29 -0700227 return a.commonProperties.CompileHostOrDevice
Colin Cross3f40fa42015-01-30 17:27:36 -0800228}
229
230func (a *AndroidModuleBase) HostSupported() bool {
231 return a.commonProperties.HostOrDeviceSupported == HostSupported ||
232 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
233 a.hostAndDeviceProperties.Host_supported
234}
235
236func (a *AndroidModuleBase) DeviceSupported() bool {
237 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
238 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
239 a.hostAndDeviceProperties.Device_supported
240}
241
242func (a *AndroidModuleBase) Disabled() bool {
243 return a.commonProperties.Disabled
244}
245
246func (a *AndroidModuleBase) computeInstallDeps(
247 ctx blueprint.ModuleContext) []string {
248
249 result := []string{}
250 ctx.VisitDepsDepthFirstIf(isFileInstaller,
251 func(m blueprint.Module) {
252 fileInstaller := m.(fileInstaller)
253 files := fileInstaller.filesToInstall()
254 result = append(result, files...)
255 })
256
257 return result
258}
259
260func (a *AndroidModuleBase) filesToInstall() []string {
261 return a.installFiles
262}
263
264func (p *AndroidModuleBase) NoAddressSanitizer() bool {
265 return p.noAddressSanitizer
266}
267
Colin Cross3f40fa42015-01-30 17:27:36 -0800268func (a *AndroidModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
269 if a != ctx.FinalModule().(AndroidModule).base() {
270 return
271 }
272
273 allInstalledFiles := []string{}
Colin Cross9454bfa2015-03-17 13:24:18 -0700274 allCheckbuildFiles := []string{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800275 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Crossc9404352015-03-26 16:10:12 -0700276 a := module.(AndroidModule).base()
277 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
278 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800279 })
280
Colin Cross9454bfa2015-03-17 13:24:18 -0700281 deps := []string{}
282
Colin Cross3f40fa42015-01-30 17:27:36 -0800283 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700284 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800285 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700286 Rule: blueprint.Phony,
287 Outputs: []string{name},
288 Implicits: allInstalledFiles,
289 })
290 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700291 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700292 }
293
294 if len(allCheckbuildFiles) > 0 {
295 name := ctx.ModuleName() + "-checkbuild"
296 ctx.Build(pctx, blueprint.BuildParams{
297 Rule: blueprint.Phony,
298 Outputs: []string{name},
299 Implicits: allCheckbuildFiles,
300 Optional: true,
301 })
302 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700303 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700304 }
305
306 if len(deps) > 0 {
307 ctx.Build(pctx, blueprint.BuildParams{
308 Rule: blueprint.Phony,
309 Outputs: []string{ctx.ModuleName()},
310 Implicits: deps,
311 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800312 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700313
314 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800315 }
316}
317
318func (a *AndroidModuleBase) DynamicDependencies(ctx blueprint.DynamicDependerModuleContext) []string {
319 actx := &androidDynamicDependerContext{
320 DynamicDependerModuleContext: ctx,
Colin Crossf6566ed2015-03-24 11:13:38 -0700321 androidBaseContextImpl: androidBaseContextImpl{
Colin Cross1332b002015-04-07 17:11:30 -0700322 arch: a.commonProperties.CompileArch,
Colin Crossd3ba0392015-05-07 14:11:29 -0700323 hod: a.commonProperties.CompileHostOrDevice,
Colin Cross1332b002015-04-07 17:11:30 -0700324 config: ctx.Config().(Config),
Colin Crossf6566ed2015-03-24 11:13:38 -0700325 },
Colin Cross3f40fa42015-01-30 17:27:36 -0800326 }
327
328 if dynamic, ok := a.module.(AndroidDynamicDepender); ok {
329 return dynamic.AndroidDynamicDependencies(actx)
330 }
331
332 return nil
333}
334
335func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
336 androidCtx := &androidModuleContext{
337 ModuleContext: ctx,
Colin Crossf6566ed2015-03-24 11:13:38 -0700338 androidBaseContextImpl: androidBaseContextImpl{
Colin Cross1332b002015-04-07 17:11:30 -0700339 arch: a.commonProperties.CompileArch,
Colin Crossd3ba0392015-05-07 14:11:29 -0700340 hod: a.commonProperties.CompileHostOrDevice,
Colin Cross1332b002015-04-07 17:11:30 -0700341 config: ctx.Config().(Config),
Colin Crossf6566ed2015-03-24 11:13:38 -0700342 },
Colin Cross28d76592015-03-26 16:14:04 -0700343 installDeps: a.computeInstallDeps(ctx),
344 installFiles: a.installFiles,
345 extendedProperties: a.extendedProperties,
Colin Cross3f40fa42015-01-30 17:27:36 -0800346 }
347
348 if a.commonProperties.Disabled {
349 return
350 }
351
352 a.module.GenerateAndroidBuildActions(androidCtx)
353 if ctx.Failed() {
354 return
355 }
356
Colin Crossc9404352015-03-26 16:10:12 -0700357 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
358 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
359
Colin Cross3f40fa42015-01-30 17:27:36 -0800360 a.generateModuleTarget(ctx)
361 if ctx.Failed() {
362 return
363 }
364}
365
Colin Crossf6566ed2015-03-24 11:13:38 -0700366type androidBaseContextImpl struct {
Colin Cross1332b002015-04-07 17:11:30 -0700367 arch Arch
Colin Crossd3ba0392015-05-07 14:11:29 -0700368 hod HostOrDevice
Colin Cross1332b002015-04-07 17:11:30 -0700369 debug bool
370 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700371}
372
Colin Cross3f40fa42015-01-30 17:27:36 -0800373type androidModuleContext struct {
374 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700375 androidBaseContextImpl
Colin Cross28d76592015-03-26 16:14:04 -0700376 installDeps []string
377 installFiles []string
378 checkbuildFiles []string
379 extendedProperties map[string]struct{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800380}
381
382func (a *androidModuleContext) Build(pctx *blueprint.PackageContext, params blueprint.BuildParams) {
383 params.Optional = true
384 a.ModuleContext.Build(pctx, params)
385}
386
Colin Cross28d76592015-03-26 16:14:04 -0700387func (a *androidModuleContext) ContainsProperty(property string) bool {
388 if a.ModuleContext.ContainsProperty(property) {
389 return true
390 }
391 _, ok := a.extendedProperties[property]
392 return ok
393}
394
Colin Crossf6566ed2015-03-24 11:13:38 -0700395func (a *androidBaseContextImpl) Arch() Arch {
Colin Cross3f40fa42015-01-30 17:27:36 -0800396 return a.arch
397}
398
Colin Crossd3ba0392015-05-07 14:11:29 -0700399func (a *androidBaseContextImpl) HostOrDevice() HostOrDevice {
400 return a.hod
401}
402
Colin Crossf6566ed2015-03-24 11:13:38 -0700403func (a *androidBaseContextImpl) Host() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700404 return a.hod.Host()
Colin Crossf6566ed2015-03-24 11:13:38 -0700405}
406
407func (a *androidBaseContextImpl) Device() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700408 return a.hod.Device()
Colin Crossf6566ed2015-03-24 11:13:38 -0700409}
410
Colin Cross0af4b842015-04-30 16:36:18 -0700411func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700412 return a.hod.Host() && runtime.GOOS == "darwin"
Colin Cross0af4b842015-04-30 16:36:18 -0700413}
414
Colin Crossf6566ed2015-03-24 11:13:38 -0700415func (a *androidBaseContextImpl) Debug() bool {
416 return a.debug
417}
418
Colin Cross1332b002015-04-07 17:11:30 -0700419func (a *androidBaseContextImpl) AConfig() Config {
420 return a.config
421}
422
Colin Cross35cec122015-04-02 14:37:16 -0700423func (a *androidModuleContext) InstallFileName(installPath, name, srcPath string,
424 deps ...string) string {
425
Colin Cross1332b002015-04-07 17:11:30 -0700426 config := a.AConfig()
Colin Cross3f40fa42015-01-30 17:27:36 -0800427 var fullInstallPath string
Colin Crossd3ba0392015-05-07 14:11:29 -0700428 if a.hod.Device() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800429 // TODO: replace unset with a device name once we have device targeting
Colin Cross35cec122015-04-02 14:37:16 -0700430 fullInstallPath = filepath.Join(config.DeviceOut(), "system",
431 installPath, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800432 } else {
Colin Cross35cec122015-04-02 14:37:16 -0700433 fullInstallPath = filepath.Join(config.HostOut(), installPath, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800434 }
435
Colin Cross35cec122015-04-02 14:37:16 -0700436 deps = append(deps, a.installDeps...)
437
Colin Cross3f40fa42015-01-30 17:27:36 -0800438 a.ModuleContext.Build(pctx, blueprint.BuildParams{
439 Rule: Cp,
440 Outputs: []string{fullInstallPath},
441 Inputs: []string{srcPath},
Colin Cross35cec122015-04-02 14:37:16 -0700442 OrderOnly: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800443 })
444
445 a.installFiles = append(a.installFiles, fullInstallPath)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700446 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700447 return fullInstallPath
448}
449
450func (a *androidModuleContext) InstallFile(installPath, srcPath string, deps ...string) string {
451 return a.InstallFileName(installPath, filepath.Base(srcPath), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800452}
453
454func (a *androidModuleContext) CheckbuildFile(srcPath string) {
455 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
456}
457
458type androidDynamicDependerContext struct {
459 blueprint.DynamicDependerModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700460 androidBaseContextImpl
Colin Cross3f40fa42015-01-30 17:27:36 -0800461}
462
463type fileInstaller interface {
464 filesToInstall() []string
465}
466
467func isFileInstaller(m blueprint.Module) bool {
468 _, ok := m.(fileInstaller)
469 return ok
470}
471
472func isAndroidModule(m blueprint.Module) bool {
473 _, ok := m.(AndroidModule)
474 return ok
475}
Colin Crossfce53272015-04-08 11:21:40 -0700476
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700477func findStringInSlice(str string, slice []string) int {
478 for i, s := range slice {
479 if s == str {
480 return i
Colin Crossfce53272015-04-08 11:21:40 -0700481 }
482 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700483 return -1
484}
485
486func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) []string {
487 prefix := ModuleSrcDir(ctx)
488 for i, e := range excludes {
489 j := findStringInSlice(e, srcFiles)
490 if j != -1 {
491 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
492 }
493
494 excludes[i] = filepath.Join(prefix, e)
495 }
496
497 for i, srcFile := range srcFiles {
498 srcFiles[i] = filepath.Join(prefix, srcFile)
499 }
Colin Crossfce53272015-04-08 11:21:40 -0700500
Colin Cross8f101b42015-06-17 15:09:06 -0700501 if !hasGlob(srcFiles) {
502 return srcFiles
503 }
504
Colin Cross8f101b42015-06-17 15:09:06 -0700505 globbedSrcFiles := make([]string, 0, len(srcFiles))
506 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700507 if glob.IsGlob(s) {
Colin Crossa819f082015-07-14 18:26:10 -0700508 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", s, excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700509 } else {
510 globbedSrcFiles = append(globbedSrcFiles, s)
511 }
512 }
513
514 return globbedSrcFiles
515}
516
Colin Crossa819f082015-07-14 18:26:10 -0700517func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) []string {
518 ret, err := Glob(ctx, filepath.Join(ModuleOutDir(ctx), outDir), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700519 if err != nil {
520 ctx.ModuleErrorf("glob: %s", err.Error())
521 }
522 return ret
Colin Crossfce53272015-04-08 11:21:40 -0700523}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700524
Colin Cross463a90e2015-06-17 14:20:06 -0700525func init() {
526 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
527}
528
Colin Cross1f8c52b2015-06-16 16:38:17 -0700529func BuildTargetSingleton() blueprint.Singleton {
530 return &buildTargetSingleton{}
531}
532
533type buildTargetSingleton struct{}
534
535func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
536 checkbuildDeps := []string{}
537
538 dirModules := make(map[string][]string)
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700539 hasBPFile := make(map[string]bool)
540 bpFiles := []string{}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700541
542 ctx.VisitAllModules(func(module blueprint.Module) {
543 if a, ok := module.(AndroidModule); ok {
544 blueprintDir := a.base().blueprintDir
545 installTarget := a.base().installTarget
546 checkbuildTarget := a.base().checkbuildTarget
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700547 bpFile := ctx.BlueprintFile(module)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700548
549 if checkbuildTarget != "" {
550 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
551 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
552 }
553
554 if installTarget != "" {
555 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
556 }
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700557
558 if !hasBPFile[bpFile] {
559 hasBPFile[bpFile] = true
560 bpFiles = append(bpFiles, bpFile)
561 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700562 }
563 })
564
565 // Create a top-level checkbuild target that depends on all modules
566 ctx.Build(pctx, blueprint.BuildParams{
567 Rule: blueprint.Phony,
568 Outputs: []string{"checkbuild"},
569 Implicits: checkbuildDeps,
570 // HACK: checkbuild should be an optional build, but force it enabled for now
571 //Optional: true,
572 })
573
574 // Create a mm/<directory> target that depends on all modules in a directory
575 dirs := sortedKeys(dirModules)
576 for _, dir := range dirs {
577 ctx.Build(pctx, blueprint.BuildParams{
578 Rule: blueprint.Phony,
579 Outputs: []string{filepath.Join("mm", dir)},
580 Implicits: dirModules[dir],
581 Optional: true,
582 })
583 }
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700584
585 // Create Android.bp->mk translation rules
586 androidMks := []string{}
587 srcDir := ctx.Config().(Config).SrcDir()
588 intermediatesDir := filepath.Join(ctx.Config().(Config).IntermediatesDir(), "androidmk")
589 sort.Strings(bpFiles)
590 for _, origBp := range bpFiles {
591 bpFile := filepath.Join(srcDir, origBp)
592 mkFile := filepath.Join(srcDir, filepath.Dir(origBp), "Android.mk")
593
594 files, err := Glob(ctx, intermediatesDir, mkFile, nil)
595 if err != nil {
596 ctx.Errorf("glob: %s", err.Error())
597 continue
598 }
599
600 // Existing Android.mk file, use that instead
601 if len(files) > 0 {
Dan Willemsencdd1a992015-06-19 14:22:08 -0700602 for _, file := range files {
603 ctx.AddNinjaFileDeps(file)
604 }
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700605 continue
606 }
607
608 transMk := filepath.Join("androidmk", "Android_"+strings.Replace(filepath.Dir(origBp), "/", "_", -1)+".mk")
609 ctx.Build(pctx, blueprint.BuildParams{
610 Rule: androidbp,
611 Outputs: []string{transMk},
612 Inputs: []string{bpFile},
613 Implicits: []string{androidbpCmd},
614 Optional: true,
615 })
616
617 androidMks = append(androidMks, transMk)
618 }
619
620 ctx.Build(pctx, blueprint.BuildParams{
621 Rule: blueprint.Phony,
622 Outputs: []string{"androidmk"},
623 Implicits: androidMks,
624 Optional: true,
625 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700626}