blob: 8228a9c5fe23e0cd6c9cc0b7d9585a342a207d24 [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
Nan Zhang6d34b302017-02-04 17:47:46 -080092
93 RequiredModuleNames() []string
Colin Cross3f40fa42015-01-30 17:27:36 -080094}
95
Colin Cross635c3b02016-05-18 15:37:25 -070096type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080097 blueprint.Module
98
Colin Cross635c3b02016-05-18 15:37:25 -070099 GenerateAndroidBuildActions(ModuleContext)
Colin Cross1e676be2016-10-12 14:38:15 -0700100 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800101
Colin Cross635c3b02016-05-18 15:37:25 -0700102 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800103 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700104 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800105 InstallInData() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800106 SkipInstall()
Colin Cross3f40fa42015-01-30 17:27:36 -0800107}
108
Colin Crossfc754582016-05-17 16:34:16 -0700109type nameProperties struct {
110 // The name of the module. Must be unique across all modules.
Colin Crossc77f9d12015-04-02 13:54:39 -0700111 Name string
Colin Crossfc754582016-05-17 16:34:16 -0700112}
113
114type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700115 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800116
Dan Willemsen0effe062015-11-30 16:06:01 -0800117 // emit build rules for this module
118 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800119
Colin Cross7d5136f2015-05-11 13:39:40 -0700120 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800121 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
122 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
123 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700124 Compile_multilib string `android:"arch_variant"`
125
126 Target struct {
127 Host struct {
128 Compile_multilib string
129 }
130 Android struct {
131 Compile_multilib string
132 }
133 }
134
135 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800136
Dan Willemsen782a2d12015-12-21 14:55:28 -0800137 // whether this is a proprietary vendor module, and should be installed into /vendor
138 Proprietary bool
139
Colin Cross55708f32017-03-20 13:23:34 -0700140 // vendor who owns this module
141 Owner string
142
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700143 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
144 // file
145 Logtags []string
146
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700147 // init.rc files to be installed if this module is installed
148 Init_rc []string
149
Chris Wolfe998306e2016-08-15 14:47:23 -0400150 // names of other modules to install if this module is installed
151 Required []string
152
Colin Crossa1ad8d12016-06-01 17:09:44 -0700153 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700154 CompileTarget Target `blueprint:"mutated"`
155 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800156
157 // Set by InitAndroidModule
158 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700159 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700160
161 SkipInstall bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800162}
163
164type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700165 Host_supported *bool
166 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800167}
168
Colin Crossc472d572015-03-17 15:06:21 -0700169type Multilib string
170
171const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700172 MultilibBoth Multilib = "both"
173 MultilibFirst Multilib = "first"
174 MultilibCommon Multilib = "common"
175 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700176)
177
Colin Crossa1ad8d12016-06-01 17:09:44 -0700178type HostOrDeviceSupported int
179
180const (
181 _ HostOrDeviceSupported = iota
182 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700183 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700184 DeviceSupported
185 HostAndDeviceSupported
186 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700187 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700188)
189
Colin Cross635c3b02016-05-18 15:37:25 -0700190func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800191 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
192
193 base := m.base()
194 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700195
Colin Crossfc754582016-05-17 16:34:16 -0700196 propertyStructs = append(propertyStructs,
197 &base.nameProperties,
198 &base.commonProperties,
199 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700200
201 return m, propertyStructs
202}
203
Colin Cross635c3b02016-05-18 15:37:25 -0700204func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700205 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
206
207 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
208
209 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800210 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700211 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700212 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800213
Dan Willemsen218f6562015-07-08 18:13:11 -0700214 switch hod {
215 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800216 // Default to module to device supported, host not supported, can override in module
217 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700218 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700219 fallthrough
220 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800221 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
222 }
223
Colin Crosscfad1192015-11-02 16:43:11 -0800224 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800225}
226
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800227// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800228// modules. It should be included as an anonymous field in every module
229// struct definition. InitAndroidModule should then be called from the module's
230// factory function, and the return values from InitAndroidModule should be
231// returned from the factory function.
232//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800233// The ModuleBase type is responsible for implementing the GenerateBuildActions
234// method to support the blueprint.Module interface. This method will then call
235// the module's GenerateAndroidBuildActions method once for each build variant
236// that is to be built. GenerateAndroidBuildActions is passed a
237// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800238// AndroidModuleContext exposes extra functionality specific to the Android build
239// system including details about the particular build variant that is to be
240// generated.
241//
242// For example:
243//
244// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800245// "android/soong/android"
Colin Cross70b40592015-03-23 12:57:34 -0700246// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800247// )
248//
249// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800250// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800251// properties struct {
252// MyProperty string
253// }
254// }
255//
256// func NewMyModule() (blueprint.Module, []interface{}) {
257// m := &myModule{}
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800258// return android.InitAndroidModule(m, &m.properties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800259// }
260//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800261// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800262// // Get the CPU architecture for the current build variant.
263// variantArch := ctx.Arch()
264//
265// // ...
266// }
Colin Cross635c3b02016-05-18 15:37:25 -0700267type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800268 // Putting the curiously recurring thing pointing to the thing that contains
269 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700270 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800271
Colin Crossfc754582016-05-17 16:34:16 -0700272 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800273 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700274 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800275 hostAndDeviceProperties hostAndDeviceProperties
276 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700277 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700278 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800279
280 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700281 installFiles Paths
282 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700283
284 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
285 // Only set on the final variant of each module
286 installTarget string
287 checkbuildTarget string
288 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700289
Colin Cross178a5092016-09-13 13:42:32 -0700290 hooks hooks
Colin Cross3f40fa42015-01-30 17:27:36 -0800291}
292
Colin Crossce75d2c2016-10-06 16:12:58 -0700293// Name returns the name of the module. It may be overridden by individual module types, for
294// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700295func (a *ModuleBase) Name() string {
296 return a.nameProperties.Name
297}
298
Colin Crossce75d2c2016-10-06 16:12:58 -0700299// BaseModuleName returns the name of the module as specified in the blueprints file.
300func (a *ModuleBase) BaseModuleName() string {
301 return a.nameProperties.Name
302}
303
Colin Cross635c3b02016-05-18 15:37:25 -0700304func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800305 return a
306}
307
Colin Cross8b74d172016-09-13 09:59:14 -0700308func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700309 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700310 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700311}
312
Colin Crossa1ad8d12016-06-01 17:09:44 -0700313func (a *ModuleBase) Target() Target {
314 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800315}
316
Colin Cross8b74d172016-09-13 09:59:14 -0700317func (a *ModuleBase) TargetPrimary() bool {
318 return a.commonProperties.CompilePrimary
319}
320
Colin Crossa1ad8d12016-06-01 17:09:44 -0700321func (a *ModuleBase) Os() OsType {
322 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800323}
324
Colin Cross635c3b02016-05-18 15:37:25 -0700325func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700326 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800327}
328
Colin Cross635c3b02016-05-18 15:37:25 -0700329func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700330 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800331}
332
Dan Willemsen0b24c742016-10-04 15:13:37 -0700333func (a *ModuleBase) ArchSpecific() bool {
334 return a.commonProperties.ArchSpecific
335}
336
Colin Crossa1ad8d12016-06-01 17:09:44 -0700337func (a *ModuleBase) OsClassSupported() []OsClass {
338 switch a.commonProperties.HostOrDeviceSupported {
339 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700340 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700341 case HostSupportedNoCross:
342 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700343 case DeviceSupported:
344 return []OsClass{Device}
345 case HostAndDeviceSupported:
346 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700347 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700348 supported = append(supported, Host, HostCross)
349 }
Colin Crossa4190c12016-07-12 13:11:25 -0700350 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700351 supported = append(supported, Device)
352 }
353 return supported
354 default:
355 return nil
356 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800357}
358
Colin Cross635c3b02016-05-18 15:37:25 -0700359func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800360 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
361 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700362 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800363}
364
Colin Cross635c3b02016-05-18 15:37:25 -0700365func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800366 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800367 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800368 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800369 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800370}
371
Colin Crossce75d2c2016-10-06 16:12:58 -0700372func (a *ModuleBase) SkipInstall() {
373 a.commonProperties.SkipInstall = true
374}
375
Colin Cross635c3b02016-05-18 15:37:25 -0700376func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700377 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800378
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700379 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800380 ctx.VisitDepsDepthFirstIf(isFileInstaller,
381 func(m blueprint.Module) {
382 fileInstaller := m.(fileInstaller)
383 files := fileInstaller.filesToInstall()
384 result = append(result, files...)
385 })
386
387 return result
388}
389
Colin Cross635c3b02016-05-18 15:37:25 -0700390func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800391 return a.installFiles
392}
393
Colin Cross635c3b02016-05-18 15:37:25 -0700394func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800395 return p.noAddressSanitizer
396}
397
Colin Cross635c3b02016-05-18 15:37:25 -0700398func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800399 return false
400}
401
Colin Cross635c3b02016-05-18 15:37:25 -0700402func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700403 allInstalledFiles := Paths{}
404 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800405 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700406 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700407 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
408 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800409 })
410
Colin Cross9454bfa2015-03-17 13:24:18 -0700411 deps := []string{}
412
Colin Cross3f40fa42015-01-30 17:27:36 -0800413 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700414 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800415 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700416 Rule: blueprint.Phony,
417 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700418 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800419 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700420 })
421 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700422 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700423 }
424
425 if len(allCheckbuildFiles) > 0 {
426 name := ctx.ModuleName() + "-checkbuild"
427 ctx.Build(pctx, blueprint.BuildParams{
428 Rule: blueprint.Phony,
429 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700430 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700431 Optional: true,
432 })
433 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700434 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700435 }
436
437 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800438 suffix := ""
439 if ctx.Config().(Config).EmbeddedInMake() {
440 suffix = "-soong"
441 }
442
Colin Cross9454bfa2015-03-17 13:24:18 -0700443 ctx.Build(pctx, blueprint.BuildParams{
444 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800445 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700446 Implicits: deps,
447 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800448 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700449
450 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800451 }
452}
453
Colin Cross635c3b02016-05-18 15:37:25 -0700454func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700455 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700456 target: a.commonProperties.CompileTarget,
457 targetPrimary: a.commonProperties.CompilePrimary,
Dan Willemsen11b26142017-03-19 18:30:37 -0700458 proprietary: a.commonProperties.Proprietary,
Colin Cross8b74d172016-09-13 09:59:14 -0700459 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800460 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800461}
462
Colin Cross635c3b02016-05-18 15:37:25 -0700463func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800464 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700465 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700466 ModuleContext: ctx,
467 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
468 installDeps: a.computeInstallDeps(ctx),
469 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800470 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800471 }
472
Colin Cross9b1d13d2016-09-19 15:18:11 -0700473 if a.Enabled() {
474 a.module.GenerateAndroidBuildActions(androidCtx)
475 if ctx.Failed() {
476 return
477 }
478
479 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
480 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800481 }
482
Colin Cross9b1d13d2016-09-19 15:18:11 -0700483 if a == ctx.FinalModule().(Module).base() {
484 a.generateModuleTarget(ctx)
485 if ctx.Failed() {
486 return
487 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800488 }
489}
490
Colin Crossf6566ed2015-03-24 11:13:38 -0700491type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700492 target Target
493 targetPrimary bool
494 debug bool
Dan Willemsen11b26142017-03-19 18:30:37 -0700495 proprietary bool
Colin Cross8b74d172016-09-13 09:59:14 -0700496 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700497}
498
Colin Cross3f40fa42015-01-30 17:27:36 -0800499type androidModuleContext struct {
500 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700501 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700502 installDeps Paths
503 installFiles Paths
504 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800505 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700506 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800507}
508
509func (a *androidModuleContext) ninjaError(outputs []string, err error) {
510 a.ModuleContext.Build(pctx, blueprint.BuildParams{
511 Rule: ErrorRule,
512 Outputs: outputs,
513 Optional: true,
514 Args: map[string]string{
515 "error": err.Error(),
516 },
517 })
518 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800519}
520
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800521func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Cross7f19f372016-11-01 11:10:25 -0700522 if a.missingDeps != nil {
Colin Cross6ff51382015-12-17 16:39:19 -0800523 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
524 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
525 return
526 }
527
Colin Cross3f40fa42015-01-30 17:27:36 -0800528 params.Optional = true
529 a.ModuleContext.Build(pctx, params)
530}
531
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700532func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
533 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700534 Rule: params.Rule,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800535 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700536 Outputs: params.Outputs.Strings(),
537 ImplicitOutputs: params.ImplicitOutputs.Strings(),
538 Inputs: params.Inputs.Strings(),
539 Implicits: params.Implicits.Strings(),
540 OrderOnly: params.OrderOnly.Strings(),
541 Args: params.Args,
542 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700543 }
544
Colin Cross33bfb0a2016-11-21 17:23:08 -0800545 if params.Depfile != nil {
546 bparams.Depfile = params.Depfile.String()
547 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700548 if params.Output != nil {
549 bparams.Outputs = append(bparams.Outputs, params.Output.String())
550 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700551 if params.ImplicitOutput != nil {
552 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
553 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700554 if params.Input != nil {
555 bparams.Inputs = append(bparams.Inputs, params.Input.String())
556 }
557 if params.Implicit != nil {
558 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
559 }
560
Colin Cross6ff51382015-12-17 16:39:19 -0800561 if a.missingDeps != nil {
562 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
563 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
564 return
565 }
566
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700567 a.ModuleContext.Build(pctx, bparams)
568}
569
Colin Cross6ff51382015-12-17 16:39:19 -0800570func (a *androidModuleContext) GetMissingDependencies() []string {
571 return a.missingDeps
572}
573
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800574func (a *androidModuleContext) AddMissingDependencies(deps []string) {
575 if deps != nil {
576 a.missingDeps = append(a.missingDeps, deps...)
577 }
578}
579
Colin Crossa1ad8d12016-06-01 17:09:44 -0700580func (a *androidBaseContextImpl) Target() Target {
581 return a.target
582}
583
Colin Cross8b74d172016-09-13 09:59:14 -0700584func (a *androidBaseContextImpl) TargetPrimary() bool {
585 return a.targetPrimary
586}
587
Colin Crossf6566ed2015-03-24 11:13:38 -0700588func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700589 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800590}
591
Colin Crossa1ad8d12016-06-01 17:09:44 -0700592func (a *androidBaseContextImpl) Os() OsType {
593 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800594}
595
Colin Crossf6566ed2015-03-24 11:13:38 -0700596func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700597 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700598}
599
600func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700601 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700602}
603
Colin Cross0af4b842015-04-30 16:36:18 -0700604func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700605 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700606}
607
Colin Crossf6566ed2015-03-24 11:13:38 -0700608func (a *androidBaseContextImpl) Debug() bool {
609 return a.debug
610}
611
Colin Cross1e7d3702016-08-24 15:25:47 -0700612func (a *androidBaseContextImpl) PrimaryArch() bool {
613 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
614}
615
Colin Cross1332b002015-04-07 17:11:30 -0700616func (a *androidBaseContextImpl) AConfig() Config {
617 return a.config
618}
619
Colin Cross9272ade2016-08-17 15:24:12 -0700620func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
621 return DeviceConfig{a.config.deviceConfig}
622}
623
Dan Willemsen11b26142017-03-19 18:30:37 -0700624func (a *androidBaseContextImpl) Proprietary() bool {
625 return a.proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800626}
627
Colin Cross8d8f8e22016-08-03 11:57:50 -0700628func (a *androidModuleContext) InstallInData() bool {
629 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800630}
631
632func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700633 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700634
Dan Willemsen782a2d12015-12-21 14:55:28 -0800635 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700636 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800637
Colin Crossce75d2c2016-10-06 16:12:58 -0700638 if !a.module.base().commonProperties.SkipInstall &&
Dan Willemsen0e2d97b2016-11-28 17:50:06 -0800639 (!a.Device() || !a.AConfig().SkipDeviceInstall()) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700640
Dan Willemsen322acaf2016-01-12 23:07:05 -0800641 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700642
Colin Cross89562dc2016-10-03 17:47:19 -0700643 var implicitDeps, orderOnlyDeps Paths
644
645 if a.Host() {
646 // Installed host modules might be used during the build, depend directly on their
647 // dependencies so their timestamp is updated whenever their dependency is updated
648 implicitDeps = deps
649 } else {
650 orderOnlyDeps = deps
651 }
652
Dan Willemsen322acaf2016-01-12 23:07:05 -0800653 a.ModuleBuild(pctx, ModuleBuildParams{
654 Rule: Cp,
655 Output: fullInstallPath,
656 Input: srcPath,
Colin Cross89562dc2016-10-03 17:47:19 -0700657 Implicits: implicitDeps,
658 OrderOnly: orderOnlyDeps,
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800659 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800660 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800661
Dan Willemsen322acaf2016-01-12 23:07:05 -0800662 a.installFiles = append(a.installFiles, fullInstallPath)
663 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700664 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700665 return fullInstallPath
666}
667
Colin Crossa2344662016-03-24 13:14:12 -0700668func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700669 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800670}
671
Colin Cross3854a602016-01-11 12:49:11 -0800672func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
673 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700674 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800675
Colin Crossce75d2c2016-10-06 16:12:58 -0700676 if !a.module.base().commonProperties.SkipInstall &&
Dan Willemsen0e2d97b2016-11-28 17:50:06 -0800677 (!a.Device() || !a.AConfig().SkipDeviceInstall()) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700678
Colin Cross12fc4972016-01-11 12:49:11 -0800679 a.ModuleBuild(pctx, ModuleBuildParams{
680 Rule: Symlink,
681 Output: fullInstallPath,
682 OrderOnly: Paths{srcPath},
683 Default: !a.AConfig().EmbeddedInMake(),
684 Args: map[string]string{
685 "fromPath": srcPath.String(),
686 },
687 })
Colin Cross3854a602016-01-11 12:49:11 -0800688
Colin Cross12fc4972016-01-11 12:49:11 -0800689 a.installFiles = append(a.installFiles, fullInstallPath)
690 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
691 }
Colin Cross3854a602016-01-11 12:49:11 -0800692 return fullInstallPath
693}
694
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700695func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800696 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
697}
698
Colin Cross3f40fa42015-01-30 17:27:36 -0800699type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700700 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800701}
702
703func isFileInstaller(m blueprint.Module) bool {
704 _, ok := m.(fileInstaller)
705 return ok
706}
707
708func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700709 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800710 return ok
711}
Colin Crossfce53272015-04-08 11:21:40 -0700712
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700713func findStringInSlice(str string, slice []string) int {
714 for i, s := range slice {
715 if s == str {
716 return i
Colin Crossfce53272015-04-08 11:21:40 -0700717 }
718 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700719 return -1
720}
721
Colin Cross068e0fe2016-12-13 15:23:47 -0800722func SrcIsModule(s string) string {
723 if len(s) > 1 && s[0] == ':' {
724 return s[1:]
725 }
726 return ""
727}
728
729type sourceDependencyTag struct {
730 blueprint.BaseDependencyTag
731}
732
733var SourceDepTag sourceDependencyTag
734
735// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
736// modules listed in srcFiles using ":module" syntax
737func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
738 var deps []string
739 for _, s := range srcFiles {
740 if m := SrcIsModule(s); m != "" {
741 deps = append(deps, m)
742 }
743 }
744
745 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
746}
747
748type SourceFileProducer interface {
749 Srcs() Paths
750}
751
752// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800753// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700754func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800755 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
756}
757
758func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700759 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800760
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700761 for i, e := range excludes {
762 j := findStringInSlice(e, srcFiles)
763 if j != -1 {
764 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
765 }
766
767 excludes[i] = filepath.Join(prefix, e)
768 }
769
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800770 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700771 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -0800772 if m := SrcIsModule(s); m != "" {
773 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
774 if srcProducer, ok := module.(SourceFileProducer); ok {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800775 expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
Colin Cross068e0fe2016-12-13 15:23:47 -0800776 } else {
777 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
778 }
779 } else if pathtools.IsGlob(s) {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800780 globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
781 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
782 for i, s := range expandedSrcFiles {
783 expandedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
784 }
Colin Cross8f101b42015-06-17 15:09:06 -0700785 } else {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800786 s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
787 expandedSrcFiles = append(expandedSrcFiles, s)
Colin Cross8f101b42015-06-17 15:09:06 -0700788 }
789 }
790
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800791 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -0700792}
793
Nan Zhang6d34b302017-02-04 17:47:46 -0800794func (ctx *androidModuleContext) RequiredModuleNames() []string {
795 return ctx.module.base().commonProperties.Required
796}
797
Colin Cross7f19f372016-11-01 11:10:25 -0700798func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
799 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700800 if err != nil {
801 ctx.ModuleErrorf("glob: %s", err.Error())
802 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700803 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700804}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700805
Colin Cross463a90e2015-06-17 14:20:06 -0700806func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700807 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700808}
809
Colin Cross1f8c52b2015-06-16 16:38:17 -0700810func BuildTargetSingleton() blueprint.Singleton {
811 return &buildTargetSingleton{}
812}
813
814type buildTargetSingleton struct{}
815
816func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
817 checkbuildDeps := []string{}
818
819 dirModules := make(map[string][]string)
820
821 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700822 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700823 blueprintDir := a.base().blueprintDir
824 installTarget := a.base().installTarget
825 checkbuildTarget := a.base().checkbuildTarget
826
827 if checkbuildTarget != "" {
828 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
829 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
830 }
831
832 if installTarget != "" {
833 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
834 }
835 }
836 })
837
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800838 suffix := ""
839 if ctx.Config().(Config).EmbeddedInMake() {
840 suffix = "-soong"
841 }
842
Colin Cross1f8c52b2015-06-16 16:38:17 -0700843 // Create a top-level checkbuild target that depends on all modules
844 ctx.Build(pctx, blueprint.BuildParams{
845 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800846 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700847 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700848 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700849 })
850
851 // Create a mm/<directory> target that depends on all modules in a directory
852 dirs := sortedKeys(dirModules)
853 for _, dir := range dirs {
854 ctx.Build(pctx, blueprint.BuildParams{
855 Rule: blueprint.Phony,
856 Outputs: []string{filepath.Join("mm", dir)},
857 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800858 // HACK: checkbuild should be an optional build, but force it
859 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800860 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700861 })
862 }
863}
Colin Crossd779da42015-12-17 18:00:23 -0800864
865type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700866 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800867 ctx interface {
868 ModuleName(blueprint.Module) string
869 ModuleSubDir(blueprint.Module) string
870 }
871}
872
873func (s AndroidModulesByName) Len() int { return len(s.slice) }
874func (s AndroidModulesByName) Less(i, j int) bool {
875 mi, mj := s.slice[i], s.slice[j]
876 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
877
878 if ni != nj {
879 return ni < nj
880 } else {
881 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
882 }
883}
884func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }