blob: 03c06b42f03b1701485abdc228c3b2cadf0d7226 [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
Colin Cross9272ade2016-08-17 15:24:12 -070059 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070060}
61
Colin Cross635c3b02016-05-18 15:37:25 -070062type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070063 blueprint.BaseModuleContext
64 androidBaseContext
65}
66
Colin Cross635c3b02016-05-18 15:37:25 -070067type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080068 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070069 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080070
Dan Willemsen34cc69e2015-09-23 15:26:20 -070071 // Similar to Build, but takes Paths instead of []string,
72 // and performs more verification.
73 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070074
Dan Willemsen34cc69e2015-09-23 15:26:20 -070075 ExpandSources(srcFiles, excludes []string) Paths
76 Glob(outDir, globPattern string, excludes []string) Paths
77
Colin Crossa2344662016-03-24 13:14:12 -070078 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
79 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080080 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) 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 Cross8d8f8e22016-08-03 11:57:50 -070084
85 Proprietary() bool
86 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080087}
88
Colin Cross635c3b02016-05-18 15:37:25 -070089type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080090 blueprint.Module
91
Colin Cross635c3b02016-05-18 15:37:25 -070092 GenerateAndroidBuildActions(ModuleContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080093
Colin Cross635c3b02016-05-18 15:37:25 -070094 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -080095 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -070096 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -080097 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080098}
99
Colin Cross3f40fa42015-01-30 17:27:36 -0800100type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700101 Name string
102 Deps []string
103 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800104
Dan Willemsen0effe062015-11-30 16:06:01 -0800105 // emit build rules for this module
106 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800107
Colin Cross7d5136f2015-05-11 13:39:40 -0700108 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800109 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
110 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
111 // platform
112 Compile_multilib string
113
Dan Willemsen782a2d12015-12-21 14:55:28 -0800114 // whether this is a proprietary vendor module, and should be installed into /vendor
115 Proprietary bool
116
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700117 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
118 // file
119 Logtags []string
120
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700121 // init.rc files to be installed if this module is installed
122 Init_rc []string
123
Chris Wolfe998306e2016-08-15 14:47:23 -0400124 // names of other modules to install if this module is installed
125 Required []string
126
Colin Crossa1ad8d12016-06-01 17:09:44 -0700127 // Set by TargetMutator
128 CompileTarget Target `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800129
130 // Set by InitAndroidModule
131 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
132}
133
134type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700135 Host_supported *bool
136 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800137}
138
Colin Crossc472d572015-03-17 15:06:21 -0700139type Multilib string
140
141const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700142 MultilibBoth Multilib = "both"
143 MultilibFirst Multilib = "first"
144 MultilibCommon Multilib = "common"
145 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700146)
147
Colin Crossa1ad8d12016-06-01 17:09:44 -0700148type HostOrDeviceSupported int
149
150const (
151 _ HostOrDeviceSupported = iota
152 HostSupported
153 DeviceSupported
154 HostAndDeviceSupported
155 HostAndDeviceDefault
156)
157
Colin Cross635c3b02016-05-18 15:37:25 -0700158func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800159 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
160
161 base := m.base()
162 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700163
Colin Cross7f64b6d2015-07-09 13:57:48 -0700164 propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700165
166 return m, propertyStructs
167}
168
Colin Cross635c3b02016-05-18 15:37:25 -0700169func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700170 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
171
172 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
173
174 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800175 base.commonProperties.HostOrDeviceSupported = hod
Colin Crosscfad1192015-11-02 16:43:11 -0800176 base.commonProperties.Compile_multilib = string(defaultMultilib)
Colin Cross3f40fa42015-01-30 17:27:36 -0800177
Dan Willemsen218f6562015-07-08 18:13:11 -0700178 switch hod {
179 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800180 // Default to module to device supported, host not supported, can override in module
181 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700182 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700183 fallthrough
184 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800185 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
186 }
187
Colin Crosscfad1192015-11-02 16:43:11 -0800188 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800189}
190
191// A AndroidModuleBase object contains the properties that are common to all Android
192// modules. It should be included as an anonymous field in every module
193// struct definition. InitAndroidModule should then be called from the module's
194// factory function, and the return values from InitAndroidModule should be
195// returned from the factory function.
196//
197// The AndroidModuleBase type is responsible for implementing the
198// GenerateBuildActions method to support the blueprint.Module interface. This
199// method will then call the module's GenerateAndroidBuildActions method once
200// for each build variant that is to be built. GenerateAndroidBuildActions is
201// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
202// AndroidModuleContext exposes extra functionality specific to the Android build
203// system including details about the particular build variant that is to be
204// generated.
205//
206// For example:
207//
208// import (
209// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700210// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800211// )
212//
213// type myModule struct {
214// common.AndroidModuleBase
215// properties struct {
216// MyProperty string
217// }
218// }
219//
220// func NewMyModule() (blueprint.Module, []interface{}) {
221// m := &myModule{}
222// return common.InitAndroidModule(m, &m.properties)
223// }
224//
225// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
226// // Get the CPU architecture for the current build variant.
227// variantArch := ctx.Arch()
228//
229// // ...
230// }
Colin Cross635c3b02016-05-18 15:37:25 -0700231type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800232 // Putting the curiously recurring thing pointing to the thing that contains
233 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700234 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800235
236 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700237 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800238 hostAndDeviceProperties hostAndDeviceProperties
239 generalProperties []interface{}
240 archProperties []*archProperties
241
242 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700243 installFiles Paths
244 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700245
246 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
247 // Only set on the final variant of each module
248 installTarget string
249 checkbuildTarget string
250 blueprintDir string
Colin Cross3f40fa42015-01-30 17:27:36 -0800251}
252
Colin Cross635c3b02016-05-18 15:37:25 -0700253func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800254 return a
255}
256
Colin Crossa1ad8d12016-06-01 17:09:44 -0700257func (a *ModuleBase) SetTarget(target Target) {
258 a.commonProperties.CompileTarget = target
Colin Crossd3ba0392015-05-07 14:11:29 -0700259}
260
Colin Crossa1ad8d12016-06-01 17:09:44 -0700261func (a *ModuleBase) Target() Target {
262 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800263}
264
Colin Crossa1ad8d12016-06-01 17:09:44 -0700265func (a *ModuleBase) Os() OsType {
266 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800267}
268
Colin Cross635c3b02016-05-18 15:37:25 -0700269func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700270 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800271}
272
Colin Cross635c3b02016-05-18 15:37:25 -0700273func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700274 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800275}
276
Colin Crossa1ad8d12016-06-01 17:09:44 -0700277func (a *ModuleBase) OsClassSupported() []OsClass {
278 switch a.commonProperties.HostOrDeviceSupported {
279 case HostSupported:
280 // TODO(ccross): explicitly mark host cross support
281 return []OsClass{Host, HostCross}
282 case DeviceSupported:
283 return []OsClass{Device}
284 case HostAndDeviceSupported:
285 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700286 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700287 supported = append(supported, Host, HostCross)
288 }
Colin Crossa4190c12016-07-12 13:11:25 -0700289 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700290 supported = append(supported, Device)
291 }
292 return supported
293 default:
294 return nil
295 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800296}
297
Colin Cross635c3b02016-05-18 15:37:25 -0700298func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800299 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
300 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700301 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800302}
303
Colin Cross635c3b02016-05-18 15:37:25 -0700304func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800305 if a.commonProperties.Enabled == nil {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700306 return a.Os().Class != HostCross
Dan Willemsen490fd492015-11-24 17:53:15 -0800307 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800308 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800309}
310
Colin Cross635c3b02016-05-18 15:37:25 -0700311func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700312 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800313
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700314 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800315 ctx.VisitDepsDepthFirstIf(isFileInstaller,
316 func(m blueprint.Module) {
317 fileInstaller := m.(fileInstaller)
318 files := fileInstaller.filesToInstall()
319 result = append(result, files...)
320 })
321
322 return result
323}
324
Colin Cross635c3b02016-05-18 15:37:25 -0700325func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800326 return a.installFiles
327}
328
Colin Cross635c3b02016-05-18 15:37:25 -0700329func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800330 return p.noAddressSanitizer
331}
332
Colin Cross635c3b02016-05-18 15:37:25 -0700333func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800334 return false
335}
336
Colin Cross635c3b02016-05-18 15:37:25 -0700337func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
338 if a != ctx.FinalModule().(Module).base() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800339 return
340 }
341
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700342 allInstalledFiles := Paths{}
343 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800344 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700345 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700346 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
347 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800348 })
349
Colin Cross9454bfa2015-03-17 13:24:18 -0700350 deps := []string{}
351
Colin Cross3f40fa42015-01-30 17:27:36 -0800352 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700353 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800354 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700355 Rule: blueprint.Phony,
356 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700357 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800358 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700359 })
360 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700361 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700362 }
363
364 if len(allCheckbuildFiles) > 0 {
365 name := ctx.ModuleName() + "-checkbuild"
366 ctx.Build(pctx, blueprint.BuildParams{
367 Rule: blueprint.Phony,
368 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700369 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700370 Optional: true,
371 })
372 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700373 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700374 }
375
376 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800377 suffix := ""
378 if ctx.Config().(Config).EmbeddedInMake() {
379 suffix = "-soong"
380 }
381
Colin Cross9454bfa2015-03-17 13:24:18 -0700382 ctx.Build(pctx, blueprint.BuildParams{
383 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800384 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700385 Implicits: deps,
386 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800387 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700388
389 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800390 }
391}
392
Colin Cross635c3b02016-05-18 15:37:25 -0700393func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700394 return androidBaseContextImpl{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700395 target: a.commonProperties.CompileTarget,
396 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800397 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800398}
399
Colin Cross635c3b02016-05-18 15:37:25 -0700400func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800401 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700402 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700403 ModuleContext: ctx,
404 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
405 installDeps: a.computeInstallDeps(ctx),
406 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800407 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800408 }
409
Dan Willemsen0effe062015-11-30 16:06:01 -0800410 if !a.Enabled() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800411 return
412 }
413
414 a.module.GenerateAndroidBuildActions(androidCtx)
415 if ctx.Failed() {
416 return
417 }
418
Colin Crossc9404352015-03-26 16:10:12 -0700419 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
420 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
421
Colin Cross3f40fa42015-01-30 17:27:36 -0800422 a.generateModuleTarget(ctx)
423 if ctx.Failed() {
424 return
425 }
426}
427
Colin Crossf6566ed2015-03-24 11:13:38 -0700428type androidBaseContextImpl struct {
Colin Cross8d8f8e22016-08-03 11:57:50 -0700429 target Target
430 debug bool
431 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700432}
433
Colin Cross3f40fa42015-01-30 17:27:36 -0800434type androidModuleContext struct {
435 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700436 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700437 installDeps Paths
438 installFiles Paths
439 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800440 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700441 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800442}
443
444func (a *androidModuleContext) ninjaError(outputs []string, err error) {
445 a.ModuleContext.Build(pctx, blueprint.BuildParams{
446 Rule: ErrorRule,
447 Outputs: outputs,
448 Optional: true,
449 Args: map[string]string{
450 "error": err.Error(),
451 },
452 })
453 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800454}
455
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800456func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Crosse2c48742016-04-27 13:47:35 -0700457 if a.missingDeps != nil && params.Rule != globRule {
Colin Cross6ff51382015-12-17 16:39:19 -0800458 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
459 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
460 return
461 }
462
Colin Cross3f40fa42015-01-30 17:27:36 -0800463 params.Optional = true
464 a.ModuleContext.Build(pctx, params)
465}
466
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700467func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
468 bparams := blueprint.BuildParams{
469 Rule: params.Rule,
470 Outputs: params.Outputs.Strings(),
471 Inputs: params.Inputs.Strings(),
472 Implicits: params.Implicits.Strings(),
473 OrderOnly: params.OrderOnly.Strings(),
474 Args: params.Args,
475 Optional: !params.Default,
476 }
477
478 if params.Output != nil {
479 bparams.Outputs = append(bparams.Outputs, params.Output.String())
480 }
481 if params.Input != nil {
482 bparams.Inputs = append(bparams.Inputs, params.Input.String())
483 }
484 if params.Implicit != nil {
485 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
486 }
487
Colin Cross6ff51382015-12-17 16:39:19 -0800488 if a.missingDeps != nil {
489 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
490 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
491 return
492 }
493
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700494 a.ModuleContext.Build(pctx, bparams)
495}
496
Colin Cross6ff51382015-12-17 16:39:19 -0800497func (a *androidModuleContext) GetMissingDependencies() []string {
498 return a.missingDeps
499}
500
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800501func (a *androidModuleContext) AddMissingDependencies(deps []string) {
502 if deps != nil {
503 a.missingDeps = append(a.missingDeps, deps...)
504 }
505}
506
Colin Crossa1ad8d12016-06-01 17:09:44 -0700507func (a *androidBaseContextImpl) Target() Target {
508 return a.target
509}
510
Colin Crossf6566ed2015-03-24 11:13:38 -0700511func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700512 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800513}
514
Colin Crossa1ad8d12016-06-01 17:09:44 -0700515func (a *androidBaseContextImpl) Os() OsType {
516 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800517}
518
Colin Crossf6566ed2015-03-24 11:13:38 -0700519func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700520 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700521}
522
523func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700524 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700525}
526
Colin Cross0af4b842015-04-30 16:36:18 -0700527func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700528 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700529}
530
Colin Crossf6566ed2015-03-24 11:13:38 -0700531func (a *androidBaseContextImpl) Debug() bool {
532 return a.debug
533}
534
Colin Cross1332b002015-04-07 17:11:30 -0700535func (a *androidBaseContextImpl) AConfig() Config {
536 return a.config
537}
538
Colin Cross9272ade2016-08-17 15:24:12 -0700539func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
540 return DeviceConfig{a.config.deviceConfig}
541}
542
Colin Cross8d8f8e22016-08-03 11:57:50 -0700543func (a *androidModuleContext) Proprietary() bool {
544 return a.module.base().commonProperties.Proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800545}
546
Colin Cross8d8f8e22016-08-03 11:57:50 -0700547func (a *androidModuleContext) InstallInData() bool {
548 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800549}
550
551func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700552 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700553
Dan Willemsen782a2d12015-12-21 14:55:28 -0800554 fullInstallPath := installPath.Join(a, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800555
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800556 if a.Host() || !a.AConfig().SkipDeviceInstall() {
Dan Willemsen322acaf2016-01-12 23:07:05 -0800557 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700558
Dan Willemsen322acaf2016-01-12 23:07:05 -0800559 a.ModuleBuild(pctx, ModuleBuildParams{
560 Rule: Cp,
561 Output: fullInstallPath,
562 Input: srcPath,
563 OrderOnly: Paths(deps),
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800564 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800565 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800566
Dan Willemsen322acaf2016-01-12 23:07:05 -0800567 a.installFiles = append(a.installFiles, fullInstallPath)
568 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700569 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700570 return fullInstallPath
571}
572
Colin Crossa2344662016-03-24 13:14:12 -0700573func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700574 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800575}
576
Colin Cross3854a602016-01-11 12:49:11 -0800577func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
578 fullInstallPath := installPath.Join(a, name)
579
Colin Cross12fc4972016-01-11 12:49:11 -0800580 if a.Host() || !a.AConfig().SkipDeviceInstall() {
581 a.ModuleBuild(pctx, ModuleBuildParams{
582 Rule: Symlink,
583 Output: fullInstallPath,
584 OrderOnly: Paths{srcPath},
585 Default: !a.AConfig().EmbeddedInMake(),
586 Args: map[string]string{
587 "fromPath": srcPath.String(),
588 },
589 })
Colin Cross3854a602016-01-11 12:49:11 -0800590
Colin Cross12fc4972016-01-11 12:49:11 -0800591 a.installFiles = append(a.installFiles, fullInstallPath)
592 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
593 }
Colin Cross3854a602016-01-11 12:49:11 -0800594 return fullInstallPath
595}
596
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700597func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800598 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
599}
600
Colin Cross3f40fa42015-01-30 17:27:36 -0800601type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700602 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800603}
604
605func isFileInstaller(m blueprint.Module) bool {
606 _, ok := m.(fileInstaller)
607 return ok
608}
609
610func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700611 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800612 return ok
613}
Colin Crossfce53272015-04-08 11:21:40 -0700614
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700615func findStringInSlice(str string, slice []string) int {
616 for i, s := range slice {
617 if s == str {
618 return i
Colin Crossfce53272015-04-08 11:21:40 -0700619 }
620 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700621 return -1
622}
623
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700624func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
625 prefix := PathForModuleSrc(ctx).String()
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700626 for i, e := range excludes {
627 j := findStringInSlice(e, srcFiles)
628 if j != -1 {
629 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
630 }
631
632 excludes[i] = filepath.Join(prefix, e)
633 }
634
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700635 globbedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700636 for _, s := range srcFiles {
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700637 if glob.IsGlob(s) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700638 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
Colin Cross8f101b42015-06-17 15:09:06 -0700639 } else {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700640 globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
Colin Cross8f101b42015-06-17 15:09:06 -0700641 }
642 }
643
644 return globbedSrcFiles
645}
646
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700647func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
648 ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700649 if err != nil {
650 ctx.ModuleErrorf("glob: %s", err.Error())
651 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700652 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700653}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700654
Colin Cross463a90e2015-06-17 14:20:06 -0700655func init() {
656 soong.RegisterSingletonType("buildtarget", BuildTargetSingleton)
657}
658
Colin Cross1f8c52b2015-06-16 16:38:17 -0700659func BuildTargetSingleton() blueprint.Singleton {
660 return &buildTargetSingleton{}
661}
662
663type buildTargetSingleton struct{}
664
665func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
666 checkbuildDeps := []string{}
667
668 dirModules := make(map[string][]string)
669
670 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700671 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700672 blueprintDir := a.base().blueprintDir
673 installTarget := a.base().installTarget
674 checkbuildTarget := a.base().checkbuildTarget
675
676 if checkbuildTarget != "" {
677 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
678 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
679 }
680
681 if installTarget != "" {
682 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
683 }
684 }
685 })
686
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800687 suffix := ""
688 if ctx.Config().(Config).EmbeddedInMake() {
689 suffix = "-soong"
690 }
691
Colin Cross1f8c52b2015-06-16 16:38:17 -0700692 // Create a top-level checkbuild target that depends on all modules
693 ctx.Build(pctx, blueprint.BuildParams{
694 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800695 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700696 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700697 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700698 })
699
700 // Create a mm/<directory> target that depends on all modules in a directory
701 dirs := sortedKeys(dirModules)
702 for _, dir := range dirs {
703 ctx.Build(pctx, blueprint.BuildParams{
704 Rule: blueprint.Phony,
705 Outputs: []string{filepath.Join("mm", dir)},
706 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800707 // HACK: checkbuild should be an optional build, but force it
708 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800709 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700710 })
711 }
712}
Colin Crossd779da42015-12-17 18:00:23 -0800713
714type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700715 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800716 ctx interface {
717 ModuleName(blueprint.Module) string
718 ModuleSubDir(blueprint.Module) string
719 }
720}
721
722func (s AndroidModulesByName) Len() int { return len(s.slice) }
723func (s AndroidModulesByName) Less(i, j int) bool {
724 mi, mj := s.slice[i], s.slice[j]
725 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
726
727 if ni != nj {
728 return ni < nj
729 } else {
730 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
731 }
732}
733func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }