blob: b5de1adf00154f4325ae076817e46f182fa77b0e [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
Colin Cross1332b002015-04-07 17:11:30 -070062 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070063 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070064}
65
Colin Cross635c3b02016-05-18 15:37:25 -070066type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070067 blueprint.BaseModuleContext
68 androidBaseContext
69}
70
Colin Cross635c3b02016-05-18 15:37:25 -070071type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080072 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070073 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080074
Dan Willemsen34cc69e2015-09-23 15:26:20 -070075 // Similar to Build, but takes Paths instead of []string,
76 // and performs more verification.
77 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070078
Dan Willemsen34cc69e2015-09-23 15:26:20 -070079 ExpandSources(srcFiles, excludes []string) Paths
Colin Crossfaeb7aa2017-02-01 14:12:44 -080080 ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
Colin Cross7f19f372016-11-01 11:10:25 -070081 Glob(globPattern string, excludes []string) Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -070082
Colin Crossa2344662016-03-24 13:14:12 -070083 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
84 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080085 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070086 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080087
88 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -070089
90 Proprietary() bool
91 InstallInData() bool
Colin Cross3f40fa42015-01-30 17:27:36 -080092}
93
Colin Cross635c3b02016-05-18 15:37:25 -070094type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080095 blueprint.Module
96
Colin Cross635c3b02016-05-18 15:37:25 -070097 GenerateAndroidBuildActions(ModuleContext)
Colin Cross1e676be2016-10-12 14:38:15 -070098 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080099
Colin Cross635c3b02016-05-18 15:37:25 -0700100 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800101 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700102 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800103 InstallInData() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800104 SkipInstall()
Colin Cross3f40fa42015-01-30 17:27:36 -0800105}
106
Colin Crossfc754582016-05-17 16:34:16 -0700107type nameProperties struct {
108 // The name of the module. Must be unique across all modules.
Colin Crossc77f9d12015-04-02 13:54:39 -0700109 Name string
Colin Crossfc754582016-05-17 16:34:16 -0700110}
111
112type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700113 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800114
Dan Willemsen0effe062015-11-30 16:06:01 -0800115 // emit build rules for this module
116 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800117
Colin Cross7d5136f2015-05-11 13:39:40 -0700118 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800119 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
120 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
121 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700122 Compile_multilib string `android:"arch_variant"`
123
124 Target struct {
125 Host struct {
126 Compile_multilib string
127 }
128 Android struct {
129 Compile_multilib string
130 }
131 }
132
133 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800134
Dan Willemsen782a2d12015-12-21 14:55:28 -0800135 // whether this is a proprietary vendor module, and should be installed into /vendor
136 Proprietary bool
137
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700138 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
139 // file
140 Logtags []string
141
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700142 // init.rc files to be installed if this module is installed
143 Init_rc []string
144
Chris Wolfe998306e2016-08-15 14:47:23 -0400145 // names of other modules to install if this module is installed
146 Required []string
147
Colin Crossa1ad8d12016-06-01 17:09:44 -0700148 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700149 CompileTarget Target `blueprint:"mutated"`
150 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800151
152 // Set by InitAndroidModule
153 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700154 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700155
156 SkipInstall bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800157}
158
159type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700160 Host_supported *bool
161 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800162}
163
Colin Crossc472d572015-03-17 15:06:21 -0700164type Multilib string
165
166const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700167 MultilibBoth Multilib = "both"
168 MultilibFirst Multilib = "first"
169 MultilibCommon Multilib = "common"
170 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700171)
172
Colin Crossa1ad8d12016-06-01 17:09:44 -0700173type HostOrDeviceSupported int
174
175const (
176 _ HostOrDeviceSupported = iota
177 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700178 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700179 DeviceSupported
180 HostAndDeviceSupported
181 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700182 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700183)
184
Colin Cross635c3b02016-05-18 15:37:25 -0700185func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800186 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
187
188 base := m.base()
189 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700190
Colin Crossfc754582016-05-17 16:34:16 -0700191 propertyStructs = append(propertyStructs,
192 &base.nameProperties,
193 &base.commonProperties,
194 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700195
196 return m, propertyStructs
197}
198
Colin Cross635c3b02016-05-18 15:37:25 -0700199func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700200 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
201
202 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
203
204 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800205 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700206 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700207 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800208
Dan Willemsen218f6562015-07-08 18:13:11 -0700209 switch hod {
210 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800211 // Default to module to device supported, host not supported, can override in module
212 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700213 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700214 fallthrough
215 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800216 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
217 }
218
Colin Crosscfad1192015-11-02 16:43:11 -0800219 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800220}
221
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800222// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800223// modules. It should be included as an anonymous field in every module
224// struct definition. InitAndroidModule should then be called from the module's
225// factory function, and the return values from InitAndroidModule should be
226// returned from the factory function.
227//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800228// The ModuleBase type is responsible for implementing the GenerateBuildActions
229// method to support the blueprint.Module interface. This method will then call
230// the module's GenerateAndroidBuildActions method once for each build variant
231// that is to be built. GenerateAndroidBuildActions is passed a
232// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800233// AndroidModuleContext exposes extra functionality specific to the Android build
234// system including details about the particular build variant that is to be
235// generated.
236//
237// For example:
238//
239// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800240// "android/soong/android"
Colin Cross70b40592015-03-23 12:57:34 -0700241// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800242// )
243//
244// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800245// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800246// properties struct {
247// MyProperty string
248// }
249// }
250//
251// func NewMyModule() (blueprint.Module, []interface{}) {
252// m := &myModule{}
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800253// return android.InitAndroidModule(m, &m.properties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800254// }
255//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800256// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800257// // Get the CPU architecture for the current build variant.
258// variantArch := ctx.Arch()
259//
260// // ...
261// }
Colin Cross635c3b02016-05-18 15:37:25 -0700262type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800263 // Putting the curiously recurring thing pointing to the thing that contains
264 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700265 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800266
Colin Crossfc754582016-05-17 16:34:16 -0700267 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800268 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700269 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800270 hostAndDeviceProperties hostAndDeviceProperties
271 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700272 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700273 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800274
275 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700276 installFiles Paths
277 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700278
279 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
280 // Only set on the final variant of each module
281 installTarget string
282 checkbuildTarget string
283 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700284
Colin Cross178a5092016-09-13 13:42:32 -0700285 hooks hooks
Colin Cross3f40fa42015-01-30 17:27:36 -0800286}
287
Colin Crossce75d2c2016-10-06 16:12:58 -0700288// Name returns the name of the module. It may be overridden by individual module types, for
289// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700290func (a *ModuleBase) Name() string {
291 return a.nameProperties.Name
292}
293
Colin Crossce75d2c2016-10-06 16:12:58 -0700294// BaseModuleName returns the name of the module as specified in the blueprints file.
295func (a *ModuleBase) BaseModuleName() string {
296 return a.nameProperties.Name
297}
298
Colin Cross635c3b02016-05-18 15:37:25 -0700299func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800300 return a
301}
302
Colin Cross8b74d172016-09-13 09:59:14 -0700303func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700304 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700305 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700306}
307
Colin Crossa1ad8d12016-06-01 17:09:44 -0700308func (a *ModuleBase) Target() Target {
309 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800310}
311
Colin Cross8b74d172016-09-13 09:59:14 -0700312func (a *ModuleBase) TargetPrimary() bool {
313 return a.commonProperties.CompilePrimary
314}
315
Colin Crossa1ad8d12016-06-01 17:09:44 -0700316func (a *ModuleBase) Os() OsType {
317 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800318}
319
Colin Cross635c3b02016-05-18 15:37:25 -0700320func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700321 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800322}
323
Colin Cross635c3b02016-05-18 15:37:25 -0700324func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700325 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800326}
327
Dan Willemsen0b24c742016-10-04 15:13:37 -0700328func (a *ModuleBase) ArchSpecific() bool {
329 return a.commonProperties.ArchSpecific
330}
331
Colin Crossa1ad8d12016-06-01 17:09:44 -0700332func (a *ModuleBase) OsClassSupported() []OsClass {
333 switch a.commonProperties.HostOrDeviceSupported {
334 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700335 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700336 case HostSupportedNoCross:
337 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700338 case DeviceSupported:
339 return []OsClass{Device}
340 case HostAndDeviceSupported:
341 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700342 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700343 supported = append(supported, Host, HostCross)
344 }
Colin Crossa4190c12016-07-12 13:11:25 -0700345 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700346 supported = append(supported, Device)
347 }
348 return supported
349 default:
350 return nil
351 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800352}
353
Colin Cross635c3b02016-05-18 15:37:25 -0700354func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800355 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
356 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700357 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800358}
359
Colin Cross635c3b02016-05-18 15:37:25 -0700360func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800361 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800362 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800363 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800364 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800365}
366
Colin Crossce75d2c2016-10-06 16:12:58 -0700367func (a *ModuleBase) SkipInstall() {
368 a.commonProperties.SkipInstall = true
369}
370
Colin Cross635c3b02016-05-18 15:37:25 -0700371func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700372 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800373
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700374 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800375 ctx.VisitDepsDepthFirstIf(isFileInstaller,
376 func(m blueprint.Module) {
377 fileInstaller := m.(fileInstaller)
378 files := fileInstaller.filesToInstall()
379 result = append(result, files...)
380 })
381
382 return result
383}
384
Colin Cross635c3b02016-05-18 15:37:25 -0700385func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800386 return a.installFiles
387}
388
Colin Cross635c3b02016-05-18 15:37:25 -0700389func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800390 return p.noAddressSanitizer
391}
392
Colin Cross635c3b02016-05-18 15:37:25 -0700393func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800394 return false
395}
396
Colin Cross635c3b02016-05-18 15:37:25 -0700397func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700398 allInstalledFiles := Paths{}
399 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800400 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700401 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700402 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
403 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800404 })
405
Colin Cross9454bfa2015-03-17 13:24:18 -0700406 deps := []string{}
407
Colin Cross3f40fa42015-01-30 17:27:36 -0800408 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700409 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800410 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700411 Rule: blueprint.Phony,
412 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700413 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800414 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700415 })
416 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700417 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700418 }
419
420 if len(allCheckbuildFiles) > 0 {
421 name := ctx.ModuleName() + "-checkbuild"
422 ctx.Build(pctx, blueprint.BuildParams{
423 Rule: blueprint.Phony,
424 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700425 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700426 Optional: true,
427 })
428 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700429 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700430 }
431
432 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800433 suffix := ""
434 if ctx.Config().(Config).EmbeddedInMake() {
435 suffix = "-soong"
436 }
437
Colin Cross9454bfa2015-03-17 13:24:18 -0700438 ctx.Build(pctx, blueprint.BuildParams{
439 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800440 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700441 Implicits: deps,
442 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800443 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700444
445 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800446 }
447}
448
Colin Cross635c3b02016-05-18 15:37:25 -0700449func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700450 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700451 target: a.commonProperties.CompileTarget,
452 targetPrimary: a.commonProperties.CompilePrimary,
453 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800454 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800455}
456
Colin Cross635c3b02016-05-18 15:37:25 -0700457func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800458 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700459 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700460 ModuleContext: ctx,
461 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
462 installDeps: a.computeInstallDeps(ctx),
463 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800464 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800465 }
466
Colin Cross9b1d13d2016-09-19 15:18:11 -0700467 if a.Enabled() {
468 a.module.GenerateAndroidBuildActions(androidCtx)
469 if ctx.Failed() {
470 return
471 }
472
473 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
474 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800475 }
476
Colin Cross9b1d13d2016-09-19 15:18:11 -0700477 if a == ctx.FinalModule().(Module).base() {
478 a.generateModuleTarget(ctx)
479 if ctx.Failed() {
480 return
481 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800482 }
483}
484
Colin Crossf6566ed2015-03-24 11:13:38 -0700485type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700486 target Target
487 targetPrimary bool
488 debug bool
489 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700490}
491
Colin Cross3f40fa42015-01-30 17:27:36 -0800492type androidModuleContext struct {
493 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700494 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700495 installDeps Paths
496 installFiles Paths
497 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800498 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700499 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800500}
501
502func (a *androidModuleContext) ninjaError(outputs []string, err error) {
503 a.ModuleContext.Build(pctx, blueprint.BuildParams{
504 Rule: ErrorRule,
505 Outputs: outputs,
506 Optional: true,
507 Args: map[string]string{
508 "error": err.Error(),
509 },
510 })
511 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800512}
513
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800514func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Cross7f19f372016-11-01 11:10:25 -0700515 if a.missingDeps != nil {
Colin Cross6ff51382015-12-17 16:39:19 -0800516 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
517 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
518 return
519 }
520
Colin Cross3f40fa42015-01-30 17:27:36 -0800521 params.Optional = true
522 a.ModuleContext.Build(pctx, params)
523}
524
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700525func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
526 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700527 Rule: params.Rule,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800528 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700529 Outputs: params.Outputs.Strings(),
530 ImplicitOutputs: params.ImplicitOutputs.Strings(),
531 Inputs: params.Inputs.Strings(),
532 Implicits: params.Implicits.Strings(),
533 OrderOnly: params.OrderOnly.Strings(),
534 Args: params.Args,
535 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700536 }
537
Colin Cross33bfb0a2016-11-21 17:23:08 -0800538 if params.Depfile != nil {
539 bparams.Depfile = params.Depfile.String()
540 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700541 if params.Output != nil {
542 bparams.Outputs = append(bparams.Outputs, params.Output.String())
543 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700544 if params.ImplicitOutput != nil {
545 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
546 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700547 if params.Input != nil {
548 bparams.Inputs = append(bparams.Inputs, params.Input.String())
549 }
550 if params.Implicit != nil {
551 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
552 }
553
Colin Cross6ff51382015-12-17 16:39:19 -0800554 if a.missingDeps != nil {
555 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
556 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
557 return
558 }
559
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700560 a.ModuleContext.Build(pctx, bparams)
561}
562
Colin Cross6ff51382015-12-17 16:39:19 -0800563func (a *androidModuleContext) GetMissingDependencies() []string {
564 return a.missingDeps
565}
566
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800567func (a *androidModuleContext) AddMissingDependencies(deps []string) {
568 if deps != nil {
569 a.missingDeps = append(a.missingDeps, deps...)
570 }
571}
572
Colin Crossa1ad8d12016-06-01 17:09:44 -0700573func (a *androidBaseContextImpl) Target() Target {
574 return a.target
575}
576
Colin Cross8b74d172016-09-13 09:59:14 -0700577func (a *androidBaseContextImpl) TargetPrimary() bool {
578 return a.targetPrimary
579}
580
Colin Crossf6566ed2015-03-24 11:13:38 -0700581func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700582 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800583}
584
Colin Crossa1ad8d12016-06-01 17:09:44 -0700585func (a *androidBaseContextImpl) Os() OsType {
586 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800587}
588
Colin Crossf6566ed2015-03-24 11:13:38 -0700589func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700590 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700591}
592
593func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700594 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700595}
596
Colin Cross0af4b842015-04-30 16:36:18 -0700597func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700598 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700599}
600
Colin Crossf6566ed2015-03-24 11:13:38 -0700601func (a *androidBaseContextImpl) Debug() bool {
602 return a.debug
603}
604
Colin Cross1e7d3702016-08-24 15:25:47 -0700605func (a *androidBaseContextImpl) PrimaryArch() bool {
606 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
607}
608
Colin Cross1332b002015-04-07 17:11:30 -0700609func (a *androidBaseContextImpl) AConfig() Config {
610 return a.config
611}
612
Colin Cross9272ade2016-08-17 15:24:12 -0700613func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
614 return DeviceConfig{a.config.deviceConfig}
615}
616
Colin Cross8d8f8e22016-08-03 11:57:50 -0700617func (a *androidModuleContext) Proprietary() bool {
618 return a.module.base().commonProperties.Proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800619}
620
Colin Cross8d8f8e22016-08-03 11:57:50 -0700621func (a *androidModuleContext) InstallInData() bool {
622 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800623}
624
625func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700626 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700627
Dan Willemsen782a2d12015-12-21 14:55:28 -0800628 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700629 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800630
Colin Crossce75d2c2016-10-06 16:12:58 -0700631 if !a.module.base().commonProperties.SkipInstall &&
632 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
633
Dan Willemsen322acaf2016-01-12 23:07:05 -0800634 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700635
Colin Cross89562dc2016-10-03 17:47:19 -0700636 var implicitDeps, orderOnlyDeps Paths
637
638 if a.Host() {
639 // Installed host modules might be used during the build, depend directly on their
640 // dependencies so their timestamp is updated whenever their dependency is updated
641 implicitDeps = deps
642 } else {
643 orderOnlyDeps = deps
644 }
645
Dan Willemsen322acaf2016-01-12 23:07:05 -0800646 a.ModuleBuild(pctx, ModuleBuildParams{
647 Rule: Cp,
648 Output: fullInstallPath,
649 Input: srcPath,
Colin Cross89562dc2016-10-03 17:47:19 -0700650 Implicits: implicitDeps,
651 OrderOnly: orderOnlyDeps,
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800652 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800653 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800654
Dan Willemsen322acaf2016-01-12 23:07:05 -0800655 a.installFiles = append(a.installFiles, fullInstallPath)
656 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700657 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700658 return fullInstallPath
659}
660
Colin Crossa2344662016-03-24 13:14:12 -0700661func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700662 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800663}
664
Colin Cross3854a602016-01-11 12:49:11 -0800665func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
666 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700667 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800668
Colin Crossce75d2c2016-10-06 16:12:58 -0700669 if !a.module.base().commonProperties.SkipInstall &&
670 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
671
Colin Cross12fc4972016-01-11 12:49:11 -0800672 a.ModuleBuild(pctx, ModuleBuildParams{
673 Rule: Symlink,
674 Output: fullInstallPath,
675 OrderOnly: Paths{srcPath},
676 Default: !a.AConfig().EmbeddedInMake(),
677 Args: map[string]string{
678 "fromPath": srcPath.String(),
679 },
680 })
Colin Cross3854a602016-01-11 12:49:11 -0800681
Colin Cross12fc4972016-01-11 12:49:11 -0800682 a.installFiles = append(a.installFiles, fullInstallPath)
683 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
684 }
Colin Cross3854a602016-01-11 12:49:11 -0800685 return fullInstallPath
686}
687
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700688func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800689 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
690}
691
Colin Cross3f40fa42015-01-30 17:27:36 -0800692type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700693 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800694}
695
696func isFileInstaller(m blueprint.Module) bool {
697 _, ok := m.(fileInstaller)
698 return ok
699}
700
701func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700702 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800703 return ok
704}
Colin Crossfce53272015-04-08 11:21:40 -0700705
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700706func findStringInSlice(str string, slice []string) int {
707 for i, s := range slice {
708 if s == str {
709 return i
Colin Crossfce53272015-04-08 11:21:40 -0700710 }
711 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700712 return -1
713}
714
Colin Cross068e0fe2016-12-13 15:23:47 -0800715func SrcIsModule(s string) string {
716 if len(s) > 1 && s[0] == ':' {
717 return s[1:]
718 }
719 return ""
720}
721
722type sourceDependencyTag struct {
723 blueprint.BaseDependencyTag
724}
725
726var SourceDepTag sourceDependencyTag
727
728// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
729// modules listed in srcFiles using ":module" syntax
730func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
731 var deps []string
732 for _, s := range srcFiles {
733 if m := SrcIsModule(s); m != "" {
734 deps = append(deps, m)
735 }
736 }
737
738 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
739}
740
741type SourceFileProducer interface {
742 Srcs() Paths
743}
744
745// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800746// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700747func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800748 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
749}
750
751func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700752 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800753
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700754 for i, e := range excludes {
755 j := findStringInSlice(e, srcFiles)
756 if j != -1 {
757 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
758 }
759
760 excludes[i] = filepath.Join(prefix, e)
761 }
762
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800763 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700764 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -0800765 if m := SrcIsModule(s); m != "" {
766 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
767 if srcProducer, ok := module.(SourceFileProducer); ok {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800768 expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
Colin Cross068e0fe2016-12-13 15:23:47 -0800769 } else {
770 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
771 }
772 } else if pathtools.IsGlob(s) {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800773 globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
774 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
775 for i, s := range expandedSrcFiles {
776 expandedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
777 }
Colin Cross8f101b42015-06-17 15:09:06 -0700778 } else {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800779 s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
780 expandedSrcFiles = append(expandedSrcFiles, s)
Colin Cross8f101b42015-06-17 15:09:06 -0700781 }
782 }
783
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800784 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -0700785}
786
Colin Cross7f19f372016-11-01 11:10:25 -0700787func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
788 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700789 if err != nil {
790 ctx.ModuleErrorf("glob: %s", err.Error())
791 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700792 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700793}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700794
Colin Cross463a90e2015-06-17 14:20:06 -0700795func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700796 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700797}
798
Colin Cross1f8c52b2015-06-16 16:38:17 -0700799func BuildTargetSingleton() blueprint.Singleton {
800 return &buildTargetSingleton{}
801}
802
803type buildTargetSingleton struct{}
804
805func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
806 checkbuildDeps := []string{}
807
808 dirModules := make(map[string][]string)
809
810 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700811 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700812 blueprintDir := a.base().blueprintDir
813 installTarget := a.base().installTarget
814 checkbuildTarget := a.base().checkbuildTarget
815
816 if checkbuildTarget != "" {
817 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
818 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
819 }
820
821 if installTarget != "" {
822 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
823 }
824 }
825 })
826
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800827 suffix := ""
828 if ctx.Config().(Config).EmbeddedInMake() {
829 suffix = "-soong"
830 }
831
Colin Cross1f8c52b2015-06-16 16:38:17 -0700832 // Create a top-level checkbuild target that depends on all modules
833 ctx.Build(pctx, blueprint.BuildParams{
834 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800835 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700836 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700837 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700838 })
839
840 // Create a mm/<directory> target that depends on all modules in a directory
841 dirs := sortedKeys(dirModules)
842 for _, dir := range dirs {
843 ctx.Build(pctx, blueprint.BuildParams{
844 Rule: blueprint.Phony,
845 Outputs: []string{filepath.Join("mm", dir)},
846 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800847 // HACK: checkbuild should be an optional build, but force it
848 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800849 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700850 })
851 }
852}
Colin Crossd779da42015-12-17 18:00:23 -0800853
854type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700855 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800856 ctx interface {
857 ModuleName(blueprint.Module) string
858 ModuleSubDir(blueprint.Module) string
859 }
860}
861
862func (s AndroidModulesByName) Len() int { return len(s.slice) }
863func (s AndroidModulesByName) Less(i, j int) bool {
864 mi, mj := s.slice[i], s.slice[j]
865 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
866
867 if ni != nj {
868 return ni < nj
869 } else {
870 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
871 }
872}
873func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }