blob: 0e608d77e23b9c27edd4ad8abf41171e702d47dd [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
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 {
Colin Crossa1ad8d12016-06-01 17:09:44 -070051 Target() Target
Colin Crossf6566ed2015-03-24 11:13:38 -070052 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070053 Os() OsType
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
Colin Cross635c3b02016-05-18 15:37:25 -070063type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070064 blueprint.BaseModuleContext
65 androidBaseContext
66}
67
Colin Cross635c3b02016-05-18 15:37:25 -070068type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080069 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
Colin Crossa2344662016-03-24 13:14:12 -070079 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
80 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070081 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080082
83 AddMissingDependencies(deps []string)
Colin Cross3f40fa42015-01-30 17:27:36 -080084}
85
Colin Cross635c3b02016-05-18 15:37:25 -070086type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080087 blueprint.Module
88
Colin Cross635c3b02016-05-18 15:37:25 -070089 GenerateAndroidBuildActions(ModuleContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080090
Colin Cross635c3b02016-05-18 15:37:25 -070091 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -080092 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -070093 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -080094 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080095}
96
Colin Cross3f40fa42015-01-30 17:27:36 -080097type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -070098 Name string
99 Deps []string
100 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800101
Dan Willemsen0effe062015-11-30 16:06:01 -0800102 // emit build rules for this module
103 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800104
Colin Cross7d5136f2015-05-11 13:39:40 -0700105 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800106 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
107 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
108 // platform
109 Compile_multilib string
110
Dan Willemsen782a2d12015-12-21 14:55:28 -0800111 // whether this is a proprietary vendor module, and should be installed into /vendor
112 Proprietary bool
113
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700114 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
115 // file
116 Logtags []string
117
Colin Crossa1ad8d12016-06-01 17:09:44 -0700118 // Set by TargetMutator
119 CompileTarget Target `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800120
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 Crossa1ad8d12016-06-01 17:09:44 -0700139type HostOrDeviceSupported int
140
141const (
142 _ HostOrDeviceSupported = iota
143 HostSupported
144 DeviceSupported
145 HostAndDeviceSupported
146 HostAndDeviceDefault
147)
148
Colin Cross635c3b02016-05-18 15:37:25 -0700149func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800150 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
151
152 base := m.base()
153 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700154
Colin Cross7f64b6d2015-07-09 13:57:48 -0700155 propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700156
157 return m, propertyStructs
158}
159
Colin Cross635c3b02016-05-18 15:37:25 -0700160func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700161 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
162
163 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
164
165 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800166 base.commonProperties.HostOrDeviceSupported = hod
Colin Crosscfad1192015-11-02 16:43:11 -0800167 base.commonProperties.Compile_multilib = string(defaultMultilib)
Colin Cross3f40fa42015-01-30 17:27:36 -0800168
Dan Willemsen218f6562015-07-08 18:13:11 -0700169 switch hod {
170 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800171 // Default to module to device supported, host not supported, can override in module
172 // properties
173 base.hostAndDeviceProperties.Device_supported = true
Dan Willemsen218f6562015-07-08 18:13:11 -0700174 fallthrough
175 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800176 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
177 }
178
Colin Crosscfad1192015-11-02 16:43:11 -0800179 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800180}
181
182// A AndroidModuleBase object contains the properties that are common to all Android
183// modules. It should be included as an anonymous field in every module
184// struct definition. InitAndroidModule should then be called from the module's
185// factory function, and the return values from InitAndroidModule should be
186// returned from the factory function.
187//
188// The AndroidModuleBase type is responsible for implementing the
189// GenerateBuildActions method to support the blueprint.Module interface. This
190// method will then call the module's GenerateAndroidBuildActions method once
191// for each build variant that is to be built. GenerateAndroidBuildActions is
192// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
193// AndroidModuleContext exposes extra functionality specific to the Android build
194// system including details about the particular build variant that is to be
195// generated.
196//
197// For example:
198//
199// import (
200// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700201// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800202// )
203//
204// type myModule struct {
205// common.AndroidModuleBase
206// properties struct {
207// MyProperty string
208// }
209// }
210//
211// func NewMyModule() (blueprint.Module, []interface{}) {
212// m := &myModule{}
213// return common.InitAndroidModule(m, &m.properties)
214// }
215//
216// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
217// // Get the CPU architecture for the current build variant.
218// variantArch := ctx.Arch()
219//
220// // ...
221// }
Colin Cross635c3b02016-05-18 15:37:25 -0700222type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800223 // Putting the curiously recurring thing pointing to the thing that contains
224 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700225 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800226
227 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700228 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800229 hostAndDeviceProperties hostAndDeviceProperties
230 generalProperties []interface{}
231 archProperties []*archProperties
232
233 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700234 installFiles Paths
235 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700236
237 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
238 // Only set on the final variant of each module
239 installTarget string
240 checkbuildTarget string
241 blueprintDir string
Colin Cross3f40fa42015-01-30 17:27:36 -0800242}
243
Colin Cross635c3b02016-05-18 15:37:25 -0700244func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800245 return a
246}
247
Colin Crossa1ad8d12016-06-01 17:09:44 -0700248func (a *ModuleBase) SetTarget(target Target) {
249 a.commonProperties.CompileTarget = target
Colin Crossd3ba0392015-05-07 14:11:29 -0700250}
251
Colin Crossa1ad8d12016-06-01 17:09:44 -0700252func (a *ModuleBase) Target() Target {
253 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800254}
255
Colin Crossa1ad8d12016-06-01 17:09:44 -0700256func (a *ModuleBase) Os() OsType {
257 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800258}
259
Colin Cross635c3b02016-05-18 15:37:25 -0700260func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700261 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800262}
263
Colin Cross635c3b02016-05-18 15:37:25 -0700264func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700265 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800266}
267
Colin Crossa1ad8d12016-06-01 17:09:44 -0700268func (a *ModuleBase) OsClassSupported() []OsClass {
269 switch a.commonProperties.HostOrDeviceSupported {
270 case HostSupported:
271 // TODO(ccross): explicitly mark host cross support
272 return []OsClass{Host, HostCross}
273 case DeviceSupported:
274 return []OsClass{Device}
275 case HostAndDeviceSupported:
276 var supported []OsClass
277 if a.hostAndDeviceProperties.Host_supported {
278 supported = append(supported, Host, HostCross)
279 }
280 if a.hostAndDeviceProperties.Device_supported {
281 supported = append(supported, Device)
282 }
283 return supported
284 default:
285 return nil
286 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800287}
288
Colin Cross635c3b02016-05-18 15:37:25 -0700289func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800290 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
291 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
292 a.hostAndDeviceProperties.Device_supported
293}
294
Colin Cross635c3b02016-05-18 15:37:25 -0700295func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800296 if a.commonProperties.Enabled == nil {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700297 return a.Os().Class != HostCross
Dan Willemsen490fd492015-11-24 17:53:15 -0800298 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800299 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800300}
301
Colin Cross635c3b02016-05-18 15:37:25 -0700302func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700303 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800304
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700305 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800306 ctx.VisitDepsDepthFirstIf(isFileInstaller,
307 func(m blueprint.Module) {
308 fileInstaller := m.(fileInstaller)
309 files := fileInstaller.filesToInstall()
310 result = append(result, files...)
311 })
312
313 return result
314}
315
Colin Cross635c3b02016-05-18 15:37:25 -0700316func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800317 return a.installFiles
318}
319
Colin Cross635c3b02016-05-18 15:37:25 -0700320func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800321 return p.noAddressSanitizer
322}
323
Colin Cross635c3b02016-05-18 15:37:25 -0700324func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800325 return false
326}
327
Colin Cross635c3b02016-05-18 15:37:25 -0700328func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
329 if a != ctx.FinalModule().(Module).base() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800330 return
331 }
332
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700333 allInstalledFiles := Paths{}
334 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800335 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700336 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700337 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
338 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800339 })
340
Colin Cross9454bfa2015-03-17 13:24:18 -0700341 deps := []string{}
342
Colin Cross3f40fa42015-01-30 17:27:36 -0800343 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700344 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800345 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700346 Rule: blueprint.Phony,
347 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700348 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800349 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700350 })
351 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700352 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700353 }
354
355 if len(allCheckbuildFiles) > 0 {
356 name := ctx.ModuleName() + "-checkbuild"
357 ctx.Build(pctx, blueprint.BuildParams{
358 Rule: blueprint.Phony,
359 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700360 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700361 Optional: true,
362 })
363 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700364 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700365 }
366
367 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800368 suffix := ""
369 if ctx.Config().(Config).EmbeddedInMake() {
370 suffix = "-soong"
371 }
372
Colin Cross9454bfa2015-03-17 13:24:18 -0700373 ctx.Build(pctx, blueprint.BuildParams{
374 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800375 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700376 Implicits: deps,
377 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800378 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700379
380 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800381 }
382}
383
Colin Cross635c3b02016-05-18 15:37:25 -0700384func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700385 return androidBaseContextImpl{
Colin Crossa1ad8d12016-06-01 17:09:44 -0700386 target: a.commonProperties.CompileTarget,
Dan Willemsen782a2d12015-12-21 14:55:28 -0800387 proprietary: a.commonProperties.Proprietary,
388 config: ctx.Config().(Config),
389 installInData: a.module.InstallInData(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800390 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800391}
392
Colin Cross635c3b02016-05-18 15:37:25 -0700393func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800394 androidCtx := &androidModuleContext{
Colin Cross6362e272015-10-29 15:25:03 -0700395 ModuleContext: ctx,
396 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
397 installDeps: a.computeInstallDeps(ctx),
398 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800399 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800400 }
401
Dan Willemsen0effe062015-11-30 16:06:01 -0800402 if !a.Enabled() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800403 return
404 }
405
406 a.module.GenerateAndroidBuildActions(androidCtx)
407 if ctx.Failed() {
408 return
409 }
410
Colin Crossc9404352015-03-26 16:10:12 -0700411 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
412 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
413
Colin Cross3f40fa42015-01-30 17:27:36 -0800414 a.generateModuleTarget(ctx)
415 if ctx.Failed() {
416 return
417 }
418}
419
Colin Crossf6566ed2015-03-24 11:13:38 -0700420type androidBaseContextImpl struct {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700421 target Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800422 debug bool
423 config Config
424 proprietary bool
425 installInData bool
Colin Crossf6566ed2015-03-24 11:13:38 -0700426}
427
Colin Cross3f40fa42015-01-30 17:27:36 -0800428type androidModuleContext struct {
429 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700430 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700431 installDeps Paths
432 installFiles Paths
433 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800434 missingDeps []string
435}
436
437func (a *androidModuleContext) ninjaError(outputs []string, err error) {
438 a.ModuleContext.Build(pctx, blueprint.BuildParams{
439 Rule: ErrorRule,
440 Outputs: outputs,
441 Optional: true,
442 Args: map[string]string{
443 "error": err.Error(),
444 },
445 })
446 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800447}
448
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800449func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Crosse2c48742016-04-27 13:47:35 -0700450 if a.missingDeps != nil && params.Rule != globRule {
Colin Cross6ff51382015-12-17 16:39:19 -0800451 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
452 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
453 return
454 }
455
Colin Cross3f40fa42015-01-30 17:27:36 -0800456 params.Optional = true
457 a.ModuleContext.Build(pctx, params)
458}
459
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700460func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
461 bparams := blueprint.BuildParams{
462 Rule: params.Rule,
463 Outputs: params.Outputs.Strings(),
464 Inputs: params.Inputs.Strings(),
465 Implicits: params.Implicits.Strings(),
466 OrderOnly: params.OrderOnly.Strings(),
467 Args: params.Args,
468 Optional: !params.Default,
469 }
470
471 if params.Output != nil {
472 bparams.Outputs = append(bparams.Outputs, params.Output.String())
473 }
474 if params.Input != nil {
475 bparams.Inputs = append(bparams.Inputs, params.Input.String())
476 }
477 if params.Implicit != nil {
478 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
479 }
480
Colin Cross6ff51382015-12-17 16:39:19 -0800481 if a.missingDeps != nil {
482 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
483 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
484 return
485 }
486
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700487 a.ModuleContext.Build(pctx, bparams)
488}
489
Colin Cross6ff51382015-12-17 16:39:19 -0800490func (a *androidModuleContext) GetMissingDependencies() []string {
491 return a.missingDeps
492}
493
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800494func (a *androidModuleContext) AddMissingDependencies(deps []string) {
495 if deps != nil {
496 a.missingDeps = append(a.missingDeps, deps...)
497 }
498}
499
Colin Crossa1ad8d12016-06-01 17:09:44 -0700500func (a *androidBaseContextImpl) Target() Target {
501 return a.target
502}
503
Colin Crossf6566ed2015-03-24 11:13:38 -0700504func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700505 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800506}
507
Colin Crossa1ad8d12016-06-01 17:09:44 -0700508func (a *androidBaseContextImpl) Os() OsType {
509 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800510}
511
Colin Crossf6566ed2015-03-24 11:13:38 -0700512func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700513 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700514}
515
516func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700517 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700518}
519
Colin Cross0af4b842015-04-30 16:36:18 -0700520func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700521 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700522}
523
Colin Crossf6566ed2015-03-24 11:13:38 -0700524func (a *androidBaseContextImpl) Debug() bool {
525 return a.debug
526}
527
Colin Cross1332b002015-04-07 17:11:30 -0700528func (a *androidBaseContextImpl) AConfig() Config {
529 return a.config
530}
531
Dan Willemsen782a2d12015-12-21 14:55:28 -0800532func (a *androidBaseContextImpl) Proprietary() bool {
533 return a.proprietary
534}
535
536func (a *androidBaseContextImpl) InstallInData() bool {
537 return a.installInData
538}
539
540func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700541 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700542
Dan Willemsen782a2d12015-12-21 14:55:28 -0800543 fullInstallPath := installPath.Join(a, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800544
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800545 if a.Host() || !a.AConfig().SkipDeviceInstall() {
Dan Willemsen322acaf2016-01-12 23:07:05 -0800546 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700547
Dan Willemsen322acaf2016-01-12 23:07:05 -0800548 a.ModuleBuild(pctx, ModuleBuildParams{
549 Rule: Cp,
550 Output: fullInstallPath,
551 Input: srcPath,
552 OrderOnly: Paths(deps),
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800553 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800554 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800555
Dan Willemsen322acaf2016-01-12 23:07:05 -0800556 a.installFiles = append(a.installFiles, fullInstallPath)
557 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700558 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700559 return fullInstallPath
560}
561
Colin Crossa2344662016-03-24 13:14:12 -0700562func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700563 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800564}
565
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700566func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800567 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
568}
569
Colin Cross3f40fa42015-01-30 17:27:36 -0800570type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700571 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800572}
573
574func isFileInstaller(m blueprint.Module) bool {
575 _, ok := m.(fileInstaller)
576 return ok
577}
578
579func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700580 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800581 return ok
582}
Colin Crossfce53272015-04-08 11:21:40 -0700583
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700584func findStringInSlice(str string, slice []string) int {
585 for i, s := range slice {
586 if s == str {
587 return i
Colin Crossfce53272015-04-08 11:21:40 -0700588 }
589 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700590 return -1
591}
592
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700593func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
594 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700595 for i, e := range excludes {
596 j := findStringInSlice(e, srcFiles)
597 if j != -1 {
598 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
599 }
600
601 excludes[i] = filepath.Join(prefix, e)
602 }
603
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700604 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700605 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700606 if glob.IsGlob(s) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700607 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700608 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700609 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700610 }
611 }
612
613 return globbedSrcFiles
614}
615
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700616func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
617 ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700618 if err != nil {
619 ctx.ModuleErrorf("glob: %s", err.Error())
620 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700621 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700622}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700623
Colin Cross463a90e2015-06-17 14:20:06 -0700624func init() {
625 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
626}
627
Colin Cross1f8c52b2015-06-16 16:38:17 -0700628func BuildTargetSingleton() blueprint.Singleton {
629 return &buildTargetSingleton{}
630}
631
632type buildTargetSingleton struct{}
633
634func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
635 checkbuildDeps := []string{}
636
637 dirModules := make(map[string][]string)
638
639 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700640 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700641 blueprintDir := a.base().blueprintDir
642 installTarget := a.base().installTarget
643 checkbuildTarget := a.base().checkbuildTarget
644
645 if checkbuildTarget != "" {
646 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
647 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
648 }
649
650 if installTarget != "" {
651 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
652 }
653 }
654 })
655
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800656 suffix := ""
657 if ctx.Config().(Config).EmbeddedInMake() {
658 suffix = "-soong"
659 }
660
Colin Cross1f8c52b2015-06-16 16:38:17 -0700661 // Create a top-level checkbuild target that depends on all modules
662 ctx.Build(pctx, blueprint.BuildParams{
663 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800664 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700665 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700666 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700667 })
668
669 // Create a mm/<directory> target that depends on all modules in a directory
670 dirs := sortedKeys(dirModules)
671 for _, dir := range dirs {
672 ctx.Build(pctx, blueprint.BuildParams{
673 Rule: blueprint.Phony,
674 Outputs: []string{filepath.Join("mm", dir)},
675 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800676 // HACK: checkbuild should be an optional build, but force it
677 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800678 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700679 })
680 }
681}
Colin Crossd779da42015-12-17 18:00:23 -0800682
683type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700684 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800685 ctx interface {
686 ModuleName(blueprint.Module) string
687 ModuleSubDir(blueprint.Module) string
688 }
689}
690
691func (s AndroidModulesByName) Len() int { return len(s.slice) }
692func (s AndroidModulesByName) Less(i, j int) bool {
693 mi, mj := s.slice[i], s.slice[j]
694 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
695
696 if ni != nj {
697 return ni < nj
698 } else {
699 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
700 }
701}
702func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }