blob: fd37ca85c348ce2620644ceacdad088ba5d13ceb [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
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Colin Cross3f40fa42015-01-30 17:27:36 -080016
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
Colin Crossa120ec12016-08-19 16:07:38 -070028func init() {
29 RegisterTopDownMutator("customizer", customizerMutator).Parallel()
30 RegisterBottomUpMutator("defaults_deps", defaultsDepsMutator).Parallel()
31 RegisterTopDownMutator("defaults", defaultsMutator).Parallel()
32
33 RegisterBottomUpMutator("arch", ArchMutator).Parallel()
34}
35
Colin Cross3f40fa42015-01-30 17:27:36 -080036var (
37 DeviceSharedLibrary = "shared_library"
38 DeviceStaticLibrary = "static_library"
39 DeviceExecutable = "executable"
40 HostSharedLibrary = "host_shared_library"
41 HostStaticLibrary = "host_static_library"
42 HostExecutable = "host_executable"
43)
44
Dan Willemsen34cc69e2015-09-23 15:26:20 -070045type ModuleBuildParams struct {
46 Rule blueprint.Rule
47 Output WritablePath
48 Outputs WritablePaths
49 Input Path
50 Inputs Paths
51 Implicit Path
52 Implicits Paths
53 OrderOnly Paths
54 Default bool
55 Args map[string]string
56}
57
Colin Crossf6566ed2015-03-24 11:13:38 -070058type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070059 Target() Target
Colin Crossf6566ed2015-03-24 11:13:38 -070060 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070061 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070062 Host() bool
63 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070064 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070065 Debug() bool
Colin Cross1332b002015-04-07 17:11:30 -070066 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070067 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070068}
69
Colin Cross635c3b02016-05-18 15:37:25 -070070type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070071 blueprint.BaseModuleContext
72 androidBaseContext
73}
74
Colin Cross635c3b02016-05-18 15:37:25 -070075type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080076 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070077 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080078
Dan Willemsen34cc69e2015-09-23 15:26:20 -070079 // Similar to Build, but takes Paths instead of []string,
80 // and performs more verification.
81 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070082
Dan Willemsen34cc69e2015-09-23 15:26:20 -070083 ExpandSources(srcFiles, excludes []string) Paths
84 Glob(outDir, globPattern string, excludes []string) Paths
85
Colin Crossa2344662016-03-24 13:14:12 -070086 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
87 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080088 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070089 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080090
91 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -070092
93 Proprietary() bool
94 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080095}
96
Colin Cross635c3b02016-05-18 15:37:25 -070097type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080098 blueprint.Module
99
Colin Cross635c3b02016-05-18 15:37:25 -0700100 GenerateAndroidBuildActions(ModuleContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800101
Colin Cross635c3b02016-05-18 15:37:25 -0700102 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800103 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700104 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800105 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800106}
107
Colin Cross3f40fa42015-01-30 17:27:36 -0800108type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700109 Name string
110 Deps []string
111 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800112
Dan Willemsen0effe062015-11-30 16:06:01 -0800113 // emit build rules for this module
114 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800115
Colin Cross7d5136f2015-05-11 13:39:40 -0700116 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800117 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
118 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
119 // platform
120 Compile_multilib string
121
Dan Willemsen782a2d12015-12-21 14:55:28 -0800122 // whether this is a proprietary vendor module, and should be installed into /vendor
123 Proprietary bool
124
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700125 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
126 // file
127 Logtags []string
128
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700129 // init.rc files to be installed if this module is installed
130 Init_rc []string
131
Chris Wolfe998306e2016-08-15 14:47:23 -0400132 // names of other modules to install if this module is installed
133 Required []string
134
Colin Crossa1ad8d12016-06-01 17:09:44 -0700135 // Set by TargetMutator
136 CompileTarget Target `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800137
138 // Set by InitAndroidModule
139 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
140}
141
142type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700143 Host_supported *bool
144 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800145}
146
Colin Crossc472d572015-03-17 15:06:21 -0700147type Multilib string
148
149const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700150 MultilibBoth Multilib = "both"
151 MultilibFirst Multilib = "first"
152 MultilibCommon Multilib = "common"
153 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700154)
155
Colin Crossa1ad8d12016-06-01 17:09:44 -0700156type HostOrDeviceSupported int
157
158const (
159 _ HostOrDeviceSupported = iota
160 HostSupported
161 DeviceSupported
162 HostAndDeviceSupported
163 HostAndDeviceDefault
164)
165
Colin Cross635c3b02016-05-18 15:37:25 -0700166func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800167 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
168
169 base := m.base()
170 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700171
Colin Cross7f64b6d2015-07-09 13:57:48 -0700172 propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700173
174 return m, propertyStructs
175}
176
Colin Cross635c3b02016-05-18 15:37:25 -0700177func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700178 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
179
180 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
181
182 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800183 base.commonProperties.HostOrDeviceSupported = hod
Colin Crosscfad1192015-11-02 16:43:11 -0800184 base.commonProperties.Compile_multilib = string(defaultMultilib)
Colin Cross3f40fa42015-01-30 17:27:36 -0800185
Dan Willemsen218f6562015-07-08 18:13:11 -0700186 switch hod {
187 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800188 // Default to module to device supported, host not supported, can override in module
189 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700190 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700191 fallthrough
192 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800193 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
194 }
195
Colin Crosscfad1192015-11-02 16:43:11 -0800196 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800197}
198
Colin Crossa120ec12016-08-19 16:07:38 -0700199func AddCustomizer(m blueprint.Module, c PropertyCustomizer) {
200 base := m.(Module).base()
201 base.customizers = append(base.customizers, c)
202}
203
Colin Cross3f40fa42015-01-30 17:27:36 -0800204// A AndroidModuleBase object contains the properties that are common to all Android
205// modules. It should be included as an anonymous field in every module
206// struct definition. InitAndroidModule should then be called from the module's
207// factory function, and the return values from InitAndroidModule should be
208// returned from the factory function.
209//
210// The AndroidModuleBase type is responsible for implementing the
211// GenerateBuildActions method to support the blueprint.Module interface. This
212// method will then call the module's GenerateAndroidBuildActions method once
213// for each build variant that is to be built. GenerateAndroidBuildActions is
214// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
215// AndroidModuleContext exposes extra functionality specific to the Android build
216// system including details about the particular build variant that is to be
217// generated.
218//
219// For example:
220//
221// import (
222// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700223// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800224// )
225//
226// type myModule struct {
227// common.AndroidModuleBase
228// properties struct {
229// MyProperty string
230// }
231// }
232//
233// func NewMyModule() (blueprint.Module, []interface{}) {
234// m := &myModule{}
235// return common.InitAndroidModule(m, &m.properties)
236// }
237//
238// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
239// // Get the CPU architecture for the current build variant.
240// variantArch := ctx.Arch()
241//
242// // ...
243// }
Colin Cross635c3b02016-05-18 15:37:25 -0700244type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800245 // Putting the curiously recurring thing pointing to the thing that contains
246 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700247 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800248
249 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700250 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800251 hostAndDeviceProperties hostAndDeviceProperties
252 generalProperties []interface{}
253 archProperties []*archProperties
Colin Crossa120ec12016-08-19 16:07:38 -0700254 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800255
256 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700257 installFiles Paths
258 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700259
260 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
261 // Only set on the final variant of each module
262 installTarget string
263 checkbuildTarget string
264 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700265
266 customizers []PropertyCustomizer
Colin Cross3f40fa42015-01-30 17:27:36 -0800267}
268
Colin Cross635c3b02016-05-18 15:37:25 -0700269func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800270 return a
271}
272
Colin Crossa1ad8d12016-06-01 17:09:44 -0700273func (a *ModuleBase) SetTarget(target Target) {
274 a.commonProperties.CompileTarget = target
Colin Crossd3ba0392015-05-07 14:11:29 -0700275}
276
Colin Crossa1ad8d12016-06-01 17:09:44 -0700277func (a *ModuleBase) Target() Target {
278 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800279}
280
Colin Crossa1ad8d12016-06-01 17:09:44 -0700281func (a *ModuleBase) Os() OsType {
282 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800283}
284
Colin Cross635c3b02016-05-18 15:37:25 -0700285func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700286 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800287}
288
Colin Cross635c3b02016-05-18 15:37:25 -0700289func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700290 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800291}
292
Colin Crossa1ad8d12016-06-01 17:09:44 -0700293func (a *ModuleBase) OsClassSupported() []OsClass {
294 switch a.commonProperties.HostOrDeviceSupported {
295 case HostSupported:
296 // TODO(ccross): explicitly mark host cross support
297 return []OsClass{Host, HostCross}
298 case DeviceSupported:
299 return []OsClass{Device}
300 case HostAndDeviceSupported:
301 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700302 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700303 supported = append(supported, Host, HostCross)
304 }
Colin Crossa4190c12016-07-12 13:11:25 -0700305 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700306 supported = append(supported, Device)
307 }
308 return supported
309 default:
310 return nil
311 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800312}
313
Colin Cross635c3b02016-05-18 15:37:25 -0700314func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800315 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
316 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700317 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800318}
319
Colin Cross635c3b02016-05-18 15:37:25 -0700320func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800321 if a.commonProperties.Enabled == nil {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700322 return a.Os().Class != HostCross
Dan Willemsen490fd492015-11-24 17:53:15 -0800323 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800324 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800325}
326
Colin Cross635c3b02016-05-18 15:37:25 -0700327func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700328 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800329
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700330 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800331 ctx.VisitDepsDepthFirstIf(isFileInstaller,
332 func(m blueprint.Module) {
333 fileInstaller := m.(fileInstaller)
334 files := fileInstaller.filesToInstall()
335 result = append(result, files...)
336 })
337
338 return result
339}
340
Colin Cross635c3b02016-05-18 15:37:25 -0700341func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800342 return a.installFiles
343}
344
Colin Cross635c3b02016-05-18 15:37:25 -0700345func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800346 return p.noAddressSanitizer
347}
348
Colin Cross635c3b02016-05-18 15:37:25 -0700349func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800350 return false
351}
352
Colin Cross635c3b02016-05-18 15:37:25 -0700353func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
354 if a != ctx.FinalModule().(Module).base() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800355 return
356 }
357
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700358 allInstalledFiles := Paths{}
359 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800360 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700361 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700362 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
363 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800364 })
365
Colin Cross9454bfa2015-03-17 13:24:18 -0700366 deps := []string{}
367
Colin Cross3f40fa42015-01-30 17:27:36 -0800368 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700369 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800370 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700371 Rule: blueprint.Phony,
372 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700373 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800374 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700375 })
376 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700377 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700378 }
379
380 if len(allCheckbuildFiles) > 0 {
381 name := ctx.ModuleName() + "-checkbuild"
382 ctx.Build(pctx, blueprint.BuildParams{
383 Rule: blueprint.Phony,
384 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700385 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700386 Optional: true,
387 })
388 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700389 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700390 }
391
392 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800393 suffix := ""
394 if ctx.Config().(Config).EmbeddedInMake() {
395 suffix = "-soong"
396 }
397
Colin Cross9454bfa2015-03-17 13:24:18 -0700398 ctx.Build(pctx, blueprint.BuildParams{
399 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800400 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700401 Implicits: deps,
402 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800403 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700404
405 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800406 }
407}
408
Colin Cross635c3b02016-05-18 15:37:25 -0700409func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700410 return androidBaseContextImpl{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700411 target: a.commonProperties.CompileTarget,
412 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800413 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800414}
415
Colin Cross635c3b02016-05-18 15:37:25 -0700416func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800417 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700418 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700419 ModuleContext: ctx,
420 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
421 installDeps: a.computeInstallDeps(ctx),
422 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800423 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800424 }
425
Dan Willemsen0effe062015-11-30 16:06:01 -0800426 if !a.Enabled() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800427 return
428 }
429
430 a.module.GenerateAndroidBuildActions(androidCtx)
431 if ctx.Failed() {
432 return
433 }
434
Colin Crossc9404352015-03-26 16:10:12 -0700435 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
436 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
437
Colin Cross3f40fa42015-01-30 17:27:36 -0800438 a.generateModuleTarget(ctx)
439 if ctx.Failed() {
440 return
441 }
442}
443
Colin Crossf6566ed2015-03-24 11:13:38 -0700444type androidBaseContextImpl struct {
Colin Cross8d8f8e22016-08-03 11:57:50 -0700445 target Target
446 debug bool
447 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700448}
449
Colin Cross3f40fa42015-01-30 17:27:36 -0800450type androidModuleContext struct {
451 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700452 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700453 installDeps Paths
454 installFiles Paths
455 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800456 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700457 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800458}
459
460func (a *androidModuleContext) ninjaError(outputs []string, err error) {
461 a.ModuleContext.Build(pctx, blueprint.BuildParams{
462 Rule: ErrorRule,
463 Outputs: outputs,
464 Optional: true,
465 Args: map[string]string{
466 "error": err.Error(),
467 },
468 })
469 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800470}
471
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800472func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Crosse2c48742016-04-27 13:47:35 -0700473 if a.missingDeps != nil && params.Rule != globRule {
Colin Cross6ff51382015-12-17 16:39:19 -0800474 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
475 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
476 return
477 }
478
Colin Cross3f40fa42015-01-30 17:27:36 -0800479 params.Optional = true
480 a.ModuleContext.Build(pctx, params)
481}
482
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700483func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
484 bparams := blueprint.BuildParams{
485 Rule: params.Rule,
486 Outputs: params.Outputs.Strings(),
487 Inputs: params.Inputs.Strings(),
488 Implicits: params.Implicits.Strings(),
489 OrderOnly: params.OrderOnly.Strings(),
490 Args: params.Args,
491 Optional: !params.Default,
492 }
493
494 if params.Output != nil {
495 bparams.Outputs = append(bparams.Outputs, params.Output.String())
496 }
497 if params.Input != nil {
498 bparams.Inputs = append(bparams.Inputs, params.Input.String())
499 }
500 if params.Implicit != nil {
501 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
502 }
503
Colin Cross6ff51382015-12-17 16:39:19 -0800504 if a.missingDeps != nil {
505 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
506 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
507 return
508 }
509
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700510 a.ModuleContext.Build(pctx, bparams)
511}
512
Colin Cross6ff51382015-12-17 16:39:19 -0800513func (a *androidModuleContext) GetMissingDependencies() []string {
514 return a.missingDeps
515}
516
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800517func (a *androidModuleContext) AddMissingDependencies(deps []string) {
518 if deps != nil {
519 a.missingDeps = append(a.missingDeps, deps...)
520 }
521}
522
Colin Crossa1ad8d12016-06-01 17:09:44 -0700523func (a *androidBaseContextImpl) Target() Target {
524 return a.target
525}
526
Colin Crossf6566ed2015-03-24 11:13:38 -0700527func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700528 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800529}
530
Colin Crossa1ad8d12016-06-01 17:09:44 -0700531func (a *androidBaseContextImpl) Os() OsType {
532 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800533}
534
Colin Crossf6566ed2015-03-24 11:13:38 -0700535func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700536 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700537}
538
539func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700540 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700541}
542
Colin Cross0af4b842015-04-30 16:36:18 -0700543func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700544 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700545}
546
Colin Crossf6566ed2015-03-24 11:13:38 -0700547func (a *androidBaseContextImpl) Debug() bool {
548 return a.debug
549}
550
Colin Cross1332b002015-04-07 17:11:30 -0700551func (a *androidBaseContextImpl) AConfig() Config {
552 return a.config
553}
554
Colin Cross9272ade2016-08-17 15:24:12 -0700555func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
556 return DeviceConfig{a.config.deviceConfig}
557}
558
Colin Cross8d8f8e22016-08-03 11:57:50 -0700559func (a *androidModuleContext) Proprietary() bool {
560 return a.module.base().commonProperties.Proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800561}
562
Colin Cross8d8f8e22016-08-03 11:57:50 -0700563func (a *androidModuleContext) InstallInData() bool {
564 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800565}
566
567func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700568 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700569
Dan Willemsen782a2d12015-12-21 14:55:28 -0800570 fullInstallPath := installPath.Join(a, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800571
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800572 if a.Host() || !a.AConfig().SkipDeviceInstall() {
Dan Willemsen322acaf2016-01-12 23:07:05 -0800573 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700574
Dan Willemsen322acaf2016-01-12 23:07:05 -0800575 a.ModuleBuild(pctx, ModuleBuildParams{
576 Rule: Cp,
577 Output: fullInstallPath,
578 Input: srcPath,
579 OrderOnly: Paths(deps),
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800580 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800581 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800582
Dan Willemsen322acaf2016-01-12 23:07:05 -0800583 a.installFiles = append(a.installFiles, fullInstallPath)
584 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700585 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700586 return fullInstallPath
587}
588
Colin Crossa2344662016-03-24 13:14:12 -0700589func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700590 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800591}
592
Colin Cross3854a602016-01-11 12:49:11 -0800593func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
594 fullInstallPath := installPath.Join(a, name)
595
Colin Cross12fc4972016-01-11 12:49:11 -0800596 if a.Host() || !a.AConfig().SkipDeviceInstall() {
597 a.ModuleBuild(pctx, ModuleBuildParams{
598 Rule: Symlink,
599 Output: fullInstallPath,
600 OrderOnly: Paths{srcPath},
601 Default: !a.AConfig().EmbeddedInMake(),
602 Args: map[string]string{
603 "fromPath": srcPath.String(),
604 },
605 })
Colin Cross3854a602016-01-11 12:49:11 -0800606
Colin Cross12fc4972016-01-11 12:49:11 -0800607 a.installFiles = append(a.installFiles, fullInstallPath)
608 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
609 }
Colin Cross3854a602016-01-11 12:49:11 -0800610 return fullInstallPath
611}
612
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700613func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800614 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
615}
616
Colin Cross3f40fa42015-01-30 17:27:36 -0800617type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700618 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800619}
620
621func isFileInstaller(m blueprint.Module) bool {
622 _, ok := m.(fileInstaller)
623 return ok
624}
625
626func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700627 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800628 return ok
629}
Colin Crossfce53272015-04-08 11:21:40 -0700630
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700631func findStringInSlice(str string, slice []string) int {
632 for i, s := range slice {
633 if s == str {
634 return i
Colin Crossfce53272015-04-08 11:21:40 -0700635 }
636 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700637 return -1
638}
639
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700640func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
641 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700642 for i, e := range excludes {
643 j := findStringInSlice(e, srcFiles)
644 if j != -1 {
645 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
646 }
647
648 excludes[i] = filepath.Join(prefix, e)
649 }
650
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700651 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700652 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700653 if glob.IsGlob(s) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700654 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700655 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700656 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700657 }
658 }
659
660 return globbedSrcFiles
661}
662
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700663func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
664 ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700665 if err != nil {
666 ctx.ModuleErrorf("glob: %s", err.Error())
667 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700668 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700669}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700670
Colin Cross463a90e2015-06-17 14:20:06 -0700671func init() {
672 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
673}
674
Colin Cross1f8c52b2015-06-16 16:38:17 -0700675func BuildTargetSingleton() blueprint.Singleton {
676 return &buildTargetSingleton{}
677}
678
679type buildTargetSingleton struct{}
680
681func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
682 checkbuildDeps := []string{}
683
684 dirModules := make(map[string][]string)
685
686 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700687 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700688 blueprintDir := a.base().blueprintDir
689 installTarget := a.base().installTarget
690 checkbuildTarget := a.base().checkbuildTarget
691
692 if checkbuildTarget != "" {
693 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
694 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
695 }
696
697 if installTarget != "" {
698 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
699 }
700 }
701 })
702
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800703 suffix := ""
704 if ctx.Config().(Config).EmbeddedInMake() {
705 suffix = "-soong"
706 }
707
Colin Cross1f8c52b2015-06-16 16:38:17 -0700708 // Create a top-level checkbuild target that depends on all modules
709 ctx.Build(pctx, blueprint.BuildParams{
710 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800711 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700712 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700713 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700714 })
715
716 // Create a mm/<directory> target that depends on all modules in a directory
717 dirs := sortedKeys(dirModules)
718 for _, dir := range dirs {
719 ctx.Build(pctx, blueprint.BuildParams{
720 Rule: blueprint.Phony,
721 Outputs: []string{filepath.Join("mm", dir)},
722 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800723 // HACK: checkbuild should be an optional build, but force it
724 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800725 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700726 })
727 }
728}
Colin Crossd779da42015-12-17 18:00:23 -0800729
730type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700731 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800732 ctx interface {
733 ModuleName(blueprint.Module) string
734 ModuleSubDir(blueprint.Module) string
735 }
736}
737
738func (s AndroidModulesByName) Len() int { return len(s.slice) }
739func (s AndroidModulesByName) Less(i, j int) bool {
740 mi, mj := s.slice[i], s.slice[j]
741 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
742
743 if ni != nj {
744 return ni < nj
745 } else {
746 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
747 }
748}
749func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }