blob: 9d9d9a93802db53bdf043fb276bf37e4f43c2be3 [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 Crossfe4bc362018-09-12 10:02:13 -070026 "github.com/google/blueprint/proptools"
Colin Cross3f40fa42015-01-30 17:27:36 -080027)
28
29var (
30 DeviceSharedLibrary = "shared_library"
31 DeviceStaticLibrary = "static_library"
32 DeviceExecutable = "executable"
33 HostSharedLibrary = "host_shared_library"
34 HostStaticLibrary = "host_static_library"
35 HostExecutable = "host_executable"
36)
37
Colin Crossae887032017-10-23 17:16:14 -070038type BuildParams struct {
Dan Willemsen9f3c5742016-11-03 14:28:31 -070039 Rule blueprint.Rule
Colin Cross33bfb0a2016-11-21 17:23:08 -080040 Deps blueprint.Deps
41 Depfile WritablePath
Colin Cross67a5c132017-05-09 13:45:28 -070042 Description string
Dan Willemsen9f3c5742016-11-03 14:28:31 -070043 Output WritablePath
44 Outputs WritablePaths
45 ImplicitOutput WritablePath
46 ImplicitOutputs WritablePaths
47 Input Path
48 Inputs Paths
49 Implicit Path
50 Implicits Paths
51 OrderOnly Paths
52 Default bool
53 Args map[string]string
Dan Willemsen34cc69e2015-09-23 15:26:20 -070054}
55
Colin Crossae887032017-10-23 17:16:14 -070056type ModuleBuildParams BuildParams
57
Colin Crossf6566ed2015-03-24 11:13:38 -070058type androidBaseContext interface {
Colin Crossa1ad8d12016-06-01 17:09:44 -070059 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -070060 TargetPrimary() bool
Colin Crossee0bc3b2018-10-02 22:01:37 -070061 MultiTargets() []Target
Colin Crossf6566ed2015-03-24 11:13:38 -070062 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -070063 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -070064 Host() bool
65 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070066 Darwin() bool
Colin Cross3edeee12017-04-04 12:59:48 -070067 Windows() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070068 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -070069 PrimaryArch() bool
Jiyong Park2db76922017-11-08 16:03:48 +090070 Platform() bool
71 DeviceSpecific() bool
72 SocSpecific() bool
73 ProductSpecific() bool
Dario Frenifd05a742018-05-29 13:28:54 +010074 ProductServicesSpecific() bool
Colin Cross1332b002015-04-07 17:11:30 -070075 AConfig() Config
Colin Cross9272ade2016-08-17 15:24:12 -070076 DeviceConfig() DeviceConfig
Colin Crossf6566ed2015-03-24 11:13:38 -070077}
78
Colin Cross635c3b02016-05-18 15:37:25 -070079type BaseContext interface {
Colin Crossaabf6792017-11-29 00:27:14 -080080 BaseModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070081 androidBaseContext
82}
83
Colin Crossaabf6792017-11-29 00:27:14 -080084// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
85// a Config instead of an interface{}.
86type BaseModuleContext interface {
87 ModuleName() string
88 ModuleDir() string
89 Config() Config
90
91 ContainsProperty(name string) bool
92 Errorf(pos scanner.Position, fmt string, args ...interface{})
93 ModuleErrorf(fmt string, args ...interface{})
94 PropertyErrorf(property, fmt string, args ...interface{})
95 Failed() bool
96
97 // GlobWithDeps returns a list of files that match the specified pattern but do not match any
98 // of the patterns in excludes. It also adds efficient dependencies to rerun the primary
99 // builder whenever a file matching the pattern as added or removed, without rerunning if a
100 // file that does not match the pattern is added to a searched directory.
101 GlobWithDeps(pattern string, excludes []string) ([]string, error)
102
103 Fs() pathtools.FileSystem
104 AddNinjaFileDeps(deps ...string)
105}
106
Colin Cross635c3b02016-05-18 15:37:25 -0700107type ModuleContext interface {
Colin Crossf6566ed2015-03-24 11:13:38 -0700108 androidBaseContext
Colin Crossaabf6792017-11-29 00:27:14 -0800109 BaseModuleContext
Colin Cross3f40fa42015-01-30 17:27:36 -0800110
Colin Crossae887032017-10-23 17:16:14 -0700111 // Deprecated: use ModuleContext.Build instead.
Colin Cross0875c522017-11-28 17:34:01 -0800112 ModuleBuild(pctx PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -0700113
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700114 ExpandSources(srcFiles, excludes []string) Paths
Colin Cross366938f2017-12-11 16:29:02 -0800115 ExpandSource(srcFile, prop string) Path
Colin Cross2383f3b2018-02-06 14:40:13 -0800116 ExpandOptionalSource(srcFile *string, prop string) OptionalPath
Colin Crossfaeb7aa2017-02-01 14:12:44 -0800117 ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
Colin Cross7f19f372016-11-01 11:10:25 -0700118 Glob(globPattern string, excludes []string) Paths
Nan Zhang581fd212018-01-10 16:06:12 -0800119 GlobFiles(globPattern string, excludes []string) Paths
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700120
Colin Cross5c517922017-08-31 12:29:17 -0700121 InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
122 InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
Colin Cross3854a602016-01-11 12:49:11 -0800123 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700124 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800125
126 AddMissingDependencies(deps []string)
Colin Cross8d8f8e22016-08-03 11:57:50 -0700127
Colin Cross8d8f8e22016-08-03 11:57:50 -0700128 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700129 InstallInSanitizerDir() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +0900130 InstallInRecovery() bool
Nan Zhang6d34b302017-02-04 17:47:46 -0800131
132 RequiredModuleNames() []string
Colin Cross3f68a132017-10-23 17:10:29 -0700133
134 // android.ModuleContext methods
135 // These are duplicated instead of embedded so that can eventually be wrapped to take an
136 // android.Module instead of a blueprint.Module
137 OtherModuleName(m blueprint.Module) string
138 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
139 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
140
141 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
142 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
143
144 ModuleSubDir() string
145
Colin Cross35143d02017-11-16 00:11:20 -0800146 VisitDirectDepsBlueprint(visit func(blueprint.Module))
Colin Crossd11fcda2017-10-23 17:59:01 -0700147 VisitDirectDeps(visit func(Module))
Colin Crossee6143c2017-12-30 17:54:27 -0800148 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
Colin Crossd11fcda2017-10-23 17:59:01 -0700149 VisitDirectDepsIf(pred func(Module) bool, 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 VisitDepsDepthFirst(visit func(Module))
Colin Cross6b753602018-06-21 13:03:07 -0700152 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
Colin Crossd11fcda2017-10-23 17:59:01 -0700153 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
154 WalkDeps(visit func(Module, Module) bool)
Colin Cross3f68a132017-10-23 17:10:29 -0700155
Colin Cross0875c522017-11-28 17:34:01 -0800156 Variable(pctx PackageContext, name, value string)
157 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
Colin Crossae887032017-10-23 17:16:14 -0700158 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
159 // and performs more verification.
Colin Cross0875c522017-11-28 17:34:01 -0800160 Build(pctx PackageContext, params BuildParams)
Colin Cross3f68a132017-10-23 17:10:29 -0700161
Colin Cross0875c522017-11-28 17:34:01 -0800162 PrimaryModule() Module
163 FinalModule() Module
164 VisitAllModuleVariants(visit func(Module))
Colin Cross3f68a132017-10-23 17:10:29 -0700165
166 GetMissingDependencies() []string
Jeff Gaston088e29e2017-11-29 16:47:17 -0800167 Namespace() blueprint.Namespace
Colin Cross3f40fa42015-01-30 17:27:36 -0800168}
169
Colin Cross635c3b02016-05-18 15:37:25 -0700170type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800171 blueprint.Module
172
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700173 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
174 // but GenerateAndroidBuildActions also has access to Android-specific information.
175 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -0700176 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700177
Colin Cross1e676be2016-10-12 14:38:15 -0700178 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800179
Colin Cross635c3b02016-05-18 15:37:25 -0700180 base() *ModuleBase
Dan Willemsen0effe062015-11-30 16:06:01 -0800181 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700182 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800183 InstallInData() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700184 InstallInSanitizerDir() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +0900185 InstallInRecovery() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800186 SkipInstall()
Jiyong Park374510b2018-03-19 18:23:01 +0900187 ExportedToMake() bool
Colin Cross36242852017-06-23 15:06:31 -0700188
189 AddProperties(props ...interface{})
190 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700191
Colin Crossae887032017-10-23 17:16:14 -0700192 BuildParamsForTests() []BuildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800193}
194
Colin Crossfc754582016-05-17 16:34:16 -0700195type nameProperties struct {
196 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800197 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700198}
199
200type commonProperties struct {
Dan Willemsen0effe062015-11-30 16:06:01 -0800201 // emit build rules for this module
202 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800203
Colin Cross7d5136f2015-05-11 13:39:40 -0700204 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800205 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
206 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
207 // platform
Colin Cross7d716ba2017-11-01 10:38:29 -0700208 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700209
210 Target struct {
211 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700212 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700213 }
214 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700215 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700216 }
217 }
218
Colin Crossee0bc3b2018-10-02 22:01:37 -0700219 UseTargetVariants bool `blueprint:"mutated"`
220 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800221
Dan Willemsen782a2d12015-12-21 14:55:28 -0800222 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700223 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800224
Colin Cross55708f32017-03-20 13:23:34 -0700225 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700226 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700227
Jiyong Park2db76922017-11-08 16:03:48 +0900228 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
229 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
230 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700231 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700232
Jiyong Park2db76922017-11-08 16:03:48 +0900233 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
234 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
235 Soc_specific *bool
236
237 // whether this module is specific to a device, not only for SoC, but also for off-chip
238 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
239 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
240 // This implies `soc_specific:true`.
241 Device_specific *bool
242
243 // whether this module is specific to a software configuration of a product (e.g. country,
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900244 // network operator, etc). When set to true, it is installed into /product (or
245 // /system/product if product partition does not exist).
Jiyong Park2db76922017-11-08 16:03:48 +0900246 Product_specific *bool
247
Dario Frenifd05a742018-05-29 13:28:54 +0100248 // whether this module provides services owned by the OS provider to the core platform. When set
Dario Freni95cf7672018-08-17 00:57:57 +0100249 // to true, it is installed into /product_services (or /system/product_services if
250 // product_services partition does not exist).
251 Product_services_specific *bool
Dario Frenifd05a742018-05-29 13:28:54 +0100252
Jiyong Parkf9332f12018-02-01 00:54:12 +0900253 // Whether this module is installed to recovery partition
254 Recovery *bool
255
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700256 // init.rc files to be installed if this module is installed
257 Init_rc []string
258
Steven Moreland57a23d22018-04-04 15:42:19 -0700259 // VINTF manifest fragments to be installed if this module is installed
260 Vintf_fragments []string
261
Chris Wolfe998306e2016-08-15 14:47:23 -0400262 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700263 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400264
Colin Cross5aac3622017-08-31 15:07:09 -0700265 // relative path to a file to include in the list of notices for the device
266 Notice *string
267
Colin Crossa1ad8d12016-06-01 17:09:44 -0700268 // Set by TargetMutator
Colin Crossee0bc3b2018-10-02 22:01:37 -0700269 CompileTarget Target `blueprint:"mutated"`
270 CompileMultiTargets []Target `blueprint:"mutated"`
271 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800272
273 // Set by InitAndroidModule
274 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700275 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700276
277 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800278
279 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800280}
281
282type hostAndDeviceProperties struct {
Colin Crossa4190c12016-07-12 13:11:25 -0700283 Host_supported *bool
284 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800285}
286
Colin Crossc472d572015-03-17 15:06:21 -0700287type Multilib string
288
289const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800290 MultilibBoth Multilib = "both"
291 MultilibFirst Multilib = "first"
292 MultilibCommon Multilib = "common"
293 MultilibCommonFirst Multilib = "common_first"
294 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700295)
296
Colin Crossa1ad8d12016-06-01 17:09:44 -0700297type HostOrDeviceSupported int
298
299const (
300 _ HostOrDeviceSupported = iota
Dan Albert0981b5c2018-08-02 13:46:35 -0700301
302 // Host and HostCross are built by default. Device is not supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700303 HostSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700304
305 // Host is built by default. HostCross and Device are not supported.
Dan Albertc6345fb2016-10-20 01:36:11 -0700306 HostSupportedNoCross
Dan Albert0981b5c2018-08-02 13:46:35 -0700307
308 // Device is built by default. Host and HostCross are not supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700309 DeviceSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700310
311 // Device is built by default. Host and HostCross are supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700312 HostAndDeviceSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700313
314 // Host, HostCross, and Device are built by default.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700315 HostAndDeviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700316
317 // Nothing is supported. This is not exposed to the user, but used to mark a
318 // host only module as unsupported when the module type is not supported on
319 // the host OS. E.g. benchmarks are supported on Linux but not Darwin.
Dan Willemsen0b24c742016-10-04 15:13:37 -0700320 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700321)
322
Jiyong Park2db76922017-11-08 16:03:48 +0900323type moduleKind int
324
325const (
326 platformModule moduleKind = iota
327 deviceSpecificModule
328 socSpecificModule
329 productSpecificModule
Dario Frenifd05a742018-05-29 13:28:54 +0100330 productServicesSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900331)
332
333func (k moduleKind) String() string {
334 switch k {
335 case platformModule:
336 return "platform"
337 case deviceSpecificModule:
338 return "device-specific"
339 case socSpecificModule:
340 return "soc-specific"
341 case productSpecificModule:
342 return "product-specific"
Dario Frenifd05a742018-05-29 13:28:54 +0100343 case productServicesSpecificModule:
344 return "productservices-specific"
Jiyong Park2db76922017-11-08 16:03:48 +0900345 default:
346 panic(fmt.Errorf("unknown module kind %d", k))
347 }
348}
349
Colin Cross36242852017-06-23 15:06:31 -0700350func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800351 base := m.base()
352 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700353
Colin Cross36242852017-06-23 15:06:31 -0700354 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700355 &base.nameProperties,
356 &base.commonProperties,
357 &base.variableProperties)
Pirama Arumuga Nainar955dc492018-04-17 14:58:42 -0700358 base.customizableProperties = m.GetProperties()
Colin Cross5049f022015-03-18 13:28:46 -0700359}
360
Colin Cross36242852017-06-23 15:06:31 -0700361func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
362 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700363
364 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800365 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700366 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700367 base.commonProperties.ArchSpecific = true
Colin Crossee0bc3b2018-10-02 22:01:37 -0700368 base.commonProperties.UseTargetVariants = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800369
Dan Willemsen218f6562015-07-08 18:13:11 -0700370 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700371 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700372 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800373 }
374
Colin Cross36242852017-06-23 15:06:31 -0700375 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800376}
377
Colin Crossee0bc3b2018-10-02 22:01:37 -0700378func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
379 InitAndroidArchModule(m, hod, defaultMultilib)
380 m.base().commonProperties.UseTargetVariants = false
381}
382
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800383// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800384// modules. It should be included as an anonymous field in every module
385// struct definition. InitAndroidModule should then be called from the module's
386// factory function, and the return values from InitAndroidModule should be
387// returned from the factory function.
388//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800389// The ModuleBase type is responsible for implementing the GenerateBuildActions
390// method to support the blueprint.Module interface. This method will then call
391// the module's GenerateAndroidBuildActions method once for each build variant
392// that is to be built. GenerateAndroidBuildActions is passed a
393// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800394// AndroidModuleContext exposes extra functionality specific to the Android build
395// system including details about the particular build variant that is to be
396// generated.
397//
398// For example:
399//
400// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800401// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800402// )
403//
404// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800405// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800406// properties struct {
407// MyProperty string
408// }
409// }
410//
Colin Cross36242852017-06-23 15:06:31 -0700411// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800412// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700413// m.AddProperties(&m.properties)
414// android.InitAndroidModule(m)
415// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800416// }
417//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800418// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800419// // Get the CPU architecture for the current build variant.
420// variantArch := ctx.Arch()
421//
422// // ...
423// }
Colin Cross635c3b02016-05-18 15:37:25 -0700424type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800425 // Putting the curiously recurring thing pointing to the thing that contains
426 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700427 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700428 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800429
Colin Crossfc754582016-05-17 16:34:16 -0700430 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800431 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700432 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800433 hostAndDeviceProperties hostAndDeviceProperties
434 generalProperties []interface{}
Dan Willemsenb1957a52016-06-23 23:44:54 -0700435 archProperties []interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700436 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800437
438 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700439 installFiles Paths
440 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700441
442 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
443 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800444 installTarget WritablePath
445 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700446 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700447
Colin Cross178a5092016-09-13 13:42:32 -0700448 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700449
450 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700451
452 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700453 buildParams []BuildParams
Colin Crossa9d8bee2018-10-02 13:59:46 -0700454
455 prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool
Colin Cross36242852017-06-23 15:06:31 -0700456}
457
458func (a *ModuleBase) AddProperties(props ...interface{}) {
459 a.registerProps = append(a.registerProps, props...)
460}
461
462func (a *ModuleBase) GetProperties() []interface{} {
463 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800464}
465
Colin Crossae887032017-10-23 17:16:14 -0700466func (a *ModuleBase) BuildParamsForTests() []BuildParams {
Colin Crosscec81712017-07-13 14:43:27 -0700467 return a.buildParams
468}
469
Colin Crossa9d8bee2018-10-02 13:59:46 -0700470func (a *ModuleBase) Prefer32(prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool) {
471 a.prefer32 = prefer32
472}
473
Colin Crossce75d2c2016-10-06 16:12:58 -0700474// Name returns the name of the module. It may be overridden by individual module types, for
475// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700476func (a *ModuleBase) Name() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800477 return String(a.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700478}
479
Colin Crossce75d2c2016-10-06 16:12:58 -0700480// BaseModuleName returns the name of the module as specified in the blueprints file.
481func (a *ModuleBase) BaseModuleName() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800482 return String(a.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700483}
484
Colin Cross635c3b02016-05-18 15:37:25 -0700485func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800486 return a
487}
488
Colin Crossee0bc3b2018-10-02 22:01:37 -0700489func (a *ModuleBase) SetTarget(target Target, multiTargets []Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700490 a.commonProperties.CompileTarget = target
Colin Crossee0bc3b2018-10-02 22:01:37 -0700491 a.commonProperties.CompileMultiTargets = multiTargets
Colin Cross8b74d172016-09-13 09:59:14 -0700492 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700493}
494
Colin Crossa1ad8d12016-06-01 17:09:44 -0700495func (a *ModuleBase) Target() Target {
496 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800497}
498
Colin Cross8b74d172016-09-13 09:59:14 -0700499func (a *ModuleBase) TargetPrimary() bool {
500 return a.commonProperties.CompilePrimary
501}
502
Colin Crossee0bc3b2018-10-02 22:01:37 -0700503func (a *ModuleBase) MultiTargets() []Target {
504 return a.commonProperties.CompileMultiTargets
505}
506
Colin Crossa1ad8d12016-06-01 17:09:44 -0700507func (a *ModuleBase) Os() OsType {
508 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800509}
510
Colin Cross635c3b02016-05-18 15:37:25 -0700511func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700512 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800513}
514
Colin Cross635c3b02016-05-18 15:37:25 -0700515func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700516 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800517}
518
Dan Willemsen0b24c742016-10-04 15:13:37 -0700519func (a *ModuleBase) ArchSpecific() bool {
520 return a.commonProperties.ArchSpecific
521}
522
Colin Crossa1ad8d12016-06-01 17:09:44 -0700523func (a *ModuleBase) OsClassSupported() []OsClass {
524 switch a.commonProperties.HostOrDeviceSupported {
525 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700526 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700527 case HostSupportedNoCross:
528 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700529 case DeviceSupported:
530 return []OsClass{Device}
Dan Albert0981b5c2018-08-02 13:46:35 -0700531 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700532 var supported []OsClass
Dan Albert0981b5c2018-08-02 13:46:35 -0700533 if Bool(a.hostAndDeviceProperties.Host_supported) ||
534 (a.commonProperties.HostOrDeviceSupported == HostAndDeviceDefault &&
535 a.hostAndDeviceProperties.Host_supported == nil) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700536 supported = append(supported, Host, HostCross)
537 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700538 if a.hostAndDeviceProperties.Device_supported == nil ||
539 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700540 supported = append(supported, Device)
541 }
542 return supported
543 default:
544 return nil
545 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800546}
547
Colin Cross635c3b02016-05-18 15:37:25 -0700548func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800549 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
550 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700551 (a.hostAndDeviceProperties.Device_supported == nil ||
552 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800553}
554
Jiyong Parkc678ad32018-04-10 13:07:10 +0900555func (a *ModuleBase) Platform() bool {
Dario Frenifd05a742018-05-29 13:28:54 +0100556 return !a.DeviceSpecific() && !a.SocSpecific() && !a.ProductSpecific() && !a.ProductServicesSpecific()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900557}
558
559func (a *ModuleBase) DeviceSpecific() bool {
560 return Bool(a.commonProperties.Device_specific)
561}
562
563func (a *ModuleBase) SocSpecific() bool {
564 return Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
565}
566
567func (a *ModuleBase) ProductSpecific() bool {
568 return Bool(a.commonProperties.Product_specific)
569}
570
Dario Frenifd05a742018-05-29 13:28:54 +0100571func (a *ModuleBase) ProductServicesSpecific() bool {
Dario Freni95cf7672018-08-17 00:57:57 +0100572 return Bool(a.commonProperties.Product_services_specific)
Dario Frenifd05a742018-05-29 13:28:54 +0100573}
574
Colin Cross635c3b02016-05-18 15:37:25 -0700575func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800576 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800577 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800578 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800579 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800580}
581
Colin Crossce75d2c2016-10-06 16:12:58 -0700582func (a *ModuleBase) SkipInstall() {
583 a.commonProperties.SkipInstall = true
584}
585
Jiyong Park374510b2018-03-19 18:23:01 +0900586func (a *ModuleBase) ExportedToMake() bool {
587 return a.commonProperties.NamespaceExportedToMake
588}
589
Colin Cross635c3b02016-05-18 15:37:25 -0700590func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700591 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800592
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700593 result := Paths{}
Colin Cross6b753602018-06-21 13:03:07 -0700594 // TODO(ccross): we need to use WalkDeps and have some way to know which dependencies require installation
Colin Cross3f40fa42015-01-30 17:27:36 -0800595 ctx.VisitDepsDepthFirstIf(isFileInstaller,
596 func(m blueprint.Module) {
597 fileInstaller := m.(fileInstaller)
598 files := fileInstaller.filesToInstall()
599 result = append(result, files...)
600 })
601
602 return result
603}
604
Colin Cross635c3b02016-05-18 15:37:25 -0700605func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800606 return a.installFiles
607}
608
Colin Cross635c3b02016-05-18 15:37:25 -0700609func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800610 return p.noAddressSanitizer
611}
612
Colin Cross635c3b02016-05-18 15:37:25 -0700613func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800614 return false
615}
616
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700617func (p *ModuleBase) InstallInSanitizerDir() bool {
618 return false
619}
620
Jiyong Parkf9332f12018-02-01 00:54:12 +0900621func (p *ModuleBase) InstallInRecovery() bool {
622 return Bool(p.commonProperties.Recovery)
623}
624
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900625func (a *ModuleBase) Owner() string {
626 return String(a.commonProperties.Owner)
627}
628
Colin Cross0875c522017-11-28 17:34:01 -0800629func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700630 allInstalledFiles := Paths{}
631 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -0800632 ctx.VisitAllModuleVariants(func(module Module) {
633 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -0700634 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
635 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800636 })
637
Colin Cross0875c522017-11-28 17:34:01 -0800638 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -0700639
Jeff Gaston088e29e2017-11-29 16:47:17 -0800640 namespacePrefix := ctx.Namespace().(*Namespace).id
641 if namespacePrefix != "" {
642 namespacePrefix = namespacePrefix + "-"
643 }
644
Colin Cross3f40fa42015-01-30 17:27:36 -0800645 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800646 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -0800647 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700648 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800649 Output: name,
650 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -0800651 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700652 })
653 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700654 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700655 }
656
657 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800658 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -0800659 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700660 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800661 Output: name,
662 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -0700663 })
664 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700665 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700666 }
667
668 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800669 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -0800670 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800671 suffix = "-soong"
672 }
673
Jeff Gaston088e29e2017-11-29 16:47:17 -0800674 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -0800675 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700676 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -0800677 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -0700678 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800679 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700680
681 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800682 }
683}
684
Jiyong Park2db76922017-11-08 16:03:48 +0900685func determineModuleKind(a *ModuleBase, ctx blueprint.BaseModuleContext) moduleKind {
686 var socSpecific = Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
687 var deviceSpecific = Bool(a.commonProperties.Device_specific)
688 var productSpecific = Bool(a.commonProperties.Product_specific)
Dario Freni95cf7672018-08-17 00:57:57 +0100689 var productServicesSpecific = Bool(a.commonProperties.Product_services_specific)
Jiyong Park2db76922017-11-08 16:03:48 +0900690
Dario Frenifd05a742018-05-29 13:28:54 +0100691 msg := "conflicting value set here"
692 if socSpecific && deviceSpecific {
693 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
Jiyong Park2db76922017-11-08 16:03:48 +0900694 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
Dario Frenifd05a742018-05-29 13:28:54 +0100705 if productSpecific && productServicesSpecific {
706 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and product_services at the same time.")
707 ctx.PropertyErrorf("product_services_specific", msg)
708 }
709
710 if (socSpecific || deviceSpecific) && (productSpecific || productServicesSpecific) {
711 if productSpecific {
712 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
713 } else {
714 ctx.PropertyErrorf("product_services_specific", "a module cannot be specific to SoC or device and product_services at the same time.")
715 }
716 if deviceSpecific {
717 ctx.PropertyErrorf("device_specific", msg)
718 } else {
719 if Bool(a.commonProperties.Vendor) {
720 ctx.PropertyErrorf("vendor", msg)
721 }
722 if Bool(a.commonProperties.Proprietary) {
723 ctx.PropertyErrorf("proprietary", msg)
724 }
725 if Bool(a.commonProperties.Soc_specific) {
726 ctx.PropertyErrorf("soc_specific", msg)
727 }
728 }
729 }
730
Jiyong Park2db76922017-11-08 16:03:48 +0900731 if productSpecific {
732 return productSpecificModule
Dario Frenifd05a742018-05-29 13:28:54 +0100733 } else if productServicesSpecific {
734 return productServicesSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900735 } else if deviceSpecific {
736 return deviceSpecificModule
737 } else if socSpecific {
738 return socSpecificModule
739 } else {
740 return platformModule
741 }
742}
743
Colin Cross635c3b02016-05-18 15:37:25 -0700744func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700745 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700746 target: a.commonProperties.CompileTarget,
747 targetPrimary: a.commonProperties.CompilePrimary,
Colin Crossee0bc3b2018-10-02 22:01:37 -0700748 multiTargets: a.commonProperties.CompileMultiTargets,
Jiyong Park2db76922017-11-08 16:03:48 +0900749 kind: determineModuleKind(a, ctx),
Colin Cross8b74d172016-09-13 09:59:14 -0700750 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800751 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800752}
753
Colin Cross0875c522017-11-28 17:34:01 -0800754func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
755 ctx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700756 module: a.module,
Colin Cross0875c522017-11-28 17:34:01 -0800757 ModuleContext: blueprintCtx,
758 androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
759 installDeps: a.computeInstallDeps(blueprintCtx),
Colin Cross6362e272015-10-29 15:25:03 -0700760 installFiles: a.installFiles,
Colin Cross0875c522017-11-28 17:34:01 -0800761 missingDeps: blueprintCtx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800762 }
763
Colin Cross67a5c132017-05-09 13:45:28 -0700764 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
765 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -0800766 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
767 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -0700768 }
Colin Cross0875c522017-11-28 17:34:01 -0800769 if !ctx.PrimaryArch() {
770 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -0700771 }
772
773 ctx.Variable(pctx, "moduleDesc", desc)
774
775 s := ""
776 if len(suffix) > 0 {
777 s = " [" + strings.Join(suffix, " ") + "]"
778 }
779 ctx.Variable(pctx, "moduleDescSuffix", s)
780
Colin Cross9b1d13d2016-09-19 15:18:11 -0700781 if a.Enabled() {
Colin Cross0875c522017-11-28 17:34:01 -0800782 a.module.GenerateAndroidBuildActions(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700783 if ctx.Failed() {
784 return
785 }
786
Colin Cross0875c522017-11-28 17:34:01 -0800787 a.installFiles = append(a.installFiles, ctx.installFiles...)
788 a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800789 }
790
Colin Cross9b1d13d2016-09-19 15:18:11 -0700791 if a == ctx.FinalModule().(Module).base() {
792 a.generateModuleTarget(ctx)
793 if ctx.Failed() {
794 return
795 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800796 }
Colin Crosscec81712017-07-13 14:43:27 -0700797
Colin Cross0875c522017-11-28 17:34:01 -0800798 a.buildParams = ctx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800799}
800
Colin Crossf6566ed2015-03-24 11:13:38 -0700801type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700802 target Target
Colin Crossee0bc3b2018-10-02 22:01:37 -0700803 multiTargets []Target
Colin Cross8b74d172016-09-13 09:59:14 -0700804 targetPrimary bool
805 debug bool
Jiyong Park2db76922017-11-08 16:03:48 +0900806 kind moduleKind
Colin Cross8b74d172016-09-13 09:59:14 -0700807 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700808}
809
Colin Cross3f40fa42015-01-30 17:27:36 -0800810type androidModuleContext struct {
811 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700812 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700813 installDeps Paths
814 installFiles Paths
815 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800816 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700817 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700818
819 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700820 buildParams []BuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800821}
822
Colin Cross67a5c132017-05-09 13:45:28 -0700823func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross0875c522017-11-28 17:34:01 -0800824 a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700825 Rule: ErrorRule,
826 Description: desc,
827 Outputs: outputs,
828 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800829 Args: map[string]string{
830 "error": err.Error(),
831 },
832 })
833 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800834}
835
Colin Crossaabf6792017-11-29 00:27:14 -0800836func (a *androidModuleContext) Config() Config {
837 return a.ModuleContext.Config().(Config)
838}
839
Colin Cross0875c522017-11-28 17:34:01 -0800840func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
Colin Crossae887032017-10-23 17:16:14 -0700841 a.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800842}
843
Colin Cross0875c522017-11-28 17:34:01 -0800844func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700845 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700846 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -0800847 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800848 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700849 Outputs: params.Outputs.Strings(),
850 ImplicitOutputs: params.ImplicitOutputs.Strings(),
851 Inputs: params.Inputs.Strings(),
852 Implicits: params.Implicits.Strings(),
853 OrderOnly: params.OrderOnly.Strings(),
854 Args: params.Args,
855 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700856 }
857
Colin Cross33bfb0a2016-11-21 17:23:08 -0800858 if params.Depfile != nil {
859 bparams.Depfile = params.Depfile.String()
860 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700861 if params.Output != nil {
862 bparams.Outputs = append(bparams.Outputs, params.Output.String())
863 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700864 if params.ImplicitOutput != nil {
865 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
866 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700867 if params.Input != nil {
868 bparams.Inputs = append(bparams.Inputs, params.Input.String())
869 }
870 if params.Implicit != nil {
871 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
872 }
873
Colin Crossfe4bc362018-09-12 10:02:13 -0700874 bparams.Outputs = proptools.NinjaEscape(bparams.Outputs)
875 bparams.ImplicitOutputs = proptools.NinjaEscape(bparams.ImplicitOutputs)
876 bparams.Inputs = proptools.NinjaEscape(bparams.Inputs)
877 bparams.Implicits = proptools.NinjaEscape(bparams.Implicits)
878 bparams.OrderOnly = proptools.NinjaEscape(bparams.OrderOnly)
879 bparams.Depfile = proptools.NinjaEscape([]string{bparams.Depfile})[0]
880
Colin Cross0875c522017-11-28 17:34:01 -0800881 return bparams
882}
883
884func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
885 a.ModuleContext.Variable(pctx.PackageContext, name, value)
886}
887
888func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
889 argNames ...string) blueprint.Rule {
890
891 return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
892}
893
894func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
895 if a.config.captureBuild {
896 a.buildParams = append(a.buildParams, params)
897 }
898
899 bparams := convertBuildParams(params)
900
901 if bparams.Description != "" {
902 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
903 }
904
Colin Cross6ff51382015-12-17 16:39:19 -0800905 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700906 a.ninjaError(bparams.Description, bparams.Outputs,
907 fmt.Errorf("module %s missing dependencies: %s\n",
908 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800909 return
910 }
911
Colin Cross0875c522017-11-28 17:34:01 -0800912 a.ModuleContext.Build(pctx.PackageContext, bparams)
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700913}
914
Colin Cross6ff51382015-12-17 16:39:19 -0800915func (a *androidModuleContext) GetMissingDependencies() []string {
916 return a.missingDeps
917}
918
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800919func (a *androidModuleContext) AddMissingDependencies(deps []string) {
920 if deps != nil {
921 a.missingDeps = append(a.missingDeps, deps...)
Colin Crossd11fcda2017-10-23 17:59:01 -0700922 a.missingDeps = FirstUniqueStrings(a.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800923 }
924}
925
Colin Crossd11fcda2017-10-23 17:59:01 -0700926func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
927 aModule, _ := module.(Module)
928 if aModule == nil {
929 a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
930 return nil
931 }
932
933 if !aModule.Enabled() {
Colin Cross6510f912017-11-29 00:27:14 -0800934 if a.Config().AllowMissingDependencies() {
Colin Crossd11fcda2017-10-23 17:59:01 -0700935 a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
936 } else {
937 a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
938 }
939 return nil
940 }
941
942 return aModule
943}
944
Colin Cross35143d02017-11-16 00:11:20 -0800945func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
946 a.ModuleContext.VisitDirectDeps(visit)
947}
948
Colin Crossd11fcda2017-10-23 17:59:01 -0700949func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
950 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
951 if aModule := a.validateAndroidModule(module); aModule != nil {
952 visit(aModule)
953 }
954 })
955}
956
Colin Crossee6143c2017-12-30 17:54:27 -0800957func (a *androidModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
958 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
959 if aModule := a.validateAndroidModule(module); aModule != nil {
960 if a.ModuleContext.OtherModuleDependencyTag(aModule) == tag {
961 visit(aModule)
962 }
963 }
964 })
965}
966
Colin Crossd11fcda2017-10-23 17:59:01 -0700967func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
968 a.ModuleContext.VisitDirectDepsIf(
969 // pred
970 func(module blueprint.Module) bool {
971 if aModule := a.validateAndroidModule(module); aModule != nil {
972 return pred(aModule)
973 } else {
974 return false
975 }
976 },
977 // visit
978 func(module blueprint.Module) {
979 visit(module.(Module))
980 })
981}
982
983func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
984 a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
985 if aModule := a.validateAndroidModule(module); aModule != nil {
986 visit(aModule)
987 }
988 })
989}
990
991func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
992 a.ModuleContext.VisitDepsDepthFirstIf(
993 // pred
994 func(module blueprint.Module) bool {
995 if aModule := a.validateAndroidModule(module); aModule != nil {
996 return pred(aModule)
997 } else {
998 return false
999 }
1000 },
1001 // visit
1002 func(module blueprint.Module) {
1003 visit(module.(Module))
1004 })
1005}
1006
1007func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
1008 a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
1009 childAndroidModule := a.validateAndroidModule(child)
1010 parentAndroidModule := a.validateAndroidModule(parent)
1011 if childAndroidModule != nil && parentAndroidModule != nil {
1012 return visit(childAndroidModule, parentAndroidModule)
1013 } else {
1014 return false
1015 }
1016 })
1017}
1018
Colin Cross0875c522017-11-28 17:34:01 -08001019func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
1020 a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
1021 visit(module.(Module))
1022 })
1023}
1024
1025func (a *androidModuleContext) PrimaryModule() Module {
1026 return a.ModuleContext.PrimaryModule().(Module)
1027}
1028
1029func (a *androidModuleContext) FinalModule() Module {
1030 return a.ModuleContext.FinalModule().(Module)
1031}
1032
Colin Crossa1ad8d12016-06-01 17:09:44 -07001033func (a *androidBaseContextImpl) Target() Target {
1034 return a.target
1035}
1036
Colin Cross8b74d172016-09-13 09:59:14 -07001037func (a *androidBaseContextImpl) TargetPrimary() bool {
1038 return a.targetPrimary
1039}
1040
Colin Crossee0bc3b2018-10-02 22:01:37 -07001041func (a *androidBaseContextImpl) MultiTargets() []Target {
1042 return a.multiTargets
1043}
1044
Colin Crossf6566ed2015-03-24 11:13:38 -07001045func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001046 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -08001047}
1048
Colin Crossa1ad8d12016-06-01 17:09:44 -07001049func (a *androidBaseContextImpl) Os() OsType {
1050 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -08001051}
1052
Colin Crossf6566ed2015-03-24 11:13:38 -07001053func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001054 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -07001055}
1056
1057func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001058 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -07001059}
1060
Colin Cross0af4b842015-04-30 16:36:18 -07001061func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001062 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -07001063}
1064
Colin Cross3edeee12017-04-04 12:59:48 -07001065func (a *androidBaseContextImpl) Windows() bool {
1066 return a.target.Os == Windows
1067}
1068
Colin Crossf6566ed2015-03-24 11:13:38 -07001069func (a *androidBaseContextImpl) Debug() bool {
1070 return a.debug
1071}
1072
Colin Cross1e7d3702016-08-24 15:25:47 -07001073func (a *androidBaseContextImpl) PrimaryArch() bool {
Colin Cross67a5c132017-05-09 13:45:28 -07001074 if len(a.config.Targets[a.target.Os.Class]) <= 1 {
1075 return true
1076 }
Colin Cross1e7d3702016-08-24 15:25:47 -07001077 return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
1078}
1079
Colin Cross1332b002015-04-07 17:11:30 -07001080func (a *androidBaseContextImpl) AConfig() Config {
1081 return a.config
1082}
1083
Colin Cross9272ade2016-08-17 15:24:12 -07001084func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
1085 return DeviceConfig{a.config.deviceConfig}
1086}
1087
Jiyong Park2db76922017-11-08 16:03:48 +09001088func (a *androidBaseContextImpl) Platform() bool {
1089 return a.kind == platformModule
1090}
1091
1092func (a *androidBaseContextImpl) DeviceSpecific() bool {
1093 return a.kind == deviceSpecificModule
1094}
1095
1096func (a *androidBaseContextImpl) SocSpecific() bool {
1097 return a.kind == socSpecificModule
1098}
1099
1100func (a *androidBaseContextImpl) ProductSpecific() bool {
1101 return a.kind == productSpecificModule
Dan Willemsen782a2d12015-12-21 14:55:28 -08001102}
1103
Dario Frenifd05a742018-05-29 13:28:54 +01001104func (a *androidBaseContextImpl) ProductServicesSpecific() bool {
1105 return a.kind == productServicesSpecificModule
1106}
1107
Jiyong Park5baac542018-08-28 09:55:37 +09001108// Makes this module a platform module, i.e. not specific to soc, device,
1109// product, or product_services.
1110func (a *ModuleBase) MakeAsPlatform() {
1111 a.commonProperties.Vendor = boolPtr(false)
1112 a.commonProperties.Proprietary = boolPtr(false)
1113 a.commonProperties.Soc_specific = boolPtr(false)
1114 a.commonProperties.Product_specific = boolPtr(false)
1115 a.commonProperties.Product_services_specific = boolPtr(false)
1116}
1117
Colin Cross8d8f8e22016-08-03 11:57:50 -07001118func (a *androidModuleContext) InstallInData() bool {
1119 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -08001120}
1121
Vishwath Mohan1dd88392017-03-29 22:00:18 -07001122func (a *androidModuleContext) InstallInSanitizerDir() bool {
1123 return a.module.InstallInSanitizerDir()
1124}
1125
Jiyong Parkf9332f12018-02-01 00:54:12 +09001126func (a *androidModuleContext) InstallInRecovery() bool {
1127 return a.module.InstallInRecovery()
1128}
1129
Colin Cross893d8162017-04-26 17:34:03 -07001130func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
1131 if a.module.base().commonProperties.SkipInstall {
1132 return true
1133 }
1134
Colin Cross3607f212018-05-07 15:28:05 -07001135 // We'll need a solution for choosing which of modules with the same name in different
1136 // namespaces to install. For now, reuse the list of namespaces exported to Make as the
1137 // list of namespaces to install in a Soong-only build.
1138 if !a.module.base().commonProperties.NamespaceExportedToMake {
1139 return true
1140 }
1141
Colin Cross893d8162017-04-26 17:34:03 -07001142 if a.Device() {
Colin Cross6510f912017-11-29 00:27:14 -08001143 if a.Config().SkipDeviceInstall() {
Colin Cross893d8162017-04-26 17:34:03 -07001144 return true
1145 }
1146
Colin Cross6510f912017-11-29 00:27:14 -08001147 if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -07001148 return true
1149 }
1150 }
1151
1152 return false
1153}
1154
Colin Cross5c517922017-08-31 12:29:17 -07001155func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -07001156 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -07001157 return a.installFile(installPath, name, srcPath, Cp, deps)
1158}
1159
1160func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
1161 deps ...Path) OutputPath {
1162 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
1163}
1164
1165func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
1166 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -07001167
Dan Willemsen782a2d12015-12-21 14:55:28 -08001168 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001169 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -08001170
Colin Cross893d8162017-04-26 17:34:03 -07001171 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001172
Dan Willemsen322acaf2016-01-12 23:07:05 -08001173 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -07001174
Colin Cross89562dc2016-10-03 17:47:19 -07001175 var implicitDeps, orderOnlyDeps Paths
1176
1177 if a.Host() {
1178 // Installed host modules might be used during the build, depend directly on their
1179 // dependencies so their timestamp is updated whenever their dependency is updated
1180 implicitDeps = deps
1181 } else {
1182 orderOnlyDeps = deps
1183 }
1184
Colin Crossae887032017-10-23 17:16:14 -07001185 a.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -07001186 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -07001187 Description: "install " + fullInstallPath.Base(),
1188 Output: fullInstallPath,
1189 Input: srcPath,
1190 Implicits: implicitDeps,
1191 OrderOnly: orderOnlyDeps,
Colin Cross6510f912017-11-29 00:27:14 -08001192 Default: !a.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -08001193 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001194
Dan Willemsen322acaf2016-01-12 23:07:05 -08001195 a.installFiles = append(a.installFiles, fullInstallPath)
1196 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001197 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -07001198 return fullInstallPath
1199}
1200
Colin Cross3854a602016-01-11 12:49:11 -08001201func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
1202 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001203 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -08001204
Colin Cross893d8162017-04-26 17:34:03 -07001205 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001206
Colin Crossae887032017-10-23 17:16:14 -07001207 a.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -07001208 Rule: Symlink,
1209 Description: "install symlink " + fullInstallPath.Base(),
1210 Output: fullInstallPath,
1211 OrderOnly: Paths{srcPath},
Colin Cross6510f912017-11-29 00:27:14 -08001212 Default: !a.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -08001213 Args: map[string]string{
1214 "fromPath": srcPath.String(),
1215 },
1216 })
Colin Cross3854a602016-01-11 12:49:11 -08001217
Colin Cross12fc4972016-01-11 12:49:11 -08001218 a.installFiles = append(a.installFiles, fullInstallPath)
1219 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1220 }
Colin Cross3854a602016-01-11 12:49:11 -08001221 return fullInstallPath
1222}
1223
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001224func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001225 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1226}
1227
Colin Cross3f40fa42015-01-30 17:27:36 -08001228type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001229 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001230}
1231
1232func isFileInstaller(m blueprint.Module) bool {
1233 _, ok := m.(fileInstaller)
1234 return ok
1235}
1236
1237func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -07001238 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -08001239 return ok
1240}
Colin Crossfce53272015-04-08 11:21:40 -07001241
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001242func findStringInSlice(str string, slice []string) int {
1243 for i, s := range slice {
1244 if s == str {
1245 return i
Colin Crossfce53272015-04-08 11:21:40 -07001246 }
1247 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001248 return -1
1249}
1250
Colin Cross068e0fe2016-12-13 15:23:47 -08001251func SrcIsModule(s string) string {
1252 if len(s) > 1 && s[0] == ':' {
1253 return s[1:]
1254 }
1255 return ""
1256}
1257
1258type sourceDependencyTag struct {
1259 blueprint.BaseDependencyTag
1260}
1261
1262var SourceDepTag sourceDependencyTag
1263
Colin Cross366938f2017-12-11 16:29:02 -08001264// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
1265// using ":module" syntax, if any.
Colin Cross068e0fe2016-12-13 15:23:47 -08001266func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
1267 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -07001268 set := make(map[string]bool)
1269
Colin Cross068e0fe2016-12-13 15:23:47 -08001270 for _, s := range srcFiles {
1271 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -07001272 if _, found := set[m]; found {
1273 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
1274 } else {
1275 set[m] = true
1276 deps = append(deps, m)
1277 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001278 }
1279 }
1280
1281 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
1282}
1283
Colin Cross366938f2017-12-11 16:29:02 -08001284// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
1285// using ":module" syntax, if any.
1286func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
1287 if s != nil {
1288 if m := SrcIsModule(*s); m != "" {
1289 ctx.AddDependency(ctx.Module(), SourceDepTag, m)
1290 }
1291 }
1292}
1293
Colin Cross068e0fe2016-12-13 15:23:47 -08001294type SourceFileProducer interface {
1295 Srcs() Paths
1296}
1297
1298// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001299// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001300func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001301 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
1302}
1303
Colin Cross366938f2017-12-11 16:29:02 -08001304// Returns a single path expanded from globs and modules referenced using ":module" syntax.
1305// ExtractSourceDeps must have already been called during the dependency resolution phase.
1306func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path {
1307 srcFiles := ctx.ExpandSourcesSubDir([]string{srcFile}, nil, "")
1308 if len(srcFiles) == 1 {
1309 return srcFiles[0]
1310 } else {
1311 ctx.PropertyErrorf(prop, "module providing %s must produce exactly one file", prop)
1312 return nil
1313 }
1314}
1315
Colin Cross2383f3b2018-02-06 14:40:13 -08001316// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
1317// the srcFile is non-nil.
1318// ExtractSourceDeps must have already been called during the dependency resolution phase.
1319func (ctx *androidModuleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
1320 if srcFile != nil {
1321 return OptionalPathForPath(ctx.ExpandSource(*srcFile, prop))
1322 }
1323 return OptionalPath{}
1324}
1325
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001326func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001327 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001328
Colin Cross461b4452018-02-23 09:22:42 -08001329 var expandedExcludes []string
1330 if excludes != nil {
1331 expandedExcludes = make([]string, 0, len(excludes))
1332 }
Nan Zhang27e284d2018-02-09 21:03:53 +00001333
1334 for _, e := range excludes {
1335 if m := SrcIsModule(e); m != "" {
1336 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
1337 if module == nil {
1338 // Error will have been handled by ExtractSourcesDeps
1339 continue
1340 }
1341 if srcProducer, ok := module.(SourceFileProducer); ok {
1342 expandedExcludes = append(expandedExcludes, srcProducer.Srcs().Strings()...)
1343 } else {
1344 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1345 }
1346 } else {
1347 expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e))
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001348 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001349 }
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001350 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -07001351 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -08001352 if m := SrcIsModule(s); m != "" {
1353 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
Colin Cross0617bb82017-10-24 13:01:18 -07001354 if module == nil {
1355 // Error will have been handled by ExtractSourcesDeps
1356 continue
1357 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001358 if srcProducer, ok := module.(SourceFileProducer); ok {
Nan Zhang27e284d2018-02-09 21:03:53 +00001359 moduleSrcs := srcProducer.Srcs()
1360 for _, e := range expandedExcludes {
1361 for j, ms := range moduleSrcs {
1362 if ms.String() == e {
1363 moduleSrcs = append(moduleSrcs[:j], moduleSrcs[j+1:]...)
1364 }
1365 }
1366 }
1367 expandedSrcFiles = append(expandedSrcFiles, moduleSrcs...)
Colin Cross068e0fe2016-12-13 15:23:47 -08001368 } else {
1369 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1370 }
1371 } else if pathtools.IsGlob(s) {
Dan Willemsen540a78c2018-02-26 21:50:08 -08001372 globbedSrcFiles := ctx.GlobFiles(filepath.Join(prefix, s), expandedExcludes)
Colin Cross05a39cb2017-10-09 13:35:19 -07001373 for i, s := range globbedSrcFiles {
1374 globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001375 }
Colin Cross05a39cb2017-10-09 13:35:19 -07001376 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
Colin Cross8f101b42015-06-17 15:09:06 -07001377 } else {
Nan Zhang27e284d2018-02-09 21:03:53 +00001378 p := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
1379 j := findStringInSlice(p.String(), expandedExcludes)
1380 if j == -1 {
1381 expandedSrcFiles = append(expandedSrcFiles, p)
1382 }
1383
Colin Cross8f101b42015-06-17 15:09:06 -07001384 }
1385 }
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001386 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -07001387}
1388
Nan Zhang6d34b302017-02-04 17:47:46 -08001389func (ctx *androidModuleContext) RequiredModuleNames() []string {
1390 return ctx.module.base().commonProperties.Required
1391}
1392
Colin Cross7f19f372016-11-01 11:10:25 -07001393func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
1394 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001395 if err != nil {
1396 ctx.ModuleErrorf("glob: %s", err.Error())
1397 }
Dan Willemsen540a78c2018-02-26 21:50:08 -08001398 return pathsForModuleSrcFromFullPath(ctx, ret, true)
Colin Crossfce53272015-04-08 11:21:40 -07001399}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001400
Nan Zhang581fd212018-01-10 16:06:12 -08001401func (ctx *androidModuleContext) GlobFiles(globPattern string, excludes []string) Paths {
Dan Willemsen540a78c2018-02-26 21:50:08 -08001402 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Nan Zhang581fd212018-01-10 16:06:12 -08001403 if err != nil {
1404 ctx.ModuleErrorf("glob: %s", err.Error())
1405 }
Dan Willemsen540a78c2018-02-26 21:50:08 -08001406 return pathsForModuleSrcFromFullPath(ctx, ret, false)
Nan Zhang581fd212018-01-10 16:06:12 -08001407}
1408
Colin Cross463a90e2015-06-17 14:20:06 -07001409func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001410 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001411}
1412
Colin Cross0875c522017-11-28 17:34:01 -08001413func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001414 return &buildTargetSingleton{}
1415}
1416
Colin Cross87d8b562017-04-25 10:01:55 -07001417func parentDir(dir string) string {
1418 dir, _ = filepath.Split(dir)
1419 return filepath.Clean(dir)
1420}
1421
Colin Cross1f8c52b2015-06-16 16:38:17 -07001422type buildTargetSingleton struct{}
1423
Colin Cross0875c522017-11-28 17:34:01 -08001424func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1425 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07001426
Colin Cross0875c522017-11-28 17:34:01 -08001427 mmTarget := func(dir string) WritablePath {
1428 return PathForPhony(ctx,
1429 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07001430 }
1431
Colin Cross0875c522017-11-28 17:34:01 -08001432 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001433
Colin Cross0875c522017-11-28 17:34:01 -08001434 ctx.VisitAllModules(func(module Module) {
1435 blueprintDir := module.base().blueprintDir
1436 installTarget := module.base().installTarget
1437 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07001438
Colin Cross0875c522017-11-28 17:34:01 -08001439 if checkbuildTarget != nil {
1440 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1441 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1442 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001443
Colin Cross0875c522017-11-28 17:34:01 -08001444 if installTarget != nil {
1445 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001446 }
1447 })
1448
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001449 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001450 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001451 suffix = "-soong"
1452 }
1453
Colin Cross1f8c52b2015-06-16 16:38:17 -07001454 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08001455 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001456 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001457 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001458 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001459 })
1460
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001461 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08001462 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001463 return
1464 }
1465
Colin Cross0875c522017-11-28 17:34:01 -08001466 sortedKeys := func(m map[string]Paths) []string {
1467 s := make([]string, 0, len(m))
1468 for k := range m {
1469 s = append(s, k)
1470 }
1471 sort.Strings(s)
1472 return s
1473 }
1474
Colin Cross87d8b562017-04-25 10:01:55 -07001475 // Ensure ancestor directories are in modulesInDir
1476 dirs := sortedKeys(modulesInDir)
1477 for _, dir := range dirs {
1478 dir := parentDir(dir)
1479 for dir != "." && dir != "/" {
1480 if _, exists := modulesInDir[dir]; exists {
1481 break
1482 }
1483 modulesInDir[dir] = nil
1484 dir = parentDir(dir)
1485 }
1486 }
1487
1488 // Make directories build their direct subdirectories
1489 dirs = sortedKeys(modulesInDir)
1490 for _, dir := range dirs {
1491 p := parentDir(dir)
1492 if p != "." && p != "/" {
1493 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1494 }
1495 }
1496
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001497 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1498 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1499 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001500 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08001501 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001502 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001503 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07001504 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001505 // HACK: checkbuild should be an optional build, but force it
1506 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08001507 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001508 })
1509 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001510
1511 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1512 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001513 ctx.VisitAllModules(func(module Module) {
1514 if module.Enabled() {
1515 os := module.Target().Os
1516 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001517 }
1518 })
1519
Colin Cross0875c522017-11-28 17:34:01 -08001520 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001521 for os, deps := range osDeps {
1522 var className string
1523
1524 switch os.Class {
1525 case Host:
1526 className = "host"
1527 case HostCross:
1528 className = "host-cross"
1529 case Device:
1530 className = "target"
1531 default:
1532 continue
1533 }
1534
Colin Cross0875c522017-11-28 17:34:01 -08001535 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001536 osClass[className] = append(osClass[className], name)
1537
Colin Cross0875c522017-11-28 17:34:01 -08001538 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001539 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001540 Output: name,
1541 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07001542 })
1543 }
1544
1545 // Wrap those into host|host-cross|target phony rules
1546 osClasses := sortedKeys(osClass)
1547 for _, class := range osClasses {
Colin Cross0875c522017-11-28 17:34:01 -08001548 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001549 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001550 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07001551 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07001552 })
1553 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001554}
Colin Crossd779da42015-12-17 18:00:23 -08001555
Colin Cross2465c3d2018-09-28 10:19:18 -07001556type ModulesByName struct {
1557 slice []blueprint.Module
Colin Crossd779da42015-12-17 18:00:23 -08001558 ctx interface {
1559 ModuleName(blueprint.Module) string
1560 ModuleSubDir(blueprint.Module) string
1561 }
1562}
1563
Colin Cross2465c3d2018-09-28 10:19:18 -07001564func (s ModulesByName) Len() int { return len(s.slice) }
1565func (s ModulesByName) Less(i, j int) bool {
Colin Crossd779da42015-12-17 18:00:23 -08001566 mi, mj := s.slice[i], s.slice[j]
1567 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1568
1569 if ni != nj {
1570 return ni < nj
1571 } else {
1572 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1573 }
1574}
Colin Cross2465c3d2018-09-28 10:19:18 -07001575func (s ModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }
Brandon Lee5d45c6f2018-08-15 15:35:38 -07001576
1577// Collect information for opening IDE project files in java/jdeps.go.
1578type IDEInfo interface {
1579 IDEInfo(ideInfo *IdeInfo)
1580 BaseModuleName() string
1581}
1582
1583// Extract the base module name from the Import name.
1584// Often the Import name has a prefix "prebuilt_".
1585// Remove the prefix explicitly if needed
1586// until we find a better solution to get the Import name.
1587type IDECustomizedModuleName interface {
1588 IDECustomizedModuleName() string
1589}
1590
1591type IdeInfo struct {
1592 Deps []string `json:"dependencies,omitempty"`
1593 Srcs []string `json:"srcs,omitempty"`
1594 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
1595 Jarjar_rules []string `json:"jarjar_rules,omitempty"`
1596 Jars []string `json:"jars,omitempty"`
1597 Classes []string `json:"class,omitempty"`
1598 Installed_paths []string `json:"installed,omitempty"`
1599}