blob: f16407272492319e2e42fdf9a3f9b8dcbf8ffd02 [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 Cross988414c2020-01-11 01:11:46 +000019 "os"
Alex Lightfb4353d2019-01-17 13:57:45 -080020 "path"
Colin Cross3f40fa42015-01-30 17:27:36 -080021 "path/filepath"
Colin Cross6ff51382015-12-17 16:39:19 -080022 "strings"
Colin Crossaabf6792017-11-29 00:27:14 -080023 "text/scanner"
Colin Crossf6566ed2015-03-24 11:13:38 -070024
25 "github.com/google/blueprint"
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 Cross1184b642019-12-30 18:43:07 -080058// EarlyModuleContext provides methods that can be called early, as soon as the properties have
59// been parsed into the module and before any mutators have run.
60type EarlyModuleContext interface {
61 Module() Module
62 ModuleName() string
63 ModuleDir() string
64 ModuleType() string
Colin Cross9d34f352019-11-22 16:03:51 -080065 BlueprintsFile() string
Colin Cross1184b642019-12-30 18:43:07 -080066
67 ContainsProperty(name string) bool
68 Errorf(pos scanner.Position, fmt string, args ...interface{})
69 ModuleErrorf(fmt string, args ...interface{})
70 PropertyErrorf(property, fmt string, args ...interface{})
71 Failed() bool
72
73 AddNinjaFileDeps(deps ...string)
74
75 DeviceSpecific() bool
76 SocSpecific() bool
77 ProductSpecific() bool
78 SystemExtSpecific() bool
79 Platform() bool
80
81 Config() Config
82 DeviceConfig() DeviceConfig
83
84 // Deprecated: use Config()
85 AConfig() Config
86
87 // GlobWithDeps returns a list of files that match the specified pattern but do not match any
88 // of the patterns in excludes. It also adds efficient dependencies to rerun the primary
89 // builder whenever a file matching the pattern as added or removed, without rerunning if a
90 // file that does not match the pattern is added to a searched directory.
91 GlobWithDeps(pattern string, excludes []string) ([]string, error)
92
93 Glob(globPattern string, excludes []string) Paths
94 GlobFiles(globPattern string, excludes []string) Paths
Colin Cross988414c2020-01-11 01:11:46 +000095 IsSymlink(path Path) bool
96 Readlink(path Path) string
Colin Cross1184b642019-12-30 18:43:07 -080097}
98
Colin Cross0ea8ba82019-06-06 14:33:29 -070099// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
Colin Crossdc35e212019-06-06 16:13:11 -0700100// a Config instead of an interface{}, and some methods have been wrapped to use an android.Module
101// instead of a blueprint.Module, plus some extra methods that return Android-specific information
Colin Cross0ea8ba82019-06-06 14:33:29 -0700102// about the current module.
103type BaseModuleContext interface {
Colin Cross1184b642019-12-30 18:43:07 -0800104 EarlyModuleContext
Colin Cross0ea8ba82019-06-06 14:33:29 -0700105
Colin Crossdc35e212019-06-06 16:13:11 -0700106 OtherModuleName(m blueprint.Module) string
107 OtherModuleDir(m blueprint.Module) string
108 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
109 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
110 OtherModuleExists(name string) bool
Jiyong Park9e6c2422019-08-09 20:39:45 +0900111 OtherModuleType(m blueprint.Module) string
Colin Crossdc35e212019-06-06 16:13:11 -0700112
113 GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module
114 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
115 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
116
117 VisitDirectDepsBlueprint(visit func(blueprint.Module))
118 VisitDirectDeps(visit func(Module))
119 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
120 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
121 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
122 VisitDepsDepthFirst(visit func(Module))
123 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
124 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
125 WalkDeps(visit func(Module, Module) bool)
126 WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool)
127 // GetWalkPath is supposed to be called in visit function passed in WalkDeps()
128 // and returns a top-down dependency path from a start module to current child module.
129 GetWalkPath() []Module
130
Paul Duffinf0207962020-03-31 11:31:36 +0100131 // GetTagPath is supposed to be called in visit function passed in WalkDeps()
132 // and returns a top-down dependency tags path from a start module to current child module.
133 // It has one less entry than GetWalkPath() as it contains the dependency tags that
134 // exist between each adjacent pair of modules in the GetWalkPath().
135 // GetTagPath()[i] is the tag between GetWalkPath()[i] and GetWalkPath()[i+1]
136 GetTagPath() []blueprint.DependencyTag
137
Colin Crossdc35e212019-06-06 16:13:11 -0700138 AddMissingDependencies(missingDeps []string)
139
Colin Crossa1ad8d12016-06-01 17:09:44 -0700140 Target() Target
Colin Cross8b74d172016-09-13 09:59:14 -0700141 TargetPrimary() bool
Paul Duffin28d70c72020-02-25 15:50:49 +0000142
143 // The additional arch specific targets (e.g. 32/64 bit) that this module variant is
144 // responsible for creating.
Colin Crossee0bc3b2018-10-02 22:01:37 -0700145 MultiTargets() []Target
Colin Crossf6566ed2015-03-24 11:13:38 -0700146 Arch() Arch
Colin Crossa1ad8d12016-06-01 17:09:44 -0700147 Os() OsType
Colin Crossf6566ed2015-03-24 11:13:38 -0700148 Host() bool
149 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -0700150 Darwin() bool
Doug Horn21b94272019-01-16 12:06:11 -0800151 Fuchsia() bool
Colin Cross3edeee12017-04-04 12:59:48 -0700152 Windows() bool
Colin Crossf6566ed2015-03-24 11:13:38 -0700153 Debug() bool
Colin Cross1e7d3702016-08-24 15:25:47 -0700154 PrimaryArch() bool
Colin Crossf6566ed2015-03-24 11:13:38 -0700155}
156
Colin Cross1184b642019-12-30 18:43:07 -0800157// Deprecated: use EarlyModuleContext instead
Colin Cross635c3b02016-05-18 15:37:25 -0700158type BaseContext interface {
Colin Cross1184b642019-12-30 18:43:07 -0800159 EarlyModuleContext
Colin Crossaabf6792017-11-29 00:27:14 -0800160}
161
Colin Cross635c3b02016-05-18 15:37:25 -0700162type ModuleContext interface {
Colin Crossaabf6792017-11-29 00:27:14 -0800163 BaseModuleContext
Colin Cross3f40fa42015-01-30 17:27:36 -0800164
Colin Crossae887032017-10-23 17:16:14 -0700165 // Deprecated: use ModuleContext.Build instead.
Colin Cross0875c522017-11-28 17:34:01 -0800166 ModuleBuild(pctx PackageContext, params ModuleBuildParams)
Colin Cross8f101b42015-06-17 15:09:06 -0700167
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700168 ExpandSources(srcFiles, excludes []string) Paths
Colin Cross366938f2017-12-11 16:29:02 -0800169 ExpandSource(srcFile, prop string) Path
Colin Cross2383f3b2018-02-06 14:40:13 -0800170 ExpandOptionalSource(srcFile *string, prop string) OptionalPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700171
Colin Cross70dda7e2019-10-01 22:05:35 -0700172 InstallExecutable(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath
173 InstallFile(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath
174 InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath
175 InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700176 CheckbuildFile(srcPath Path)
Dan Willemsen6553f5e2016-03-10 18:14:25 -0800177
Colin Cross8d8f8e22016-08-03 11:57:50 -0700178 InstallInData() bool
Jaewoong Jung0949f312019-09-11 10:25:18 -0700179 InstallInTestcases() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700180 InstallInSanitizerDir() bool
Yifan Hong1b3348d2020-01-21 15:53:22 -0800181 InstallInRamdisk() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +0900182 InstallInRecovery() bool
Colin Cross90ba5f42019-10-02 11:10:58 -0700183 InstallInRoot() bool
Colin Cross607d8582019-07-29 16:44:46 -0700184 InstallBypassMake() bool
Nan Zhang6d34b302017-02-04 17:47:46 -0800185
186 RequiredModuleNames() []string
Sasha Smundakb6d23052019-04-01 18:37:36 -0700187 HostRequiredModuleNames() []string
188 TargetRequiredModuleNames() []string
Colin Cross3f68a132017-10-23 17:10:29 -0700189
Colin Cross3f68a132017-10-23 17:10:29 -0700190 ModuleSubDir() string
191
Colin Cross0875c522017-11-28 17:34:01 -0800192 Variable(pctx PackageContext, name, value string)
193 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
Colin Crossae887032017-10-23 17:16:14 -0700194 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
195 // and performs more verification.
Colin Cross0875c522017-11-28 17:34:01 -0800196 Build(pctx PackageContext, params BuildParams)
Colin Cross3f68a132017-10-23 17:10:29 -0700197
Colin Cross0875c522017-11-28 17:34:01 -0800198 PrimaryModule() Module
199 FinalModule() Module
200 VisitAllModuleVariants(visit func(Module))
Colin Cross3f68a132017-10-23 17:10:29 -0700201
202 GetMissingDependencies() []string
Jeff Gaston088e29e2017-11-29 16:47:17 -0800203 Namespace() blueprint.Namespace
Colin Cross3f40fa42015-01-30 17:27:36 -0800204}
205
Colin Cross635c3b02016-05-18 15:37:25 -0700206type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -0800207 blueprint.Module
208
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700209 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
210 // but GenerateAndroidBuildActions also has access to Android-specific information.
211 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -0700212 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -0700213
Colin Cross1e676be2016-10-12 14:38:15 -0700214 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -0800215
Colin Cross635c3b02016-05-18 15:37:25 -0700216 base() *ModuleBase
Inseob Kimeec88e12020-01-22 11:11:29 +0900217 Disable()
Dan Willemsen0effe062015-11-30 16:06:01 -0800218 Enabled() bool
Colin Crossa1ad8d12016-06-01 17:09:44 -0700219 Target() Target
Dan Willemsen782a2d12015-12-21 14:55:28 -0800220 InstallInData() bool
Jaewoong Jung0949f312019-09-11 10:25:18 -0700221 InstallInTestcases() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700222 InstallInSanitizerDir() bool
Yifan Hong1b3348d2020-01-21 15:53:22 -0800223 InstallInRamdisk() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +0900224 InstallInRecovery() bool
Colin Cross90ba5f42019-10-02 11:10:58 -0700225 InstallInRoot() bool
Colin Cross607d8582019-07-29 16:44:46 -0700226 InstallBypassMake() bool
Colin Crossa2f296f2016-11-29 15:16:18 -0800227 SkipInstall()
Ulya Trafimovichcc21bba2020-01-13 15:18:16 +0000228 IsSkipInstall() bool
Jiyong Park374510b2018-03-19 18:23:01 +0900229 ExportedToMake() bool
Inseob Kim8471cda2019-11-15 09:59:12 +0900230 InitRc() Paths
231 VintfFragments() Paths
Jiyong Park52818fc2019-03-18 12:01:38 +0900232 NoticeFile() OptionalPath
Colin Cross36242852017-06-23 15:06:31 -0700233
234 AddProperties(props ...interface{})
235 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700236
Colin Crossae887032017-10-23 17:16:14 -0700237 BuildParamsForTests() []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800238 RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800239 VariablesForTests() map[string]string
Paul Duffine2453c72019-05-31 14:00:04 +0100240
Colin Cross9a362232019-07-01 15:32:45 -0700241 // String returns a string that includes the module name and variants for printing during debugging.
242 String() string
243
Paul Duffine2453c72019-05-31 14:00:04 +0100244 // Get the qualified module id for this module.
245 qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName
246
247 // Get information about the properties that can contain visibility rules.
248 visibilityProperties() []visibilityProperty
Paul Duffin63c6e182019-07-24 14:24:38 +0100249
Jiyong Park6a8cf5f2019-12-30 16:31:09 +0900250 RequiredModuleNames() []string
251 HostRequiredModuleNames() []string
252 TargetRequiredModuleNames() []string
Paul Duffine2453c72019-05-31 14:00:04 +0100253}
254
255// Qualified id for a module
256type qualifiedModuleName struct {
257 // The package (i.e. directory) in which the module is defined, without trailing /
258 pkg string
259
260 // The name of the module, empty string if package.
261 name string
262}
263
264func (q qualifiedModuleName) String() string {
265 if q.name == "" {
266 return "//" + q.pkg
267 }
268 return "//" + q.pkg + ":" + q.name
269}
270
Paul Duffine484f472019-06-20 16:38:08 +0100271func (q qualifiedModuleName) isRootPackage() bool {
272 return q.pkg == "" && q.name == ""
273}
274
Paul Duffine2453c72019-05-31 14:00:04 +0100275// Get the id for the package containing this module.
276func (q qualifiedModuleName) getContainingPackageId() qualifiedModuleName {
277 pkg := q.pkg
278 if q.name == "" {
Paul Duffine484f472019-06-20 16:38:08 +0100279 if pkg == "" {
280 panic(fmt.Errorf("Cannot get containing package id of root package"))
281 }
282
283 index := strings.LastIndex(pkg, "/")
284 if index == -1 {
285 pkg = ""
286 } else {
287 pkg = pkg[:index]
288 }
Paul Duffine2453c72019-05-31 14:00:04 +0100289 }
290 return newPackageId(pkg)
291}
292
293func newPackageId(pkg string) qualifiedModuleName {
294 // A qualified id for a package module has no name.
295 return qualifiedModuleName{pkg: pkg, name: ""}
Colin Cross3f40fa42015-01-30 17:27:36 -0800296}
297
Colin Crossfc754582016-05-17 16:34:16 -0700298type nameProperties struct {
299 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800300 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700301}
302
303type commonProperties struct {
Dan Willemsen0effe062015-11-30 16:06:01 -0800304 // emit build rules for this module
Paul Duffin54d9bb72020-02-12 10:20:56 +0000305 //
306 // Disabling a module should only be done for those modules that cannot be built
307 // in the current environment. Modules that can build in the current environment
308 // but are not usually required (e.g. superceded by a prebuilt) should not be
309 // disabled as that will prevent them from being built by the checkbuild target
310 // and so prevent early detection of changes that have broken those modules.
Dan Willemsen0effe062015-11-30 16:06:01 -0800311 Enabled *bool `android:"arch_variant"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800312
Paul Duffin2e61fa62019-03-28 14:10:57 +0000313 // Controls the visibility of this module to other modules. Allowable values are one or more of
314 // these formats:
315 //
316 // ["//visibility:public"]: Anyone can use this module.
317 // ["//visibility:private"]: Only rules in the module's package (not its subpackages) can use
318 // this module.
Paul Duffin31c43e72020-05-05 19:19:22 +0100319 // ["//visibility:override"]: Discards any rules inherited from defaults or a creating module.
320 // Can only be used at the beginning of a list of visibility rules.
Paul Duffin2e61fa62019-03-28 14:10:57 +0000321 // ["//some/package:__pkg__", "//other/package:__pkg__"]: Only modules in some/package and
322 // other/package (defined in some/package/*.bp and other/package/*.bp) have access to
323 // this module. Note that sub-packages do not have access to the rule; for example,
324 // //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__
325 // is a special module and must be used verbatim. It represents all of the modules in the
326 // package.
327 // ["//project:__subpackages__", "//other:__subpackages__"]: Only modules in packages project
328 // or other or in one of their sub-packages have access to this module. For example,
329 // //project:rule, //project/library:lib or //other/testing/internal:munge are allowed
330 // to depend on this rule (but not //independent:evil)
331 // ["//project"]: This is shorthand for ["//project:__pkg__"]
332 // [":__subpackages__"]: This is shorthand for ["//project:__subpackages__"] where
333 // //project is the module's package. e.g. using [":__subpackages__"] in
334 // packages/apps/Settings/Android.bp is equivalent to
335 // //packages/apps/Settings:__subpackages__.
336 // ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public
337 // for now. It is an error if it is used in a module.
Paul Duffine2453c72019-05-31 14:00:04 +0100338 //
339 // If a module does not specify the `visibility` property then it uses the
340 // `default_visibility` property of the `package` module in the module's package.
341 //
342 // If the `default_visibility` property is not set for the module's package then
Paul Duffine484f472019-06-20 16:38:08 +0100343 // it will use the `default_visibility` of its closest ancestor package for which
344 // a `default_visibility` property is specified.
345 //
346 // If no `default_visibility` property can be found then the module uses the
347 // global default of `//visibility:legacy_public`.
Paul Duffine2453c72019-05-31 14:00:04 +0100348 //
Paul Duffin95d53b52019-07-24 13:45:05 +0100349 // The `visibility` property has no effect on a defaults module although it does
350 // apply to any non-defaults module that uses it. To set the visibility of a
351 // defaults module, use the `defaults_visibility` property on the defaults module;
352 // not to be confused with the `default_visibility` property on the package module.
353 //
Paul Duffin2e61fa62019-03-28 14:10:57 +0000354 // See https://android.googlesource.com/platform/build/soong/+/master/README.md#visibility for
355 // more details.
356 Visibility []string
357
Colin Cross7d5136f2015-05-11 13:39:40 -0700358 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800359 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
360 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
361 // platform
Colin Cross7d716ba2017-11-01 10:38:29 -0700362 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700363
364 Target struct {
365 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700366 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700367 }
368 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700369 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700370 }
371 }
372
Paul Duffin28d70c72020-02-25 15:50:49 +0000373 // If set to true then the archMutator will create variants for each arch specific target
374 // (e.g. 32/64) that the module is required to produce. If set to false then it will only
375 // create a variant for the architecture and will list the additional arch specific targets
376 // that the variant needs to produce in the CompileMultiTargets property.
Colin Crossee0bc3b2018-10-02 22:01:37 -0700377 UseTargetVariants bool `blueprint:"mutated"`
378 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800379
Dan Willemsen782a2d12015-12-21 14:55:28 -0800380 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700381 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800382
Colin Cross55708f32017-03-20 13:23:34 -0700383 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700384 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700385
Jiyong Park2db76922017-11-08 16:03:48 +0900386 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
387 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
388 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700389 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700390
Jiyong Park2db76922017-11-08 16:03:48 +0900391 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
392 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
393 Soc_specific *bool
394
395 // whether this module is specific to a device, not only for SoC, but also for off-chip
396 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
397 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
398 // This implies `soc_specific:true`.
399 Device_specific *bool
400
401 // whether this module is specific to a software configuration of a product (e.g. country,
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900402 // network operator, etc). When set to true, it is installed into /product (or
403 // /system/product if product partition does not exist).
Jiyong Park2db76922017-11-08 16:03:48 +0900404 Product_specific *bool
405
Justin Yund5f6c822019-06-25 16:47:17 +0900406 // whether this module extends system. When set to true, it is installed into /system_ext
407 // (or /system/system_ext if system_ext partition does not exist).
408 System_ext_specific *bool
409
Jiyong Parkf9332f12018-02-01 00:54:12 +0900410 // Whether this module is installed to recovery partition
411 Recovery *bool
412
Yifan Hong1b3348d2020-01-21 15:53:22 -0800413 // Whether this module is installed to ramdisk
414 Ramdisk *bool
415
dimitry1f33e402019-03-26 12:39:31 +0100416 // Whether this module is built for non-native architecures (also known as native bridge binary)
417 Native_bridge_supported *bool `android:"arch_variant"`
418
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700419 // init.rc files to be installed if this module is installed
Colin Cross27b922f2019-03-04 22:35:41 -0800420 Init_rc []string `android:"path"`
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700421
Steven Moreland57a23d22018-04-04 15:42:19 -0700422 // VINTF manifest fragments to be installed if this module is installed
Colin Cross27b922f2019-03-04 22:35:41 -0800423 Vintf_fragments []string `android:"path"`
Steven Moreland57a23d22018-04-04 15:42:19 -0700424
Chris Wolfe998306e2016-08-15 14:47:23 -0400425 // names of other modules to install if this module is installed
Colin Crossc602b7d2017-05-05 13:36:36 -0700426 Required []string `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400427
Sasha Smundakb6d23052019-04-01 18:37:36 -0700428 // names of other modules to install on host if this module is installed
429 Host_required []string `android:"arch_variant"`
430
431 // names of other modules to install on target if this module is installed
432 Target_required []string `android:"arch_variant"`
433
Colin Cross5aac3622017-08-31 15:07:09 -0700434 // relative path to a file to include in the list of notices for the device
Colin Cross27b922f2019-03-04 22:35:41 -0800435 Notice *string `android:"path"`
Colin Cross5aac3622017-08-31 15:07:09 -0700436
Dan Willemsen569edc52018-11-19 09:33:29 -0800437 Dist struct {
438 // copy the output of this module to the $DIST_DIR when `dist` is specified on the
439 // command line and any of these targets are also on the command line, or otherwise
440 // built
441 Targets []string `android:"arch_variant"`
442
443 // The name of the output artifact. This defaults to the basename of the output of
444 // the module.
445 Dest *string `android:"arch_variant"`
446
447 // The directory within the dist directory to store the artifact. Defaults to the
448 // top level directory ("").
449 Dir *string `android:"arch_variant"`
450
451 // A suffix to add to the artifact file name (before any extension).
452 Suffix *string `android:"arch_variant"`
453 } `android:"arch_variant"`
454
Paul Duffin28d70c72020-02-25 15:50:49 +0000455 // The OsType of artifacts that this module variant is responsible for creating.
456 //
457 // Set by osMutator
458 CompileOS OsType `blueprint:"mutated"`
459
460 // The Target of artifacts that this module variant is responsible for creating.
461 //
462 // Set by archMutator
463 CompileTarget Target `blueprint:"mutated"`
464
465 // The additional arch specific targets (e.g. 32/64 bit) that this module variant is
466 // responsible for creating.
467 //
468 // By default this is nil as, where necessary, separate variants are created for the
469 // different multilib types supported and that information is encapsulated in the
470 // CompileTarget so the module variant simply needs to create artifacts for that.
471 //
472 // However, if UseTargetVariants is set to false (e.g. by
473 // InitAndroidMultiTargetsArchModule) then no separate variants are created for the
474 // multilib targets. Instead a single variant is created for the architecture and
475 // this contains the multilib specific targets that this variant should create.
476 //
477 // Set by archMutator
Colin Crossee0bc3b2018-10-02 22:01:37 -0700478 CompileMultiTargets []Target `blueprint:"mutated"`
Paul Duffin28d70c72020-02-25 15:50:49 +0000479
480 // True if the module variant's CompileTarget is the primary target
481 //
482 // Set by archMutator
483 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800484
485 // Set by InitAndroidModule
486 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700487 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700488
Paul Duffinb0cbec32020-02-25 19:26:33 +0000489 // If set to true then a CommonOS variant will be created which will have dependencies
490 // on all its OsType specific variants. Used by sdk/module_exports to create a snapshot
491 // that covers all os and architecture variants.
492 //
493 // The OsType specific variants can be retrieved by calling
494 // GetOsSpecificVariantsOfCommonOSVariant
495 //
496 // Set at module initialization time by calling InitCommonOSAndroidMultiTargetsArchModule
497 CreateCommonOSVariant bool `blueprint:"mutated"`
498
499 // If set to true then this variant is the CommonOS variant that has dependencies on its
500 // OsType specific variants.
501 //
502 // Set by osMutator.
503 CommonOSVariant bool `blueprint:"mutated"`
504
Colin Crossce75d2c2016-10-06 16:12:58 -0700505 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800506
507 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross6c4f21f2019-06-06 15:41:36 -0700508
509 MissingDeps []string `blueprint:"mutated"`
Colin Cross9a362232019-07-01 15:32:45 -0700510
511 // Name and variant strings stored by mutators to enable Module.String()
512 DebugName string `blueprint:"mutated"`
513 DebugMutators []string `blueprint:"mutated"`
514 DebugVariations []string `blueprint:"mutated"`
Colin Cross7228ecd2019-11-18 16:00:16 -0800515
516 // set by ImageMutator
517 ImageVariation string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800518}
519
520type hostAndDeviceProperties struct {
Colin Cross4e81d702018-11-09 10:36:55 -0800521 // If set to true, build a variant of the module for the host. Defaults to false.
522 Host_supported *bool
523
524 // If set to true, build a variant of the module for the device. Defaults to true.
Colin Crossa4190c12016-07-12 13:11:25 -0700525 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800526}
527
Colin Crossc472d572015-03-17 15:06:21 -0700528type Multilib string
529
530const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800531 MultilibBoth Multilib = "both"
532 MultilibFirst Multilib = "first"
533 MultilibCommon Multilib = "common"
534 MultilibCommonFirst Multilib = "common_first"
535 MultilibDefault Multilib = ""
Colin Crossc472d572015-03-17 15:06:21 -0700536)
537
Colin Crossa1ad8d12016-06-01 17:09:44 -0700538type HostOrDeviceSupported int
539
540const (
541 _ HostOrDeviceSupported = iota
Dan Albert0981b5c2018-08-02 13:46:35 -0700542
543 // Host and HostCross are built by default. Device is not supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700544 HostSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700545
546 // Host is built by default. HostCross and Device are not supported.
Dan Albertc6345fb2016-10-20 01:36:11 -0700547 HostSupportedNoCross
Dan Albert0981b5c2018-08-02 13:46:35 -0700548
549 // Device is built by default. Host and HostCross are not supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700550 DeviceSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700551
552 // Device is built by default. Host and HostCross are supported.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700553 HostAndDeviceSupported
Dan Albert0981b5c2018-08-02 13:46:35 -0700554
555 // Host, HostCross, and Device are built by default.
Colin Crossa1ad8d12016-06-01 17:09:44 -0700556 HostAndDeviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700557
558 // Nothing is supported. This is not exposed to the user, but used to mark a
559 // host only module as unsupported when the module type is not supported on
560 // the host OS. E.g. benchmarks are supported on Linux but not Darwin.
Dan Willemsen0b24c742016-10-04 15:13:37 -0700561 NeitherHostNorDeviceSupported
Colin Crossa1ad8d12016-06-01 17:09:44 -0700562)
563
Jiyong Park2db76922017-11-08 16:03:48 +0900564type moduleKind int
565
566const (
567 platformModule moduleKind = iota
568 deviceSpecificModule
569 socSpecificModule
570 productSpecificModule
Justin Yund5f6c822019-06-25 16:47:17 +0900571 systemExtSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900572)
573
574func (k moduleKind) String() string {
575 switch k {
576 case platformModule:
577 return "platform"
578 case deviceSpecificModule:
579 return "device-specific"
580 case socSpecificModule:
581 return "soc-specific"
582 case productSpecificModule:
583 return "product-specific"
Justin Yund5f6c822019-06-25 16:47:17 +0900584 case systemExtSpecificModule:
585 return "systemext-specific"
Jiyong Park2db76922017-11-08 16:03:48 +0900586 default:
587 panic(fmt.Errorf("unknown module kind %d", k))
588 }
589}
590
Colin Cross9d34f352019-11-22 16:03:51 -0800591func initAndroidModuleBase(m Module) {
592 m.base().module = m
593}
594
Colin Cross36242852017-06-23 15:06:31 -0700595func InitAndroidModule(m Module) {
Colin Cross9d34f352019-11-22 16:03:51 -0800596 initAndroidModuleBase(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800597 base := m.base()
Colin Cross5049f022015-03-18 13:28:46 -0700598
Colin Cross36242852017-06-23 15:06:31 -0700599 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700600 &base.nameProperties,
Colin Cross18c46802019-09-24 22:19:02 -0700601 &base.commonProperties)
602
Colin Crosseabaedd2020-02-06 17:01:55 -0800603 initProductVariableModule(m)
Colin Cross18c46802019-09-24 22:19:02 -0700604
Colin Crossa3a97412019-03-18 12:24:29 -0700605 base.generalProperties = m.GetProperties()
Pirama Arumuga Nainar955dc492018-04-17 14:58:42 -0700606 base.customizableProperties = m.GetProperties()
Paul Duffin63c6e182019-07-24 14:24:38 +0100607
608 // The default_visibility property needs to be checked and parsed by the visibility module during
Paul Duffinabc9a642020-05-01 17:52:01 +0100609 // its checking and parsing phases so make it the primary visibility property.
610 setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility)
Colin Cross5049f022015-03-18 13:28:46 -0700611}
612
Colin Cross36242852017-06-23 15:06:31 -0700613func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
614 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700615
616 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800617 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700618 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700619 base.commonProperties.ArchSpecific = true
Colin Crossee0bc3b2018-10-02 22:01:37 -0700620 base.commonProperties.UseTargetVariants = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800621
Dan Willemsen218f6562015-07-08 18:13:11 -0700622 switch hod {
Nan Zhang1a0f09b2017-07-05 10:35:11 -0700623 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Cross36242852017-06-23 15:06:31 -0700624 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800625 }
626
Colin Cross36242852017-06-23 15:06:31 -0700627 InitArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800628}
629
Colin Crossee0bc3b2018-10-02 22:01:37 -0700630func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
631 InitAndroidArchModule(m, hod, defaultMultilib)
632 m.base().commonProperties.UseTargetVariants = false
633}
634
Paul Duffinb0cbec32020-02-25 19:26:33 +0000635// As InitAndroidMultiTargetsArchModule except it creates an additional CommonOS variant that
636// has dependencies on all the OsType specific variants.
637func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
638 InitAndroidArchModule(m, hod, defaultMultilib)
639 m.base().commonProperties.UseTargetVariants = false
640 m.base().commonProperties.CreateCommonOSVariant = true
641}
642
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800643// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800644// modules. It should be included as an anonymous field in every module
645// struct definition. InitAndroidModule should then be called from the module's
646// factory function, and the return values from InitAndroidModule should be
647// returned from the factory function.
648//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800649// The ModuleBase type is responsible for implementing the GenerateBuildActions
650// method to support the blueprint.Module interface. This method will then call
651// the module's GenerateAndroidBuildActions method once for each build variant
Colin Cross25de6c32019-06-06 14:29:25 -0700652// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext
653// rather than the usual blueprint.ModuleContext.
654// ModuleContext exposes extra functionality specific to the Android build
Colin Cross3f40fa42015-01-30 17:27:36 -0800655// system including details about the particular build variant that is to be
656// generated.
657//
658// For example:
659//
660// import (
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800661// "android/soong/android"
Colin Cross3f40fa42015-01-30 17:27:36 -0800662// )
663//
664// type myModule struct {
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800665// android.ModuleBase
Colin Cross3f40fa42015-01-30 17:27:36 -0800666// properties struct {
667// MyProperty string
668// }
669// }
670//
Colin Cross36242852017-06-23 15:06:31 -0700671// func NewMyModule() android.Module) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800672// m := &myModule{}
Colin Cross36242852017-06-23 15:06:31 -0700673// m.AddProperties(&m.properties)
674// android.InitAndroidModule(m)
675// return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800676// }
677//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800678// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800679// // Get the CPU architecture for the current build variant.
680// variantArch := ctx.Arch()
681//
682// // ...
683// }
Colin Cross635c3b02016-05-18 15:37:25 -0700684type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800685 // Putting the curiously recurring thing pointing to the thing that contains
686 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700687 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700688 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800689
Colin Crossfc754582016-05-17 16:34:16 -0700690 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800691 commonProperties commonProperties
Colin Cross18c46802019-09-24 22:19:02 -0700692 variableProperties interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800693 hostAndDeviceProperties hostAndDeviceProperties
694 generalProperties []interface{}
Colin Crossc17727d2018-10-24 12:42:09 -0700695 archProperties [][]interface{}
Colin Crossa120ec12016-08-19 16:07:38 -0700696 customizableProperties []interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800697
Paul Duffin63c6e182019-07-24 14:24:38 +0100698 // Information about all the properties on the module that contains visibility rules that need
699 // checking.
700 visibilityPropertyInfo []visibilityProperty
701
702 // The primary visibility property, may be nil, that controls access to the module.
703 primaryVisibilityProperty visibilityProperty
704
Colin Cross3f40fa42015-01-30 17:27:36 -0800705 noAddressSanitizer bool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700706 installFiles Paths
707 checkbuildFiles Paths
Jiyong Park52818fc2019-03-18 12:01:38 +0900708 noticeFile OptionalPath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700709
710 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
711 // Only set on the final variant of each module
Colin Cross0875c522017-11-28 17:34:01 -0800712 installTarget WritablePath
713 checkbuildTarget WritablePath
Colin Cross1f8c52b2015-06-16 16:38:17 -0700714 blueprintDir string
Colin Crossa120ec12016-08-19 16:07:38 -0700715
Colin Cross178a5092016-09-13 13:42:32 -0700716 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700717
718 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700719
720 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700721 buildParams []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800722 ruleParams map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800723 variables map[string]string
Colin Crossa9d8bee2018-10-02 13:59:46 -0700724
Inseob Kim8471cda2019-11-15 09:59:12 +0900725 initRcPaths Paths
726 vintfFragmentsPaths Paths
727
Colin Crossa9d8bee2018-10-02 13:59:46 -0700728 prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool
Colin Cross36242852017-06-23 15:06:31 -0700729}
730
Colin Cross4157e882019-06-06 16:57:04 -0700731func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
Colin Cross5f692ec2019-02-01 16:53:07 -0800732
Colin Cross4157e882019-06-06 16:57:04 -0700733func (m *ModuleBase) AddProperties(props ...interface{}) {
734 m.registerProps = append(m.registerProps, props...)
Colin Cross36242852017-06-23 15:06:31 -0700735}
736
Colin Cross4157e882019-06-06 16:57:04 -0700737func (m *ModuleBase) GetProperties() []interface{} {
738 return m.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -0800739}
740
Colin Cross4157e882019-06-06 16:57:04 -0700741func (m *ModuleBase) BuildParamsForTests() []BuildParams {
742 return m.buildParams
Colin Crosscec81712017-07-13 14:43:27 -0700743}
744
Colin Cross4157e882019-06-06 16:57:04 -0700745func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
746 return m.ruleParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800747}
748
Colin Cross4157e882019-06-06 16:57:04 -0700749func (m *ModuleBase) VariablesForTests() map[string]string {
750 return m.variables
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800751}
752
Colin Cross4157e882019-06-06 16:57:04 -0700753func (m *ModuleBase) Prefer32(prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool) {
754 m.prefer32 = prefer32
Colin Crossa9d8bee2018-10-02 13:59:46 -0700755}
756
Colin Crossce75d2c2016-10-06 16:12:58 -0700757// Name returns the name of the module. It may be overridden by individual module types, for
758// example prebuilts will prepend prebuilt_ to the name.
Colin Cross4157e882019-06-06 16:57:04 -0700759func (m *ModuleBase) Name() string {
760 return String(m.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -0700761}
762
Colin Cross9a362232019-07-01 15:32:45 -0700763// String returns a string that includes the module name and variants for printing during debugging.
764func (m *ModuleBase) String() string {
765 sb := strings.Builder{}
766 sb.WriteString(m.commonProperties.DebugName)
767 sb.WriteString("{")
768 for i := range m.commonProperties.DebugMutators {
769 if i != 0 {
770 sb.WriteString(",")
771 }
772 sb.WriteString(m.commonProperties.DebugMutators[i])
773 sb.WriteString(":")
774 sb.WriteString(m.commonProperties.DebugVariations[i])
775 }
776 sb.WriteString("}")
777 return sb.String()
778}
779
Colin Crossce75d2c2016-10-06 16:12:58 -0700780// BaseModuleName returns the name of the module as specified in the blueprints file.
Colin Cross4157e882019-06-06 16:57:04 -0700781func (m *ModuleBase) BaseModuleName() string {
782 return String(m.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -0700783}
784
Colin Cross4157e882019-06-06 16:57:04 -0700785func (m *ModuleBase) base() *ModuleBase {
786 return m
Colin Cross3f40fa42015-01-30 17:27:36 -0800787}
788
Paul Duffine2453c72019-05-31 14:00:04 +0100789func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName {
790 return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()}
791}
792
793func (m *ModuleBase) visibilityProperties() []visibilityProperty {
Paul Duffin63c6e182019-07-24 14:24:38 +0100794 return m.visibilityPropertyInfo
795}
796
Colin Cross4157e882019-06-06 16:57:04 -0700797func (m *ModuleBase) Target() Target {
798 return m.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -0800799}
800
Colin Cross4157e882019-06-06 16:57:04 -0700801func (m *ModuleBase) TargetPrimary() bool {
802 return m.commonProperties.CompilePrimary
Colin Cross8b74d172016-09-13 09:59:14 -0700803}
804
Colin Cross4157e882019-06-06 16:57:04 -0700805func (m *ModuleBase) MultiTargets() []Target {
806 return m.commonProperties.CompileMultiTargets
Colin Crossee0bc3b2018-10-02 22:01:37 -0700807}
808
Colin Cross4157e882019-06-06 16:57:04 -0700809func (m *ModuleBase) Os() OsType {
810 return m.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -0800811}
812
Colin Cross4157e882019-06-06 16:57:04 -0700813func (m *ModuleBase) Host() bool {
814 return m.Os().Class == Host || m.Os().Class == HostCross
Dan Willemsen97750522016-02-09 17:43:51 -0800815}
816
Colin Cross4157e882019-06-06 16:57:04 -0700817func (m *ModuleBase) Arch() Arch {
818 return m.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -0800819}
820
Colin Cross4157e882019-06-06 16:57:04 -0700821func (m *ModuleBase) ArchSpecific() bool {
822 return m.commonProperties.ArchSpecific
Dan Willemsen0b24c742016-10-04 15:13:37 -0700823}
824
Paul Duffinb0cbec32020-02-25 19:26:33 +0000825// True if the current variant is a CommonOS variant, false otherwise.
826func (m *ModuleBase) IsCommonOSVariant() bool {
827 return m.commonProperties.CommonOSVariant
828}
829
Colin Cross4157e882019-06-06 16:57:04 -0700830func (m *ModuleBase) OsClassSupported() []OsClass {
831 switch m.commonProperties.HostOrDeviceSupported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700832 case HostSupported:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700833 return []OsClass{Host, HostCross}
Dan Albertc6345fb2016-10-20 01:36:11 -0700834 case HostSupportedNoCross:
835 return []OsClass{Host}
Colin Crossa1ad8d12016-06-01 17:09:44 -0700836 case DeviceSupported:
837 return []OsClass{Device}
Dan Albert0981b5c2018-08-02 13:46:35 -0700838 case HostAndDeviceSupported, HostAndDeviceDefault:
Colin Crossa1ad8d12016-06-01 17:09:44 -0700839 var supported []OsClass
Colin Cross4157e882019-06-06 16:57:04 -0700840 if Bool(m.hostAndDeviceProperties.Host_supported) ||
841 (m.commonProperties.HostOrDeviceSupported == HostAndDeviceDefault &&
842 m.hostAndDeviceProperties.Host_supported == nil) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700843 supported = append(supported, Host, HostCross)
844 }
Colin Cross4157e882019-06-06 16:57:04 -0700845 if m.hostAndDeviceProperties.Device_supported == nil ||
846 *m.hostAndDeviceProperties.Device_supported {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700847 supported = append(supported, Device)
848 }
849 return supported
850 default:
851 return nil
852 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800853}
854
Colin Cross4157e882019-06-06 16:57:04 -0700855func (m *ModuleBase) DeviceSupported() bool {
856 return m.commonProperties.HostOrDeviceSupported == DeviceSupported ||
857 m.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
858 (m.hostAndDeviceProperties.Device_supported == nil ||
859 *m.hostAndDeviceProperties.Device_supported)
Colin Cross3f40fa42015-01-30 17:27:36 -0800860}
861
Paul Duffine44358f2019-11-26 18:04:12 +0000862func (m *ModuleBase) HostSupported() bool {
863 return m.commonProperties.HostOrDeviceSupported == HostSupported ||
864 m.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
865 (m.hostAndDeviceProperties.Host_supported != nil &&
866 *m.hostAndDeviceProperties.Host_supported)
867}
868
Colin Cross4157e882019-06-06 16:57:04 -0700869func (m *ModuleBase) Platform() bool {
Justin Yund5f6c822019-06-25 16:47:17 +0900870 return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.SystemExtSpecific()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900871}
872
Colin Cross4157e882019-06-06 16:57:04 -0700873func (m *ModuleBase) DeviceSpecific() bool {
874 return Bool(m.commonProperties.Device_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900875}
876
Colin Cross4157e882019-06-06 16:57:04 -0700877func (m *ModuleBase) SocSpecific() bool {
878 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900879}
880
Colin Cross4157e882019-06-06 16:57:04 -0700881func (m *ModuleBase) ProductSpecific() bool {
882 return Bool(m.commonProperties.Product_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900883}
884
Justin Yund5f6c822019-06-25 16:47:17 +0900885func (m *ModuleBase) SystemExtSpecific() bool {
886 return Bool(m.commonProperties.System_ext_specific)
Dario Frenifd05a742018-05-29 13:28:54 +0100887}
888
Bill Peckham1c610cf2020-03-20 18:33:20 -0700889func (m *ModuleBase) PartitionTag(config DeviceConfig) string {
890 partition := "system"
891 if m.SocSpecific() {
892 // A SoC-specific module could be on the vendor partition at
893 // "vendor" or the system partition at "system/vendor".
894 if config.VendorPath() == "vendor" {
895 partition = "vendor"
896 }
897 } else if m.DeviceSpecific() {
898 // A device-specific module could be on the odm partition at
899 // "odm", the vendor partition at "vendor/odm", or the system
900 // partition at "system/vendor/odm".
901 if config.OdmPath() == "odm" {
902 partition = "odm"
Ulya Trafimovichcc21bba2020-01-13 15:18:16 +0000903 } else if strings.HasPrefix(config.OdmPath(), "vendor/") {
Bill Peckham1c610cf2020-03-20 18:33:20 -0700904 partition = "vendor"
905 }
906 } else if m.ProductSpecific() {
907 // A product-specific module could be on the product partition
908 // at "product" or the system partition at "system/product".
909 if config.ProductPath() == "product" {
910 partition = "product"
911 }
912 } else if m.SystemExtSpecific() {
913 // A system_ext-specific module could be on the system_ext
914 // partition at "system_ext" or the system partition at
915 // "system/system_ext".
916 if config.SystemExtPath() == "system_ext" {
917 partition = "system_ext"
918 }
919 }
920 return partition
921}
922
Colin Cross4157e882019-06-06 16:57:04 -0700923func (m *ModuleBase) Enabled() bool {
924 if m.commonProperties.Enabled == nil {
925 return !m.Os().DefaultDisabled
Dan Willemsen490fd492015-11-24 17:53:15 -0800926 }
Colin Cross4157e882019-06-06 16:57:04 -0700927 return *m.commonProperties.Enabled
Colin Cross3f40fa42015-01-30 17:27:36 -0800928}
929
Inseob Kimeec88e12020-01-22 11:11:29 +0900930func (m *ModuleBase) Disable() {
931 m.commonProperties.Enabled = proptools.BoolPtr(false)
932}
933
Colin Cross4157e882019-06-06 16:57:04 -0700934func (m *ModuleBase) SkipInstall() {
935 m.commonProperties.SkipInstall = true
Colin Crossce75d2c2016-10-06 16:12:58 -0700936}
937
Ulya Trafimovichcc21bba2020-01-13 15:18:16 +0000938func (m *ModuleBase) IsSkipInstall() bool {
939 return m.commonProperties.SkipInstall == true
940}
941
Colin Cross4157e882019-06-06 16:57:04 -0700942func (m *ModuleBase) ExportedToMake() bool {
943 return m.commonProperties.NamespaceExportedToMake
Jiyong Park374510b2018-03-19 18:23:01 +0900944}
945
Colin Cross4157e882019-06-06 16:57:04 -0700946func (m *ModuleBase) computeInstallDeps(
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700947 ctx blueprint.ModuleContext) Paths {
Colin Cross3f40fa42015-01-30 17:27:36 -0800948
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700949 result := Paths{}
Colin Cross6b753602018-06-21 13:03:07 -0700950 // TODO(ccross): we need to use WalkDeps and have some way to know which dependencies require installation
Colin Cross3f40fa42015-01-30 17:27:36 -0800951 ctx.VisitDepsDepthFirstIf(isFileInstaller,
952 func(m blueprint.Module) {
953 fileInstaller := m.(fileInstaller)
954 files := fileInstaller.filesToInstall()
955 result = append(result, files...)
956 })
957
958 return result
959}
960
Colin Cross4157e882019-06-06 16:57:04 -0700961func (m *ModuleBase) filesToInstall() Paths {
962 return m.installFiles
Colin Cross3f40fa42015-01-30 17:27:36 -0800963}
964
Colin Cross4157e882019-06-06 16:57:04 -0700965func (m *ModuleBase) NoAddressSanitizer() bool {
966 return m.noAddressSanitizer
Colin Cross3f40fa42015-01-30 17:27:36 -0800967}
968
Colin Cross4157e882019-06-06 16:57:04 -0700969func (m *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -0800970 return false
971}
972
Jaewoong Jung0949f312019-09-11 10:25:18 -0700973func (m *ModuleBase) InstallInTestcases() bool {
974 return false
975}
976
Colin Cross4157e882019-06-06 16:57:04 -0700977func (m *ModuleBase) InstallInSanitizerDir() bool {
Vishwath Mohan1dd88392017-03-29 22:00:18 -0700978 return false
979}
980
Yifan Hong1b3348d2020-01-21 15:53:22 -0800981func (m *ModuleBase) InstallInRamdisk() bool {
982 return Bool(m.commonProperties.Ramdisk)
983}
984
Colin Cross4157e882019-06-06 16:57:04 -0700985func (m *ModuleBase) InstallInRecovery() bool {
986 return Bool(m.commonProperties.Recovery)
Jiyong Parkf9332f12018-02-01 00:54:12 +0900987}
988
Colin Cross90ba5f42019-10-02 11:10:58 -0700989func (m *ModuleBase) InstallInRoot() bool {
990 return false
991}
992
Colin Cross607d8582019-07-29 16:44:46 -0700993func (m *ModuleBase) InstallBypassMake() bool {
994 return false
995}
996
Colin Cross4157e882019-06-06 16:57:04 -0700997func (m *ModuleBase) Owner() string {
998 return String(m.commonProperties.Owner)
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900999}
1000
Colin Cross4157e882019-06-06 16:57:04 -07001001func (m *ModuleBase) NoticeFile() OptionalPath {
1002 return m.noticeFile
Jiyong Park52818fc2019-03-18 12:01:38 +09001003}
1004
Colin Cross7228ecd2019-11-18 16:00:16 -08001005func (m *ModuleBase) setImageVariation(variant string) {
1006 m.commonProperties.ImageVariation = variant
1007}
1008
1009func (m *ModuleBase) ImageVariation() blueprint.Variation {
1010 return blueprint.Variation{
1011 Mutator: "image",
1012 Variation: m.base().commonProperties.ImageVariation,
1013 }
1014}
1015
Paul Duffin6cb8f172020-03-12 10:24:35 +00001016func (m *ModuleBase) getVariationByMutatorName(mutator string) string {
1017 for i, v := range m.commonProperties.DebugMutators {
1018 if v == mutator {
1019 return m.commonProperties.DebugVariations[i]
1020 }
1021 }
1022
1023 return ""
1024}
1025
Yifan Hong1b3348d2020-01-21 15:53:22 -08001026func (m *ModuleBase) InRamdisk() bool {
1027 return m.base().commonProperties.ImageVariation == RamdiskVariation
1028}
1029
Colin Cross7228ecd2019-11-18 16:00:16 -08001030func (m *ModuleBase) InRecovery() bool {
1031 return m.base().commonProperties.ImageVariation == RecoveryVariation
1032}
1033
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09001034func (m *ModuleBase) RequiredModuleNames() []string {
1035 return m.base().commonProperties.Required
1036}
1037
1038func (m *ModuleBase) HostRequiredModuleNames() []string {
1039 return m.base().commonProperties.Host_required
1040}
1041
1042func (m *ModuleBase) TargetRequiredModuleNames() []string {
1043 return m.base().commonProperties.Target_required
1044}
1045
Inseob Kim8471cda2019-11-15 09:59:12 +09001046func (m *ModuleBase) InitRc() Paths {
1047 return append(Paths{}, m.initRcPaths...)
1048}
1049
1050func (m *ModuleBase) VintfFragments() Paths {
1051 return append(Paths{}, m.vintfFragmentsPaths...)
1052}
1053
Colin Cross4157e882019-06-06 16:57:04 -07001054func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001055 allInstalledFiles := Paths{}
1056 allCheckbuildFiles := Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08001057 ctx.VisitAllModuleVariants(func(module Module) {
1058 a := module.base()
Colin Crossc9404352015-03-26 16:10:12 -07001059 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
1060 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -08001061 })
1062
Colin Cross0875c522017-11-28 17:34:01 -08001063 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -07001064
Jeff Gaston088e29e2017-11-29 16:47:17 -08001065 namespacePrefix := ctx.Namespace().(*Namespace).id
1066 if namespacePrefix != "" {
1067 namespacePrefix = namespacePrefix + "-"
1068 }
1069
Colin Cross3f40fa42015-01-30 17:27:36 -08001070 if len(allInstalledFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -08001071 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
Colin Cross0875c522017-11-28 17:34:01 -08001072 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -07001073 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001074 Output: name,
1075 Implicits: allInstalledFiles,
Colin Crossaabf6792017-11-29 00:27:14 -08001076 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross9454bfa2015-03-17 13:24:18 -07001077 })
1078 deps = append(deps, name)
Colin Cross4157e882019-06-06 16:57:04 -07001079 m.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -07001080 }
1081
1082 if len(allCheckbuildFiles) > 0 {
Jeff Gaston088e29e2017-11-29 16:47:17 -08001083 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
Colin Cross0875c522017-11-28 17:34:01 -08001084 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -07001085 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08001086 Output: name,
1087 Implicits: allCheckbuildFiles,
Colin Cross9454bfa2015-03-17 13:24:18 -07001088 })
1089 deps = append(deps, name)
Colin Cross4157e882019-06-06 16:57:04 -07001090 m.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -07001091 }
1092
1093 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001094 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08001095 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001096 suffix = "-soong"
1097 }
1098
Jeff Gaston088e29e2017-11-29 16:47:17 -08001099 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
Colin Cross0875c522017-11-28 17:34:01 -08001100 ctx.Build(pctx, BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -07001101 Rule: blueprint.Phony,
Jeff Gaston088e29e2017-11-29 16:47:17 -08001102 Outputs: []WritablePath{name},
Colin Cross9454bfa2015-03-17 13:24:18 -07001103 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -08001104 })
Colin Cross1f8c52b2015-06-16 16:38:17 -07001105
Colin Cross4157e882019-06-06 16:57:04 -07001106 m.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -08001107 }
1108}
1109
Colin Crossc34d2322020-01-03 15:23:27 -08001110func determineModuleKind(m *ModuleBase, ctx blueprint.EarlyModuleContext) moduleKind {
Colin Cross4157e882019-06-06 16:57:04 -07001111 var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
1112 var deviceSpecific = Bool(m.commonProperties.Device_specific)
1113 var productSpecific = Bool(m.commonProperties.Product_specific)
Justin Yund5f6c822019-06-25 16:47:17 +09001114 var systemExtSpecific = Bool(m.commonProperties.System_ext_specific)
Jiyong Park2db76922017-11-08 16:03:48 +09001115
Dario Frenifd05a742018-05-29 13:28:54 +01001116 msg := "conflicting value set here"
1117 if socSpecific && deviceSpecific {
1118 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
Colin Cross4157e882019-06-06 16:57:04 -07001119 if Bool(m.commonProperties.Vendor) {
Jiyong Park2db76922017-11-08 16:03:48 +09001120 ctx.PropertyErrorf("vendor", msg)
1121 }
Colin Cross4157e882019-06-06 16:57:04 -07001122 if Bool(m.commonProperties.Proprietary) {
Jiyong Park2db76922017-11-08 16:03:48 +09001123 ctx.PropertyErrorf("proprietary", msg)
1124 }
Colin Cross4157e882019-06-06 16:57:04 -07001125 if Bool(m.commonProperties.Soc_specific) {
Jiyong Park2db76922017-11-08 16:03:48 +09001126 ctx.PropertyErrorf("soc_specific", msg)
1127 }
1128 }
1129
Justin Yund5f6c822019-06-25 16:47:17 +09001130 if productSpecific && systemExtSpecific {
1131 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and system_ext at the same time.")
1132 ctx.PropertyErrorf("system_ext_specific", msg)
Dario Frenifd05a742018-05-29 13:28:54 +01001133 }
1134
Justin Yund5f6c822019-06-25 16:47:17 +09001135 if (socSpecific || deviceSpecific) && (productSpecific || systemExtSpecific) {
Dario Frenifd05a742018-05-29 13:28:54 +01001136 if productSpecific {
1137 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
1138 } else {
Justin Yund5f6c822019-06-25 16:47:17 +09001139 ctx.PropertyErrorf("system_ext_specific", "a module cannot be specific to SoC or device and system_ext at the same time.")
Dario Frenifd05a742018-05-29 13:28:54 +01001140 }
1141 if deviceSpecific {
1142 ctx.PropertyErrorf("device_specific", msg)
1143 } else {
Colin Cross4157e882019-06-06 16:57:04 -07001144 if Bool(m.commonProperties.Vendor) {
Dario Frenifd05a742018-05-29 13:28:54 +01001145 ctx.PropertyErrorf("vendor", msg)
1146 }
Colin Cross4157e882019-06-06 16:57:04 -07001147 if Bool(m.commonProperties.Proprietary) {
Dario Frenifd05a742018-05-29 13:28:54 +01001148 ctx.PropertyErrorf("proprietary", msg)
1149 }
Colin Cross4157e882019-06-06 16:57:04 -07001150 if Bool(m.commonProperties.Soc_specific) {
Dario Frenifd05a742018-05-29 13:28:54 +01001151 ctx.PropertyErrorf("soc_specific", msg)
1152 }
1153 }
1154 }
1155
Jiyong Park2db76922017-11-08 16:03:48 +09001156 if productSpecific {
1157 return productSpecificModule
Justin Yund5f6c822019-06-25 16:47:17 +09001158 } else if systemExtSpecific {
1159 return systemExtSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +09001160 } else if deviceSpecific {
1161 return deviceSpecificModule
1162 } else if socSpecific {
1163 return socSpecificModule
1164 } else {
1165 return platformModule
1166 }
1167}
1168
Colin Crossc34d2322020-01-03 15:23:27 -08001169func (m *ModuleBase) earlyModuleContextFactory(ctx blueprint.EarlyModuleContext) earlyModuleContext {
Colin Cross1184b642019-12-30 18:43:07 -08001170 return earlyModuleContext{
Colin Crossc34d2322020-01-03 15:23:27 -08001171 EarlyModuleContext: ctx,
1172 kind: determineModuleKind(m, ctx),
1173 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -08001174 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001175}
1176
Colin Cross1184b642019-12-30 18:43:07 -08001177func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext {
1178 return baseModuleContext{
1179 bp: ctx,
1180 earlyModuleContext: m.earlyModuleContextFactory(ctx),
1181 os: m.commonProperties.CompileOS,
1182 target: m.commonProperties.CompileTarget,
1183 targetPrimary: m.commonProperties.CompilePrimary,
1184 multiTargets: m.commonProperties.CompileMultiTargets,
1185 }
1186}
1187
Colin Cross4157e882019-06-06 16:57:04 -07001188func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
Colin Cross25de6c32019-06-06 14:29:25 -07001189 ctx := &moduleContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -07001190 module: m.module,
Colin Crossdc35e212019-06-06 16:13:11 -07001191 bp: blueprintCtx,
Colin Cross0ea8ba82019-06-06 14:33:29 -07001192 baseModuleContext: m.baseModuleContextFactory(blueprintCtx),
1193 installDeps: m.computeInstallDeps(blueprintCtx),
1194 installFiles: m.installFiles,
Colin Cross0ea8ba82019-06-06 14:33:29 -07001195 variables: make(map[string]string),
Colin Cross3f40fa42015-01-30 17:27:36 -08001196 }
1197
Colin Cross6c4f21f2019-06-06 15:41:36 -07001198 // Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never
1199 // reporting missing dependency errors in Blueprint when AllowMissingDependencies == true.
1200 // TODO: This will be removed once defaults modules handle missing dependency errors
1201 blueprintCtx.GetMissingDependencies()
1202
Colin Crossdc35e212019-06-06 16:13:11 -07001203 // For the final GenerateAndroidBuildActions pass, require that all visited dependencies Soong modules and
Paul Duffinb0cbec32020-02-25 19:26:33 +00001204 // are enabled. Unless the module is a CommonOS variant which may have dependencies on disabled variants
1205 // (because the dependencies are added before the modules are disabled). The
1206 // GetOsSpecificVariantsOfCommonOSVariant(...) method will ensure that the disabled variants are
1207 // ignored.
1208 ctx.baseModuleContext.strictVisitDeps = !m.IsCommonOSVariant()
Colin Crossdc35e212019-06-06 16:13:11 -07001209
Colin Cross4c83e5c2019-02-25 14:54:28 -08001210 if ctx.config.captureBuild {
1211 ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
1212 }
1213
Colin Cross67a5c132017-05-09 13:45:28 -07001214 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
1215 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -08001216 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
1217 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -07001218 }
Colin Cross0875c522017-11-28 17:34:01 -08001219 if !ctx.PrimaryArch() {
1220 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -07001221 }
Dan Willemsenb13a9482020-02-14 11:25:54 -08001222 if apex, ok := m.module.(ApexModule); ok && !apex.IsForPlatform() {
1223 suffix = append(suffix, apex.ApexName())
1224 }
Colin Cross67a5c132017-05-09 13:45:28 -07001225
1226 ctx.Variable(pctx, "moduleDesc", desc)
1227
1228 s := ""
1229 if len(suffix) > 0 {
1230 s = " [" + strings.Join(suffix, " ") + "]"
1231 }
1232 ctx.Variable(pctx, "moduleDescSuffix", s)
1233
Dan Willemsen569edc52018-11-19 09:33:29 -08001234 // Some common property checks for properties that will be used later in androidmk.go
Colin Cross4157e882019-06-06 16:57:04 -07001235 if m.commonProperties.Dist.Dest != nil {
1236 _, err := validateSafePath(*m.commonProperties.Dist.Dest)
Dan Willemsen569edc52018-11-19 09:33:29 -08001237 if err != nil {
1238 ctx.PropertyErrorf("dist.dest", "%s", err.Error())
1239 }
1240 }
Colin Cross4157e882019-06-06 16:57:04 -07001241 if m.commonProperties.Dist.Dir != nil {
1242 _, err := validateSafePath(*m.commonProperties.Dist.Dir)
Dan Willemsen569edc52018-11-19 09:33:29 -08001243 if err != nil {
1244 ctx.PropertyErrorf("dist.dir", "%s", err.Error())
1245 }
1246 }
Colin Cross4157e882019-06-06 16:57:04 -07001247 if m.commonProperties.Dist.Suffix != nil {
1248 if strings.Contains(*m.commonProperties.Dist.Suffix, "/") {
Dan Willemsen569edc52018-11-19 09:33:29 -08001249 ctx.PropertyErrorf("dist.suffix", "Suffix may not contain a '/' character.")
1250 }
1251 }
1252
Colin Cross4157e882019-06-06 16:57:04 -07001253 if m.Enabled() {
Jooyung Hand48f3c32019-08-23 11:18:57 +09001254 // ensure all direct android.Module deps are enabled
1255 ctx.VisitDirectDepsBlueprint(func(bm blueprint.Module) {
1256 if _, ok := bm.(Module); ok {
1257 ctx.validateAndroidModule(bm, ctx.baseModuleContext.strictVisitDeps)
1258 }
1259 })
1260
Colin Cross4157e882019-06-06 16:57:04 -07001261 notice := proptools.StringDefault(m.commonProperties.Notice, "NOTICE")
1262 if module := SrcIsModule(notice); module != "" {
1263 m.noticeFile = ctx.ExpandOptionalSource(&notice, "notice")
Jiyong Park52818fc2019-03-18 12:01:38 +09001264 } else {
1265 noticePath := filepath.Join(ctx.ModuleDir(), notice)
Colin Cross4157e882019-06-06 16:57:04 -07001266 m.noticeFile = ExistentPathForSource(ctx, noticePath)
Jaewoong Jung62707f72018-11-16 13:26:43 -08001267 }
Jaewoong Jung5b425e22019-06-17 17:40:56 -07001268
1269 m.module.GenerateAndroidBuildActions(ctx)
1270 if ctx.Failed() {
1271 return
1272 }
1273
1274 m.installFiles = append(m.installFiles, ctx.installFiles...)
1275 m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
Inseob Kim8471cda2019-11-15 09:59:12 +09001276 m.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc)
1277 m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments)
Colin Crossdc35e212019-06-06 16:13:11 -07001278 } else if ctx.Config().AllowMissingDependencies() {
1279 // If the module is not enabled it will not create any build rules, nothing will call
1280 // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
1281 // and report them as an error even when AllowMissingDependencies = true. Call
1282 // ctx.GetMissingDependencies() here to tell blueprint not to handle them.
1283 ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08001284 }
1285
Colin Cross4157e882019-06-06 16:57:04 -07001286 if m == ctx.FinalModule().(Module).base() {
1287 m.generateModuleTarget(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -07001288 if ctx.Failed() {
1289 return
1290 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001291 }
Colin Crosscec81712017-07-13 14:43:27 -07001292
Colin Cross4157e882019-06-06 16:57:04 -07001293 m.buildParams = ctx.buildParams
1294 m.ruleParams = ctx.ruleParams
1295 m.variables = ctx.variables
Colin Cross3f40fa42015-01-30 17:27:36 -08001296}
1297
Colin Cross1184b642019-12-30 18:43:07 -08001298type earlyModuleContext struct {
Colin Crossc34d2322020-01-03 15:23:27 -08001299 blueprint.EarlyModuleContext
Colin Cross1184b642019-12-30 18:43:07 -08001300
1301 kind moduleKind
1302 config Config
1303}
1304
1305func (e *earlyModuleContext) Glob(globPattern string, excludes []string) Paths {
1306 ret, err := e.GlobWithDeps(globPattern, excludes)
1307 if err != nil {
1308 e.ModuleErrorf("glob: %s", err.Error())
1309 }
1310 return pathsForModuleSrcFromFullPath(e, ret, true)
1311}
1312
1313func (e *earlyModuleContext) GlobFiles(globPattern string, excludes []string) Paths {
1314 ret, err := e.GlobWithDeps(globPattern, excludes)
1315 if err != nil {
1316 e.ModuleErrorf("glob: %s", err.Error())
1317 }
1318 return pathsForModuleSrcFromFullPath(e, ret, false)
1319}
1320
Colin Cross988414c2020-01-11 01:11:46 +00001321func (b *earlyModuleContext) IsSymlink(path Path) bool {
1322 fileInfo, err := b.config.fs.Lstat(path.String())
1323 if err != nil {
1324 b.ModuleErrorf("os.Lstat(%q) failed: %s", path.String(), err)
1325 }
1326 return fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink
1327}
1328
1329func (b *earlyModuleContext) Readlink(path Path) string {
1330 dest, err := b.config.fs.Readlink(path.String())
1331 if err != nil {
1332 b.ModuleErrorf("os.Readlink(%q) failed: %s", path.String(), err)
1333 }
1334 return dest
1335}
1336
Colin Cross1184b642019-12-30 18:43:07 -08001337func (e *earlyModuleContext) Module() Module {
Colin Crossc34d2322020-01-03 15:23:27 -08001338 module, _ := e.EarlyModuleContext.Module().(Module)
Colin Cross1184b642019-12-30 18:43:07 -08001339 return module
1340}
1341
1342func (e *earlyModuleContext) Config() Config {
Colin Crossc34d2322020-01-03 15:23:27 -08001343 return e.EarlyModuleContext.Config().(Config)
Colin Cross1184b642019-12-30 18:43:07 -08001344}
1345
1346func (e *earlyModuleContext) AConfig() Config {
1347 return e.config
1348}
1349
1350func (e *earlyModuleContext) DeviceConfig() DeviceConfig {
1351 return DeviceConfig{e.config.deviceConfig}
1352}
1353
1354func (e *earlyModuleContext) Platform() bool {
1355 return e.kind == platformModule
1356}
1357
1358func (e *earlyModuleContext) DeviceSpecific() bool {
1359 return e.kind == deviceSpecificModule
1360}
1361
1362func (e *earlyModuleContext) SocSpecific() bool {
1363 return e.kind == socSpecificModule
1364}
1365
1366func (e *earlyModuleContext) ProductSpecific() bool {
1367 return e.kind == productSpecificModule
1368}
1369
1370func (e *earlyModuleContext) SystemExtSpecific() bool {
1371 return e.kind == systemExtSpecificModule
1372}
1373
1374type baseModuleContext struct {
1375 bp blueprint.BaseModuleContext
1376 earlyModuleContext
Colin Crossfb0c16e2019-11-20 17:12:35 -08001377 os OsType
Colin Cross8b74d172016-09-13 09:59:14 -07001378 target Target
Colin Crossee0bc3b2018-10-02 22:01:37 -07001379 multiTargets []Target
Colin Cross8b74d172016-09-13 09:59:14 -07001380 targetPrimary bool
1381 debug bool
Colin Crossdc35e212019-06-06 16:13:11 -07001382
1383 walkPath []Module
Paul Duffinf0207962020-03-31 11:31:36 +01001384 tagPath []blueprint.DependencyTag
Colin Crossdc35e212019-06-06 16:13:11 -07001385
1386 strictVisitDeps bool // If true, enforce that all dependencies are enabled
Colin Crossf6566ed2015-03-24 11:13:38 -07001387}
1388
Ulya Trafimovichcc21bba2020-01-13 15:18:16 +00001389func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string {
1390 return b.bp.OtherModuleName(m)
1391}
1392func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { return b.bp.OtherModuleDir(m) }
Colin Cross1184b642019-12-30 18:43:07 -08001393func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) {
Jooyung Han67b141d2020-02-26 02:05:18 +09001394 b.bp.OtherModuleErrorf(m, fmt, args...)
Colin Cross1184b642019-12-30 18:43:07 -08001395}
1396func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag {
1397 return b.bp.OtherModuleDependencyTag(m)
1398}
Ulya Trafimovichcc21bba2020-01-13 15:18:16 +00001399func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) }
1400func (b *baseModuleContext) OtherModuleType(m blueprint.Module) string {
1401 return b.bp.OtherModuleType(m)
1402}
Colin Cross1184b642019-12-30 18:43:07 -08001403
1404func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
1405 return b.bp.GetDirectDepWithTag(name, tag)
1406}
1407
Colin Cross25de6c32019-06-06 14:29:25 -07001408type moduleContext struct {
Colin Crossdc35e212019-06-06 16:13:11 -07001409 bp blueprint.ModuleContext
Colin Cross0ea8ba82019-06-06 14:33:29 -07001410 baseModuleContext
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001411 installDeps Paths
1412 installFiles Paths
1413 checkbuildFiles Paths
Colin Cross8d8f8e22016-08-03 11:57:50 -07001414 module Module
Colin Crosscec81712017-07-13 14:43:27 -07001415
1416 // For tests
Colin Crossae887032017-10-23 17:16:14 -07001417 buildParams []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -08001418 ruleParams map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001419 variables map[string]string
Colin Cross6ff51382015-12-17 16:39:19 -08001420}
1421
Colin Crossb88b3c52019-06-10 15:15:17 -07001422func (m *moduleContext) ninjaError(params BuildParams, err error) (PackageContext, BuildParams) {
1423 return pctx, BuildParams{
Colin Cross4b69c492019-06-07 13:06:06 -07001424 Rule: ErrorRule,
1425 Description: params.Description,
1426 Output: params.Output,
1427 Outputs: params.Outputs,
1428 ImplicitOutput: params.ImplicitOutput,
1429 ImplicitOutputs: params.ImplicitOutputs,
Colin Cross6ff51382015-12-17 16:39:19 -08001430 Args: map[string]string{
1431 "error": err.Error(),
1432 },
Colin Crossb88b3c52019-06-10 15:15:17 -07001433 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001434}
1435
Colin Cross25de6c32019-06-06 14:29:25 -07001436func (m *moduleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
1437 m.Build(pctx, BuildParams(params))
Colin Cross3f40fa42015-01-30 17:27:36 -08001438}
1439
Colin Cross0875c522017-11-28 17:34:01 -08001440func convertBuildParams(params BuildParams) blueprint.BuildParams {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001441 bparams := blueprint.BuildParams{
Dan Willemsen9f3c5742016-11-03 14:28:31 -07001442 Rule: params.Rule,
Colin Cross0875c522017-11-28 17:34:01 -08001443 Description: params.Description,
Colin Cross33bfb0a2016-11-21 17:23:08 -08001444 Deps: params.Deps,
Dan Willemsen9f3c5742016-11-03 14:28:31 -07001445 Outputs: params.Outputs.Strings(),
1446 ImplicitOutputs: params.ImplicitOutputs.Strings(),
1447 Inputs: params.Inputs.Strings(),
1448 Implicits: params.Implicits.Strings(),
1449 OrderOnly: params.OrderOnly.Strings(),
1450 Args: params.Args,
1451 Optional: !params.Default,
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001452 }
1453
Colin Cross33bfb0a2016-11-21 17:23:08 -08001454 if params.Depfile != nil {
1455 bparams.Depfile = params.Depfile.String()
1456 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001457 if params.Output != nil {
1458 bparams.Outputs = append(bparams.Outputs, params.Output.String())
1459 }
Dan Willemsen9f3c5742016-11-03 14:28:31 -07001460 if params.ImplicitOutput != nil {
1461 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
1462 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001463 if params.Input != nil {
1464 bparams.Inputs = append(bparams.Inputs, params.Input.String())
1465 }
1466 if params.Implicit != nil {
1467 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
1468 }
1469
Colin Cross0b9f31f2019-02-28 11:00:01 -08001470 bparams.Outputs = proptools.NinjaEscapeList(bparams.Outputs)
1471 bparams.ImplicitOutputs = proptools.NinjaEscapeList(bparams.ImplicitOutputs)
1472 bparams.Inputs = proptools.NinjaEscapeList(bparams.Inputs)
1473 bparams.Implicits = proptools.NinjaEscapeList(bparams.Implicits)
1474 bparams.OrderOnly = proptools.NinjaEscapeList(bparams.OrderOnly)
1475 bparams.Depfile = proptools.NinjaEscapeList([]string{bparams.Depfile})[0]
Colin Crossfe4bc362018-09-12 10:02:13 -07001476
Colin Cross0875c522017-11-28 17:34:01 -08001477 return bparams
1478}
1479
Colin Cross25de6c32019-06-06 14:29:25 -07001480func (m *moduleContext) Variable(pctx PackageContext, name, value string) {
1481 if m.config.captureBuild {
1482 m.variables[name] = value
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001483 }
1484
Colin Crossdc35e212019-06-06 16:13:11 -07001485 m.bp.Variable(pctx.PackageContext, name, value)
Colin Cross0875c522017-11-28 17:34:01 -08001486}
1487
Colin Cross25de6c32019-06-06 14:29:25 -07001488func (m *moduleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
Colin Cross0875c522017-11-28 17:34:01 -08001489 argNames ...string) blueprint.Rule {
1490
Ramy Medhat79c4fcc2020-03-31 22:14:52 -04001491 if m.config.UseRemoteBuild() {
1492 if params.Pool == nil {
1493 // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict
1494 // jobs to the local parallelism value
1495 params.Pool = localPool
1496 } else if params.Pool == remotePool {
1497 // remotePool is a fake pool used to identify rule that are supported for remoting. If the rule's
1498 // pool is the remotePool, replace with nil so that ninja runs it at NINJA_REMOTE_NUM_JOBS
1499 // parallelism.
1500 params.Pool = nil
1501 }
Colin Cross2e2dbc22019-09-25 13:31:46 -07001502 }
1503
Colin Crossdc35e212019-06-06 16:13:11 -07001504 rule := m.bp.Rule(pctx.PackageContext, name, params, argNames...)
Colin Cross4c83e5c2019-02-25 14:54:28 -08001505
Colin Cross25de6c32019-06-06 14:29:25 -07001506 if m.config.captureBuild {
1507 m.ruleParams[rule] = params
Colin Cross4c83e5c2019-02-25 14:54:28 -08001508 }
1509
1510 return rule
Colin Cross0875c522017-11-28 17:34:01 -08001511}
1512
Colin Cross25de6c32019-06-06 14:29:25 -07001513func (m *moduleContext) Build(pctx PackageContext, params BuildParams) {
Colin Crossb88b3c52019-06-10 15:15:17 -07001514 if params.Description != "" {
1515 params.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
1516 }
1517
1518 if missingDeps := m.GetMissingDependencies(); len(missingDeps) > 0 {
1519 pctx, params = m.ninjaError(params, fmt.Errorf("module %s missing dependencies: %s\n",
1520 m.ModuleName(), strings.Join(missingDeps, ", ")))
1521 }
1522
Colin Cross25de6c32019-06-06 14:29:25 -07001523 if m.config.captureBuild {
1524 m.buildParams = append(m.buildParams, params)
Colin Cross0875c522017-11-28 17:34:01 -08001525 }
1526
Colin Crossdc35e212019-06-06 16:13:11 -07001527 m.bp.Build(pctx.PackageContext, convertBuildParams(params))
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001528}
Colin Cross25de6c32019-06-06 14:29:25 -07001529func (m *moduleContext) GetMissingDependencies() []string {
Colin Cross6c4f21f2019-06-06 15:41:36 -07001530 var missingDeps []string
1531 missingDeps = append(missingDeps, m.Module().base().commonProperties.MissingDeps...)
Colin Crossdc35e212019-06-06 16:13:11 -07001532 missingDeps = append(missingDeps, m.bp.GetMissingDependencies()...)
Colin Cross6c4f21f2019-06-06 15:41:36 -07001533 missingDeps = FirstUniqueStrings(missingDeps)
1534 return missingDeps
Colin Cross6ff51382015-12-17 16:39:19 -08001535}
1536
Colin Crossdc35e212019-06-06 16:13:11 -07001537func (b *baseModuleContext) AddMissingDependencies(deps []string) {
Dan Willemsen6553f5e2016-03-10 18:14:25 -08001538 if deps != nil {
Colin Crossdc35e212019-06-06 16:13:11 -07001539 missingDeps := &b.Module().base().commonProperties.MissingDeps
Colin Cross6c4f21f2019-06-06 15:41:36 -07001540 *missingDeps = append(*missingDeps, deps...)
1541 *missingDeps = FirstUniqueStrings(*missingDeps)
Dan Willemsen6553f5e2016-03-10 18:14:25 -08001542 }
1543}
1544
Colin Crossdc35e212019-06-06 16:13:11 -07001545func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, strict bool) Module {
Colin Crossd11fcda2017-10-23 17:59:01 -07001546 aModule, _ := module.(Module)
Colin Crossdc35e212019-06-06 16:13:11 -07001547
1548 if !strict {
1549 return aModule
1550 }
1551
Colin Cross380c69a2019-06-10 17:49:58 +00001552 if aModule == nil {
Colin Crossdc35e212019-06-06 16:13:11 -07001553 b.ModuleErrorf("module %q not an android module", b.OtherModuleName(module))
Colin Cross380c69a2019-06-10 17:49:58 +00001554 return nil
1555 }
1556
1557 if !aModule.Enabled() {
Colin Crossdc35e212019-06-06 16:13:11 -07001558 if b.Config().AllowMissingDependencies() {
1559 b.AddMissingDependencies([]string{b.OtherModuleName(aModule)})
Colin Cross380c69a2019-06-10 17:49:58 +00001560 } else {
Colin Crossdc35e212019-06-06 16:13:11 -07001561 b.ModuleErrorf("depends on disabled module %q", b.OtherModuleName(aModule))
Colin Cross380c69a2019-06-10 17:49:58 +00001562 }
1563 return nil
1564 }
Colin Crossd11fcda2017-10-23 17:59:01 -07001565 return aModule
1566}
1567
Colin Crossdc35e212019-06-06 16:13:11 -07001568func (b *baseModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) {
Jiyong Parkf2976302019-04-17 21:47:37 +09001569 type dep struct {
1570 mod blueprint.Module
1571 tag blueprint.DependencyTag
1572 }
1573 var deps []dep
Colin Crossdc35e212019-06-06 16:13:11 -07001574 b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
Colin Cross25de6c32019-06-06 14:29:25 -07001575 if aModule, _ := module.(Module); aModule != nil && aModule.base().BaseModuleName() == name {
Colin Cross1184b642019-12-30 18:43:07 -08001576 returnedTag := b.bp.OtherModuleDependencyTag(aModule)
Jiyong Parkf2976302019-04-17 21:47:37 +09001577 if tag == nil || returnedTag == tag {
1578 deps = append(deps, dep{aModule, returnedTag})
1579 }
1580 }
1581 })
1582 if len(deps) == 1 {
1583 return deps[0].mod, deps[0].tag
1584 } else if len(deps) >= 2 {
1585 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
Colin Crossdc35e212019-06-06 16:13:11 -07001586 name, b.ModuleName()))
Jiyong Parkf2976302019-04-17 21:47:37 +09001587 } else {
1588 return nil, nil
1589 }
1590}
1591
Colin Crossdc35e212019-06-06 16:13:11 -07001592func (b *baseModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module {
Colin Cross0ef08162019-05-01 15:50:51 -07001593 var deps []Module
Colin Crossdc35e212019-06-06 16:13:11 -07001594 b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
Colin Cross25de6c32019-06-06 14:29:25 -07001595 if aModule, _ := module.(Module); aModule != nil {
Colin Cross1184b642019-12-30 18:43:07 -08001596 if b.bp.OtherModuleDependencyTag(aModule) == tag {
Colin Cross0ef08162019-05-01 15:50:51 -07001597 deps = append(deps, aModule)
1598 }
1599 }
1600 })
1601 return deps
1602}
1603
Colin Cross25de6c32019-06-06 14:29:25 -07001604func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
1605 module, _ := m.getDirectDepInternal(name, tag)
1606 return module
Jiyong Parkf2976302019-04-17 21:47:37 +09001607}
1608
Colin Crossdc35e212019-06-06 16:13:11 -07001609func (b *baseModuleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) {
1610 return b.getDirectDepInternal(name, nil)
Jiyong Parkf2976302019-04-17 21:47:37 +09001611}
1612
Colin Crossdc35e212019-06-06 16:13:11 -07001613func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
Colin Cross1184b642019-12-30 18:43:07 -08001614 b.bp.VisitDirectDeps(visit)
Colin Cross35143d02017-11-16 00:11:20 -08001615}
1616
Colin Crossdc35e212019-06-06 16:13:11 -07001617func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) {
Colin Cross1184b642019-12-30 18:43:07 -08001618 b.bp.VisitDirectDeps(func(module blueprint.Module) {
Colin Crossdc35e212019-06-06 16:13:11 -07001619 if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil {
Colin Crossd11fcda2017-10-23 17:59:01 -07001620 visit(aModule)
1621 }
1622 })
1623}
1624
Colin Crossdc35e212019-06-06 16:13:11 -07001625func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
Colin Cross1184b642019-12-30 18:43:07 -08001626 b.bp.VisitDirectDeps(func(module blueprint.Module) {
Colin Crossdc35e212019-06-06 16:13:11 -07001627 if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil {
Colin Cross1184b642019-12-30 18:43:07 -08001628 if b.bp.OtherModuleDependencyTag(aModule) == tag {
Colin Crossee6143c2017-12-30 17:54:27 -08001629 visit(aModule)
1630 }
1631 }
1632 })
1633}
1634
Colin Crossdc35e212019-06-06 16:13:11 -07001635func (b *baseModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
Colin Cross1184b642019-12-30 18:43:07 -08001636 b.bp.VisitDirectDepsIf(
Colin Crossd11fcda2017-10-23 17:59:01 -07001637 // pred
1638 func(module blueprint.Module) bool {
Colin Crossdc35e212019-06-06 16:13:11 -07001639 if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil {
Colin Crossd11fcda2017-10-23 17:59:01 -07001640 return pred(aModule)
1641 } else {
1642 return false
1643 }
1644 },
1645 // visit
1646 func(module blueprint.Module) {
1647 visit(module.(Module))
1648 })
1649}
1650
Colin Crossdc35e212019-06-06 16:13:11 -07001651func (b *baseModuleContext) VisitDepsDepthFirst(visit func(Module)) {
Colin Cross1184b642019-12-30 18:43:07 -08001652 b.bp.VisitDepsDepthFirst(func(module blueprint.Module) {
Colin Crossdc35e212019-06-06 16:13:11 -07001653 if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil {
Colin Crossd11fcda2017-10-23 17:59:01 -07001654 visit(aModule)
1655 }
1656 })
1657}
1658
Colin Crossdc35e212019-06-06 16:13:11 -07001659func (b *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
Colin Cross1184b642019-12-30 18:43:07 -08001660 b.bp.VisitDepsDepthFirstIf(
Colin Crossd11fcda2017-10-23 17:59:01 -07001661 // pred
1662 func(module blueprint.Module) bool {
Colin Crossdc35e212019-06-06 16:13:11 -07001663 if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil {
Colin Crossd11fcda2017-10-23 17:59:01 -07001664 return pred(aModule)
1665 } else {
1666 return false
1667 }
1668 },
1669 // visit
1670 func(module blueprint.Module) {
1671 visit(module.(Module))
1672 })
1673}
1674
Colin Crossdc35e212019-06-06 16:13:11 -07001675func (b *baseModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) {
Colin Cross1184b642019-12-30 18:43:07 -08001676 b.bp.WalkDeps(visit)
Alex Light778127a2019-02-27 14:19:50 -08001677}
1678
Colin Crossdc35e212019-06-06 16:13:11 -07001679func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) {
1680 b.walkPath = []Module{b.Module()}
Paul Duffinf0207962020-03-31 11:31:36 +01001681 b.tagPath = []blueprint.DependencyTag{}
Colin Cross1184b642019-12-30 18:43:07 -08001682 b.bp.WalkDeps(func(child, parent blueprint.Module) bool {
Colin Crossdc35e212019-06-06 16:13:11 -07001683 childAndroidModule, _ := child.(Module)
1684 parentAndroidModule, _ := parent.(Module)
Colin Crossd11fcda2017-10-23 17:59:01 -07001685 if childAndroidModule != nil && parentAndroidModule != nil {
Colin Crossdc35e212019-06-06 16:13:11 -07001686 // record walkPath before visit
1687 for b.walkPath[len(b.walkPath)-1] != parentAndroidModule {
1688 b.walkPath = b.walkPath[0 : len(b.walkPath)-1]
Paul Duffinf0207962020-03-31 11:31:36 +01001689 b.tagPath = b.tagPath[0 : len(b.tagPath)-1]
Colin Crossdc35e212019-06-06 16:13:11 -07001690 }
1691 b.walkPath = append(b.walkPath, childAndroidModule)
Paul Duffinf0207962020-03-31 11:31:36 +01001692 b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule))
Colin Crossd11fcda2017-10-23 17:59:01 -07001693 return visit(childAndroidModule, parentAndroidModule)
1694 } else {
1695 return false
1696 }
1697 })
1698}
1699
Colin Crossdc35e212019-06-06 16:13:11 -07001700func (b *baseModuleContext) GetWalkPath() []Module {
1701 return b.walkPath
1702}
1703
Paul Duffinf0207962020-03-31 11:31:36 +01001704func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag {
1705 return b.tagPath
1706}
1707
Colin Cross25de6c32019-06-06 14:29:25 -07001708func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) {
Colin Crossdc35e212019-06-06 16:13:11 -07001709 m.bp.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Cross0875c522017-11-28 17:34:01 -08001710 visit(module.(Module))
1711 })
1712}
1713
Colin Cross25de6c32019-06-06 14:29:25 -07001714func (m *moduleContext) PrimaryModule() Module {
Colin Crossdc35e212019-06-06 16:13:11 -07001715 return m.bp.PrimaryModule().(Module)
Colin Cross0875c522017-11-28 17:34:01 -08001716}
1717
Colin Cross25de6c32019-06-06 14:29:25 -07001718func (m *moduleContext) FinalModule() Module {
Colin Crossdc35e212019-06-06 16:13:11 -07001719 return m.bp.FinalModule().(Module)
1720}
1721
1722func (m *moduleContext) ModuleSubDir() string {
1723 return m.bp.ModuleSubDir()
Colin Cross0875c522017-11-28 17:34:01 -08001724}
1725
Colin Cross0ea8ba82019-06-06 14:33:29 -07001726func (b *baseModuleContext) Target() Target {
Colin Cross25de6c32019-06-06 14:29:25 -07001727 return b.target
Colin Crossa1ad8d12016-06-01 17:09:44 -07001728}
1729
Colin Cross0ea8ba82019-06-06 14:33:29 -07001730func (b *baseModuleContext) TargetPrimary() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001731 return b.targetPrimary
Colin Cross8b74d172016-09-13 09:59:14 -07001732}
1733
Colin Cross0ea8ba82019-06-06 14:33:29 -07001734func (b *baseModuleContext) MultiTargets() []Target {
Colin Cross25de6c32019-06-06 14:29:25 -07001735 return b.multiTargets
Colin Crossee0bc3b2018-10-02 22:01:37 -07001736}
1737
Colin Cross0ea8ba82019-06-06 14:33:29 -07001738func (b *baseModuleContext) Arch() Arch {
Colin Cross25de6c32019-06-06 14:29:25 -07001739 return b.target.Arch
Colin Cross3f40fa42015-01-30 17:27:36 -08001740}
1741
Colin Cross0ea8ba82019-06-06 14:33:29 -07001742func (b *baseModuleContext) Os() OsType {
Colin Crossfb0c16e2019-11-20 17:12:35 -08001743 return b.os
Dan Willemsen490fd492015-11-24 17:53:15 -08001744}
1745
Colin Cross0ea8ba82019-06-06 14:33:29 -07001746func (b *baseModuleContext) Host() bool {
Colin Crossfb0c16e2019-11-20 17:12:35 -08001747 return b.os.Class == Host || b.os.Class == HostCross
Colin Crossf6566ed2015-03-24 11:13:38 -07001748}
1749
Colin Cross0ea8ba82019-06-06 14:33:29 -07001750func (b *baseModuleContext) Device() bool {
Colin Crossfb0c16e2019-11-20 17:12:35 -08001751 return b.os.Class == Device
Colin Crossf6566ed2015-03-24 11:13:38 -07001752}
1753
Colin Cross0ea8ba82019-06-06 14:33:29 -07001754func (b *baseModuleContext) Darwin() bool {
Colin Crossfb0c16e2019-11-20 17:12:35 -08001755 return b.os == Darwin
Colin Cross0af4b842015-04-30 16:36:18 -07001756}
1757
Colin Cross0ea8ba82019-06-06 14:33:29 -07001758func (b *baseModuleContext) Fuchsia() bool {
Colin Crossfb0c16e2019-11-20 17:12:35 -08001759 return b.os == Fuchsia
Doug Horn21b94272019-01-16 12:06:11 -08001760}
1761
Colin Cross0ea8ba82019-06-06 14:33:29 -07001762func (b *baseModuleContext) Windows() bool {
Colin Crossfb0c16e2019-11-20 17:12:35 -08001763 return b.os == Windows
Colin Cross3edeee12017-04-04 12:59:48 -07001764}
1765
Colin Cross0ea8ba82019-06-06 14:33:29 -07001766func (b *baseModuleContext) Debug() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001767 return b.debug
Colin Crossf6566ed2015-03-24 11:13:38 -07001768}
1769
Colin Cross0ea8ba82019-06-06 14:33:29 -07001770func (b *baseModuleContext) PrimaryArch() bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001771 if len(b.config.Targets[b.target.Os]) <= 1 {
Colin Cross67a5c132017-05-09 13:45:28 -07001772 return true
1773 }
Colin Cross25de6c32019-06-06 14:29:25 -07001774 return b.target.Arch.ArchType == b.config.Targets[b.target.Os][0].Arch.ArchType
Colin Cross1e7d3702016-08-24 15:25:47 -07001775}
1776
Jiyong Park5baac542018-08-28 09:55:37 +09001777// Makes this module a platform module, i.e. not specific to soc, device,
Justin Yund5f6c822019-06-25 16:47:17 +09001778// product, or system_ext.
Colin Cross4157e882019-06-06 16:57:04 -07001779func (m *ModuleBase) MakeAsPlatform() {
1780 m.commonProperties.Vendor = boolPtr(false)
1781 m.commonProperties.Proprietary = boolPtr(false)
1782 m.commonProperties.Soc_specific = boolPtr(false)
1783 m.commonProperties.Product_specific = boolPtr(false)
Justin Yund5f6c822019-06-25 16:47:17 +09001784 m.commonProperties.System_ext_specific = boolPtr(false)
Jiyong Park5baac542018-08-28 09:55:37 +09001785}
1786
Colin Cross4157e882019-06-06 16:57:04 -07001787func (m *ModuleBase) EnableNativeBridgeSupportByDefault() {
1788 m.commonProperties.Native_bridge_supported = boolPtr(true)
dimitry03dc3f62019-05-09 14:07:34 +02001789}
1790
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09001791func (m *ModuleBase) MakeAsSystemExt() {
Jooyung Han91df2082019-11-20 01:49:42 +09001792 m.commonProperties.Vendor = boolPtr(false)
1793 m.commonProperties.Proprietary = boolPtr(false)
1794 m.commonProperties.Soc_specific = boolPtr(false)
1795 m.commonProperties.Product_specific = boolPtr(false)
1796 m.commonProperties.System_ext_specific = boolPtr(true)
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09001797}
1798
Jooyung Han344d5432019-08-23 11:17:39 +09001799// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true"
1800func (m *ModuleBase) IsNativeBridgeSupported() bool {
1801 return proptools.Bool(m.commonProperties.Native_bridge_supported)
1802}
1803
Colin Cross25de6c32019-06-06 14:29:25 -07001804func (m *moduleContext) InstallInData() bool {
1805 return m.module.InstallInData()
Dan Willemsen782a2d12015-12-21 14:55:28 -08001806}
1807
Jaewoong Jung0949f312019-09-11 10:25:18 -07001808func (m *moduleContext) InstallInTestcases() bool {
1809 return m.module.InstallInTestcases()
1810}
1811
Colin Cross25de6c32019-06-06 14:29:25 -07001812func (m *moduleContext) InstallInSanitizerDir() bool {
1813 return m.module.InstallInSanitizerDir()
Vishwath Mohan1dd88392017-03-29 22:00:18 -07001814}
1815
Yifan Hong1b3348d2020-01-21 15:53:22 -08001816func (m *moduleContext) InstallInRamdisk() bool {
1817 return m.module.InstallInRamdisk()
1818}
1819
Colin Cross25de6c32019-06-06 14:29:25 -07001820func (m *moduleContext) InstallInRecovery() bool {
1821 return m.module.InstallInRecovery()
Jiyong Parkf9332f12018-02-01 00:54:12 +09001822}
1823
Colin Cross90ba5f42019-10-02 11:10:58 -07001824func (m *moduleContext) InstallInRoot() bool {
1825 return m.module.InstallInRoot()
1826}
1827
Colin Cross607d8582019-07-29 16:44:46 -07001828func (m *moduleContext) InstallBypassMake() bool {
1829 return m.module.InstallBypassMake()
1830}
1831
Colin Cross70dda7e2019-10-01 22:05:35 -07001832func (m *moduleContext) skipInstall(fullInstallPath InstallPath) bool {
Colin Cross25de6c32019-06-06 14:29:25 -07001833 if m.module.base().commonProperties.SkipInstall {
Colin Cross893d8162017-04-26 17:34:03 -07001834 return true
1835 }
1836
Colin Cross3607f212018-05-07 15:28:05 -07001837 // We'll need a solution for choosing which of modules with the same name in different
1838 // namespaces to install. For now, reuse the list of namespaces exported to Make as the
1839 // list of namespaces to install in a Soong-only build.
Colin Cross25de6c32019-06-06 14:29:25 -07001840 if !m.module.base().commonProperties.NamespaceExportedToMake {
Colin Cross3607f212018-05-07 15:28:05 -07001841 return true
1842 }
1843
Colin Cross25de6c32019-06-06 14:29:25 -07001844 if m.Device() {
Colin Cross607d8582019-07-29 16:44:46 -07001845 if m.Config().EmbeddedInMake() && !m.InstallBypassMake() {
Colin Cross893d8162017-04-26 17:34:03 -07001846 return true
1847 }
1848
Colin Cross25de6c32019-06-06 14:29:25 -07001849 if m.Config().SkipMegaDeviceInstall(fullInstallPath.String()) {
Colin Cross893d8162017-04-26 17:34:03 -07001850 return true
1851 }
1852 }
1853
1854 return false
1855}
1856
Colin Cross70dda7e2019-10-01 22:05:35 -07001857func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path,
1858 deps ...Path) InstallPath {
Colin Cross25de6c32019-06-06 14:29:25 -07001859 return m.installFile(installPath, name, srcPath, Cp, deps)
Colin Cross5c517922017-08-31 12:29:17 -07001860}
1861
Colin Cross70dda7e2019-10-01 22:05:35 -07001862func (m *moduleContext) InstallExecutable(installPath InstallPath, name string, srcPath Path,
1863 deps ...Path) InstallPath {
Colin Cross25de6c32019-06-06 14:29:25 -07001864 return m.installFile(installPath, name, srcPath, CpExecutable, deps)
Colin Cross5c517922017-08-31 12:29:17 -07001865}
1866
Colin Cross70dda7e2019-10-01 22:05:35 -07001867func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path,
1868 rule blueprint.Rule, deps []Path) InstallPath {
Colin Cross35cec122015-04-02 14:37:16 -07001869
Colin Cross25de6c32019-06-06 14:29:25 -07001870 fullInstallPath := installPath.Join(m, name)
1871 m.module.base().hooks.runInstallHooks(m, fullInstallPath, false)
Colin Cross3f40fa42015-01-30 17:27:36 -08001872
Colin Cross25de6c32019-06-06 14:29:25 -07001873 if !m.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001874
Colin Cross25de6c32019-06-06 14:29:25 -07001875 deps = append(deps, m.installDeps...)
Colin Cross35cec122015-04-02 14:37:16 -07001876
Colin Cross89562dc2016-10-03 17:47:19 -07001877 var implicitDeps, orderOnlyDeps Paths
1878
Colin Cross25de6c32019-06-06 14:29:25 -07001879 if m.Host() {
Colin Cross89562dc2016-10-03 17:47:19 -07001880 // Installed host modules might be used during the build, depend directly on their
1881 // dependencies so their timestamp is updated whenever their dependency is updated
1882 implicitDeps = deps
1883 } else {
1884 orderOnlyDeps = deps
1885 }
1886
Colin Cross25de6c32019-06-06 14:29:25 -07001887 m.Build(pctx, BuildParams{
Colin Cross5c517922017-08-31 12:29:17 -07001888 Rule: rule,
Colin Cross67a5c132017-05-09 13:45:28 -07001889 Description: "install " + fullInstallPath.Base(),
1890 Output: fullInstallPath,
1891 Input: srcPath,
1892 Implicits: implicitDeps,
1893 OrderOnly: orderOnlyDeps,
Colin Cross25de6c32019-06-06 14:29:25 -07001894 Default: !m.Config().EmbeddedInMake(),
Dan Willemsen322acaf2016-01-12 23:07:05 -08001895 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001896
Colin Cross25de6c32019-06-06 14:29:25 -07001897 m.installFiles = append(m.installFiles, fullInstallPath)
Dan Willemsen322acaf2016-01-12 23:07:05 -08001898 }
Colin Cross25de6c32019-06-06 14:29:25 -07001899 m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -07001900 return fullInstallPath
1901}
1902
Colin Cross70dda7e2019-10-01 22:05:35 -07001903func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath {
Colin Cross25de6c32019-06-06 14:29:25 -07001904 fullInstallPath := installPath.Join(m, name)
1905 m.module.base().hooks.runInstallHooks(m, fullInstallPath, true)
Colin Cross3854a602016-01-11 12:49:11 -08001906
Colin Cross25de6c32019-06-06 14:29:25 -07001907 if !m.skipInstall(fullInstallPath) {
Colin Crossce75d2c2016-10-06 16:12:58 -07001908
Alex Lightfb4353d2019-01-17 13:57:45 -08001909 relPath, err := filepath.Rel(path.Dir(fullInstallPath.String()), srcPath.String())
1910 if err != nil {
1911 panic(fmt.Sprintf("Unable to generate symlink between %q and %q: %s", fullInstallPath.Base(), srcPath.Base(), err))
1912 }
Colin Cross25de6c32019-06-06 14:29:25 -07001913 m.Build(pctx, BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -07001914 Rule: Symlink,
1915 Description: "install symlink " + fullInstallPath.Base(),
1916 Output: fullInstallPath,
Dan Willemsen40efa1c2020-01-14 15:19:52 -08001917 Input: srcPath,
Colin Cross25de6c32019-06-06 14:29:25 -07001918 Default: !m.Config().EmbeddedInMake(),
Colin Cross12fc4972016-01-11 12:49:11 -08001919 Args: map[string]string{
Alex Lightfb4353d2019-01-17 13:57:45 -08001920 "fromPath": relPath,
Colin Cross12fc4972016-01-11 12:49:11 -08001921 },
1922 })
Colin Cross3854a602016-01-11 12:49:11 -08001923
Colin Cross25de6c32019-06-06 14:29:25 -07001924 m.installFiles = append(m.installFiles, fullInstallPath)
1925 m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
Colin Cross12fc4972016-01-11 12:49:11 -08001926 }
Colin Cross3854a602016-01-11 12:49:11 -08001927 return fullInstallPath
1928}
1929
Jiyong Parkf1194352019-02-25 11:05:47 +09001930// installPath/name -> absPath where absPath might be a path that is available only at runtime
1931// (e.g. /apex/...)
Colin Cross70dda7e2019-10-01 22:05:35 -07001932func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath {
Colin Cross25de6c32019-06-06 14:29:25 -07001933 fullInstallPath := installPath.Join(m, name)
1934 m.module.base().hooks.runInstallHooks(m, fullInstallPath, true)
Jiyong Parkf1194352019-02-25 11:05:47 +09001935
Colin Cross25de6c32019-06-06 14:29:25 -07001936 if !m.skipInstall(fullInstallPath) {
1937 m.Build(pctx, BuildParams{
Jiyong Parkf1194352019-02-25 11:05:47 +09001938 Rule: Symlink,
1939 Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
1940 Output: fullInstallPath,
Colin Cross25de6c32019-06-06 14:29:25 -07001941 Default: !m.Config().EmbeddedInMake(),
Jiyong Parkf1194352019-02-25 11:05:47 +09001942 Args: map[string]string{
1943 "fromPath": absPath,
1944 },
1945 })
1946
Colin Cross25de6c32019-06-06 14:29:25 -07001947 m.installFiles = append(m.installFiles, fullInstallPath)
Jiyong Parkf1194352019-02-25 11:05:47 +09001948 }
1949 return fullInstallPath
1950}
1951
Colin Cross25de6c32019-06-06 14:29:25 -07001952func (m *moduleContext) CheckbuildFile(srcPath Path) {
1953 m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
Colin Cross3f40fa42015-01-30 17:27:36 -08001954}
1955
Colin Cross3f40fa42015-01-30 17:27:36 -08001956type fileInstaller interface {
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001957 filesToInstall() Paths
Colin Cross3f40fa42015-01-30 17:27:36 -08001958}
1959
1960func isFileInstaller(m blueprint.Module) bool {
1961 _, ok := m.(fileInstaller)
1962 return ok
1963}
1964
1965func isAndroidModule(m blueprint.Module) bool {
Colin Cross635c3b02016-05-18 15:37:25 -07001966 _, ok := m.(Module)
Colin Cross3f40fa42015-01-30 17:27:36 -08001967 return ok
1968}
Colin Crossfce53272015-04-08 11:21:40 -07001969
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001970func findStringInSlice(str string, slice []string) int {
1971 for i, s := range slice {
1972 if s == str {
1973 return i
Colin Crossfce53272015-04-08 11:21:40 -07001974 }
1975 }
Dan Willemsen2ef08f42015-06-30 18:15:24 -07001976 return -1
1977}
1978
Colin Cross41955e82019-05-29 14:40:35 -07001979// SrcIsModule decodes module references in the format ":name" into the module name, or empty string if the input
1980// was not a module reference.
1981func SrcIsModule(s string) (module string) {
Colin Cross068e0fe2016-12-13 15:23:47 -08001982 if len(s) > 1 && s[0] == ':' {
1983 return s[1:]
1984 }
1985 return ""
1986}
1987
Colin Cross41955e82019-05-29 14:40:35 -07001988// SrcIsModule decodes module references in the format ":name{.tag}" into the module name and tag, ":name" into the
1989// module name and an empty string for the tag, or empty strings if the input was not a module reference.
1990func SrcIsModuleWithTag(s string) (module, tag string) {
1991 if len(s) > 1 && s[0] == ':' {
1992 module = s[1:]
1993 if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
1994 if module[len(module)-1] == '}' {
1995 tag = module[tagStart+1 : len(module)-1]
1996 module = module[:tagStart]
1997 return module, tag
1998 }
1999 }
2000 return module, ""
2001 }
2002 return "", ""
Colin Cross068e0fe2016-12-13 15:23:47 -08002003}
2004
Colin Cross41955e82019-05-29 14:40:35 -07002005type sourceOrOutputDependencyTag struct {
2006 blueprint.BaseDependencyTag
2007 tag string
2008}
2009
2010func sourceOrOutputDepTag(tag string) blueprint.DependencyTag {
2011 return sourceOrOutputDependencyTag{tag: tag}
2012}
2013
2014var SourceDepTag = sourceOrOutputDepTag("")
Colin Cross068e0fe2016-12-13 15:23:47 -08002015
Colin Cross366938f2017-12-11 16:29:02 -08002016// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
2017// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08002018//
2019// Deprecated: tag the property with `android:"path"` instead.
Colin Cross068e0fe2016-12-13 15:23:47 -08002020func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
Nan Zhang2439eb72017-04-10 11:27:50 -07002021 set := make(map[string]bool)
2022
Colin Cross068e0fe2016-12-13 15:23:47 -08002023 for _, s := range srcFiles {
Colin Cross41955e82019-05-29 14:40:35 -07002024 if m, t := SrcIsModuleWithTag(s); m != "" {
2025 if _, found := set[s]; found {
2026 ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
Nan Zhang2439eb72017-04-10 11:27:50 -07002027 } else {
Colin Cross41955e82019-05-29 14:40:35 -07002028 set[s] = true
2029 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
Nan Zhang2439eb72017-04-10 11:27:50 -07002030 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002031 }
2032 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002033}
2034
Colin Cross366938f2017-12-11 16:29:02 -08002035// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
2036// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08002037//
2038// Deprecated: tag the property with `android:"path"` instead.
Colin Cross366938f2017-12-11 16:29:02 -08002039func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
2040 if s != nil {
Colin Cross41955e82019-05-29 14:40:35 -07002041 if m, t := SrcIsModuleWithTag(*s); m != "" {
2042 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
Colin Cross366938f2017-12-11 16:29:02 -08002043 }
2044 }
2045}
2046
Colin Cross41955e82019-05-29 14:40:35 -07002047// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"`
2048// using the ":module" syntax and provides a list of paths to be used as if they were listed in the property.
Colin Cross068e0fe2016-12-13 15:23:47 -08002049type SourceFileProducer interface {
2050 Srcs() Paths
2051}
2052
Colin Cross41955e82019-05-29 14:40:35 -07002053// A module that implements OutputFileProducer can be referenced from any property that is tagged with `android:"path"`
Roland Levillain97c1f342019-11-22 14:20:54 +00002054// using the ":module" syntax or ":module{.tag}" syntax and provides a list of output files to be used as if they were
Colin Cross41955e82019-05-29 14:40:35 -07002055// listed in the property.
2056type OutputFileProducer interface {
2057 OutputFiles(tag string) (Paths, error)
2058}
2059
Colin Cross5e708052019-08-06 13:59:50 -07002060// OutputFilesForModule returns the paths from an OutputFileProducer with the given tag. On error, including if the
2061// module produced zero paths, it reports errors to the ctx and returns nil.
2062func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) Paths {
2063 paths, err := outputFilesForModule(ctx, module, tag)
2064 if err != nil {
2065 reportPathError(ctx, err)
2066 return nil
2067 }
2068 return paths
2069}
2070
2071// OutputFileForModule returns the path from an OutputFileProducer with the given tag. On error, including if the
2072// module produced zero or multiple paths, it reports errors to the ctx and returns nil.
2073func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) Path {
2074 paths, err := outputFilesForModule(ctx, module, tag)
2075 if err != nil {
2076 reportPathError(ctx, err)
2077 return nil
2078 }
2079 if len(paths) > 1 {
2080 reportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
2081 pathContextName(ctx, module))
2082 return nil
2083 }
2084 return paths[0]
2085}
2086
2087func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
2088 if outputFileProducer, ok := module.(OutputFileProducer); ok {
2089 paths, err := outputFileProducer.OutputFiles(tag)
2090 if err != nil {
2091 return nil, fmt.Errorf("failed to get output file from module %q: %s",
2092 pathContextName(ctx, module), err.Error())
2093 }
2094 if len(paths) == 0 {
2095 return nil, fmt.Errorf("failed to get output files from module %q", pathContextName(ctx, module))
2096 }
2097 return paths, nil
2098 } else {
2099 return nil, fmt.Errorf("module %q is not an OutputFileProducer", pathContextName(ctx, module))
2100 }
2101}
2102
Colin Crossfe17f6f2019-03-28 19:30:56 -07002103type HostToolProvider interface {
2104 HostToolPath() OptionalPath
2105}
2106
Colin Cross27b922f2019-03-04 22:35:41 -08002107// Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must
2108// be tagged with `android:"path" to support automatic source module dependency resolution.
Colin Cross8a497952019-03-05 22:25:09 -08002109//
2110// Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
Colin Cross25de6c32019-06-06 14:29:25 -07002111func (m *moduleContext) ExpandSources(srcFiles, excludes []string) Paths {
2112 return PathsForModuleSrcExcludes(m, srcFiles, excludes)
Colin Cross8f101b42015-06-17 15:09:06 -07002113}
2114
Colin Cross2fafa3e2019-03-05 12:39:51 -08002115// Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must
2116// be tagged with `android:"path" to support automatic source module dependency resolution.
Colin Cross8a497952019-03-05 22:25:09 -08002117//
2118// Deprecated: use PathForModuleSrc instead.
Colin Cross25de6c32019-06-06 14:29:25 -07002119func (m *moduleContext) ExpandSource(srcFile, prop string) Path {
2120 return PathForModuleSrc(m, srcFile)
Colin Cross2fafa3e2019-03-05 12:39:51 -08002121}
2122
2123// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
2124// the srcFile is non-nil. The property must be tagged with `android:"path" to support automatic source module
2125// dependency resolution.
Colin Cross25de6c32019-06-06 14:29:25 -07002126func (m *moduleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
Colin Cross2fafa3e2019-03-05 12:39:51 -08002127 if srcFile != nil {
Colin Cross25de6c32019-06-06 14:29:25 -07002128 return OptionalPathForPath(PathForModuleSrc(m, *srcFile))
Colin Cross2fafa3e2019-03-05 12:39:51 -08002129 }
2130 return OptionalPath{}
2131}
2132
Colin Cross25de6c32019-06-06 14:29:25 -07002133func (m *moduleContext) RequiredModuleNames() []string {
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09002134 return m.module.RequiredModuleNames()
Nan Zhang6d34b302017-02-04 17:47:46 -08002135}
2136
Colin Cross25de6c32019-06-06 14:29:25 -07002137func (m *moduleContext) HostRequiredModuleNames() []string {
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09002138 return m.module.HostRequiredModuleNames()
Sasha Smundakb6d23052019-04-01 18:37:36 -07002139}
2140
Colin Cross25de6c32019-06-06 14:29:25 -07002141func (m *moduleContext) TargetRequiredModuleNames() []string {
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09002142 return m.module.TargetRequiredModuleNames()
Sasha Smundakb6d23052019-04-01 18:37:36 -07002143}
2144
Colin Cross463a90e2015-06-17 14:20:06 -07002145func init() {
Colin Cross798bfce2016-10-12 14:28:16 -07002146 RegisterSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07002147}
2148
Colin Cross0875c522017-11-28 17:34:01 -08002149func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07002150 return &buildTargetSingleton{}
2151}
2152
Colin Cross87d8b562017-04-25 10:01:55 -07002153func parentDir(dir string) string {
2154 dir, _ = filepath.Split(dir)
2155 return filepath.Clean(dir)
2156}
2157
Colin Cross1f8c52b2015-06-16 16:38:17 -07002158type buildTargetSingleton struct{}
2159
Colin Cross0875c522017-11-28 17:34:01 -08002160func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
2161 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07002162
Colin Cross0875c522017-11-28 17:34:01 -08002163 mmTarget := func(dir string) WritablePath {
2164 return PathForPhony(ctx,
2165 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
Colin Cross87d8b562017-04-25 10:01:55 -07002166 }
2167
Colin Cross0875c522017-11-28 17:34:01 -08002168 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002169
Colin Cross0875c522017-11-28 17:34:01 -08002170 ctx.VisitAllModules(func(module Module) {
2171 blueprintDir := module.base().blueprintDir
2172 installTarget := module.base().installTarget
2173 checkbuildTarget := module.base().checkbuildTarget
Colin Cross1f8c52b2015-06-16 16:38:17 -07002174
Colin Cross0875c522017-11-28 17:34:01 -08002175 if checkbuildTarget != nil {
2176 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
2177 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
2178 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07002179
Colin Cross0875c522017-11-28 17:34:01 -08002180 if installTarget != nil {
2181 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002182 }
2183 })
2184
Dan Willemsen5ba07e82015-12-11 13:51:06 -08002185 suffix := ""
Colin Crossaabf6792017-11-29 00:27:14 -08002186 if ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08002187 suffix = "-soong"
2188 }
2189
Colin Cross1f8c52b2015-06-16 16:38:17 -07002190 // Create a top-level checkbuild target that depends on all modules
Colin Cross0875c522017-11-28 17:34:01 -08002191 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07002192 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08002193 Output: PathForPhony(ctx, "checkbuild"+suffix),
Colin Cross1f8c52b2015-06-16 16:38:17 -07002194 Implicits: checkbuildDeps,
Colin Cross1f8c52b2015-06-16 16:38:17 -07002195 })
2196
Dan Willemsend2e95fb2017-09-20 14:30:50 -07002197 // Make will generate the MODULES-IN-* targets
Colin Crossaabf6792017-11-29 00:27:14 -08002198 if ctx.Config().EmbeddedInMake() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07002199 return
2200 }
2201
Colin Cross87d8b562017-04-25 10:01:55 -07002202 // Ensure ancestor directories are in modulesInDir
Inseob Kim1a365c62019-06-08 15:47:51 +09002203 dirs := SortedStringKeys(modulesInDir)
Colin Cross87d8b562017-04-25 10:01:55 -07002204 for _, dir := range dirs {
2205 dir := parentDir(dir)
2206 for dir != "." && dir != "/" {
2207 if _, exists := modulesInDir[dir]; exists {
2208 break
2209 }
2210 modulesInDir[dir] = nil
2211 dir = parentDir(dir)
2212 }
2213 }
2214
2215 // Make directories build their direct subdirectories
Colin Cross87d8b562017-04-25 10:01:55 -07002216 for _, dir := range dirs {
2217 p := parentDir(dir)
2218 if p != "." && p != "/" {
2219 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
2220 }
2221 }
2222
Dan Willemsend2e95fb2017-09-20 14:30:50 -07002223 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
2224 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
2225 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07002226 for _, dir := range dirs {
Colin Cross0875c522017-11-28 17:34:01 -08002227 ctx.Build(pctx, BuildParams{
Colin Cross1f8c52b2015-06-16 16:38:17 -07002228 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08002229 Output: mmTarget(dir),
Colin Cross87d8b562017-04-25 10:01:55 -07002230 Implicits: modulesInDir[dir],
Dan Willemsen5ba07e82015-12-11 13:51:06 -08002231 // HACK: checkbuild should be an optional build, but force it
2232 // enabled for now in standalone builds
Colin Crossaabf6792017-11-29 00:27:14 -08002233 Default: !ctx.Config().EmbeddedInMake(),
Colin Cross1f8c52b2015-06-16 16:38:17 -07002234 })
2235 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07002236
2237 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
2238 osDeps := map[OsType]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08002239 ctx.VisitAllModules(func(module Module) {
2240 if module.Enabled() {
2241 os := module.Target().Os
2242 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07002243 }
2244 })
2245
Colin Cross0875c522017-11-28 17:34:01 -08002246 osClass := make(map[string]Paths)
Dan Willemsen61d88b82017-09-20 17:29:08 -07002247 for os, deps := range osDeps {
2248 var className string
2249
2250 switch os.Class {
2251 case Host:
2252 className = "host"
2253 case HostCross:
2254 className = "host-cross"
2255 case Device:
2256 className = "target"
2257 default:
2258 continue
2259 }
2260
Colin Cross0875c522017-11-28 17:34:01 -08002261 name := PathForPhony(ctx, className+"-"+os.Name)
Dan Willemsen61d88b82017-09-20 17:29:08 -07002262 osClass[className] = append(osClass[className], name)
2263
Colin Cross0875c522017-11-28 17:34:01 -08002264 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07002265 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08002266 Output: name,
2267 Implicits: deps,
Dan Willemsen61d88b82017-09-20 17:29:08 -07002268 })
2269 }
2270
2271 // Wrap those into host|host-cross|target phony rules
Inseob Kim1a365c62019-06-08 15:47:51 +09002272 for _, class := range SortedStringKeys(osClass) {
Colin Cross0875c522017-11-28 17:34:01 -08002273 ctx.Build(pctx, BuildParams{
Dan Willemsen61d88b82017-09-20 17:29:08 -07002274 Rule: blueprint.Phony,
Colin Cross0875c522017-11-28 17:34:01 -08002275 Output: PathForPhony(ctx, class),
Dan Willemsen61d88b82017-09-20 17:29:08 -07002276 Implicits: osClass[class],
Dan Willemsen61d88b82017-09-20 17:29:08 -07002277 })
2278 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07002279}
Colin Crossd779da42015-12-17 18:00:23 -08002280
Brandon Lee5d45c6f2018-08-15 15:35:38 -07002281// Collect information for opening IDE project files in java/jdeps.go.
2282type IDEInfo interface {
2283 IDEInfo(ideInfo *IdeInfo)
2284 BaseModuleName() string
2285}
2286
2287// Extract the base module name from the Import name.
2288// Often the Import name has a prefix "prebuilt_".
2289// Remove the prefix explicitly if needed
2290// until we find a better solution to get the Import name.
2291type IDECustomizedModuleName interface {
2292 IDECustomizedModuleName() string
2293}
2294
2295type IdeInfo struct {
2296 Deps []string `json:"dependencies,omitempty"`
2297 Srcs []string `json:"srcs,omitempty"`
2298 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
2299 Jarjar_rules []string `json:"jarjar_rules,omitempty"`
2300 Jars []string `json:"jars,omitempty"`
2301 Classes []string `json:"class,omitempty"`
2302 Installed_paths []string `json:"installed,omitempty"`
patricktu18c82ff2019-05-10 15:48:50 +08002303 SrcJars []string `json:"srcjars,omitempty"`
Brandon Lee5d45c6f2018-08-15 15:35:38 -07002304}