blob: b58dd4b5f5eb8234ff666875b72a7a1085ce2ddc [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
Dario Frenifd05a742018-05-29 13:28:54 +010072 ProductServicesSpecific() bool
Colin Cross1332b002015-04-07 17:11:30 -070073 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070074 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070075}
76
Colin Cross635c3b02016-05-18 15:37:25 -070077type BaseContext interface {
Colin Crossaabf6792017-11-29 00:27:14 -080078 BaseModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070079 androidBaseContext
80}
81
Colin Crossaabf6792017-11-29 00:27:14 -080082// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
83// a Config instead of an interface{}.
84type BaseModuleContext interface {
85 ModuleName() string
86 ModuleDir() string
87 Config() Config
88
89 ContainsProperty(name string) bool
90 Errorf(pos scanner.Position, fmt string, args ...interface{})
91 ModuleErrorf(fmt string, args ...interface{})
92 PropertyErrorf(property, fmt string, args ...interface{})
93 Failed() bool
94
95 // GlobWithDeps returns a list of files that match the specified pattern but do not match any
96 // of the patterns in excludes. It also adds efficient dependencies to rerun the primary
97 // builder whenever a file matching the pattern as added or removed, without rerunning if a
98 // file that does not match the pattern is added to a searched directory.
99 GlobWithDeps(pattern string, excludes []string) ([]string, error)
100
101 Fs() pathtools.FileSystem
102 AddNinjaFileDeps(deps ...string)
103}
104
Colin Cross635c3b02016-05-18 15:37:25 -0700105type ModuleContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -0700106 androidBaseContext
Colin Crossaabf6792017-11-29 00:27:14 -0800107 BaseModuleContext
Colin Cross3f40fa42015-01-30 17:27:36 -0800108
Colin Crossae887032017-10-23 17:16:14 -0700109 // Deprecated: use ModuleContext.Build instead.
Colin Cross0875c522017-11-28 17:34:01 -0800110 ModuleBuild(pctx PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -0700111
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700112 ExpandSources(srcFiles, excludes []string) Paths
Colin Cross366938f2017-12-11 16:29:02 -0800113 ExpandSource(srcFile, prop string) Path
Colin Cross2383f3b2018-02-06 14:40:13 -0800114 ExpandOptionalSource(srcFile *string, prop string) OptionalPath
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800115 ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
Colin Cross7f19f372016-11-01 11:10:25 -0700116 Glob(globPattern string, excludes []string) Paths
Nan Zhang581fd212018-01-10 16:06:12 -0800117 GlobFiles(globPattern string, excludes []string) Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700118
Colin Cross5c517922017-08-31 12:29:17 -0700119 InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
120 InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -0800121 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700122 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800123
124 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -0700125
Colin Cross8d8f8e22016-08-03 11:57:50 -0700126 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700127 InstallInSanitizerDir() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +0900128 InstallInRecovery() bool
Nan Zhang6d34b302017-02-04 17:47:46 -0800129
130 RequiredModuleNames() []string
Colin Cross3f68a132017-10-23 17:10:29 -0700131
132 // android.ModuleContext methods
133 // These are duplicated instead of embedded so that can eventually be wrapped to take an
134 // android.Module instead of a blueprint.Module
135 OtherModuleName(m blueprint.Module) string
136 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
137 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
138
139 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
140 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
141
142 ModuleSubDir() string
143
Colin Cross35143d02017-11-16 00:11:20 -0800144 VisitDirectDepsBlueprint(visit func(blueprint.Module))
Colin Crossd11fcda2017-10-23 17:59:01 -0700145 VisitDirectDeps(visit func(Module))
Colin Crossee6143c2017-12-30 17:54:27 -0800146 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
Colin Crossd11fcda2017-10-23 17:59:01 -0700147 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
Colin Cross6b753602018-06-21 13:03:07 -0700148 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
Colin Crossd11fcda2017-10-23 17:59:01 -0700149 VisitDepsDepthFirst(visit func(Module))
Colin Cross6b753602018-06-21 13:03:07 -0700150 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
Colin Crossd11fcda2017-10-23 17:59:01 -0700151 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
152 WalkDeps(visit func(Module, Module) bool)
Colin Cross3f68a132017-10-23 17:10:29 -0700153
Colin Cross0875c522017-11-28 17:34:01 -0800154 Variable(pctx PackageContext, name, value string)
155 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
Colin Crossae887032017-10-23 17:16:14 -0700156 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
157 // and performs more verification.
Colin Cross0875c522017-11-28 17:34:01 -0800158 Build(pctx PackageContext, params BuildParams)
Colin Cross3f68a132017-10-23 17:10:29 -0700159
Colin Cross0875c522017-11-28 17:34:01 -0800160 PrimaryModule() Module
161 FinalModule() Module
162 VisitAllModuleVariants(visit func(Module))
Colin Cross3f68a132017-10-23 17:10:29 -0700163
164 GetMissingDependencies() []string
Jeff Gaston088e29e2017-11-29 16:47:17 -0800165 Namespace() blueprint.Namespace
Colin Cross3f40fa42015-01-30 17:27:36 -0800166}
167
Colin Cross635c3b02016-05-18 15:37:25 -0700168type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800169 blueprint.Module
170
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700171 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
172 // but GenerateAndroidBuildActions also has access to Android-specific information.
173 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -0700174 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700175
Colin Cross1e676be2016-10-12 14:38:15 -0700176 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800177
Colin Cross635c3b02016-05-18 15:37:25 -0700178 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800179 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700180 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800181 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700182 InstallInSanitizerDir() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +0900183 InstallInRecovery() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800184 SkipInstall()
Jiyong Park374510b2018-03-19 18:23:01 +0900185 ExportedToMake() bool
Colin Cross36242852017-06-23 15:06:31 -0700186
187 AddProperties(props ...interface{})
188 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700189
Colin Crossae887032017-10-23 17:16:14 -0700190 BuildParamsForTests() []BuildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800191}
192
Colin Crossfc754582016-05-17 16:34:16 -0700193type nameProperties struct {
194 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800195 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700196}
197
198type commonProperties struct {
Dan Willemsen0effe062015-11-30 16:06:01 -0800199 // emit build rules for this module
200 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800201
Colin Cross7d5136f2015-05-11 13:39:40 -0700202 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800203 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
204 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
205 // platform
Colin Cross7d716ba2017-11-01 10:38:29 -0700206 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700207
208 Target struct {
209 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700210 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700211 }
212 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700213 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700214 }
215 }
216
217 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800218
Dan Willemsen782a2d12015-12-21 14:55:28 -0800219 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700220 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800221
Colin Cross55708f32017-03-20 13:23:34 -0700222 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700223 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700224
Jiyong Park2db76922017-11-08 16:03:48 +0900225 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
226 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
227 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700228 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700229
Jiyong Park2db76922017-11-08 16:03:48 +0900230 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
231 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
232 Soc_specific *bool
233
234 // whether this module is specific to a device, not only for SoC, but also for off-chip
235 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
236 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
237 // This implies `soc_specific:true`.
238 Device_specific *bool
239
240 // whether this module is specific to a software configuration of a product (e.g. country,
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900241 // network operator, etc). When set to true, it is installed into /product (or
242 // /system/product if product partition does not exist).
Jiyong Park2db76922017-11-08 16:03:48 +0900243 Product_specific *bool
244
Dario Frenifd05a742018-05-29 13:28:54 +0100245 // whether this module provides services owned by the OS provider to the core platform. When set
246 // to true, it is installed into /product-services (or /system/product-services if
247 // product-services partition does not exist).
248 ProductServices_specific *bool
249
Jiyong Parkf9332f12018-02-01 00:54:12 +0900250 // Whether this module is installed to recovery partition
251 Recovery *bool
252
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700253 // init.rc files to be installed if this module is installed
254 Init_rc []string
255
Steven Moreland57a23d22018-04-04 15:42:19 -0700256 // VINTF manifest fragments to be installed if this module is installed
257 Vintf_fragments []string
258
Chris Wolfe998306e2016-08-15 14:47:23 -0400259 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700260 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400261
Colin Cross5aac3622017-08-31 15:07:09 -0700262 // relative path to a file to include in the list of notices for the device
263 Notice *string
264
Colin Crossa1ad8d12016-06-01 17:09:44 -0700265 // Set by TargetMutator
Colin Cross8b74d172016-09-13 09:59:14 -0700266 CompileTarget Target `blueprint:"mutated"`
267 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800268
269 // Set by InitAndroidModule
270 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700271 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700272
273 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800274
275 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800276}
277
278type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700279 Host_supported *bool
280 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800281}
282
Colin Crossc472d572015-03-17 15:06:21 -0700283type Multilib string
284
285const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800286 MultilibBoth Multilib = "both"
287 MultilibFirst Multilib = "first"
288 MultilibCommon Multilib = "common"
289 MultilibCommonFirst Multilib = "common_first"
290 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700291)
292
Colin Crossa1ad8d12016-06-01 17:09:44 -0700293type HostOrDeviceSupported int
294
295const (
296 _ HostOrDeviceSupported = iota
297 HostSupported
Dan Albertc6345fb2016-10-20 01:36:11 -0700298 HostSupportedNoCross
Colin Crossa1ad8d12016-06-01 17:09:44 -0700299 DeviceSupported
300 HostAndDeviceSupported
301 HostAndDeviceDefault
Dan Willemsen0b24c742016-10-04 15:13:37 -0700302 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700303)
304
Jiyong Park2db76922017-11-08 16:03:48 +0900305type moduleKind int
306
307const (
308 platformModule moduleKind = iota
309 deviceSpecificModule
310 socSpecificModule
311 productSpecificModule
Dario Frenifd05a742018-05-29 13:28:54 +0100312 productServicesSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900313)
314
315func (k moduleKind) String() string {
316 switch k {
317 case platformModule:
318 return "platform"
319 case deviceSpecificModule:
320 return "device-specific"
321 case socSpecificModule:
322 return "soc-specific"
323 case productSpecificModule:
324 return "product-specific"
Dario Frenifd05a742018-05-29 13:28:54 +0100325 case productServicesSpecificModule:
326 return "productservices-specific"
Jiyong Park2db76922017-11-08 16:03:48 +0900327 default:
328 panic(fmt.Errorf("unknown module kind %d", k))
329 }
330}
331
Colin Cross36242852017-06-23 15:06:31 -0700332func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800333 base := m.base()
334 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700335
Colin Cross36242852017-06-23 15:06:31 -0700336 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700337 &base.nameProperties,
338 &base.commonProperties,
339 &base.variableProperties)
Pirama Arumuga Nainar955dc492018-04-17 14:58:42 -0700340 base.customizableProperties = m.GetProperties()
Colin Cross5049f022015-03-18 13:28:46 -0700341}
342
Colin Cross36242852017-06-23 15:06:31 -0700343func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
344 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700345
346 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800347 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700348 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700349 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800350
Dan Willemsen218f6562015-07-08 18:13:11 -0700351 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700352 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700353 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800354 }
355
Colin Cross36242852017-06-23 15:06:31 -0700356 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800357}
358
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800359// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800360// modules. It should be included as an anonymous field in every module
361// struct definition. InitAndroidModule should then be called from the module's
362// factory function, and the return values from InitAndroidModule should be
363// returned from the factory function.
364//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800365// The ModuleBase type is responsible for implementing the GenerateBuildActions
366// method to support the blueprint.Module interface. This method will then call
367// the module's GenerateAndroidBuildActions method once for each build variant
368// that is to be built. GenerateAndroidBuildActions is passed a
369// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800370// AndroidModuleContext exposes extra functionality specific to the Android build
371// system including details about the particular build variant that is to be
372// generated.
373//
374// For example:
375//
376// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800377// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800378// )
379//
380// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800381// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800382// properties struct {
383// MyProperty string
384// }
385// }
386//
Colin Cross36242852017-06-23 15:06:31 -0700387// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800388// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700389// m.AddProperties(&m.properties)
390// android.InitAndroidModule(m)
391// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800392// }
393//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800394// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800395// // Get the CPU architecture for the current build variant.
396// variantArch := ctx.Arch()
397//
398// // ...
399// }
Colin Cross635c3b02016-05-18 15:37:25 -0700400type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800401 // Putting the curiously recurring thing pointing to the thing that contains
402 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700403 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700404 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800405
Colin Crossfc754582016-05-17 16:34:16 -0700406 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800407 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700408 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800409 hostAndDeviceProperties hostAndDeviceProperties
410 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700411 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700412 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800413
414 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700415 installFiles Paths
416 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700417
418 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
419 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800420 installTarget WritablePath
421 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700422 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700423
Colin Cross178a5092016-09-13 13:42:32 -0700424 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700425
426 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700427
428 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700429 buildParams []BuildParams
Colin Cross36242852017-06-23 15:06:31 -0700430}
431
432func (a *ModuleBase) AddProperties(props ...interface{}) {
433 a.registerProps = append(a.registerProps, props...)
434}
435
436func (a *ModuleBase) GetProperties() []interface{} {
437 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800438}
439
Colin Crossae887032017-10-23 17:16:14 -0700440func (a *ModuleBase) BuildParamsForTests() []BuildParams {
Colin Crosscec81712017-07-13 14:43:27 -0700441 return a.buildParams
442}
443
Colin Crossce75d2c2016-10-06 16:12:58 -0700444// Name returns the name of the module. It may be overridden by individual module types, for
445// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700446func (a *ModuleBase) Name() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800447 return String(a.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700448}
449
Colin Crossce75d2c2016-10-06 16:12:58 -0700450// BaseModuleName returns the name of the module as specified in the blueprints file.
451func (a *ModuleBase) BaseModuleName() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800452 return String(a.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700453}
454
Colin Cross635c3b02016-05-18 15:37:25 -0700455func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800456 return a
457}
458
Colin Cross8b74d172016-09-13 09:59:14 -0700459func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700460 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700461 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700462}
463
Colin Crossa1ad8d12016-06-01 17:09:44 -0700464func (a *ModuleBase) Target() Target {
465 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800466}
467
Colin Cross8b74d172016-09-13 09:59:14 -0700468func (a *ModuleBase) TargetPrimary() bool {
469 return a.commonProperties.CompilePrimary
470}
471
Colin Crossa1ad8d12016-06-01 17:09:44 -0700472func (a *ModuleBase) Os() OsType {
473 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800474}
475
Colin Cross635c3b02016-05-18 15:37:25 -0700476func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700477 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800478}
479
Colin Cross635c3b02016-05-18 15:37:25 -0700480func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700481 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800482}
483
Dan Willemsen0b24c742016-10-04 15:13:37 -0700484func (a *ModuleBase) ArchSpecific() bool {
485 return a.commonProperties.ArchSpecific
486}
487
Colin Crossa1ad8d12016-06-01 17:09:44 -0700488func (a *ModuleBase) OsClassSupported() []OsClass {
489 switch a.commonProperties.HostOrDeviceSupported {
490 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700491 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700492 case HostSupportedNoCross:
493 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700494 case DeviceSupported:
495 return []OsClass{Device}
496 case HostAndDeviceSupported:
497 var supported []OsClass
Colin Crossa4190c12016-07-12 13:11:25 -0700498 if Bool(a.hostAndDeviceProperties.Host_supported) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700499 supported = append(supported, Host, HostCross)
500 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700501 if a.hostAndDeviceProperties.Device_supported == nil ||
502 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700503 supported = append(supported, Device)
504 }
505 return supported
506 default:
507 return nil
508 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800509}
510
Colin Cross635c3b02016-05-18 15:37:25 -0700511func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800512 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
513 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700514 (a.hostAndDeviceProperties.Device_supported == nil ||
515 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800516}
517
Jiyong Parkc678ad32018-04-10 13:07:10 +0900518func (a *ModuleBase) Platform() bool {
Dario Frenifd05a742018-05-29 13:28:54 +0100519 return !a.DeviceSpecific() && !a.SocSpecific() && !a.ProductSpecific() && !a.ProductServicesSpecific()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900520}
521
522func (a *ModuleBase) DeviceSpecific() bool {
523 return Bool(a.commonProperties.Device_specific)
524}
525
526func (a *ModuleBase) SocSpecific() bool {
527 return Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
528}
529
530func (a *ModuleBase) ProductSpecific() bool {
531 return Bool(a.commonProperties.Product_specific)
532}
533
Dario Frenifd05a742018-05-29 13:28:54 +0100534func (a *ModuleBase) ProductServicesSpecific() bool {
535 return Bool(a.commonProperties.ProductServices_specific)
536}
537
Colin Cross635c3b02016-05-18 15:37:25 -0700538func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800539 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800540 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800541 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800542 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800543}
544
Colin Crossce75d2c2016-10-06 16:12:58 -0700545func (a *ModuleBase) SkipInstall() {
546 a.commonProperties.SkipInstall = true
547}
548
Jiyong Park374510b2018-03-19 18:23:01 +0900549func (a *ModuleBase) ExportedToMake() bool {
550 return a.commonProperties.NamespaceExportedToMake
551}
552
Colin Cross635c3b02016-05-18 15:37:25 -0700553func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700554 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800555
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700556 result := Paths{}
Colin Cross6b753602018-06-21 13:03:07 -0700557 // TODO(ccross): we need to use WalkDeps and have some way to know which dependencies require installation
Colin Cross3f40fa42015-01-30 17:27:36 -0800558 ctx.VisitDepsDepthFirstIf(isFileInstaller,
559 func(m blueprint.Module) {
560 fileInstaller := m.(fileInstaller)
561 files := fileInstaller.filesToInstall()
562 result = append(result, files...)
563 })
564
565 return result
566}
567
Colin Cross635c3b02016-05-18 15:37:25 -0700568func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800569 return a.installFiles
570}
571
Colin Cross635c3b02016-05-18 15:37:25 -0700572func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800573 return p.noAddressSanitizer
574}
575
Colin Cross635c3b02016-05-18 15:37:25 -0700576func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800577 return false
578}
579
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700580func (p *ModuleBase) InstallInSanitizerDir() bool {
581 return false
582}
583
Jiyong Parkf9332f12018-02-01 00:54:12 +0900584func (p *ModuleBase) InstallInRecovery() bool {
585 return Bool(p.commonProperties.Recovery)
586}
587
Colin Cross0875c522017-11-28 17:34:01 -0800588func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700589 allInstalledFiles := Paths{}
590 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -0800591 ctx.VisitAllModuleVariants(func(module Module) {
592 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -0700593 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
594 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800595 })
596
Colin Cross0875c522017-11-28 17:34:01 -0800597 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -0700598
Jeff Gaston088e29e2017-11-29 16:47:17 -0800599 namespacePrefix := ctx.Namespace().(*Namespace).id
600 if namespacePrefix != "" {
601 namespacePrefix = namespacePrefix + "-"
602 }
603
Colin Cross3f40fa42015-01-30 17:27:36 -0800604 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800605 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -0800606 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700607 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800608 Output: name,
609 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -0800610 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700611 })
612 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700613 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700614 }
615
616 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800617 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -0800618 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700619 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800620 Output: name,
621 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -0700622 })
623 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700624 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700625 }
626
627 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800628 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -0800629 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800630 suffix = "-soong"
631 }
632
Jeff Gaston088e29e2017-11-29 16:47:17 -0800633 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -0800634 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700635 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -0800636 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -0700637 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800638 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700639
640 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800641 }
642}
643
Jiyong Park2db76922017-11-08 16:03:48 +0900644func determineModuleKind(a *ModuleBase, ctx blueprint.BaseModuleContext) moduleKind {
645 var socSpecific = Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
646 var deviceSpecific = Bool(a.commonProperties.Device_specific)
647 var productSpecific = Bool(a.commonProperties.Product_specific)
Dario Frenifd05a742018-05-29 13:28:54 +0100648 var productServicesSpecific = Bool(a.commonProperties.ProductServices_specific)
Jiyong Park2db76922017-11-08 16:03:48 +0900649
Dario Frenifd05a742018-05-29 13:28:54 +0100650 msg := "conflicting value set here"
651 if socSpecific && deviceSpecific {
652 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
Jiyong Park2db76922017-11-08 16:03:48 +0900653 if Bool(a.commonProperties.Vendor) {
654 ctx.PropertyErrorf("vendor", msg)
655 }
656 if Bool(a.commonProperties.Proprietary) {
657 ctx.PropertyErrorf("proprietary", msg)
658 }
659 if Bool(a.commonProperties.Soc_specific) {
660 ctx.PropertyErrorf("soc_specific", msg)
661 }
662 }
663
Dario Frenifd05a742018-05-29 13:28:54 +0100664 if productSpecific && productServicesSpecific {
665 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and product_services at the same time.")
666 ctx.PropertyErrorf("product_services_specific", msg)
667 }
668
669 if (socSpecific || deviceSpecific) && (productSpecific || productServicesSpecific) {
670 if productSpecific {
671 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
672 } else {
673 ctx.PropertyErrorf("product_services_specific", "a module cannot be specific to SoC or device and product_services at the same time.")
674 }
675 if deviceSpecific {
676 ctx.PropertyErrorf("device_specific", msg)
677 } else {
678 if Bool(a.commonProperties.Vendor) {
679 ctx.PropertyErrorf("vendor", msg)
680 }
681 if Bool(a.commonProperties.Proprietary) {
682 ctx.PropertyErrorf("proprietary", msg)
683 }
684 if Bool(a.commonProperties.Soc_specific) {
685 ctx.PropertyErrorf("soc_specific", msg)
686 }
687 }
688 }
689
Jiyong Park2db76922017-11-08 16:03:48 +0900690 if productSpecific {
691 return productSpecificModule
Dario Frenifd05a742018-05-29 13:28:54 +0100692 } else if productServicesSpecific {
693 return productServicesSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900694 } else if deviceSpecific {
695 return deviceSpecificModule
696 } else if socSpecific {
697 return socSpecificModule
698 } else {
699 return platformModule
700 }
701}
702
Colin Cross635c3b02016-05-18 15:37:25 -0700703func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700704 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700705 target: a.commonProperties.CompileTarget,
706 targetPrimary: a.commonProperties.CompilePrimary,
Jiyong Park2db76922017-11-08 16:03:48 +0900707 kind: determineModuleKind(a, ctx),
Colin Cross8b74d172016-09-13 09:59:14 -0700708 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800709 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800710}
711
Colin Cross0875c522017-11-28 17:34:01 -0800712func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
713 ctx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700714 module: a.module,
Colin Cross0875c522017-11-28 17:34:01 -0800715 ModuleContext: blueprintCtx,
716 androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
717 installDeps: a.computeInstallDeps(blueprintCtx),
Colin Cross6362e272015-10-29 15:25:03 -0700718 installFiles: a.installFiles,
Colin Cross0875c522017-11-28 17:34:01 -0800719 missingDeps: blueprintCtx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800720 }
721
Colin Cross67a5c132017-05-09 13:45:28 -0700722 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
723 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -0800724 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
725 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -0700726 }
Colin Cross0875c522017-11-28 17:34:01 -0800727 if !ctx.PrimaryArch() {
728 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -0700729 }
730
731 ctx.Variable(pctx, "moduleDesc", desc)
732
733 s := ""
734 if len(suffix) > 0 {
735 s = " [" + strings.Join(suffix, " ") + "]"
736 }
737 ctx.Variable(pctx, "moduleDescSuffix", s)
738
Colin Cross9b1d13d2016-09-19 15:18:11 -0700739 if a.Enabled() {
Colin Cross0875c522017-11-28 17:34:01 -0800740 a.module.GenerateAndroidBuildActions(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700741 if ctx.Failed() {
742 return
743 }
744
Colin Cross0875c522017-11-28 17:34:01 -0800745 a.installFiles = append(a.installFiles, ctx.installFiles...)
746 a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800747 }
748
Colin Cross9b1d13d2016-09-19 15:18:11 -0700749 if a == ctx.FinalModule().(Module).base() {
750 a.generateModuleTarget(ctx)
751 if ctx.Failed() {
752 return
753 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800754 }
Colin Crosscec81712017-07-13 14:43:27 -0700755
Colin Cross0875c522017-11-28 17:34:01 -0800756 a.buildParams = ctx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800757}
758
Colin Crossf6566ed2015-03-24 11:13:38 -0700759type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700760 target Target
761 targetPrimary bool
762 debug bool
Jiyong Park2db76922017-11-08 16:03:48 +0900763 kind moduleKind
Colin Cross8b74d172016-09-13 09:59:14 -0700764 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700765}
766
Colin Cross3f40fa42015-01-30 17:27:36 -0800767type androidModuleContext struct {
768 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700769 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700770 installDeps Paths
771 installFiles Paths
772 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800773 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700774 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700775
776 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700777 buildParams []BuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800778}
779
Colin Cross67a5c132017-05-09 13:45:28 -0700780func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross0875c522017-11-28 17:34:01 -0800781 a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700782 Rule: ErrorRule,
783 Description: desc,
784 Outputs: outputs,
785 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800786 Args: map[string]string{
787 "error": err.Error(),
788 },
789 })
790 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800791}
792
Colin Crossaabf6792017-11-29 00:27:14 -0800793func (a *androidModuleContext) Config() Config {
794 return a.ModuleContext.Config().(Config)
795}
796
Colin Cross0875c522017-11-28 17:34:01 -0800797func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
Colin Crossae887032017-10-23 17:16:14 -0700798 a.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800799}
800
Colin Cross0875c522017-11-28 17:34:01 -0800801func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700802 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700803 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -0800804 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800805 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700806 Outputs: params.Outputs.Strings(),
807 ImplicitOutputs: params.ImplicitOutputs.Strings(),
808 Inputs: params.Inputs.Strings(),
809 Implicits: params.Implicits.Strings(),
810 OrderOnly: params.OrderOnly.Strings(),
811 Args: params.Args,
812 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700813 }
814
Colin Cross33bfb0a2016-11-21 17:23:08 -0800815 if params.Depfile != nil {
816 bparams.Depfile = params.Depfile.String()
817 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700818 if params.Output != nil {
819 bparams.Outputs = append(bparams.Outputs, params.Output.String())
820 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700821 if params.ImplicitOutput != nil {
822 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
823 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700824 if params.Input != nil {
825 bparams.Inputs = append(bparams.Inputs, params.Input.String())
826 }
827 if params.Implicit != nil {
828 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
829 }
830
Colin Cross0875c522017-11-28 17:34:01 -0800831 return bparams
832}
833
834func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
835 a.ModuleContext.Variable(pctx.PackageContext, name, value)
836}
837
838func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
839 argNames ...string) blueprint.Rule {
840
841 return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
842}
843
844func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
845 if a.config.captureBuild {
846 a.buildParams = append(a.buildParams, params)
847 }
848
849 bparams := convertBuildParams(params)
850
851 if bparams.Description != "" {
852 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
853 }
854
Colin Cross6ff51382015-12-17 16:39:19 -0800855 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700856 a.ninjaError(bparams.Description, bparams.Outputs,
857 fmt.Errorf("module %s missing dependencies: %s\n",
858 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800859 return
860 }
861
Colin Cross0875c522017-11-28 17:34:01 -0800862 a.ModuleContext.Build(pctx.PackageContext, bparams)
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700863}
864
Colin Cross6ff51382015-12-17 16:39:19 -0800865func (a *androidModuleContext) GetMissingDependencies() []string {
866 return a.missingDeps
867}
868
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800869func (a *androidModuleContext) AddMissingDependencies(deps []string) {
870 if deps != nil {
871 a.missingDeps = append(a.missingDeps, deps...)
Colin Crossd11fcda2017-10-23 17:59:01 -0700872 a.missingDeps = FirstUniqueStrings(a.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800873 }
874}
875
Colin Crossd11fcda2017-10-23 17:59:01 -0700876func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
877 aModule, _ := module.(Module)
878 if aModule == nil {
879 a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
880 return nil
881 }
882
883 if !aModule.Enabled() {
Colin Cross6510f912017-11-29 00:27:14 -0800884 if a.Config().AllowMissingDependencies() {
Colin Crossd11fcda2017-10-23 17:59:01 -0700885 a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
886 } else {
887 a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
888 }
889 return nil
890 }
891
892 return aModule
893}
894
Colin Cross35143d02017-11-16 00:11:20 -0800895func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
896 a.ModuleContext.VisitDirectDeps(visit)
897}
898
Colin Crossd11fcda2017-10-23 17:59:01 -0700899func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
900 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
901 if aModule := a.validateAndroidModule(module); aModule != nil {
902 visit(aModule)
903 }
904 })
905}
906
Colin Crossee6143c2017-12-30 17:54:27 -0800907func (a *androidModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
908 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
909 if aModule := a.validateAndroidModule(module); aModule != nil {
910 if a.ModuleContext.OtherModuleDependencyTag(aModule) == tag {
911 visit(aModule)
912 }
913 }
914 })
915}
916
Colin Crossd11fcda2017-10-23 17:59:01 -0700917func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
918 a.ModuleContext.VisitDirectDepsIf(
919 // pred
920 func(module blueprint.Module) bool {
921 if aModule := a.validateAndroidModule(module); aModule != nil {
922 return pred(aModule)
923 } else {
924 return false
925 }
926 },
927 // visit
928 func(module blueprint.Module) {
929 visit(module.(Module))
930 })
931}
932
933func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
934 a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
935 if aModule := a.validateAndroidModule(module); aModule != nil {
936 visit(aModule)
937 }
938 })
939}
940
941func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
942 a.ModuleContext.VisitDepsDepthFirstIf(
943 // pred
944 func(module blueprint.Module) bool {
945 if aModule := a.validateAndroidModule(module); aModule != nil {
946 return pred(aModule)
947 } else {
948 return false
949 }
950 },
951 // visit
952 func(module blueprint.Module) {
953 visit(module.(Module))
954 })
955}
956
957func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
958 a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
959 childAndroidModule := a.validateAndroidModule(child)
960 parentAndroidModule := a.validateAndroidModule(parent)
961 if childAndroidModule != nil && parentAndroidModule != nil {
962 return visit(childAndroidModule, parentAndroidModule)
963 } else {
964 return false
965 }
966 })
967}
968
Colin Cross0875c522017-11-28 17:34:01 -0800969func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
970 a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
971 visit(module.(Module))
972 })
973}
974
975func (a *androidModuleContext) PrimaryModule() Module {
976 return a.ModuleContext.PrimaryModule().(Module)
977}
978
979func (a *androidModuleContext) FinalModule() Module {
980 return a.ModuleContext.FinalModule().(Module)
981}
982
Colin Crossa1ad8d12016-06-01 17:09:44 -0700983func (a *androidBaseContextImpl) Target() Target {
984 return a.target
985}
986
Colin Cross8b74d172016-09-13 09:59:14 -0700987func (a *androidBaseContextImpl) TargetPrimary() bool {
988 return a.targetPrimary
989}
990
Colin Crossf6566ed2015-03-24 11:13:38 -0700991func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700992 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -0800993}
994
Colin Crossa1ad8d12016-06-01 17:09:44 -0700995func (a *androidBaseContextImpl) Os() OsType {
996 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800997}
998
Colin Crossf6566ed2015-03-24 11:13:38 -0700999func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001000 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -07001001}
1002
1003func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001004 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -07001005}
1006
Colin Cross0af4b842015-04-30 16:36:18 -07001007func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001008 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -07001009}
1010
Colin Cross3edeee12017-04-04 12:59:48 -07001011func (a *androidBaseContextImpl) Windows() bool {
1012 return a.target.Os == Windows
1013}
1014
Colin Crossf6566ed2015-03-24 11:13:38 -07001015func (a *androidBaseContextImpl) Debug() bool {
1016 return a.debug
1017}
1018
Colin Cross1e7d3702016-08-24 15:25:47 -07001019func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -07001020 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
1021 return true
1022 }
Colin Cross1e7d3702016-08-24 15:25:47 -07001023 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
1024}
1025
Colin Cross1332b002015-04-07 17:11:30 -07001026func (a *androidBaseContextImpl) AConfig() Config {
1027 return a.config
1028}
1029
Colin Cross9272ade2016-08-17 15:24:12 -07001030func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
1031 return DeviceConfig{a.config.deviceConfig}
1032}
1033
Jiyong Park2db76922017-11-08 16:03:48 +09001034func (a *androidBaseContextImpl) Platform() bool {
1035 return a.kind == platformModule
1036}
1037
1038func (a *androidBaseContextImpl) DeviceSpecific() bool {
1039 return a.kind == deviceSpecificModule
1040}
1041
1042func (a *androidBaseContextImpl) SocSpecific() bool {
1043 return a.kind == socSpecificModule
1044}
1045
1046func (a *androidBaseContextImpl) ProductSpecific() bool {
1047 return a.kind == productSpecificModule
Dan Willemsen782a2d12015-12-21 14:55:28 -08001048}
1049
Dario Frenifd05a742018-05-29 13:28:54 +01001050func (a *androidBaseContextImpl) ProductServicesSpecific() bool {
1051 return a.kind == productServicesSpecificModule
1052}
1053
Colin Cross8d8f8e22016-08-03 11:57:50 -07001054func (a *androidModuleContext) InstallInData() bool {
1055 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -08001056}
1057
Vishwath Mohan1dd88392017-03-29 22:00:18 -07001058func (a *androidModuleContext) InstallInSanitizerDir() bool {
1059 return a.module.InstallInSanitizerDir()
1060}
1061
Jiyong Parkf9332f12018-02-01 00:54:12 +09001062func (a *androidModuleContext) InstallInRecovery() bool {
1063 return a.module.InstallInRecovery()
1064}
1065
Colin Cross893d8162017-04-26 17:34:03 -07001066func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
1067 if a.module.base().commonProperties.SkipInstall {
1068 return true
1069 }
1070
Colin Cross3607f212018-05-07 15:28:05 -07001071 // We'll need a solution for choosing which of modules with the same name in different
1072 // namespaces to install. For now, reuse the list of namespaces exported to Make as the
1073 // list of namespaces to install in a Soong-only build.
1074 if !a.module.base().commonProperties.NamespaceExportedToMake {
1075 return true
1076 }
1077
Colin Cross893d8162017-04-26 17:34:03 -07001078 if a.Device() {
Colin Cross6510f912017-11-29 00:27:14 -08001079 if a.Config().SkipDeviceInstall() {
Colin Cross893d8162017-04-26 17:34:03 -07001080 return true
1081 }
1082
Colin Cross6510f912017-11-29 00:27:14 -08001083 if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -07001084 return true
1085 }
1086 }
1087
1088 return false
1089}
1090
Colin Cross5c517922017-08-31 12:29:17 -07001091func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -07001092 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -07001093 return a.installFile(installPath, name, srcPath, Cp, deps)
1094}
1095
1096func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
1097 deps ...Path) OutputPath {
1098 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
1099}
1100
1101func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
1102 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -07001103
Dan Willemsen782a2d12015-12-21 14:55:28 -08001104 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001105 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -08001106
Colin Cross893d8162017-04-26 17:34:03 -07001107 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001108
Dan Willemsen322acaf2016-01-12 23:07:05 -08001109 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -07001110
Colin Cross89562dc2016-10-03 17:47:19 -07001111 var implicitDeps, orderOnlyDeps Paths
1112
1113 if a.Host() {
1114 // Installed host modules might be used during the build, depend directly on their
1115 // dependencies so their timestamp is updated whenever their dependency is updated
1116 implicitDeps = deps
1117 } else {
1118 orderOnlyDeps = deps
1119 }
1120
Colin Crossae887032017-10-23 17:16:14 -07001121 a.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -07001122 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -07001123 Description: "install " + fullInstallPath.Base(),
1124 Output: fullInstallPath,
1125 Input: srcPath,
1126 Implicits: implicitDeps,
1127 OrderOnly: orderOnlyDeps,
Colin Cross6510f912017-11-29 00:27:14 -08001128 Default: !a.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -08001129 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001130
Dan Willemsen322acaf2016-01-12 23:07:05 -08001131 a.installFiles = append(a.installFiles, fullInstallPath)
1132 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001133 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -07001134 return fullInstallPath
1135}
1136
Colin Cross3854a602016-01-11 12:49:11 -08001137func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
1138 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001139 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -08001140
Colin Cross893d8162017-04-26 17:34:03 -07001141 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001142
Colin Crossae887032017-10-23 17:16:14 -07001143 a.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -07001144 Rule: Symlink,
1145 Description: "install symlink " + fullInstallPath.Base(),
1146 Output: fullInstallPath,
1147 OrderOnly: Paths{srcPath},
Colin Cross6510f912017-11-29 00:27:14 -08001148 Default: !a.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -08001149 Args: map[string]string{
1150 "fromPath": srcPath.String(),
1151 },
1152 })
Colin Cross3854a602016-01-11 12:49:11 -08001153
Colin Cross12fc4972016-01-11 12:49:11 -08001154 a.installFiles = append(a.installFiles, fullInstallPath)
1155 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1156 }
Colin Cross3854a602016-01-11 12:49:11 -08001157 return fullInstallPath
1158}
1159
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001160func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001161 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1162}
1163
Colin Cross3f40fa42015-01-30 17:27:36 -08001164type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001165 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001166}
1167
1168func isFileInstaller(m blueprint.Module) bool {
1169 _, ok := m.(fileInstaller)
1170 return ok
1171}
1172
1173func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -07001174 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -08001175 return ok
1176}
Colin Crossfce53272015-04-08 11:21:40 -07001177
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001178func findStringInSlice(str string, slice []string) int {
1179 for i, s := range slice {
1180 if s == str {
1181 return i
Colin Crossfce53272015-04-08 11:21:40 -07001182 }
1183 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001184 return -1
1185}
1186
Colin Cross068e0fe2016-12-13 15:23:47 -08001187func SrcIsModule(s string) string {
1188 if len(s) > 1 && s[0] == ':' {
1189 return s[1:]
1190 }
1191 return ""
1192}
1193
1194type sourceDependencyTag struct {
1195 blueprint.BaseDependencyTag
1196}
1197
1198var SourceDepTag sourceDependencyTag
1199
Colin Cross366938f2017-12-11 16:29:02 -08001200// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
1201// using ":module" syntax, if any.
Colin Cross068e0fe2016-12-13 15:23:47 -08001202func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
1203 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -07001204 set := make(map[string]bool)
1205
Colin Cross068e0fe2016-12-13 15:23:47 -08001206 for _, s := range srcFiles {
1207 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -07001208 if _, found := set[m]; found {
1209 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
1210 } else {
1211 set[m] = true
1212 deps = append(deps, m)
1213 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001214 }
1215 }
1216
1217 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
1218}
1219
Colin Cross366938f2017-12-11 16:29:02 -08001220// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
1221// using ":module" syntax, if any.
1222func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
1223 if s != nil {
1224 if m := SrcIsModule(*s); m != "" {
1225 ctx.AddDependency(ctx.Module(), SourceDepTag, m)
1226 }
1227 }
1228}
1229
Colin Cross068e0fe2016-12-13 15:23:47 -08001230type SourceFileProducer interface {
1231 Srcs() Paths
1232}
1233
1234// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001235// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001236func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001237 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
1238}
1239
Colin Cross366938f2017-12-11 16:29:02 -08001240// Returns a single path expanded from globs and modules referenced using ":module" syntax.
1241// ExtractSourceDeps must have already been called during the dependency resolution phase.
1242func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path {
1243 srcFiles := ctx.ExpandSourcesSubDir([]string{srcFile}, nil, "")
1244 if len(srcFiles) == 1 {
1245 return srcFiles[0]
1246 } else {
1247 ctx.PropertyErrorf(prop, "module providing %s must produce exactly one file", prop)
1248 return nil
1249 }
1250}
1251
Colin Cross2383f3b2018-02-06 14:40:13 -08001252// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
1253// the srcFile is non-nil.
1254// ExtractSourceDeps must have already been called during the dependency resolution phase.
1255func (ctx *androidModuleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
1256 if srcFile != nil {
1257 return OptionalPathForPath(ctx.ExpandSource(*srcFile, prop))
1258 }
1259 return OptionalPath{}
1260}
1261
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001262func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001263 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001264
Colin Cross461b4452018-02-23 09:22:42 -08001265 var expandedExcludes []string
1266 if excludes != nil {
1267 expandedExcludes = make([]string, 0, len(excludes))
1268 }
Nan Zhang27e284d2018-02-09 21:03:53 +00001269
1270 for _, e := range excludes {
1271 if m := SrcIsModule(e); m != "" {
1272 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
1273 if module == nil {
1274 // Error will have been handled by ExtractSourcesDeps
1275 continue
1276 }
1277 if srcProducer, ok := module.(SourceFileProducer); ok {
1278 expandedExcludes = append(expandedExcludes, srcProducer.Srcs().Strings()...)
1279 } else {
1280 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1281 }
1282 } else {
1283 expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e))
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001284 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001285 }
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001286 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -07001287 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -08001288 if m := SrcIsModule(s); m != "" {
1289 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
Colin Cross0617bb82017-10-24 13:01:18 -07001290 if module == nil {
1291 // Error will have been handled by ExtractSourcesDeps
1292 continue
1293 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001294 if srcProducer, ok := module.(SourceFileProducer); ok {
Nan Zhang27e284d2018-02-09 21:03:53 +00001295 moduleSrcs := srcProducer.Srcs()
1296 for _, e := range expandedExcludes {
1297 for j, ms := range moduleSrcs {
1298 if ms.String() == e {
1299 moduleSrcs = append(moduleSrcs[:j], moduleSrcs[j+1:]...)
1300 }
1301 }
1302 }
1303 expandedSrcFiles = append(expandedSrcFiles, moduleSrcs...)
Colin Cross068e0fe2016-12-13 15:23:47 -08001304 } else {
1305 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1306 }
1307 } else if pathtools.IsGlob(s) {
Dan Willemsen540a78c2018-02-26 21:50:08 -08001308 globbedSrcFiles := ctx.GlobFiles(filepath.Join(prefix, s), expandedExcludes)
Colin Cross05a39cb2017-10-09 13:35:19 -07001309 for i, s := range globbedSrcFiles {
1310 globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001311 }
Colin Cross05a39cb2017-10-09 13:35:19 -07001312 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
Colin Cross8f101b42015-06-17 15:09:06 -07001313 } else {
Nan Zhang27e284d2018-02-09 21:03:53 +00001314 p := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
1315 j := findStringInSlice(p.String(), expandedExcludes)
1316 if j == -1 {
1317 expandedSrcFiles = append(expandedSrcFiles, p)
1318 }
1319
Colin Cross8f101b42015-06-17 15:09:06 -07001320 }
1321 }
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001322 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -07001323}
1324
Nan Zhang6d34b302017-02-04 17:47:46 -08001325func (ctx *androidModuleContext) RequiredModuleNames() []string {
1326 return ctx.module.base().commonProperties.Required
1327}
1328
Colin Cross7f19f372016-11-01 11:10:25 -07001329func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
1330 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001331 if err != nil {
1332 ctx.ModuleErrorf("glob: %s", err.Error())
1333 }
Dan Willemsen540a78c2018-02-26 21:50:08 -08001334 return pathsForModuleSrcFromFullPath(ctx, ret, true)
Colin Crossfce53272015-04-08 11:21:40 -07001335}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001336
Nan Zhang581fd212018-01-10 16:06:12 -08001337func (ctx *androidModuleContext) GlobFiles(globPattern string, excludes []string) Paths {
Dan Willemsen540a78c2018-02-26 21:50:08 -08001338 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Nan Zhang581fd212018-01-10 16:06:12 -08001339 if err != nil {
1340 ctx.ModuleErrorf("glob: %s", err.Error())
1341 }
Dan Willemsen540a78c2018-02-26 21:50:08 -08001342 return pathsForModuleSrcFromFullPath(ctx, ret, false)
Nan Zhang581fd212018-01-10 16:06:12 -08001343}
1344
Colin Cross463a90e2015-06-17 14:20:06 -07001345func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001346 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001347}
1348
Colin Cross0875c522017-11-28 17:34:01 -08001349func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001350 return &buildTargetSingleton{}
1351}
1352
Colin Cross87d8b562017-04-25 10:01:55 -07001353func parentDir(dir string) string {
1354 dir, _ = filepath.Split(dir)
1355 return filepath.Clean(dir)
1356}
1357
Colin Cross1f8c52b2015-06-16 16:38:17 -07001358type buildTargetSingleton struct{}
1359
Colin Cross0875c522017-11-28 17:34:01 -08001360func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1361 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07001362
Colin Cross0875c522017-11-28 17:34:01 -08001363 mmTarget := func(dir string) WritablePath {
1364 return PathForPhony(ctx,
1365 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07001366 }
1367
Colin Cross0875c522017-11-28 17:34:01 -08001368 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001369
Colin Cross0875c522017-11-28 17:34:01 -08001370 ctx.VisitAllModules(func(module Module) {
1371 blueprintDir := module.base().blueprintDir
1372 installTarget := module.base().installTarget
1373 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07001374
Colin Cross0875c522017-11-28 17:34:01 -08001375 if checkbuildTarget != nil {
1376 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1377 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1378 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001379
Colin Cross0875c522017-11-28 17:34:01 -08001380 if installTarget != nil {
1381 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001382 }
1383 })
1384
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001385 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001386 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001387 suffix = "-soong"
1388 }
1389
Colin Cross1f8c52b2015-06-16 16:38:17 -07001390 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08001391 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001392 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001393 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001394 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001395 })
1396
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001397 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08001398 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001399 return
1400 }
1401
Colin Cross0875c522017-11-28 17:34:01 -08001402 sortedKeys := func(m map[string]Paths) []string {
1403 s := make([]string, 0, len(m))
1404 for k := range m {
1405 s = append(s, k)
1406 }
1407 sort.Strings(s)
1408 return s
1409 }
1410
Colin Cross87d8b562017-04-25 10:01:55 -07001411 // Ensure ancestor directories are in modulesInDir
1412 dirs := sortedKeys(modulesInDir)
1413 for _, dir := range dirs {
1414 dir := parentDir(dir)
1415 for dir != "." && dir != "/" {
1416 if _, exists := modulesInDir[dir]; exists {
1417 break
1418 }
1419 modulesInDir[dir] = nil
1420 dir = parentDir(dir)
1421 }
1422 }
1423
1424 // Make directories build their direct subdirectories
1425 dirs = sortedKeys(modulesInDir)
1426 for _, dir := range dirs {
1427 p := parentDir(dir)
1428 if p != "." && p != "/" {
1429 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1430 }
1431 }
1432
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001433 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1434 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1435 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001436 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08001437 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001438 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001439 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07001440 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001441 // HACK: checkbuild should be an optional build, but force it
1442 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08001443 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001444 })
1445 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001446
1447 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1448 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001449 ctx.VisitAllModules(func(module Module) {
1450 if module.Enabled() {
1451 os := module.Target().Os
1452 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001453 }
1454 })
1455
Colin Cross0875c522017-11-28 17:34:01 -08001456 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001457 for os, deps := range osDeps {
1458 var className string
1459
1460 switch os.Class {
1461 case Host:
1462 className = "host"
1463 case HostCross:
1464 className = "host-cross"
1465 case Device:
1466 className = "target"
1467 default:
1468 continue
1469 }
1470
Colin Cross0875c522017-11-28 17:34:01 -08001471 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001472 osClass[className] = append(osClass[className], name)
1473
Colin Cross0875c522017-11-28 17:34:01 -08001474 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001475 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001476 Output: name,
1477 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07001478 })
1479 }
1480
1481 // Wrap those into host|host-cross|target phony rules
1482 osClasses := sortedKeys(osClass)
1483 for _, class := range osClasses {
Colin Cross0875c522017-11-28 17:34:01 -08001484 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001485 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001486 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07001487 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07001488 })
1489 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001490}
Colin Crossd779da42015-12-17 18:00:23 -08001491
1492type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -07001493 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -08001494 ctx interface {
1495 ModuleName(blueprint.Module) string
1496 ModuleSubDir(blueprint.Module) string
1497 }
1498}
1499
1500func (s AndroidModulesByName) Len() int { return len(s.slice) }
1501func (s AndroidModulesByName) Less(i, j int) bool {
1502 mi, mj := s.slice[i], s.slice[j]
1503 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1504
1505 if ni != nj {
1506 return ni < nj
1507 } else {
1508 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1509 }
1510}
1511func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }