blob: ac7e606c6154e314c54ef84c63f686d9afb0bd29 [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
Dan Albert0981b5c2018-08-02 13:46:35 -0700297
298 // Host and HostCross are built by default. Device is not supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700299 HostSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700300
301 // Host is built by default. HostCross and Device are not supported.
Dan Albertc6345fb2016-10-20 01:36:11 -0700302 HostSupportedNoCross
Dan Albert0981b5c2018-08-02 13:46:35 -0700303
304 // Device is built by default. Host and HostCross are not supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700305 DeviceSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700306
307 // Device is built by default. Host and HostCross are supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700308 HostAndDeviceSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700309
310 // Host, HostCross, and Device are built by default.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700311 HostAndDeviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700312
313 // Nothing is supported. This is not exposed to the user, but used to mark a
314 // host only module as unsupported when the module type is not supported on
315 // the host OS. E.g. benchmarks are supported on Linux but not Darwin.
Dan Willemsen0b24c742016-10-04 15:13:37 -0700316 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700317)
318
Jiyong Park2db76922017-11-08 16:03:48 +0900319type moduleKind int
320
321const (
322 platformModule moduleKind = iota
323 deviceSpecificModule
324 socSpecificModule
325 productSpecificModule
Dario Frenifd05a742018-05-29 13:28:54 +0100326 productServicesSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900327)
328
329func (k moduleKind) String() string {
330 switch k {
331 case platformModule:
332 return "platform"
333 case deviceSpecificModule:
334 return "device-specific"
335 case socSpecificModule:
336 return "soc-specific"
337 case productSpecificModule:
338 return "product-specific"
Dario Frenifd05a742018-05-29 13:28:54 +0100339 case productServicesSpecificModule:
340 return "productservices-specific"
Jiyong Park2db76922017-11-08 16:03:48 +0900341 default:
342 panic(fmt.Errorf("unknown module kind %d", k))
343 }
344}
345
Colin Cross36242852017-06-23 15:06:31 -0700346func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800347 base := m.base()
348 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700349
Colin Cross36242852017-06-23 15:06:31 -0700350 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700351 &base.nameProperties,
352 &base.commonProperties,
353 &base.variableProperties)
Pirama Arumuga Nainar955dc492018-04-17 14:58:42 -0700354 base.customizableProperties = m.GetProperties()
Colin Cross5049f022015-03-18 13:28:46 -0700355}
356
Colin Cross36242852017-06-23 15:06:31 -0700357func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
358 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700359
360 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800361 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700362 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700363 base.commonProperties.ArchSpecific = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800364
Dan Willemsen218f6562015-07-08 18:13:11 -0700365 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700366 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700367 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800368 }
369
Colin Cross36242852017-06-23 15:06:31 -0700370 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800371}
372
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800373// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800374// modules. It should be included as an anonymous field in every module
375// struct definition. InitAndroidModule should then be called from the module's
376// factory function, and the return values from InitAndroidModule should be
377// returned from the factory function.
378//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800379// The ModuleBase type is responsible for implementing the GenerateBuildActions
380// method to support the blueprint.Module interface. This method will then call
381// the module's GenerateAndroidBuildActions method once for each build variant
382// that is to be built. GenerateAndroidBuildActions is passed a
383// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800384// AndroidModuleContext exposes extra functionality specific to the Android build
385// system including details about the particular build variant that is to be
386// generated.
387//
388// For example:
389//
390// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800391// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800392// )
393//
394// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800395// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800396// properties struct {
397// MyProperty string
398// }
399// }
400//
Colin Cross36242852017-06-23 15:06:31 -0700401// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800402// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700403// m.AddProperties(&m.properties)
404// android.InitAndroidModule(m)
405// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800406// }
407//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800408// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800409// // Get the CPU architecture for the current build variant.
410// variantArch := ctx.Arch()
411//
412// // ...
413// }
Colin Cross635c3b02016-05-18 15:37:25 -0700414type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800415 // Putting the curiously recurring thing pointing to the thing that contains
416 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700417 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700418 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800419
Colin Crossfc754582016-05-17 16:34:16 -0700420 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800421 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700422 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800423 hostAndDeviceProperties hostAndDeviceProperties
424 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700425 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700426 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800427
428 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700429 installFiles Paths
430 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700431
432 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
433 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800434 installTarget WritablePath
435 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700436 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700437
Colin Cross178a5092016-09-13 13:42:32 -0700438 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700439
440 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700441
442 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700443 buildParams []BuildParams
Colin Cross36242852017-06-23 15:06:31 -0700444}
445
446func (a *ModuleBase) AddProperties(props ...interface{}) {
447 a.registerProps = append(a.registerProps, props...)
448}
449
450func (a *ModuleBase) GetProperties() []interface{} {
451 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800452}
453
Colin Crossae887032017-10-23 17:16:14 -0700454func (a *ModuleBase) BuildParamsForTests() []BuildParams {
Colin Crosscec81712017-07-13 14:43:27 -0700455 return a.buildParams
456}
457
Colin Crossce75d2c2016-10-06 16:12:58 -0700458// Name returns the name of the module. It may be overridden by individual module types, for
459// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700460func (a *ModuleBase) Name() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800461 return String(a.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700462}
463
Colin Crossce75d2c2016-10-06 16:12:58 -0700464// BaseModuleName returns the name of the module as specified in the blueprints file.
465func (a *ModuleBase) BaseModuleName() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800466 return String(a.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700467}
468
Colin Cross635c3b02016-05-18 15:37:25 -0700469func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800470 return a
471}
472
Colin Cross8b74d172016-09-13 09:59:14 -0700473func (a *ModuleBase) SetTarget(target Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700474 a.commonProperties.CompileTarget = target
Colin Cross8b74d172016-09-13 09:59:14 -0700475 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700476}
477
Colin Crossa1ad8d12016-06-01 17:09:44 -0700478func (a *ModuleBase) Target() Target {
479 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800480}
481
Colin Cross8b74d172016-09-13 09:59:14 -0700482func (a *ModuleBase) TargetPrimary() bool {
483 return a.commonProperties.CompilePrimary
484}
485
Colin Crossa1ad8d12016-06-01 17:09:44 -0700486func (a *ModuleBase) Os() OsType {
487 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800488}
489
Colin Cross635c3b02016-05-18 15:37:25 -0700490func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700491 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800492}
493
Colin Cross635c3b02016-05-18 15:37:25 -0700494func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700495 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800496}
497
Dan Willemsen0b24c742016-10-04 15:13:37 -0700498func (a *ModuleBase) ArchSpecific() bool {
499 return a.commonProperties.ArchSpecific
500}
501
Colin Crossa1ad8d12016-06-01 17:09:44 -0700502func (a *ModuleBase) OsClassSupported() []OsClass {
503 switch a.commonProperties.HostOrDeviceSupported {
504 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700505 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700506 case HostSupportedNoCross:
507 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700508 case DeviceSupported:
509 return []OsClass{Device}
Dan Albert0981b5c2018-08-02 13:46:35 -0700510 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700511 var supported []OsClass
Dan Albert0981b5c2018-08-02 13:46:35 -0700512 if Bool(a.hostAndDeviceProperties.Host_supported) ||
513 (a.commonProperties.HostOrDeviceSupported == HostAndDeviceDefault &&
514 a.hostAndDeviceProperties.Host_supported == nil) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700515 supported = append(supported, Host, HostCross)
516 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700517 if a.hostAndDeviceProperties.Device_supported == nil ||
518 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700519 supported = append(supported, Device)
520 }
521 return supported
522 default:
523 return nil
524 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800525}
526
Colin Cross635c3b02016-05-18 15:37:25 -0700527func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800528 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
529 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700530 (a.hostAndDeviceProperties.Device_supported == nil ||
531 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800532}
533
Jiyong Parkc678ad32018-04-10 13:07:10 +0900534func (a *ModuleBase) Platform() bool {
Dario Frenifd05a742018-05-29 13:28:54 +0100535 return !a.DeviceSpecific() && !a.SocSpecific() && !a.ProductSpecific() && !a.ProductServicesSpecific()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900536}
537
538func (a *ModuleBase) DeviceSpecific() bool {
539 return Bool(a.commonProperties.Device_specific)
540}
541
542func (a *ModuleBase) SocSpecific() bool {
543 return Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
544}
545
546func (a *ModuleBase) ProductSpecific() bool {
547 return Bool(a.commonProperties.Product_specific)
548}
549
Dario Frenifd05a742018-05-29 13:28:54 +0100550func (a *ModuleBase) ProductServicesSpecific() bool {
551 return Bool(a.commonProperties.ProductServices_specific)
552}
553
Colin Cross635c3b02016-05-18 15:37:25 -0700554func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800555 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800556 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800557 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800558 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800559}
560
Colin Crossce75d2c2016-10-06 16:12:58 -0700561func (a *ModuleBase) SkipInstall() {
562 a.commonProperties.SkipInstall = true
563}
564
Jiyong Park374510b2018-03-19 18:23:01 +0900565func (a *ModuleBase) ExportedToMake() bool {
566 return a.commonProperties.NamespaceExportedToMake
567}
568
Colin Cross635c3b02016-05-18 15:37:25 -0700569func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700570 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800571
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700572 result := Paths{}
Colin Cross6b753602018-06-21 13:03:07 -0700573 // TODO(ccross): we need to use WalkDeps and have some way to know which dependencies require installation
Colin Cross3f40fa42015-01-30 17:27:36 -0800574 ctx.VisitDepsDepthFirstIf(isFileInstaller,
575 func(m blueprint.Module) {
576 fileInstaller := m.(fileInstaller)
577 files := fileInstaller.filesToInstall()
578 result = append(result, files...)
579 })
580
581 return result
582}
583
Colin Cross635c3b02016-05-18 15:37:25 -0700584func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800585 return a.installFiles
586}
587
Colin Cross635c3b02016-05-18 15:37:25 -0700588func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800589 return p.noAddressSanitizer
590}
591
Colin Cross635c3b02016-05-18 15:37:25 -0700592func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800593 return false
594}
595
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700596func (p *ModuleBase) InstallInSanitizerDir() bool {
597 return false
598}
599
Jiyong Parkf9332f12018-02-01 00:54:12 +0900600func (p *ModuleBase) InstallInRecovery() bool {
601 return Bool(p.commonProperties.Recovery)
602}
603
Colin Cross0875c522017-11-28 17:34:01 -0800604func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700605 allInstalledFiles := Paths{}
606 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -0800607 ctx.VisitAllModuleVariants(func(module Module) {
608 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -0700609 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
610 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800611 })
612
Colin Cross0875c522017-11-28 17:34:01 -0800613 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -0700614
Jeff Gaston088e29e2017-11-29 16:47:17 -0800615 namespacePrefix := ctx.Namespace().(*Namespace).id
616 if namespacePrefix != "" {
617 namespacePrefix = namespacePrefix + "-"
618 }
619
Colin Cross3f40fa42015-01-30 17:27:36 -0800620 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800621 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -0800622 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700623 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800624 Output: name,
625 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -0800626 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700627 })
628 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700629 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700630 }
631
632 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800633 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -0800634 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700635 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800636 Output: name,
637 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -0700638 })
639 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700640 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700641 }
642
643 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800644 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -0800645 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800646 suffix = "-soong"
647 }
648
Jeff Gaston088e29e2017-11-29 16:47:17 -0800649 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -0800650 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700651 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -0800652 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -0700653 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800654 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700655
656 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800657 }
658}
659
Jiyong Park2db76922017-11-08 16:03:48 +0900660func determineModuleKind(a *ModuleBase, ctx blueprint.BaseModuleContext) moduleKind {
661 var socSpecific = Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
662 var deviceSpecific = Bool(a.commonProperties.Device_specific)
663 var productSpecific = Bool(a.commonProperties.Product_specific)
Dario Frenifd05a742018-05-29 13:28:54 +0100664 var productServicesSpecific = Bool(a.commonProperties.ProductServices_specific)
Jiyong Park2db76922017-11-08 16:03:48 +0900665
Dario Frenifd05a742018-05-29 13:28:54 +0100666 msg := "conflicting value set here"
667 if socSpecific && deviceSpecific {
668 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
Jiyong Park2db76922017-11-08 16:03:48 +0900669 if Bool(a.commonProperties.Vendor) {
670 ctx.PropertyErrorf("vendor", msg)
671 }
672 if Bool(a.commonProperties.Proprietary) {
673 ctx.PropertyErrorf("proprietary", msg)
674 }
675 if Bool(a.commonProperties.Soc_specific) {
676 ctx.PropertyErrorf("soc_specific", msg)
677 }
678 }
679
Dario Frenifd05a742018-05-29 13:28:54 +0100680 if productSpecific && productServicesSpecific {
681 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and product_services at the same time.")
682 ctx.PropertyErrorf("product_services_specific", msg)
683 }
684
685 if (socSpecific || deviceSpecific) && (productSpecific || productServicesSpecific) {
686 if productSpecific {
687 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
688 } else {
689 ctx.PropertyErrorf("product_services_specific", "a module cannot be specific to SoC or device and product_services at the same time.")
690 }
691 if deviceSpecific {
692 ctx.PropertyErrorf("device_specific", msg)
693 } else {
694 if Bool(a.commonProperties.Vendor) {
695 ctx.PropertyErrorf("vendor", msg)
696 }
697 if Bool(a.commonProperties.Proprietary) {
698 ctx.PropertyErrorf("proprietary", msg)
699 }
700 if Bool(a.commonProperties.Soc_specific) {
701 ctx.PropertyErrorf("soc_specific", msg)
702 }
703 }
704 }
705
Jiyong Park2db76922017-11-08 16:03:48 +0900706 if productSpecific {
707 return productSpecificModule
Dario Frenifd05a742018-05-29 13:28:54 +0100708 } else if productServicesSpecific {
709 return productServicesSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900710 } else if deviceSpecific {
711 return deviceSpecificModule
712 } else if socSpecific {
713 return socSpecificModule
714 } else {
715 return platformModule
716 }
717}
718
Colin Cross635c3b02016-05-18 15:37:25 -0700719func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700720 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700721 target: a.commonProperties.CompileTarget,
722 targetPrimary: a.commonProperties.CompilePrimary,
Jiyong Park2db76922017-11-08 16:03:48 +0900723 kind: determineModuleKind(a, ctx),
Colin Cross8b74d172016-09-13 09:59:14 -0700724 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800725 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800726}
727
Colin Cross0875c522017-11-28 17:34:01 -0800728func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
729 ctx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700730 module: a.module,
Colin Cross0875c522017-11-28 17:34:01 -0800731 ModuleContext: blueprintCtx,
732 androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
733 installDeps: a.computeInstallDeps(blueprintCtx),
Colin Cross6362e272015-10-29 15:25:03 -0700734 installFiles: a.installFiles,
Colin Cross0875c522017-11-28 17:34:01 -0800735 missingDeps: blueprintCtx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800736 }
737
Colin Cross67a5c132017-05-09 13:45:28 -0700738 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
739 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -0800740 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
741 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -0700742 }
Colin Cross0875c522017-11-28 17:34:01 -0800743 if !ctx.PrimaryArch() {
744 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -0700745 }
746
747 ctx.Variable(pctx, "moduleDesc", desc)
748
749 s := ""
750 if len(suffix) > 0 {
751 s = " [" + strings.Join(suffix, " ") + "]"
752 }
753 ctx.Variable(pctx, "moduleDescSuffix", s)
754
Colin Cross9b1d13d2016-09-19 15:18:11 -0700755 if a.Enabled() {
Colin Cross0875c522017-11-28 17:34:01 -0800756 a.module.GenerateAndroidBuildActions(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700757 if ctx.Failed() {
758 return
759 }
760
Colin Cross0875c522017-11-28 17:34:01 -0800761 a.installFiles = append(a.installFiles, ctx.installFiles...)
762 a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800763 }
764
Colin Cross9b1d13d2016-09-19 15:18:11 -0700765 if a == ctx.FinalModule().(Module).base() {
766 a.generateModuleTarget(ctx)
767 if ctx.Failed() {
768 return
769 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800770 }
Colin Crosscec81712017-07-13 14:43:27 -0700771
Colin Cross0875c522017-11-28 17:34:01 -0800772 a.buildParams = ctx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800773}
774
Colin Crossf6566ed2015-03-24 11:13:38 -0700775type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700776 target Target
777 targetPrimary bool
778 debug bool
Jiyong Park2db76922017-11-08 16:03:48 +0900779 kind moduleKind
Colin Cross8b74d172016-09-13 09:59:14 -0700780 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700781}
782
Colin Cross3f40fa42015-01-30 17:27:36 -0800783type androidModuleContext struct {
784 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700785 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700786 installDeps Paths
787 installFiles Paths
788 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800789 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700790 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700791
792 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700793 buildParams []BuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800794}
795
Colin Cross67a5c132017-05-09 13:45:28 -0700796func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross0875c522017-11-28 17:34:01 -0800797 a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700798 Rule: ErrorRule,
799 Description: desc,
800 Outputs: outputs,
801 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800802 Args: map[string]string{
803 "error": err.Error(),
804 },
805 })
806 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800807}
808
Colin Crossaabf6792017-11-29 00:27:14 -0800809func (a *androidModuleContext) Config() Config {
810 return a.ModuleContext.Config().(Config)
811}
812
Colin Cross0875c522017-11-28 17:34:01 -0800813func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
Colin Crossae887032017-10-23 17:16:14 -0700814 a.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800815}
816
Colin Cross0875c522017-11-28 17:34:01 -0800817func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700818 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700819 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -0800820 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800821 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700822 Outputs: params.Outputs.Strings(),
823 ImplicitOutputs: params.ImplicitOutputs.Strings(),
824 Inputs: params.Inputs.Strings(),
825 Implicits: params.Implicits.Strings(),
826 OrderOnly: params.OrderOnly.Strings(),
827 Args: params.Args,
828 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700829 }
830
Colin Cross33bfb0a2016-11-21 17:23:08 -0800831 if params.Depfile != nil {
832 bparams.Depfile = params.Depfile.String()
833 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700834 if params.Output != nil {
835 bparams.Outputs = append(bparams.Outputs, params.Output.String())
836 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700837 if params.ImplicitOutput != nil {
838 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
839 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700840 if params.Input != nil {
841 bparams.Inputs = append(bparams.Inputs, params.Input.String())
842 }
843 if params.Implicit != nil {
844 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
845 }
846
Colin Cross0875c522017-11-28 17:34:01 -0800847 return bparams
848}
849
850func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
851 a.ModuleContext.Variable(pctx.PackageContext, name, value)
852}
853
854func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
855 argNames ...string) blueprint.Rule {
856
857 return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
858}
859
860func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
861 if a.config.captureBuild {
862 a.buildParams = append(a.buildParams, params)
863 }
864
865 bparams := convertBuildParams(params)
866
867 if bparams.Description != "" {
868 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
869 }
870
Colin Cross6ff51382015-12-17 16:39:19 -0800871 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700872 a.ninjaError(bparams.Description, bparams.Outputs,
873 fmt.Errorf("module %s missing dependencies: %s\n",
874 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800875 return
876 }
877
Colin Cross0875c522017-11-28 17:34:01 -0800878 a.ModuleContext.Build(pctx.PackageContext, bparams)
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700879}
880
Colin Cross6ff51382015-12-17 16:39:19 -0800881func (a *androidModuleContext) GetMissingDependencies() []string {
882 return a.missingDeps
883}
884
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800885func (a *androidModuleContext) AddMissingDependencies(deps []string) {
886 if deps != nil {
887 a.missingDeps = append(a.missingDeps, deps...)
Colin Crossd11fcda2017-10-23 17:59:01 -0700888 a.missingDeps = FirstUniqueStrings(a.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800889 }
890}
891
Colin Crossd11fcda2017-10-23 17:59:01 -0700892func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
893 aModule, _ := module.(Module)
894 if aModule == nil {
895 a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
896 return nil
897 }
898
899 if !aModule.Enabled() {
Colin Cross6510f912017-11-29 00:27:14 -0800900 if a.Config().AllowMissingDependencies() {
Colin Crossd11fcda2017-10-23 17:59:01 -0700901 a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
902 } else {
903 a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
904 }
905 return nil
906 }
907
908 return aModule
909}
910
Colin Cross35143d02017-11-16 00:11:20 -0800911func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
912 a.ModuleContext.VisitDirectDeps(visit)
913}
914
Colin Crossd11fcda2017-10-23 17:59:01 -0700915func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
916 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
917 if aModule := a.validateAndroidModule(module); aModule != nil {
918 visit(aModule)
919 }
920 })
921}
922
Colin Crossee6143c2017-12-30 17:54:27 -0800923func (a *androidModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
924 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
925 if aModule := a.validateAndroidModule(module); aModule != nil {
926 if a.ModuleContext.OtherModuleDependencyTag(aModule) == tag {
927 visit(aModule)
928 }
929 }
930 })
931}
932
Colin Crossd11fcda2017-10-23 17:59:01 -0700933func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
934 a.ModuleContext.VisitDirectDepsIf(
935 // pred
936 func(module blueprint.Module) bool {
937 if aModule := a.validateAndroidModule(module); aModule != nil {
938 return pred(aModule)
939 } else {
940 return false
941 }
942 },
943 // visit
944 func(module blueprint.Module) {
945 visit(module.(Module))
946 })
947}
948
949func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
950 a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
951 if aModule := a.validateAndroidModule(module); aModule != nil {
952 visit(aModule)
953 }
954 })
955}
956
957func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
958 a.ModuleContext.VisitDepsDepthFirstIf(
959 // pred
960 func(module blueprint.Module) bool {
961 if aModule := a.validateAndroidModule(module); aModule != nil {
962 return pred(aModule)
963 } else {
964 return false
965 }
966 },
967 // visit
968 func(module blueprint.Module) {
969 visit(module.(Module))
970 })
971}
972
973func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
974 a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
975 childAndroidModule := a.validateAndroidModule(child)
976 parentAndroidModule := a.validateAndroidModule(parent)
977 if childAndroidModule != nil && parentAndroidModule != nil {
978 return visit(childAndroidModule, parentAndroidModule)
979 } else {
980 return false
981 }
982 })
983}
984
Colin Cross0875c522017-11-28 17:34:01 -0800985func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
986 a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
987 visit(module.(Module))
988 })
989}
990
991func (a *androidModuleContext) PrimaryModule() Module {
992 return a.ModuleContext.PrimaryModule().(Module)
993}
994
995func (a *androidModuleContext) FinalModule() Module {
996 return a.ModuleContext.FinalModule().(Module)
997}
998
Colin Crossa1ad8d12016-06-01 17:09:44 -0700999func (a *androidBaseContextImpl) Target() Target {
1000 return a.target
1001}
1002
Colin Cross8b74d172016-09-13 09:59:14 -07001003func (a *androidBaseContextImpl) TargetPrimary() bool {
1004 return a.targetPrimary
1005}
1006
Colin Crossf6566ed2015-03-24 11:13:38 -07001007func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001008 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -08001009}
1010
Colin Crossa1ad8d12016-06-01 17:09:44 -07001011func (a *androidBaseContextImpl) Os() OsType {
1012 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -08001013}
1014
Colin Crossf6566ed2015-03-24 11:13:38 -07001015func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001016 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -07001017}
1018
1019func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001020 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -07001021}
1022
Colin Cross0af4b842015-04-30 16:36:18 -07001023func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001024 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -07001025}
1026
Colin Cross3edeee12017-04-04 12:59:48 -07001027func (a *androidBaseContextImpl) Windows() bool {
1028 return a.target.Os == Windows
1029}
1030
Colin Crossf6566ed2015-03-24 11:13:38 -07001031func (a *androidBaseContextImpl) Debug() bool {
1032 return a.debug
1033}
1034
Colin Cross1e7d3702016-08-24 15:25:47 -07001035func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -07001036 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
1037 return true
1038 }
Colin Cross1e7d3702016-08-24 15:25:47 -07001039 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
1040}
1041
Colin Cross1332b002015-04-07 17:11:30 -07001042func (a *androidBaseContextImpl) AConfig() Config {
1043 return a.config
1044}
1045
Colin Cross9272ade2016-08-17 15:24:12 -07001046func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
1047 return DeviceConfig{a.config.deviceConfig}
1048}
1049
Jiyong Park2db76922017-11-08 16:03:48 +09001050func (a *androidBaseContextImpl) Platform() bool {
1051 return a.kind == platformModule
1052}
1053
1054func (a *androidBaseContextImpl) DeviceSpecific() bool {
1055 return a.kind == deviceSpecificModule
1056}
1057
1058func (a *androidBaseContextImpl) SocSpecific() bool {
1059 return a.kind == socSpecificModule
1060}
1061
1062func (a *androidBaseContextImpl) ProductSpecific() bool {
1063 return a.kind == productSpecificModule
Dan Willemsen782a2d12015-12-21 14:55:28 -08001064}
1065
Dario Frenifd05a742018-05-29 13:28:54 +01001066func (a *androidBaseContextImpl) ProductServicesSpecific() bool {
1067 return a.kind == productServicesSpecificModule
1068}
1069
Colin Cross8d8f8e22016-08-03 11:57:50 -07001070func (a *androidModuleContext) InstallInData() bool {
1071 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -08001072}
1073
Vishwath Mohan1dd88392017-03-29 22:00:18 -07001074func (a *androidModuleContext) InstallInSanitizerDir() bool {
1075 return a.module.InstallInSanitizerDir()
1076}
1077
Jiyong Parkf9332f12018-02-01 00:54:12 +09001078func (a *androidModuleContext) InstallInRecovery() bool {
1079 return a.module.InstallInRecovery()
1080}
1081
Colin Cross893d8162017-04-26 17:34:03 -07001082func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
1083 if a.module.base().commonProperties.SkipInstall {
1084 return true
1085 }
1086
Colin Cross3607f212018-05-07 15:28:05 -07001087 // We'll need a solution for choosing which of modules with the same name in different
1088 // namespaces to install. For now, reuse the list of namespaces exported to Make as the
1089 // list of namespaces to install in a Soong-only build.
1090 if !a.module.base().commonProperties.NamespaceExportedToMake {
1091 return true
1092 }
1093
Colin Cross893d8162017-04-26 17:34:03 -07001094 if a.Device() {
Colin Cross6510f912017-11-29 00:27:14 -08001095 if a.Config().SkipDeviceInstall() {
Colin Cross893d8162017-04-26 17:34:03 -07001096 return true
1097 }
1098
Colin Cross6510f912017-11-29 00:27:14 -08001099 if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -07001100 return true
1101 }
1102 }
1103
1104 return false
1105}
1106
Colin Cross5c517922017-08-31 12:29:17 -07001107func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -07001108 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -07001109 return a.installFile(installPath, name, srcPath, Cp, deps)
1110}
1111
1112func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
1113 deps ...Path) OutputPath {
1114 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
1115}
1116
1117func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
1118 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -07001119
Dan Willemsen782a2d12015-12-21 14:55:28 -08001120 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001121 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -08001122
Colin Cross893d8162017-04-26 17:34:03 -07001123 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001124
Dan Willemsen322acaf2016-01-12 23:07:05 -08001125 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -07001126
Colin Cross89562dc2016-10-03 17:47:19 -07001127 var implicitDeps, orderOnlyDeps Paths
1128
1129 if a.Host() {
1130 // Installed host modules might be used during the build, depend directly on their
1131 // dependencies so their timestamp is updated whenever their dependency is updated
1132 implicitDeps = deps
1133 } else {
1134 orderOnlyDeps = deps
1135 }
1136
Colin Crossae887032017-10-23 17:16:14 -07001137 a.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -07001138 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -07001139 Description: "install " + fullInstallPath.Base(),
1140 Output: fullInstallPath,
1141 Input: srcPath,
1142 Implicits: implicitDeps,
1143 OrderOnly: orderOnlyDeps,
Colin Cross6510f912017-11-29 00:27:14 -08001144 Default: !a.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -08001145 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001146
Dan Willemsen322acaf2016-01-12 23:07:05 -08001147 a.installFiles = append(a.installFiles, fullInstallPath)
1148 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001149 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -07001150 return fullInstallPath
1151}
1152
Colin Cross3854a602016-01-11 12:49:11 -08001153func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
1154 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001155 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -08001156
Colin Cross893d8162017-04-26 17:34:03 -07001157 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001158
Colin Crossae887032017-10-23 17:16:14 -07001159 a.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -07001160 Rule: Symlink,
1161 Description: "install symlink " + fullInstallPath.Base(),
1162 Output: fullInstallPath,
1163 OrderOnly: Paths{srcPath},
Colin Cross6510f912017-11-29 00:27:14 -08001164 Default: !a.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -08001165 Args: map[string]string{
1166 "fromPath": srcPath.String(),
1167 },
1168 })
Colin Cross3854a602016-01-11 12:49:11 -08001169
Colin Cross12fc4972016-01-11 12:49:11 -08001170 a.installFiles = append(a.installFiles, fullInstallPath)
1171 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1172 }
Colin Cross3854a602016-01-11 12:49:11 -08001173 return fullInstallPath
1174}
1175
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001176func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001177 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1178}
1179
Colin Cross3f40fa42015-01-30 17:27:36 -08001180type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001181 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001182}
1183
1184func isFileInstaller(m blueprint.Module) bool {
1185 _, ok := m.(fileInstaller)
1186 return ok
1187}
1188
1189func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -07001190 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -08001191 return ok
1192}
Colin Crossfce53272015-04-08 11:21:40 -07001193
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001194func findStringInSlice(str string, slice []string) int {
1195 for i, s := range slice {
1196 if s == str {
1197 return i
Colin Crossfce53272015-04-08 11:21:40 -07001198 }
1199 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001200 return -1
1201}
1202
Colin Cross068e0fe2016-12-13 15:23:47 -08001203func SrcIsModule(s string) string {
1204 if len(s) > 1 && s[0] == ':' {
1205 return s[1:]
1206 }
1207 return ""
1208}
1209
1210type sourceDependencyTag struct {
1211 blueprint.BaseDependencyTag
1212}
1213
1214var SourceDepTag sourceDependencyTag
1215
Colin Cross366938f2017-12-11 16:29:02 -08001216// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
1217// using ":module" syntax, if any.
Colin Cross068e0fe2016-12-13 15:23:47 -08001218func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
1219 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -07001220 set := make(map[string]bool)
1221
Colin Cross068e0fe2016-12-13 15:23:47 -08001222 for _, s := range srcFiles {
1223 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -07001224 if _, found := set[m]; found {
1225 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
1226 } else {
1227 set[m] = true
1228 deps = append(deps, m)
1229 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001230 }
1231 }
1232
1233 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
1234}
1235
Colin Cross366938f2017-12-11 16:29:02 -08001236// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
1237// using ":module" syntax, if any.
1238func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
1239 if s != nil {
1240 if m := SrcIsModule(*s); m != "" {
1241 ctx.AddDependency(ctx.Module(), SourceDepTag, m)
1242 }
1243 }
1244}
1245
Colin Cross068e0fe2016-12-13 15:23:47 -08001246type SourceFileProducer interface {
1247 Srcs() Paths
1248}
1249
1250// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001251// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001252func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001253 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
1254}
1255
Colin Cross366938f2017-12-11 16:29:02 -08001256// Returns a single path expanded from globs and modules referenced using ":module" syntax.
1257// ExtractSourceDeps must have already been called during the dependency resolution phase.
1258func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path {
1259 srcFiles := ctx.ExpandSourcesSubDir([]string{srcFile}, nil, "")
1260 if len(srcFiles) == 1 {
1261 return srcFiles[0]
1262 } else {
1263 ctx.PropertyErrorf(prop, "module providing %s must produce exactly one file", prop)
1264 return nil
1265 }
1266}
1267
Colin Cross2383f3b2018-02-06 14:40:13 -08001268// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
1269// the srcFile is non-nil.
1270// ExtractSourceDeps must have already been called during the dependency resolution phase.
1271func (ctx *androidModuleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
1272 if srcFile != nil {
1273 return OptionalPathForPath(ctx.ExpandSource(*srcFile, prop))
1274 }
1275 return OptionalPath{}
1276}
1277
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001278func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001279 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001280
Colin Cross461b4452018-02-23 09:22:42 -08001281 var expandedExcludes []string
1282 if excludes != nil {
1283 expandedExcludes = make([]string, 0, len(excludes))
1284 }
Nan Zhang27e284d2018-02-09 21:03:53 +00001285
1286 for _, e := range excludes {
1287 if m := SrcIsModule(e); m != "" {
1288 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
1289 if module == nil {
1290 // Error will have been handled by ExtractSourcesDeps
1291 continue
1292 }
1293 if srcProducer, ok := module.(SourceFileProducer); ok {
1294 expandedExcludes = append(expandedExcludes, srcProducer.Srcs().Strings()...)
1295 } else {
1296 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1297 }
1298 } else {
1299 expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e))
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001300 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001301 }
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001302 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -07001303 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -08001304 if m := SrcIsModule(s); m != "" {
1305 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
Colin Cross0617bb82017-10-24 13:01:18 -07001306 if module == nil {
1307 // Error will have been handled by ExtractSourcesDeps
1308 continue
1309 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001310 if srcProducer, ok := module.(SourceFileProducer); ok {
Nan Zhang27e284d2018-02-09 21:03:53 +00001311 moduleSrcs := srcProducer.Srcs()
1312 for _, e := range expandedExcludes {
1313 for j, ms := range moduleSrcs {
1314 if ms.String() == e {
1315 moduleSrcs = append(moduleSrcs[:j], moduleSrcs[j+1:]...)
1316 }
1317 }
1318 }
1319 expandedSrcFiles = append(expandedSrcFiles, moduleSrcs...)
Colin Cross068e0fe2016-12-13 15:23:47 -08001320 } else {
1321 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1322 }
1323 } else if pathtools.IsGlob(s) {
Dan Willemsen540a78c2018-02-26 21:50:08 -08001324 globbedSrcFiles := ctx.GlobFiles(filepath.Join(prefix, s), expandedExcludes)
Colin Cross05a39cb2017-10-09 13:35:19 -07001325 for i, s := range globbedSrcFiles {
1326 globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001327 }
Colin Cross05a39cb2017-10-09 13:35:19 -07001328 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
Colin Cross8f101b42015-06-17 15:09:06 -07001329 } else {
Nan Zhang27e284d2018-02-09 21:03:53 +00001330 p := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
1331 j := findStringInSlice(p.String(), expandedExcludes)
1332 if j == -1 {
1333 expandedSrcFiles = append(expandedSrcFiles, p)
1334 }
1335
Colin Cross8f101b42015-06-17 15:09:06 -07001336 }
1337 }
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001338 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -07001339}
1340
Nan Zhang6d34b302017-02-04 17:47:46 -08001341func (ctx *androidModuleContext) RequiredModuleNames() []string {
1342 return ctx.module.base().commonProperties.Required
1343}
1344
Colin Cross7f19f372016-11-01 11:10:25 -07001345func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
1346 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001347 if err != nil {
1348 ctx.ModuleErrorf("glob: %s", err.Error())
1349 }
Dan Willemsen540a78c2018-02-26 21:50:08 -08001350 return pathsForModuleSrcFromFullPath(ctx, ret, true)
Colin Crossfce53272015-04-08 11:21:40 -07001351}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001352
Nan Zhang581fd212018-01-10 16:06:12 -08001353func (ctx *androidModuleContext) GlobFiles(globPattern string, excludes []string) Paths {
Dan Willemsen540a78c2018-02-26 21:50:08 -08001354 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Nan Zhang581fd212018-01-10 16:06:12 -08001355 if err != nil {
1356 ctx.ModuleErrorf("glob: %s", err.Error())
1357 }
Dan Willemsen540a78c2018-02-26 21:50:08 -08001358 return pathsForModuleSrcFromFullPath(ctx, ret, false)
Nan Zhang581fd212018-01-10 16:06:12 -08001359}
1360
Colin Cross463a90e2015-06-17 14:20:06 -07001361func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001362 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001363}
1364
Colin Cross0875c522017-11-28 17:34:01 -08001365func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001366 return &buildTargetSingleton{}
1367}
1368
Colin Cross87d8b562017-04-25 10:01:55 -07001369func parentDir(dir string) string {
1370 dir, _ = filepath.Split(dir)
1371 return filepath.Clean(dir)
1372}
1373
Colin Cross1f8c52b2015-06-16 16:38:17 -07001374type buildTargetSingleton struct{}
1375
Colin Cross0875c522017-11-28 17:34:01 -08001376func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1377 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07001378
Colin Cross0875c522017-11-28 17:34:01 -08001379 mmTarget := func(dir string) WritablePath {
1380 return PathForPhony(ctx,
1381 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07001382 }
1383
Colin Cross0875c522017-11-28 17:34:01 -08001384 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001385
Colin Cross0875c522017-11-28 17:34:01 -08001386 ctx.VisitAllModules(func(module Module) {
1387 blueprintDir := module.base().blueprintDir
1388 installTarget := module.base().installTarget
1389 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07001390
Colin Cross0875c522017-11-28 17:34:01 -08001391 if checkbuildTarget != nil {
1392 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1393 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1394 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001395
Colin Cross0875c522017-11-28 17:34:01 -08001396 if installTarget != nil {
1397 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001398 }
1399 })
1400
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001401 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001402 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001403 suffix = "-soong"
1404 }
1405
Colin Cross1f8c52b2015-06-16 16:38:17 -07001406 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08001407 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001408 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001409 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001410 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001411 })
1412
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001413 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08001414 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001415 return
1416 }
1417
Colin Cross0875c522017-11-28 17:34:01 -08001418 sortedKeys := func(m map[string]Paths) []string {
1419 s := make([]string, 0, len(m))
1420 for k := range m {
1421 s = append(s, k)
1422 }
1423 sort.Strings(s)
1424 return s
1425 }
1426
Colin Cross87d8b562017-04-25 10:01:55 -07001427 // Ensure ancestor directories are in modulesInDir
1428 dirs := sortedKeys(modulesInDir)
1429 for _, dir := range dirs {
1430 dir := parentDir(dir)
1431 for dir != "." && dir != "/" {
1432 if _, exists := modulesInDir[dir]; exists {
1433 break
1434 }
1435 modulesInDir[dir] = nil
1436 dir = parentDir(dir)
1437 }
1438 }
1439
1440 // Make directories build their direct subdirectories
1441 dirs = sortedKeys(modulesInDir)
1442 for _, dir := range dirs {
1443 p := parentDir(dir)
1444 if p != "." && p != "/" {
1445 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1446 }
1447 }
1448
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001449 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1450 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1451 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001452 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08001453 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001454 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001455 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07001456 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001457 // HACK: checkbuild should be an optional build, but force it
1458 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08001459 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001460 })
1461 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001462
1463 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1464 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001465 ctx.VisitAllModules(func(module Module) {
1466 if module.Enabled() {
1467 os := module.Target().Os
1468 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001469 }
1470 })
1471
Colin Cross0875c522017-11-28 17:34:01 -08001472 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001473 for os, deps := range osDeps {
1474 var className string
1475
1476 switch os.Class {
1477 case Host:
1478 className = "host"
1479 case HostCross:
1480 className = "host-cross"
1481 case Device:
1482 className = "target"
1483 default:
1484 continue
1485 }
1486
Colin Cross0875c522017-11-28 17:34:01 -08001487 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001488 osClass[className] = append(osClass[className], name)
1489
Colin Cross0875c522017-11-28 17:34:01 -08001490 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001491 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001492 Output: name,
1493 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07001494 })
1495 }
1496
1497 // Wrap those into host|host-cross|target phony rules
1498 osClasses := sortedKeys(osClass)
1499 for _, class := range osClasses {
Colin Cross0875c522017-11-28 17:34:01 -08001500 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001501 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001502 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07001503 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07001504 })
1505 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001506}
Colin Crossd779da42015-12-17 18:00:23 -08001507
1508type AndroidModulesByName struct {
Colin Cross635c3b02016-05-18 15:37:25 -07001509 slice []Module
Colin Crossd779da42015-12-17 18:00:23 -08001510 ctx interface {
1511 ModuleName(blueprint.Module) string
1512 ModuleSubDir(blueprint.Module) string
1513 }
1514}
1515
1516func (s AndroidModulesByName) Len() int { return len(s.slice) }
1517func (s AndroidModulesByName) Less(i, j int) bool {
1518 mi, mj := s.slice[i], s.slice[j]
1519 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1520
1521 if ni != nj {
1522 return ni < nj
1523 } else {
1524 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1525 }
1526}
1527func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }