blob: e03b006e5c4d4906e34f0fb881e27a854054a861 [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
Dan Willemsen34cc69e2015-09-23 15:26:20 -070035type ModuleBuildParams struct {
36 Rule blueprint.Rule
37 Output WritablePath
38 Outputs WritablePaths
39 Input Path
40 Inputs Paths
41 Implicit Path
42 Implicits Paths
43 OrderOnly Paths
44 Default bool
45 Args map[string]string
46}
47
Colin Crossf6566ed2015-03-24 11:13:38 -070048type androidBaseContext interface {
49 Arch() Arch
Colin Crossd3ba0392015-05-07 14:11:29 -070050 HostOrDevice() HostOrDevice
Dan Willemsen490fd492015-11-24 17:53:15 -080051 HostType() HostType
Colin Crossf6566ed2015-03-24 11:13:38 -070052 Host() bool
53 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070054 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070055 Debug() bool
Colin Cross1332b002015-04-07 17:11:30 -070056 AConfig() Config
Colin Crossf6566ed2015-03-24 11:13:38 -070057}
58
59type AndroidBaseContext interface {
60 blueprint.BaseModuleContext
61 androidBaseContext
62}
63
Colin Cross3f40fa42015-01-30 17:27:36 -080064type AndroidModuleContext interface {
65 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070066 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080067
Dan Willemsen34cc69e2015-09-23 15:26:20 -070068 // Similar to Build, but takes Paths instead of []string,
69 // and performs more verification.
70 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070071
Dan Willemsen34cc69e2015-09-23 15:26:20 -070072 ExpandSources(srcFiles, excludes []string) Paths
73 Glob(outDir, globPattern string, excludes []string) Paths
74
75 InstallFile(installPath string, srcPath Path, deps ...Path) Path
76 InstallFileName(installPath, name string, srcPath Path, deps ...Path) Path
77 CheckbuildFile(srcPath Path)
Colin Cross3f40fa42015-01-30 17:27:36 -080078}
79
80type AndroidModule interface {
81 blueprint.Module
82
83 GenerateAndroidBuildActions(AndroidModuleContext)
84
85 base() *AndroidModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -080086 Enabled() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080087 HostOrDevice() HostOrDevice
88}
89
Colin Cross3f40fa42015-01-30 17:27:36 -080090type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -070091 Name string
92 Deps []string
93 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -080094
Dan Willemsen0effe062015-11-30 16:06:01 -080095 // emit build rules for this module
96 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -080097
Colin Cross7d5136f2015-05-11 13:39:40 -070098 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -080099 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
100 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
101 // platform
102 Compile_multilib string
103
Colin Crossd3ba0392015-05-07 14:11:29 -0700104 // Set by HostOrDeviceMutator
105 CompileHostOrDevice HostOrDevice `blueprint:"mutated"`
106
Dan Willemsen490fd492015-11-24 17:53:15 -0800107 // Set by HostTypeMutator
108 CompileHostType HostType `blueprint:"mutated"`
109
Colin Cross3f40fa42015-01-30 17:27:36 -0800110 // Set by ArchMutator
111 CompileArch Arch `blueprint:"mutated"`
112
113 // Set by InitAndroidModule
114 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
115}
116
117type hostAndDeviceProperties struct {
118 Host_supported bool
119 Device_supported bool
120}
121
Colin Crossc472d572015-03-17 15:06:21 -0700122type Multilib string
123
124const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700125 MultilibBoth Multilib = "both"
126 MultilibFirst Multilib = "first"
127 MultilibCommon Multilib = "common"
128 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700129)
130
Colin Cross5049f022015-03-18 13:28:46 -0700131func InitAndroidModule(m AndroidModule,
Colin Cross3f40fa42015-01-30 17:27:36 -0800132 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
133
134 base := m.base()
135 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700136
Colin Cross7f64b6d2015-07-09 13:57:48 -0700137 propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700138
139 return m, propertyStructs
140}
141
142func InitAndroidArchModule(m AndroidModule, hod HostOrDeviceSupported, defaultMultilib Multilib,
143 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
144
145 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
146
147 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800148 base.commonProperties.HostOrDeviceSupported = hod
Colin Crosscfad1192015-11-02 16:43:11 -0800149 base.commonProperties.Compile_multilib = string(defaultMultilib)
Colin Cross3f40fa42015-01-30 17:27:36 -0800150
Dan Willemsen218f6562015-07-08 18:13:11 -0700151 switch hod {
152 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800153 // Default to module to device supported, host not supported, can override in module
154 // properties
155 base.hostAndDeviceProperties.Device_supported = true
Dan Willemsen218f6562015-07-08 18:13:11 -0700156 fallthrough
157 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800158 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
159 }
160
Colin Crosscfad1192015-11-02 16:43:11 -0800161 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800162}
163
164// A AndroidModuleBase object contains the properties that are common to all Android
165// modules. It should be included as an anonymous field in every module
166// struct definition. InitAndroidModule should then be called from the module's
167// factory function, and the return values from InitAndroidModule should be
168// returned from the factory function.
169//
170// The AndroidModuleBase type is responsible for implementing the
171// GenerateBuildActions method to support the blueprint.Module interface. This
172// method will then call the module's GenerateAndroidBuildActions method once
173// for each build variant that is to be built. GenerateAndroidBuildActions is
174// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
175// AndroidModuleContext exposes extra functionality specific to the Android build
176// system including details about the particular build variant that is to be
177// generated.
178//
179// For example:
180//
181// import (
182// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700183// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800184// )
185//
186// type myModule struct {
187// common.AndroidModuleBase
188// properties struct {
189// MyProperty string
190// }
191// }
192//
193// func NewMyModule() (blueprint.Module, []interface{}) {
194// m := &myModule{}
195// return common.InitAndroidModule(m, &m.properties)
196// }
197//
198// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
199// // Get the CPU architecture for the current build variant.
200// variantArch := ctx.Arch()
201//
202// // ...
203// }
204type AndroidModuleBase struct {
205 // Putting the curiously recurring thing pointing to the thing that contains
206 // the thing pattern to good use.
207 module AndroidModule
208
209 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700210 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800211 hostAndDeviceProperties hostAndDeviceProperties
212 generalProperties []interface{}
213 archProperties []*archProperties
214
215 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700216 installFiles Paths
217 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700218
219 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
220 // Only set on the final variant of each module
221 installTarget string
222 checkbuildTarget string
223 blueprintDir string
Colin Cross3f40fa42015-01-30 17:27:36 -0800224}
225
226func (a *AndroidModuleBase) base() *AndroidModuleBase {
227 return a
228}
229
Colin Crossd3ba0392015-05-07 14:11:29 -0700230func (a *AndroidModuleBase) SetHostOrDevice(hod HostOrDevice) {
231 a.commonProperties.CompileHostOrDevice = hod
232}
233
Dan Willemsen490fd492015-11-24 17:53:15 -0800234func (a *AndroidModuleBase) SetHostType(ht HostType) {
235 a.commonProperties.CompileHostType = ht
236}
237
Colin Cross3f40fa42015-01-30 17:27:36 -0800238func (a *AndroidModuleBase) SetArch(arch Arch) {
239 a.commonProperties.CompileArch = arch
240}
241
242func (a *AndroidModuleBase) HostOrDevice() HostOrDevice {
Colin Crossd3ba0392015-05-07 14:11:29 -0700243 return a.commonProperties.CompileHostOrDevice
Colin Cross3f40fa42015-01-30 17:27:36 -0800244}
245
Dan Willemsen490fd492015-11-24 17:53:15 -0800246func (a *AndroidModuleBase) HostType() HostType {
247 return a.commonProperties.CompileHostType
248}
249
Colin Cross3f40fa42015-01-30 17:27:36 -0800250func (a *AndroidModuleBase) HostSupported() bool {
251 return a.commonProperties.HostOrDeviceSupported == HostSupported ||
252 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
253 a.hostAndDeviceProperties.Host_supported
254}
255
256func (a *AndroidModuleBase) DeviceSupported() bool {
257 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
258 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
259 a.hostAndDeviceProperties.Device_supported
260}
261
Dan Willemsen0effe062015-11-30 16:06:01 -0800262func (a *AndroidModuleBase) Enabled() bool {
263 if a.commonProperties.Enabled == nil {
264 if a.HostSupported() && a.HostOrDevice().Host() && a.HostType() == Windows {
265 return false
266 } else {
267 return true
268 }
Dan Willemsen490fd492015-11-24 17:53:15 -0800269 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800270 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800271}
272
273func (a *AndroidModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700274 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800275
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700276 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800277 ctx.VisitDepsDepthFirstIf(isFileInstaller,
278 func(m blueprint.Module) {
279 fileInstaller := m.(fileInstaller)
280 files := fileInstaller.filesToInstall()
281 result = append(result, files...)
282 })
283
284 return result
285}
286
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700287func (a *AndroidModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800288 return a.installFiles
289}
290
291func (p *AndroidModuleBase) NoAddressSanitizer() bool {
292 return p.noAddressSanitizer
293}
294
Colin Cross3f40fa42015-01-30 17:27:36 -0800295func (a *AndroidModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
296 if a != ctx.FinalModule().(AndroidModule).base() {
297 return
298 }
299
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700300 allInstalledFiles := Paths{}
301 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800302 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Crossc9404352015-03-26 16:10:12 -0700303 a := module.(AndroidModule).base()
304 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
305 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800306 })
307
Colin Cross9454bfa2015-03-17 13:24:18 -0700308 deps := []string{}
309
Colin Cross3f40fa42015-01-30 17:27:36 -0800310 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700311 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800312 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700313 Rule: blueprint.Phony,
314 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700315 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800316 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700317 })
318 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700319 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700320 }
321
322 if len(allCheckbuildFiles) > 0 {
323 name := ctx.ModuleName() + "-checkbuild"
324 ctx.Build(pctx, blueprint.BuildParams{
325 Rule: blueprint.Phony,
326 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700327 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700328 Optional: true,
329 })
330 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700331 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700332 }
333
334 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800335 suffix := ""
336 if ctx.Config().(Config).EmbeddedInMake() {
337 suffix = "-soong"
338 }
339
Colin Cross9454bfa2015-03-17 13:24:18 -0700340 ctx.Build(pctx, blueprint.BuildParams{
341 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800342 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700343 Implicits: deps,
344 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800345 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700346
347 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800348 }
349}
350
Colin Cross6362e272015-10-29 15:25:03 -0700351func (a *AndroidModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
352 return androidBaseContextImpl{
353 arch: a.commonProperties.CompileArch,
354 hod: a.commonProperties.CompileHostOrDevice,
Dan Willemsen490fd492015-11-24 17:53:15 -0800355 ht: a.commonProperties.CompileHostType,
Colin Cross6362e272015-10-29 15:25:03 -0700356 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800357 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800358}
359
360func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
361 androidCtx := &androidModuleContext{
Colin Cross6362e272015-10-29 15:25:03 -0700362 ModuleContext: ctx,
363 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
364 installDeps: a.computeInstallDeps(ctx),
365 installFiles: a.installFiles,
Colin Cross3f40fa42015-01-30 17:27:36 -0800366 }
367
Dan Willemsen0effe062015-11-30 16:06:01 -0800368 if !a.Enabled() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800369 return
370 }
371
372 a.module.GenerateAndroidBuildActions(androidCtx)
373 if ctx.Failed() {
374 return
375 }
376
Colin Crossc9404352015-03-26 16:10:12 -0700377 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
378 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
379
Colin Cross3f40fa42015-01-30 17:27:36 -0800380 a.generateModuleTarget(ctx)
381 if ctx.Failed() {
382 return
383 }
384}
385
Colin Crossf6566ed2015-03-24 11:13:38 -0700386type androidBaseContextImpl struct {
Colin Cross1332b002015-04-07 17:11:30 -0700387 arch Arch
Colin Crossd3ba0392015-05-07 14:11:29 -0700388 hod HostOrDevice
Dan Willemsen490fd492015-11-24 17:53:15 -0800389 ht HostType
Colin Cross1332b002015-04-07 17:11:30 -0700390 debug bool
391 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700392}
393
Colin Cross3f40fa42015-01-30 17:27:36 -0800394type androidModuleContext struct {
395 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700396 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700397 installDeps Paths
398 installFiles Paths
399 checkbuildFiles Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800400}
401
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800402func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800403 params.Optional = true
404 a.ModuleContext.Build(pctx, params)
405}
406
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700407func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
408 bparams := blueprint.BuildParams{
409 Rule: params.Rule,
410 Outputs: params.Outputs.Strings(),
411 Inputs: params.Inputs.Strings(),
412 Implicits: params.Implicits.Strings(),
413 OrderOnly: params.OrderOnly.Strings(),
414 Args: params.Args,
415 Optional: !params.Default,
416 }
417
418 if params.Output != nil {
419 bparams.Outputs = append(bparams.Outputs, params.Output.String())
420 }
421 if params.Input != nil {
422 bparams.Inputs = append(bparams.Inputs, params.Input.String())
423 }
424 if params.Implicit != nil {
425 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
426 }
427
428 a.ModuleContext.Build(pctx, bparams)
429}
430
Colin Crossf6566ed2015-03-24 11:13:38 -0700431func (a *androidBaseContextImpl) Arch() Arch {
Colin Cross3f40fa42015-01-30 17:27:36 -0800432 return a.arch
433}
434
Colin Crossd3ba0392015-05-07 14:11:29 -0700435func (a *androidBaseContextImpl) HostOrDevice() HostOrDevice {
436 return a.hod
437}
438
Dan Willemsen490fd492015-11-24 17:53:15 -0800439func (a *androidBaseContextImpl) HostType() HostType {
440 return a.ht
441}
442
Colin Crossf6566ed2015-03-24 11:13:38 -0700443func (a *androidBaseContextImpl) Host() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700444 return a.hod.Host()
Colin Crossf6566ed2015-03-24 11:13:38 -0700445}
446
447func (a *androidBaseContextImpl) Device() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700448 return a.hod.Device()
Colin Crossf6566ed2015-03-24 11:13:38 -0700449}
450
Colin Cross0af4b842015-04-30 16:36:18 -0700451func (a *androidBaseContextImpl) Darwin() bool {
Dan Willemsen490fd492015-11-24 17:53:15 -0800452 return a.hod.Host() && a.ht == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700453}
454
Colin Crossf6566ed2015-03-24 11:13:38 -0700455func (a *androidBaseContextImpl) Debug() bool {
456 return a.debug
457}
458
Colin Cross1332b002015-04-07 17:11:30 -0700459func (a *androidBaseContextImpl) AConfig() Config {
460 return a.config
461}
462
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700463func (a *androidModuleContext) InstallFileName(installPath, name string, srcPath Path,
464 deps ...Path) Path {
Colin Cross35cec122015-04-02 14:37:16 -0700465
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700466 fullInstallPath := PathForModuleInstall(a, installPath, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800467
Colin Cross35cec122015-04-02 14:37:16 -0700468 deps = append(deps, a.installDeps...)
469
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700470 a.ModuleBuild(pctx, ModuleBuildParams{
Colin Cross3f40fa42015-01-30 17:27:36 -0800471 Rule: Cp,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700472 Output: fullInstallPath,
473 Input: srcPath,
474 OrderOnly: Paths(deps),
Colin Cross346aa132015-12-17 17:19:51 -0800475 Default: !a.AConfig().EmbeddedInMake(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800476 })
477
478 a.installFiles = append(a.installFiles, fullInstallPath)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700479 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700480 return fullInstallPath
481}
482
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700483func (a *androidModuleContext) InstallFile(installPath string, srcPath Path, deps ...Path) Path {
484 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800485}
486
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700487func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800488 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
489}
490
Colin Cross3f40fa42015-01-30 17:27:36 -0800491type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700492 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800493}
494
495func isFileInstaller(m blueprint.Module) bool {
496 _, ok := m.(fileInstaller)
497 return ok
498}
499
500func isAndroidModule(m blueprint.Module) bool {
501 _, ok := m.(AndroidModule)
502 return ok
503}
Colin Crossfce53272015-04-08 11:21:40 -0700504
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700505func findStringInSlice(str string, slice []string) int {
506 for i, s := range slice {
507 if s == str {
508 return i
Colin Crossfce53272015-04-08 11:21:40 -0700509 }
510 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700511 return -1
512}
513
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700514func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
515 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700516 for i, e := range excludes {
517 j := findStringInSlice(e, srcFiles)
518 if j != -1 {
519 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
520 }
521
522 excludes[i] = filepath.Join(prefix, e)
523 }
524
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700525 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700526 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700527 if glob.IsGlob(s) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700528 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700529 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700530 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700531 }
532 }
533
534 return globbedSrcFiles
535}
536
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700537func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
538 ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700539 if err != nil {
540 ctx.ModuleErrorf("glob: %s", err.Error())
541 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700542 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700543}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700544
Colin Cross463a90e2015-06-17 14:20:06 -0700545func init() {
546 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
547}
548
Colin Cross1f8c52b2015-06-16 16:38:17 -0700549func BuildTargetSingleton() blueprint.Singleton {
550 return &buildTargetSingleton{}
551}
552
553type buildTargetSingleton struct{}
554
555func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
556 checkbuildDeps := []string{}
557
558 dirModules := make(map[string][]string)
559
560 ctx.VisitAllModules(func(module blueprint.Module) {
561 if a, ok := module.(AndroidModule); ok {
562 blueprintDir := a.base().blueprintDir
563 installTarget := a.base().installTarget
564 checkbuildTarget := a.base().checkbuildTarget
565
566 if checkbuildTarget != "" {
567 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
568 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
569 }
570
571 if installTarget != "" {
572 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
573 }
574 }
575 })
576
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800577 suffix := ""
578 if ctx.Config().(Config).EmbeddedInMake() {
579 suffix = "-soong"
580 }
581
Colin Cross1f8c52b2015-06-16 16:38:17 -0700582 // Create a top-level checkbuild target that depends on all modules
583 ctx.Build(pctx, blueprint.BuildParams{
584 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800585 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700586 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700587 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700588 })
589
590 // Create a mm/<directory> target that depends on all modules in a directory
591 dirs := sortedKeys(dirModules)
592 for _, dir := range dirs {
593 ctx.Build(pctx, blueprint.BuildParams{
594 Rule: blueprint.Phony,
595 Outputs: []string{filepath.Join("mm", dir)},
596 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800597 // HACK: checkbuild should be an optional build, but force it
598 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800599 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700600 })
601 }
602}