blob: 3c09b3eae8e71bba56b5f5a604e6b70651e155eb [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 Cross3edeee12017-04-04 12:59:48 -070060 Windows() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070061 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070062 PrimaryArch() bool
Dan Willemsen11b26142017-03-19 18:30:37 -070063 Proprietary() bool
Colin Cross1332b002015-04-07 17:11:30 -070064 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070065 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070066}
67
Colin Cross635c3b02016-05-18 15:37:25 -070068type BaseContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -070069 blueprint.BaseModuleContext
70 androidBaseContext
71}
72
Colin Cross635c3b02016-05-18 15:37:25 -070073type ModuleContext interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080074 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070075 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080076
Dan Willemsen34cc69e2015-09-23 15:26:20 -070077 // Similar to Build, but takes Paths instead of []string,
78 // and performs more verification.
79 ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -070080
Dan Willemsen34cc69e2015-09-23 15:26:20 -070081 ExpandSources(srcFiles, excludes []string) Paths
Colin Crossfaeb7aa2017-02-01 14:12:44 -080082 ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
Colin Cross7f19f372016-11-01 11:10:25 -070083 Glob(globPattern string, excludes []string) Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -070084
Colin Crossa2344662016-03-24 13:14:12 -070085 InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
86 InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -080087 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -070088 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -080089
90 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -070091
Colin Cross8d8f8e22016-08-03 11:57:50 -070092 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -070093 InstallInSanitizerDir() bool
Nan Zhang6d34b302017-02-04 17:47:46 -080094
95 RequiredModuleNames() []string
Colin Cross3f40fa42015-01-30 17:27:36 -080096}
97
Colin Cross635c3b02016-05-18 15:37:25 -070098type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080099 blueprint.Module
100
Colin Cross635c3b02016-05-18 15:37:25 -0700101 GenerateAndroidBuildActions(ModuleContext)
Colin Cross1e676be2016-10-12 14:38:15 -0700102 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800103
Colin Cross635c3b02016-05-18 15:37:25 -0700104 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800105 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700106 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800107 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700108 InstallInSanitizerDir() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800109 SkipInstall()
Colin Cross3f40fa42015-01-30 17:27:36 -0800110}
111
Colin Crossfc754582016-05-17 16:34:16 -0700112type nameProperties struct {
113 // The name of the module. Must be unique across all modules.
Colin Crossc77f9d12015-04-02 13:54:39 -0700114 Name string
Colin Crossfc754582016-05-17 16:34:16 -0700115}
116
117type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700118 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800119
Dan Willemsen0effe062015-11-30 16:06:01 -0800120 // emit build rules for this module
121 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800122
Colin Cross7d5136f2015-05-11 13:39:40 -0700123 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800124 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
125 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
126 // platform
Colin Cross69617d32016-09-06 10:39:07 -0700127 Compile_multilib string `android:"arch_variant"`
128
129 Target struct {
130 Host struct {
131 Compile_multilib string
132 }
133 Android struct {
134 Compile_multilib string
135 }
136 }
137
138 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800139
Dan Willemsen782a2d12015-12-21 14:55:28 -0800140 // whether this is a proprietary vendor module, and should be installed into /vendor
141 Proprietary bool
142
Colin Cross55708f32017-03-20 13:23:34 -0700143 // vendor who owns this module
144 Owner string
145
Dan Willemsen0fda89f2016-06-01 15:25:32 -0700146 // *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
147 // file
148 Logtags []string
149
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700150 // init.rc files to be installed if this module is installed
151 Init_rc []string
152
Chris Wolfe998306e2016-08-15 14:47:23 -0400153 // names of other modules to install if this module is installed
154 Required []string
155
Colin Crossa1ad8d12016-06-01 17:09:44 -0700156 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700157 CompileTarget Target `blueprint:"mutated"`
158 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800159
160 // Set by InitAndroidModule
161 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700162 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700163
164 SkipInstall bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800165}
166
167type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700168 Host_supported *bool
169 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800170}
171
Colin Crossc472d572015-03-17 15:06:21 -0700172type Multilib string
173
174const (
Dan Willemsen218f6562015-07-08 18:13:11 -0700175 MultilibBoth Multilib = "both"
176 MultilibFirst Multilib = "first"
177 MultilibCommon Multilib = "common"
178 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700179)
180
Colin Crossa1ad8d12016-06-01 17:09:44 -0700181type HostOrDeviceSupported int
182
183const (
184 _ HostOrDeviceSupported = iota
185 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700186 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700187 DeviceSupported
188 HostAndDeviceSupported
189 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700190 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700191)
192
Colin Cross635c3b02016-05-18 15:37:25 -0700193func InitAndroidModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800194 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
195
196 base := m.base()
197 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700198
Colin Crossfc754582016-05-17 16:34:16 -0700199 propertyStructs = append(propertyStructs,
200 &base.nameProperties,
201 &base.commonProperties,
202 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700203
204 return m, propertyStructs
205}
206
Colin Cross635c3b02016-05-18 15:37:25 -0700207func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib,
Colin Cross5049f022015-03-18 13:28:46 -0700208 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
209
210 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
211
212 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800213 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700214 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700215 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800216
Dan Willemsen218f6562015-07-08 18:13:11 -0700217 switch hod {
218 case HostAndDeviceSupported:
Colin Cross3f40fa42015-01-30 17:27:36 -0800219 // Default to module to device supported, host not supported, can override in module
220 // properties
Colin Crossa4190c12016-07-12 13:11:25 -0700221 base.hostAndDeviceProperties.Device_supported = boolPtr(true)
Dan Willemsen218f6562015-07-08 18:13:11 -0700222 fallthrough
223 case HostAndDeviceDefault:
Colin Cross3f40fa42015-01-30 17:27:36 -0800224 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
225 }
226
Colin Crosscfad1192015-11-02 16:43:11 -0800227 return InitArchModule(m, propertyStructs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800228}
229
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800230// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800231// modules. It should be included as an anonymous field in every module
232// struct definition. InitAndroidModule should then be called from the module's
233// factory function, and the return values from InitAndroidModule should be
234// returned from the factory function.
235//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800236// The ModuleBase type is responsible for implementing the GenerateBuildActions
237// method to support the blueprint.Module interface. This method will then call
238// the module's GenerateAndroidBuildActions method once for each build variant
239// that is to be built. GenerateAndroidBuildActions is passed a
240// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800241// AndroidModuleContext exposes extra functionality specific to the Android build
242// system including details about the particular build variant that is to be
243// generated.
244//
245// For example:
246//
247// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800248// "android/soong/android"
Colin Cross70b40592015-03-23 12:57:34 -0700249// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800250// )
251//
252// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800253// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800254// properties struct {
255// MyProperty string
256// }
257// }
258//
259// func NewMyModule() (blueprint.Module, []interface{}) {
260// m := &myModule{}
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800261// return android.InitAndroidModule(m, &m.properties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800262// }
263//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800264// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800265// // Get the CPU architecture for the current build variant.
266// variantArch := ctx.Arch()
267//
268// // ...
269// }
Colin Cross635c3b02016-05-18 15:37:25 -0700270type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800271 // Putting the curiously recurring thing pointing to the thing that contains
272 // the thing pattern to good use.
Colin Cross635c3b02016-05-18 15:37:25 -0700273 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800274
Colin Crossfc754582016-05-17 16:34:16 -0700275 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800276 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700277 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800278 hostAndDeviceProperties hostAndDeviceProperties
279 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700280 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700281 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800282
283 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700284 installFiles Paths
285 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700286
287 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
288 // Only set on the final variant of each module
289 installTarget string
290 checkbuildTarget string
291 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700292
Colin Cross178a5092016-09-13 13:42:32 -0700293 hooks hooks
Colin Cross3f40fa42015-01-30 17:27:36 -0800294}
295
Colin Crossce75d2c2016-10-06 16:12:58 -0700296// Name returns the name of the module. It may be overridden by individual module types, for
297// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700298func (a *ModuleBase) Name() string {
299 return a.nameProperties.Name
300}
301
Colin Crossce75d2c2016-10-06 16:12:58 -0700302// BaseModuleName returns the name of the module as specified in the blueprints file.
303func (a *ModuleBase) BaseModuleName() string {
304 return a.nameProperties.Name
305}
306
Colin Cross635c3b02016-05-18 15:37:25 -0700307func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800308 return a
309}
310
Colin Cross8b74d172016-09-13 09:59:14 -0700311func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700312 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700313 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700314}
315
Colin Crossa1ad8d12016-06-01 17:09:44 -0700316func (a *ModuleBase) Target() Target {
317 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800318}
319
Colin Cross8b74d172016-09-13 09:59:14 -0700320func (a *ModuleBase) TargetPrimary() bool {
321 return a.commonProperties.CompilePrimary
322}
323
Colin Crossa1ad8d12016-06-01 17:09:44 -0700324func (a *ModuleBase) Os() OsType {
325 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800326}
327
Colin Cross635c3b02016-05-18 15:37:25 -0700328func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700329 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800330}
331
Colin Cross635c3b02016-05-18 15:37:25 -0700332func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700333 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800334}
335
Dan Willemsen0b24c742016-10-04 15:13:37 -0700336func (a *ModuleBase) ArchSpecific() bool {
337 return a.commonProperties.ArchSpecific
338}
339
Colin Crossa1ad8d12016-06-01 17:09:44 -0700340func (a *ModuleBase) OsClassSupported() []OsClass {
341 switch a.commonProperties.HostOrDeviceSupported {
342 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700343 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700344 case HostSupportedNoCross:
345 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700346 case DeviceSupported:
347 return []OsClass{Device}
348 case HostAndDeviceSupported:
349 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700350 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700351 supported = append(supported, Host, HostCross)
352 }
Colin Crossa4190c12016-07-12 13:11:25 -0700353 if Bool(a.hostAndDeviceProperties.Device_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700354 supported = append(supported, Device)
355 }
356 return supported
357 default:
358 return nil
359 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800360}
361
Colin Cross635c3b02016-05-18 15:37:25 -0700362func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800363 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
364 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Colin Crossa4190c12016-07-12 13:11:25 -0700365 Bool(a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800366}
367
Colin Cross635c3b02016-05-18 15:37:25 -0700368func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800369 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800370 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800371 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800372 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800373}
374
Colin Crossce75d2c2016-10-06 16:12:58 -0700375func (a *ModuleBase) SkipInstall() {
376 a.commonProperties.SkipInstall = true
377}
378
Colin Cross635c3b02016-05-18 15:37:25 -0700379func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700380 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800381
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700382 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800383 ctx.VisitDepsDepthFirstIf(isFileInstaller,
384 func(m blueprint.Module) {
385 fileInstaller := m.(fileInstaller)
386 files := fileInstaller.filesToInstall()
387 result = append(result, files...)
388 })
389
390 return result
391}
392
Colin Cross635c3b02016-05-18 15:37:25 -0700393func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800394 return a.installFiles
395}
396
Colin Cross635c3b02016-05-18 15:37:25 -0700397func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800398 return p.noAddressSanitizer
399}
400
Colin Cross635c3b02016-05-18 15:37:25 -0700401func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800402 return false
403}
404
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700405func (p *ModuleBase) InstallInSanitizerDir() bool {
406 return false
407}
408
Colin Cross635c3b02016-05-18 15:37:25 -0700409func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700410 allInstalledFiles := Paths{}
411 allCheckbuildFiles := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800412 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700413 a := module.(Module).base()
Colin Crossc9404352015-03-26 16:10:12 -0700414 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
415 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800416 })
417
Colin Cross9454bfa2015-03-17 13:24:18 -0700418 deps := []string{}
419
Colin Cross3f40fa42015-01-30 17:27:36 -0800420 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700421 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800422 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700423 Rule: blueprint.Phony,
424 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700425 Implicits: allInstalledFiles.Strings(),
Colin Cross346aa132015-12-17 17:19:51 -0800426 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700427 })
428 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700429 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700430 }
431
432 if len(allCheckbuildFiles) > 0 {
433 name := ctx.ModuleName() + "-checkbuild"
434 ctx.Build(pctx, blueprint.BuildParams{
435 Rule: blueprint.Phony,
436 Outputs: []string{name},
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700437 Implicits: allCheckbuildFiles.Strings(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700438 Optional: true,
439 })
440 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700441 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700442 }
443
444 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800445 suffix := ""
446 if ctx.Config().(Config).EmbeddedInMake() {
447 suffix = "-soong"
448 }
449
Colin Cross9454bfa2015-03-17 13:24:18 -0700450 ctx.Build(pctx, blueprint.BuildParams{
451 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800452 Outputs: []string{ctx.ModuleName() + suffix},
Colin Cross9454bfa2015-03-17 13:24:18 -0700453 Implicits: deps,
454 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800455 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700456
457 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800458 }
459}
460
Colin Cross635c3b02016-05-18 15:37:25 -0700461func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700462 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700463 target: a.commonProperties.CompileTarget,
464 targetPrimary: a.commonProperties.CompilePrimary,
Dan Willemsen11b26142017-03-19 18:30:37 -0700465 proprietary: a.commonProperties.Proprietary,
Colin Cross8b74d172016-09-13 09:59:14 -0700466 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800467 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800468}
469
Colin Cross635c3b02016-05-18 15:37:25 -0700470func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800471 androidCtx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700472 module: a.module,
Colin Cross6362e272015-10-29 15:25:03 -0700473 ModuleContext: ctx,
474 androidBaseContextImpl: a.androidBaseContextFactory(ctx),
475 installDeps: a.computeInstallDeps(ctx),
476 installFiles: a.installFiles,
Colin Cross6ff51382015-12-17 16:39:19 -0800477 missingDeps: ctx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800478 }
479
Colin Cross9b1d13d2016-09-19 15:18:11 -0700480 if a.Enabled() {
481 a.module.GenerateAndroidBuildActions(androidCtx)
482 if ctx.Failed() {
483 return
484 }
485
486 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
487 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800488 }
489
Colin Cross9b1d13d2016-09-19 15:18:11 -0700490 if a == ctx.FinalModule().(Module).base() {
491 a.generateModuleTarget(ctx)
492 if ctx.Failed() {
493 return
494 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800495 }
496}
497
Colin Crossf6566ed2015-03-24 11:13:38 -0700498type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700499 target Target
500 targetPrimary bool
501 debug bool
Dan Willemsen11b26142017-03-19 18:30:37 -0700502 proprietary bool
Colin Cross8b74d172016-09-13 09:59:14 -0700503 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700504}
505
Colin Cross3f40fa42015-01-30 17:27:36 -0800506type androidModuleContext struct {
507 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700508 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700509 installDeps Paths
510 installFiles Paths
511 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800512 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700513 module Module
Colin Cross6ff51382015-12-17 16:39:19 -0800514}
515
516func (a *androidModuleContext) ninjaError(outputs []string, err error) {
517 a.ModuleContext.Build(pctx, blueprint.BuildParams{
518 Rule: ErrorRule,
519 Outputs: outputs,
520 Optional: true,
521 Args: map[string]string{
522 "error": err.Error(),
523 },
524 })
525 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800526}
527
Dan Willemsen14e5c2a2015-11-30 13:59:34 -0800528func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
Colin Cross7f19f372016-11-01 11:10:25 -0700529 if a.missingDeps != nil {
Colin Cross6ff51382015-12-17 16:39:19 -0800530 a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
531 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
532 return
533 }
534
Colin Cross3f40fa42015-01-30 17:27:36 -0800535 params.Optional = true
536 a.ModuleContext.Build(pctx, params)
537}
538
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700539func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
540 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700541 Rule: params.Rule,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800542 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700543 Outputs: params.Outputs.Strings(),
544 ImplicitOutputs: params.ImplicitOutputs.Strings(),
545 Inputs: params.Inputs.Strings(),
546 Implicits: params.Implicits.Strings(),
547 OrderOnly: params.OrderOnly.Strings(),
548 Args: params.Args,
549 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700550 }
551
Colin Cross33bfb0a2016-11-21 17:23:08 -0800552 if params.Depfile != nil {
553 bparams.Depfile = params.Depfile.String()
554 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700555 if params.Output != nil {
556 bparams.Outputs = append(bparams.Outputs, params.Output.String())
557 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700558 if params.ImplicitOutput != nil {
559 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
560 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700561 if params.Input != nil {
562 bparams.Inputs = append(bparams.Inputs, params.Input.String())
563 }
564 if params.Implicit != nil {
565 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
566 }
567
Colin Cross6ff51382015-12-17 16:39:19 -0800568 if a.missingDeps != nil {
569 a.ninjaError(bparams.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
570 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
571 return
572 }
573
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700574 a.ModuleContext.Build(pctx, bparams)
575}
576
Colin Cross6ff51382015-12-17 16:39:19 -0800577func (a *androidModuleContext) GetMissingDependencies() []string {
578 return a.missingDeps
579}
580
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800581func (a *androidModuleContext) AddMissingDependencies(deps []string) {
582 if deps != nil {
583 a.missingDeps = append(a.missingDeps, deps...)
584 }
585}
586
Colin Crossa1ad8d12016-06-01 17:09:44 -0700587func (a *androidBaseContextImpl) Target() Target {
588 return a.target
589}
590
Colin Cross8b74d172016-09-13 09:59:14 -0700591func (a *androidBaseContextImpl) TargetPrimary() bool {
592 return a.targetPrimary
593}
594
Colin Crossf6566ed2015-03-24 11:13:38 -0700595func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700596 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800597}
598
Colin Crossa1ad8d12016-06-01 17:09:44 -0700599func (a *androidBaseContextImpl) Os() OsType {
600 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800601}
602
Colin Crossf6566ed2015-03-24 11:13:38 -0700603func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700604 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700605}
606
607func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700608 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700609}
610
Colin Cross0af4b842015-04-30 16:36:18 -0700611func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700612 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700613}
614
Colin Cross3edeee12017-04-04 12:59:48 -0700615func (a *androidBaseContextImpl) Windows() bool {
616 return a.target.Os == Windows
617}
618
Colin Crossf6566ed2015-03-24 11:13:38 -0700619func (a *androidBaseContextImpl) Debug() bool {
620 return a.debug
621}
622
Colin Cross1e7d3702016-08-24 15:25:47 -0700623func (a *androidBaseContextImpl) PrimaryArch() bool {
624 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
625}
626
Colin Cross1332b002015-04-07 17:11:30 -0700627func (a *androidBaseContextImpl) AConfig() Config {
628 return a.config
629}
630
Colin Cross9272ade2016-08-17 15:24:12 -0700631func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
632 return DeviceConfig{a.config.deviceConfig}
633}
634
Dan Willemsen11b26142017-03-19 18:30:37 -0700635func (a *androidBaseContextImpl) Proprietary() bool {
636 return a.proprietary
Dan Willemsen782a2d12015-12-21 14:55:28 -0800637}
638
Colin Cross8d8f8e22016-08-03 11:57:50 -0700639func (a *androidModuleContext) InstallInData() bool {
640 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800641}
642
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700643func (a *androidModuleContext) InstallInSanitizerDir() bool {
644 return a.module.InstallInSanitizerDir()
645}
646
Dan Willemsen782a2d12015-12-21 14:55:28 -0800647func (a *androidModuleContext) InstallFileName(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -0700648 deps ...Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -0700649
Dan Willemsen782a2d12015-12-21 14:55:28 -0800650 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700651 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -0800652
Colin Crossce75d2c2016-10-06 16:12:58 -0700653 if !a.module.base().commonProperties.SkipInstall &&
Dan Willemsen0e2d97b2016-11-28 17:50:06 -0800654 (!a.Device() || !a.AConfig().SkipDeviceInstall()) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700655
Dan Willemsen322acaf2016-01-12 23:07:05 -0800656 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -0700657
Colin Cross89562dc2016-10-03 17:47:19 -0700658 var implicitDeps, orderOnlyDeps Paths
659
660 if a.Host() {
661 // Installed host modules might be used during the build, depend directly on their
662 // dependencies so their timestamp is updated whenever their dependency is updated
663 implicitDeps = deps
664 } else {
665 orderOnlyDeps = deps
666 }
667
Dan Willemsen322acaf2016-01-12 23:07:05 -0800668 a.ModuleBuild(pctx, ModuleBuildParams{
669 Rule: Cp,
670 Output: fullInstallPath,
671 Input: srcPath,
Colin Cross89562dc2016-10-03 17:47:19 -0700672 Implicits: implicitDeps,
673 OrderOnly: orderOnlyDeps,
Dan Willemsen7f730fd2016-01-14 11:22:23 -0800674 Default: !a.AConfig().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -0800675 })
Colin Cross3f40fa42015-01-30 17:27:36 -0800676
Dan Willemsen322acaf2016-01-12 23:07:05 -0800677 a.installFiles = append(a.installFiles, fullInstallPath)
678 }
Colin Cross1f8c52b2015-06-16 16:38:17 -0700679 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700680 return fullInstallPath
681}
682
Colin Crossa2344662016-03-24 13:14:12 -0700683func (a *androidModuleContext) InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700684 return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800685}
686
Colin Cross3854a602016-01-11 12:49:11 -0800687func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
688 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -0700689 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -0800690
Colin Crossce75d2c2016-10-06 16:12:58 -0700691 if !a.module.base().commonProperties.SkipInstall &&
Dan Willemsen0e2d97b2016-11-28 17:50:06 -0800692 (!a.Device() || !a.AConfig().SkipDeviceInstall()) {
Colin Crossce75d2c2016-10-06 16:12:58 -0700693
Colin Cross12fc4972016-01-11 12:49:11 -0800694 a.ModuleBuild(pctx, ModuleBuildParams{
695 Rule: Symlink,
696 Output: fullInstallPath,
697 OrderOnly: Paths{srcPath},
698 Default: !a.AConfig().EmbeddedInMake(),
699 Args: map[string]string{
700 "fromPath": srcPath.String(),
701 },
702 })
Colin Cross3854a602016-01-11 12:49:11 -0800703
Colin Cross12fc4972016-01-11 12:49:11 -0800704 a.installFiles = append(a.installFiles, fullInstallPath)
705 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
706 }
Colin Cross3854a602016-01-11 12:49:11 -0800707 return fullInstallPath
708}
709
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700710func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800711 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
712}
713
Colin Cross3f40fa42015-01-30 17:27:36 -0800714type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700715 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -0800716}
717
718func isFileInstaller(m blueprint.Module) bool {
719 _, ok := m.(fileInstaller)
720 return ok
721}
722
723func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -0700724 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -0800725 return ok
726}
Colin Crossfce53272015-04-08 11:21:40 -0700727
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700728func findStringInSlice(str string, slice []string) int {
729 for i, s := range slice {
730 if s == str {
731 return i
Colin Crossfce53272015-04-08 11:21:40 -0700732 }
733 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700734 return -1
735}
736
Colin Cross068e0fe2016-12-13 15:23:47 -0800737func SrcIsModule(s string) string {
738 if len(s) > 1 && s[0] == ':' {
739 return s[1:]
740 }
741 return ""
742}
743
744type sourceDependencyTag struct {
745 blueprint.BaseDependencyTag
746}
747
748var SourceDepTag sourceDependencyTag
749
750// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
751// modules listed in srcFiles using ":module" syntax
752func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
753 var deps []string
754 for _, s := range srcFiles {
755 if m := SrcIsModule(s); m != "" {
756 deps = append(deps, m)
757 }
758 }
759
760 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
761}
762
763type SourceFileProducer interface {
764 Srcs() Paths
765}
766
767// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800768// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700769func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800770 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
771}
772
773func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700774 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800775
Dan Willemsen2ef08f42015-06-30 18:15:24 -0700776 for i, e := range excludes {
777 j := findStringInSlice(e, srcFiles)
778 if j != -1 {
779 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
780 }
781
782 excludes[i] = filepath.Join(prefix, e)
783 }
784
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800785 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -0700786 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -0800787 if m := SrcIsModule(s); m != "" {
788 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
789 if srcProducer, ok := module.(SourceFileProducer); ok {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800790 expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
Colin Cross068e0fe2016-12-13 15:23:47 -0800791 } else {
792 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
793 }
794 } else if pathtools.IsGlob(s) {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800795 globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
796 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
797 for i, s := range expandedSrcFiles {
798 expandedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
799 }
Colin Cross8f101b42015-06-17 15:09:06 -0700800 } else {
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800801 s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
802 expandedSrcFiles = append(expandedSrcFiles, s)
Colin Cross8f101b42015-06-17 15:09:06 -0700803 }
804 }
805
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800806 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -0700807}
808
Nan Zhang6d34b302017-02-04 17:47:46 -0800809func (ctx *androidModuleContext) RequiredModuleNames() []string {
810 return ctx.module.base().commonProperties.Required
811}
812
Colin Cross7f19f372016-11-01 11:10:25 -0700813func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
814 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -0700815 if err != nil {
816 ctx.ModuleErrorf("glob: %s", err.Error())
817 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700818 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -0700819}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700820
Colin Cross463a90e2015-06-17 14:20:06 -0700821func init() {
Colin Cross798bfce2016-10-12 14:28:16 -0700822 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -0700823}
824
Colin Cross1f8c52b2015-06-16 16:38:17 -0700825func BuildTargetSingleton() blueprint.Singleton {
826 return &buildTargetSingleton{}
827}
828
829type buildTargetSingleton struct{}
830
831func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
832 checkbuildDeps := []string{}
833
834 dirModules := make(map[string][]string)
835
836 ctx.VisitAllModules(func(module blueprint.Module) {
Colin Cross635c3b02016-05-18 15:37:25 -0700837 if a, ok := module.(Module); ok {
Colin Cross1f8c52b2015-06-16 16:38:17 -0700838 blueprintDir := a.base().blueprintDir
839 installTarget := a.base().installTarget
840 checkbuildTarget := a.base().checkbuildTarget
841
842 if checkbuildTarget != "" {
843 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
844 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
845 }
846
847 if installTarget != "" {
848 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
849 }
850 }
851 })
852
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800853 suffix := ""
854 if ctx.Config().(Config).EmbeddedInMake() {
855 suffix = "-soong"
856 }
857
Colin Cross1f8c52b2015-06-16 16:38:17 -0700858 // Create a top-level checkbuild target that depends on all modules
859 ctx.Build(pctx, blueprint.BuildParams{
860 Rule: blueprint.Phony,
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800861 Outputs: []string{"checkbuild" + suffix},
Colin Cross1f8c52b2015-06-16 16:38:17 -0700862 Implicits: checkbuildDeps,
Dan Willemsen218f6562015-07-08 18:13:11 -0700863 Optional: true,
Colin Cross1f8c52b2015-06-16 16:38:17 -0700864 })
865
866 // Create a mm/<directory> target that depends on all modules in a directory
867 dirs := sortedKeys(dirModules)
868 for _, dir := range dirs {
869 ctx.Build(pctx, blueprint.BuildParams{
870 Rule: blueprint.Phony,
871 Outputs: []string{filepath.Join("mm", dir)},
872 Implicits: dirModules[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800873 // HACK: checkbuild should be an optional build, but force it
874 // enabled for now in standalone builds
Colin Cross1604ecf2015-12-17 16:33:43 -0800875 Optional: ctx.Config().(Config).EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -0700876 })
877 }
878}
Colin Crossd779da42015-12-17 18:00:23 -0800879
880type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -0700881 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -0800882 ctx interface {
883 ModuleName(blueprint.Module) string
884 ModuleSubDir(blueprint.Module) string
885 }
886}
887
888func (s AndroidModulesByName) Len() int { return len(s.slice) }
889func (s AndroidModulesByName) Less(i, j int) bool {
890 mi, mj := s.slice[i], s.slice[j]
891 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
892
893 if ni != nj {
894 return ni < nj
895 } else {
896 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
897 }
898}
899func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }