blob: 7b35d32f0e5244d17164f03512db9765b3912610 [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
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
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700140 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
141 // file
142 Logtags []string
143
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700144 // init.rc files to be installed if this module is installed
145 Init_rc []string
146
Chris Wolfe998306e2016-08-15 14:47:23 -0400147 // names of other modules to install if this module is installed
148 Required []string
149
Colin Crossa1ad8d12016-06-01 17:09:44 -0700150 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700151 CompileTarget Target `blueprint:"mutated"`
152 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800153
154 // Set by InitAndroidModule
155 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700156 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700157
158 SkipInstall bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800159}
160
161type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700162 Host_supported *bool
163 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800164}
165
Colin Crossc472d572015-03-17 15:06:21 -0700166type Multilib string
167
168const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700169 MultilibBoth Multilib = "both"
170 MultilibFirst Multilib = "first"
171 MultilibCommon Multilib = "common"
172 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700173)
174
Colin Crossa1ad8d12016-06-01 17:09:44 -0700175type HostOrDeviceSupported int
176
177const (
178 _ HostOrDeviceSupported = iota
179 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700180 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700181 DeviceSupported
182 HostAndDeviceSupported
183 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700184 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700185)
186
Colin Cross635c3b02016-05-18 15:37:25 -0700187func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800188 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
189
190 base := m.base()
191 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700192
Colin Crossfc754582016-05-17 16:34:16 -0700193 propertyStructs = append(propertyStructs,
194 &base.nameProperties,
195 &base.commonProperties,
196 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700197
198 return m, propertyStructs
199}
200
Colin Cross635c3b02016-05-18 15:37:25 -0700201func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700202 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
203
204 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
205
206 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800207 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700208 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700209 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800210
Dan Willemsen218f6562015-07-08 18:13:11 -0700211 switch hod {
212 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800213 // Default to module to device supported, host not supported, can override in module
214 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700215 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700216 fallthrough
217 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800218 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
219 }
220
Colin Crosscfad1192015-11-02 16:43:11 -0800221 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800222}
223
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800224// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800225// modules. It should be included as an anonymous field in every module
226// struct definition. InitAndroidModule should then be called from the module's
227// factory function, and the return values from InitAndroidModule should be
228// returned from the factory function.
229//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800230// The ModuleBase type is responsible for implementing the GenerateBuildActions
231// method to support the blueprint.Module interface. This method will then call
232// the module's GenerateAndroidBuildActions method once for each build variant
233// that is to be built. GenerateAndroidBuildActions is passed a
234// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800235// AndroidModuleContext exposes extra functionality specific to the Android build
236// system including details about the particular build variant that is to be
237// generated.
238//
239// For example:
240//
241// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800242// "android/soong/android"
Colin Cross70b40592015-03-23 12:57:34 -0700243// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800244// )
245//
246// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800247// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800248// properties struct {
249// MyProperty string
250// }
251// }
252//
253// func NewMyModule() (blueprint.Module, []interface{}) {
254// m := &myModule{}
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800255// return android.InitAndroidModule(m, &m.properties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800256// }
257//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800258// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800259// // Get the CPU architecture for the current build variant.
260// variantArch := ctx.Arch()
261//
262// // ...
263// }
Colin Cross635c3b02016-05-18 15:37:25 -0700264type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800265 // Putting the curiously recurring thing pointing to the thing that contains
266 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700267 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800268
Colin Crossfc754582016-05-17 16:34:16 -0700269 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800270 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700271 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800272 hostAndDeviceProperties hostAndDeviceProperties
273 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700274 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700275 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800276
277 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700278 installFiles Paths
279 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700280
281 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
282 // Only set on the final variant of each module
283 installTarget string
284 checkbuildTarget string
285 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700286
Colin Cross178a5092016-09-13 13:42:32 -0700287 hooks hooks
Colin Cross3f40fa42015-01-30 17:27:36 -0800288}
289
Colin Crossce75d2c2016-10-06 16:12:58 -0700290// Name returns the name of the module. It may be overridden by individual module types, for
291// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700292func (a *ModuleBase) Name() string {
293 return a.nameProperties.Name
294}
295
Colin Crossce75d2c2016-10-06 16:12:58 -0700296// BaseModuleName returns the name of the module as specified in the blueprints file.
297func (a *ModuleBase) BaseModuleName() string {
298 return a.nameProperties.Name
299}
300
Colin Cross635c3b02016-05-18 15:37:25 -0700301func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800302 return a
303}
304
Colin Cross8b74d172016-09-13 09:59:14 -0700305func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700306 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700307 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700308}
309
Colin Crossa1ad8d12016-06-01 17:09:44 -0700310func (a *ModuleBase) Target() Target {
311 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800312}
313
Colin Cross8b74d172016-09-13 09:59:14 -0700314func (a *ModuleBase) TargetPrimary() bool {
315 return a.commonProperties.CompilePrimary
316}
317
Colin Crossa1ad8d12016-06-01 17:09:44 -0700318func (a *ModuleBase) Os() OsType {
319 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800320}
321
Colin Cross635c3b02016-05-18 15:37:25 -0700322func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700323 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800324}
325
Colin Cross635c3b02016-05-18 15:37:25 -0700326func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700327 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800328}
329
Dan Willemsen0b24c742016-10-04 15:13:37 -0700330func (a *ModuleBase) ArchSpecific() bool {
331 return a.commonProperties.ArchSpecific
332}
333
Colin Crossa1ad8d12016-06-01 17:09:44 -0700334func (a *ModuleBase) OsClassSupported() []OsClass {
335 switch a.commonProperties.HostOrDeviceSupported {
336 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700337 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700338 case HostSupportedNoCross:
339 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700340 case DeviceSupported:
341 return []OsClass{Device}
342 case HostAndDeviceSupported:
343 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700344 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700345 supported = append(supported, Host, HostCross)
346 }
Colin Crossa4190c12016-07-12 13:11:25 -0700347 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700348 supported = append(supported, Device)
349 }
350 return supported
351 default:
352 return nil
353 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800354}
355
Colin Cross635c3b02016-05-18 15:37:25 -0700356func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800357 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
358 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700359 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800360}
361
Colin Cross635c3b02016-05-18 15:37:25 -0700362func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800363 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800364 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800365 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800366 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800367}
368
Colin Crossce75d2c2016-10-06 16:12:58 -0700369func (a *ModuleBase) SkipInstall() {
370 a.commonProperties.SkipInstall = true
371}
372
Colin Cross635c3b02016-05-18 15:37:25 -0700373func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700374 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800375
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700376 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800377 ctx.VisitDepsDepthFirstIf(isFileInstaller,
378 func(m blueprint.Module) {
379 fileInstaller := m.(fileInstaller)
380 files := fileInstaller.filesToInstall()
381 result = append(result, files...)
382 })
383
384 return result
385}
386
Colin Cross635c3b02016-05-18 15:37:25 -0700387func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800388 return a.installFiles
389}
390
Colin Cross635c3b02016-05-18 15:37:25 -0700391func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800392 return p.noAddressSanitizer
393}
394
Colin Cross635c3b02016-05-18 15:37:25 -0700395func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800396 return false
397}
398
Colin Cross635c3b02016-05-18 15:37:25 -0700399func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700400 allInstalledFiles := Paths{}
401 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800402 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700403 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700404 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
405 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800406 })
407
Colin Cross9454bfa2015-03-17 13:24:18 -0700408 deps := []string{}
409
Colin Cross3f40fa42015-01-30 17:27:36 -0800410 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700411 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800412 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700413 Rule: blueprint.Phony,
414 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700415 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800416 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700417 })
418 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700419 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700420 }
421
422 if len(allCheckbuildFiles) > 0 {
423 name := ctx.ModuleName() + "-checkbuild"
424 ctx.Build(pctx, blueprint.BuildParams{
425 Rule: blueprint.Phony,
426 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700427 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700428 Optional: true,
429 })
430 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700431 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700432 }
433
434 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800435 suffix := ""
436 if ctx.Config().(Config).EmbeddedInMake() {
437 suffix = "-soong"
438 }
439
Colin Cross9454bfa2015-03-17 13:24:18 -0700440 ctx.Build(pctx, blueprint.BuildParams{
441 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800442 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700443 Implicits: deps,
444 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800445 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700446
447 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800448 }
449}
450
Colin Cross635c3b02016-05-18 15:37:25 -0700451func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700452 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700453 target: a.commonProperties.CompileTarget,
454 targetPrimary: a.commonProperties.CompilePrimary,
455 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800456 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800457}
458
Colin Cross635c3b02016-05-18 15:37:25 -0700459func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800460 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700461 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700462 ModuleContext: ctx,
463 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
464 installDeps: a.computeInstallDeps(ctx),
465 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800466 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800467 }
468
Colin Cross9b1d13d2016-09-19 15:18:11 -0700469 if a.Enabled() {
470 a.module.GenerateAndroidBuildActions(androidCtx)
471 if ctx.Failed() {
472 return
473 }
474
475 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
476 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800477 }
478
Colin Cross9b1d13d2016-09-19 15:18:11 -0700479 if a == ctx.FinalModule().(Module).base() {
480 a.generateModuleTarget(ctx)
481 if ctx.Failed() {
482 return
483 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800484 }
485}
486
Colin Crossf6566ed2015-03-24 11:13:38 -0700487type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700488 target Target
489 targetPrimary bool
490 debug bool
491 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700492}
493
Colin Cross3f40fa42015-01-30 17:27:36 -0800494type androidModuleContext struct {
495 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700496 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700497 installDeps Paths
498 installFiles Paths
499 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800500 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700501 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800502}
503
504func (a *androidModuleContext) ninjaError(outputs []string, err error) {
505 a.ModuleContext.Build(pctx, blueprint.BuildParams{
506 Rule: ErrorRule,
507 Outputs: outputs,
508 Optional: true,
509 Args: map[string]string{
510 "error": err.Error(),
511 },
512 })
513 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800514}
515
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800516func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Cross7f19f372016-11-01 11:10:25 -0700517 if a.missingDeps != nil {
Colin Cross6ff51382015-12-17 16:39:19 -0800518 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
519 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
520 return
521 }
522
Colin Cross3f40fa42015-01-30 17:27:36 -0800523 params.Optional = true
524 a.ModuleContext.Build(pctx, params)
525}
526
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700527func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
528 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700529 Rule: params.Rule,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800530 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700531 Outputs: params.Outputs.Strings(),
532 ImplicitOutputs: params.ImplicitOutputs.Strings(),
533 Inputs: params.Inputs.Strings(),
534 Implicits: params.Implicits.Strings(),
535 OrderOnly: params.OrderOnly.Strings(),
536 Args: params.Args,
537 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700538 }
539
Colin Cross33bfb0a2016-11-21 17:23:08 -0800540 if params.Depfile != nil {
541 bparams.Depfile = params.Depfile.String()
542 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700543 if params.Output != nil {
544 bparams.Outputs = append(bparams.Outputs, params.Output.String())
545 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700546 if params.ImplicitOutput != nil {
547 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
548 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700549 if params.Input != nil {
550 bparams.Inputs = append(bparams.Inputs, params.Input.String())
551 }
552 if params.Implicit != nil {
553 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
554 }
555
Colin Cross6ff51382015-12-17 16:39:19 -0800556 if a.missingDeps != nil {
557 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
558 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
559 return
560 }
561
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700562 a.ModuleContext.Build(pctx, bparams)
563}
564
Colin Cross6ff51382015-12-17 16:39:19 -0800565func (a *androidModuleContext) GetMissingDependencies() []string {
566 return a.missingDeps
567}
568
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800569func (a *androidModuleContext) AddMissingDependencies(deps []string) {
570 if deps != nil {
571 a.missingDeps = append(a.missingDeps, deps...)
572 }
573}
574
Colin Crossa1ad8d12016-06-01 17:09:44 -0700575func (a *androidBaseContextImpl) Target() Target {
576 return a.target
577}
578
Colin Cross8b74d172016-09-13 09:59:14 -0700579func (a *androidBaseContextImpl) TargetPrimary() bool {
580 return a.targetPrimary
581}
582
Colin Crossf6566ed2015-03-24 11:13:38 -0700583func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700584 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800585}
586
Colin Crossa1ad8d12016-06-01 17:09:44 -0700587func (a *androidBaseContextImpl) Os() OsType {
588 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800589}
590
Colin Crossf6566ed2015-03-24 11:13:38 -0700591func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700592 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700593}
594
595func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700596 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700597}
598
Colin Cross0af4b842015-04-30 16:36:18 -0700599func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700600 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700601}
602
Colin Crossf6566ed2015-03-24 11:13:38 -0700603func (a *androidBaseContextImpl) Debug() bool {
604 return a.debug
605}
606
Colin Cross1e7d3702016-08-24 15:25:47 -0700607func (a *androidBaseContextImpl) PrimaryArch() bool {
608 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
609}
610
Colin Cross1332b002015-04-07 17:11:30 -0700611func (a *androidBaseContextImpl) AConfig() Config {
612 return a.config
613}
614
Colin Cross9272ade2016-08-17 15:24:12 -0700615func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
616 return DeviceConfig{a.config.deviceConfig}
617}
618
Colin Cross8d8f8e22016-08-03 11:57:50 -0700619func (a *androidModuleContext) Proprietary() bool {
620 return a.module.base().commonProperties.Proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800621}
622
Colin Cross8d8f8e22016-08-03 11:57:50 -0700623func (a *androidModuleContext) InstallInData() bool {
624 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800625}
626
627func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700628 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700629
Dan Willemsen782a2d12015-12-21 14:55:28 -0800630 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700631 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800632
Colin Crossce75d2c2016-10-06 16:12:58 -0700633 if !a.module.base().commonProperties.SkipInstall &&
634 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
635
Dan Willemsen322acaf2016-01-12 23:07:05 -0800636 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700637
Colin Cross89562dc2016-10-03 17:47:19 -0700638 var implicitDeps, orderOnlyDeps Paths
639
640 if a.Host() {
641 // Installed host modules might be used during the build, depend directly on their
642 // dependencies so their timestamp is updated whenever their dependency is updated
643 implicitDeps = deps
644 } else {
645 orderOnlyDeps = deps
646 }
647
Dan Willemsen322acaf2016-01-12 23:07:05 -0800648 a.ModuleBuild(pctx, ModuleBuildParams{
649 Rule: Cp,
650 Output: fullInstallPath,
651 Input: srcPath,
Colin Cross89562dc2016-10-03 17:47:19 -0700652 Implicits: implicitDeps,
653 OrderOnly: orderOnlyDeps,
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800654 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800655 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800656
Dan Willemsen322acaf2016-01-12 23:07:05 -0800657 a.installFiles = append(a.installFiles, fullInstallPath)
658 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700659 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700660 return fullInstallPath
661}
662
Colin Crossa2344662016-03-24 13:14:12 -0700663func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700664 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800665}
666
Colin Cross3854a602016-01-11 12:49:11 -0800667func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
668 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700669 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800670
Colin Crossce75d2c2016-10-06 16:12:58 -0700671 if !a.module.base().commonProperties.SkipInstall &&
672 (a.Host() || !a.AConfig().SkipDeviceInstall()) {
673
Colin Cross12fc4972016-01-11 12:49:11 -0800674 a.ModuleBuild(pctx, ModuleBuildParams{
675 Rule: Symlink,
676 Output: fullInstallPath,
677 OrderOnly: Paths{srcPath},
678 Default: !a.AConfig().EmbeddedInMake(),
679 Args: map[string]string{
680 "fromPath": srcPath.String(),
681 },
682 })
Colin Cross3854a602016-01-11 12:49:11 -0800683
Colin Cross12fc4972016-01-11 12:49:11 -0800684 a.installFiles = append(a.installFiles, fullInstallPath)
685 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
686 }
Colin Cross3854a602016-01-11 12:49:11 -0800687 return fullInstallPath
688}
689
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700690func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800691 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
692}
693
Colin Cross3f40fa42015-01-30 17:27:36 -0800694type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700695 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800696}
697
698func isFileInstaller(m blueprint.Module) bool {
699 _, ok := m.(fileInstaller)
700 return ok
701}
702
703func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700704 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800705 return ok
706}
Colin Crossfce53272015-04-08 11:21:40 -0700707
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700708func findStringInSlice(str string, slice []string) int {
709 for i, s := range slice {
710 if s == str {
711 return i
Colin Crossfce53272015-04-08 11:21:40 -0700712 }
713 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700714 return -1
715}
716
Colin Cross068e0fe2016-12-13 15:23:47 -0800717func SrcIsModule(s string) string {
718 if len(s) > 1 && s[0] == ':' {
719 return s[1:]
720 }
721 return ""
722}
723
724type sourceDependencyTag struct {
725 blueprint.BaseDependencyTag
726}
727
728var SourceDepTag sourceDependencyTag
729
730// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
731// modules listed in srcFiles using ":module" syntax
732func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
733 var deps []string
734 for _, s := range srcFiles {
735 if m := SrcIsModule(s); m != "" {
736 deps = append(deps, m)
737 }
738 }
739
740 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
741}
742
743type SourceFileProducer interface {
744 Srcs() Paths
745}
746
747// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800748// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700749func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800750 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
751}
752
753func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700754 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800755
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700756 for i, e := range excludes {
757 j := findStringInSlice(e, srcFiles)
758 if j != -1 {
759 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
760 }
761
762 excludes[i] = filepath.Join(prefix, e)
763 }
764
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800765 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700766 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -0800767 if m := SrcIsModule(s); m != "" {
768 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
769 if srcProducer, ok := module.(SourceFileProducer); ok {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800770 expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
Colin Cross068e0fe2016-12-13 15:23:47 -0800771 } else {
772 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
773 }
774 } else if pathtools.IsGlob(s) {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800775 globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
776 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
777 for i, s := range expandedSrcFiles {
778 expandedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
779 }
Colin Cross8f101b42015-06-17 15:09:06 -0700780 } else {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800781 s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
782 expandedSrcFiles = append(expandedSrcFiles, s)
Colin Cross8f101b42015-06-17 15:09:06 -0700783 }
784 }
785
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800786 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -0700787}
788
Nan Zhang6d34b302017-02-04 17:47:46 -0800789func (ctx *androidModuleContext) RequiredModuleNames() []string {
790 return ctx.module.base().commonProperties.Required
791}
792
Colin Cross7f19f372016-11-01 11:10:25 -0700793func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
794 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700795 if err != nil {
796 ctx.ModuleErrorf("glob: %s", err.Error())
797 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700798 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700799}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700800
Colin Cross463a90e2015-06-17 14:20:06 -0700801func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700802 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700803}
804
Colin Cross1f8c52b2015-06-16 16:38:17 -0700805func BuildTargetSingleton() blueprint.Singleton {
806 return &buildTargetSingleton{}
807}
808
809type buildTargetSingleton struct{}
810
811func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
812 checkbuildDeps := []string{}
813
814 dirModules := make(map[string][]string)
815
816 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700817 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700818 blueprintDir := a.base().blueprintDir
819 installTarget := a.base().installTarget
820 checkbuildTarget := a.base().checkbuildTarget
821
822 if checkbuildTarget != "" {
823 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
824 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
825 }
826
827 if installTarget != "" {
828 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
829 }
830 }
831 })
832
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800833 suffix := ""
834 if ctx.Config().(Config).EmbeddedInMake() {
835 suffix = "-soong"
836 }
837
Colin Cross1f8c52b2015-06-16 16:38:17 -0700838 // Create a top-level checkbuild target that depends on all modules
839 ctx.Build(pctx, blueprint.BuildParams{
840 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800841 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700842 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700843 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700844 })
845
846 // Create a mm/<directory> target that depends on all modules in a directory
847 dirs := sortedKeys(dirModules)
848 for _, dir := range dirs {
849 ctx.Build(pctx, blueprint.BuildParams{
850 Rule: blueprint.Phony,
851 Outputs: []string{filepath.Join("mm", dir)},
852 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800853 // HACK: checkbuild should be an optional build, but force it
854 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800855 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700856 })
857 }
858}
Colin Crossd779da42015-12-17 18:00:23 -0800859
860type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700861 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800862 ctx interface {
863 ModuleName(blueprint.Module) string
864 ModuleSubDir(blueprint.Module) string
865 }
866}
867
868func (s AndroidModulesByName) Len() int { return len(s.slice) }
869func (s AndroidModulesByName) Less(i, j int) bool {
870 mi, mj := s.slice[i], s.slice[j]
871 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
872
873 if ni != nj {
874 return ni < nj
875 } else {
876 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
877 }
878}
879func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }