blob: bbe7d3646fe415e2f3d4272b138482c8eb82b39e [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
Dan Willemsen569edc52018-11-19 09:33:29 -0800268 Dist struct {
269 // copy the output of this module to the $DIST_DIR when `dist` is specified on the
270 // command line and any of these targets are also on the command line, or otherwise
271 // built
272 Targets []string `android:"arch_variant"`
273
274 // The name of the output artifact. This defaults to the basename of the output of
275 // the module.
276 Dest *string `android:"arch_variant"`
277
278 // The directory within the dist directory to store the artifact. Defaults to the
279 // top level directory ("").
280 Dir *string `android:"arch_variant"`
281
282 // A suffix to add to the artifact file name (before any extension).
283 Suffix *string `android:"arch_variant"`
284 } `android:"arch_variant"`
285
Colin Crossa1ad8d12016-06-01 17:09:44 -0700286 // Set by TargetMutator
Colin Crossee0bc3b2018-10-02 22:01:37 -0700287 CompileTarget Target `blueprint:"mutated"`
288 CompileMultiTargets []Target `blueprint:"mutated"`
289 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800290
291 // Set by InitAndroidModule
292 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700293 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700294
295 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800296
297 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800298}
299
300type hostAndDeviceProperties struct {
Colin Cross4e81d702018-11-09 10:36:55 -0800301 // If set to true, build a variant of the module for the host. Defaults to false.
302 Host_supported *bool
303
304 // If set to true, build a variant of the module for the device. Defaults to true.
Colin Crossa4190c12016-07-12 13:11:25 -0700305 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800306}
307
Colin Crossc472d572015-03-17 15:06:21 -0700308type Multilib string
309
310const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800311 MultilibBoth Multilib = "both"
312 MultilibFirst Multilib = "first"
313 MultilibCommon Multilib = "common"
314 MultilibCommonFirst Multilib = "common_first"
315 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700316)
317
Colin Crossa1ad8d12016-06-01 17:09:44 -0700318type HostOrDeviceSupported int
319
320const (
321 _ HostOrDeviceSupported = iota
Dan Albert0981b5c2018-08-02 13:46:35 -0700322
323 // Host and HostCross are built by default. Device is not supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700324 HostSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700325
326 // Host is built by default. HostCross and Device are not supported.
Dan Albertc6345fb2016-10-20 01:36:11 -0700327 HostSupportedNoCross
Dan Albert0981b5c2018-08-02 13:46:35 -0700328
329 // Device is built by default. Host and HostCross are not supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700330 DeviceSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700331
332 // Device is built by default. Host and HostCross are supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700333 HostAndDeviceSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700334
335 // Host, HostCross, and Device are built by default.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700336 HostAndDeviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700337
338 // Nothing is supported. This is not exposed to the user, but used to mark a
339 // host only module as unsupported when the module type is not supported on
340 // the host OS. E.g. benchmarks are supported on Linux but not Darwin.
Dan Willemsen0b24c742016-10-04 15:13:37 -0700341 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700342)
343
Jiyong Park2db76922017-11-08 16:03:48 +0900344type moduleKind int
345
346const (
347 platformModule moduleKind = iota
348 deviceSpecificModule
349 socSpecificModule
350 productSpecificModule
Dario Frenifd05a742018-05-29 13:28:54 +0100351 productServicesSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900352)
353
354func (k moduleKind) String() string {
355 switch k {
356 case platformModule:
357 return "platform"
358 case deviceSpecificModule:
359 return "device-specific"
360 case socSpecificModule:
361 return "soc-specific"
362 case productSpecificModule:
363 return "product-specific"
Dario Frenifd05a742018-05-29 13:28:54 +0100364 case productServicesSpecificModule:
365 return "productservices-specific"
Jiyong Park2db76922017-11-08 16:03:48 +0900366 default:
367 panic(fmt.Errorf("unknown module kind %d", k))
368 }
369}
370
Colin Cross36242852017-06-23 15:06:31 -0700371func InitAndroidModule(m Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800372 base := m.base()
373 base.module = m
Colin Cross5049f022015-03-18 13:28:46 -0700374
Colin Cross36242852017-06-23 15:06:31 -0700375 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700376 &base.nameProperties,
377 &base.commonProperties,
378 &base.variableProperties)
Pirama Arumuga Nainar955dc492018-04-17 14:58:42 -0700379 base.customizableProperties = m.GetProperties()
Colin Cross5049f022015-03-18 13:28:46 -0700380}
381
Colin Cross36242852017-06-23 15:06:31 -0700382func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
383 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700384
385 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800386 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700387 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700388 base.commonProperties.ArchSpecific = true
Colin Crossee0bc3b2018-10-02 22:01:37 -0700389 base.commonProperties.UseTargetVariants = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800390
Dan Willemsen218f6562015-07-08 18:13:11 -0700391 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700392 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700393 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800394 }
395
Colin Cross36242852017-06-23 15:06:31 -0700396 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800397}
398
Colin Crossee0bc3b2018-10-02 22:01:37 -0700399func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
400 InitAndroidArchModule(m, hod, defaultMultilib)
401 m.base().commonProperties.UseTargetVariants = false
402}
403
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800404// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800405// modules. It should be included as an anonymous field in every module
406// struct definition. InitAndroidModule should then be called from the module's
407// factory function, and the return values from InitAndroidModule should be
408// returned from the factory function.
409//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800410// The ModuleBase type is responsible for implementing the GenerateBuildActions
411// method to support the blueprint.Module interface. This method will then call
412// the module's GenerateAndroidBuildActions method once for each build variant
413// that is to be built. GenerateAndroidBuildActions is passed a
414// AndroidModuleContext rather than the usual blueprint.ModuleContext.
Colin Cross3f40fa42015-01-30 17:27:36 -0800415// AndroidModuleContext exposes extra functionality specific to the Android build
416// system including details about the particular build variant that is to be
417// generated.
418//
419// For example:
420//
421// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800422// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800423// )
424//
425// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800426// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800427// properties struct {
428// MyProperty string
429// }
430// }
431//
Colin Cross36242852017-06-23 15:06:31 -0700432// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800433// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700434// m.AddProperties(&m.properties)
435// android.InitAndroidModule(m)
436// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800437// }
438//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800439// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800440// // Get the CPU architecture for the current build variant.
441// variantArch := ctx.Arch()
442//
443// // ...
444// }
Colin Cross635c3b02016-05-18 15:37:25 -0700445type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800446 // Putting the curiously recurring thing pointing to the thing that contains
447 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700448 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700449 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800450
Colin Crossfc754582016-05-17 16:34:16 -0700451 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800452 commonProperties commonProperties
Colin Cross7f64b6d2015-07-09 13:57:48 -0700453 variableProperties variableProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800454 hostAndDeviceProperties hostAndDeviceProperties
455 generalProperties []interface{}
Colin Crossc17727d2018-10-24 12:42:09 -0700456 archProperties [][]interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700457 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800458
459 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700460 installFiles Paths
461 checkbuildFiles Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -0700462
463 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
464 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800465 installTarget WritablePath
466 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700467 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700468
Colin Cross178a5092016-09-13 13:42:32 -0700469 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700470
471 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700472
473 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700474 buildParams []BuildParams
Colin Crossa9d8bee2018-10-02 13:59:46 -0700475
476 prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool
Colin Cross36242852017-06-23 15:06:31 -0700477}
478
479func (a *ModuleBase) AddProperties(props ...interface{}) {
480 a.registerProps = append(a.registerProps, props...)
481}
482
483func (a *ModuleBase) GetProperties() []interface{} {
484 return a.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800485}
486
Colin Crossae887032017-10-23 17:16:14 -0700487func (a *ModuleBase) BuildParamsForTests() []BuildParams {
Colin Crosscec81712017-07-13 14:43:27 -0700488 return a.buildParams
489}
490
Colin Crossa9d8bee2018-10-02 13:59:46 -0700491func (a *ModuleBase) Prefer32(prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool) {
492 a.prefer32 = prefer32
493}
494
Colin Crossce75d2c2016-10-06 16:12:58 -0700495// Name returns the name of the module. It may be overridden by individual module types, for
496// example prebuilts will prepend prebuilt_ to the name.
Colin Crossfc754582016-05-17 16:34:16 -0700497func (a *ModuleBase) Name() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800498 return String(a.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700499}
500
Colin Crossce75d2c2016-10-06 16:12:58 -0700501// BaseModuleName returns the name of the module as specified in the blueprints file.
502func (a *ModuleBase) BaseModuleName() string {
Nan Zhang0007d812017-11-07 10:57:05 -0800503 return String(a.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700504}
505
Colin Cross635c3b02016-05-18 15:37:25 -0700506func (a *ModuleBase) base() *ModuleBase {
Colin Cross3f40fa42015-01-30 17:27:36 -0800507 return a
508}
509
Colin Crossee0bc3b2018-10-02 22:01:37 -0700510func (a *ModuleBase) SetTarget(target Target, multiTargets []Target, primary bool) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700511 a.commonProperties.CompileTarget = target
Colin Crossee0bc3b2018-10-02 22:01:37 -0700512 a.commonProperties.CompileMultiTargets = multiTargets
Colin Cross8b74d172016-09-13 09:59:14 -0700513 a.commonProperties.CompilePrimary = primary
Colin Crossd3ba0392015-05-07 14:11:29 -0700514}
515
Colin Crossa1ad8d12016-06-01 17:09:44 -0700516func (a *ModuleBase) Target() Target {
517 return a.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800518}
519
Colin Cross8b74d172016-09-13 09:59:14 -0700520func (a *ModuleBase) TargetPrimary() bool {
521 return a.commonProperties.CompilePrimary
522}
523
Colin Crossee0bc3b2018-10-02 22:01:37 -0700524func (a *ModuleBase) MultiTargets() []Target {
525 return a.commonProperties.CompileMultiTargets
526}
527
Colin Crossa1ad8d12016-06-01 17:09:44 -0700528func (a *ModuleBase) Os() OsType {
529 return a.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800530}
531
Colin Cross635c3b02016-05-18 15:37:25 -0700532func (a *ModuleBase) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700533 return a.Os().Class == Host || a.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800534}
535
Colin Cross635c3b02016-05-18 15:37:25 -0700536func (a *ModuleBase) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700537 return a.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800538}
539
Dan Willemsen0b24c742016-10-04 15:13:37 -0700540func (a *ModuleBase) ArchSpecific() bool {
541 return a.commonProperties.ArchSpecific
542}
543
Colin Crossa1ad8d12016-06-01 17:09:44 -0700544func (a *ModuleBase) OsClassSupported() []OsClass {
545 switch a.commonProperties.HostOrDeviceSupported {
546 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700547 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700548 case HostSupportedNoCross:
549 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700550 case DeviceSupported:
551 return []OsClass{Device}
Dan Albert0981b5c2018-08-02 13:46:35 -0700552 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700553 var supported []OsClass
Dan Albert0981b5c2018-08-02 13:46:35 -0700554 if Bool(a.hostAndDeviceProperties.Host_supported) ||
555 (a.commonProperties.HostOrDeviceSupported == HostAndDeviceDefault &&
556 a.hostAndDeviceProperties.Host_supported == nil) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700557 supported = append(supported, Host, HostCross)
558 }
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700559 if a.hostAndDeviceProperties.Device_supported == nil ||
560 *a.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700561 supported = append(supported, Device)
562 }
563 return supported
564 default:
565 return nil
566 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800567}
568
Colin Cross635c3b02016-05-18 15:37:25 -0700569func (a *ModuleBase) DeviceSupported() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800570 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
571 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700572 (a.hostAndDeviceProperties.Device_supported == nil ||
573 *a.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800574}
575
Jiyong Parkc678ad32018-04-10 13:07:10 +0900576func (a *ModuleBase) Platform() bool {
Dario Frenifd05a742018-05-29 13:28:54 +0100577 return !a.DeviceSpecific() && !a.SocSpecific() && !a.ProductSpecific() && !a.ProductServicesSpecific()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900578}
579
580func (a *ModuleBase) DeviceSpecific() bool {
581 return Bool(a.commonProperties.Device_specific)
582}
583
584func (a *ModuleBase) SocSpecific() bool {
585 return Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
586}
587
588func (a *ModuleBase) ProductSpecific() bool {
589 return Bool(a.commonProperties.Product_specific)
590}
591
Dario Frenifd05a742018-05-29 13:28:54 +0100592func (a *ModuleBase) ProductServicesSpecific() bool {
Dario Freni95cf7672018-08-17 00:57:57 +0100593 return Bool(a.commonProperties.Product_services_specific)
Dario Frenifd05a742018-05-29 13:28:54 +0100594}
595
Colin Cross635c3b02016-05-18 15:37:25 -0700596func (a *ModuleBase) Enabled() bool {
Dan Willemsen0effe062015-11-30 16:06:01 -0800597 if a.commonProperties.Enabled == nil {
Dan Willemsen0a37a2a2016-11-13 10:16:05 -0800598 return !a.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800599 }
Dan Willemsen0effe062015-11-30 16:06:01 -0800600 return *a.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800601}
602
Colin Crossce75d2c2016-10-06 16:12:58 -0700603func (a *ModuleBase) SkipInstall() {
604 a.commonProperties.SkipInstall = true
605}
606
Jiyong Park374510b2018-03-19 18:23:01 +0900607func (a *ModuleBase) ExportedToMake() bool {
608 return a.commonProperties.NamespaceExportedToMake
609}
610
Colin Cross635c3b02016-05-18 15:37:25 -0700611func (a *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700612 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800613
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700614 result := Paths{}
Colin Cross6b753602018-06-21 13:03:07 -0700615 // TODO(ccross): we need to use WalkDeps and have some way to know which dependencies require installation
Colin Cross3f40fa42015-01-30 17:27:36 -0800616 ctx.VisitDepsDepthFirstIf(isFileInstaller,
617 func(m blueprint.Module) {
618 fileInstaller := m.(fileInstaller)
619 files := fileInstaller.filesToInstall()
620 result = append(result, files...)
621 })
622
623 return result
624}
625
Colin Cross635c3b02016-05-18 15:37:25 -0700626func (a *ModuleBase) filesToInstall() Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800627 return a.installFiles
628}
629
Colin Cross635c3b02016-05-18 15:37:25 -0700630func (p *ModuleBase) NoAddressSanitizer() bool {
Colin Cross3f40fa42015-01-30 17:27:36 -0800631 return p.noAddressSanitizer
632}
633
Colin Cross635c3b02016-05-18 15:37:25 -0700634func (p *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800635 return false
636}
637
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700638func (p *ModuleBase) InstallInSanitizerDir() bool {
639 return false
640}
641
Jiyong Parkf9332f12018-02-01 00:54:12 +0900642func (p *ModuleBase) InstallInRecovery() bool {
643 return Bool(p.commonProperties.Recovery)
644}
645
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900646func (a *ModuleBase) Owner() string {
647 return String(a.commonProperties.Owner)
648}
649
Colin Cross0875c522017-11-28 17:34:01 -0800650func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700651 allInstalledFiles := Paths{}
652 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -0800653 ctx.VisitAllModuleVariants(func(module Module) {
654 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -0700655 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
656 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800657 })
658
Colin Cross0875c522017-11-28 17:34:01 -0800659 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -0700660
Jeff Gaston088e29e2017-11-29 16:47:17 -0800661 namespacePrefix := ctx.Namespace().(*Namespace).id
662 if namespacePrefix != "" {
663 namespacePrefix = namespacePrefix + "-"
664 }
665
Colin Cross3f40fa42015-01-30 17:27:36 -0800666 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800667 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -0800668 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700669 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800670 Output: name,
671 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -0800672 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -0700673 })
674 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700675 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700676 }
677
678 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800679 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -0800680 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700681 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -0800682 Output: name,
683 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -0700684 })
685 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700686 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700687 }
688
689 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800690 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -0800691 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800692 suffix = "-soong"
693 }
694
Jeff Gaston088e29e2017-11-29 16:47:17 -0800695 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -0800696 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700697 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -0800698 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -0700699 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800700 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700701
702 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800703 }
704}
705
Jiyong Park2db76922017-11-08 16:03:48 +0900706func determineModuleKind(a *ModuleBase, ctx blueprint.BaseModuleContext) moduleKind {
707 var socSpecific = Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
708 var deviceSpecific = Bool(a.commonProperties.Device_specific)
709 var productSpecific = Bool(a.commonProperties.Product_specific)
Dario Freni95cf7672018-08-17 00:57:57 +0100710 var productServicesSpecific = Bool(a.commonProperties.Product_services_specific)
Jiyong Park2db76922017-11-08 16:03:48 +0900711
Dario Frenifd05a742018-05-29 13:28:54 +0100712 msg := "conflicting value set here"
713 if socSpecific && deviceSpecific {
714 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
Jiyong Park2db76922017-11-08 16:03:48 +0900715 if Bool(a.commonProperties.Vendor) {
716 ctx.PropertyErrorf("vendor", msg)
717 }
718 if Bool(a.commonProperties.Proprietary) {
719 ctx.PropertyErrorf("proprietary", msg)
720 }
721 if Bool(a.commonProperties.Soc_specific) {
722 ctx.PropertyErrorf("soc_specific", msg)
723 }
724 }
725
Dario Frenifd05a742018-05-29 13:28:54 +0100726 if productSpecific && productServicesSpecific {
727 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and product_services at the same time.")
728 ctx.PropertyErrorf("product_services_specific", msg)
729 }
730
731 if (socSpecific || deviceSpecific) && (productSpecific || productServicesSpecific) {
732 if productSpecific {
733 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
734 } else {
735 ctx.PropertyErrorf("product_services_specific", "a module cannot be specific to SoC or device and product_services at the same time.")
736 }
737 if deviceSpecific {
738 ctx.PropertyErrorf("device_specific", msg)
739 } else {
740 if Bool(a.commonProperties.Vendor) {
741 ctx.PropertyErrorf("vendor", msg)
742 }
743 if Bool(a.commonProperties.Proprietary) {
744 ctx.PropertyErrorf("proprietary", msg)
745 }
746 if Bool(a.commonProperties.Soc_specific) {
747 ctx.PropertyErrorf("soc_specific", msg)
748 }
749 }
750 }
751
Jiyong Park2db76922017-11-08 16:03:48 +0900752 if productSpecific {
753 return productSpecificModule
Dario Frenifd05a742018-05-29 13:28:54 +0100754 } else if productServicesSpecific {
755 return productServicesSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900756 } else if deviceSpecific {
757 return deviceSpecificModule
758 } else if socSpecific {
759 return socSpecificModule
760 } else {
761 return platformModule
762 }
763}
764
Colin Cross635c3b02016-05-18 15:37:25 -0700765func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
Colin Cross6362e272015-10-29 15:25:03 -0700766 return androidBaseContextImpl{
Colin Cross8b74d172016-09-13 09:59:14 -0700767 target: a.commonProperties.CompileTarget,
768 targetPrimary: a.commonProperties.CompilePrimary,
Colin Crossee0bc3b2018-10-02 22:01:37 -0700769 multiTargets: a.commonProperties.CompileMultiTargets,
Jiyong Park2db76922017-11-08 16:03:48 +0900770 kind: determineModuleKind(a, ctx),
Colin Cross8b74d172016-09-13 09:59:14 -0700771 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -0800772 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800773}
774
Colin Cross0875c522017-11-28 17:34:01 -0800775func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
776 ctx := &androidModuleContext{
Colin Cross8d8f8e22016-08-03 11:57:50 -0700777 module: a.module,
Colin Cross0875c522017-11-28 17:34:01 -0800778 ModuleContext: blueprintCtx,
779 androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
780 installDeps: a.computeInstallDeps(blueprintCtx),
Colin Cross6362e272015-10-29 15:25:03 -0700781 installFiles: a.installFiles,
Colin Cross0875c522017-11-28 17:34:01 -0800782 missingDeps: blueprintCtx.GetMissingDependencies(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800783 }
784
Colin Cross67a5c132017-05-09 13:45:28 -0700785 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
786 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -0800787 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
788 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -0700789 }
Colin Cross0875c522017-11-28 17:34:01 -0800790 if !ctx.PrimaryArch() {
791 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -0700792 }
793
794 ctx.Variable(pctx, "moduleDesc", desc)
795
796 s := ""
797 if len(suffix) > 0 {
798 s = " [" + strings.Join(suffix, " ") + "]"
799 }
800 ctx.Variable(pctx, "moduleDescSuffix", s)
801
Dan Willemsen569edc52018-11-19 09:33:29 -0800802 // Some common property checks for properties that will be used later in androidmk.go
803 if a.commonProperties.Dist.Dest != nil {
804 _, err := validateSafePath(*a.commonProperties.Dist.Dest)
805 if err != nil {
806 ctx.PropertyErrorf("dist.dest", "%s", err.Error())
807 }
808 }
809 if a.commonProperties.Dist.Dir != nil {
810 _, err := validateSafePath(*a.commonProperties.Dist.Dir)
811 if err != nil {
812 ctx.PropertyErrorf("dist.dir", "%s", err.Error())
813 }
814 }
815 if a.commonProperties.Dist.Suffix != nil {
816 if strings.Contains(*a.commonProperties.Dist.Suffix, "/") {
817 ctx.PropertyErrorf("dist.suffix", "Suffix may not contain a '/' character.")
818 }
819 }
820
Colin Cross9b1d13d2016-09-19 15:18:11 -0700821 if a.Enabled() {
Colin Cross0875c522017-11-28 17:34:01 -0800822 a.module.GenerateAndroidBuildActions(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -0700823 if ctx.Failed() {
824 return
825 }
826
Colin Cross0875c522017-11-28 17:34:01 -0800827 a.installFiles = append(a.installFiles, ctx.installFiles...)
828 a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800829 }
830
Colin Cross9b1d13d2016-09-19 15:18:11 -0700831 if a == ctx.FinalModule().(Module).base() {
832 a.generateModuleTarget(ctx)
833 if ctx.Failed() {
834 return
835 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800836 }
Colin Crosscec81712017-07-13 14:43:27 -0700837
Colin Cross0875c522017-11-28 17:34:01 -0800838 a.buildParams = ctx.buildParams
Colin Cross3f40fa42015-01-30 17:27:36 -0800839}
840
Colin Crossf6566ed2015-03-24 11:13:38 -0700841type androidBaseContextImpl struct {
Colin Cross8b74d172016-09-13 09:59:14 -0700842 target Target
Colin Crossee0bc3b2018-10-02 22:01:37 -0700843 multiTargets []Target
Colin Cross8b74d172016-09-13 09:59:14 -0700844 targetPrimary bool
845 debug bool
Jiyong Park2db76922017-11-08 16:03:48 +0900846 kind moduleKind
Colin Cross8b74d172016-09-13 09:59:14 -0700847 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700848}
849
Colin Cross3f40fa42015-01-30 17:27:36 -0800850type androidModuleContext struct {
851 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700852 androidBaseContextImpl
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700853 installDeps Paths
854 installFiles Paths
855 checkbuildFiles Paths
Colin Cross6ff51382015-12-17 16:39:19 -0800856 missingDeps []string
Colin Cross8d8f8e22016-08-03 11:57:50 -0700857 module Module
Colin Crosscec81712017-07-13 14:43:27 -0700858
859 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700860 buildParams []BuildParams
Colin Cross6ff51382015-12-17 16:39:19 -0800861}
862
Colin Cross67a5c132017-05-09 13:45:28 -0700863func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
Colin Cross0875c522017-11-28 17:34:01 -0800864 a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700865 Rule: ErrorRule,
866 Description: desc,
867 Outputs: outputs,
868 Optional: true,
Colin Cross6ff51382015-12-17 16:39:19 -0800869 Args: map[string]string{
870 "error": err.Error(),
871 },
872 })
873 return
Colin Cross3f40fa42015-01-30 17:27:36 -0800874}
875
Colin Crossaabf6792017-11-29 00:27:14 -0800876func (a *androidModuleContext) Config() Config {
877 return a.ModuleContext.Config().(Config)
878}
879
Colin Cross0875c522017-11-28 17:34:01 -0800880func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
Colin Crossae887032017-10-23 17:16:14 -0700881 a.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -0800882}
883
Colin Cross0875c522017-11-28 17:34:01 -0800884func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700885 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700886 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -0800887 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -0800888 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700889 Outputs: params.Outputs.Strings(),
890 ImplicitOutputs: params.ImplicitOutputs.Strings(),
891 Inputs: params.Inputs.Strings(),
892 Implicits: params.Implicits.Strings(),
893 OrderOnly: params.OrderOnly.Strings(),
894 Args: params.Args,
895 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700896 }
897
Colin Cross33bfb0a2016-11-21 17:23:08 -0800898 if params.Depfile != nil {
899 bparams.Depfile = params.Depfile.String()
900 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700901 if params.Output != nil {
902 bparams.Outputs = append(bparams.Outputs, params.Output.String())
903 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -0700904 if params.ImplicitOutput != nil {
905 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
906 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700907 if params.Input != nil {
908 bparams.Inputs = append(bparams.Inputs, params.Input.String())
909 }
910 if params.Implicit != nil {
911 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
912 }
913
Colin Crossfe4bc362018-09-12 10:02:13 -0700914 bparams.Outputs = proptools.NinjaEscape(bparams.Outputs)
915 bparams.ImplicitOutputs = proptools.NinjaEscape(bparams.ImplicitOutputs)
916 bparams.Inputs = proptools.NinjaEscape(bparams.Inputs)
917 bparams.Implicits = proptools.NinjaEscape(bparams.Implicits)
918 bparams.OrderOnly = proptools.NinjaEscape(bparams.OrderOnly)
919 bparams.Depfile = proptools.NinjaEscape([]string{bparams.Depfile})[0]
920
Colin Cross0875c522017-11-28 17:34:01 -0800921 return bparams
922}
923
924func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
925 a.ModuleContext.Variable(pctx.PackageContext, name, value)
926}
927
928func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
929 argNames ...string) blueprint.Rule {
930
931 return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
932}
933
934func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
935 if a.config.captureBuild {
936 a.buildParams = append(a.buildParams, params)
937 }
938
939 bparams := convertBuildParams(params)
940
941 if bparams.Description != "" {
942 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
943 }
944
Colin Cross6ff51382015-12-17 16:39:19 -0800945 if a.missingDeps != nil {
Colin Cross67a5c132017-05-09 13:45:28 -0700946 a.ninjaError(bparams.Description, bparams.Outputs,
947 fmt.Errorf("module %s missing dependencies: %s\n",
948 a.ModuleName(), strings.Join(a.missingDeps, ", ")))
Colin Cross6ff51382015-12-17 16:39:19 -0800949 return
950 }
951
Colin Cross0875c522017-11-28 17:34:01 -0800952 a.ModuleContext.Build(pctx.PackageContext, bparams)
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700953}
954
Colin Cross6ff51382015-12-17 16:39:19 -0800955func (a *androidModuleContext) GetMissingDependencies() []string {
956 return a.missingDeps
957}
958
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800959func (a *androidModuleContext) AddMissingDependencies(deps []string) {
960 if deps != nil {
961 a.missingDeps = append(a.missingDeps, deps...)
Colin Crossd11fcda2017-10-23 17:59:01 -0700962 a.missingDeps = FirstUniqueStrings(a.missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800963 }
964}
965
Colin Crossd11fcda2017-10-23 17:59:01 -0700966func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module {
967 aModule, _ := module.(Module)
968 if aModule == nil {
969 a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule))
970 return nil
971 }
972
973 if !aModule.Enabled() {
Colin Cross6510f912017-11-29 00:27:14 -0800974 if a.Config().AllowMissingDependencies() {
Colin Crossd11fcda2017-10-23 17:59:01 -0700975 a.AddMissingDependencies([]string{a.OtherModuleName(aModule)})
976 } else {
977 a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule))
978 }
979 return nil
980 }
981
982 return aModule
983}
984
Colin Cross35143d02017-11-16 00:11:20 -0800985func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
986 a.ModuleContext.VisitDirectDeps(visit)
987}
988
Colin Crossd11fcda2017-10-23 17:59:01 -0700989func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
990 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
991 if aModule := a.validateAndroidModule(module); aModule != nil {
992 visit(aModule)
993 }
994 })
995}
996
Colin Crossee6143c2017-12-30 17:54:27 -0800997func (a *androidModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
998 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
999 if aModule := a.validateAndroidModule(module); aModule != nil {
1000 if a.ModuleContext.OtherModuleDependencyTag(aModule) == tag {
1001 visit(aModule)
1002 }
1003 }
1004 })
1005}
1006
Colin Crossd11fcda2017-10-23 17:59:01 -07001007func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
1008 a.ModuleContext.VisitDirectDepsIf(
1009 // pred
1010 func(module blueprint.Module) bool {
1011 if aModule := a.validateAndroidModule(module); aModule != nil {
1012 return pred(aModule)
1013 } else {
1014 return false
1015 }
1016 },
1017 // visit
1018 func(module blueprint.Module) {
1019 visit(module.(Module))
1020 })
1021}
1022
1023func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) {
1024 a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) {
1025 if aModule := a.validateAndroidModule(module); aModule != nil {
1026 visit(aModule)
1027 }
1028 })
1029}
1030
1031func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
1032 a.ModuleContext.VisitDepsDepthFirstIf(
1033 // pred
1034 func(module blueprint.Module) bool {
1035 if aModule := a.validateAndroidModule(module); aModule != nil {
1036 return pred(aModule)
1037 } else {
1038 return false
1039 }
1040 },
1041 // visit
1042 func(module blueprint.Module) {
1043 visit(module.(Module))
1044 })
1045}
1046
1047func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
1048 a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
1049 childAndroidModule := a.validateAndroidModule(child)
1050 parentAndroidModule := a.validateAndroidModule(parent)
1051 if childAndroidModule != nil && parentAndroidModule != nil {
1052 return visit(childAndroidModule, parentAndroidModule)
1053 } else {
1054 return false
1055 }
1056 })
1057}
1058
Colin Cross0875c522017-11-28 17:34:01 -08001059func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
1060 a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
1061 visit(module.(Module))
1062 })
1063}
1064
1065func (a *androidModuleContext) PrimaryModule() Module {
1066 return a.ModuleContext.PrimaryModule().(Module)
1067}
1068
1069func (a *androidModuleContext) FinalModule() Module {
1070 return a.ModuleContext.FinalModule().(Module)
1071}
1072
Colin Crossa1ad8d12016-06-01 17:09:44 -07001073func (a *androidBaseContextImpl) Target() Target {
1074 return a.target
1075}
1076
Colin Cross8b74d172016-09-13 09:59:14 -07001077func (a *androidBaseContextImpl) TargetPrimary() bool {
1078 return a.targetPrimary
1079}
1080
Colin Crossee0bc3b2018-10-02 22:01:37 -07001081func (a *androidBaseContextImpl) MultiTargets() []Target {
1082 return a.multiTargets
1083}
1084
Colin Crossf6566ed2015-03-24 11:13:38 -07001085func (a *androidBaseContextImpl) Arch() Arch {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001086 return a.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -08001087}
1088
Colin Crossa1ad8d12016-06-01 17:09:44 -07001089func (a *androidBaseContextImpl) Os() OsType {
1090 return a.target.Os
Dan Willemsen490fd492015-11-24 17:53:15 -08001091}
1092
Colin Crossf6566ed2015-03-24 11:13:38 -07001093func (a *androidBaseContextImpl) Host() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001094 return a.target.Os.Class == Host || a.target.Os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -07001095}
1096
1097func (a *androidBaseContextImpl) Device() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001098 return a.target.Os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -07001099}
1100
Colin Cross0af4b842015-04-30 16:36:18 -07001101func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossa1ad8d12016-06-01 17:09:44 -07001102 return a.target.Os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -07001103}
1104
Colin Cross3edeee12017-04-04 12:59:48 -07001105func (a *androidBaseContextImpl) Windows() bool {
1106 return a.target.Os == Windows
1107}
1108
Colin Crossf6566ed2015-03-24 11:13:38 -07001109func (a *androidBaseContextImpl) Debug() bool {
1110 return a.debug
1111}
1112
Colin Cross1e7d3702016-08-24 15:25:47 -07001113func (a *androidBaseContextImpl) PrimaryArch() bool {
Dan Willemsen0ef639b2018-10-10 17:02:29 -07001114 if len(a.config.Targets[a.target.Os]) <= 1 {
Colin Cross67a5c132017-05-09 13:45:28 -07001115 return true
1116 }
Dan Willemsen0ef639b2018-10-10 17:02:29 -07001117 return a.target.Arch.ArchType == a.config.Targets[a.target.Os][0].Arch.ArchType
Colin Cross1e7d3702016-08-24 15:25:47 -07001118}
1119
Colin Cross1332b002015-04-07 17:11:30 -07001120func (a *androidBaseContextImpl) AConfig() Config {
1121 return a.config
1122}
1123
Colin Cross9272ade2016-08-17 15:24:12 -07001124func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig {
1125 return DeviceConfig{a.config.deviceConfig}
1126}
1127
Jiyong Park2db76922017-11-08 16:03:48 +09001128func (a *androidBaseContextImpl) Platform() bool {
1129 return a.kind == platformModule
1130}
1131
1132func (a *androidBaseContextImpl) DeviceSpecific() bool {
1133 return a.kind == deviceSpecificModule
1134}
1135
1136func (a *androidBaseContextImpl) SocSpecific() bool {
1137 return a.kind == socSpecificModule
1138}
1139
1140func (a *androidBaseContextImpl) ProductSpecific() bool {
1141 return a.kind == productSpecificModule
Dan Willemsen782a2d12015-12-21 14:55:28 -08001142}
1143
Dario Frenifd05a742018-05-29 13:28:54 +01001144func (a *androidBaseContextImpl) ProductServicesSpecific() bool {
1145 return a.kind == productServicesSpecificModule
1146}
1147
Jiyong Park5baac542018-08-28 09:55:37 +09001148// Makes this module a platform module, i.e. not specific to soc, device,
1149// product, or product_services.
1150func (a *ModuleBase) MakeAsPlatform() {
1151 a.commonProperties.Vendor = boolPtr(false)
1152 a.commonProperties.Proprietary = boolPtr(false)
1153 a.commonProperties.Soc_specific = boolPtr(false)
1154 a.commonProperties.Product_specific = boolPtr(false)
1155 a.commonProperties.Product_services_specific = boolPtr(false)
1156}
1157
Colin Cross8d8f8e22016-08-03 11:57:50 -07001158func (a *androidModuleContext) InstallInData() bool {
1159 return a.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -08001160}
1161
Vishwath Mohan1dd88392017-03-29 22:00:18 -07001162func (a *androidModuleContext) InstallInSanitizerDir() bool {
1163 return a.module.InstallInSanitizerDir()
1164}
1165
Jiyong Parkf9332f12018-02-01 00:54:12 +09001166func (a *androidModuleContext) InstallInRecovery() bool {
1167 return a.module.InstallInRecovery()
1168}
1169
Colin Cross893d8162017-04-26 17:34:03 -07001170func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool {
1171 if a.module.base().commonProperties.SkipInstall {
1172 return true
1173 }
1174
Colin Cross3607f212018-05-07 15:28:05 -07001175 // We'll need a solution for choosing which of modules with the same name in different
1176 // namespaces to install. For now, reuse the list of namespaces exported to Make as the
1177 // list of namespaces to install in a Soong-only build.
1178 if !a.module.base().commonProperties.NamespaceExportedToMake {
1179 return true
1180 }
1181
Colin Cross893d8162017-04-26 17:34:03 -07001182 if a.Device() {
Colin Cross6510f912017-11-29 00:27:14 -08001183 if a.Config().SkipDeviceInstall() {
Colin Cross893d8162017-04-26 17:34:03 -07001184 return true
1185 }
1186
Colin Cross6510f912017-11-29 00:27:14 -08001187 if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -07001188 return true
1189 }
1190 }
1191
1192 return false
1193}
1194
Colin Cross5c517922017-08-31 12:29:17 -07001195func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
Colin Crossa2344662016-03-24 13:14:12 -07001196 deps ...Path) OutputPath {
Colin Cross5c517922017-08-31 12:29:17 -07001197 return a.installFile(installPath, name, srcPath, Cp, deps)
1198}
1199
1200func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
1201 deps ...Path) OutputPath {
1202 return a.installFile(installPath, name, srcPath, CpExecutable, deps)
1203}
1204
1205func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path,
1206 rule blueprint.Rule, deps []Path) OutputPath {
Colin Cross35cec122015-04-02 14:37:16 -07001207
Dan Willemsen782a2d12015-12-21 14:55:28 -08001208 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001209 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -08001210
Colin Cross893d8162017-04-26 17:34:03 -07001211 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001212
Dan Willemsen322acaf2016-01-12 23:07:05 -08001213 deps = append(deps, a.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -07001214
Colin Cross89562dc2016-10-03 17:47:19 -07001215 var implicitDeps, orderOnlyDeps Paths
1216
1217 if a.Host() {
1218 // Installed host modules might be used during the build, depend directly on their
1219 // dependencies so their timestamp is updated whenever their dependency is updated
1220 implicitDeps = deps
1221 } else {
1222 orderOnlyDeps = deps
1223 }
1224
Colin Crossae887032017-10-23 17:16:14 -07001225 a.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -07001226 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -07001227 Description: "install " + fullInstallPath.Base(),
1228 Output: fullInstallPath,
1229 Input: srcPath,
1230 Implicits: implicitDeps,
1231 OrderOnly: orderOnlyDeps,
Colin Cross6510f912017-11-29 00:27:14 -08001232 Default: !a.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -08001233 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001234
Dan Willemsen322acaf2016-01-12 23:07:05 -08001235 a.installFiles = append(a.installFiles, fullInstallPath)
1236 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001237 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -07001238 return fullInstallPath
1239}
1240
Colin Cross3854a602016-01-11 12:49:11 -08001241func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
1242 fullInstallPath := installPath.Join(a, name)
Colin Cross178a5092016-09-13 13:42:32 -07001243 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -08001244
Colin Cross893d8162017-04-26 17:34:03 -07001245 if !a.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001246
Colin Crossae887032017-10-23 17:16:14 -07001247 a.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -07001248 Rule: Symlink,
1249 Description: "install symlink " + fullInstallPath.Base(),
1250 Output: fullInstallPath,
1251 OrderOnly: Paths{srcPath},
Colin Cross6510f912017-11-29 00:27:14 -08001252 Default: !a.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -08001253 Args: map[string]string{
1254 "fromPath": srcPath.String(),
1255 },
1256 })
Colin Cross3854a602016-01-11 12:49:11 -08001257
Colin Cross12fc4972016-01-11 12:49:11 -08001258 a.installFiles = append(a.installFiles, fullInstallPath)
1259 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1260 }
Colin Cross3854a602016-01-11 12:49:11 -08001261 return fullInstallPath
1262}
1263
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001264func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
Colin Cross3f40fa42015-01-30 17:27:36 -08001265 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
1266}
1267
Colin Cross3f40fa42015-01-30 17:27:36 -08001268type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001269 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001270}
1271
1272func isFileInstaller(m blueprint.Module) bool {
1273 _, ok := m.(fileInstaller)
1274 return ok
1275}
1276
1277func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -07001278 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -08001279 return ok
1280}
Colin Crossfce53272015-04-08 11:21:40 -07001281
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001282func findStringInSlice(str string, slice []string) int {
1283 for i, s := range slice {
1284 if s == str {
1285 return i
Colin Crossfce53272015-04-08 11:21:40 -07001286 }
1287 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001288 return -1
1289}
1290
Colin Cross068e0fe2016-12-13 15:23:47 -08001291func SrcIsModule(s string) string {
1292 if len(s) > 1 && s[0] == ':' {
1293 return s[1:]
1294 }
1295 return ""
1296}
1297
1298type sourceDependencyTag struct {
1299 blueprint.BaseDependencyTag
1300}
1301
1302var SourceDepTag sourceDependencyTag
1303
Colin Cross366938f2017-12-11 16:29:02 -08001304// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
1305// using ":module" syntax, if any.
Colin Cross068e0fe2016-12-13 15:23:47 -08001306func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
1307 var deps []string
Nan Zhang2439eb72017-04-10 11:27:50 -07001308 set := make(map[string]bool)
1309
Colin Cross068e0fe2016-12-13 15:23:47 -08001310 for _, s := range srcFiles {
1311 if m := SrcIsModule(s); m != "" {
Nan Zhang2439eb72017-04-10 11:27:50 -07001312 if _, found := set[m]; found {
1313 ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
1314 } else {
1315 set[m] = true
1316 deps = append(deps, m)
1317 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001318 }
1319 }
1320
1321 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
1322}
1323
Colin Cross366938f2017-12-11 16:29:02 -08001324// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
1325// using ":module" syntax, if any.
1326func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
1327 if s != nil {
1328 if m := SrcIsModule(*s); m != "" {
1329 ctx.AddDependency(ctx.Module(), SourceDepTag, m)
1330 }
1331 }
1332}
1333
Colin Cross068e0fe2016-12-13 15:23:47 -08001334type SourceFileProducer interface {
1335 Srcs() Paths
1336}
1337
1338// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001339// ExtractSourcesDeps must have already been called during the dependency resolution phase.
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001340func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001341 return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
1342}
1343
Colin Cross366938f2017-12-11 16:29:02 -08001344// Returns a single path expanded from globs and modules referenced using ":module" syntax.
1345// ExtractSourceDeps must have already been called during the dependency resolution phase.
1346func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path {
1347 srcFiles := ctx.ExpandSourcesSubDir([]string{srcFile}, nil, "")
1348 if len(srcFiles) == 1 {
1349 return srcFiles[0]
1350 } else {
1351 ctx.PropertyErrorf(prop, "module providing %s must produce exactly one file", prop)
1352 return nil
1353 }
1354}
1355
Colin Cross2383f3b2018-02-06 14:40:13 -08001356// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
1357// the srcFile is non-nil.
1358// ExtractSourceDeps must have already been called during the dependency resolution phase.
1359func (ctx *androidModuleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
1360 if srcFile != nil {
1361 return OptionalPathForPath(ctx.ExpandSource(*srcFile, prop))
1362 }
1363 return OptionalPath{}
1364}
1365
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001366func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001367 prefix := PathForModuleSrc(ctx).String()
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001368
Colin Cross461b4452018-02-23 09:22:42 -08001369 var expandedExcludes []string
1370 if excludes != nil {
1371 expandedExcludes = make([]string, 0, len(excludes))
1372 }
Nan Zhang27e284d2018-02-09 21:03:53 +00001373
1374 for _, e := range excludes {
1375 if m := SrcIsModule(e); m != "" {
1376 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
1377 if module == nil {
1378 // Error will have been handled by ExtractSourcesDeps
1379 continue
1380 }
1381 if srcProducer, ok := module.(SourceFileProducer); ok {
1382 expandedExcludes = append(expandedExcludes, srcProducer.Srcs().Strings()...)
1383 } else {
1384 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1385 }
1386 } else {
1387 expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e))
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001388 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001389 }
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001390 expandedSrcFiles := make(Paths, 0, len(srcFiles))
Colin Cross8f101b42015-06-17 15:09:06 -07001391 for _, s := range srcFiles {
Colin Cross068e0fe2016-12-13 15:23:47 -08001392 if m := SrcIsModule(s); m != "" {
1393 module := ctx.GetDirectDepWithTag(m, SourceDepTag)
Colin Cross0617bb82017-10-24 13:01:18 -07001394 if module == nil {
1395 // Error will have been handled by ExtractSourcesDeps
1396 continue
1397 }
Colin Cross068e0fe2016-12-13 15:23:47 -08001398 if srcProducer, ok := module.(SourceFileProducer); ok {
Nan Zhang27e284d2018-02-09 21:03:53 +00001399 moduleSrcs := srcProducer.Srcs()
1400 for _, e := range expandedExcludes {
1401 for j, ms := range moduleSrcs {
1402 if ms.String() == e {
1403 moduleSrcs = append(moduleSrcs[:j], moduleSrcs[j+1:]...)
1404 }
1405 }
1406 }
1407 expandedSrcFiles = append(expandedSrcFiles, moduleSrcs...)
Colin Cross068e0fe2016-12-13 15:23:47 -08001408 } else {
1409 ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
1410 }
1411 } else if pathtools.IsGlob(s) {
Dan Willemsen540a78c2018-02-26 21:50:08 -08001412 globbedSrcFiles := ctx.GlobFiles(filepath.Join(prefix, s), expandedExcludes)
Colin Cross05a39cb2017-10-09 13:35:19 -07001413 for i, s := range globbedSrcFiles {
1414 globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001415 }
Colin Cross05a39cb2017-10-09 13:35:19 -07001416 expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
Colin Cross8f101b42015-06-17 15:09:06 -07001417 } else {
Nan Zhang27e284d2018-02-09 21:03:53 +00001418 p := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
1419 j := findStringInSlice(p.String(), expandedExcludes)
1420 if j == -1 {
1421 expandedSrcFiles = append(expandedSrcFiles, p)
1422 }
1423
Colin Cross8f101b42015-06-17 15:09:06 -07001424 }
1425 }
Colin Crossfaeb7aa2017-02-01 14:12:44 -08001426 return expandedSrcFiles
Colin Cross8f101b42015-06-17 15:09:06 -07001427}
1428
Nan Zhang6d34b302017-02-04 17:47:46 -08001429func (ctx *androidModuleContext) RequiredModuleNames() []string {
1430 return ctx.module.base().commonProperties.Required
1431}
1432
Colin Cross7f19f372016-11-01 11:10:25 -07001433func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
1434 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07001435 if err != nil {
1436 ctx.ModuleErrorf("glob: %s", err.Error())
1437 }
Dan Willemsen540a78c2018-02-26 21:50:08 -08001438 return pathsForModuleSrcFromFullPath(ctx, ret, true)
Colin Crossfce53272015-04-08 11:21:40 -07001439}
Colin Cross1f8c52b2015-06-16 16:38:17 -07001440
Nan Zhang581fd212018-01-10 16:06:12 -08001441func (ctx *androidModuleContext) GlobFiles(globPattern string, excludes []string) Paths {
Dan Willemsen540a78c2018-02-26 21:50:08 -08001442 ret, err := ctx.GlobWithDeps(globPattern, excludes)
Nan Zhang581fd212018-01-10 16:06:12 -08001443 if err != nil {
1444 ctx.ModuleErrorf("glob: %s", err.Error())
1445 }
Dan Willemsen540a78c2018-02-26 21:50:08 -08001446 return pathsForModuleSrcFromFullPath(ctx, ret, false)
Nan Zhang581fd212018-01-10 16:06:12 -08001447}
1448
Colin Cross463a90e2015-06-17 14:20:06 -07001449func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07001450 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07001451}
1452
Colin Cross0875c522017-11-28 17:34:01 -08001453func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07001454 return &buildTargetSingleton{}
1455}
1456
Colin Cross87d8b562017-04-25 10:01:55 -07001457func parentDir(dir string) string {
1458 dir, _ = filepath.Split(dir)
1459 return filepath.Clean(dir)
1460}
1461
Colin Cross1f8c52b2015-06-16 16:38:17 -07001462type buildTargetSingleton struct{}
1463
Colin Cross0875c522017-11-28 17:34:01 -08001464func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
1465 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07001466
Colin Cross0875c522017-11-28 17:34:01 -08001467 mmTarget := func(dir string) WritablePath {
1468 return PathForPhony(ctx,
1469 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07001470 }
1471
Colin Cross0875c522017-11-28 17:34:01 -08001472 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001473
Colin Cross0875c522017-11-28 17:34:01 -08001474 ctx.VisitAllModules(func(module Module) {
1475 blueprintDir := module.base().blueprintDir
1476 installTarget := module.base().installTarget
1477 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07001478
Colin Cross0875c522017-11-28 17:34:01 -08001479 if checkbuildTarget != nil {
1480 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
1481 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
1482 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001483
Colin Cross0875c522017-11-28 17:34:01 -08001484 if installTarget != nil {
1485 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001486 }
1487 })
1488
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001489 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001490 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001491 suffix = "-soong"
1492 }
1493
Colin Cross1f8c52b2015-06-16 16:38:17 -07001494 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08001495 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001496 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001497 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001498 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07001499 })
1500
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001501 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08001502 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001503 return
1504 }
1505
Colin Cross0875c522017-11-28 17:34:01 -08001506 sortedKeys := func(m map[string]Paths) []string {
1507 s := make([]string, 0, len(m))
1508 for k := range m {
1509 s = append(s, k)
1510 }
1511 sort.Strings(s)
1512 return s
1513 }
1514
Colin Cross87d8b562017-04-25 10:01:55 -07001515 // Ensure ancestor directories are in modulesInDir
1516 dirs := sortedKeys(modulesInDir)
1517 for _, dir := range dirs {
1518 dir := parentDir(dir)
1519 for dir != "." && dir != "/" {
1520 if _, exists := modulesInDir[dir]; exists {
1521 break
1522 }
1523 modulesInDir[dir] = nil
1524 dir = parentDir(dir)
1525 }
1526 }
1527
1528 // Make directories build their direct subdirectories
1529 dirs = sortedKeys(modulesInDir)
1530 for _, dir := range dirs {
1531 p := parentDir(dir)
1532 if p != "." && p != "/" {
1533 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
1534 }
1535 }
1536
Dan Willemsend2e95fb2017-09-20 14:30:50 -07001537 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
1538 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
1539 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07001540 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08001541 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07001542 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001543 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07001544 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001545 // HACK: checkbuild should be an optional build, but force it
1546 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08001547 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07001548 })
1549 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07001550
1551 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
1552 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001553 ctx.VisitAllModules(func(module Module) {
1554 if module.Enabled() {
1555 os := module.Target().Os
1556 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001557 }
1558 })
1559
Colin Cross0875c522017-11-28 17:34:01 -08001560 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001561 for os, deps := range osDeps {
1562 var className string
1563
1564 switch os.Class {
1565 case Host:
1566 className = "host"
1567 case HostCross:
1568 className = "host-cross"
1569 case Device:
1570 className = "target"
1571 default:
1572 continue
1573 }
1574
Colin Cross0875c522017-11-28 17:34:01 -08001575 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07001576 osClass[className] = append(osClass[className], name)
1577
Colin Cross0875c522017-11-28 17:34:01 -08001578 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001579 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001580 Output: name,
1581 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07001582 })
1583 }
1584
1585 // Wrap those into host|host-cross|target phony rules
1586 osClasses := sortedKeys(osClass)
1587 for _, class := range osClasses {
Colin Cross0875c522017-11-28 17:34:01 -08001588 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07001589 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001590 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07001591 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07001592 })
1593 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001594}
Colin Crossd779da42015-12-17 18:00:23 -08001595
Colin Cross2465c3d2018-09-28 10:19:18 -07001596type ModulesByName struct {
1597 slice []blueprint.Module
Colin Crossd779da42015-12-17 18:00:23 -08001598 ctx interface {
1599 ModuleName(blueprint.Module) string
1600 ModuleSubDir(blueprint.Module) string
1601 }
1602}
1603
Colin Cross2465c3d2018-09-28 10:19:18 -07001604func (s ModulesByName) Len() int { return len(s.slice) }
1605func (s ModulesByName) Less(i, j int) bool {
Colin Crossd779da42015-12-17 18:00:23 -08001606 mi, mj := s.slice[i], s.slice[j]
1607 ni, nj := s.ctx.ModuleName(mi), s.ctx.ModuleName(mj)
1608
1609 if ni != nj {
1610 return ni < nj
1611 } else {
1612 return s.ctx.ModuleSubDir(mi) < s.ctx.ModuleSubDir(mj)
1613 }
1614}
Colin Cross2465c3d2018-09-28 10:19:18 -07001615func (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 -07001616
1617// Collect information for opening IDE project files in java/jdeps.go.
1618type IDEInfo interface {
1619 IDEInfo(ideInfo *IdeInfo)
1620 BaseModuleName() string
1621}
1622
1623// Extract the base module name from the Import name.
1624// Often the Import name has a prefix "prebuilt_".
1625// Remove the prefix explicitly if needed
1626// until we find a better solution to get the Import name.
1627type IDECustomizedModuleName interface {
1628 IDECustomizedModuleName() string
1629}
1630
1631type IdeInfo struct {
1632 Deps []string `json:"dependencies,omitempty"`
1633 Srcs []string `json:"srcs,omitempty"`
1634 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
1635 Jarjar_rules []string `json:"jarjar_rules,omitempty"`
1636 Jars []string `json:"jars,omitempty"`
1637 Classes []string `json:"class,omitempty"`
1638 Installed_paths []string `json:"installed,omitempty"`
1639}