blob: 844db7f6737a5f2a6ceea1811fca18b1b0e0e6bc [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 Cross6ff51382015-12-17 16:39:19 -080018 "fmt"
Colin Cross3f40fa42015-01-30 17:27:36 -080019 "path/filepath"
Colin Cross6ff51382015-12-17 16:39:19 -080020 "strings"
Colin Crossf6566ed2015-03-24 11:13:38 -070021
Dan Willemsen0effe062015-11-30 16:06:01 -080022 "android/soong"
Colin Cross8f101b42015-06-17 15:09:06 -070023 "android/soong/glob"
24
Colin Crossf6566ed2015-03-24 11:13:38 -070025 "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -080026)
27
28var (
29 DeviceSharedLibrary = "shared_library"
30 DeviceStaticLibrary = "static_library"
31 DeviceExecutable = "executable"
32 HostSharedLibrary = "host_shared_library"
33 HostStaticLibrary = "host_static_library"
34 HostExecutable = "host_executable"
35)
36
Dan Willemsen34cc69e2015-09-23 15:26:20 -070037type ModuleBuildParams struct {
38 Rule blueprint.Rule
39 Output WritablePath
40 Outputs WritablePaths
41 Input Path
42 Inputs Paths
43 Implicit Path
44 Implicits Paths
45 OrderOnly Paths
46 Default bool
47 Args map[string]string
48}
49
Colin Crossf6566ed2015-03-24 11:13:38 -070050type androidBaseContext interface {
51 Arch() Arch
Colin Crossd3ba0392015-05-07 14:11:29 -070052 HostOrDevice() HostOrDevice
Dan Willemsen490fd492015-11-24 17:53:15 -080053 HostType() HostType
Colin Crossf6566ed2015-03-24 11:13:38 -070054 Host() bool
55 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070056 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070057 Debug() bool
Colin Cross1332b002015-04-07 17:11:30 -070058 AConfig() Config
Dan Willemsen782a2d12015-12-21 14:55:28 -080059 Proprietary() bool
60 InstallInData() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070061}
62
63type AndroidBaseContext interface {
64 blueprint.BaseModuleContext
65 androidBaseContext
66}
67
Colin Cross3f40fa42015-01-30 17:27:36 -080068type AndroidModuleContext interface {
69 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070070 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080071
Dan Willemsen34cc69e2015-09-23 15:26:20 -070072 // Similar to Build, but takes Paths instead of []string,
73 // and performs more verification.
74 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070075
Dan Willemsen34cc69e2015-09-23 15:26:20 -070076 ExpandSources(srcFiles, excludes []string) Paths
77 Glob(outDir, globPattern string, excludes []string) Paths
78
Dan Willemsen782a2d12015-12-21 14:55:28 -080079 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) Path
80 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) Path
Dan Willemsen34cc69e2015-09-23 15:26:20 -070081 CheckbuildFile(srcPath Path)
Colin Cross3f40fa42015-01-30 17:27:36 -080082}
83
84type AndroidModule interface {
85 blueprint.Module
86
87 GenerateAndroidBuildActions(AndroidModuleContext)
88
89 base() *AndroidModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -080090 Enabled() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080091 HostOrDevice() HostOrDevice
Dan Willemsen782a2d12015-12-21 14:55:28 -080092 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080093}
94
Colin Cross3f40fa42015-01-30 17:27:36 -080095type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -070096 Name string
97 Deps []string
98 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -080099
Dan Willemsen0effe062015-11-30 16:06:01 -0800100 // emit build rules for this module
101 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800102
Colin Cross7d5136f2015-05-11 13:39:40 -0700103 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800104 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
105 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
106 // platform
107 Compile_multilib string
108
Dan Willemsen782a2d12015-12-21 14:55:28 -0800109 // whether this is a proprietary vendor module, and should be installed into /vendor
110 Proprietary bool
111
Colin Crossd3ba0392015-05-07 14:11:29 -0700112 // Set by HostOrDeviceMutator
113 CompileHostOrDevice HostOrDevice `blueprint:"mutated"`
114
Dan Willemsen490fd492015-11-24 17:53:15 -0800115 // Set by HostTypeMutator
116 CompileHostType HostType `blueprint:"mutated"`
117
Colin Cross3f40fa42015-01-30 17:27:36 -0800118 // Set by ArchMutator
119 CompileArch Arch `blueprint:"mutated"`
120
121 // Set by InitAndroidModule
122 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
123}
124
125type hostAndDeviceProperties struct {
126 Host_supported bool
127 Device_supported bool
128}
129
Colin Crossc472d572015-03-17 15:06:21 -0700130type Multilib string
131
132const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700133 MultilibBoth Multilib = "both"
134 MultilibFirst Multilib = "first"
135 MultilibCommon Multilib = "common"
136 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700137)
138
Colin Cross5049f022015-03-18 13:28:46 -0700139func InitAndroidModule(m AndroidModule,
Colin Cross3f40fa42015-01-30 17:27:36 -0800140 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
141
142 base := m.base()
143 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700144
Colin Cross7f64b6d2015-07-09 13:57:48 -0700145 propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700146
147 return m, propertyStructs
148}
149
150func InitAndroidArchModule(m AndroidModule, hod HostOrDeviceSupported, defaultMultilib Multilib,
151 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
152
153 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
154
155 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800156 base.commonProperties.HostOrDeviceSupported = hod
Colin Crosscfad1192015-11-02 16:43:11 -0800157 base.commonProperties.Compile_multilib = string(defaultMultilib)
Colin Cross3f40fa42015-01-30 17:27:36 -0800158
Dan Willemsen218f6562015-07-08 18:13:11 -0700159 switch hod {
160 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800161 // Default to module to device supported, host not supported, can override in module
162 // properties
163 base.hostAndDeviceProperties.Device_supported = true
Dan Willemsen218f6562015-07-08 18:13:11 -0700164 fallthrough
165 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800166 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
167 }
168
Colin Crosscfad1192015-11-02 16:43:11 -0800169 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800170}
171
172// A AndroidModuleBase object contains the properties that are common to all Android
173// modules. It should be included as an anonymous field in every module
174// struct definition. InitAndroidModule should then be called from the module's
175// factory function, and the return values from InitAndroidModule should be
176// returned from the factory function.
177//
178// The AndroidModuleBase type is responsible for implementing the
179// GenerateBuildActions method to support the blueprint.Module interface. This
180// method will then call the module's GenerateAndroidBuildActions method once
181// for each build variant that is to be built. GenerateAndroidBuildActions is
182// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
183// AndroidModuleContext exposes extra functionality specific to the Android build
184// system including details about the particular build variant that is to be
185// generated.
186//
187// For example:
188//
189// import (
190// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700191// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800192// )
193//
194// type myModule struct {
195// common.AndroidModuleBase
196// properties struct {
197// MyProperty string
198// }
199// }
200//
201// func NewMyModule() (blueprint.Module, []interface{}) {
202// m := &myModule{}
203// return common.InitAndroidModule(m, &m.properties)
204// }
205//
206// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
207// // Get the CPU architecture for the current build variant.
208// variantArch := ctx.Arch()
209//
210// // ...
211// }
212type AndroidModuleBase struct {
213 // Putting the curiously recurring thing pointing to the thing that contains
214 // the thing pattern to good use.
215 module AndroidModule
216
217 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700218 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800219 hostAndDeviceProperties hostAndDeviceProperties
220 generalProperties []interface{}
221 archProperties []*archProperties
222
223 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700224 installFiles Paths
225 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700226
227 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
228 // Only set on the final variant of each module
229 installTarget string
230 checkbuildTarget string
231 blueprintDir string
Colin Cross3f40fa42015-01-30 17:27:36 -0800232}
233
234func (a *AndroidModuleBase) base() *AndroidModuleBase {
235 return a
236}
237
Colin Crossd3ba0392015-05-07 14:11:29 -0700238func (a *AndroidModuleBase) SetHostOrDevice(hod HostOrDevice) {
239 a.commonProperties.CompileHostOrDevice = hod
240}
241
Dan Willemsen490fd492015-11-24 17:53:15 -0800242func (a *AndroidModuleBase) SetHostType(ht HostType) {
243 a.commonProperties.CompileHostType = ht
244}
245
Colin Cross3f40fa42015-01-30 17:27:36 -0800246func (a *AndroidModuleBase) SetArch(arch Arch) {
247 a.commonProperties.CompileArch = arch
248}
249
250func (a *AndroidModuleBase) HostOrDevice() HostOrDevice {
Colin Crossd3ba0392015-05-07 14:11:29 -0700251 return a.commonProperties.CompileHostOrDevice
Colin Cross3f40fa42015-01-30 17:27:36 -0800252}
253
Dan Willemsen490fd492015-11-24 17:53:15 -0800254func (a *AndroidModuleBase) HostType() HostType {
255 return a.commonProperties.CompileHostType
256}
257
Dan Willemsen97750522016-02-09 17:43:51 -0800258func (a *AndroidModuleBase) Host() bool {
259 return a.HostOrDevice().Host()
260}
261
262func (a *AndroidModuleBase) Arch() Arch {
263 return a.commonProperties.CompileArch
264}
265
Colin Cross3f40fa42015-01-30 17:27:36 -0800266func (a *AndroidModuleBase) HostSupported() bool {
267 return a.commonProperties.HostOrDeviceSupported == HostSupported ||
268 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
269 a.hostAndDeviceProperties.Host_supported
270}
271
272func (a *AndroidModuleBase) DeviceSupported() bool {
273 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
274 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
275 a.hostAndDeviceProperties.Device_supported
276}
277
Dan Willemsen0effe062015-11-30 16:06:01 -0800278func (a *AndroidModuleBase) Enabled() bool {
279 if a.commonProperties.Enabled == nil {
280 if a.HostSupported() && a.HostOrDevice().Host() && a.HostType() == Windows {
281 return false
282 } else {
283 return true
284 }
Dan Willemsen490fd492015-11-24 17:53:15 -0800285 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800286 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800287}
288
289func (a *AndroidModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700290 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800291
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700292 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800293 ctx.VisitDepsDepthFirstIf(isFileInstaller,
294 func(m blueprint.Module) {
295 fileInstaller := m.(fileInstaller)
296 files := fileInstaller.filesToInstall()
297 result = append(result, files...)
298 })
299
300 return result
301}
302
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700303func (a *AndroidModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800304 return a.installFiles
305}
306
307func (p *AndroidModuleBase) NoAddressSanitizer() bool {
308 return p.noAddressSanitizer
309}
310
Dan Willemsen782a2d12015-12-21 14:55:28 -0800311func (p *AndroidModuleBase) InstallInData() bool {
312 return false
313}
314
Colin Cross3f40fa42015-01-30 17:27:36 -0800315func (a *AndroidModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
316 if a != ctx.FinalModule().(AndroidModule).base() {
317 return
318 }
319
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700320 allInstalledFiles := Paths{}
321 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800322 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Crossc9404352015-03-26 16:10:12 -0700323 a := module.(AndroidModule).base()
324 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
325 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800326 })
327
Colin Cross9454bfa2015-03-17 13:24:18 -0700328 deps := []string{}
329
Colin Cross3f40fa42015-01-30 17:27:36 -0800330 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700331 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800332 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700333 Rule: blueprint.Phony,
334 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700335 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800336 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700337 })
338 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700339 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700340 }
341
342 if len(allCheckbuildFiles) > 0 {
343 name := ctx.ModuleName() + "-checkbuild"
344 ctx.Build(pctx, blueprint.BuildParams{
345 Rule: blueprint.Phony,
346 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700347 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700348 Optional: true,
349 })
350 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700351 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700352 }
353
354 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800355 suffix := ""
356 if ctx.Config().(Config).EmbeddedInMake() {
357 suffix = "-soong"
358 }
359
Colin Cross9454bfa2015-03-17 13:24:18 -0700360 ctx.Build(pctx, blueprint.BuildParams{
361 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800362 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700363 Implicits: deps,
364 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800365 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700366
367 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800368 }
369}
370
Colin Cross6362e272015-10-29 15:25:03 -0700371func (a *AndroidModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
372 return androidBaseContextImpl{
Dan Willemsen782a2d12015-12-21 14:55:28 -0800373 arch: a.commonProperties.CompileArch,
374 hod: a.commonProperties.CompileHostOrDevice,
375 ht: a.commonProperties.CompileHostType,
376 proprietary: a.commonProperties.Proprietary,
377 config: ctx.Config().(Config),
378 installInData: a.module.InstallInData(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800379 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800380}
381
382func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
383 androidCtx := &androidModuleContext{
Colin Cross6362e272015-10-29 15:25:03 -0700384 ModuleContext: ctx,
385 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
386 installDeps: a.computeInstallDeps(ctx),
387 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800388 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800389 }
390
Dan Willemsen0effe062015-11-30 16:06:01 -0800391 if !a.Enabled() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800392 return
393 }
394
395 a.module.GenerateAndroidBuildActions(androidCtx)
396 if ctx.Failed() {
397 return
398 }
399
Colin Crossc9404352015-03-26 16:10:12 -0700400 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
401 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
402
Colin Cross3f40fa42015-01-30 17:27:36 -0800403 a.generateModuleTarget(ctx)
404 if ctx.Failed() {
405 return
406 }
407}
408
Colin Crossf6566ed2015-03-24 11:13:38 -0700409type androidBaseContextImpl struct {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800410 arch Arch
411 hod HostOrDevice
412 ht HostType
413 debug bool
414 config Config
415 proprietary bool
416 installInData bool
Colin Crossf6566ed2015-03-24 11:13:38 -0700417}
418
Colin Cross3f40fa42015-01-30 17:27:36 -0800419type androidModuleContext struct {
420 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700421 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700422 installDeps Paths
423 installFiles Paths
424 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800425 missingDeps []string
426}
427
428func (a *androidModuleContext) ninjaError(outputs []string, err error) {
429 a.ModuleContext.Build(pctx, blueprint.BuildParams{
430 Rule: ErrorRule,
431 Outputs: outputs,
432 Optional: true,
433 Args: map[string]string{
434 "error": err.Error(),
435 },
436 })
437 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800438}
439
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800440func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Cross6ff51382015-12-17 16:39:19 -0800441 if a.missingDeps != nil {
442 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
443 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
444 return
445 }
446
Colin Cross3f40fa42015-01-30 17:27:36 -0800447 params.Optional = true
448 a.ModuleContext.Build(pctx, params)
449}
450
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700451func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
452 bparams := blueprint.BuildParams{
453 Rule: params.Rule,
454 Outputs: params.Outputs.Strings(),
455 Inputs: params.Inputs.Strings(),
456 Implicits: params.Implicits.Strings(),
457 OrderOnly: params.OrderOnly.Strings(),
458 Args: params.Args,
459 Optional: !params.Default,
460 }
461
462 if params.Output != nil {
463 bparams.Outputs = append(bparams.Outputs, params.Output.String())
464 }
465 if params.Input != nil {
466 bparams.Inputs = append(bparams.Inputs, params.Input.String())
467 }
468 if params.Implicit != nil {
469 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
470 }
471
Colin Cross6ff51382015-12-17 16:39:19 -0800472 if a.missingDeps != nil {
473 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
474 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
475 return
476 }
477
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700478 a.ModuleContext.Build(pctx, bparams)
479}
480
Colin Cross6ff51382015-12-17 16:39:19 -0800481func (a *androidModuleContext) GetMissingDependencies() []string {
482 return a.missingDeps
483}
484
Colin Crossf6566ed2015-03-24 11:13:38 -0700485func (a *androidBaseContextImpl) Arch() Arch {
Colin Cross3f40fa42015-01-30 17:27:36 -0800486 return a.arch
487}
488
Colin Crossd3ba0392015-05-07 14:11:29 -0700489func (a *androidBaseContextImpl) HostOrDevice() HostOrDevice {
490 return a.hod
491}
492
Dan Willemsen490fd492015-11-24 17:53:15 -0800493func (a *androidBaseContextImpl) HostType() HostType {
494 return a.ht
495}
496
Colin Crossf6566ed2015-03-24 11:13:38 -0700497func (a *androidBaseContextImpl) Host() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700498 return a.hod.Host()
Colin Crossf6566ed2015-03-24 11:13:38 -0700499}
500
501func (a *androidBaseContextImpl) Device() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700502 return a.hod.Device()
Colin Crossf6566ed2015-03-24 11:13:38 -0700503}
504
Colin Cross0af4b842015-04-30 16:36:18 -0700505func (a *androidBaseContextImpl) Darwin() bool {
Dan Willemsen490fd492015-11-24 17:53:15 -0800506 return a.hod.Host() && a.ht == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700507}
508
Colin Crossf6566ed2015-03-24 11:13:38 -0700509func (a *androidBaseContextImpl) Debug() bool {
510 return a.debug
511}
512
Colin Cross1332b002015-04-07 17:11:30 -0700513func (a *androidBaseContextImpl) AConfig() Config {
514 return a.config
515}
516
Dan Willemsen782a2d12015-12-21 14:55:28 -0800517func (a *androidBaseContextImpl) Proprietary() bool {
518 return a.proprietary
519}
520
521func (a *androidBaseContextImpl) InstallInData() bool {
522 return a.installInData
523}
524
525func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700526 deps ...Path) Path {
Colin Cross35cec122015-04-02 14:37:16 -0700527
Dan Willemsen782a2d12015-12-21 14:55:28 -0800528 fullInstallPath := installPath.Join(a, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800529
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800530 if a.Host() || !a.AConfig().SkipDeviceInstall() {
Dan Willemsen322acaf2016-01-12 23:07:05 -0800531 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700532
Dan Willemsen322acaf2016-01-12 23:07:05 -0800533 a.ModuleBuild(pctx, ModuleBuildParams{
534 Rule: Cp,
535 Output: fullInstallPath,
536 Input: srcPath,
537 OrderOnly: Paths(deps),
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800538 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800539 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800540
Dan Willemsen322acaf2016-01-12 23:07:05 -0800541 a.installFiles = append(a.installFiles, fullInstallPath)
542 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700543 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700544 return fullInstallPath
545}
546
Dan Willemsen782a2d12015-12-21 14:55:28 -0800547func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) Path {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700548 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800549}
550
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700551func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800552 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
553}
554
Colin Cross3f40fa42015-01-30 17:27:36 -0800555type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700556 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800557}
558
559func isFileInstaller(m blueprint.Module) bool {
560 _, ok := m.(fileInstaller)
561 return ok
562}
563
564func isAndroidModule(m blueprint.Module) bool {
565 _, ok := m.(AndroidModule)
566 return ok
567}
Colin Crossfce53272015-04-08 11:21:40 -0700568
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700569func findStringInSlice(str string, slice []string) int {
570 for i, s := range slice {
571 if s == str {
572 return i
Colin Crossfce53272015-04-08 11:21:40 -0700573 }
574 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700575 return -1
576}
577
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700578func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
579 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700580 for i, e := range excludes {
581 j := findStringInSlice(e, srcFiles)
582 if j != -1 {
583 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
584 }
585
586 excludes[i] = filepath.Join(prefix, e)
587 }
588
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700589 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700590 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700591 if glob.IsGlob(s) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700592 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700593 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700594 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700595 }
596 }
597
598 return globbedSrcFiles
599}
600
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700601func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
602 ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700603 if err != nil {
604 ctx.ModuleErrorf("glob: %s", err.Error())
605 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700606 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700607}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700608
Colin Cross463a90e2015-06-17 14:20:06 -0700609func init() {
610 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
611}
612
Colin Cross1f8c52b2015-06-16 16:38:17 -0700613func BuildTargetSingleton() blueprint.Singleton {
614 return &buildTargetSingleton{}
615}
616
617type buildTargetSingleton struct{}
618
619func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
620 checkbuildDeps := []string{}
621
622 dirModules := make(map[string][]string)
623
624 ctx.VisitAllModules(func(module blueprint.Module) {
625 if a, ok := module.(AndroidModule); ok {
626 blueprintDir := a.base().blueprintDir
627 installTarget := a.base().installTarget
628 checkbuildTarget := a.base().checkbuildTarget
629
630 if checkbuildTarget != "" {
631 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
632 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
633 }
634
635 if installTarget != "" {
636 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
637 }
638 }
639 })
640
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800641 suffix := ""
642 if ctx.Config().(Config).EmbeddedInMake() {
643 suffix = "-soong"
644 }
645
Colin Cross1f8c52b2015-06-16 16:38:17 -0700646 // Create a top-level checkbuild target that depends on all modules
647 ctx.Build(pctx, blueprint.BuildParams{
648 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800649 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700650 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700651 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700652 })
653
654 // Create a mm/<directory> target that depends on all modules in a directory
655 dirs := sortedKeys(dirModules)
656 for _, dir := range dirs {
657 ctx.Build(pctx, blueprint.BuildParams{
658 Rule: blueprint.Phony,
659 Outputs: []string{filepath.Join("mm", dir)},
660 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800661 // HACK: checkbuild should be an optional build, but force it
662 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800663 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700664 })
665 }
666}
Colin Crossd779da42015-12-17 18:00:23 -0800667
668type AndroidModulesByName struct {
669 slice []AndroidModule
670 ctx interface {
671 ModuleName(blueprint.Module) string
672 ModuleSubDir(blueprint.Module) string
673 }
674}
675
676func (s AndroidModulesByName) Len() int { return len(s.slice) }
677func (s AndroidModulesByName) Less(i, j int) bool {
678 mi, mj := s.slice[i], s.slice[j]
679 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
680
681 if ni != nj {
682 return ni < nj
683 } else {
684 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
685 }
686}
687func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }