blob: 0fb9479630755b0a4d9d12003a3780fe155868a9 [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 Cross0875c522017-11-28 17:34:01 -080020 "sort"
Colin Cross6ff51382015-12-17 16:39:19 -080021 "strings"
Colin Crossaabf6792017-11-29 00:27:14 -080022 "text/scanner"
Colin Crossf6566ed2015-03-24 11:13:38 -070023
24 "github.com/google/blueprint"
Colin Cross7f19f372016-11-01 11:10:25 -070025 "github.com/google/blueprint/pathtools"
Colin Cross3f40fa42015-01-30 17:27:36 -080026)
27
28var (
29 DeviceSharedLibrary = "shared_library"
30 DeviceStaticLibrary = "static_library"
31 DeviceExecutable = "executable"
32 HostSharedLibrary = "host_shared_library"
33 HostStaticLibrary = "host_static_library"
34 HostExecutable = "host_executable"
35)
36
Colin Crossae887032017-10-23 17:16:14 -070037type BuildParams struct {
Dan Willemsen9f3c5742016-11-03 14:28:31 -070038 Rule blueprint.Rule
Colin Cross33bfb0a2016-11-21 17:23:08 -080039 Deps blueprint.Deps
40 Depfile WritablePath
Colin Cross67a5c132017-05-09 13:45:28 -070041 Description string
Dan Willemsen9f3c5742016-11-03 14:28:31 -070042 Output WritablePath
43 Outputs WritablePaths
44 ImplicitOutput WritablePath
45 ImplicitOutputs WritablePaths
46 Input Path
47 Inputs Paths
48 Implicit Path
49 Implicits Paths
50 OrderOnly Paths
51 Default bool
52 Args map[string]string
Dan Willemsen34cc69e2015-09-23 15:26:20 -070053}
54
Colin Crossae887032017-10-23 17:16:14 -070055type ModuleBuildParams BuildParams
56
Colin Crossf6566ed2015-03-24 11:13:38 -070057type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070058 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -070059 TargetPrimary() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070060 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070061 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070062 Host() bool
63 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070064 Darwin() bool
Colin Cross3edeee12017-04-04 12:59:48 -070065 Windows() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070066 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070067 PrimaryArch() bool
Jiyong Park2db76922017-11-08 16:03:48 +090068 Platform() bool
69 DeviceSpecific() bool
70 SocSpecific() bool
71 ProductSpecific() bool
Colin Cross1332b002015-04-07 17:11:30 -070072 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070073 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070074}
75
Colin Cross635c3b02016-05-18 15:37:25 -070076type BaseContext interface {
Colin Crossaabf6792017-11-29 00:27:14 -080077 BaseModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070078 androidBaseContext
79}
80
Colin Crossaabf6792017-11-29 00:27:14 -080081// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
82// a Config instead of an interface{}.
83type BaseModuleContext interface {
84 ModuleName() string
85 ModuleDir() string
86 Config() Config
87
88 ContainsProperty(name string) bool
89 Errorf(pos scanner.Position, fmt string, args ...interface{})
90 ModuleErrorf(fmt string, args ...interface{})
91 PropertyErrorf(property, fmt string, args ...interface{})
92 Failed() bool
93
94 // GlobWithDeps returns a list of files that match the specified pattern but do not match any
95 // of the patterns in excludes. It also adds efficient dependencies to rerun the primary
96 // builder whenever a file matching the pattern as added or removed, without rerunning if a
97 // file that does not match the pattern is added to a searched directory.
98 GlobWithDeps(pattern string, excludes []string) ([]string, error)
99
100 Fs() pathtools.FileSystem
101 AddNinjaFileDeps(deps ...string)
102}
103
Colin Cross635c3b02016-05-18 15:37:25 -0700104type ModuleContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -0700105 androidBaseContext
Colin Crossaabf6792017-11-29 00:27:14 -0800106 BaseModuleContext
Colin Cross3f40fa42015-01-30 17:27:36 -0800107
Colin Crossae887032017-10-23 17:16:14 -0700108 // Deprecated: use ModuleContext.Build instead.
Colin Cross0875c522017-11-28 17:34:01 -0800109 ModuleBuild(pctx PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -0700110
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700111 ExpandSources(srcFiles, excludes []string) Paths
Colin Cross366938f2017-12-11 16:29:02 -0800112 ExpandSource(srcFile, prop string) Path
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800113 ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
Colin Cross7f19f372016-11-01 11:10:25 -0700114 Glob(globPattern string, excludes []string) Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700115
Colin Cross5c517922017-08-31 12:29:17 -0700116 InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
117 InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -0800118 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700119 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800120
121 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -0700122
Colin Cross8d8f8e22016-08-03 11:57:50 -0700123 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700124 InstallInSanitizerDir() bool
Nan Zhang6d34b302017-02-04 17:47:46 -0800125
126 RequiredModuleNames() []string
Colin Cross3f68a132017-10-23 17:10:29 -0700127
128 // android.ModuleContext methods
129 // These are duplicated instead of embedded so that can eventually be wrapped to take an
130 // android.Module instead of a blueprint.Module
131 OtherModuleName(m blueprint.Module) string
132 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
133 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
134
135 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
136 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
137
138 ModuleSubDir() string
139
Colin Cross35143d02017-11-16 00:11:20 -0800140 VisitDirectDepsBlueprint(visit func(blueprint.Module))
Colin Crossd11fcda2017-10-23 17:59:01 -0700141 VisitDirectDeps(visit func(Module))
Colin Crossee6143c2017-12-30 17:54:27 -0800142 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
Colin Crossd11fcda2017-10-23 17:59:01 -0700143 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
144 VisitDepsDepthFirst(visit func(Module))
145 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
146 WalkDeps(visit func(Module, Module) bool)
Colin Cross3f68a132017-10-23 17:10:29 -0700147
Colin Cross0875c522017-11-28 17:34:01 -0800148 Variable(pctx PackageContext, name, value string)
149 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
Colin Crossae887032017-10-23 17:16:14 -0700150 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
151 // and performs more verification.
Colin Cross0875c522017-11-28 17:34:01 -0800152 Build(pctx PackageContext, params BuildParams)
Colin Cross3f68a132017-10-23 17:10:29 -0700153
Colin Cross0875c522017-11-28 17:34:01 -0800154 PrimaryModule() Module
155 FinalModule() Module
156 VisitAllModuleVariants(visit func(Module))
Colin Cross3f68a132017-10-23 17:10:29 -0700157
158 GetMissingDependencies() []string
Jeff Gaston088e29e2017-11-29 16:47:17 -0800159 Namespace() blueprint.Namespace
Colin Cross3f40fa42015-01-30 17:27:36 -0800160}
161
Colin Cross635c3b02016-05-18 15:37:25 -0700162type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800163 blueprint.Module
164
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700165 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
166 // but GenerateAndroidBuildActions also has access to Android-specific information.
167 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -0700168 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700169
Colin Cross1e676be2016-10-12 14:38:15 -0700170 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800171
Colin Cross635c3b02016-05-18 15:37:25 -0700172 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800173 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700174 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800175 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700176 InstallInSanitizerDir() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800177 SkipInstall()
Colin Cross36242852017-06-23 15:06:31 -0700178
179 AddProperties(props ...interface{})
180 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700181
Colin Crossae887032017-10-23 17:16:14 -0700182 BuildParamsForTests() []BuildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800183}
184
Colin Crossfc754582016-05-17 16:34:16 -0700185type nameProperties struct {
186 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800187 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700188}
189
190type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -0700191 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800192
Dan Willemsen0effe062015-11-30 16:06:01 -0800193 // emit build rules for this module
194 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800195
Colin Cross7d5136f2015-05-11 13:39:40 -0700196 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800197 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
198 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
199 // platform
Colin Cross7d716ba2017-11-01 10:38:29 -0700200 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700201
202 Target struct {
203 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700204 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700205 }
206 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700207 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700208 }
209 }
210
211 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800212
Dan Willemsen782a2d12015-12-21 14:55:28 -0800213 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700214 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800215
Colin Cross55708f32017-03-20 13:23:34 -0700216 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700217 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700218
Jiyong Park2db76922017-11-08 16:03:48 +0900219 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
220 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
221 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700222 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700223
Jiyong Park2db76922017-11-08 16:03:48 +0900224 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
225 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
226 Soc_specific *bool
227
228 // whether this module is specific to a device, not only for SoC, but also for off-chip
229 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
230 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
231 // This implies `soc_specific:true`.
232 Device_specific *bool
233
234 // whether this module is specific to a software configuration of a product (e.g. country,
235 // network operator, etc). When set to true, it is installed into /oem (or /system/oem if
236 // oem partition does not exist).
237 Product_specific *bool
238
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700239 // init.rc files to be installed if this module is installed
240 Init_rc []string
241
Chris Wolfe998306e2016-08-15 14:47:23 -0400242 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700243 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400244
Colin Cross5aac3622017-08-31 15:07:09 -0700245 // relative path to a file to include in the list of notices for the device
246 Notice *string
247
Colin Crossa1ad8d12016-06-01 17:09:44 -0700248 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700249 CompileTarget Target `blueprint:"mutated"`
250 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800251
252 // Set by InitAndroidModule
253 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700254 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700255
256 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800257
258 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800259}
260
261type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700262 Host_supported *bool
263 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800264}
265
Colin Crossc472d572015-03-17 15:06:21 -0700266type Multilib string
267
268const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800269 MultilibBoth Multilib = "both"
270 MultilibFirst Multilib = "first"
271 MultilibCommon Multilib = "common"
272 MultilibCommonFirst Multilib = "common_first"
273 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700274)
275
Colin Crossa1ad8d12016-06-01 17:09:44 -0700276type HostOrDeviceSupported int
277
278const (
279 _ HostOrDeviceSupported = iota
280 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700281 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700282 DeviceSupported
283 HostAndDeviceSupported
284 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700285 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700286)
287
Jiyong Park2db76922017-11-08 16:03:48 +0900288type moduleKind int
289
290const (
291 platformModule moduleKind = iota
292 deviceSpecificModule
293 socSpecificModule
294 productSpecificModule
295)
296
297func (k moduleKind) String() string {
298 switch k {
299 case platformModule:
300 return "platform"
301 case deviceSpecificModule:
302 return "device-specific"
303 case socSpecificModule:
304 return "soc-specific"
305 case productSpecificModule:
306 return "product-specific"
307 default:
308 panic(fmt.Errorf("unknown module kind %d", k))
309 }
310}
311
Colin Cross36242852017-06-23 15:06:31 -0700312func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800313 base := m.base()
314 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700315
Colin Cross36242852017-06-23 15:06:31 -0700316 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700317 &base.nameProperties,
318 &base.commonProperties,
319 &base.variableProperties)
Colin Cross5049f022015-03-18 13:28:46 -0700320}
321
Colin Cross36242852017-06-23 15:06:31 -0700322func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
323 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700324
325 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800326 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700327 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700328 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800329
Dan Willemsen218f6562015-07-08 18:13:11 -0700330 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700331 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700332 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800333 }
334
Colin Cross36242852017-06-23 15:06:31 -0700335 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800336}
337
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800338// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800339// modules. It should be included as an anonymous field in every module
340// struct definition. InitAndroidModule should then be called from the module's
341// factory function, and the return values from InitAndroidModule should be
342// returned from the factory function.
343//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800344// The ModuleBase type is responsible for implementing the GenerateBuildActions
345// method to support the blueprint.Module interface. This method will then call
346// the module's GenerateAndroidBuildActions method once for each build variant
347// that is to be built. GenerateAndroidBuildActions is passed a
348// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800349// AndroidModuleContext exposes extra functionality specific to the Android build
350// system including details about the particular build variant that is to be
351// generated.
352//
353// For example:
354//
355// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800356// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800357// )
358//
359// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800360// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800361// properties struct {
362// MyProperty string
363// }
364// }
365//
Colin Cross36242852017-06-23 15:06:31 -0700366// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800367// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700368// m.AddProperties(&m.properties)
369// android.InitAndroidModule(m)
370// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800371// }
372//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800373// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800374// // Get the CPU architecture for the current build variant.
375// variantArch := ctx.Arch()
376//
377// // ...
378// }
Colin Cross635c3b02016-05-18 15:37:25 -0700379type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800380 // Putting the curiously recurring thing pointing to the thing that contains
381 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700382 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700383 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800384
Colin Crossfc754582016-05-17 16:34:16 -0700385 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800386 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700387 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800388 hostAndDeviceProperties hostAndDeviceProperties
389 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700390 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700391 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800392
393 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700394 installFiles Paths
395 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700396
397 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
398 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800399 installTarget WritablePath
400 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700401 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700402
Colin Cross178a5092016-09-13 13:42:32 -0700403 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700404
405 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700406
407 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700408 buildParams []BuildParams
Colin Cross36242852017-06-23 15:06:31 -0700409}
410
411func (a *ModuleBase) AddProperties(props ...interface{}) {
412 a.registerProps = append(a.registerProps, props...)
413}
414
415func (a *ModuleBase) GetProperties() []interface{} {
416 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800417}
418
Colin Crossae887032017-10-23 17:16:14 -0700419func (a *ModuleBase) BuildParamsForTests() []BuildParams {
Colin Crosscec81712017-07-13 14:43:27 -0700420 return a.buildParams
421}
422
Colin Crossce75d2c2016-10-06 16:12:58 -0700423// Name returns the name of the module. It may be overridden by individual module types, for
424// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700425func (a *ModuleBase) Name() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800426 return String(a.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700427}
428
Colin Crossce75d2c2016-10-06 16:12:58 -0700429// BaseModuleName returns the name of the module as specified in the blueprints file.
430func (a *ModuleBase) BaseModuleName() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800431 return String(a.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700432}
433
Colin Cross635c3b02016-05-18 15:37:25 -0700434func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800435 return a
436}
437
Colin Cross8b74d172016-09-13 09:59:14 -0700438func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700439 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700440 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700441}
442
Colin Crossa1ad8d12016-06-01 17:09:44 -0700443func (a *ModuleBase) Target() Target {
444 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800445}
446
Colin Cross8b74d172016-09-13 09:59:14 -0700447func (a *ModuleBase) TargetPrimary() bool {
448 return a.commonProperties.CompilePrimary
449}
450
Colin Crossa1ad8d12016-06-01 17:09:44 -0700451func (a *ModuleBase) Os() OsType {
452 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800453}
454
Colin Cross635c3b02016-05-18 15:37:25 -0700455func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700456 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800457}
458
Colin Cross635c3b02016-05-18 15:37:25 -0700459func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700460 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800461}
462
Dan Willemsen0b24c742016-10-04 15:13:37 -0700463func (a *ModuleBase) ArchSpecific() bool {
464 return a.commonProperties.ArchSpecific
465}
466
Colin Crossa1ad8d12016-06-01 17:09:44 -0700467func (a *ModuleBase) OsClassSupported() []OsClass {
468 switch a.commonProperties.HostOrDeviceSupported {
469 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700470 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700471 case HostSupportedNoCross:
472 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700473 case DeviceSupported:
474 return []OsClass{Device}
475 case HostAndDeviceSupported:
476 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700477 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700478 supported = append(supported, Host, HostCross)
479 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700480 if a.hostAndDeviceProperties.Device_supported == nil ||
481 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700482 supported = append(supported, Device)
483 }
484 return supported
485 default:
486 return nil
487 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800488}
489
Colin Cross635c3b02016-05-18 15:37:25 -0700490func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800491 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
492 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700493 (a.hostAndDeviceProperties.Device_supported == nil ||
494 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800495}
496
Colin Cross635c3b02016-05-18 15:37:25 -0700497func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800498 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800499 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800500 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800501 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800502}
503
Colin Crossce75d2c2016-10-06 16:12:58 -0700504func (a *ModuleBase) SkipInstall() {
505 a.commonProperties.SkipInstall = true
506}
507
Colin Cross635c3b02016-05-18 15:37:25 -0700508func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700509 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800510
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700511 result := Paths{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800512 ctx.VisitDepsDepthFirstIf(isFileInstaller,
513 func(m blueprint.Module) {
514 fileInstaller := m.(fileInstaller)
515 files := fileInstaller.filesToInstall()
516 result = append(result, files...)
517 })
518
519 return result
520}
521
Colin Cross635c3b02016-05-18 15:37:25 -0700522func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800523 return a.installFiles
524}
525
Colin Cross635c3b02016-05-18 15:37:25 -0700526func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800527 return p.noAddressSanitizer
528}
529
Colin Cross635c3b02016-05-18 15:37:25 -0700530func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800531 return false
532}
533
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700534func (p *ModuleBase) InstallInSanitizerDir() bool {
535 return false
536}
537
Colin Cross0875c522017-11-28 17:34:01 -0800538func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700539 allInstalledFiles := Paths{}
540 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -0800541 ctx.VisitAllModuleVariants(func(module Module) {
542 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -0700543 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
544 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800545 })
546
Colin Cross0875c522017-11-28 17:34:01 -0800547 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -0700548
Jeff Gaston088e29e2017-11-29 16:47:17 -0800549 namespacePrefix := ctx.Namespace().(*Namespace).id
550 if namespacePrefix != "" {
551 namespacePrefix = namespacePrefix + "-"
552 }
553
Colin Cross3f40fa42015-01-30 17:27:36 -0800554 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800555 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -0800556 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700557 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800558 Output: name,
559 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -0800560 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700561 })
562 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700563 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700564 }
565
566 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800567 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -0800568 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700569 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800570 Output: name,
571 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -0700572 })
573 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700574 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700575 }
576
577 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800578 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -0800579 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800580 suffix = "-soong"
581 }
582
Jeff Gaston088e29e2017-11-29 16:47:17 -0800583 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -0800584 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700585 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -0800586 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -0700587 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800588 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700589
590 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800591 }
592}
593
Jiyong Park2db76922017-11-08 16:03:48 +0900594func determineModuleKind(a *ModuleBase, ctx blueprint.BaseModuleContext) moduleKind {
595 var socSpecific = Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
596 var deviceSpecific = Bool(a.commonProperties.Device_specific)
597 var productSpecific = Bool(a.commonProperties.Product_specific)
598
599 if ((socSpecific || deviceSpecific) && productSpecific) || (socSpecific && deviceSpecific) {
600 msg := "conflicting value set here"
601 if productSpecific {
602 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
603 if deviceSpecific {
604 ctx.PropertyErrorf("device_specific", msg)
605 }
606 } else {
607 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
608 }
609 if Bool(a.commonProperties.Vendor) {
610 ctx.PropertyErrorf("vendor", msg)
611 }
612 if Bool(a.commonProperties.Proprietary) {
613 ctx.PropertyErrorf("proprietary", msg)
614 }
615 if Bool(a.commonProperties.Soc_specific) {
616 ctx.PropertyErrorf("soc_specific", msg)
617 }
618 }
619
620 if productSpecific {
621 return productSpecificModule
622 } else if deviceSpecific {
623 return deviceSpecificModule
624 } else if socSpecific {
625 return socSpecificModule
626 } else {
627 return platformModule
628 }
629}
630
Colin Cross635c3b02016-05-18 15:37:25 -0700631func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700632 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700633 target: a.commonProperties.CompileTarget,
634 targetPrimary: a.commonProperties.CompilePrimary,
Jiyong Park2db76922017-11-08 16:03:48 +0900635 kind: determineModuleKind(a, ctx),
Colin Cross8b74d172016-09-13 09:59:14 -0700636 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800637 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800638}
639
Colin Cross0875c522017-11-28 17:34:01 -0800640func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
641 ctx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700642 module: a.module,
Colin Cross0875c522017-11-28 17:34:01 -0800643 ModuleContext: blueprintCtx,
644 androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
645 installDeps: a.computeInstallDeps(blueprintCtx),
Colin Cross6362e272015-10-29 15:25:03 -0700646 installFiles: a.installFiles,
Colin Cross0875c522017-11-28 17:34:01 -0800647 missingDeps: blueprintCtx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800648 }
649
Colin Cross67a5c132017-05-09 13:45:28 -0700650 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
651 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -0800652 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
653 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -0700654 }
Colin Cross0875c522017-11-28 17:34:01 -0800655 if !ctx.PrimaryArch() {
656 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -0700657 }
658
659 ctx.Variable(pctx, "moduleDesc", desc)
660
661 s := ""
662 if len(suffix) > 0 {
663 s = " [" + strings.Join(suffix, " ") + "]"
664 }
665 ctx.Variable(pctx, "moduleDescSuffix", s)
666
Colin Cross9b1d13d2016-09-19 15:18:11 -0700667 if a.Enabled() {
Colin Cross0875c522017-11-28 17:34:01 -0800668 a.module.GenerateAndroidBuildActions(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700669 if ctx.Failed() {
670 return
671 }
672
Colin Cross0875c522017-11-28 17:34:01 -0800673 a.installFiles = append(a.installFiles, ctx.installFiles...)
674 a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800675 }
676
Colin Cross9b1d13d2016-09-19 15:18:11 -0700677 if a == ctx.FinalModule().(Module).base() {
678 a.generateModuleTarget(ctx)
679 if ctx.Failed() {
680 return
681 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800682 }
Colin Crosscec81712017-07-13 14:43:27 -0700683
Colin Cross0875c522017-11-28 17:34:01 -0800684 a.buildParams = ctx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800685}
686
Colin Crossf6566ed2015-03-24 11:13:38 -0700687type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700688 target Target
689 targetPrimary bool
690 debug bool
Jiyong Park2db76922017-11-08 16:03:48 +0900691 kind moduleKind
Colin Cross8b74d172016-09-13 09:59:14 -0700692 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700693}
694
Colin Cross3f40fa42015-01-30 17:27:36 -0800695type androidModuleContext struct {
696 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700697 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700698 installDeps Paths
699 installFiles Paths
700 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800701 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700702 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700703
704 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700705 buildParams []BuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800706}
707
Colin Cross67a5c132017-05-09 13:45:28 -0700708func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross0875c522017-11-28 17:34:01 -0800709 a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700710 Rule: ErrorRule,
711 Description: desc,
712 Outputs: outputs,
713 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800714 Args: map[string]string{
715 "error": err.Error(),
716 },
717 })
718 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800719}
720
Colin Crossaabf6792017-11-29 00:27:14 -0800721func (a *androidModuleContext) Config() Config {
722 return a.ModuleContext.Config().(Config)
723}
724
Colin Cross0875c522017-11-28 17:34:01 -0800725func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
Colin Crossae887032017-10-23 17:16:14 -0700726 a.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800727}
728
Colin Cross0875c522017-11-28 17:34:01 -0800729func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700730 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700731 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -0800732 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800733 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700734 Outputs: params.Outputs.Strings(),
735 ImplicitOutputs: params.ImplicitOutputs.Strings(),
736 Inputs: params.Inputs.Strings(),
737 Implicits: params.Implicits.Strings(),
738 OrderOnly: params.OrderOnly.Strings(),
739 Args: params.Args,
740 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700741 }
742
Colin Cross33bfb0a2016-11-21 17:23:08 -0800743 if params.Depfile != nil {
744 bparams.Depfile = params.Depfile.String()
745 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700746 if params.Output != nil {
747 bparams.Outputs = append(bparams.Outputs, params.Output.String())
748 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700749 if params.ImplicitOutput != nil {
750 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
751 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700752 if params.Input != nil {
753 bparams.Inputs = append(bparams.Inputs, params.Input.String())
754 }
755 if params.Implicit != nil {
756 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
757 }
758
Colin Cross0875c522017-11-28 17:34:01 -0800759 return bparams
760}
761
762func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
763 a.ModuleContext.Variable(pctx.PackageContext, name, value)
764}
765
766func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
767 argNames ...string) blueprint.Rule {
768
769 return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
770}
771
772func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
773 if a.config.captureBuild {
774 a.buildParams = append(a.buildParams, params)
775 }
776
777 bparams := convertBuildParams(params)
778
779 if bparams.Description != "" {
780 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
781 }
782
Colin Cross6ff51382015-12-17 16:39:19 -0800783 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700784 a.ninjaError(bparams.Description, bparams.Outputs,
785 fmt.Errorf("module %s missing dependencies: %s\n",
786 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800787 return
788 }
789
Colin Cross0875c522017-11-28 17:34:01 -0800790 a.ModuleContext.Build(pctx.PackageContext, bparams)
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700791}
792
Colin Cross6ff51382015-12-17 16:39:19 -0800793func (a *androidModuleContext) GetMissingDependencies() []string {
794 return a.missingDeps
795}
796
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800797func (a *androidModuleContext) AddMissingDependencies(deps []string) {
798 if deps != nil {
799 a.missingDeps = append(a.missingDeps, deps...)
Colin Crossd11fcda2017-10-23 17:59:01 -0700800 a.missingDeps = FirstUniqueStrings(a.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800801 }
802}
803
Colin Crossd11fcda2017-10-23 17:59:01 -0700804func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
805 aModule, _ := module.(Module)
806 if aModule == nil {
807 a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
808 return nil
809 }
810
811 if !aModule.Enabled() {
Colin Cross6510f912017-11-29 00:27:14 -0800812 if a.Config().AllowMissingDependencies() {
Colin Crossd11fcda2017-10-23 17:59:01 -0700813 a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
814 } else {
815 a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
816 }
817 return nil
818 }
819
820 return aModule
821}
822
Colin Cross35143d02017-11-16 00:11:20 -0800823func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
824 a.ModuleContext.VisitDirectDeps(visit)
825}
826
Colin Crossd11fcda2017-10-23 17:59:01 -0700827func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
828 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
829 if aModule := a.validateAndroidModule(module); aModule != nil {
830 visit(aModule)
831 }
832 })
833}
834
Colin Crossee6143c2017-12-30 17:54:27 -0800835func (a *androidModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
836 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
837 if aModule := a.validateAndroidModule(module); aModule != nil {
838 if a.ModuleContext.OtherModuleDependencyTag(aModule) == tag {
839 visit(aModule)
840 }
841 }
842 })
843}
844
Colin Crossd11fcda2017-10-23 17:59:01 -0700845func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
846 a.ModuleContext.VisitDirectDepsIf(
847 // pred
848 func(module blueprint.Module) bool {
849 if aModule := a.validateAndroidModule(module); aModule != nil {
850 return pred(aModule)
851 } else {
852 return false
853 }
854 },
855 // visit
856 func(module blueprint.Module) {
857 visit(module.(Module))
858 })
859}
860
861func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
862 a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
863 if aModule := a.validateAndroidModule(module); aModule != nil {
864 visit(aModule)
865 }
866 })
867}
868
869func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
870 a.ModuleContext.VisitDepsDepthFirstIf(
871 // pred
872 func(module blueprint.Module) bool {
873 if aModule := a.validateAndroidModule(module); aModule != nil {
874 return pred(aModule)
875 } else {
876 return false
877 }
878 },
879 // visit
880 func(module blueprint.Module) {
881 visit(module.(Module))
882 })
883}
884
885func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
886 a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
887 childAndroidModule := a.validateAndroidModule(child)
888 parentAndroidModule := a.validateAndroidModule(parent)
889 if childAndroidModule != nil && parentAndroidModule != nil {
890 return visit(childAndroidModule, parentAndroidModule)
891 } else {
892 return false
893 }
894 })
895}
896
Colin Cross0875c522017-11-28 17:34:01 -0800897func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
898 a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
899 visit(module.(Module))
900 })
901}
902
903func (a *androidModuleContext) PrimaryModule() Module {
904 return a.ModuleContext.PrimaryModule().(Module)
905}
906
907func (a *androidModuleContext) FinalModule() Module {
908 return a.ModuleContext.FinalModule().(Module)
909}
910
Colin Crossa1ad8d12016-06-01 17:09:44 -0700911func (a *androidBaseContextImpl) Target() Target {
912 return a.target
913}
914
Colin Cross8b74d172016-09-13 09:59:14 -0700915func (a *androidBaseContextImpl) TargetPrimary() bool {
916 return a.targetPrimary
917}
918
Colin Crossf6566ed2015-03-24 11:13:38 -0700919func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700920 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800921}
922
Colin Crossa1ad8d12016-06-01 17:09:44 -0700923func (a *androidBaseContextImpl) Os() OsType {
924 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800925}
926
Colin Crossf6566ed2015-03-24 11:13:38 -0700927func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700928 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -0700929}
930
931func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700932 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -0700933}
934
Colin Cross0af4b842015-04-30 16:36:18 -0700935func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700936 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -0700937}
938
Colin Cross3edeee12017-04-04 12:59:48 -0700939func (a *androidBaseContextImpl) Windows() bool {
940 return a.target.Os == Windows
941}
942
Colin Crossf6566ed2015-03-24 11:13:38 -0700943func (a *androidBaseContextImpl) Debug() bool {
944 return a.debug
945}
946
Colin Cross1e7d3702016-08-24 15:25:47 -0700947func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -0700948 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
949 return true
950 }
Colin Cross1e7d3702016-08-24 15:25:47 -0700951 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
952}
953
Colin Cross1332b002015-04-07 17:11:30 -0700954func (a *androidBaseContextImpl) AConfig() Config {
955 return a.config
956}
957
Colin Cross9272ade2016-08-17 15:24:12 -0700958func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
959 return DeviceConfig{a.config.deviceConfig}
960}
961
Jiyong Park2db76922017-11-08 16:03:48 +0900962func (a *androidBaseContextImpl) Platform() bool {
963 return a.kind == platformModule
964}
965
966func (a *androidBaseContextImpl) DeviceSpecific() bool {
967 return a.kind == deviceSpecificModule
968}
969
970func (a *androidBaseContextImpl) SocSpecific() bool {
971 return a.kind == socSpecificModule
972}
973
974func (a *androidBaseContextImpl) ProductSpecific() bool {
975 return a.kind == productSpecificModule
Dan Willemsen782a2d12015-12-21 14:55:28 -0800976}
977
Colin Cross8d8f8e22016-08-03 11:57:50 -0700978func (a *androidModuleContext) InstallInData() bool {
979 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -0800980}
981
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700982func (a *androidModuleContext) InstallInSanitizerDir() bool {
983 return a.module.InstallInSanitizerDir()
984}
985
Colin Cross893d8162017-04-26 17:34:03 -0700986func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
987 if a.module.base().commonProperties.SkipInstall {
988 return true
989 }
990
991 if a.Device() {
Colin Cross6510f912017-11-29 00:27:14 -0800992 if a.Config().SkipDeviceInstall() {
Colin Cross893d8162017-04-26 17:34:03 -0700993 return true
994 }
995
Colin Cross6510f912017-11-29 00:27:14 -0800996 if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -0700997 return true
998 }
999 }
1000
1001 return false
1002}
1003
Colin Cross5c517922017-08-31 12:29:17 -07001004func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -07001005 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -07001006 return a.installFile(installPath, name, srcPath, Cp, deps)
1007}
1008
1009func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
1010 deps ...Path) OutputPath {
1011 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
1012}
1013
1014func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
1015 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -07001016
Dan Willemsen782a2d12015-12-21 14:55:28 -08001017 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001018 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -08001019
Colin Cross893d8162017-04-26 17:34:03 -07001020 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001021
Dan Willemsen322acaf2016-01-12 23:07:05 -08001022 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -07001023
Colin Cross89562dc2016-10-03 17:47:19 -07001024 var implicitDeps, orderOnlyDeps Paths
1025
1026 if a.Host() {
1027 // Installed host modules might be used during the build, depend directly on their
1028 // dependencies so their timestamp is updated whenever their dependency is updated
1029 implicitDeps = deps
1030 } else {
1031 orderOnlyDeps = deps
1032 }
1033
Colin Crossae887032017-10-23 17:16:14 -07001034 a.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -07001035 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -07001036 Description: "install " + fullInstallPath.Base(),
1037 Output: fullInstallPath,
1038 Input: srcPath,
1039 Implicits: implicitDeps,
1040 OrderOnly: orderOnlyDeps,
Colin Cross6510f912017-11-29 00:27:14 -08001041 Default: !a.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -08001042 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001043
Dan Willemsen322acaf2016-01-12 23:07:05 -08001044 a.installFiles = append(a.installFiles, fullInstallPath)
1045 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001046 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -07001047 return fullInstallPath
1048}
1049
Colin Cross3854a602016-01-11 12:49:11 -08001050func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
1051 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001052 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -08001053
Colin Cross893d8162017-04-26 17:34:03 -07001054 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001055
Colin Crossae887032017-10-23 17:16:14 -07001056 a.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -07001057 Rule: Symlink,
1058 Description: "install symlink " + fullInstallPath.Base(),
1059 Output: fullInstallPath,
1060 OrderOnly: Paths{srcPath},
Colin Cross6510f912017-11-29 00:27:14 -08001061 Default: !a.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -08001062 Args: map[string]string{
1063 "fromPath": srcPath.String(),
1064 },
1065 })
Colin Cross3854a602016-01-11 12:49:11 -08001066
Colin Cross12fc4972016-01-11 12:49:11 -08001067 a.installFiles = append(a.installFiles, fullInstallPath)
1068 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1069 }
Colin Cross3854a602016-01-11 12:49:11 -08001070 return fullInstallPath
1071}
1072
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001073func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001074 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1075}
1076
Colin Cross3f40fa42015-01-30 17:27:36 -08001077type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001078 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001079}
1080
1081func isFileInstaller(m blueprint.Module) bool {
1082 _, ok := m.(fileInstaller)
1083 return ok
1084}
1085
1086func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -07001087 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -08001088 return ok
1089}
Colin Crossfce53272015-04-08 11:21:40 -07001090
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001091func findStringInSlice(str string, slice []string) int {
1092 for i, s := range slice {
1093 if s == str {
1094 return i
Colin Crossfce53272015-04-08 11:21:40 -07001095 }
1096 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001097 return -1
1098}
1099
Colin Cross068e0fe2016-12-13 15:23:47 -08001100func SrcIsModule(s string) string {
1101 if len(s) > 1 && s[0] == ':' {
1102 return s[1:]
1103 }
1104 return ""
1105}
1106
1107type sourceDependencyTag struct {
1108 blueprint.BaseDependencyTag
1109}
1110
1111var SourceDepTag sourceDependencyTag
1112
Colin Cross366938f2017-12-11 16:29:02 -08001113// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
1114// using ":module" syntax, if any.
Colin Cross068e0fe2016-12-13 15:23:47 -08001115func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
1116 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -07001117 set := make(map[string]bool)
1118
Colin Cross068e0fe2016-12-13 15:23:47 -08001119 for _, s := range srcFiles {
1120 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -07001121 if _, found := set[m]; found {
1122 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
1123 } else {
1124 set[m] = true
1125 deps = append(deps, m)
1126 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001127 }
1128 }
1129
1130 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
1131}
1132
Colin Cross366938f2017-12-11 16:29:02 -08001133// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
1134// using ":module" syntax, if any.
1135func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
1136 if s != nil {
1137 if m := SrcIsModule(*s); m != "" {
1138 ctx.AddDependency(ctx.Module(), SourceDepTag, m)
1139 }
1140 }
1141}
1142
Colin Cross068e0fe2016-12-13 15:23:47 -08001143type SourceFileProducer interface {
1144 Srcs() Paths
1145}
1146
1147// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001148// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001149func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001150 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
1151}
1152
Colin Cross366938f2017-12-11 16:29:02 -08001153// Returns a single path expanded from globs and modules referenced using ":module" syntax.
1154// ExtractSourceDeps must have already been called during the dependency resolution phase.
1155func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path {
1156 srcFiles := ctx.ExpandSourcesSubDir([]string{srcFile}, nil, "")
1157 if len(srcFiles) == 1 {
1158 return srcFiles[0]
1159 } else {
1160 ctx.PropertyErrorf(prop, "module providing %s must produce exactly one file", prop)
1161 return nil
1162 }
1163}
1164
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001165func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001166 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001167
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001168 for i, e := range excludes {
1169 j := findStringInSlice(e, srcFiles)
1170 if j != -1 {
1171 srcFiles = append(srcFiles[:j], srcFiles[j+1:]...)
1172 }
1173
1174 excludes[i] = filepath.Join(prefix, e)
1175 }
1176
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001177 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -07001178 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -08001179 if m := SrcIsModule(s); m != "" {
1180 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
Colin Cross0617bb82017-10-24 13:01:18 -07001181 if module == nil {
1182 // Error will have been handled by ExtractSourcesDeps
1183 continue
1184 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001185 if srcProducer, ok := module.(SourceFileProducer); ok {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001186 expandedSrcFiles = append(expandedSrcFiles, srcProducer.Srcs()...)
Colin Cross068e0fe2016-12-13 15:23:47 -08001187 } else {
1188 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1189 }
1190 } else if pathtools.IsGlob(s) {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001191 globbedSrcFiles := ctx.Glob(filepath.Join(prefix, s), excludes)
Colin Cross05a39cb2017-10-09 13:35:19 -07001192 for i, s := range globbedSrcFiles {
1193 globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001194 }
Colin Cross05a39cb2017-10-09 13:35:19 -07001195 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
Colin Cross8f101b42015-06-17 15:09:06 -07001196 } else {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001197 s := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
1198 expandedSrcFiles = append(expandedSrcFiles, s)
Colin Cross8f101b42015-06-17 15:09:06 -07001199 }
1200 }
1201
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001202 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -07001203}
1204
Nan Zhang6d34b302017-02-04 17:47:46 -08001205func (ctx *androidModuleContext) RequiredModuleNames() []string {
1206 return ctx.module.base().commonProperties.Required
1207}
1208
Colin Cross7f19f372016-11-01 11:10:25 -07001209func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
1210 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001211 if err != nil {
1212 ctx.ModuleErrorf("glob: %s", err.Error())
1213 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001214 return pathsForModuleSrcFromFullPath(ctx, ret)
Colin Crossfce53272015-04-08 11:21:40 -07001215}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001216
Colin Cross463a90e2015-06-17 14:20:06 -07001217func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001218 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001219}
1220
Colin Cross0875c522017-11-28 17:34:01 -08001221func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001222 return &buildTargetSingleton{}
1223}
1224
Colin Cross87d8b562017-04-25 10:01:55 -07001225func parentDir(dir string) string {
1226 dir, _ = filepath.Split(dir)
1227 return filepath.Clean(dir)
1228}
1229
Colin Cross1f8c52b2015-06-16 16:38:17 -07001230type buildTargetSingleton struct{}
1231
Colin Cross0875c522017-11-28 17:34:01 -08001232func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1233 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07001234
Colin Cross0875c522017-11-28 17:34:01 -08001235 mmTarget := func(dir string) WritablePath {
1236 return PathForPhony(ctx,
1237 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07001238 }
1239
Colin Cross0875c522017-11-28 17:34:01 -08001240 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001241
Colin Cross0875c522017-11-28 17:34:01 -08001242 ctx.VisitAllModules(func(module Module) {
1243 blueprintDir := module.base().blueprintDir
1244 installTarget := module.base().installTarget
1245 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07001246
Colin Cross0875c522017-11-28 17:34:01 -08001247 if checkbuildTarget != nil {
1248 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1249 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1250 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001251
Colin Cross0875c522017-11-28 17:34:01 -08001252 if installTarget != nil {
1253 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001254 }
1255 })
1256
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001257 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001258 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001259 suffix = "-soong"
1260 }
1261
Colin Cross1f8c52b2015-06-16 16:38:17 -07001262 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08001263 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001264 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001265 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001266 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001267 })
1268
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001269 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08001270 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001271 return
1272 }
1273
Colin Cross0875c522017-11-28 17:34:01 -08001274 sortedKeys := func(m map[string]Paths) []string {
1275 s := make([]string, 0, len(m))
1276 for k := range m {
1277 s = append(s, k)
1278 }
1279 sort.Strings(s)
1280 return s
1281 }
1282
Colin Cross87d8b562017-04-25 10:01:55 -07001283 // Ensure ancestor directories are in modulesInDir
1284 dirs := sortedKeys(modulesInDir)
1285 for _, dir := range dirs {
1286 dir := parentDir(dir)
1287 for dir != "." && dir != "/" {
1288 if _, exists := modulesInDir[dir]; exists {
1289 break
1290 }
1291 modulesInDir[dir] = nil
1292 dir = parentDir(dir)
1293 }
1294 }
1295
1296 // Make directories build their direct subdirectories
1297 dirs = sortedKeys(modulesInDir)
1298 for _, dir := range dirs {
1299 p := parentDir(dir)
1300 if p != "." && p != "/" {
1301 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1302 }
1303 }
1304
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001305 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1306 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1307 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001308 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08001309 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001310 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001311 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07001312 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001313 // HACK: checkbuild should be an optional build, but force it
1314 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08001315 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001316 })
1317 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001318
1319 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1320 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001321 ctx.VisitAllModules(func(module Module) {
1322 if module.Enabled() {
1323 os := module.Target().Os
1324 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001325 }
1326 })
1327
Colin Cross0875c522017-11-28 17:34:01 -08001328 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001329 for os, deps := range osDeps {
1330 var className string
1331
1332 switch os.Class {
1333 case Host:
1334 className = "host"
1335 case HostCross:
1336 className = "host-cross"
1337 case Device:
1338 className = "target"
1339 default:
1340 continue
1341 }
1342
Colin Cross0875c522017-11-28 17:34:01 -08001343 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001344 osClass[className] = append(osClass[className], name)
1345
Colin Cross0875c522017-11-28 17:34:01 -08001346 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001347 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001348 Output: name,
1349 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07001350 })
1351 }
1352
1353 // Wrap those into host|host-cross|target phony rules
1354 osClasses := sortedKeys(osClass)
1355 for _, class := range osClasses {
Colin Cross0875c522017-11-28 17:34:01 -08001356 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001357 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001358 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07001359 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07001360 })
1361 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001362}
Colin Crossd779da42015-12-17 18:00:23 -08001363
1364type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -07001365 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -08001366 ctx interface {
1367 ModuleName(blueprint.Module) string
1368 ModuleSubDir(blueprint.Module) string
1369 }
1370}
1371
1372func (s AndroidModulesByName) Len() int { return len(s.slice) }
1373func (s AndroidModulesByName) Less(i, j int) bool {
1374 mi, mj := s.slice[i], s.slice[j]
1375 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1376
1377 if ni != nj {
1378 return ni < nj
1379 } else {
1380 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1381 }
1382}
1383func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }