blob: 113768a7abf53e8ba411059296708a608eb56bcb [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 Cross3f40fa42015-01-30 17:27:36 -080018 "path/filepath"
Colin Crossf6566ed2015-03-24 11:13:38 -070019
Dan Willemsen0effe062015-11-30 16:06:01 -080020 "android/soong"
Colin Cross8f101b42015-06-17 15:09:06 -070021 "android/soong/glob"
22
Colin Crossf6566ed2015-03-24 11:13:38 -070023 "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -080024)
25
26var (
27 DeviceSharedLibrary = "shared_library"
28 DeviceStaticLibrary = "static_library"
29 DeviceExecutable = "executable"
30 HostSharedLibrary = "host_shared_library"
31 HostStaticLibrary = "host_static_library"
32 HostExecutable = "host_executable"
33)
34
Colin Crossf6566ed2015-03-24 11:13:38 -070035type androidBaseContext interface {
36 Arch() Arch
Colin Crossd3ba0392015-05-07 14:11:29 -070037 HostOrDevice() HostOrDevice
Dan Willemsen490fd492015-11-24 17:53:15 -080038 HostType() HostType
Colin Crossf6566ed2015-03-24 11:13:38 -070039 Host() bool
40 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070041 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070042 Debug() bool
Colin Cross1332b002015-04-07 17:11:30 -070043 AConfig() Config
Colin Crossf6566ed2015-03-24 11:13:38 -070044}
45
46type AndroidBaseContext interface {
47 blueprint.BaseModuleContext
48 androidBaseContext
49}
50
Colin Cross3f40fa42015-01-30 17:27:36 -080051type AndroidModuleContext interface {
52 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070053 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080054
Dan Willemsen2ef08f42015-06-30 18:15:24 -070055 ExpandSources(srcFiles, excludes []string) []string
Colin Crossa819f082015-07-14 18:26:10 -070056 Glob(outDir, globPattern string, excludes []string) []string
Colin Cross8f101b42015-06-17 15:09:06 -070057
Colin Cross35cec122015-04-02 14:37:16 -070058 InstallFile(installPath, srcPath string, deps ...string) string
59 InstallFileName(installPath, name, srcPath string, deps ...string) string
Colin Cross3f40fa42015-01-30 17:27:36 -080060 CheckbuildFile(srcPath string)
61}
62
63type AndroidModule interface {
64 blueprint.Module
65
66 GenerateAndroidBuildActions(AndroidModuleContext)
67
68 base() *AndroidModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -080069 Enabled() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080070 HostOrDevice() HostOrDevice
71}
72
Colin Cross3f40fa42015-01-30 17:27:36 -080073type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -070074 Name string
75 Deps []string
76 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -080077
Dan Willemsen0effe062015-11-30 16:06:01 -080078 // emit build rules for this module
79 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -080080
Colin Cross7d5136f2015-05-11 13:39:40 -070081 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -080082 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
83 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
84 // platform
85 Compile_multilib string
86
Colin Crossd3ba0392015-05-07 14:11:29 -070087 // Set by HostOrDeviceMutator
88 CompileHostOrDevice HostOrDevice `blueprint:"mutated"`
89
Dan Willemsen490fd492015-11-24 17:53:15 -080090 // Set by HostTypeMutator
91 CompileHostType HostType `blueprint:"mutated"`
92
Colin Cross3f40fa42015-01-30 17:27:36 -080093 // Set by ArchMutator
94 CompileArch Arch `blueprint:"mutated"`
95
96 // Set by InitAndroidModule
97 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
98}
99
100type hostAndDeviceProperties struct {
101 Host_supported bool
102 Device_supported bool
103}
104
Colin Crossc472d572015-03-17 15:06:21 -0700105type Multilib string
106
107const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700108 MultilibBoth Multilib = "both"
109 MultilibFirst Multilib = "first"
110 MultilibCommon Multilib = "common"
111 MultilibDefault Multilib = ""
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
Dan Willemsen218f6562015-07-08 18:13:11 -0700134 switch hod {
135 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800136 // Default to module to device supported, host not supported, can override in module
137 // properties
138 base.hostAndDeviceProperties.Device_supported = true
Dan Willemsen218f6562015-07-08 18:13:11 -0700139 fallthrough
140 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800141 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
142 }
143
Colin Crosscfad1192015-11-02 16:43:11 -0800144 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800145}
146
147// A AndroidModuleBase object contains the properties that are common to all Android
148// modules. It should be included as an anonymous field in every module
149// struct definition. InitAndroidModule should then be called from the module's
150// factory function, and the return values from InitAndroidModule should be
151// returned from the factory function.
152//
153// The AndroidModuleBase type is responsible for implementing the
154// GenerateBuildActions method to support the blueprint.Module interface. This
155// method will then call the module's GenerateAndroidBuildActions method once
156// for each build variant that is to be built. GenerateAndroidBuildActions is
157// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
158// AndroidModuleContext exposes extra functionality specific to the Android build
159// system including details about the particular build variant that is to be
160// generated.
161//
162// For example:
163//
164// import (
165// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700166// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800167// )
168//
169// type myModule struct {
170// common.AndroidModuleBase
171// properties struct {
172// MyProperty string
173// }
174// }
175//
176// func NewMyModule() (blueprint.Module, []interface{}) {
177// m := &myModule{}
178// return common.InitAndroidModule(m, &m.properties)
179// }
180//
181// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
182// // Get the CPU architecture for the current build variant.
183// variantArch := ctx.Arch()
184//
185// // ...
186// }
187type AndroidModuleBase struct {
188 // Putting the curiously recurring thing pointing to the thing that contains
189 // the thing pattern to good use.
190 module AndroidModule
191
192 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700193 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800194 hostAndDeviceProperties hostAndDeviceProperties
195 generalProperties []interface{}
196 archProperties []*archProperties
197
198 noAddressSanitizer bool
199 installFiles []string
200 checkbuildFiles []string
Colin Cross1f8c52b2015-06-16 16:38:17 -0700201
202 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
203 // Only set on the final variant of each module
204 installTarget string
205 checkbuildTarget string
206 blueprintDir string
Colin Cross3f40fa42015-01-30 17:27:36 -0800207}
208
209func (a *AndroidModuleBase) base() *AndroidModuleBase {
210 return a
211}
212
Colin Crossd3ba0392015-05-07 14:11:29 -0700213func (a *AndroidModuleBase) SetHostOrDevice(hod HostOrDevice) {
214 a.commonProperties.CompileHostOrDevice = hod
215}
216
Dan Willemsen490fd492015-11-24 17:53:15 -0800217func (a *AndroidModuleBase) SetHostType(ht HostType) {
218 a.commonProperties.CompileHostType = ht
219}
220
Colin Cross3f40fa42015-01-30 17:27:36 -0800221func (a *AndroidModuleBase) SetArch(arch Arch) {
222 a.commonProperties.CompileArch = arch
223}
224
225func (a *AndroidModuleBase) HostOrDevice() HostOrDevice {
Colin Crossd3ba0392015-05-07 14:11:29 -0700226 return a.commonProperties.CompileHostOrDevice
Colin Cross3f40fa42015-01-30 17:27:36 -0800227}
228
Dan Willemsen490fd492015-11-24 17:53:15 -0800229func (a *AndroidModuleBase) HostType() HostType {
230 return a.commonProperties.CompileHostType
231}
232
Colin Cross3f40fa42015-01-30 17:27:36 -0800233func (a *AndroidModuleBase) HostSupported() bool {
234 return a.commonProperties.HostOrDeviceSupported == HostSupported ||
235 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
236 a.hostAndDeviceProperties.Host_supported
237}
238
239func (a *AndroidModuleBase) DeviceSupported() bool {
240 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
241 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
242 a.hostAndDeviceProperties.Device_supported
243}
244
Dan Willemsen0effe062015-11-30 16:06:01 -0800245func (a *AndroidModuleBase) Enabled() bool {
246 if a.commonProperties.Enabled == nil {
247 if a.HostSupported() && a.HostOrDevice().Host() && a.HostType() == Windows {
248 return false
249 } else {
250 return true
251 }
Dan Willemsen490fd492015-11-24 17:53:15 -0800252 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800253 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800254}
255
256func (a *AndroidModuleBase) computeInstallDeps(
257 ctx blueprint.ModuleContext) []string {
258
259 result := []string{}
260 ctx.VisitDepsDepthFirstIf(isFileInstaller,
261 func(m blueprint.Module) {
262 fileInstaller := m.(fileInstaller)
263 files := fileInstaller.filesToInstall()
264 result = append(result, files...)
265 })
266
267 return result
268}
269
270func (a *AndroidModuleBase) filesToInstall() []string {
271 return a.installFiles
272}
273
274func (p *AndroidModuleBase) NoAddressSanitizer() bool {
275 return p.noAddressSanitizer
276}
277
Colin Cross3f40fa42015-01-30 17:27:36 -0800278func (a *AndroidModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
279 if a != ctx.FinalModule().(AndroidModule).base() {
280 return
281 }
282
283 allInstalledFiles := []string{}
Colin Cross9454bfa2015-03-17 13:24:18 -0700284 allCheckbuildFiles := []string{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800285 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Crossc9404352015-03-26 16:10:12 -0700286 a := module.(AndroidModule).base()
287 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
288 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800289 })
290
Colin Cross9454bfa2015-03-17 13:24:18 -0700291 deps := []string{}
292
Colin Cross3f40fa42015-01-30 17:27:36 -0800293 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700294 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800295 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700296 Rule: blueprint.Phony,
297 Outputs: []string{name},
298 Implicits: allInstalledFiles,
299 })
300 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700301 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700302 }
303
304 if len(allCheckbuildFiles) > 0 {
305 name := ctx.ModuleName() + "-checkbuild"
306 ctx.Build(pctx, blueprint.BuildParams{
307 Rule: blueprint.Phony,
308 Outputs: []string{name},
309 Implicits: allCheckbuildFiles,
310 Optional: true,
311 })
312 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700313 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700314 }
315
316 if len(deps) > 0 {
317 ctx.Build(pctx, blueprint.BuildParams{
318 Rule: blueprint.Phony,
Dan Willemsen218f6562015-07-08 18:13:11 -0700319 Outputs: []string{ctx.ModuleName() + "-soong"},
Colin Cross9454bfa2015-03-17 13:24:18 -0700320 Implicits: deps,
321 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800322 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700323
324 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800325 }
326}
327
Colin Cross6362e272015-10-29 15:25:03 -0700328func (a *AndroidModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
329 return androidBaseContextImpl{
330 arch: a.commonProperties.CompileArch,
331 hod: a.commonProperties.CompileHostOrDevice,
Dan Willemsen490fd492015-11-24 17:53:15 -0800332 ht: a.commonProperties.CompileHostType,
Colin Cross6362e272015-10-29 15:25:03 -0700333 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800334 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800335}
336
337func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
338 androidCtx := &androidModuleContext{
Colin Cross6362e272015-10-29 15:25:03 -0700339 ModuleContext: ctx,
340 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
341 installDeps: a.computeInstallDeps(ctx),
342 installFiles: a.installFiles,
Colin Cross3f40fa42015-01-30 17:27:36 -0800343 }
344
Dan Willemsen0effe062015-11-30 16:06:01 -0800345 if !a.Enabled() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800346 return
347 }
348
349 a.module.GenerateAndroidBuildActions(androidCtx)
350 if ctx.Failed() {
351 return
352 }
353
Colin Crossc9404352015-03-26 16:10:12 -0700354 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
355 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
356
Colin Cross3f40fa42015-01-30 17:27:36 -0800357 a.generateModuleTarget(ctx)
358 if ctx.Failed() {
359 return
360 }
361}
362
Colin Crossf6566ed2015-03-24 11:13:38 -0700363type androidBaseContextImpl struct {
Colin Cross1332b002015-04-07 17:11:30 -0700364 arch Arch
Colin Crossd3ba0392015-05-07 14:11:29 -0700365 hod HostOrDevice
Dan Willemsen490fd492015-11-24 17:53:15 -0800366 ht HostType
Colin Cross1332b002015-04-07 17:11:30 -0700367 debug bool
368 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700369}
370
Colin Cross3f40fa42015-01-30 17:27:36 -0800371type androidModuleContext struct {
372 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700373 androidBaseContextImpl
Colin Cross06a931b2015-10-28 17:23:31 -0700374 installDeps []string
375 installFiles []string
376 checkbuildFiles []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800377}
378
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800379func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800380 params.Optional = true
381 a.ModuleContext.Build(pctx, params)
382}
383
Colin Crossf6566ed2015-03-24 11:13:38 -0700384func (a *androidBaseContextImpl) Arch() Arch {
Colin Cross3f40fa42015-01-30 17:27:36 -0800385 return a.arch
386}
387
Colin Crossd3ba0392015-05-07 14:11:29 -0700388func (a *androidBaseContextImpl) HostOrDevice() HostOrDevice {
389 return a.hod
390}
391
Dan Willemsen490fd492015-11-24 17:53:15 -0800392func (a *androidBaseContextImpl) HostType() HostType {
393 return a.ht
394}
395
Colin Crossf6566ed2015-03-24 11:13:38 -0700396func (a *androidBaseContextImpl) Host() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700397 return a.hod.Host()
Colin Crossf6566ed2015-03-24 11:13:38 -0700398}
399
400func (a *androidBaseContextImpl) Device() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700401 return a.hod.Device()
Colin Crossf6566ed2015-03-24 11:13:38 -0700402}
403
Colin Cross0af4b842015-04-30 16:36:18 -0700404func (a *androidBaseContextImpl) Darwin() bool {
Dan Willemsen490fd492015-11-24 17:53:15 -0800405 return a.hod.Host() && a.ht == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700406}
407
Colin Crossf6566ed2015-03-24 11:13:38 -0700408func (a *androidBaseContextImpl) Debug() bool {
409 return a.debug
410}
411
Colin Cross1332b002015-04-07 17:11:30 -0700412func (a *androidBaseContextImpl) AConfig() Config {
413 return a.config
414}
415
Colin Cross35cec122015-04-02 14:37:16 -0700416func (a *androidModuleContext) InstallFileName(installPath, name, srcPath string,
417 deps ...string) string {
418
Colin Cross1332b002015-04-07 17:11:30 -0700419 config := a.AConfig()
Colin Cross3f40fa42015-01-30 17:27:36 -0800420 var fullInstallPath string
Colin Crossd3ba0392015-05-07 14:11:29 -0700421 if a.hod.Device() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800422 // TODO: replace unset with a device name once we have device targeting
Colin Cross35cec122015-04-02 14:37:16 -0700423 fullInstallPath = filepath.Join(config.DeviceOut(), "system",
424 installPath, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800425 } else {
Dan Willemsen490fd492015-11-24 17:53:15 -0800426 // TODO
427 if a.ht == Windows {
428 fullInstallPath = filepath.Join(config.BuildDir(), "host", "windows-x86", installPath, name)
429 } else {
430 fullInstallPath = filepath.Join(config.HostOut(), installPath, name)
431 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800432 }
433
Colin Cross35cec122015-04-02 14:37:16 -0700434 deps = append(deps, a.installDeps...)
435
Colin Cross3f40fa42015-01-30 17:27:36 -0800436 a.ModuleContext.Build(pctx, blueprint.BuildParams{
437 Rule: Cp,
438 Outputs: []string{fullInstallPath},
439 Inputs: []string{srcPath},
Colin Cross35cec122015-04-02 14:37:16 -0700440 OrderOnly: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800441 })
442
443 a.installFiles = append(a.installFiles, fullInstallPath)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700444 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700445 return fullInstallPath
446}
447
448func (a *androidModuleContext) InstallFile(installPath, srcPath string, deps ...string) string {
449 return a.InstallFileName(installPath, filepath.Base(srcPath), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800450}
451
452func (a *androidModuleContext) CheckbuildFile(srcPath string) {
453 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
454}
455
Colin Cross3f40fa42015-01-30 17:27:36 -0800456type fileInstaller interface {
457 filesToInstall() []string
458}
459
460func isFileInstaller(m blueprint.Module) bool {
461 _, ok := m.(fileInstaller)
462 return ok
463}
464
465func isAndroidModule(m blueprint.Module) bool {
466 _, ok := m.(AndroidModule)
467 return ok
468}
Colin Crossfce53272015-04-08 11:21:40 -0700469
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700470func findStringInSlice(str string, slice []string) int {
471 for i, s := range slice {
472 if s == str {
473 return i
Colin Crossfce53272015-04-08 11:21:40 -0700474 }
475 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700476 return -1
477}
478
479func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) []string {
480 prefix := ModuleSrcDir(ctx)
481 for i, e := range excludes {
482 j := findStringInSlice(e, srcFiles)
483 if j != -1 {
484 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
485 }
486
487 excludes[i] = filepath.Join(prefix, e)
488 }
489
490 for i, srcFile := range srcFiles {
491 srcFiles[i] = filepath.Join(prefix, srcFile)
492 }
Colin Crossfce53272015-04-08 11:21:40 -0700493
Colin Cross8f101b42015-06-17 15:09:06 -0700494 if !hasGlob(srcFiles) {
495 return srcFiles
496 }
497
Colin Cross8f101b42015-06-17 15:09:06 -0700498 globbedSrcFiles := make([]string, 0, len(srcFiles))
499 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700500 if glob.IsGlob(s) {
Colin Crossa819f082015-07-14 18:26:10 -0700501 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", s, excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700502 } else {
503 globbedSrcFiles = append(globbedSrcFiles, s)
504 }
505 }
506
507 return globbedSrcFiles
508}
509
Colin Crossa819f082015-07-14 18:26:10 -0700510func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) []string {
511 ret, err := Glob(ctx, filepath.Join(ModuleOutDir(ctx), outDir), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700512 if err != nil {
513 ctx.ModuleErrorf("glob: %s", err.Error())
514 }
515 return ret
Colin Crossfce53272015-04-08 11:21:40 -0700516}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700517
Colin Cross463a90e2015-06-17 14:20:06 -0700518func init() {
519 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
520}
521
Colin Cross1f8c52b2015-06-16 16:38:17 -0700522func BuildTargetSingleton() blueprint.Singleton {
523 return &buildTargetSingleton{}
524}
525
526type buildTargetSingleton struct{}
527
528func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
529 checkbuildDeps := []string{}
530
531 dirModules := make(map[string][]string)
532
533 ctx.VisitAllModules(func(module blueprint.Module) {
534 if a, ok := module.(AndroidModule); ok {
535 blueprintDir := a.base().blueprintDir
536 installTarget := a.base().installTarget
537 checkbuildTarget := a.base().checkbuildTarget
538
539 if checkbuildTarget != "" {
540 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
541 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
542 }
543
544 if installTarget != "" {
545 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
546 }
547 }
548 })
549
550 // Create a top-level checkbuild target that depends on all modules
551 ctx.Build(pctx, blueprint.BuildParams{
552 Rule: blueprint.Phony,
Dan Willemsen218f6562015-07-08 18:13:11 -0700553 Outputs: []string{"checkbuild-soong"},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700554 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700555 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700556 })
557
558 // Create a mm/<directory> target that depends on all modules in a directory
559 dirs := sortedKeys(dirModules)
560 for _, dir := range dirs {
561 ctx.Build(pctx, blueprint.BuildParams{
562 Rule: blueprint.Phony,
563 Outputs: []string{filepath.Join("mm", dir)},
564 Implicits: dirModules[dir],
565 Optional: true,
566 })
567 }
568}