blob: 7bb21a25c48ac41dfbcb1bbb33777fe5a9f95599 [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 Crossf6566ed2015-03-24 11:13:38 -070020
Colin Cross8f101b42015-06-17 15:09:06 -070021 "android/soong/glob"
22
Colin Crossf6566ed2015-03-24 11:13:38 -070023 "github.com/google/blueprint"
Dan Willemsen53aa1f62015-11-09 14:05:27 -080024 "github.com/google/blueprint/proptools"
Colin Cross3f40fa42015-01-30 17:27:36 -080025)
26
27var (
28 DeviceSharedLibrary = "shared_library"
29 DeviceStaticLibrary = "static_library"
30 DeviceExecutable = "executable"
31 HostSharedLibrary = "host_shared_library"
32 HostStaticLibrary = "host_static_library"
33 HostExecutable = "host_executable"
34)
35
Colin Crossf6566ed2015-03-24 11:13:38 -070036type androidBaseContext interface {
37 Arch() Arch
Colin Crossd3ba0392015-05-07 14:11:29 -070038 HostOrDevice() HostOrDevice
Dan Willemsen490fd492015-11-24 17:53:15 -080039 HostType() HostType
Colin Crossf6566ed2015-03-24 11:13:38 -070040 Host() bool
41 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070042 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070043 Debug() bool
Colin Cross1332b002015-04-07 17:11:30 -070044 AConfig() Config
Colin Crossf6566ed2015-03-24 11:13:38 -070045}
46
47type AndroidBaseContext interface {
48 blueprint.BaseModuleContext
49 androidBaseContext
50}
51
Colin Cross3f40fa42015-01-30 17:27:36 -080052type AndroidModuleContext interface {
53 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070054 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080055
Dan Willemsen2ef08f42015-06-30 18:15:24 -070056 ExpandSources(srcFiles, excludes []string) []string
Colin Crossa819f082015-07-14 18:26:10 -070057 Glob(outDir, globPattern string, excludes []string) []string
Colin Cross8f101b42015-06-17 15:09:06 -070058
Colin Cross35cec122015-04-02 14:37:16 -070059 InstallFile(installPath, srcPath string, deps ...string) string
60 InstallFileName(installPath, name, srcPath string, deps ...string) string
Colin Cross3f40fa42015-01-30 17:27:36 -080061 CheckbuildFile(srcPath string)
62}
63
64type AndroidModule interface {
65 blueprint.Module
66
67 GenerateAndroidBuildActions(AndroidModuleContext)
68
69 base() *AndroidModuleBase
70 Disabled() bool
71 HostOrDevice() HostOrDevice
72}
73
Colin Cross3f40fa42015-01-30 17:27:36 -080074type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -070075 Name string
76 Deps []string
77 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -080078
Colin Cross7d5136f2015-05-11 13:39:40 -070079 // don't emit any build rules for this module
Dan Willemsen53aa1f62015-11-09 14:05:27 -080080 Disabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -080081
Colin Cross7d5136f2015-05-11 13:39:40 -070082 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -080083 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
84 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
85 // platform
86 Compile_multilib string
87
Colin Crossd3ba0392015-05-07 14:11:29 -070088 // Set by HostOrDeviceMutator
89 CompileHostOrDevice HostOrDevice `blueprint:"mutated"`
90
Dan Willemsen490fd492015-11-24 17:53:15 -080091 // Set by HostTypeMutator
92 CompileHostType HostType `blueprint:"mutated"`
93
Colin Cross3f40fa42015-01-30 17:27:36 -080094 // Set by ArchMutator
95 CompileArch Arch `blueprint:"mutated"`
96
97 // Set by InitAndroidModule
98 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
99}
100
101type hostAndDeviceProperties struct {
102 Host_supported bool
103 Device_supported bool
104}
105
Colin Crossc472d572015-03-17 15:06:21 -0700106type Multilib string
107
108const (
Colin Cross2fe66872015-03-30 17:20:39 -0700109 MultilibBoth Multilib = "both"
110 MultilibFirst Multilib = "first"
111 MultilibCommon Multilib = "common"
Colin Crossc472d572015-03-17 15:06:21 -0700112)
113
Colin Cross5049f022015-03-18 13:28:46 -0700114func InitAndroidModule(m AndroidModule,
Colin Cross3f40fa42015-01-30 17:27:36 -0800115 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
116
117 base := m.base()
118 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700119
Colin Cross7f64b6d2015-07-09 13:57:48 -0700120 propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700121
122 return m, propertyStructs
123}
124
125func InitAndroidArchModule(m AndroidModule, hod HostOrDeviceSupported, defaultMultilib Multilib,
126 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
127
128 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
129
130 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800131 base.commonProperties.HostOrDeviceSupported = hod
Colin Crosscfad1192015-11-02 16:43:11 -0800132 base.commonProperties.Compile_multilib = string(defaultMultilib)
Colin Cross3f40fa42015-01-30 17:27:36 -0800133
134 if hod == HostAndDeviceSupported {
135 // Default to module to device supported, host not supported, can override in module
136 // properties
137 base.hostAndDeviceProperties.Device_supported = true
138 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
139 }
140
Colin Crosscfad1192015-11-02 16:43:11 -0800141 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800142}
143
144// A AndroidModuleBase object contains the properties that are common to all Android
145// modules. It should be included as an anonymous field in every module
146// struct definition. InitAndroidModule should then be called from the module's
147// factory function, and the return values from InitAndroidModule should be
148// returned from the factory function.
149//
150// The AndroidModuleBase type is responsible for implementing the
151// GenerateBuildActions method to support the blueprint.Module interface. This
152// method will then call the module's GenerateAndroidBuildActions method once
153// for each build variant that is to be built. GenerateAndroidBuildActions is
154// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
155// AndroidModuleContext exposes extra functionality specific to the Android build
156// system including details about the particular build variant that is to be
157// generated.
158//
159// For example:
160//
161// import (
162// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700163// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800164// )
165//
166// type myModule struct {
167// common.AndroidModuleBase
168// properties struct {
169// MyProperty string
170// }
171// }
172//
173// func NewMyModule() (blueprint.Module, []interface{}) {
174// m := &myModule{}
175// return common.InitAndroidModule(m, &m.properties)
176// }
177//
178// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
179// // Get the CPU architecture for the current build variant.
180// variantArch := ctx.Arch()
181//
182// // ...
183// }
184type AndroidModuleBase struct {
185 // Putting the curiously recurring thing pointing to the thing that contains
186 // the thing pattern to good use.
187 module AndroidModule
188
189 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700190 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800191 hostAndDeviceProperties hostAndDeviceProperties
192 generalProperties []interface{}
193 archProperties []*archProperties
194
195 noAddressSanitizer bool
196 installFiles []string
197 checkbuildFiles []string
Colin Cross1f8c52b2015-06-16 16:38:17 -0700198
199 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
200 // Only set on the final variant of each module
201 installTarget string
202 checkbuildTarget string
203 blueprintDir string
Colin Cross3f40fa42015-01-30 17:27:36 -0800204}
205
206func (a *AndroidModuleBase) base() *AndroidModuleBase {
207 return a
208}
209
Colin Crossd3ba0392015-05-07 14:11:29 -0700210func (a *AndroidModuleBase) SetHostOrDevice(hod HostOrDevice) {
211 a.commonProperties.CompileHostOrDevice = hod
212}
213
Dan Willemsen490fd492015-11-24 17:53:15 -0800214func (a *AndroidModuleBase) SetHostType(ht HostType) {
215 a.commonProperties.CompileHostType = ht
216}
217
Colin Cross3f40fa42015-01-30 17:27:36 -0800218func (a *AndroidModuleBase) SetArch(arch Arch) {
219 a.commonProperties.CompileArch = arch
220}
221
222func (a *AndroidModuleBase) HostOrDevice() HostOrDevice {
Colin Crossd3ba0392015-05-07 14:11:29 -0700223 return a.commonProperties.CompileHostOrDevice
Colin Cross3f40fa42015-01-30 17:27:36 -0800224}
225
Dan Willemsen490fd492015-11-24 17:53:15 -0800226func (a *AndroidModuleBase) HostType() HostType {
227 return a.commonProperties.CompileHostType
228}
229
Colin Cross3f40fa42015-01-30 17:27:36 -0800230func (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 {
Dan Willemsen490fd492015-11-24 17:53:15 -0800243 if a.commonProperties.CompileHostOrDevice == Host &&
244 a.commonProperties.CompileHostType == Windows &&
245 a.commonProperties.Disabled == nil {
246
247 return true
248 }
Dan Willemsen53aa1f62015-11-09 14:05:27 -0800249 return proptools.Bool(a.commonProperties.Disabled)
Colin Cross3f40fa42015-01-30 17:27:36 -0800250}
251
252func (a *AndroidModuleBase) computeInstallDeps(
253 ctx blueprint.ModuleContext) []string {
254
255 result := []string{}
256 ctx.VisitDepsDepthFirstIf(isFileInstaller,
257 func(m blueprint.Module) {
258 fileInstaller := m.(fileInstaller)
259 files := fileInstaller.filesToInstall()
260 result = append(result, files...)
261 })
262
263 return result
264}
265
266func (a *AndroidModuleBase) filesToInstall() []string {
267 return a.installFiles
268}
269
270func (p *AndroidModuleBase) NoAddressSanitizer() bool {
271 return p.noAddressSanitizer
272}
273
Colin Cross3f40fa42015-01-30 17:27:36 -0800274func (a *AndroidModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
275 if a != ctx.FinalModule().(AndroidModule).base() {
276 return
277 }
278
279 allInstalledFiles := []string{}
Colin Cross9454bfa2015-03-17 13:24:18 -0700280 allCheckbuildFiles := []string{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800281 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Crossc9404352015-03-26 16:10:12 -0700282 a := module.(AndroidModule).base()
283 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
284 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800285 })
286
Colin Cross9454bfa2015-03-17 13:24:18 -0700287 deps := []string{}
288
Colin Cross3f40fa42015-01-30 17:27:36 -0800289 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700290 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800291 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700292 Rule: blueprint.Phony,
293 Outputs: []string{name},
294 Implicits: allInstalledFiles,
295 })
296 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700297 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700298 }
299
300 if len(allCheckbuildFiles) > 0 {
301 name := ctx.ModuleName() + "-checkbuild"
302 ctx.Build(pctx, blueprint.BuildParams{
303 Rule: blueprint.Phony,
304 Outputs: []string{name},
305 Implicits: allCheckbuildFiles,
306 Optional: true,
307 })
308 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700309 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700310 }
311
312 if len(deps) > 0 {
313 ctx.Build(pctx, blueprint.BuildParams{
314 Rule: blueprint.Phony,
315 Outputs: []string{ctx.ModuleName()},
316 Implicits: deps,
317 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800318 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700319
320 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800321 }
322}
323
Colin Cross6362e272015-10-29 15:25:03 -0700324func (a *AndroidModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
325 return androidBaseContextImpl{
326 arch: a.commonProperties.CompileArch,
327 hod: a.commonProperties.CompileHostOrDevice,
Dan Willemsen490fd492015-11-24 17:53:15 -0800328 ht: a.commonProperties.CompileHostType,
Colin Cross6362e272015-10-29 15:25:03 -0700329 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800330 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800331}
332
333func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
334 androidCtx := &androidModuleContext{
Colin Cross6362e272015-10-29 15:25:03 -0700335 ModuleContext: ctx,
336 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
337 installDeps: a.computeInstallDeps(ctx),
338 installFiles: a.installFiles,
Colin Cross3f40fa42015-01-30 17:27:36 -0800339 }
340
Dan Willemsen490fd492015-11-24 17:53:15 -0800341 if a.Disabled() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800342 return
343 }
344
345 a.module.GenerateAndroidBuildActions(androidCtx)
346 if ctx.Failed() {
347 return
348 }
349
Colin Crossc9404352015-03-26 16:10:12 -0700350 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
351 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
352
Colin Cross3f40fa42015-01-30 17:27:36 -0800353 a.generateModuleTarget(ctx)
354 if ctx.Failed() {
355 return
356 }
357}
358
Colin Crossf6566ed2015-03-24 11:13:38 -0700359type androidBaseContextImpl struct {
Colin Cross1332b002015-04-07 17:11:30 -0700360 arch Arch
Colin Crossd3ba0392015-05-07 14:11:29 -0700361 hod HostOrDevice
Dan Willemsen490fd492015-11-24 17:53:15 -0800362 ht HostType
Colin Cross1332b002015-04-07 17:11:30 -0700363 debug bool
364 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700365}
366
Colin Cross3f40fa42015-01-30 17:27:36 -0800367type androidModuleContext struct {
368 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700369 androidBaseContextImpl
Colin Cross06a931b2015-10-28 17:23:31 -0700370 installDeps []string
371 installFiles []string
372 checkbuildFiles []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800373}
374
375func (a *androidModuleContext) Build(pctx *blueprint.PackageContext, params blueprint.BuildParams) {
376 params.Optional = true
377 a.ModuleContext.Build(pctx, params)
378}
379
Colin Crossf6566ed2015-03-24 11:13:38 -0700380func (a *androidBaseContextImpl) Arch() Arch {
Colin Cross3f40fa42015-01-30 17:27:36 -0800381 return a.arch
382}
383
Colin Crossd3ba0392015-05-07 14:11:29 -0700384func (a *androidBaseContextImpl) HostOrDevice() HostOrDevice {
385 return a.hod
386}
387
Dan Willemsen490fd492015-11-24 17:53:15 -0800388func (a *androidBaseContextImpl) HostType() HostType {
389 return a.ht
390}
391
Colin Crossf6566ed2015-03-24 11:13:38 -0700392func (a *androidBaseContextImpl) Host() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700393 return a.hod.Host()
Colin Crossf6566ed2015-03-24 11:13:38 -0700394}
395
396func (a *androidBaseContextImpl) Device() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700397 return a.hod.Device()
Colin Crossf6566ed2015-03-24 11:13:38 -0700398}
399
Colin Cross0af4b842015-04-30 16:36:18 -0700400func (a *androidBaseContextImpl) Darwin() bool {
Dan Willemsen490fd492015-11-24 17:53:15 -0800401 return a.hod.Host() && a.ht == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700402}
403
Colin Crossf6566ed2015-03-24 11:13:38 -0700404func (a *androidBaseContextImpl) Debug() bool {
405 return a.debug
406}
407
Colin Cross1332b002015-04-07 17:11:30 -0700408func (a *androidBaseContextImpl) AConfig() Config {
409 return a.config
410}
411
Colin Cross35cec122015-04-02 14:37:16 -0700412func (a *androidModuleContext) InstallFileName(installPath, name, srcPath string,
413 deps ...string) string {
414
Colin Cross1332b002015-04-07 17:11:30 -0700415 config := a.AConfig()
Colin Cross3f40fa42015-01-30 17:27:36 -0800416 var fullInstallPath string
Colin Crossd3ba0392015-05-07 14:11:29 -0700417 if a.hod.Device() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800418 // TODO: replace unset with a device name once we have device targeting
Colin Cross35cec122015-04-02 14:37:16 -0700419 fullInstallPath = filepath.Join(config.DeviceOut(), "system",
420 installPath, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800421 } else {
Dan Willemsen490fd492015-11-24 17:53:15 -0800422 // TODO
423 if a.ht == Windows {
424 fullInstallPath = filepath.Join(config.BuildDir(), "host", "windows-x86", installPath, name)
425 } else {
426 fullInstallPath = filepath.Join(config.HostOut(), installPath, name)
427 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800428 }
429
Colin Cross35cec122015-04-02 14:37:16 -0700430 deps = append(deps, a.installDeps...)
431
Colin Cross3f40fa42015-01-30 17:27:36 -0800432 a.ModuleContext.Build(pctx, blueprint.BuildParams{
433 Rule: Cp,
434 Outputs: []string{fullInstallPath},
435 Inputs: []string{srcPath},
Colin Cross35cec122015-04-02 14:37:16 -0700436 OrderOnly: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800437 })
438
439 a.installFiles = append(a.installFiles, fullInstallPath)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700440 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700441 return fullInstallPath
442}
443
444func (a *androidModuleContext) InstallFile(installPath, srcPath string, deps ...string) string {
445 return a.InstallFileName(installPath, filepath.Base(srcPath), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800446}
447
448func (a *androidModuleContext) CheckbuildFile(srcPath string) {
449 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
450}
451
Colin Cross3f40fa42015-01-30 17:27:36 -0800452type fileInstaller interface {
453 filesToInstall() []string
454}
455
456func isFileInstaller(m blueprint.Module) bool {
457 _, ok := m.(fileInstaller)
458 return ok
459}
460
461func isAndroidModule(m blueprint.Module) bool {
462 _, ok := m.(AndroidModule)
463 return ok
464}
Colin Crossfce53272015-04-08 11:21:40 -0700465
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700466func findStringInSlice(str string, slice []string) int {
467 for i, s := range slice {
468 if s == str {
469 return i
Colin Crossfce53272015-04-08 11:21:40 -0700470 }
471 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700472 return -1
473}
474
475func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) []string {
476 prefix := ModuleSrcDir(ctx)
477 for i, e := range excludes {
478 j := findStringInSlice(e, srcFiles)
479 if j != -1 {
480 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
481 }
482
483 excludes[i] = filepath.Join(prefix, e)
484 }
485
486 for i, srcFile := range srcFiles {
487 srcFiles[i] = filepath.Join(prefix, srcFile)
488 }
Colin Crossfce53272015-04-08 11:21:40 -0700489
Colin Cross8f101b42015-06-17 15:09:06 -0700490 if !hasGlob(srcFiles) {
491 return srcFiles
492 }
493
Colin Cross8f101b42015-06-17 15:09:06 -0700494 globbedSrcFiles := make([]string, 0, len(srcFiles))
495 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700496 if glob.IsGlob(s) {
Colin Crossa819f082015-07-14 18:26:10 -0700497 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", s, excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700498 } else {
499 globbedSrcFiles = append(globbedSrcFiles, s)
500 }
501 }
502
503 return globbedSrcFiles
504}
505
Colin Crossa819f082015-07-14 18:26:10 -0700506func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) []string {
507 ret, err := Glob(ctx, filepath.Join(ModuleOutDir(ctx), outDir), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700508 if err != nil {
509 ctx.ModuleErrorf("glob: %s", err.Error())
510 }
511 return ret
Colin Crossfce53272015-04-08 11:21:40 -0700512}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700513
Colin Cross463a90e2015-06-17 14:20:06 -0700514func init() {
515 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
516}
517
Colin Cross1f8c52b2015-06-16 16:38:17 -0700518func BuildTargetSingleton() blueprint.Singleton {
519 return &buildTargetSingleton{}
520}
521
522type buildTargetSingleton struct{}
523
524func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
525 checkbuildDeps := []string{}
526
527 dirModules := make(map[string][]string)
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700528 hasBPFile := make(map[string]bool)
529 bpFiles := []string{}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700530
531 ctx.VisitAllModules(func(module blueprint.Module) {
532 if a, ok := module.(AndroidModule); ok {
533 blueprintDir := a.base().blueprintDir
534 installTarget := a.base().installTarget
535 checkbuildTarget := a.base().checkbuildTarget
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700536 bpFile := ctx.BlueprintFile(module)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700537
538 if checkbuildTarget != "" {
539 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
540 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
541 }
542
543 if installTarget != "" {
544 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
545 }
Dan Willemsenbf9207a2015-06-17 15:17:12 -0700546
547 if !hasBPFile[bpFile] {
548 hasBPFile[bpFile] = true
549 bpFiles = append(bpFiles, bpFile)
550 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700551 }
552 })
553
554 // Create a top-level checkbuild target that depends on all modules
555 ctx.Build(pctx, blueprint.BuildParams{
556 Rule: blueprint.Phony,
557 Outputs: []string{"checkbuild"},
558 Implicits: checkbuildDeps,
559 // HACK: checkbuild should be an optional build, but force it enabled for now
560 //Optional: true,
561 })
562
563 // Create a mm/<directory> target that depends on all modules in a directory
564 dirs := sortedKeys(dirModules)
565 for _, dir := range dirs {
566 ctx.Build(pctx, blueprint.BuildParams{
567 Rule: blueprint.Phony,
568 Outputs: []string{filepath.Join("mm", dir)},
569 Implicits: dirModules[dir],
570 Optional: true,
571 })
572 }
573}