blob: 4fba1cf7af028c75675a2d24d65c4b7db0525383 [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
22 "github.com/google/blueprint"
Colin Cross7f19f372016-11-01 11:10:25 -070023 "github.com/google/blueprint/pathtools"
Colin Cross3f40fa42015-01-30 17:27:36 -080024)
25
26var (
27 DeviceSharedLibrary = "shared_library"
28 DeviceStaticLibrary = "static_library"
29 DeviceExecutable = "executable"
30 HostSharedLibrary = "host_shared_library"
31 HostStaticLibrary = "host_static_library"
32 HostExecutable = "host_executable"
33)
34
Dan Willemsen34cc69e2015-09-23 15:26:20 -070035type ModuleBuildParams struct {
Dan Willemsen9f3c5742016-11-03 14:28:31 -070036 Rule blueprint.Rule
Colin Cross33bfb0a2016-11-21 17:23:08 -080037 Deps blueprint.Deps
38 Depfile WritablePath
Dan Willemsen9f3c5742016-11-03 14:28:31 -070039 Output WritablePath
40 Outputs WritablePaths
41 ImplicitOutput WritablePath
42 ImplicitOutputs WritablePaths
43 Input Path
44 Inputs Paths
45 Implicit Path
46 Implicits Paths
47 OrderOnly Paths
48 Default bool
49 Args map[string]string
Dan Willemsen34cc69e2015-09-23 15:26:20 -070050}
51
Colin Crossf6566ed2015-03-24 11:13:38 -070052type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070053 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -070054 TargetPrimary() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070055 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070056 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070057 Host() bool
58 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070059 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070060 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070061 PrimaryArch() bool
Dan Willemsen11b26142017-03-19 18:30:37 -070062 Proprietary() bool
Colin Cross1332b002015-04-07 17:11:30 -070063 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070064 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070065}
66
Colin Cross635c3b02016-05-18 15:37:25 -070067type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070068 blueprint.BaseModuleContext
69 androidBaseContext
70}
71
Colin Cross635c3b02016-05-18 15:37:25 -070072type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080073 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070074 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080075
Dan Willemsen34cc69e2015-09-23 15:26:20 -070076 // Similar to Build, but takes Paths instead of []string,
77 // and performs more verification.
78 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070079
Dan Willemsen34cc69e2015-09-23 15:26:20 -070080 ExpandSources(srcFiles, excludes []string) Paths
Colin Crossfaeb7aa2017-02-01 14:12:44 -080081 ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
Colin Cross7f19f372016-11-01 11:10:25 -070082 Glob(globPattern string, excludes []string) Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -070083
Colin Crossa2344662016-03-24 13:14:12 -070084 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
85 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080086 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070087 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080088
89 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -070090
Colin Cross8d8f8e22016-08-03 11:57:50 -070091 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -070092 InstallInSanitizerDir() bool
Nan Zhang6d34b302017-02-04 17:47:46 -080093
94 RequiredModuleNames() []string
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 Cross1e676be2016-10-12 14:38:15 -0700101 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800102
Colin Cross635c3b02016-05-18 15:37:25 -0700103 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800104 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700105 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800106 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700107 InstallInSanitizerDir() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800108 SkipInstall()
Colin Cross3f40fa42015-01-30 17:27:36 -0800109}
110
Colin Crossfc754582016-05-17 16:34:16 -0700111type nameProperties struct {
112 // The name of the module. Must be unique across all modules.
Colin Crossc77f9d12015-04-02 13:54:39 -0700113 Name string
Colin Crossfc754582016-05-17 16:34:16 -0700114}
115
116type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700117 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800118
Dan Willemsen0effe062015-11-30 16:06:01 -0800119 // emit build rules for this module
120 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800121
Colin Cross7d5136f2015-05-11 13:39:40 -0700122 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800123 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
124 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
125 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700126 Compile_multilib string `android:"arch_variant"`
127
128 Target struct {
129 Host struct {
130 Compile_multilib string
131 }
132 Android struct {
133 Compile_multilib string
134 }
135 }
136
137 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800138
Dan Willemsen782a2d12015-12-21 14:55:28 -0800139 // whether this is a proprietary vendor module, and should be installed into /vendor
140 Proprietary bool
141
Colin Cross55708f32017-03-20 13:23:34 -0700142 // vendor who owns this module
143 Owner string
144
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700145 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
146 // file
147 Logtags []string
148
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700149 // init.rc files to be installed if this module is installed
150 Init_rc []string
151
Chris Wolfe998306e2016-08-15 14:47:23 -0400152 // names of other modules to install if this module is installed
153 Required []string
154
Colin Crossa1ad8d12016-06-01 17:09:44 -0700155 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700156 CompileTarget Target `blueprint:"mutated"`
157 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800158
159 // Set by InitAndroidModule
160 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700161 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700162
163 SkipInstall bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800164}
165
166type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700167 Host_supported *bool
168 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800169}
170
Colin Crossc472d572015-03-17 15:06:21 -0700171type Multilib string
172
173const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700174 MultilibBoth Multilib = "both"
175 MultilibFirst Multilib = "first"
176 MultilibCommon Multilib = "common"
177 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700178)
179
Colin Crossa1ad8d12016-06-01 17:09:44 -0700180type HostOrDeviceSupported int
181
182const (
183 _ HostOrDeviceSupported = iota
184 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700185 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700186 DeviceSupported
187 HostAndDeviceSupported
188 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700189 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700190)
191
Colin Cross635c3b02016-05-18 15:37:25 -0700192func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800193 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
194
195 base := m.base()
196 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700197
Colin Crossfc754582016-05-17 16:34:16 -0700198 propertyStructs = append(propertyStructs,
199 &base.nameProperties,
200 &base.commonProperties,
201 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700202
203 return m, propertyStructs
204}
205
Colin Cross635c3b02016-05-18 15:37:25 -0700206func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700207 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
208
209 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
210
211 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800212 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700213 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700214 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800215
Dan Willemsen218f6562015-07-08 18:13:11 -0700216 switch hod {
217 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800218 // Default to module to device supported, host not supported, can override in module
219 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700220 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700221 fallthrough
222 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800223 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
224 }
225
Colin Crosscfad1192015-11-02 16:43:11 -0800226 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800227}
228
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800229// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800230// modules. It should be included as an anonymous field in every module
231// struct definition. InitAndroidModule should then be called from the module's
232// factory function, and the return values from InitAndroidModule should be
233// returned from the factory function.
234//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800235// The ModuleBase type is responsible for implementing the GenerateBuildActions
236// method to support the blueprint.Module interface. This method will then call
237// the module's GenerateAndroidBuildActions method once for each build variant
238// that is to be built. GenerateAndroidBuildActions is passed a
239// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800240// AndroidModuleContext exposes extra functionality specific to the Android build
241// system including details about the particular build variant that is to be
242// generated.
243//
244// For example:
245//
246// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800247// "android/soong/android"
Colin Cross70b40592015-03-23 12:57:34 -0700248// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800249// )
250//
251// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800252// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800253// properties struct {
254// MyProperty string
255// }
256// }
257//
258// func NewMyModule() (blueprint.Module, []interface{}) {
259// m := &myModule{}
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800260// return android.InitAndroidModule(m, &m.properties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800261// }
262//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800263// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800264// // Get the CPU architecture for the current build variant.
265// variantArch := ctx.Arch()
266//
267// // ...
268// }
Colin Cross635c3b02016-05-18 15:37:25 -0700269type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800270 // Putting the curiously recurring thing pointing to the thing that contains
271 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700272 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800273
Colin Crossfc754582016-05-17 16:34:16 -0700274 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800275 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700276 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800277 hostAndDeviceProperties hostAndDeviceProperties
278 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700279 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700280 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800281
282 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700283 installFiles Paths
284 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700285
286 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
287 // Only set on the final variant of each module
288 installTarget string
289 checkbuildTarget string
290 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700291
Colin Cross178a5092016-09-13 13:42:32 -0700292 hooks hooks
Colin Cross3f40fa42015-01-30 17:27:36 -0800293}
294
Colin Crossce75d2c2016-10-06 16:12:58 -0700295// Name returns the name of the module. It may be overridden by individual module types, for
296// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700297func (a *ModuleBase) Name() string {
298 return a.nameProperties.Name
299}
300
Colin Crossce75d2c2016-10-06 16:12:58 -0700301// BaseModuleName returns the name of the module as specified in the blueprints file.
302func (a *ModuleBase) BaseModuleName() string {
303 return a.nameProperties.Name
304}
305
Colin Cross635c3b02016-05-18 15:37:25 -0700306func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800307 return a
308}
309
Colin Cross8b74d172016-09-13 09:59:14 -0700310func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700311 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700312 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700313}
314
Colin Crossa1ad8d12016-06-01 17:09:44 -0700315func (a *ModuleBase) Target() Target {
316 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800317}
318
Colin Cross8b74d172016-09-13 09:59:14 -0700319func (a *ModuleBase) TargetPrimary() bool {
320 return a.commonProperties.CompilePrimary
321}
322
Colin Crossa1ad8d12016-06-01 17:09:44 -0700323func (a *ModuleBase) Os() OsType {
324 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800325}
326
Colin Cross635c3b02016-05-18 15:37:25 -0700327func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700328 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800329}
330
Colin Cross635c3b02016-05-18 15:37:25 -0700331func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700332 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800333}
334
Dan Willemsen0b24c742016-10-04 15:13:37 -0700335func (a *ModuleBase) ArchSpecific() bool {
336 return a.commonProperties.ArchSpecific
337}
338
Colin Crossa1ad8d12016-06-01 17:09:44 -0700339func (a *ModuleBase) OsClassSupported() []OsClass {
340 switch a.commonProperties.HostOrDeviceSupported {
341 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700342 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700343 case HostSupportedNoCross:
344 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700345 case DeviceSupported:
346 return []OsClass{Device}
347 case HostAndDeviceSupported:
348 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700349 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700350 supported = append(supported, Host, HostCross)
351 }
Colin Crossa4190c12016-07-12 13:11:25 -0700352 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700353 supported = append(supported, Device)
354 }
355 return supported
356 default:
357 return nil
358 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800359}
360
Colin Cross635c3b02016-05-18 15:37:25 -0700361func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800362 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
363 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700364 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800365}
366
Colin Cross635c3b02016-05-18 15:37:25 -0700367func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800368 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800369 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800370 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800371 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800372}
373
Colin Crossce75d2c2016-10-06 16:12:58 -0700374func (a *ModuleBase) SkipInstall() {
375 a.commonProperties.SkipInstall = true
376}
377
Colin Cross635c3b02016-05-18 15:37:25 -0700378func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700379 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800380
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700381 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800382 ctx.VisitDepsDepthFirstIf(isFileInstaller,
383 func(m blueprint.Module) {
384 fileInstaller := m.(fileInstaller)
385 files := fileInstaller.filesToInstall()
386 result = append(result, files...)
387 })
388
389 return result
390}
391
Colin Cross635c3b02016-05-18 15:37:25 -0700392func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800393 return a.installFiles
394}
395
Colin Cross635c3b02016-05-18 15:37:25 -0700396func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800397 return p.noAddressSanitizer
398}
399
Colin Cross635c3b02016-05-18 15:37:25 -0700400func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800401 return false
402}
403
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700404func (p *ModuleBase) InstallInSanitizerDir() bool {
405 return false
406}
407
Colin Cross635c3b02016-05-18 15:37:25 -0700408func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700409 allInstalledFiles := Paths{}
410 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800411 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700412 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700413 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
414 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800415 })
416
Colin Cross9454bfa2015-03-17 13:24:18 -0700417 deps := []string{}
418
Colin Cross3f40fa42015-01-30 17:27:36 -0800419 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700420 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800421 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700422 Rule: blueprint.Phony,
423 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700424 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800425 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700426 })
427 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700428 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700429 }
430
431 if len(allCheckbuildFiles) > 0 {
432 name := ctx.ModuleName() + "-checkbuild"
433 ctx.Build(pctx, blueprint.BuildParams{
434 Rule: blueprint.Phony,
435 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700436 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700437 Optional: true,
438 })
439 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700440 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700441 }
442
443 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800444 suffix := ""
445 if ctx.Config().(Config).EmbeddedInMake() {
446 suffix = "-soong"
447 }
448
Colin Cross9454bfa2015-03-17 13:24:18 -0700449 ctx.Build(pctx, blueprint.BuildParams{
450 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800451 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700452 Implicits: deps,
453 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800454 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700455
456 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800457 }
458}
459
Colin Cross635c3b02016-05-18 15:37:25 -0700460func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700461 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700462 target: a.commonProperties.CompileTarget,
463 targetPrimary: a.commonProperties.CompilePrimary,
Dan Willemsen11b26142017-03-19 18:30:37 -0700464 proprietary: a.commonProperties.Proprietary,
Colin Cross8b74d172016-09-13 09:59:14 -0700465 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800466 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800467}
468
Colin Cross635c3b02016-05-18 15:37:25 -0700469func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800470 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700471 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700472 ModuleContext: ctx,
473 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
474 installDeps: a.computeInstallDeps(ctx),
475 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800476 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800477 }
478
Colin Cross9b1d13d2016-09-19 15:18:11 -0700479 if a.Enabled() {
480 a.module.GenerateAndroidBuildActions(androidCtx)
481 if ctx.Failed() {
482 return
483 }
484
485 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
486 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800487 }
488
Colin Cross9b1d13d2016-09-19 15:18:11 -0700489 if a == ctx.FinalModule().(Module).base() {
490 a.generateModuleTarget(ctx)
491 if ctx.Failed() {
492 return
493 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800494 }
495}
496
Colin Crossf6566ed2015-03-24 11:13:38 -0700497type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700498 target Target
499 targetPrimary bool
500 debug bool
Dan Willemsen11b26142017-03-19 18:30:37 -0700501 proprietary bool
Colin Cross8b74d172016-09-13 09:59:14 -0700502 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700503}
504
Colin Cross3f40fa42015-01-30 17:27:36 -0800505type androidModuleContext struct {
506 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700507 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700508 installDeps Paths
509 installFiles Paths
510 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800511 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700512 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800513}
514
515func (a *androidModuleContext) ninjaError(outputs []string, err error) {
516 a.ModuleContext.Build(pctx, blueprint.BuildParams{
517 Rule: ErrorRule,
518 Outputs: outputs,
519 Optional: true,
520 Args: map[string]string{
521 "error": err.Error(),
522 },
523 })
524 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800525}
526
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800527func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Cross7f19f372016-11-01 11:10:25 -0700528 if a.missingDeps != nil {
Colin Cross6ff51382015-12-17 16:39:19 -0800529 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
530 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
531 return
532 }
533
Colin Cross3f40fa42015-01-30 17:27:36 -0800534 params.Optional = true
535 a.ModuleContext.Build(pctx, params)
536}
537
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700538func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
539 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700540 Rule: params.Rule,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800541 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700542 Outputs: params.Outputs.Strings(),
543 ImplicitOutputs: params.ImplicitOutputs.Strings(),
544 Inputs: params.Inputs.Strings(),
545 Implicits: params.Implicits.Strings(),
546 OrderOnly: params.OrderOnly.Strings(),
547 Args: params.Args,
548 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700549 }
550
Colin Cross33bfb0a2016-11-21 17:23:08 -0800551 if params.Depfile != nil {
552 bparams.Depfile = params.Depfile.String()
553 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700554 if params.Output != nil {
555 bparams.Outputs = append(bparams.Outputs, params.Output.String())
556 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700557 if params.ImplicitOutput != nil {
558 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
559 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700560 if params.Input != nil {
561 bparams.Inputs = append(bparams.Inputs, params.Input.String())
562 }
563 if params.Implicit != nil {
564 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
565 }
566
Colin Cross6ff51382015-12-17 16:39:19 -0800567 if a.missingDeps != nil {
568 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
569 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
570 return
571 }
572
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700573 a.ModuleContext.Build(pctx, bparams)
574}
575
Colin Cross6ff51382015-12-17 16:39:19 -0800576func (a *androidModuleContext) GetMissingDependencies() []string {
577 return a.missingDeps
578}
579
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800580func (a *androidModuleContext) AddMissingDependencies(deps []string) {
581 if deps != nil {
582 a.missingDeps = append(a.missingDeps, deps...)
583 }
584}
585
Colin Crossa1ad8d12016-06-01 17:09:44 -0700586func (a *androidBaseContextImpl) Target() Target {
587 return a.target
588}
589
Colin Cross8b74d172016-09-13 09:59:14 -0700590func (a *androidBaseContextImpl) TargetPrimary() bool {
591 return a.targetPrimary
592}
593
Colin Crossf6566ed2015-03-24 11:13:38 -0700594func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700595 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800596}
597
Colin Crossa1ad8d12016-06-01 17:09:44 -0700598func (a *androidBaseContextImpl) Os() OsType {
599 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800600}
601
Colin Crossf6566ed2015-03-24 11:13:38 -0700602func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700603 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700604}
605
606func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700607 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700608}
609
Colin Cross0af4b842015-04-30 16:36:18 -0700610func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700611 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700612}
613
Colin Crossf6566ed2015-03-24 11:13:38 -0700614func (a *androidBaseContextImpl) Debug() bool {
615 return a.debug
616}
617
Colin Cross1e7d3702016-08-24 15:25:47 -0700618func (a *androidBaseContextImpl) PrimaryArch() bool {
619 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
620}
621
Colin Cross1332b002015-04-07 17:11:30 -0700622func (a *androidBaseContextImpl) AConfig() Config {
623 return a.config
624}
625
Colin Cross9272ade2016-08-17 15:24:12 -0700626func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
627 return DeviceConfig{a.config.deviceConfig}
628}
629
Dan Willemsen11b26142017-03-19 18:30:37 -0700630func (a *androidBaseContextImpl) Proprietary() bool {
631 return a.proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800632}
633
Colin Cross8d8f8e22016-08-03 11:57:50 -0700634func (a *androidModuleContext) InstallInData() bool {
635 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800636}
637
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700638func (a *androidModuleContext) InstallInSanitizerDir() bool {
639 return a.module.InstallInSanitizerDir()
640}
641
Dan Willemsen782a2d12015-12-21 14:55:28 -0800642func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700643 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700644
Dan Willemsen782a2d12015-12-21 14:55:28 -0800645 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700646 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800647
Colin Crossce75d2c2016-10-06 16:12:58 -0700648 if !a.module.base().commonProperties.SkipInstall &&
Dan Willemsen0e2d97b2016-11-28 17:50:06 -0800649 (!a.Device() || !a.AConfig().SkipDeviceInstall()) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700650
Dan Willemsen322acaf2016-01-12 23:07:05 -0800651 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700652
Colin Cross89562dc2016-10-03 17:47:19 -0700653 var implicitDeps, orderOnlyDeps Paths
654
655 if a.Host() {
656 // Installed host modules might be used during the build, depend directly on their
657 // dependencies so their timestamp is updated whenever their dependency is updated
658 implicitDeps = deps
659 } else {
660 orderOnlyDeps = deps
661 }
662
Dan Willemsen322acaf2016-01-12 23:07:05 -0800663 a.ModuleBuild(pctx, ModuleBuildParams{
664 Rule: Cp,
665 Output: fullInstallPath,
666 Input: srcPath,
Colin Cross89562dc2016-10-03 17:47:19 -0700667 Implicits: implicitDeps,
668 OrderOnly: orderOnlyDeps,
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800669 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800670 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800671
Dan Willemsen322acaf2016-01-12 23:07:05 -0800672 a.installFiles = append(a.installFiles, fullInstallPath)
673 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700674 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700675 return fullInstallPath
676}
677
Colin Crossa2344662016-03-24 13:14:12 -0700678func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700679 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800680}
681
Colin Cross3854a602016-01-11 12:49:11 -0800682func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
683 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700684 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800685
Colin Crossce75d2c2016-10-06 16:12:58 -0700686 if !a.module.base().commonProperties.SkipInstall &&
Dan Willemsen0e2d97b2016-11-28 17:50:06 -0800687 (!a.Device() || !a.AConfig().SkipDeviceInstall()) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700688
Colin Cross12fc4972016-01-11 12:49:11 -0800689 a.ModuleBuild(pctx, ModuleBuildParams{
690 Rule: Symlink,
691 Output: fullInstallPath,
692 OrderOnly: Paths{srcPath},
693 Default: !a.AConfig().EmbeddedInMake(),
694 Args: map[string]string{
695 "fromPath": srcPath.String(),
696 },
697 })
Colin Cross3854a602016-01-11 12:49:11 -0800698
Colin Cross12fc4972016-01-11 12:49:11 -0800699 a.installFiles = append(a.installFiles, fullInstallPath)
700 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
701 }
Colin Cross3854a602016-01-11 12:49:11 -0800702 return fullInstallPath
703}
704
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700705func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800706 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
707}
708
Colin Cross3f40fa42015-01-30 17:27:36 -0800709type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700710 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800711}
712
713func isFileInstaller(m blueprint.Module) bool {
714 _, ok := m.(fileInstaller)
715 return ok
716}
717
718func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700719 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800720 return ok
721}
Colin Crossfce53272015-04-08 11:21:40 -0700722
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700723func findStringInSlice(str string, slice []string) int {
724 for i, s := range slice {
725 if s == str {
726 return i
Colin Crossfce53272015-04-08 11:21:40 -0700727 }
728 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700729 return -1
730}
731
Colin Cross068e0fe2016-12-13 15:23:47 -0800732func SrcIsModule(s string) string {
733 if len(s) > 1 && s[0] == ':' {
734 return s[1:]
735 }
736 return ""
737}
738
739type sourceDependencyTag struct {
740 blueprint.BaseDependencyTag
741}
742
743var SourceDepTag sourceDependencyTag
744
745// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
746// modules listed in srcFiles using ":module" syntax
747func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
748 var deps []string
749 for _, s := range srcFiles {
750 if m := SrcIsModule(s); m != "" {
751 deps = append(deps, m)
752 }
753 }
754
755 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
756}
757
758type SourceFileProducer interface {
759 Srcs() Paths
760}
761
762// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800763// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700764func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800765 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
766}
767
768func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700769 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800770
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700771 for i, e := range excludes {
772 j := findStringInSlice(e, srcFiles)
773 if j != -1 {
774 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
775 }
776
777 excludes[i] = filepath.Join(prefix, e)
778 }
779
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800780 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700781 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -0800782 if m := SrcIsModule(s); m != "" {
783 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
784 if srcProducer, ok := module.(SourceFileProducer); ok {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800785 expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
Colin Cross068e0fe2016-12-13 15:23:47 -0800786 } else {
787 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
788 }
789 } else if pathtools.IsGlob(s) {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800790 globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
791 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
792 for i, s := range expandedSrcFiles {
793 expandedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
794 }
Colin Cross8f101b42015-06-17 15:09:06 -0700795 } else {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800796 s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
797 expandedSrcFiles = append(expandedSrcFiles, s)
Colin Cross8f101b42015-06-17 15:09:06 -0700798 }
799 }
800
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800801 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -0700802}
803
Nan Zhang6d34b302017-02-04 17:47:46 -0800804func (ctx *androidModuleContext) RequiredModuleNames() []string {
805 return ctx.module.base().commonProperties.Required
806}
807
Colin Cross7f19f372016-11-01 11:10:25 -0700808func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
809 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700810 if err != nil {
811 ctx.ModuleErrorf("glob: %s", err.Error())
812 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700813 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700814}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700815
Colin Cross463a90e2015-06-17 14:20:06 -0700816func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700817 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700818}
819
Colin Cross1f8c52b2015-06-16 16:38:17 -0700820func BuildTargetSingleton() blueprint.Singleton {
821 return &buildTargetSingleton{}
822}
823
824type buildTargetSingleton struct{}
825
826func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
827 checkbuildDeps := []string{}
828
829 dirModules := make(map[string][]string)
830
831 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700832 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700833 blueprintDir := a.base().blueprintDir
834 installTarget := a.base().installTarget
835 checkbuildTarget := a.base().checkbuildTarget
836
837 if checkbuildTarget != "" {
838 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
839 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
840 }
841
842 if installTarget != "" {
843 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
844 }
845 }
846 })
847
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800848 suffix := ""
849 if ctx.Config().(Config).EmbeddedInMake() {
850 suffix = "-soong"
851 }
852
Colin Cross1f8c52b2015-06-16 16:38:17 -0700853 // Create a top-level checkbuild target that depends on all modules
854 ctx.Build(pctx, blueprint.BuildParams{
855 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800856 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700857 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700858 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700859 })
860
861 // Create a mm/<directory> target that depends on all modules in a directory
862 dirs := sortedKeys(dirModules)
863 for _, dir := range dirs {
864 ctx.Build(pctx, blueprint.BuildParams{
865 Rule: blueprint.Phony,
866 Outputs: []string{filepath.Join("mm", dir)},
867 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800868 // HACK: checkbuild should be an optional build, but force it
869 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800870 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700871 })
872 }
873}
Colin Crossd779da42015-12-17 18:00:23 -0800874
875type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700876 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800877 ctx interface {
878 ModuleName(blueprint.Module) string
879 ModuleSubDir(blueprint.Module) string
880 }
881}
882
883func (s AndroidModulesByName) Len() int { return len(s.slice) }
884func (s AndroidModulesByName) Less(i, j int) bool {
885 mi, mj := s.slice[i], s.slice[j]
886 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
887
888 if ni != nj {
889 return ni < nj
890 } else {
891 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
892 }
893}
894func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }