blob: 1538861d3d4d36bbd7e56445ba8a3ec8af21e9d8 [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 (
Cole Fausta8437c52025-02-25 14:45:43 -080018 "errors"
Colin Cross6ff51382015-12-17 16:39:19 -080019 "fmt"
Bob Badour4101c712022-02-09 11:54:35 -080020 "net/url"
Colin Cross3f40fa42015-01-30 17:27:36 -080021 "path/filepath"
Liz Kammer9525e712022-01-05 13:46:24 -050022 "reflect"
Colin Crossd6fd0132023-11-06 13:54:06 -080023 "slices"
Bob Badour4101c712022-02-09 11:54:35 -080024 "sort"
Cole Faust764aaca2025-03-18 11:24:39 -070025 "strconv"
Colin Cross6ff51382015-12-17 16:39:19 -080026 "strings"
Tahsin Loqman77dc7d02022-12-19 16:27:25 +000027
Colin Crossf6566ed2015-03-24 11:13:38 -070028 "github.com/google/blueprint"
Yu Liu3cadf7d2024-10-24 18:47:06 +000029 "github.com/google/blueprint/depset"
30 "github.com/google/blueprint/gobtools"
Colin Crossfe4bc362018-09-12 10:02:13 -070031 "github.com/google/blueprint/proptools"
Colin Cross3f40fa42015-01-30 17:27:36 -080032)
33
34var (
35 DeviceSharedLibrary = "shared_library"
36 DeviceStaticLibrary = "static_library"
Joe Onorato349ae8d2024-02-05 22:46:00 +000037 jarJarPrefixHandler func(ctx ModuleContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080038)
39
Colin Cross635c3b02016-05-18 15:37:25 -070040type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080041 blueprint.Module
42
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070043 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
44 // but GenerateAndroidBuildActions also has access to Android-specific information.
45 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -070046 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070047
Colin Crossb790b9c2025-03-19 14:12:09 -070048 // CleanupAfterBuildActions is called after ModuleBase.GenerateBuildActions is finished.
49 // If all interactions with this module are handled via providers instead of direct access
50 // to the module then it can free memory attached to the module.
51 // This is a temporary measure to reduce memory usage, eventually blueprint's reference
52 // to the Module should be dropped after GenerateAndroidBuildActions once all accesses
53 // can be done through providers.
54 CleanupAfterBuildActions()
55
Paul Duffin44f1d842020-06-26 20:17:02 +010056 // Add dependencies to the components of a module, i.e. modules that are created
57 // by the module and which are considered to be part of the creating module.
58 //
59 // This is called before prebuilts are renamed so as to allow a dependency to be
60 // added directly to a prebuilt child module instead of depending on a source module
61 // and relying on prebuilt processing to switch to the prebuilt module if preferred.
62 //
63 // A dependency on a prebuilt must include the "prebuilt_" prefix.
64 ComponentDepsMutator(ctx BottomUpMutatorContext)
65
Colin Cross1e676be2016-10-12 14:38:15 -070066 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080067
Colin Cross635c3b02016-05-18 15:37:25 -070068 base() *ModuleBase
Inseob Kimeec88e12020-01-22 11:11:29 +090069 Disable()
Cole Fauste8a87832024-09-11 11:35:46 -070070 Enabled(ctx ConfigurableEvaluatorContext) bool
Colin Crossa1ad8d12016-06-01 17:09:44 -070071 Target() Target
Paul Duffinc04fb9e2021-03-01 12:25:10 +000072 MultiTargets() []Target
Paul Duffinb42fa672021-09-09 16:37:49 +010073
74 // ImageVariation returns the image variation of this module.
75 //
76 // The returned structure has its Mutator field set to "image" and its Variation field set to the
77 // image variation, e.g. recovery, ramdisk, etc.. The Variation field is "" for host modules and
78 // device modules that have no image variation.
79 ImageVariation() blueprint.Variation
80
Anton Hansson1ee62c02020-06-30 11:51:53 +010081 Owner() string
Dan Willemsen782a2d12015-12-21 14:55:28 -080082 InstallInData() bool
Jaewoong Jung0949f312019-09-11 10:25:18 -070083 InstallInTestcases() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -070084 InstallInSanitizerDir() bool
Yifan Hong1b3348d2020-01-21 15:53:22 -080085 InstallInRamdisk() bool
Yifan Hong60e0cfb2020-10-21 15:17:56 -070086 InstallInVendorRamdisk() bool
Inseob Kim08758f02021-04-08 21:13:22 +090087 InstallInDebugRamdisk() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +090088 InstallInRecovery() bool
Colin Cross90ba5f42019-10-02 11:10:58 -070089 InstallInRoot() bool
Colin Crossea30d852023-11-29 16:00:16 -080090 InstallInOdm() bool
91 InstallInProduct() bool
Kiyoung Kimae11c232021-07-19 11:38:04 +090092 InstallInVendor() bool
Spandan Das950deca2024-10-01 18:35:23 +000093 InstallInSystemExt() bool
Spandan Das27ff7672024-11-06 19:23:57 +000094 InstallInSystemDlkm() bool
95 InstallInVendorDlkm() bool
96 InstallInOdmDlkm() bool
Jiyong Park87788b52020-09-01 12:37:45 +090097 InstallForceOS() (*OsType, *ArchType)
Jiyong Parkce243632023-02-17 18:22:25 +090098 PartitionTag(DeviceConfig) string
Colin Crossa9c8c9f2020-12-16 10:20:23 -080099 HideFromMake()
100 IsHideFromMake() bool
Spandan Das034af2c2024-10-30 21:45:09 +0000101 SkipInstall()
Martin Stjernholm9e7f45e2020-12-23 03:50:30 +0000102 IsSkipInstall() bool
Iván Budnik295da162023-03-10 16:11:26 +0000103 MakeUninstallable()
Liz Kammer5ca3a622020-08-05 15:40:41 -0700104 ReplacedByPrebuilt()
105 IsReplacedByPrebuilt() bool
Jiyong Park374510b2018-03-19 18:23:01 +0900106 ExportedToMake() bool
Justin Yun885a7de2021-06-29 20:34:53 +0900107 EffectiveLicenseFiles() Paths
Colin Cross36242852017-06-23 15:06:31 -0700108
109 AddProperties(props ...interface{})
110 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700111
Colin Crossae887032017-10-23 17:16:14 -0700112 BuildParamsForTests() []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800113 RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800114 VariablesForTests() map[string]string
Paul Duffine2453c72019-05-31 14:00:04 +0100115
Colin Cross9a362232019-07-01 15:32:45 -0700116 // String returns a string that includes the module name and variants for printing during debugging.
117 String() string
118
Paul Duffine2453c72019-05-31 14:00:04 +0100119 // Get the qualified module id for this module.
120 qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName
121
122 // Get information about the properties that can contain visibility rules.
123 visibilityProperties() []visibilityProperty
Paul Duffin63c6e182019-07-24 14:24:38 +0100124
Cole Fauste8a87832024-09-11 11:35:46 -0700125 RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string
Jiyong Park6a8cf5f2019-12-30 16:31:09 +0900126 HostRequiredModuleNames() []string
127 TargetRequiredModuleNames() []string
Cole Fauste8a87832024-09-11 11:35:46 -0700128 VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string
Kiyoung Kim23be5bb2024-11-27 00:50:30 +0000129 VintfFragments(ctx ConfigurableEvaluatorContext) []string
Colin Cross897266e2020-02-13 13:22:08 -0800130
Cole Fauste8a87832024-09-11 11:35:46 -0700131 ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator
Jihoon Kang0d545b82024-10-11 00:21:57 +0000132
133 // The usage of this method is experimental and should not be used outside of fsgen package.
134 // This will be removed once product packaging migration to Soong is complete.
135 DecodeMultilib(ctx ConfigContext) (string, string)
Spandan Dase1860e42024-10-24 22:29:50 +0000136
137 // WARNING: This should not be used outside build/soong/fsgen
138 // Overrides returns the list of modules which should not be installed if this module is installed.
139 Overrides() []string
Justin Yunbe6f81d2024-12-17 21:15:59 +0900140
141 // If this is true, the module must not read product-specific configurations.
142 UseGenericConfig() bool
Paul Duffine2453c72019-05-31 14:00:04 +0100143}
144
145// Qualified id for a module
146type qualifiedModuleName struct {
147 // The package (i.e. directory) in which the module is defined, without trailing /
148 pkg string
149
150 // The name of the module, empty string if package.
151 name string
152}
153
154func (q qualifiedModuleName) String() string {
155 if q.name == "" {
156 return "//" + q.pkg
157 }
158 return "//" + q.pkg + ":" + q.name
159}
160
Paul Duffine484f472019-06-20 16:38:08 +0100161func (q qualifiedModuleName) isRootPackage() bool {
162 return q.pkg == "" && q.name == ""
163}
164
Paul Duffine2453c72019-05-31 14:00:04 +0100165// Get the id for the package containing this module.
166func (q qualifiedModuleName) getContainingPackageId() qualifiedModuleName {
167 pkg := q.pkg
168 if q.name == "" {
Paul Duffine484f472019-06-20 16:38:08 +0100169 if pkg == "" {
170 panic(fmt.Errorf("Cannot get containing package id of root package"))
171 }
172
173 index := strings.LastIndex(pkg, "/")
174 if index == -1 {
175 pkg = ""
176 } else {
177 pkg = pkg[:index]
178 }
Paul Duffine2453c72019-05-31 14:00:04 +0100179 }
180 return newPackageId(pkg)
181}
182
183func newPackageId(pkg string) qualifiedModuleName {
184 // A qualified id for a package module has no name.
185 return qualifiedModuleName{pkg: pkg, name: ""}
Colin Cross3f40fa42015-01-30 17:27:36 -0800186}
187
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000188type Dist struct {
189 // Copy the output of this module to the $DIST_DIR when `dist` is specified on the
190 // command line and any of these targets are also on the command line, or otherwise
191 // built
192 Targets []string `android:"arch_variant"`
193
194 // The name of the output artifact. This defaults to the basename of the output of
195 // the module.
196 Dest *string `android:"arch_variant"`
197
198 // The directory within the dist directory to store the artifact. Defaults to the
199 // top level directory ("").
200 Dir *string `android:"arch_variant"`
201
202 // A suffix to add to the artifact file name (before any extension).
203 Suffix *string `android:"arch_variant"`
204
Trevor Radcliffe90727f42022-03-21 19:34:02 +0000205 // If true, then the artifact file will be appended with _<product name>. For
206 // example, if the product is coral and the module is an android_app module
207 // of name foo, then the artifact would be foo_coral.apk. If false, there is
208 // no change to the artifact file name.
209 Append_artifact_with_product *bool `android:"arch_variant"`
210
Bill Yang870dbdc2025-03-20 08:54:11 +0000211 // If true, then the artifact file will be prepended with <product name>-. For
212 // example, if the product is coral and the module is an android_app module
213 // of name foo, then the artifact would be coral-foo.apk. If false, there is
214 // no change to the artifact file name.
215 Prepend_artifact_with_product *bool `android:"arch_variant"`
216
Paul Duffin74f05592020-11-25 16:37:46 +0000217 // A string tag to select the OutputFiles associated with the tag.
218 //
219 // If no tag is specified then it will select the default dist paths provided
220 // by the module type. If a tag of "" is specified then it will return the
221 // default output files provided by the modules, i.e. the result of calling
222 // OutputFiles("").
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000223 Tag *string `android:"arch_variant"`
224}
225
Bob Badour4101c712022-02-09 11:54:35 -0800226// NamedPath associates a path with a name. e.g. a license text path with a package name
227type NamedPath struct {
228 Path Path
229 Name string
230}
231
232// String returns an escaped string representing the `NamedPath`.
233func (p NamedPath) String() string {
234 if len(p.Name) > 0 {
235 return p.Path.String() + ":" + url.QueryEscape(p.Name)
236 }
237 return p.Path.String()
238}
239
240// NamedPaths describes a list of paths each associated with a name.
241type NamedPaths []NamedPath
242
243// Strings returns a list of escaped strings representing each `NamedPath` in the list.
244func (l NamedPaths) Strings() []string {
245 result := make([]string, 0, len(l))
246 for _, p := range l {
247 result = append(result, p.String())
248 }
249 return result
250}
251
252// SortedUniqueNamedPaths modifies `l` in place to return the sorted unique subset.
253func SortedUniqueNamedPaths(l NamedPaths) NamedPaths {
254 if len(l) == 0 {
255 return l
256 }
257 sort.Slice(l, func(i, j int) bool {
258 return l[i].String() < l[j].String()
259 })
260 k := 0
261 for i := 1; i < len(l); i++ {
262 if l[i].String() == l[k].String() {
263 continue
264 }
265 k++
266 if k < i {
267 l[k] = l[i]
268 }
269 }
270 return l[:k+1]
271}
272
Colin Crossfc754582016-05-17 16:34:16 -0700273type nameProperties struct {
274 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800275 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700276}
277
Cole Faust2239ae62025-01-27 15:32:11 -0800278// Properties common to all modules inheriting from ModuleBase. These properties are automatically
279// inherited by sub-modules created with ctx.CreateModule()
Colin Cross08d6f8f2020-11-19 02:33:19 +0000280type commonProperties struct {
Dan Willemsen0effe062015-11-30 16:06:01 -0800281 // emit build rules for this module
Paul Duffin54d9bb72020-02-12 10:20:56 +0000282 //
283 // Disabling a module should only be done for those modules that cannot be built
284 // in the current environment. Modules that can build in the current environment
285 // but are not usually required (e.g. superceded by a prebuilt) should not be
286 // disabled as that will prevent them from being built by the checkbuild target
287 // and so prevent early detection of changes that have broken those modules.
Cole Fausta963b942024-04-11 17:43:00 -0700288 Enabled proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800289
Paul Duffin2e61fa62019-03-28 14:10:57 +0000290 // Controls the visibility of this module to other modules. Allowable values are one or more of
291 // these formats:
292 //
293 // ["//visibility:public"]: Anyone can use this module.
294 // ["//visibility:private"]: Only rules in the module's package (not its subpackages) can use
295 // this module.
Paul Duffin51084ff2020-05-05 19:19:22 +0100296 // ["//visibility:override"]: Discards any rules inherited from defaults or a creating module.
297 // Can only be used at the beginning of a list of visibility rules.
Paul Duffin2e61fa62019-03-28 14:10:57 +0000298 // ["//some/package:__pkg__", "//other/package:__pkg__"]: Only modules in some/package and
299 // other/package (defined in some/package/*.bp and other/package/*.bp) have access to
300 // this module. Note that sub-packages do not have access to the rule; for example,
301 // //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__
302 // is a special module and must be used verbatim. It represents all of the modules in the
303 // package.
304 // ["//project:__subpackages__", "//other:__subpackages__"]: Only modules in packages project
305 // or other or in one of their sub-packages have access to this module. For example,
306 // //project:rule, //project/library:lib or //other/testing/internal:munge are allowed
307 // to depend on this rule (but not //independent:evil)
308 // ["//project"]: This is shorthand for ["//project:__pkg__"]
309 // [":__subpackages__"]: This is shorthand for ["//project:__subpackages__"] where
310 // //project is the module's package. e.g. using [":__subpackages__"] in
311 // packages/apps/Settings/Android.bp is equivalent to
312 // //packages/apps/Settings:__subpackages__.
313 // ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public
314 // for now. It is an error if it is used in a module.
Paul Duffine2453c72019-05-31 14:00:04 +0100315 //
316 // If a module does not specify the `visibility` property then it uses the
317 // `default_visibility` property of the `package` module in the module's package.
318 //
319 // If the `default_visibility` property is not set for the module's package then
Paul Duffine484f472019-06-20 16:38:08 +0100320 // it will use the `default_visibility` of its closest ancestor package for which
321 // a `default_visibility` property is specified.
322 //
323 // If no `default_visibility` property can be found then the module uses the
324 // global default of `//visibility:legacy_public`.
Paul Duffine2453c72019-05-31 14:00:04 +0100325 //
Paul Duffin95d53b52019-07-24 13:45:05 +0100326 // The `visibility` property has no effect on a defaults module although it does
327 // apply to any non-defaults module that uses it. To set the visibility of a
328 // defaults module, use the `defaults_visibility` property on the defaults module;
329 // not to be confused with the `default_visibility` property on the package module.
330 //
Elliott Hughes10363162024-01-09 22:02:03 +0000331 // See https://android.googlesource.com/platform/build/soong/+/main/README.md#visibility for
Paul Duffin2e61fa62019-03-28 14:10:57 +0000332 // more details.
333 Visibility []string
334
Bob Badour37af0462021-01-07 03:34:31 +0000335 // Describes the licenses applicable to this module. Must reference license modules.
336 Licenses []string
337
Bob Badour37af0462021-01-07 03:34:31 +0000338 // Override of module name when reporting licenses
339 Effective_package_name *string `blueprint:"mutated"`
340 // Notice files
Bob Badour4101c712022-02-09 11:54:35 -0800341 Effective_license_text NamedPaths `blueprint:"mutated"`
Bob Badour37af0462021-01-07 03:34:31 +0000342 // License names
343 Effective_license_kinds []string `blueprint:"mutated"`
344 // License conditions
345 Effective_license_conditions []string `blueprint:"mutated"`
346
Colin Cross7d5136f2015-05-11 13:39:40 -0700347 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800348 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
349 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
Roland Levillain24bb2e62020-09-22 11:18:38 +0000350 // platform).
Colin Cross7d716ba2017-11-01 10:38:29 -0700351 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700352
353 Target struct {
354 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700355 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700356 }
357 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700358 Compile_multilib *string
Spandan Dasde588a32024-12-03 22:52:24 +0000359 Enabled *bool
Colin Cross69617d32016-09-06 10:39:07 -0700360 }
361 }
362
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000363 // If set to true then the archMutator will create variants for each arch specific target
364 // (e.g. 32/64) that the module is required to produce. If set to false then it will only
365 // create a variant for the architecture and will list the additional arch specific targets
366 // that the variant needs to produce in the CompileMultiTargets property.
Colin Crossee0bc3b2018-10-02 22:01:37 -0700367 UseTargetVariants bool `blueprint:"mutated"`
368 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800369
Dan Willemsen782a2d12015-12-21 14:55:28 -0800370 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700371 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800372
Colin Cross55708f32017-03-20 13:23:34 -0700373 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700374 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700375
Jiyong Park2db76922017-11-08 16:03:48 +0900376 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
377 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
378 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700379 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700380
Jiyong Park2db76922017-11-08 16:03:48 +0900381 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
382 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
383 Soc_specific *bool
384
385 // whether this module is specific to a device, not only for SoC, but also for off-chip
386 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
387 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
388 // This implies `soc_specific:true`.
389 Device_specific *bool
390
391 // whether this module is specific to a software configuration of a product (e.g. country,
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900392 // network operator, etc). When set to true, it is installed into /product (or
393 // /system/product if product partition does not exist).
Jiyong Park2db76922017-11-08 16:03:48 +0900394 Product_specific *bool
395
Justin Yund5f6c822019-06-25 16:47:17 +0900396 // whether this module extends system. When set to true, it is installed into /system_ext
397 // (or /system/system_ext if system_ext partition does not exist).
398 System_ext_specific *bool
399
Jiyong Parkf9332f12018-02-01 00:54:12 +0900400 // Whether this module is installed to recovery partition
401 Recovery *bool
402
Yifan Hong1b3348d2020-01-21 15:53:22 -0800403 // Whether this module is installed to ramdisk
404 Ramdisk *bool
405
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700406 // Whether this module is installed to vendor ramdisk
407 Vendor_ramdisk *bool
408
Inseob Kim08758f02021-04-08 21:13:22 +0900409 // Whether this module is installed to debug ramdisk
410 Debug_ramdisk *bool
411
Spandan Das27ff7672024-11-06 19:23:57 +0000412 // Install to partition system_dlkm when set to true.
413 System_dlkm_specific *bool
414
415 // Install to partition vendor_dlkm when set to true.
416 Vendor_dlkm_specific *bool
417
418 // Install to partition odm_dlkm when set to true.
419 Odm_dlkm_specific *bool
420
Jaewoong Jung8e93aba2021-03-02 16:58:08 -0800421 // Whether this module is built for non-native architectures (also known as native bridge binary)
dimitry1f33e402019-03-26 12:39:31 +0100422 Native_bridge_supported *bool `android:"arch_variant"`
423
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700424 // init.rc files to be installed if this module is installed
Inseob Kim713b87d2024-09-13 11:29:54 +0900425 Init_rc proptools.Configurable[[]string] `android:"arch_variant,path"`
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700426
Steven Moreland57a23d22018-04-04 15:42:19 -0700427 // VINTF manifest fragments to be installed if this module is installed
Inseob Kimf2237022024-07-23 13:36:31 +0900428 Vintf_fragments proptools.Configurable[[]string] `android:"path"`
Steven Moreland57a23d22018-04-04 15:42:19 -0700429
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000430 // The OsType of artifacts that this module variant is responsible for creating.
431 //
432 // Set by osMutator
433 CompileOS OsType `blueprint:"mutated"`
434
Cole Faust0aa21cc2024-03-20 12:28:03 -0700435 // Set to true after the arch mutator has run on this module and set CompileTarget,
436 // CompileMultiTargets, and CompilePrimary
437 ArchReady bool `blueprint:"mutated"`
438
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000439 // The Target of artifacts that this module variant is responsible for creating.
440 //
441 // Set by archMutator
442 CompileTarget Target `blueprint:"mutated"`
443
444 // The additional arch specific targets (e.g. 32/64 bit) that this module variant is
445 // responsible for creating.
446 //
447 // By default this is nil as, where necessary, separate variants are created for the
448 // different multilib types supported and that information is encapsulated in the
449 // CompileTarget so the module variant simply needs to create artifacts for that.
450 //
451 // However, if UseTargetVariants is set to false (e.g. by
452 // InitAndroidMultiTargetsArchModule) then no separate variants are created for the
453 // multilib targets. Instead a single variant is created for the architecture and
454 // this contains the multilib specific targets that this variant should create.
455 //
456 // Set by archMutator
Colin Crossee0bc3b2018-10-02 22:01:37 -0700457 CompileMultiTargets []Target `blueprint:"mutated"`
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000458
459 // True if the module variant's CompileTarget is the primary target
460 //
461 // Set by archMutator
462 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800463
464 // Set by InitAndroidModule
465 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700466 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700467
Paul Duffin1356d8c2020-02-25 19:26:33 +0000468 // If set to true then a CommonOS variant will be created which will have dependencies
469 // on all its OsType specific variants. Used by sdk/module_exports to create a snapshot
470 // that covers all os and architecture variants.
471 //
472 // The OsType specific variants can be retrieved by calling
473 // GetOsSpecificVariantsOfCommonOSVariant
474 //
475 // Set at module initialization time by calling InitCommonOSAndroidMultiTargetsArchModule
476 CreateCommonOSVariant bool `blueprint:"mutated"`
477
Jiyong Park3f627e62024-05-01 16:14:38 +0900478 // When set to true, this module is not installed to the full install path (ex: under
479 // out/target/product/<name>/<partition>). It can be installed only to the packaging
480 // modules like android_filesystem.
481 No_full_install *bool
482
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800483 // When HideFromMake is set to true, no entry for this variant will be emitted in the
484 // generated Android.mk file.
485 HideFromMake bool `blueprint:"mutated"`
486
487 // When SkipInstall is set to true, calls to ctx.InstallFile, ctx.InstallExecutable,
488 // ctx.InstallSymlink and ctx.InstallAbsoluteSymlink act like calls to ctx.PackageFile
489 // and don't create a rule to install the file.
Colin Crossce75d2c2016-10-06 16:12:58 -0700490 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800491
Colin Crossbd3a16b2023-04-25 11:30:51 -0700492 // UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex
493 // mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant
494 // is used to avoid adding install or packaging dependencies into libraries provided
495 // by apexes.
496 UninstallableApexPlatformVariant bool `blueprint:"mutated"`
497
Liz Kammer5ca3a622020-08-05 15:40:41 -0700498 // Whether the module has been replaced by a prebuilt
499 ReplacedByPrebuilt bool `blueprint:"mutated"`
500
Justin Yun32f053b2020-07-31 23:07:17 +0900501 // Disabled by mutators. If set to true, it overrides Enabled property.
502 ForcedDisabled bool `blueprint:"mutated"`
503
Jeff Gaston088e29e2017-11-29 16:47:17 -0800504 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross6c4f21f2019-06-06 15:41:36 -0700505
Liz Kammerc13f7852023-05-17 13:01:48 -0400506 MissingDeps []string `blueprint:"mutated"`
507 CheckedMissingDeps bool `blueprint:"mutated"`
Colin Cross9a362232019-07-01 15:32:45 -0700508
509 // Name and variant strings stored by mutators to enable Module.String()
510 DebugName string `blueprint:"mutated"`
511 DebugMutators []string `blueprint:"mutated"`
512 DebugVariations []string `blueprint:"mutated"`
Colin Cross7228ecd2019-11-18 16:00:16 -0800513
Colin Crossa6845402020-11-16 15:08:19 -0800514 // ImageVariation is set by ImageMutator to specify which image this variation is for,
515 // for example "" for core or "recovery" for recovery. It will often be set to one of the
516 // constants in image.go, but can also be set to a custom value by individual module types.
Colin Cross7228ecd2019-11-18 16:00:16 -0800517 ImageVariation string `blueprint:"mutated"`
Liz Kammer2ada09a2021-08-11 00:17:36 -0400518
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800519 // The team (defined by the owner/vendor) who owns the property.
520 Team *string `android:"path"`
Kiyoung Kimfaf6af32024-08-12 11:15:19 +0900521
522 // vintf_fragment Modules required from this module.
523 Vintf_fragment_modules proptools.Configurable[[]string] `android:"path"`
Jiyong Parka574d532024-08-28 18:06:43 +0900524
525 // List of module names that are prevented from being installed when this module gets
526 // installed.
527 Overrides []string
Justin Yunbe6f81d2024-12-17 21:15:59 +0900528
529 // Set to true if this module must be generic and does not require product-specific information.
530 // To be included in the system image, this property must be set to true.
531 Use_generic_config *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800532}
533
Cole Faust2239ae62025-01-27 15:32:11 -0800534// Properties common to all modules inheriting from ModuleBase. Unlike commonProperties, these
535// properties are NOT automatically inherited by sub-modules created with ctx.CreateModule()
536type baseProperties struct {
537 // names of other modules to install if this module is installed
538 Required proptools.Configurable[[]string] `android:"arch_variant"`
539
540 // names of other modules to install on host if this module is installed
541 Host_required []string `android:"arch_variant"`
542
543 // names of other modules to install on target if this module is installed
544 Target_required []string `android:"arch_variant"`
Cole Faust55c03f02025-03-10 15:52:36 -0700545
546 // If this is a soong config module, this property will be set to the name of the original
547 // module type. This is used by neverallow to ensure you can't bypass a ModuleType() matcher
548 // just by creating a soong config module type.
549 Soong_config_base_module_type *string `blueprint:"mutated"`
Cole Faust2239ae62025-01-27 15:32:11 -0800550}
551
Paul Duffined875132020-09-02 13:08:57 +0100552type distProperties struct {
553 // configuration to distribute output files from this module to the distribution
554 // directory (default: $OUT/dist, configurable with $DIST_DIR)
555 Dist Dist `android:"arch_variant"`
556
557 // a list of configurations to distribute output files from this module to the
558 // distribution directory (default: $OUT/dist, configurable with $DIST_DIR)
559 Dists []Dist `android:"arch_variant"`
560}
561
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800562type TeamDepTagType struct {
563 blueprint.BaseDependencyTag
564}
565
566var teamDepTag = TeamDepTagType{}
567
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900568// Dependency tag for required, host_required, and target_required modules.
569var RequiredDepTag = struct {
570 blueprint.BaseDependencyTag
571 InstallAlwaysNeededDependencyTag
572 // Requiring disabled module has been supported (as a side effect of this being implemented
573 // in Make). We may want to make it an error, but for now, let's keep the existing behavior.
574 AlwaysAllowDisabledModuleDependencyTag
575}{}
576
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800577// CommonTestOptions represents the common `test_options` properties in
578// Android.bp.
579type CommonTestOptions struct {
580 // If the test is a hostside (no device required) unittest that shall be run
581 // during presubmit check.
582 Unit_test *bool
Zhenhuang Wang409d2772022-08-22 16:00:05 +0800583
584 // Tags provide additional metadata to customize test execution by downstream
585 // test runners. The tags have no special meaning to Soong.
586 Tags []string
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800587}
588
589// SetAndroidMkEntries sets AndroidMkEntries according to the value of base
590// `test_options`.
591func (t *CommonTestOptions) SetAndroidMkEntries(entries *AndroidMkEntries) {
592 entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test))
Zhenhuang Wang409d2772022-08-22 16:00:05 +0800593 if len(t.Tags) > 0 {
594 entries.AddStrings("LOCAL_TEST_OPTIONS_TAGS", t.Tags...)
595 }
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800596}
597
Yu Liue70976d2024-10-15 20:45:35 +0000598func (t *CommonTestOptions) SetAndroidMkInfoEntries(entries *AndroidMkInfo) {
599 entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test))
600 if len(t.Tags) > 0 {
601 entries.AddStrings("LOCAL_TEST_OPTIONS_TAGS", t.Tags...)
602 }
603}
604
Paul Duffin74f05592020-11-25 16:37:46 +0000605// The key to use in TaggedDistFiles when a Dist structure does not specify a
606// tag property. This intentionally does not use "" as the default because that
607// would mean that an empty tag would have a different meaning when used in a dist
608// structure that when used to reference a specific set of output paths using the
609// :module{tag} syntax, which passes tag to the OutputFiles(tag) method.
610const DefaultDistTag = "<default-dist-tag>"
611
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000612// A map of OutputFile tag keys to Paths, for disting purposes.
613type TaggedDistFiles map[string]Paths
614
Paul Duffin74f05592020-11-25 16:37:46 +0000615// addPathsForTag adds a mapping from the tag to the paths. If the map is nil
616// then it will create a map, update it and then return it. If a mapping already
617// exists for the tag then the paths are appended to the end of the current list
618// of paths, ignoring any duplicates.
619func (t TaggedDistFiles) addPathsForTag(tag string, paths ...Path) TaggedDistFiles {
620 if t == nil {
621 t = make(TaggedDistFiles)
622 }
623
624 for _, distFile := range paths {
625 if distFile != nil && !t[tag].containsPath(distFile) {
626 t[tag] = append(t[tag], distFile)
627 }
628 }
629
630 return t
631}
632
633// merge merges the entries from the other TaggedDistFiles object into this one.
634// If the TaggedDistFiles is nil then it will create a new instance, merge the
635// other into it, and then return it.
636func (t TaggedDistFiles) merge(other TaggedDistFiles) TaggedDistFiles {
637 for tag, paths := range other {
638 t = t.addPathsForTag(tag, paths...)
639 }
640
641 return t
642}
643
Colin Cross3f40fa42015-01-30 17:27:36 -0800644type hostAndDeviceProperties struct {
Colin Cross4e81d702018-11-09 10:36:55 -0800645 // If set to true, build a variant of the module for the host. Defaults to false.
646 Host_supported *bool
647
648 // If set to true, build a variant of the module for the device. Defaults to true.
Colin Crossa4190c12016-07-12 13:11:25 -0700649 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800650}
651
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000652type hostCrossProperties struct {
653 // If set to true, build a variant of the module for the host cross. Defaults to true.
654 Host_cross_supported *bool
655}
656
Colin Crossc472d572015-03-17 15:06:21 -0700657type Multilib string
658
659const (
Cole Faustb9c67e22024-10-08 16:39:56 -0700660 MultilibBoth Multilib = "both"
661 MultilibFirst Multilib = "first"
662 MultilibCommon Multilib = "common"
Colin Crossc472d572015-03-17 15:06:21 -0700663)
664
Colin Crossa1ad8d12016-06-01 17:09:44 -0700665type HostOrDeviceSupported int
666
667const (
Colin Cross34037c62020-11-17 13:19:17 -0800668 hostSupported = 1 << iota
669 hostCrossSupported
670 deviceSupported
671 hostDefault
672 deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700673
674 // Host and HostCross are built by default. Device is not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800675 HostSupported = hostSupported | hostCrossSupported | hostDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700676
677 // Host is built by default. HostCross and Device are not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800678 HostSupportedNoCross = hostSupported | hostDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700679
680 // Device is built by default. Host and HostCross are not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800681 DeviceSupported = deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700682
Liz Kammer8631cc72021-08-23 21:12:07 +0000683 // By default, _only_ device variant is built. Device variant can be disabled with `device_supported: false`
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -0700684 // Host and HostCross are disabled by default and can be enabled with `host_supported: true`
Colin Cross34037c62020-11-17 13:19:17 -0800685 HostAndDeviceSupported = hostSupported | hostCrossSupported | deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700686
687 // Host, HostCross, and Device are built by default.
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -0700688 // Building Device can be disabled with `device_supported: false`
689 // Building Host and HostCross can be disabled with `host_supported: false`
Colin Cross34037c62020-11-17 13:19:17 -0800690 HostAndDeviceDefault = hostSupported | hostCrossSupported | hostDefault |
691 deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700692
693 // Nothing is supported. This is not exposed to the user, but used to mark a
694 // host only module as unsupported when the module type is not supported on
695 // the host OS. E.g. benchmarks are supported on Linux but not Darwin.
Colin Cross34037c62020-11-17 13:19:17 -0800696 NeitherHostNorDeviceSupported = 0
Colin Crossa1ad8d12016-06-01 17:09:44 -0700697)
698
Jiyong Park2db76922017-11-08 16:03:48 +0900699type moduleKind int
700
701const (
702 platformModule moduleKind = iota
703 deviceSpecificModule
704 socSpecificModule
705 productSpecificModule
Justin Yund5f6c822019-06-25 16:47:17 +0900706 systemExtSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900707)
708
709func (k moduleKind) String() string {
710 switch k {
711 case platformModule:
712 return "platform"
713 case deviceSpecificModule:
714 return "device-specific"
715 case socSpecificModule:
716 return "soc-specific"
717 case productSpecificModule:
718 return "product-specific"
Justin Yund5f6c822019-06-25 16:47:17 +0900719 case systemExtSpecificModule:
720 return "systemext-specific"
Jiyong Park2db76922017-11-08 16:03:48 +0900721 default:
722 panic(fmt.Errorf("unknown module kind %d", k))
723 }
724}
725
Colin Cross9d34f352019-11-22 16:03:51 -0800726func initAndroidModuleBase(m Module) {
727 m.base().module = m
728}
729
Colin Crossa6845402020-11-16 15:08:19 -0800730// InitAndroidModule initializes the Module as an Android module that is not architecture-specific.
731// It adds the common properties, for example "name" and "enabled".
Colin Cross36242852017-06-23 15:06:31 -0700732func InitAndroidModule(m Module) {
Colin Cross9d34f352019-11-22 16:03:51 -0800733 initAndroidModuleBase(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800734 base := m.base()
Colin Cross5049f022015-03-18 13:28:46 -0700735
Colin Cross36242852017-06-23 15:06:31 -0700736 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700737 &base.nameProperties,
Paul Duffined875132020-09-02 13:08:57 +0100738 &base.commonProperties,
Cole Faust2239ae62025-01-27 15:32:11 -0800739 &base.baseProperties,
Paul Duffined875132020-09-02 13:08:57 +0100740 &base.distProperties)
Colin Cross18c46802019-09-24 22:19:02 -0700741
Colin Crosseabaedd2020-02-06 17:01:55 -0800742 initProductVariableModule(m)
Colin Cross18c46802019-09-24 22:19:02 -0700743
Paul Duffin63c6e182019-07-24 14:24:38 +0100744 // The default_visibility property needs to be checked and parsed by the visibility module during
Paul Duffin5ec73ec2020-05-01 17:52:01 +0100745 // its checking and parsing phases so make it the primary visibility property.
746 setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility)
Bob Badour37af0462021-01-07 03:34:31 +0000747
748 // The default_applicable_licenses property needs to be checked and parsed by the licenses module during
749 // its checking and parsing phases so make it the primary licenses property.
750 setPrimaryLicensesProperty(m, "licenses", &base.commonProperties.Licenses)
Colin Cross5049f022015-03-18 13:28:46 -0700751}
752
Colin Crossa6845402020-11-16 15:08:19 -0800753// InitAndroidArchModule initializes the Module as an Android module that is architecture-specific.
754// It adds the common properties, for example "name" and "enabled", as well as runtime generated
755// property structs for architecture-specific versions of generic properties tagged with
756// `android:"arch_variant"`.
757//
Colin Crossd079e0b2022-08-16 10:27:33 -0700758// InitAndroidModule should not be called if InitAndroidArchModule was called.
Colin Cross36242852017-06-23 15:06:31 -0700759func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
760 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700761
762 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800763 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700764 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700765 base.commonProperties.ArchSpecific = true
Colin Crossee0bc3b2018-10-02 22:01:37 -0700766 base.commonProperties.UseTargetVariants = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800767
Colin Cross34037c62020-11-17 13:19:17 -0800768 if hod&hostSupported != 0 && hod&deviceSupported != 0 {
Colin Cross36242852017-06-23 15:06:31 -0700769 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800770 }
771
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000772 if hod&hostCrossSupported != 0 {
773 m.AddProperties(&base.hostCrossProperties)
774 }
775
Colin Crossa6845402020-11-16 15:08:19 -0800776 initArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800777}
778
Colin Crossa6845402020-11-16 15:08:19 -0800779// InitAndroidMultiTargetsArchModule initializes the Module as an Android module that is
780// architecture-specific, but will only have a single variant per OS that handles all the
781// architectures simultaneously. The list of Targets that it must handle will be available from
782// ModuleContext.MultiTargets. It adds the common properties, for example "name" and "enabled", as
783// well as runtime generated property structs for architecture-specific versions of generic
784// properties tagged with `android:"arch_variant"`.
785//
786// InitAndroidModule or InitAndroidArchModule should not be called if
787// InitAndroidMultiTargetsArchModule was called.
Colin Crossee0bc3b2018-10-02 22:01:37 -0700788func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
789 InitAndroidArchModule(m, hod, defaultMultilib)
790 m.base().commonProperties.UseTargetVariants = false
791}
792
Colin Crossa6845402020-11-16 15:08:19 -0800793// InitCommonOSAndroidMultiTargetsArchModule initializes the Module as an Android module that is
794// architecture-specific, but will only have a single variant per OS that handles all the
795// architectures simultaneously, and will also have an additional CommonOS variant that has
796// dependencies on all the OS-specific variants. The list of Targets that it must handle will be
797// available from ModuleContext.MultiTargets. It adds the common properties, for example "name" and
798// "enabled", as well as runtime generated property structs for architecture-specific versions of
799// generic properties tagged with `android:"arch_variant"`.
800//
801// InitAndroidModule, InitAndroidArchModule or InitAndroidMultiTargetsArchModule should not be
802// called if InitCommonOSAndroidMultiTargetsArchModule was called.
Paul Duffin1356d8c2020-02-25 19:26:33 +0000803func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
804 InitAndroidArchModule(m, hod, defaultMultilib)
805 m.base().commonProperties.UseTargetVariants = false
806 m.base().commonProperties.CreateCommonOSVariant = true
807}
808
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800809// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800810// modules. It should be included as an anonymous field in every module
811// struct definition. InitAndroidModule should then be called from the module's
812// factory function, and the return values from InitAndroidModule should be
813// returned from the factory function.
814//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800815// The ModuleBase type is responsible for implementing the GenerateBuildActions
816// method to support the blueprint.Module interface. This method will then call
817// the module's GenerateAndroidBuildActions method once for each build variant
Colin Cross25de6c32019-06-06 14:29:25 -0700818// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext
819// rather than the usual blueprint.ModuleContext.
820// ModuleContext exposes extra functionality specific to the Android build
Colin Cross3f40fa42015-01-30 17:27:36 -0800821// system including details about the particular build variant that is to be
822// generated.
823//
824// For example:
825//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800826// import (
827// "android/soong/android"
828// )
Colin Cross3f40fa42015-01-30 17:27:36 -0800829//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800830// type myModule struct {
831// android.ModuleBase
832// properties struct {
833// MyProperty string
834// }
835// }
Colin Cross3f40fa42015-01-30 17:27:36 -0800836//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800837// func NewMyModule() android.Module {
838// m := &myModule{}
839// m.AddProperties(&m.properties)
840// android.InitAndroidModule(m)
841// return m
842// }
Colin Cross3f40fa42015-01-30 17:27:36 -0800843//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800844// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
845// // Get the CPU architecture for the current build variant.
846// variantArch := ctx.Arch()
Colin Cross3f40fa42015-01-30 17:27:36 -0800847//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800848// // ...
849// }
Colin Cross635c3b02016-05-18 15:37:25 -0700850type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800851 // Putting the curiously recurring thing pointing to the thing that contains
852 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700853 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700854 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800855
Colin Crossfc754582016-05-17 16:34:16 -0700856 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800857 commonProperties commonProperties
Cole Faust2239ae62025-01-27 15:32:11 -0800858 baseProperties baseProperties
Paul Duffined875132020-09-02 13:08:57 +0100859 distProperties distProperties
Colin Cross18c46802019-09-24 22:19:02 -0700860 variableProperties interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800861 hostAndDeviceProperties hostAndDeviceProperties
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000862 hostCrossProperties hostCrossProperties
Jingwen Chen5d864492021-02-24 07:20:12 -0500863
Usta851a3272022-01-05 23:42:33 -0500864 // Arch specific versions of structs in GetProperties() prior to
865 // initialization in InitAndroidArchModule, lets call it `generalProperties`.
866 // The outer index has the same order as generalProperties and the inner index
867 // chooses the props specific to the architecture. The interface{} value is an
868 // archPropRoot that is filled with arch specific values by the arch mutator.
Jingwen Chen5d864492021-02-24 07:20:12 -0500869 archProperties [][]interface{}
870
Paul Duffin63c6e182019-07-24 14:24:38 +0100871 // Information about all the properties on the module that contains visibility rules that need
872 // checking.
873 visibilityPropertyInfo []visibilityProperty
874
875 // The primary visibility property, may be nil, that controls access to the module.
876 primaryVisibilityProperty visibilityProperty
877
Bob Badour37af0462021-01-07 03:34:31 +0000878 // The primary licenses property, may be nil, records license metadata for the module.
879 primaryLicensesProperty applicableLicensesProperty
880
Yu Liueb6d7052024-08-27 22:35:54 +0000881 noAddressSanitizer bool
Colin Cross1f8c52b2015-06-16 16:38:17 -0700882
Colin Cross178a5092016-09-13 13:42:32 -0700883 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700884
885 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700886
887 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700888 buildParams []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800889 ruleParams map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800890 variables map[string]string
Colin Cross36242852017-06-23 15:06:31 -0700891}
892
Lukacs T. Berkid18d8ca2021-06-25 09:11:22 +0200893func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
Liz Kammer9525e712022-01-05 13:46:24 -0500894 (*d)["Android"] = map[string]interface{}{
895 // Properties set in Blueprint or in blueprint of a defaults modules
896 "SetProperties": m.propertiesWithValues(),
897 }
898}
899
900type propInfo struct {
Liz Kammer898e0762022-03-22 11:27:26 -0400901 Name string
902 Type string
903 Value string
904 Values []string
Liz Kammer9525e712022-01-05 13:46:24 -0500905}
906
907func (m *ModuleBase) propertiesWithValues() []propInfo {
908 var info []propInfo
909 props := m.GetProperties()
910
911 var propsWithValues func(name string, v reflect.Value)
912 propsWithValues = func(name string, v reflect.Value) {
913 kind := v.Kind()
914 switch kind {
915 case reflect.Ptr, reflect.Interface:
916 if v.IsNil() {
917 return
918 }
919 propsWithValues(name, v.Elem())
920 case reflect.Struct:
921 if v.IsZero() {
922 return
923 }
924 for i := 0; i < v.NumField(); i++ {
925 namePrefix := name
926 sTyp := v.Type().Field(i)
927 if proptools.ShouldSkipProperty(sTyp) {
928 continue
929 }
930 if name != "" && !strings.HasSuffix(namePrefix, ".") {
931 namePrefix += "."
932 }
933 if !proptools.IsEmbedded(sTyp) {
934 namePrefix += sTyp.Name
935 }
936 sVal := v.Field(i)
937 propsWithValues(namePrefix, sVal)
938 }
939 case reflect.Array, reflect.Slice:
940 if v.IsNil() {
941 return
942 }
943 elKind := v.Type().Elem().Kind()
Liz Kammer898e0762022-03-22 11:27:26 -0400944 info = append(info, propInfo{Name: name, Type: elKind.String() + " " + kind.String(), Values: sliceReflectionValue(v)})
Liz Kammer9525e712022-01-05 13:46:24 -0500945 default:
Liz Kammer898e0762022-03-22 11:27:26 -0400946 info = append(info, propInfo{Name: name, Type: kind.String(), Value: reflectionValue(v)})
Liz Kammer9525e712022-01-05 13:46:24 -0500947 }
948 }
949
950 for _, p := range props {
951 propsWithValues("", reflect.ValueOf(p).Elem())
952 }
Liz Kammer898e0762022-03-22 11:27:26 -0400953 sort.Slice(info, func(i, j int) bool {
954 return info[i].Name < info[j].Name
955 })
Liz Kammer9525e712022-01-05 13:46:24 -0500956 return info
Lukacs T. Berkid18d8ca2021-06-25 09:11:22 +0200957}
958
Liz Kammer898e0762022-03-22 11:27:26 -0400959func reflectionValue(value reflect.Value) string {
960 switch value.Kind() {
961 case reflect.Bool:
962 return fmt.Sprintf("%t", value.Bool())
963 case reflect.Int64:
964 return fmt.Sprintf("%d", value.Int())
965 case reflect.String:
966 return fmt.Sprintf("%s", value.String())
967 case reflect.Struct:
968 if value.IsZero() {
969 return "{}"
970 }
971 length := value.NumField()
972 vals := make([]string, length, length)
973 for i := 0; i < length; i++ {
974 sTyp := value.Type().Field(i)
975 if proptools.ShouldSkipProperty(sTyp) {
976 continue
977 }
978 name := sTyp.Name
979 vals[i] = fmt.Sprintf("%s: %s", name, reflectionValue(value.Field(i)))
980 }
981 return fmt.Sprintf("%s{%s}", value.Type(), strings.Join(vals, ", "))
982 case reflect.Array, reflect.Slice:
983 vals := sliceReflectionValue(value)
984 return fmt.Sprintf("[%s]", strings.Join(vals, ", "))
985 }
986 return ""
987}
988
989func sliceReflectionValue(value reflect.Value) []string {
990 length := value.Len()
991 vals := make([]string, length, length)
992 for i := 0; i < length; i++ {
993 vals[i] = reflectionValue(value.Index(i))
994 }
995 return vals
996}
997
Paul Duffin44f1d842020-06-26 20:17:02 +0100998func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {}
999
Colin Cross4157e882019-06-06 16:57:04 -07001000func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
Colin Cross5f692ec2019-02-01 16:53:07 -08001001
Ronald Braunstein73b08ff2023-12-19 10:24:47 -08001002func (m *ModuleBase) baseDepsMutator(ctx BottomUpMutatorContext) {
1003 if m.Team() != "" {
1004 ctx.AddDependency(ctx.Module(), teamDepTag, m.Team())
1005 }
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001006
1007 // TODO(jiyong): remove below case. This is to work around build errors happening
1008 // on branches with reduced manifest like aosp_kernel-build-tools.
1009 // In the branch, a build error occurs as follows.
1010 // 1. aosp_kernel-build-tools is a reduced manifest branch. It doesn't have some git
1011 // projects like external/bouncycastle
1012 // 2. `boot_signer` is `required` by modules like `build_image` which is explicitly list as
1013 // the top-level build goal (in the shell file that invokes Soong).
1014 // 3. `boot_signer` depends on `bouncycastle-unbundled` which is in the missing git project.
Cole Faust88f469e2025-01-21 13:05:05 -08001015 // 4. aosp_kernel-build-tools invokes soong with `--soong-only`. Therefore, the absence of
1016 // ALLOW_MISSING_DEPENDENCIES didn't cause a problem, as previously only make processed required
1017 // dependencies.
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001018 // 5. Now, since Soong understands `required` deps, it tries to build `boot_signer` and the
1019 // absence of external/bouncycastle fails the build.
1020 //
1021 // Unfortunately, there's no way for Soong to correctly determine if it's running in a
1022 // reduced manifest branch. Instead, here, we use the absence of DeviceArch or DeviceName as
1023 // a strong signal, because that's very common across reduced manifest branches.
1024 pv := ctx.Config().productVariables
1025 fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil
1026 if fullManifest {
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001027 addVintfFragmentDeps(ctx)
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001028 }
1029}
1030
Inseob Kim0c67c8e2025-03-14 18:33:55 +09001031// required property can be overridden too; handle it separately
1032func (m *ModuleBase) baseOverridablePropertiesDepsMutator(ctx BottomUpMutatorContext) {
1033 pv := ctx.Config().productVariables
1034 fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil
1035 if fullManifest {
1036 addRequiredDeps(ctx)
1037 }
1038}
1039
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001040// addRequiredDeps adds required, target_required, and host_required as dependencies.
Jiyong Parkf21dd652024-04-17 05:22:37 +00001041func addRequiredDeps(ctx BottomUpMutatorContext) {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001042 addDep := func(target Target, depName string) {
1043 if !ctx.OtherModuleExists(depName) {
1044 if ctx.Config().AllowMissingDependencies() {
1045 return
1046 }
1047 }
1048
1049 // If Android native module requires another Android native module, ensure that
1050 // they have the same bitness. This mimics the policy in select-bitness-of-required-modules
1051 // in build/make/core/main.mk.
1052 // TODO(jiyong): the Make-side does this only when the required module is a shared
1053 // library or a native test.
Jiyong Parkf21dd652024-04-17 05:22:37 +00001054 bothInAndroid := ctx.Device() && target.Os.Class == Device
Jiyong Parkc4b1d552024-05-13 16:47:30 +09001055 nativeArch := InList(ctx.Arch().ArchType.Multilib, []string{"lib32", "lib64"}) &&
1056 InList(target.Arch.ArchType.Multilib, []string{"lib32", "lib64"})
Jiyong Parkf21dd652024-04-17 05:22:37 +00001057 sameBitness := ctx.Arch().ArchType.Multilib == target.Arch.ArchType.Multilib
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001058 if bothInAndroid && nativeArch && !sameBitness {
1059 return
1060 }
1061
Jiyong Park8db44152024-05-28 12:22:04 +09001062 // ... also don't make a dependency between native bridge arch and non-native bridge
1063 // arches. b/342945184
1064 if ctx.Target().NativeBridge != target.NativeBridge {
1065 return
1066 }
1067
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001068 variation := target.Variations()
1069 if ctx.OtherModuleFarDependencyVariantExists(variation, depName) {
1070 ctx.AddFarVariationDependencies(variation, RequiredDepTag, depName)
1071 }
1072 }
1073
Jiyong Park73e5bab2024-04-05 13:37:21 +09001074 var deviceTargets []Target
1075 deviceTargets = append(deviceTargets, ctx.Config().Targets[Android]...)
1076 deviceTargets = append(deviceTargets, ctx.Config().AndroidCommonTarget)
1077
1078 var hostTargets []Target
1079 hostTargets = append(hostTargets, ctx.Config().Targets[ctx.Config().BuildOS]...)
1080 hostTargets = append(hostTargets, ctx.Config().BuildOSCommonTarget)
1081
Jiyong Parkf21dd652024-04-17 05:22:37 +00001082 if ctx.Device() {
Jihoon Kangd1a01422024-12-26 19:07:13 +00001083 for _, depName := range append(ctx.Module().RequiredModuleNames(ctx), ctx.Module().VintfFragmentModuleNames(ctx)...) {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001084 for _, target := range deviceTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001085 addDep(target, depName)
1086 }
1087 }
Jiyong Parkf21dd652024-04-17 05:22:37 +00001088 for _, depName := range ctx.Module().HostRequiredModuleNames() {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001089 for _, target := range hostTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001090 addDep(target, depName)
1091 }
1092 }
1093 }
1094
Jiyong Parkf21dd652024-04-17 05:22:37 +00001095 if ctx.Host() {
Jihoon Kangd1a01422024-12-26 19:07:13 +00001096 for _, depName := range append(ctx.Module().RequiredModuleNames(ctx), ctx.Module().VintfFragmentModuleNames(ctx)...) {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001097 for _, target := range hostTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001098 // When a host module requires another host module, don't make a
1099 // dependency if they have different OSes (i.e. hostcross).
Jiyong Parkf21dd652024-04-17 05:22:37 +00001100 if ctx.Target().HostCross != target.HostCross {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001101 continue
1102 }
1103 addDep(target, depName)
1104 }
1105 }
Jiyong Parkf21dd652024-04-17 05:22:37 +00001106 for _, depName := range ctx.Module().TargetRequiredModuleNames() {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001107 for _, target := range deviceTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001108 addDep(target, depName)
1109 }
1110 }
1111 }
Ronald Braunstein73b08ff2023-12-19 10:24:47 -08001112}
1113
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001114var vintfDepTag = struct {
1115 blueprint.BaseDependencyTag
1116 InstallAlwaysNeededDependencyTag
1117}{}
1118
Kiyoung Kim11ad4e92024-09-04 14:16:47 +09001119func IsVintfDepTag(depTag blueprint.DependencyTag) bool {
1120 return depTag == vintfDepTag
1121}
1122
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001123func addVintfFragmentDeps(ctx BottomUpMutatorContext) {
Kiyoung Kim55234812024-09-11 17:00:24 +09001124 // Vintf manifests in the recovery partition will be ignored.
1125 if !ctx.Device() || ctx.Module().InstallInRecovery() {
1126 return
1127 }
1128
1129 deviceConfig := ctx.DeviceConfig()
1130
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001131 mod := ctx.Module()
Kiyoung Kim55234812024-09-11 17:00:24 +09001132 vintfModules := ctx.AddDependency(mod, vintfDepTag, mod.VintfFragmentModuleNames(ctx)...)
1133
1134 modPartition := mod.PartitionTag(deviceConfig)
1135 for _, vintf := range vintfModules {
Cole Faust69788792024-10-10 11:00:36 -07001136 if vintf == nil {
1137 // TODO(b/372091092): Remove this. Having it gives us missing dependency errors instead
1138 // of nil pointer dereference errors, but we should resolve the missing dependencies.
1139 continue
1140 }
Kiyoung Kim11ad4e92024-09-04 14:16:47 +09001141 if vintfModule, ok := vintf.(*VintfFragmentModule); ok {
Kiyoung Kim55234812024-09-11 17:00:24 +09001142 vintfPartition := vintfModule.PartitionTag(deviceConfig)
1143 if modPartition != vintfPartition {
1144 ctx.ModuleErrorf("Module %q(%q) and Vintf_fragment %q(%q) are installed to different partitions.",
1145 mod.Name(), modPartition,
1146 vintfModule.Name(), vintfPartition)
1147 }
1148 } else {
1149 ctx.ModuleErrorf("Only vintf_fragment type module should be listed in vintf_fragment_modules : %q", vintf.Name())
1150 }
1151 }
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001152}
1153
Usta355a5872021-12-01 15:16:32 -05001154// AddProperties "registers" the provided props
1155// each value in props MUST be a pointer to a struct
Colin Cross4157e882019-06-06 16:57:04 -07001156func (m *ModuleBase) AddProperties(props ...interface{}) {
1157 m.registerProps = append(m.registerProps, props...)
Colin Cross36242852017-06-23 15:06:31 -07001158}
1159
Colin Cross4157e882019-06-06 16:57:04 -07001160func (m *ModuleBase) GetProperties() []interface{} {
1161 return m.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -08001162}
1163
Colin Cross4157e882019-06-06 16:57:04 -07001164func (m *ModuleBase) BuildParamsForTests() []BuildParams {
Chih-Hung Hsiehb8082292021-09-09 23:20:39 -07001165 // Expand the references to module variables like $flags[0-9]*,
1166 // so we do not need to change many existing unit tests.
1167 // This looks like undoing the shareFlags optimization in cc's
1168 // transformSourceToObj, and should only affects unit tests.
1169 vars := m.VariablesForTests()
1170 buildParams := append([]BuildParams(nil), m.buildParams...)
Sasha Smundake198eaf2022-08-04 13:07:02 -07001171 for i := range buildParams {
Chih-Hung Hsiehb8082292021-09-09 23:20:39 -07001172 newArgs := make(map[string]string)
1173 for k, v := range buildParams[i].Args {
1174 newArgs[k] = v
1175 // Replaces both ${flags1} and $flags1 syntax.
1176 if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") {
1177 if value, found := vars[v[2:len(v)-1]]; found {
1178 newArgs[k] = value
1179 }
1180 } else if strings.HasPrefix(v, "$") {
1181 if value, found := vars[v[1:]]; found {
1182 newArgs[k] = value
1183 }
1184 }
1185 }
1186 buildParams[i].Args = newArgs
1187 }
1188 return buildParams
Colin Crosscec81712017-07-13 14:43:27 -07001189}
1190
Colin Cross4157e882019-06-06 16:57:04 -07001191func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
1192 return m.ruleParams
Colin Cross4c83e5c2019-02-25 14:54:28 -08001193}
1194
Colin Cross4157e882019-06-06 16:57:04 -07001195func (m *ModuleBase) VariablesForTests() map[string]string {
1196 return m.variables
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001197}
1198
Colin Crossce75d2c2016-10-06 16:12:58 -07001199// Name returns the name of the module. It may be overridden by individual module types, for
1200// example prebuilts will prepend prebuilt_ to the name.
Colin Cross4157e882019-06-06 16:57:04 -07001201func (m *ModuleBase) Name() string {
1202 return String(m.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -07001203}
1204
Colin Cross9a362232019-07-01 15:32:45 -07001205// String returns a string that includes the module name and variants for printing during debugging.
1206func (m *ModuleBase) String() string {
1207 sb := strings.Builder{}
1208 sb.WriteString(m.commonProperties.DebugName)
1209 sb.WriteString("{")
1210 for i := range m.commonProperties.DebugMutators {
1211 if i != 0 {
1212 sb.WriteString(",")
1213 }
1214 sb.WriteString(m.commonProperties.DebugMutators[i])
1215 sb.WriteString(":")
1216 sb.WriteString(m.commonProperties.DebugVariations[i])
1217 }
1218 sb.WriteString("}")
1219 return sb.String()
1220}
1221
Colin Crossce75d2c2016-10-06 16:12:58 -07001222// BaseModuleName returns the name of the module as specified in the blueprints file.
Colin Cross4157e882019-06-06 16:57:04 -07001223func (m *ModuleBase) BaseModuleName() string {
1224 return String(m.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -07001225}
1226
Colin Cross4157e882019-06-06 16:57:04 -07001227func (m *ModuleBase) base() *ModuleBase {
1228 return m
Colin Cross3f40fa42015-01-30 17:27:36 -08001229}
1230
Paul Duffine2453c72019-05-31 14:00:04 +01001231func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName {
1232 return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()}
1233}
1234
1235func (m *ModuleBase) visibilityProperties() []visibilityProperty {
Paul Duffin63c6e182019-07-24 14:24:38 +01001236 return m.visibilityPropertyInfo
1237}
1238
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001239func (m *ModuleBase) Dists() []Dist {
Paul Duffined875132020-09-02 13:08:57 +01001240 if len(m.distProperties.Dist.Targets) > 0 {
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001241 // Make a copy of the underlying Dists slice to protect against
1242 // backing array modifications with repeated calls to this method.
Paul Duffined875132020-09-02 13:08:57 +01001243 distsCopy := append([]Dist(nil), m.distProperties.Dists...)
1244 return append(distsCopy, m.distProperties.Dist)
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001245 } else {
Paul Duffined875132020-09-02 13:08:57 +01001246 return m.distProperties.Dists
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001247 }
1248}
1249
1250func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFiles {
Paul Duffin74f05592020-11-25 16:37:46 +00001251 var distFiles TaggedDistFiles
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001252 for _, dist := range m.Dists() {
Paul Duffin74f05592020-11-25 16:37:46 +00001253 // If no tag is specified then it means to use the default dist paths so use
1254 // the special tag name which represents that.
1255 tag := proptools.StringDefault(dist.Tag, DefaultDistTag)
1256
mrziwangabdb2932024-06-18 12:43:41 -07001257 distFileForTagFromProvider, err := outputFilesForModuleFromProvider(ctx, m.module, tag)
Cole Fausta8437c52025-02-25 14:45:43 -08001258
1259 // If the module doesn't define output files for the DefaultDistTag, try the files under
1260 // the "" tag.
1261 if tag == DefaultDistTag && errors.Is(err, ErrUnsupportedOutputTag) {
1262 distFileForTagFromProvider, err = outputFilesForModuleFromProvider(ctx, m.module, "")
1263 }
1264
mrziwangabdb2932024-06-18 12:43:41 -07001265 if err != OutputFilesProviderNotSet {
1266 if err != nil && tag != DefaultDistTag {
1267 ctx.PropertyErrorf("dist.tag", "%s", err.Error())
1268 } else {
1269 distFiles = distFiles.addPathsForTag(tag, distFileForTagFromProvider...)
1270 continue
1271 }
1272 }
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001273 }
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001274 return distFiles
1275}
1276
Cole Faust02987bd2024-03-21 17:58:43 -07001277func (m *ModuleBase) ArchReady() bool {
1278 return m.commonProperties.ArchReady
1279}
1280
Colin Cross4157e882019-06-06 16:57:04 -07001281func (m *ModuleBase) Target() Target {
1282 return m.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -08001283}
1284
Colin Cross4157e882019-06-06 16:57:04 -07001285func (m *ModuleBase) TargetPrimary() bool {
1286 return m.commonProperties.CompilePrimary
Colin Cross8b74d172016-09-13 09:59:14 -07001287}
1288
Colin Cross4157e882019-06-06 16:57:04 -07001289func (m *ModuleBase) MultiTargets() []Target {
1290 return m.commonProperties.CompileMultiTargets
Colin Crossee0bc3b2018-10-02 22:01:37 -07001291}
1292
Colin Cross4157e882019-06-06 16:57:04 -07001293func (m *ModuleBase) Os() OsType {
1294 return m.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -08001295}
1296
Colin Cross4157e882019-06-06 16:57:04 -07001297func (m *ModuleBase) Host() bool {
Jiyong Park1613e552020-09-14 19:43:17 +09001298 return m.Os().Class == Host
Dan Willemsen97750522016-02-09 17:43:51 -08001299}
1300
Yo Chiangbba545e2020-06-09 16:15:37 +08001301func (m *ModuleBase) Device() bool {
1302 return m.Os().Class == Device
1303}
1304
Colin Cross4157e882019-06-06 16:57:04 -07001305func (m *ModuleBase) Arch() Arch {
1306 return m.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -08001307}
1308
Colin Cross4157e882019-06-06 16:57:04 -07001309func (m *ModuleBase) ArchSpecific() bool {
1310 return m.commonProperties.ArchSpecific
Dan Willemsen0b24c742016-10-04 15:13:37 -07001311}
1312
Paul Duffin1356d8c2020-02-25 19:26:33 +00001313// True if the current variant is a CommonOS variant, false otherwise.
1314func (m *ModuleBase) IsCommonOSVariant() bool {
Colin Cross8bbc3d52024-09-11 15:33:54 -07001315 return m.commonProperties.CompileOS == CommonOS
Paul Duffin1356d8c2020-02-25 19:26:33 +00001316}
1317
Colin Cross34037c62020-11-17 13:19:17 -08001318// supportsTarget returns true if the given Target is supported by the current module.
1319func (m *ModuleBase) supportsTarget(target Target) bool {
1320 switch target.Os.Class {
1321 case Host:
1322 if target.HostCross {
1323 return m.HostCrossSupported()
1324 } else {
1325 return m.HostSupported()
Colin Crossa1ad8d12016-06-01 17:09:44 -07001326 }
Colin Cross34037c62020-11-17 13:19:17 -08001327 case Device:
1328 return m.DeviceSupported()
Colin Crossa1ad8d12016-06-01 17:09:44 -07001329 default:
Jiyong Park1613e552020-09-14 19:43:17 +09001330 return false
Colin Crossa1ad8d12016-06-01 17:09:44 -07001331 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001332}
1333
Colin Cross34037c62020-11-17 13:19:17 -08001334// DeviceSupported returns true if the current module is supported and enabled for device targets,
1335// i.e. the factory method set the HostOrDeviceSupported value to include device support and
1336// the device support is enabled by default or enabled by the device_supported property.
Colin Cross4157e882019-06-06 16:57:04 -07001337func (m *ModuleBase) DeviceSupported() bool {
Colin Cross34037c62020-11-17 13:19:17 -08001338 hod := m.commonProperties.HostOrDeviceSupported
1339 // deviceEnabled is true if the device_supported property is true or the HostOrDeviceSupported
1340 // value has the deviceDefault bit set.
1341 deviceEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Device_supported, hod&deviceDefault != 0)
1342 return hod&deviceSupported != 0 && deviceEnabled
Colin Cross3f40fa42015-01-30 17:27:36 -08001343}
1344
Colin Cross34037c62020-11-17 13:19:17 -08001345// HostSupported returns true if the current module is supported and enabled for host targets,
1346// i.e. the factory method set the HostOrDeviceSupported value to include host support and
1347// the host support is enabled by default or enabled by the host_supported property.
Paul Duffine44358f2019-11-26 18:04:12 +00001348func (m *ModuleBase) HostSupported() bool {
Colin Cross34037c62020-11-17 13:19:17 -08001349 hod := m.commonProperties.HostOrDeviceSupported
1350 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1351 // value has the hostDefault bit set.
1352 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
1353 return hod&hostSupported != 0 && hostEnabled
1354}
1355
1356// HostCrossSupported returns true if the current module is supported and enabled for host cross
1357// targets, i.e. the factory method set the HostOrDeviceSupported value to include host cross
1358// support and the host cross support is enabled by default or enabled by the
1359// host_supported property.
1360func (m *ModuleBase) HostCrossSupported() bool {
1361 hod := m.commonProperties.HostOrDeviceSupported
1362 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1363 // value has the hostDefault bit set.
1364 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
Ivan Lozanoc7eafa72024-07-16 17:55:33 +00001365
1366 // Default true for the Host_cross_supported property
1367 hostCrossEnabled := proptools.BoolDefault(m.hostCrossProperties.Host_cross_supported, true)
1368
1369 return hod&hostCrossSupported != 0 && hostEnabled && hostCrossEnabled
Paul Duffine44358f2019-11-26 18:04:12 +00001370}
1371
Colin Cross4157e882019-06-06 16:57:04 -07001372func (m *ModuleBase) Platform() bool {
Justin Yund5f6c822019-06-25 16:47:17 +09001373 return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.SystemExtSpecific()
Jiyong Parkc678ad32018-04-10 13:07:10 +09001374}
1375
Colin Cross4157e882019-06-06 16:57:04 -07001376func (m *ModuleBase) DeviceSpecific() bool {
1377 return Bool(m.commonProperties.Device_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001378}
1379
Colin Cross4157e882019-06-06 16:57:04 -07001380func (m *ModuleBase) SocSpecific() bool {
1381 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001382}
1383
Colin Cross4157e882019-06-06 16:57:04 -07001384func (m *ModuleBase) ProductSpecific() bool {
1385 return Bool(m.commonProperties.Product_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001386}
1387
Justin Yund5f6c822019-06-25 16:47:17 +09001388func (m *ModuleBase) SystemExtSpecific() bool {
1389 return Bool(m.commonProperties.System_ext_specific)
Dario Frenifd05a742018-05-29 13:28:54 +01001390}
1391
Colin Crossc2d24052020-05-13 11:05:02 -07001392// RequiresStableAPIs returns true if the module will be installed to a partition that may
1393// be updated separately from the system image.
1394func (m *ModuleBase) RequiresStableAPIs(ctx BaseModuleContext) bool {
1395 return m.SocSpecific() || m.DeviceSpecific() ||
1396 (m.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface())
1397}
1398
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001399func (m *ModuleBase) PartitionTag(config DeviceConfig) string {
1400 partition := "system"
1401 if m.SocSpecific() {
1402 // A SoC-specific module could be on the vendor partition at
1403 // "vendor" or the system partition at "system/vendor".
1404 if config.VendorPath() == "vendor" {
1405 partition = "vendor"
1406 }
1407 } else if m.DeviceSpecific() {
1408 // A device-specific module could be on the odm partition at
1409 // "odm", the vendor partition at "vendor/odm", or the system
1410 // partition at "system/vendor/odm".
1411 if config.OdmPath() == "odm" {
1412 partition = "odm"
Ramy Medhat944839a2020-03-31 22:14:52 -04001413 } else if strings.HasPrefix(config.OdmPath(), "vendor/") {
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001414 partition = "vendor"
1415 }
1416 } else if m.ProductSpecific() {
1417 // A product-specific module could be on the product partition
1418 // at "product" or the system partition at "system/product".
1419 if config.ProductPath() == "product" {
1420 partition = "product"
1421 }
1422 } else if m.SystemExtSpecific() {
1423 // A system_ext-specific module could be on the system_ext
1424 // partition at "system_ext" or the system partition at
1425 // "system/system_ext".
1426 if config.SystemExtPath() == "system_ext" {
1427 partition = "system_ext"
1428 }
Cole Faust76a6e952024-11-07 16:56:45 -08001429 } else if m.InstallInRamdisk() {
1430 partition = "ramdisk"
Jihoon Kang30bf8f62024-11-26 21:50:55 +00001431 } else if m.InstallInVendorRamdisk() {
1432 partition = "vendor_ramdisk"
Jihoon Kang3216c982024-12-02 19:42:20 +00001433 } else if m.InstallInRecovery() {
1434 partition = "recovery"
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001435 }
1436 return partition
1437}
1438
Cole Fauste8a87832024-09-11 11:35:46 -07001439func (m *ModuleBase) Enabled(ctx ConfigurableEvaluatorContext) bool {
Justin Yun32f053b2020-07-31 23:07:17 +09001440 if m.commonProperties.ForcedDisabled {
1441 return false
1442 }
Cole Fausta963b942024-04-11 17:43:00 -07001443 return m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled)
Colin Cross3f40fa42015-01-30 17:27:36 -08001444}
1445
Cole Faust8eeae4b2024-09-12 11:51:04 -07001446// Returns a copy of the enabled property, useful for passing it on to sub-modules
1447func (m *ModuleBase) EnabledProperty() proptools.Configurable[bool] {
1448 if m.commonProperties.ForcedDisabled {
1449 return proptools.NewSimpleConfigurable(false)
1450 }
1451 return m.commonProperties.Enabled.Clone()
1452}
1453
Inseob Kimeec88e12020-01-22 11:11:29 +09001454func (m *ModuleBase) Disable() {
Justin Yun32f053b2020-07-31 23:07:17 +09001455 m.commonProperties.ForcedDisabled = true
Inseob Kimeec88e12020-01-22 11:11:29 +09001456}
1457
Colin Crossa9c8c9f2020-12-16 10:20:23 -08001458// HideFromMake marks this variant so that it is not emitted in the generated Android.mk file.
1459func (m *ModuleBase) HideFromMake() {
1460 m.commonProperties.HideFromMake = true
1461}
1462
1463// IsHideFromMake returns true if HideFromMake was previously called.
1464func (m *ModuleBase) IsHideFromMake() bool {
1465 return m.commonProperties.HideFromMake == true
1466}
1467
1468// SkipInstall marks this variant to not create install rules when ctx.Install* are called.
Colin Cross4157e882019-06-06 16:57:04 -07001469func (m *ModuleBase) SkipInstall() {
1470 m.commonProperties.SkipInstall = true
Colin Crossce75d2c2016-10-06 16:12:58 -07001471}
1472
Martin Stjernholm9e7f45e2020-12-23 03:50:30 +00001473// IsSkipInstall returns true if this variant is marked to not create install
1474// rules when ctx.Install* are called.
1475func (m *ModuleBase) IsSkipInstall() bool {
1476 return m.commonProperties.SkipInstall
1477}
1478
Iván Budnik295da162023-03-10 16:11:26 +00001479// Similar to HideFromMake, but if the AndroidMk entry would set
1480// LOCAL_UNINSTALLABLE_MODULE then this variant may still output that entry
1481// rather than leaving it out altogether. That happens in cases where it would
1482// have other side effects, in particular when it adds a NOTICE file target,
1483// which other install targets might depend on.
1484func (m *ModuleBase) MakeUninstallable() {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001485 m.commonProperties.UninstallableApexPlatformVariant = true
Iván Budnik295da162023-03-10 16:11:26 +00001486 m.HideFromMake()
Spandan Das034af2c2024-10-30 21:45:09 +00001487 m.SkipInstall()
Iván Budnik295da162023-03-10 16:11:26 +00001488}
1489
Liz Kammer5ca3a622020-08-05 15:40:41 -07001490func (m *ModuleBase) ReplacedByPrebuilt() {
1491 m.commonProperties.ReplacedByPrebuilt = true
Colin Crossa9c8c9f2020-12-16 10:20:23 -08001492 m.HideFromMake()
Liz Kammer5ca3a622020-08-05 15:40:41 -07001493}
1494
1495func (m *ModuleBase) IsReplacedByPrebuilt() bool {
1496 return m.commonProperties.ReplacedByPrebuilt
1497}
1498
Colin Cross4157e882019-06-06 16:57:04 -07001499func (m *ModuleBase) ExportedToMake() bool {
1500 return m.commonProperties.NamespaceExportedToMake
Jiyong Park374510b2018-03-19 18:23:01 +09001501}
1502
Justin Yun885a7de2021-06-29 20:34:53 +09001503func (m *ModuleBase) EffectiveLicenseFiles() Paths {
Bob Badour4101c712022-02-09 11:54:35 -08001504 result := make(Paths, 0, len(m.commonProperties.Effective_license_text))
1505 for _, p := range m.commonProperties.Effective_license_text {
1506 result = append(result, p.Path)
1507 }
1508 return result
Justin Yun885a7de2021-06-29 20:34:53 +09001509}
1510
Colin Crosse9fe2942020-11-10 18:12:15 -08001511// computeInstallDeps finds the installed paths of all dependencies that have a dependency
Colin Crossbd3a16b2023-04-25 11:30:51 -07001512// tag that is annotated as needing installation via the isInstallDepNeeded method.
Colin Crossa14fb6a2024-10-23 16:57:06 -07001513func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]depset.DepSet[InstallPath], []depset.DepSet[PackagingSpec]) {
1514 var installDeps []depset.DepSet[InstallPath]
1515 var packagingSpecs []depset.DepSet[PackagingSpec]
Yu Liu5697f8f2024-12-13 23:31:08 +00001516 ctx.VisitDirectDepsProxy(func(dep ModuleProxy) {
1517 if isInstallDepNeeded(ctx, dep) {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001518 // Installation is still handled by Make, so anything hidden from Make is not
1519 // installable.
Yu Liubad1eef2024-08-21 22:37:35 +00001520 info := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider)
Yu Liuf22120f2025-03-13 18:36:35 +00001521 commonInfo := OtherModulePointerProviderOrDefault(ctx, dep, CommonModuleInfoProvider)
Yu Liu5697f8f2024-12-13 23:31:08 +00001522 if !commonInfo.HideFromMake && !commonInfo.SkipInstall {
Yu Liubad1eef2024-08-21 22:37:35 +00001523 installDeps = append(installDeps, info.TransitiveInstallFiles)
Colin Crossbd3a16b2023-04-25 11:30:51 -07001524 }
1525 // Add packaging deps even when the dependency is not installed so that uninstallable
1526 // modules can still be packaged. Often the package will be installed instead.
Yu Liubad1eef2024-08-21 22:37:35 +00001527 packagingSpecs = append(packagingSpecs, info.TransitivePackagingSpecs)
Colin Cross897266e2020-02-13 13:22:08 -08001528 }
1529 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001530
Colin Crossffe6b9d2020-12-01 15:40:06 -08001531 return installDeps, packagingSpecs
Colin Cross3f40fa42015-01-30 17:27:36 -08001532}
1533
Colin Crossbd3a16b2023-04-25 11:30:51 -07001534// isInstallDepNeeded returns true if installing the output files of the current module
1535// should also install the output files of the given dependency and dependency tag.
Yu Liu5697f8f2024-12-13 23:31:08 +00001536func isInstallDepNeeded(ctx ModuleContext, dep ModuleProxy) bool {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001537 // Don't add a dependency from the platform to a library provided by an apex.
Yu Liuf22120f2025-03-13 18:36:35 +00001538 if OtherModulePointerProviderOrDefault(ctx, dep, CommonModuleInfoProvider).UninstallableApexPlatformVariant {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001539 return false
1540 }
1541 // Only install modules if the dependency tag is an InstallDepNeeded tag.
Yu Liu5697f8f2024-12-13 23:31:08 +00001542 return IsInstallDepNeededTag(ctx.OtherModuleDependencyTag(dep))
Colin Crossbd3a16b2023-04-25 11:30:51 -07001543}
1544
Colin Cross4157e882019-06-06 16:57:04 -07001545func (m *ModuleBase) NoAddressSanitizer() bool {
1546 return m.noAddressSanitizer
Colin Cross3f40fa42015-01-30 17:27:36 -08001547}
1548
Colin Cross4157e882019-06-06 16:57:04 -07001549func (m *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -08001550 return false
1551}
1552
Jaewoong Jung0949f312019-09-11 10:25:18 -07001553func (m *ModuleBase) InstallInTestcases() bool {
1554 return false
1555}
1556
Colin Cross4157e882019-06-06 16:57:04 -07001557func (m *ModuleBase) InstallInSanitizerDir() bool {
Vishwath Mohan1dd88392017-03-29 22:00:18 -07001558 return false
1559}
1560
Yifan Hong1b3348d2020-01-21 15:53:22 -08001561func (m *ModuleBase) InstallInRamdisk() bool {
1562 return Bool(m.commonProperties.Ramdisk)
1563}
1564
Yifan Hong60e0cfb2020-10-21 15:17:56 -07001565func (m *ModuleBase) InstallInVendorRamdisk() bool {
1566 return Bool(m.commonProperties.Vendor_ramdisk)
1567}
1568
Inseob Kim08758f02021-04-08 21:13:22 +09001569func (m *ModuleBase) InstallInDebugRamdisk() bool {
1570 return Bool(m.commonProperties.Debug_ramdisk)
1571}
1572
Colin Cross4157e882019-06-06 16:57:04 -07001573func (m *ModuleBase) InstallInRecovery() bool {
1574 return Bool(m.commonProperties.Recovery)
Jiyong Parkf9332f12018-02-01 00:54:12 +09001575}
1576
Colin Crossea30d852023-11-29 16:00:16 -08001577func (m *ModuleBase) InstallInOdm() bool {
1578 return false
1579}
1580
1581func (m *ModuleBase) InstallInProduct() bool {
1582 return false
1583}
1584
Kiyoung Kimae11c232021-07-19 11:38:04 +09001585func (m *ModuleBase) InstallInVendor() bool {
Kiyoung Kimf160f7f2022-11-29 10:58:08 +09001586 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Soc_specific) || Bool(m.commonProperties.Proprietary)
Kiyoung Kimae11c232021-07-19 11:38:04 +09001587}
1588
Spandan Das950deca2024-10-01 18:35:23 +00001589func (m *ModuleBase) InstallInSystemExt() bool {
1590 return Bool(m.commonProperties.System_ext_specific)
1591}
1592
Colin Cross90ba5f42019-10-02 11:10:58 -07001593func (m *ModuleBase) InstallInRoot() bool {
1594 return false
1595}
1596
Spandan Das27ff7672024-11-06 19:23:57 +00001597func (m *ModuleBase) InstallInSystemDlkm() bool {
1598 return Bool(m.commonProperties.System_dlkm_specific)
1599}
1600
1601func (m *ModuleBase) InstallInVendorDlkm() bool {
1602 return Bool(m.commonProperties.Vendor_dlkm_specific)
1603}
1604
1605func (m *ModuleBase) InstallInOdmDlkm() bool {
1606 return Bool(m.commonProperties.Odm_dlkm_specific)
1607}
1608
Jiyong Park87788b52020-09-01 12:37:45 +09001609func (m *ModuleBase) InstallForceOS() (*OsType, *ArchType) {
1610 return nil, nil
Colin Cross6e359402020-02-10 15:29:54 -08001611}
1612
Colin Cross4157e882019-06-06 16:57:04 -07001613func (m *ModuleBase) Owner() string {
1614 return String(m.commonProperties.Owner)
Sundong Ahn4fd04bb2018-08-31 18:01:37 +09001615}
1616
Ronald Braunstein73b08ff2023-12-19 10:24:47 -08001617func (m *ModuleBase) Team() string {
1618 return String(m.commonProperties.Team)
1619}
1620
Colin Cross7228ecd2019-11-18 16:00:16 -08001621func (m *ModuleBase) setImageVariation(variant string) {
1622 m.commonProperties.ImageVariation = variant
1623}
1624
1625func (m *ModuleBase) ImageVariation() blueprint.Variation {
1626 return blueprint.Variation{
1627 Mutator: "image",
1628 Variation: m.base().commonProperties.ImageVariation,
1629 }
1630}
1631
Paul Duffin9b76c0b2020-03-12 10:24:35 +00001632func (m *ModuleBase) getVariationByMutatorName(mutator string) string {
1633 for i, v := range m.commonProperties.DebugMutators {
1634 if v == mutator {
1635 return m.commonProperties.DebugVariations[i]
1636 }
1637 }
1638
1639 return ""
1640}
1641
Yifan Hong1b3348d2020-01-21 15:53:22 -08001642func (m *ModuleBase) InRamdisk() bool {
1643 return m.base().commonProperties.ImageVariation == RamdiskVariation
1644}
1645
Yifan Hong60e0cfb2020-10-21 15:17:56 -07001646func (m *ModuleBase) InVendorRamdisk() bool {
1647 return m.base().commonProperties.ImageVariation == VendorRamdiskVariation
1648}
1649
Inseob Kim08758f02021-04-08 21:13:22 +09001650func (m *ModuleBase) InDebugRamdisk() bool {
1651 return m.base().commonProperties.ImageVariation == DebugRamdiskVariation
1652}
1653
Colin Cross7228ecd2019-11-18 16:00:16 -08001654func (m *ModuleBase) InRecovery() bool {
1655 return m.base().commonProperties.ImageVariation == RecoveryVariation
1656}
1657
Cole Fauste8a87832024-09-11 11:35:46 -07001658func (m *ModuleBase) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string {
Cole Faust2239ae62025-01-27 15:32:11 -08001659 return m.base().baseProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09001660}
1661
1662func (m *ModuleBase) HostRequiredModuleNames() []string {
Cole Faust2239ae62025-01-27 15:32:11 -08001663 return m.base().baseProperties.Host_required
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09001664}
1665
1666func (m *ModuleBase) TargetRequiredModuleNames() []string {
Cole Faust2239ae62025-01-27 15:32:11 -08001667 return m.base().baseProperties.Target_required
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09001668}
1669
Cole Fauste8a87832024-09-11 11:35:46 -07001670func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string {
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001671 return m.base().commonProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
1672}
1673
Kiyoung Kim23be5bb2024-11-27 00:50:30 +00001674func (m *ModuleBase) VintfFragments(ctx ConfigurableEvaluatorContext) []string {
1675 return m.base().commonProperties.Vintf_fragments.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
1676}
1677
Colin Crossa6182ab2024-08-21 10:47:44 -07001678func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) {
1679 namespacePrefix := ctx.Namespace().id
1680 if namespacePrefix != "" {
1681 namespacePrefix = namespacePrefix + "-"
1682 }
1683
1684 if !ctx.uncheckedModule {
1685 name := namespacePrefix + ctx.ModuleName() + "-" + ctx.ModuleSubDir() + "-checkbuild"
1686 ctx.Phony(name, ctx.checkbuildFiles...)
1687 ctx.checkbuildTarget = PathForPhony(ctx, name)
1688 }
1689
1690}
1691
Cole Faust0523b8f2025-03-03 15:11:32 -08001692// generateModuleTarget generates phony targets so that you can do `m <module-name>`.
1693// It will be run on every variant of the module, so it relies on the fact that phony targets
1694// are deduped to merge all the deps from different variants together.
Yu Liuddc28332024-08-09 22:48:30 +00001695func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) {
Yu Liu460c0fa2024-08-20 19:31:15 +00001696 var namespacePrefix string
1697 nameSpace := ctx.Namespace().Path
1698 if nameSpace != "." {
1699 namespacePrefix = strings.ReplaceAll(nameSpace, "/", ".") + "-"
Jeff Gaston088e29e2017-11-29 16:47:17 -08001700 }
1701
Cole Faustc5bfbdd2025-01-08 13:05:40 -08001702 var deps Paths
Cole Faust0523b8f2025-03-03 15:11:32 -08001703 var info ModuleBuildTargetsInfo
Yu Liuddc2e1a2024-08-20 21:31:22 +00001704
Cole Faust0523b8f2025-03-03 15:11:32 -08001705 if len(ctx.installFiles) > 0 {
Colin Crossc3d87d32020-06-04 13:25:17 -07001706 name := namespacePrefix + ctx.ModuleName() + "-install"
Cole Faustd1bf2722025-03-05 10:42:50 -08001707 installFiles := ctx.installFiles.Paths()
1708 ctx.Phony(name, installFiles...)
Yu Liuddc2e1a2024-08-20 21:31:22 +00001709 info.InstallTarget = PathForPhony(ctx, name)
Cole Faustd1bf2722025-03-05 10:42:50 -08001710 deps = append(deps, installFiles...)
Colin Cross9454bfa2015-03-17 13:24:18 -07001711 }
1712
Cole Faust0523b8f2025-03-03 15:11:32 -08001713 // A module's -checkbuild phony targets should
1714 // not be created if the module is not exported to make.
1715 // Those could depend on the build target and fail to compile
1716 // for the current build target.
1717 if (!ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, m)) && !ctx.uncheckedModule && ctx.checkbuildTarget != nil {
Colin Crossc3d87d32020-06-04 13:25:17 -07001718 name := namespacePrefix + ctx.ModuleName() + "-checkbuild"
Cole Faust0523b8f2025-03-03 15:11:32 -08001719 ctx.Phony(name, ctx.checkbuildTarget)
Cole Faustd1bf2722025-03-05 10:42:50 -08001720 deps = append(deps, ctx.checkbuildTarget)
Colin Cross9454bfa2015-03-17 13:24:18 -07001721 }
1722
Cole Faust0523b8f2025-03-03 15:11:32 -08001723 if outputFiles, err := outputFilesForModule(ctx, ctx.Module(), ""); err == nil && len(outputFiles) > 0 {
Cole Faust71e3e7a2025-01-22 10:44:36 -08001724 name := namespacePrefix + ctx.ModuleName() + "-outputs"
Cole Faust0523b8f2025-03-03 15:11:32 -08001725 ctx.Phony(name, outputFiles...)
Cole Faustd1bf2722025-03-05 10:42:50 -08001726 deps = append(deps, outputFiles...)
Cole Faust71e3e7a2025-01-22 10:44:36 -08001727 }
1728
Colin Cross9454bfa2015-03-17 13:24:18 -07001729 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001730 suffix := ""
Jingwen Chencda22c92020-11-23 00:22:30 -05001731 if ctx.Config().KatiEnabled() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001732 suffix = "-soong"
1733 }
1734
Colin Crossc3d87d32020-06-04 13:25:17 -07001735 ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...)
Spandan Das25301f12025-01-24 22:22:37 +00001736 if ctx.Device() {
1737 // Generate a target suffix for use in atest etc.
1738 ctx.Phony(namespacePrefix+ctx.ModuleName()+"-target"+suffix, deps...)
Spandan Das25301f12025-01-24 22:22:37 +00001739 } else {
1740 // Generate a host suffix for use in atest etc.
1741 ctx.Phony(namespacePrefix+ctx.ModuleName()+"-host"+suffix, deps...)
Spandan Das481ec672025-01-27 19:55:52 +00001742 if ctx.Target().HostCross {
1743 // Generate a host-cross suffix for use in atest etc.
1744 ctx.Phony(namespacePrefix+ctx.ModuleName()+"-host-cross"+suffix, deps...)
1745 }
Spandan Das25301f12025-01-24 22:22:37 +00001746 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001747
Yu Liuddc2e1a2024-08-20 21:31:22 +00001748 info.BlueprintDir = ctx.ModuleDir()
Cole Faust0523b8f2025-03-03 15:11:32 -08001749 SetProvider(ctx, ModuleBuildTargetsProvider, info)
Colin Cross3f40fa42015-01-30 17:27:36 -08001750 }
1751}
1752
Cole Faust5b7635d2024-10-28 13:01:12 -07001753func determineModuleKind(m *ModuleBase, ctx ModuleErrorContext) moduleKind {
Colin Cross4157e882019-06-06 16:57:04 -07001754 var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
1755 var deviceSpecific = Bool(m.commonProperties.Device_specific)
1756 var productSpecific = Bool(m.commonProperties.Product_specific)
Justin Yund5f6c822019-06-25 16:47:17 +09001757 var systemExtSpecific = Bool(m.commonProperties.System_ext_specific)
Jiyong Park2db76922017-11-08 16:03:48 +09001758
Dario Frenifd05a742018-05-29 13:28:54 +01001759 msg := "conflicting value set here"
1760 if socSpecific && deviceSpecific {
1761 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
Colin Cross4157e882019-06-06 16:57:04 -07001762 if Bool(m.commonProperties.Vendor) {
Jiyong Park2db76922017-11-08 16:03:48 +09001763 ctx.PropertyErrorf("vendor", msg)
1764 }
Colin Cross4157e882019-06-06 16:57:04 -07001765 if Bool(m.commonProperties.Proprietary) {
Jiyong Park2db76922017-11-08 16:03:48 +09001766 ctx.PropertyErrorf("proprietary", msg)
1767 }
Colin Cross4157e882019-06-06 16:57:04 -07001768 if Bool(m.commonProperties.Soc_specific) {
Jiyong Park2db76922017-11-08 16:03:48 +09001769 ctx.PropertyErrorf("soc_specific", msg)
1770 }
1771 }
1772
Justin Yund5f6c822019-06-25 16:47:17 +09001773 if productSpecific && systemExtSpecific {
1774 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and system_ext at the same time.")
1775 ctx.PropertyErrorf("system_ext_specific", msg)
Dario Frenifd05a742018-05-29 13:28:54 +01001776 }
1777
Justin Yund5f6c822019-06-25 16:47:17 +09001778 if (socSpecific || deviceSpecific) && (productSpecific || systemExtSpecific) {
Dario Frenifd05a742018-05-29 13:28:54 +01001779 if productSpecific {
1780 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
1781 } else {
Justin Yund5f6c822019-06-25 16:47:17 +09001782 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 +01001783 }
1784 if deviceSpecific {
1785 ctx.PropertyErrorf("device_specific", msg)
1786 } else {
Colin Cross4157e882019-06-06 16:57:04 -07001787 if Bool(m.commonProperties.Vendor) {
Dario Frenifd05a742018-05-29 13:28:54 +01001788 ctx.PropertyErrorf("vendor", msg)
1789 }
Colin Cross4157e882019-06-06 16:57:04 -07001790 if Bool(m.commonProperties.Proprietary) {
Dario Frenifd05a742018-05-29 13:28:54 +01001791 ctx.PropertyErrorf("proprietary", msg)
1792 }
Colin Cross4157e882019-06-06 16:57:04 -07001793 if Bool(m.commonProperties.Soc_specific) {
Dario Frenifd05a742018-05-29 13:28:54 +01001794 ctx.PropertyErrorf("soc_specific", msg)
1795 }
1796 }
1797 }
1798
Jiyong Park2db76922017-11-08 16:03:48 +09001799 if productSpecific {
1800 return productSpecificModule
Justin Yund5f6c822019-06-25 16:47:17 +09001801 } else if systemExtSpecific {
1802 return systemExtSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +09001803 } else if deviceSpecific {
1804 return deviceSpecificModule
1805 } else if socSpecific {
1806 return socSpecificModule
1807 } else {
1808 return platformModule
1809 }
1810}
1811
Colin Crossc34d2322020-01-03 15:23:27 -08001812func (m *ModuleBase) earlyModuleContextFactory(ctx blueprint.EarlyModuleContext) earlyModuleContext {
Colin Cross1184b642019-12-30 18:43:07 -08001813 return earlyModuleContext{
Colin Crossc34d2322020-01-03 15:23:27 -08001814 EarlyModuleContext: ctx,
1815 kind: determineModuleKind(m, ctx),
1816 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -08001817 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001818}
1819
Colin Cross1184b642019-12-30 18:43:07 -08001820func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext {
1821 return baseModuleContext{
1822 bp: ctx,
Colin Cross1d3d9f12024-01-18 14:30:22 -08001823 archModuleContext: m.archModuleContextFactory(ctx),
Colin Cross1184b642019-12-30 18:43:07 -08001824 earlyModuleContext: m.earlyModuleContextFactory(ctx),
Colin Cross1184b642019-12-30 18:43:07 -08001825 }
1826}
1827
Colin Crosse1a85552024-06-14 12:17:37 -07001828type archModuleContextFactoryContext interface {
1829 Config() interface{}
1830}
1831
1832func (m *ModuleBase) archModuleContextFactory(ctx archModuleContextFactoryContext) archModuleContext {
Colin Cross1d3d9f12024-01-18 14:30:22 -08001833 config := ctx.Config().(Config)
1834 target := m.Target()
1835 primaryArch := false
1836 if len(config.Targets[target.Os]) <= 1 {
1837 primaryArch = true
1838 } else {
1839 primaryArch = target.Arch.ArchType == config.Targets[target.Os][0].Arch.ArchType
1840 }
1841
1842 return archModuleContext{
Cole Faust0aa21cc2024-03-20 12:28:03 -07001843 ready: m.commonProperties.ArchReady,
Colin Cross1d3d9f12024-01-18 14:30:22 -08001844 os: m.commonProperties.CompileOS,
1845 target: m.commonProperties.CompileTarget,
1846 targetPrimary: m.commonProperties.CompilePrimary,
1847 multiTargets: m.commonProperties.CompileMultiTargets,
1848 primaryArch: primaryArch,
1849 }
1850
1851}
1852
Yu Liuddc28332024-08-09 22:48:30 +00001853type InstallFilesInfo struct {
Colin Crossa6182ab2024-08-21 10:47:44 -07001854 InstallFiles InstallPaths
1855 CheckbuildFiles Paths
1856 CheckbuildTarget Path
1857 UncheckedModule bool
1858 PackagingSpecs []PackagingSpec
Yu Liud46e5ae2024-08-15 18:46:17 +00001859 // katiInstalls tracks the install rules that were created by Soong but are being exported
1860 // to Make to convert to ninja rules so that Make can add additional dependencies.
Yu Liuec810542024-08-26 18:09:15 +00001861 KatiInstalls katiInstalls
1862 KatiSymlinks katiInstalls
1863 TestData []DataPath
Colin Crossa14fb6a2024-10-23 16:57:06 -07001864 TransitivePackagingSpecs depset.DepSet[PackagingSpec]
Yu Liuec810542024-08-26 18:09:15 +00001865 LicenseMetadataFile WritablePath
1866
1867 // The following fields are private before, make it private again once we have
1868 // better solution.
Colin Crossa14fb6a2024-10-23 16:57:06 -07001869 TransitiveInstallFiles depset.DepSet[InstallPath]
Yu Liu82a6d142024-08-27 19:02:29 +00001870 // katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
1871 // allowed to have duplicates across modules and variants.
1872 KatiInitRcInstalls katiInstalls
1873 KatiVintfInstalls katiInstalls
1874 InitRcPaths Paths
1875 VintfFragmentsPaths Paths
1876 InstalledInitRcPaths InstallPaths
1877 InstalledVintfFragmentsPaths InstallPaths
1878
Yu Liuec810542024-08-26 18:09:15 +00001879 // The files to copy to the dist as explicitly specified in the .bp file.
1880 DistFiles TaggedDistFiles
Yu Liuddc28332024-08-09 22:48:30 +00001881}
1882
Yu Liubad1eef2024-08-21 22:37:35 +00001883var InstallFilesProvider = blueprint.NewProvider[InstallFilesInfo]()
Yu Liuddc2e1a2024-08-20 21:31:22 +00001884
Yu Liud3228ac2024-11-08 23:11:47 +00001885type SourceFilesInfo struct {
1886 Srcs Paths
1887}
1888
Yu Liuc41eae52025-01-14 01:03:08 +00001889var SourceFilesInfoProvider = blueprint.NewProvider[SourceFilesInfo]()
Yu Liud3228ac2024-11-08 23:11:47 +00001890
Cole Faust0523b8f2025-03-03 15:11:32 -08001891// ModuleBuildTargetsInfo is used by buildTargetSingleton to create checkbuild and
1892// per-directory build targets.
1893type ModuleBuildTargetsInfo struct {
Yu Liuddc2e1a2024-08-20 21:31:22 +00001894 InstallTarget WritablePath
1895 CheckbuildTarget WritablePath
1896 BlueprintDir string
1897}
1898
Cole Faust0523b8f2025-03-03 15:11:32 -08001899var ModuleBuildTargetsProvider = blueprint.NewProvider[ModuleBuildTargetsInfo]()
Yu Liuddc28332024-08-09 22:48:30 +00001900
Yu Liub5275322024-11-13 18:40:43 +00001901type CommonModuleInfo struct {
Yu Liudd9ccb42024-10-07 17:07:44 +00001902 Enabled bool
1903 // Whether the module has been replaced by a prebuilt
1904 ReplacedByPrebuilt bool
Yu Liuec7043d2024-11-05 18:22:20 +00001905 // The Target of artifacts that this module variant is responsible for creating.
Yu Liu8024b922024-12-20 23:31:32 +00001906 Target Target
Yu Liub5275322024-11-13 18:40:43 +00001907 SkipAndroidMkProcessing bool
Yu Liu63bdf632024-12-03 19:54:05 +00001908 BaseModuleName string
Yu Liub1bfa9d2024-12-05 18:57:51 +00001909 CanHaveApexVariants bool
Yu Liu5d3a2cf2025-02-06 00:25:22 +00001910 MinSdkVersion ApiLevelOrPlatform
Yu Liuf6f85492025-01-13 21:02:36 +00001911 SdkVersion string
Yu Liu8f2c5c02024-12-06 00:40:39 +00001912 NotAvailableForPlatform bool
Yu Liu8024b922024-12-20 23:31:32 +00001913 // There some subtle differences between this one and the one above.
1914 NotInPlatform bool
Yu Liu5697f8f2024-12-13 23:31:08 +00001915 // UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex
1916 // mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant
1917 // is used to avoid adding install or packaging dependencies into libraries provided
1918 // by apexes.
1919 UninstallableApexPlatformVariant bool
Yu Liudf0b8392025-02-12 18:27:03 +00001920 MinSdkVersionSupported ApiLevel
1921 ModuleWithMinSdkVersionCheck bool
Yu Liu0a37d422025-02-13 02:05:00 +00001922 // Tests if this module can be installed to APEX as a file. For example, this would return
1923 // true for shared libs while return false for static libs because static libs are not
1924 // installable module (but it can still be mutated for APEX)
1925 IsInstallableToApex bool
1926 HideFromMake bool
1927 SkipInstall bool
1928 IsStubsModule bool
1929 Host bool
1930 IsApexModule bool
Yu Liu367827f2025-02-15 00:18:33 +00001931 // The primary licenses property, may be nil, records license metadata for the module.
1932 PrimaryLicensesProperty applicableLicensesProperty
1933 Owner string
Yu Liu64371e02025-02-19 23:44:48 +00001934 Vendor bool
1935 Proprietary bool
1936 SocSpecific bool
1937 ProductSpecific bool
1938 SystemExtSpecific bool
1939 DeviceSpecific bool
1940 // When set to true, this module is not installed to the full install path (ex: under
1941 // out/target/product/<name>/<partition>). It can be installed only to the packaging
1942 // modules like android_filesystem.
1943 NoFullInstall bool
1944 InVendorRamdisk bool
1945 ExemptFromRequiredApplicableLicensesProperty bool
1946 RequiredModuleNames []string
1947 HostRequiredModuleNames []string
1948 TargetRequiredModuleNames []string
1949 VintfFragmentModuleNames []string
1950 Dists []Dist
Yu Liu2a815b62025-02-21 20:46:25 +00001951 ExportedToMake bool
Yu Liu95cef3a2025-02-25 00:54:20 +00001952 Team string
Spandan Das31769ef2025-03-06 00:49:57 +00001953 PartitionTag string
Yu Liudd9ccb42024-10-07 17:07:44 +00001954}
1955
Yu Liu5d3a2cf2025-02-06 00:25:22 +00001956type ApiLevelOrPlatform struct {
1957 ApiLevel *ApiLevel
1958 IsPlatform bool
1959}
1960
Yu Liuf22120f2025-03-13 18:36:35 +00001961var CommonModuleInfoProvider = blueprint.NewProvider[*CommonModuleInfo]()
Yu Liudd9ccb42024-10-07 17:07:44 +00001962
Yu Liu8a8d5b42025-01-07 00:48:08 +00001963type PrebuiltModuleInfo struct {
1964 SourceExists bool
Yu Liu2da9d9a2025-01-15 00:27:02 +00001965 UsePrebuilt bool
Yu Liudd9ccb42024-10-07 17:07:44 +00001966}
1967
Yu Liu8a8d5b42025-01-07 00:48:08 +00001968var PrebuiltModuleInfoProvider = blueprint.NewProvider[PrebuiltModuleInfo]()
Yu Liudd9ccb42024-10-07 17:07:44 +00001969
Yu Liu2da9d9a2025-01-15 00:27:02 +00001970type HostToolProviderInfo struct {
Yu Liudd9ccb42024-10-07 17:07:44 +00001971 HostToolPath OptionalPath
1972}
1973
Yu Liu2da9d9a2025-01-15 00:27:02 +00001974var HostToolProviderInfoProvider = blueprint.NewProvider[HostToolProviderInfo]()
Yu Liudd9ccb42024-10-07 17:07:44 +00001975
Cole Faustd62a4892025-02-07 16:55:11 -08001976type DistInfo struct {
1977 Dists []dist
1978}
1979
1980var DistProvider = blueprint.NewProvider[DistInfo]()
1981
Yu Liu8024b922024-12-20 23:31:32 +00001982type SourceFileGenerator interface {
1983 GeneratedSourceFiles() Paths
1984 GeneratedHeaderDirs() Paths
1985 GeneratedDeps() Paths
1986}
1987
1988type GeneratedSourceInfo struct {
1989 GeneratedSourceFiles Paths
1990 GeneratedHeaderDirs Paths
1991 GeneratedDeps Paths
1992}
1993
1994var GeneratedSourceInfoProvider = blueprint.NewProvider[GeneratedSourceInfo]()
1995
Colin Cross4157e882019-06-06 16:57:04 -07001996func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
Colin Cross25de6c32019-06-06 14:29:25 -07001997 ctx := &moduleContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -07001998 module: m.module,
Colin Crossdc35e212019-06-06 16:13:11 -07001999 bp: blueprintCtx,
Colin Cross0ea8ba82019-06-06 14:33:29 -07002000 baseModuleContext: m.baseModuleContextFactory(blueprintCtx),
Colin Cross0ea8ba82019-06-06 14:33:29 -07002001 variables: make(map[string]string),
Yu Liu54513622024-08-19 20:00:32 +00002002 phonies: make(map[string]Paths),
Colin Cross3f40fa42015-01-30 17:27:36 -08002003 }
2004
Jihoon Kangc3d4e112024-06-24 22:16:27 +00002005 setContainerInfo(ctx)
Jihoon Kang85bc1932024-07-01 17:04:46 +00002006 if ctx.Config().Getenv("DISABLE_CONTAINER_CHECK") != "true" {
2007 checkContainerViolations(ctx)
2008 }
Jihoon Kangc3d4e112024-06-24 22:16:27 +00002009
Yu Liuec810542024-08-26 18:09:15 +00002010 ctx.licenseMetadataFile = PathForModuleOut(ctx, "meta_lic")
Colin Crossaa1cab02022-01-28 14:49:24 -08002011
Colin Crossffe6b9d2020-12-01 15:40:06 -08002012 dependencyInstallFiles, dependencyPackagingSpecs := m.computeInstallDeps(ctx)
Yu Liubad1eef2024-08-21 22:37:35 +00002013 // set the TransitiveInstallFiles to only the transitive dependencies to be used as the dependencies
Colin Cross5d583952020-11-24 16:21:24 -08002014 // of installed files of this module. It will be replaced by a depset including the installed
2015 // files of this module at the end for use by modules that depend on this one.
Colin Crossa14fb6a2024-10-23 16:57:06 -07002016 ctx.TransitiveInstallFiles = depset.New[InstallPath](depset.TOPOLOGICAL, nil, dependencyInstallFiles)
Colin Cross5d583952020-11-24 16:21:24 -08002017
Colin Cross6c4f21f2019-06-06 15:41:36 -07002018 // Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never
2019 // reporting missing dependency errors in Blueprint when AllowMissingDependencies == true.
2020 // TODO: This will be removed once defaults modules handle missing dependency errors
2021 blueprintCtx.GetMissingDependencies()
2022
Colin Crossdc35e212019-06-06 16:13:11 -07002023 // For the final GenerateAndroidBuildActions pass, require that all visited dependencies Soong modules and
Paul Duffin1356d8c2020-02-25 19:26:33 +00002024 // are enabled. Unless the module is a CommonOS variant which may have dependencies on disabled variants
2025 // (because the dependencies are added before the modules are disabled). The
2026 // GetOsSpecificVariantsOfCommonOSVariant(...) method will ensure that the disabled variants are
2027 // ignored.
2028 ctx.baseModuleContext.strictVisitDeps = !m.IsCommonOSVariant()
Colin Crossdc35e212019-06-06 16:13:11 -07002029
Colin Cross4c83e5c2019-02-25 14:54:28 -08002030 if ctx.config.captureBuild {
2031 ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
2032 }
2033
Colin Cross67a5c132017-05-09 13:45:28 -07002034 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
2035 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -08002036 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
2037 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -07002038 }
Colin Cross0875c522017-11-28 17:34:01 -08002039 if !ctx.PrimaryArch() {
2040 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -07002041 }
Colin Crossff694a82023-12-13 15:54:49 -08002042 if apexInfo, _ := ModuleProvider(ctx, ApexInfoProvider); !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -07002043 suffix = append(suffix, apexInfo.ApexVariationName)
Dan Willemsenb13a9482020-02-14 11:25:54 -08002044 }
Colin Cross67a5c132017-05-09 13:45:28 -07002045
2046 ctx.Variable(pctx, "moduleDesc", desc)
2047
2048 s := ""
2049 if len(suffix) > 0 {
2050 s = " [" + strings.Join(suffix, " ") + "]"
2051 }
2052 ctx.Variable(pctx, "moduleDescSuffix", s)
2053
Dan Willemsen569edc52018-11-19 09:33:29 -08002054 // Some common property checks for properties that will be used later in androidmk.go
Paul Duffin89968e32020-11-23 18:17:03 +00002055 checkDistProperties(ctx, "dist", &m.distProperties.Dist)
Sasha Smundake198eaf2022-08-04 13:07:02 -07002056 for i := range m.distProperties.Dists {
Paul Duffin89968e32020-11-23 18:17:03 +00002057 checkDistProperties(ctx, fmt.Sprintf("dists[%d]", i), &m.distProperties.Dists[i])
Dan Willemsen569edc52018-11-19 09:33:29 -08002058 }
2059
Yu Liubad1eef2024-08-21 22:37:35 +00002060 var installFiles InstallFilesInfo
2061
Cole Fausta963b942024-04-11 17:43:00 -07002062 if m.Enabled(ctx) {
Jooyung Hand48f3c32019-08-23 11:18:57 +09002063 // ensure all direct android.Module deps are enabled
Yu Liu4552aeb2024-11-13 00:59:49 +00002064 ctx.VisitDirectDepsProxy(func(m ModuleProxy) {})
Jooyung Hand48f3c32019-08-23 11:18:57 +09002065
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002066 if m.Device() {
2067 // Handle any init.rc and vintf fragment files requested by the module. All files installed by this
2068 // module will automatically have a dependency on the installed init.rc or vintf fragment file.
2069 // The same init.rc or vintf fragment file may be requested by multiple modules or variants,
2070 // so instead of installing them now just compute the install path and store it for later.
2071 // The full list of all init.rc and vintf fragment install rules will be deduplicated later
2072 // so only a single rule is created for each init.rc or vintf fragment file.
2073
2074 if !m.InVendorRamdisk() {
Inseob Kim713b87d2024-09-13 11:29:54 +09002075 ctx.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc.GetOrDefault(ctx, nil))
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002076 rcDir := PathForModuleInstall(ctx, "etc", "init")
Yu Liu82a6d142024-08-27 19:02:29 +00002077 for _, src := range ctx.initRcPaths {
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002078 installedInitRc := rcDir.Join(ctx, src.Base())
Yu Liu82a6d142024-08-27 19:02:29 +00002079 ctx.katiInitRcInstalls = append(ctx.katiInitRcInstalls, katiInstall{
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002080 from: src,
2081 to: installedInitRc,
2082 })
2083 ctx.PackageFile(rcDir, src.Base(), src)
Yu Liu82a6d142024-08-27 19:02:29 +00002084 ctx.installedInitRcPaths = append(ctx.installedInitRcPaths, installedInitRc)
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002085 }
Yu Liu82a6d142024-08-27 19:02:29 +00002086 installFiles.InitRcPaths = ctx.initRcPaths
2087 installFiles.KatiInitRcInstalls = ctx.katiInitRcInstalls
2088 installFiles.InstalledInitRcPaths = ctx.installedInitRcPaths
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002089 }
2090
Yu Liu82a6d142024-08-27 19:02:29 +00002091 ctx.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments.GetOrDefault(ctx, nil))
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002092 vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest")
Yu Liu82a6d142024-08-27 19:02:29 +00002093 for _, src := range ctx.vintfFragmentsPaths {
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002094 installedVintfFragment := vintfDir.Join(ctx, src.Base())
Yu Liu82a6d142024-08-27 19:02:29 +00002095 ctx.katiVintfInstalls = append(ctx.katiVintfInstalls, katiInstall{
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002096 from: src,
2097 to: installedVintfFragment,
2098 })
2099 ctx.PackageFile(vintfDir, src.Base(), src)
Yu Liu82a6d142024-08-27 19:02:29 +00002100 ctx.installedVintfFragmentsPaths = append(ctx.installedVintfFragmentsPaths, installedVintfFragment)
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002101 }
Yu Liu82a6d142024-08-27 19:02:29 +00002102 installFiles.VintfFragmentsPaths = ctx.vintfFragmentsPaths
2103 installFiles.KatiVintfInstalls = ctx.katiVintfInstalls
2104 installFiles.InstalledVintfFragmentsPaths = ctx.installedVintfFragmentsPaths
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002105 }
2106
Bob Badour37af0462021-01-07 03:34:31 +00002107 licensesPropertyFlattener(ctx)
2108 if ctx.Failed() {
2109 return
2110 }
2111
Joe Onorato349ae8d2024-02-05 22:46:00 +00002112 if jarJarPrefixHandler != nil {
2113 jarJarPrefixHandler(ctx)
2114 if ctx.Failed() {
2115 return
2116 }
2117 }
2118
Justin Yun40182b62024-05-07 10:22:19 +09002119 // Call aconfigUpdateAndroidBuildActions to collect merged aconfig files before being used
2120 // in m.module.GenerateAndroidBuildActions
2121 aconfigUpdateAndroidBuildActions(ctx)
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002122 if ctx.Failed() {
2123 return
2124 }
2125
Yu Liu26a716d2024-08-30 23:40:32 +00002126 m.module.GenerateAndroidBuildActions(ctx)
2127 if ctx.Failed() {
2128 return
Yu Liufa297642024-06-11 00:13:02 +00002129 }
2130
Yu Liu26a716d2024-08-30 23:40:32 +00002131 if x, ok := m.module.(IDEInfo); ok {
2132 var result IdeInfo
2133 x.IDEInfo(ctx, &result)
2134 result.BaseModuleName = x.BaseModuleName()
2135 SetProvider(ctx, IdeInfoProviderKey, result)
LaMont Jonesb5099382024-01-10 23:42:36 +00002136 }
2137
Paul Duffinaf970a22020-11-23 23:32:56 +00002138 // Create the set of tagged dist files after calling GenerateAndroidBuildActions
2139 // as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
2140 // output paths being set which must be done before or during
2141 // GenerateAndroidBuildActions.
Yu Liuec810542024-08-26 18:09:15 +00002142 installFiles.DistFiles = m.GenerateTaggedDistFiles(ctx)
Paul Duffinaf970a22020-11-23 23:32:56 +00002143 if ctx.Failed() {
2144 return
2145 }
2146
Colin Crossa6182ab2024-08-21 10:47:44 -07002147 m.generateVariantTarget(ctx)
2148
Yu Liuec810542024-08-26 18:09:15 +00002149 installFiles.LicenseMetadataFile = ctx.licenseMetadataFile
Yu Liubad1eef2024-08-21 22:37:35 +00002150 installFiles.InstallFiles = ctx.installFiles
2151 installFiles.CheckbuildFiles = ctx.checkbuildFiles
Colin Crossa6182ab2024-08-21 10:47:44 -07002152 installFiles.CheckbuildTarget = ctx.checkbuildTarget
2153 installFiles.UncheckedModule = ctx.uncheckedModule
Yu Liubad1eef2024-08-21 22:37:35 +00002154 installFiles.PackagingSpecs = ctx.packagingSpecs
2155 installFiles.KatiInstalls = ctx.katiInstalls
2156 installFiles.KatiSymlinks = ctx.katiSymlinks
2157 installFiles.TestData = ctx.testData
Colin Crossdc35e212019-06-06 16:13:11 -07002158 } else if ctx.Config().AllowMissingDependencies() {
2159 // If the module is not enabled it will not create any build rules, nothing will call
2160 // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
2161 // and report them as an error even when AllowMissingDependencies = true. Call
2162 // ctx.GetMissingDependencies() here to tell blueprint not to handle them.
2163 ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08002164 }
2165
Yu Liud3228ac2024-11-08 23:11:47 +00002166 if sourceFileProducer, ok := m.module.(SourceFileProducer); ok {
Cole Faust0523b8f2025-03-03 15:11:32 -08002167 srcs := sourceFileProducer.Srcs()
2168 for _, src := range srcs {
2169 if src == nil {
2170 ctx.ModuleErrorf("SourceFileProducer cannot return nil srcs")
2171 return
2172 }
2173 }
Yu Liuc41eae52025-01-14 01:03:08 +00002174 SetProvider(ctx, SourceFilesInfoProvider, SourceFilesInfo{Srcs: sourceFileProducer.Srcs()})
Yu Liud3228ac2024-11-08 23:11:47 +00002175 }
2176
Cole Faust0523b8f2025-03-03 15:11:32 -08002177 m.generateModuleTarget(ctx)
2178 if ctx.Failed() {
2179 return
Colin Cross3f40fa42015-01-30 17:27:36 -08002180 }
Colin Crosscec81712017-07-13 14:43:27 -07002181
Colin Crossa14fb6a2024-10-23 16:57:06 -07002182 ctx.TransitiveInstallFiles = depset.New[InstallPath](depset.TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles)
Yu Liubad1eef2024-08-21 22:37:35 +00002183 installFiles.TransitiveInstallFiles = ctx.TransitiveInstallFiles
Colin Crossa14fb6a2024-10-23 16:57:06 -07002184 installFiles.TransitivePackagingSpecs = depset.New[PackagingSpec](depset.TOPOLOGICAL, ctx.packagingSpecs, dependencyPackagingSpecs)
Colin Cross5d583952020-11-24 16:21:24 -08002185
Yu Liubad1eef2024-08-21 22:37:35 +00002186 SetProvider(ctx, InstallFilesProvider, installFiles)
Yu Liuec810542024-08-26 18:09:15 +00002187 buildLicenseMetadata(ctx, ctx.licenseMetadataFile)
Colin Cross4acaea92021-12-10 23:05:02 +00002188
Jihoon Kangd4063812025-01-24 00:25:30 +00002189 if len(ctx.moduleInfoJSON) > 0 {
2190 for _, moduleInfoJSON := range ctx.moduleInfoJSON {
2191 if moduleInfoJSON.Disabled {
2192 continue
2193 }
2194 var installed InstallPaths
2195 installed = append(installed, ctx.katiInstalls.InstallPaths()...)
2196 installed = append(installed, ctx.katiSymlinks.InstallPaths()...)
2197 installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...)
2198 installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...)
2199 installedStrings := installed.Strings()
Colin Crossd6fd0132023-11-06 13:54:06 -08002200
Jihoon Kangd4063812025-01-24 00:25:30 +00002201 var targetRequired, hostRequired []string
2202 if ctx.Host() {
2203 targetRequired = m.baseProperties.Target_required
2204 } else {
2205 hostRequired = m.baseProperties.Host_required
2206 }
Cole Faust156085b2025-03-04 11:34:55 -08002207 hostRequired = append(hostRequired, moduleInfoJSON.ExtraHostRequired...)
Colin Crossd6fd0132023-11-06 13:54:06 -08002208
Jihoon Kangd4063812025-01-24 00:25:30 +00002209 var data []string
2210 for _, d := range ctx.testData {
2211 data = append(data, d.ToRelativeInstallPath())
2212 }
Colin Crossd6fd0132023-11-06 13:54:06 -08002213
Jihoon Kangd4063812025-01-24 00:25:30 +00002214 if moduleInfoJSON.Uninstallable {
2215 installedStrings = nil
2216 if len(moduleInfoJSON.CompatibilitySuites) == 1 && moduleInfoJSON.CompatibilitySuites[0] == "null-suite" {
2217 moduleInfoJSON.CompatibilitySuites = nil
2218 moduleInfoJSON.TestConfig = nil
2219 moduleInfoJSON.AutoTestConfig = nil
2220 data = nil
2221 }
2222 }
2223
2224 // M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}.
2225 // To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite,
2226 // we add the full test suite to our list. This was inherited from
2227 // AndroidMkEntries.AddCompatibilityTestSuites.
2228 suites := moduleInfoJSON.CompatibilitySuites
2229 if PrefixInList(suites, "mts-") && !InList("mts", suites) {
2230 suites = append(suites, "mts")
2231 }
2232 if PrefixInList(suites, "mcts-") && !InList("mcts", suites) {
2233 suites = append(suites, "mcts")
2234 }
2235 moduleInfoJSON.CompatibilitySuites = suites
2236
2237 required := append(m.RequiredModuleNames(ctx), m.VintfFragmentModuleNames(ctx)...)
2238 required = append(required, moduleInfoJSON.ExtraRequired...)
2239
2240 registerName := moduleInfoJSON.RegisterNameOverride
2241 if len(registerName) == 0 {
2242 registerName = m.moduleInfoRegisterName(ctx, moduleInfoJSON.SubName)
2243 }
2244
2245 moduleName := moduleInfoJSON.ModuleNameOverride
2246 if len(moduleName) == 0 {
2247 moduleName = m.BaseModuleName() + moduleInfoJSON.SubName
2248 }
2249
2250 supportedVariants := moduleInfoJSON.SupportedVariantsOverride
2251 if moduleInfoJSON.SupportedVariantsOverride == nil {
2252 supportedVariants = []string{m.moduleInfoVariant(ctx)}
2253 }
2254
2255 moduleInfoJSON.core = CoreModuleInfoJSON{
2256 RegisterName: registerName,
2257 Path: []string{ctx.ModuleDir()},
2258 Installed: installedStrings,
2259 ModuleName: moduleName,
2260 SupportedVariants: supportedVariants,
2261 TargetDependencies: targetRequired,
2262 HostDependencies: hostRequired,
2263 Data: data,
2264 Required: required,
Colin Crossd6fd0132023-11-06 13:54:06 -08002265 }
2266 }
2267
Yu Liu4297ad92024-08-27 19:50:13 +00002268 SetProvider(ctx, ModuleInfoJSONProvider, ctx.moduleInfoJSON)
Colin Crossd6fd0132023-11-06 13:54:06 -08002269 }
2270
Colin Cross4157e882019-06-06 16:57:04 -07002271 m.buildParams = ctx.buildParams
2272 m.ruleParams = ctx.ruleParams
2273 m.variables = ctx.variables
mrziwange6c85812024-05-22 14:36:09 -07002274
Yu Liu876b7ce2024-08-21 18:20:13 +00002275 outputFiles := ctx.GetOutputFiles()
2276 if outputFiles.DefaultOutputFiles != nil || outputFiles.TaggedOutputFiles != nil {
2277 SetProvider(ctx, OutputFilesProvider, outputFiles)
mrziwange6c85812024-05-22 14:36:09 -07002278 }
Wei Lia1aa2972024-06-21 13:08:51 -07002279
Yu Liu54513622024-08-19 20:00:32 +00002280 if len(ctx.phonies) > 0 {
2281 SetProvider(ctx, ModulePhonyProvider, ModulePhonyInfo{
2282 Phonies: ctx.phonies,
2283 })
2284 }
Cole Faustd62a4892025-02-07 16:55:11 -08002285
2286 if len(ctx.dists) > 0 {
2287 SetProvider(ctx, DistProvider, DistInfo{
2288 Dists: ctx.dists,
2289 })
2290 }
2291
Wei Lia1aa2972024-06-21 13:08:51 -07002292 buildComplianceMetadataProvider(ctx, m)
Yu Liudd9ccb42024-10-07 17:07:44 +00002293
Yu Liub5275322024-11-13 18:40:43 +00002294 commonData := CommonModuleInfo{
Yu Liu367827f2025-02-15 00:18:33 +00002295 Enabled: m.Enabled(ctx),
Yu Liu5697f8f2024-12-13 23:31:08 +00002296 ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt,
Yu Liu8024b922024-12-20 23:31:32 +00002297 Target: m.commonProperties.CompileTarget,
Yu Liu5697f8f2024-12-13 23:31:08 +00002298 SkipAndroidMkProcessing: shouldSkipAndroidMkProcessing(ctx, m),
Yu Liu5697f8f2024-12-13 23:31:08 +00002299 UninstallableApexPlatformVariant: m.commonProperties.UninstallableApexPlatformVariant,
2300 HideFromMake: m.commonProperties.HideFromMake,
2301 SkipInstall: m.commonProperties.SkipInstall,
Yu Liu68a70b72025-01-08 22:54:44 +00002302 Host: m.Host(),
Yu Liu367827f2025-02-15 00:18:33 +00002303 PrimaryLicensesProperty: m.primaryLicensesProperty,
Yu Liu64371e02025-02-19 23:44:48 +00002304 Owner: m.module.Owner(),
2305 SocSpecific: Bool(m.commonProperties.Soc_specific),
2306 Vendor: Bool(m.commonProperties.Vendor),
2307 Proprietary: Bool(m.commonProperties.Proprietary),
2308 ProductSpecific: Bool(m.commonProperties.Product_specific),
2309 SystemExtSpecific: Bool(m.commonProperties.System_ext_specific),
2310 DeviceSpecific: Bool(m.commonProperties.Device_specific),
2311 NoFullInstall: proptools.Bool(m.commonProperties.No_full_install),
2312 InVendorRamdisk: m.InVendorRamdisk(),
2313 ExemptFromRequiredApplicableLicensesProperty: exemptFromRequiredApplicableLicensesProperty(m.module),
2314 RequiredModuleNames: m.module.RequiredModuleNames(ctx),
2315 HostRequiredModuleNames: m.module.HostRequiredModuleNames(),
2316 TargetRequiredModuleNames: m.module.TargetRequiredModuleNames(),
2317 VintfFragmentModuleNames: m.module.VintfFragmentModuleNames(ctx),
2318 Dists: m.Dists(),
Yu Liu2a815b62025-02-21 20:46:25 +00002319 ExportedToMake: m.ExportedToMake(),
Yu Liu95cef3a2025-02-25 00:54:20 +00002320 Team: m.Team(),
Spandan Das31769ef2025-03-06 00:49:57 +00002321 PartitionTag: m.PartitionTag(ctx.DeviceConfig()),
Yu Liudd9ccb42024-10-07 17:07:44 +00002322 }
Yu Liu8f2c5c02024-12-06 00:40:39 +00002323 if mm, ok := m.module.(interface {
2324 MinSdkVersion(ctx EarlyModuleContext) ApiLevel
2325 }); ok {
2326 ver := mm.MinSdkVersion(ctx)
Yu Liu5d3a2cf2025-02-06 00:25:22 +00002327 commonData.MinSdkVersion.ApiLevel = &ver
Yu Liu8f2c5c02024-12-06 00:40:39 +00002328 } else if mm, ok := m.module.(interface{ MinSdkVersion() string }); ok {
Yu Liu5d3a2cf2025-02-06 00:25:22 +00002329 ver := mm.MinSdkVersion()
2330 // Compile against the current platform
2331 if ver == "" {
2332 commonData.MinSdkVersion.IsPlatform = true
2333 } else {
2334 api := ApiLevelFrom(ctx, ver)
2335 commonData.MinSdkVersion.ApiLevel = &api
2336 }
Yu Liu8f2c5c02024-12-06 00:40:39 +00002337 }
2338
Yu Liuf6f85492025-01-13 21:02:36 +00002339 if mm, ok := m.module.(interface {
2340 SdkVersion(ctx EarlyModuleContext) ApiLevel
2341 }); ok {
2342 ver := mm.SdkVersion(ctx)
2343 if !ver.IsNone() {
2344 commonData.SdkVersion = ver.String()
2345 }
2346 } else if mm, ok := m.module.(interface{ SdkVersion() string }); ok {
2347 commonData.SdkVersion = mm.SdkVersion()
2348 }
2349
Yu Liu8f2c5c02024-12-06 00:40:39 +00002350 if am, ok := m.module.(ApexModule); ok {
2351 commonData.CanHaveApexVariants = am.CanHaveApexVariants()
2352 commonData.NotAvailableForPlatform = am.NotAvailableForPlatform()
Yu Liu8024b922024-12-20 23:31:32 +00002353 commonData.NotInPlatform = am.NotInPlatform()
Yu Liudf0b8392025-02-12 18:27:03 +00002354 commonData.MinSdkVersionSupported = am.MinSdkVersionSupported(ctx)
Yu Liu0a37d422025-02-13 02:05:00 +00002355 commonData.IsInstallableToApex = am.IsInstallableToApex()
2356 commonData.IsApexModule = true
Yu Liu8f2c5c02024-12-06 00:40:39 +00002357 }
Yu Liudf0b8392025-02-12 18:27:03 +00002358
2359 if _, ok := m.module.(ModuleWithMinSdkVersionCheck); ok {
2360 commonData.ModuleWithMinSdkVersionCheck = true
2361 }
2362
Yu Liu97880e12025-01-07 19:03:34 +00002363 if st, ok := m.module.(StubsAvailableModule); ok {
2364 commonData.IsStubsModule = st.IsStubsModule()
2365 }
Yu Liu0a37d422025-02-13 02:05:00 +00002366 if mm, ok := m.module.(interface{ BaseModuleName() string }); ok {
2367 commonData.BaseModuleName = mm.BaseModuleName()
2368 }
Yu Liuf22120f2025-03-13 18:36:35 +00002369 SetProvider(ctx, CommonModuleInfoProvider, &commonData)
Yu Liudd9ccb42024-10-07 17:07:44 +00002370 if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil {
Yu Liu8a8d5b42025-01-07 00:48:08 +00002371 SetProvider(ctx, PrebuiltModuleInfoProvider, PrebuiltModuleInfo{
2372 SourceExists: p.Prebuilt().SourceExists(),
Yu Liu2da9d9a2025-01-15 00:27:02 +00002373 UsePrebuilt: p.Prebuilt().UsePrebuilt(),
Yu Liu8a8d5b42025-01-07 00:48:08 +00002374 })
Yu Liudd9ccb42024-10-07 17:07:44 +00002375 }
2376 if h, ok := m.module.(HostToolProvider); ok {
Yu Liu2da9d9a2025-01-15 00:27:02 +00002377 SetProvider(ctx, HostToolProviderInfoProvider, HostToolProviderInfo{
Yu Liudd9ccb42024-10-07 17:07:44 +00002378 HostToolPath: h.HostToolPath()})
2379 }
Yu Liue70976d2024-10-15 20:45:35 +00002380
Yu Liub5275322024-11-13 18:40:43 +00002381 if p, ok := m.module.(AndroidMkProviderInfoProducer); ok && !commonData.SkipAndroidMkProcessing {
Yu Liue70976d2024-10-15 20:45:35 +00002382 SetProvider(ctx, AndroidMkInfoProvider, p.PrepareAndroidMKProviderInfo(ctx.Config()))
2383 }
Yu Liu8024b922024-12-20 23:31:32 +00002384
2385 if s, ok := m.module.(SourceFileGenerator); ok {
2386 SetProvider(ctx, GeneratedSourceInfoProvider, GeneratedSourceInfo{
2387 GeneratedSourceFiles: s.GeneratedSourceFiles(),
2388 GeneratedHeaderDirs: s.GeneratedHeaderDirs(),
2389 GeneratedDeps: s.GeneratedDeps(),
2390 })
2391 }
Yu Liu2a815b62025-02-21 20:46:25 +00002392
Yu Liu71f1ea32025-02-26 23:39:20 +00002393 if m.Enabled(ctx) {
2394 if v, ok := m.module.(ModuleMakeVarsProvider); ok {
2395 SetProvider(ctx, ModuleMakeVarsInfoProvider, v.MakeVars(ctx))
2396 }
2397
2398 if am, ok := m.module.(AndroidMkDataProvider); ok {
2399 SetProvider(ctx, AndroidMkDataInfoProvider, AndroidMkDataInfo{
2400 Class: am.AndroidMk().Class,
2401 })
2402 }
Yu Liu2a815b62025-02-21 20:46:25 +00002403 }
Colin Crossb790b9c2025-03-19 14:12:09 -07002404
2405 m.module.CleanupAfterBuildActions()
Colin Cross3f40fa42015-01-30 17:27:36 -08002406}
2407
Colin Crossb790b9c2025-03-19 14:12:09 -07002408func (m *ModuleBase) CleanupAfterBuildActions() {}
2409
Joe Onorato349ae8d2024-02-05 22:46:00 +00002410func SetJarJarPrefixHandler(handler func(ModuleContext)) {
2411 if jarJarPrefixHandler != nil {
2412 panic("jarJarPrefixHandler already set")
2413 }
2414 jarJarPrefixHandler = handler
2415}
2416
Colin Crossd6fd0132023-11-06 13:54:06 -08002417func (m *ModuleBase) moduleInfoRegisterName(ctx ModuleContext, subName string) string {
2418 name := m.BaseModuleName()
2419
2420 prefix := ""
2421 if ctx.Host() {
2422 if ctx.Os() != ctx.Config().BuildOS {
2423 prefix = "host_cross_"
2424 }
2425 }
2426 suffix := ""
2427 arches := slices.Clone(ctx.Config().Targets[ctx.Os()])
2428 arches = slices.DeleteFunc(arches, func(target Target) bool {
2429 return target.NativeBridge != ctx.Target().NativeBridge
2430 })
Cole Faust866ab392025-01-23 12:56:20 -08002431 if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType && ctx.Arch().ArchType != Common {
Colin Crossd6fd0132023-11-06 13:54:06 -08002432 if ctx.Arch().ArchType.Multilib == "lib32" {
2433 suffix = "_32"
2434 } else {
2435 suffix = "_64"
2436 }
2437 }
2438 return prefix + name + subName + suffix
2439}
2440
2441func (m *ModuleBase) moduleInfoVariant(ctx ModuleContext) string {
2442 variant := "DEVICE"
2443 if ctx.Host() {
2444 if ctx.Os() != ctx.Config().BuildOS {
2445 variant = "HOST_CROSS"
2446 } else {
2447 variant = "HOST"
2448 }
2449 }
2450 return variant
2451}
2452
Paul Duffin89968e32020-11-23 18:17:03 +00002453// Check the supplied dist structure to make sure that it is valid.
2454//
2455// property - the base property, e.g. dist or dists[1], which is combined with the
2456// name of the nested property to produce the full property, e.g. dist.dest or
2457// dists[1].dir.
2458func checkDistProperties(ctx *moduleContext, property string, dist *Dist) {
2459 if dist.Dest != nil {
2460 _, err := validateSafePath(*dist.Dest)
2461 if err != nil {
2462 ctx.PropertyErrorf(property+".dest", "%s", err.Error())
2463 }
2464 }
2465 if dist.Dir != nil {
2466 _, err := validateSafePath(*dist.Dir)
2467 if err != nil {
2468 ctx.PropertyErrorf(property+".dir", "%s", err.Error())
2469 }
2470 }
2471 if dist.Suffix != nil {
2472 if strings.Contains(*dist.Suffix, "/") {
2473 ctx.PropertyErrorf(property+".suffix", "Suffix may not contain a '/' character.")
2474 }
2475 }
2476
2477}
2478
Colin Cross6301c3c2021-09-28 17:40:21 -07002479// katiInstall stores a request from Soong to Make to create an install rule.
2480type katiInstall struct {
2481 from Path
2482 to InstallPath
2483 implicitDeps Paths
2484 orderOnlyDeps Paths
2485 executable bool
Colin Cross50ed1f92021-11-12 17:41:02 -08002486 extraFiles *extraFilesZip
Yu Liu467d7c52024-09-18 21:54:44 +00002487 absFrom string
Colin Cross6301c3c2021-09-28 17:40:21 -07002488}
2489
Yu Liu467d7c52024-09-18 21:54:44 +00002490type katiInstallGob struct {
2491 From Path
2492 To InstallPath
2493 ImplicitDeps Paths
2494 OrderOnlyDeps Paths
2495 Executable bool
2496 ExtraFiles *extraFilesZip
2497 AbsFrom string
Yu Liu26a716d2024-08-30 23:40:32 +00002498}
2499
Yu Liu467d7c52024-09-18 21:54:44 +00002500func (k *katiInstall) ToGob() *katiInstallGob {
2501 return &katiInstallGob{
2502 From: k.from,
2503 To: k.to,
2504 ImplicitDeps: k.implicitDeps,
2505 OrderOnlyDeps: k.orderOnlyDeps,
2506 Executable: k.executable,
2507 ExtraFiles: k.extraFiles,
2508 AbsFrom: k.absFrom,
Yu Liu26a716d2024-08-30 23:40:32 +00002509 }
Yu Liu467d7c52024-09-18 21:54:44 +00002510}
Yu Liu26a716d2024-08-30 23:40:32 +00002511
Yu Liu467d7c52024-09-18 21:54:44 +00002512func (k *katiInstall) FromGob(data *katiInstallGob) {
2513 k.from = data.From
2514 k.to = data.To
2515 k.implicitDeps = data.ImplicitDeps
2516 k.orderOnlyDeps = data.OrderOnlyDeps
2517 k.executable = data.Executable
2518 k.extraFiles = data.ExtraFiles
2519 k.absFrom = data.AbsFrom
2520}
2521
2522func (k *katiInstall) GobEncode() ([]byte, error) {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002523 return gobtools.CustomGobEncode[katiInstallGob](k)
Yu Liu467d7c52024-09-18 21:54:44 +00002524}
2525
2526func (k *katiInstall) GobDecode(data []byte) error {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002527 return gobtools.CustomGobDecode[katiInstallGob](data, k)
Yu Liu26a716d2024-08-30 23:40:32 +00002528}
2529
Colin Cross50ed1f92021-11-12 17:41:02 -08002530type extraFilesZip struct {
2531 zip Path
2532 dir InstallPath
2533}
2534
Yu Liu467d7c52024-09-18 21:54:44 +00002535type extraFilesZipGob struct {
2536 Zip Path
2537 Dir InstallPath
Yu Liu26a716d2024-08-30 23:40:32 +00002538}
2539
Yu Liu467d7c52024-09-18 21:54:44 +00002540func (e *extraFilesZip) ToGob() *extraFilesZipGob {
2541 return &extraFilesZipGob{
2542 Zip: e.zip,
2543 Dir: e.dir,
Yu Liu26a716d2024-08-30 23:40:32 +00002544 }
Yu Liu467d7c52024-09-18 21:54:44 +00002545}
Yu Liu26a716d2024-08-30 23:40:32 +00002546
Yu Liu467d7c52024-09-18 21:54:44 +00002547func (e *extraFilesZip) FromGob(data *extraFilesZipGob) {
2548 e.zip = data.Zip
2549 e.dir = data.Dir
2550}
2551
2552func (e *extraFilesZip) GobEncode() ([]byte, error) {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002553 return gobtools.CustomGobEncode[extraFilesZipGob](e)
Yu Liu467d7c52024-09-18 21:54:44 +00002554}
2555
2556func (e *extraFilesZip) GobDecode(data []byte) error {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002557 return gobtools.CustomGobDecode[extraFilesZipGob](data, e)
Yu Liu26a716d2024-08-30 23:40:32 +00002558}
2559
Colin Cross6301c3c2021-09-28 17:40:21 -07002560type katiInstalls []katiInstall
2561
2562// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
2563// space separated list of from:to tuples.
2564func (installs katiInstalls) BuiltInstalled() string {
2565 sb := strings.Builder{}
2566 for i, install := range installs {
2567 if i != 0 {
2568 sb.WriteRune(' ')
2569 }
2570 sb.WriteString(install.from.String())
2571 sb.WriteRune(':')
2572 sb.WriteString(install.to.String())
2573 }
2574 return sb.String()
2575}
2576
2577// InstallPaths returns the install path of each entry.
2578func (installs katiInstalls) InstallPaths() InstallPaths {
2579 paths := make(InstallPaths, 0, len(installs))
2580 for _, install := range installs {
2581 paths = append(paths, install.to)
2582 }
2583 return paths
2584}
2585
Jiyong Park5baac542018-08-28 09:55:37 +09002586// Makes this module a platform module, i.e. not specific to soc, device,
Justin Yund5f6c822019-06-25 16:47:17 +09002587// product, or system_ext.
Colin Cross4157e882019-06-06 16:57:04 -07002588func (m *ModuleBase) MakeAsPlatform() {
2589 m.commonProperties.Vendor = boolPtr(false)
2590 m.commonProperties.Proprietary = boolPtr(false)
2591 m.commonProperties.Soc_specific = boolPtr(false)
2592 m.commonProperties.Product_specific = boolPtr(false)
Justin Yund5f6c822019-06-25 16:47:17 +09002593 m.commonProperties.System_ext_specific = boolPtr(false)
Jiyong Park5baac542018-08-28 09:55:37 +09002594}
2595
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09002596func (m *ModuleBase) MakeAsSystemExt() {
Jooyung Han91df2082019-11-20 01:49:42 +09002597 m.commonProperties.Vendor = boolPtr(false)
2598 m.commonProperties.Proprietary = boolPtr(false)
2599 m.commonProperties.Soc_specific = boolPtr(false)
2600 m.commonProperties.Product_specific = boolPtr(false)
2601 m.commonProperties.System_ext_specific = boolPtr(true)
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09002602}
2603
Jooyung Han344d5432019-08-23 11:17:39 +09002604// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true"
2605func (m *ModuleBase) IsNativeBridgeSupported() bool {
2606 return proptools.Bool(m.commonProperties.Native_bridge_supported)
2607}
2608
Jihoon Kang0d545b82024-10-11 00:21:57 +00002609func (m *ModuleBase) DecodeMultilib(ctx ConfigContext) (string, string) {
2610 return decodeMultilib(ctx, m)
2611}
2612
Spandan Dase1860e42024-10-24 22:29:50 +00002613func (m *ModuleBase) Overrides() []string {
2614 return m.commonProperties.Overrides
2615}
2616
Justin Yunbe6f81d2024-12-17 21:15:59 +09002617func (m *ModuleBase) UseGenericConfig() bool {
2618 return proptools.Bool(m.commonProperties.Use_generic_config)
2619}
2620
Colin Cross8bbc3d52024-09-11 15:33:54 -07002621type ConfigContext interface {
2622 Config() Config
2623}
2624
Cole Fauste8a87832024-09-11 11:35:46 -07002625type ConfigurableEvaluatorContext interface {
Cole Faust55b56fe2024-08-23 12:06:11 -07002626 OtherModuleProviderContext
Cole Faust02987bd2024-03-21 17:58:43 -07002627 Config() Config
2628 OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{})
Cole Faustd7067092024-09-13 13:37:59 -07002629 HasMutatorFinished(mutatorName string) bool
Cole Faust02987bd2024-03-21 17:58:43 -07002630}
2631
2632type configurationEvalutor struct {
Cole Fauste8a87832024-09-11 11:35:46 -07002633 ctx ConfigurableEvaluatorContext
Cole Faust02987bd2024-03-21 17:58:43 -07002634 m Module
2635}
2636
Cole Fauste8a87832024-09-11 11:35:46 -07002637func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator {
Cole Faust02987bd2024-03-21 17:58:43 -07002638 return configurationEvalutor{
2639 ctx: ctx,
2640 m: m.module,
2641 }
2642}
2643
2644func (e configurationEvalutor) PropertyErrorf(property string, fmt string, args ...interface{}) {
Cole Fausta963b942024-04-11 17:43:00 -07002645 e.ctx.OtherModulePropertyErrorf(e.m, property, fmt, args...)
Cole Faust02987bd2024-03-21 17:58:43 -07002646}
2647
Cole Faustfdbf5d42024-04-10 15:01:23 -07002648func (e configurationEvalutor) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue {
Cole Faust02987bd2024-03-21 17:58:43 -07002649 ctx := e.ctx
2650 m := e.m
Cole Faustd7067092024-09-13 13:37:59 -07002651
2652 if !ctx.HasMutatorFinished("defaults") {
2653 ctx.OtherModulePropertyErrorf(m, property, "Cannot evaluate configurable property before the defaults mutator has run")
2654 return proptools.ConfigurableValueUndefined()
2655 }
2656
Cole Faust8afc5142024-04-26 16:30:19 -07002657 switch condition.FunctionName() {
Cole Fauste19f7412024-05-09 15:14:04 -07002658 case "release_flag":
Cole Faust8afc5142024-04-26 16:30:19 -07002659 if condition.NumArgs() != 1 {
Cole Fauste19f7412024-05-09 15:14:04 -07002660 ctx.OtherModulePropertyErrorf(m, property, "release_flag requires 1 argument, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002661 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002662 }
Cole Faust751a4a52024-05-21 16:51:59 -07002663 if ty, ok := ctx.Config().productVariables.BuildFlagTypes[condition.Arg(0)]; ok {
2664 v := ctx.Config().productVariables.BuildFlags[condition.Arg(0)]
2665 switch ty {
2666 case "unspecified", "obsolete":
2667 return proptools.ConfigurableValueUndefined()
2668 case "string":
2669 return proptools.ConfigurableValueString(v)
2670 case "bool":
2671 return proptools.ConfigurableValueBool(v == "true")
2672 default:
2673 panic("unhandled release flag type: " + ty)
2674 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002675 }
2676 return proptools.ConfigurableValueUndefined()
2677 case "product_variable":
Jiyong Parke3250752024-05-17 14:56:10 +09002678 if condition.NumArgs() != 1 {
2679 ctx.OtherModulePropertyErrorf(m, property, "product_variable requires 1 argument, found %d", condition.NumArgs())
2680 return proptools.ConfigurableValueUndefined()
2681 }
2682 variable := condition.Arg(0)
2683 switch variable {
Jihoon Kang82bea762024-09-30 18:50:54 +00002684 case "build_from_text_stub":
2685 return proptools.ConfigurableValueBool(ctx.Config().BuildFromTextStub())
Jiyong Parke3250752024-05-17 14:56:10 +09002686 case "debuggable":
2687 return proptools.ConfigurableValueBool(ctx.Config().Debuggable())
kellyhungf833fba2025-01-14 10:05:46 +00002688 case "eng":
2689 return proptools.ConfigurableValueBool(ctx.Config().Eng())
Kiyoung Kim881e4652024-07-08 11:02:23 +09002690 case "use_debug_art":
2691 // TODO(b/234351700): Remove once ART does not have separated debug APEX
2692 return proptools.ConfigurableValueBool(ctx.Config().UseDebugArt())
kellyhung1e613d22024-07-29 12:56:51 +00002693 case "selinux_ignore_neverallows":
2694 return proptools.ConfigurableValueBool(ctx.Config().SelinuxIgnoreNeverallows())
Spandan Dasdd604262025-03-14 18:27:33 +00002695 case "always_use_prebuilt_sdks":
2696 return proptools.ConfigurableValueBool(ctx.Config().AlwaysUsePrebuiltSdks())
Jiyong Parke3250752024-05-17 14:56:10 +09002697 default:
2698 // TODO(b/323382414): Might add these on a case-by-case basis
2699 ctx.OtherModulePropertyErrorf(m, property, fmt.Sprintf("TODO(b/323382414): Product variable %q is not yet supported in selects", variable))
2700 return proptools.ConfigurableValueUndefined()
2701 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002702 case "soong_config_variable":
Cole Faust8afc5142024-04-26 16:30:19 -07002703 if condition.NumArgs() != 2 {
2704 ctx.OtherModulePropertyErrorf(m, property, "soong_config_variable requires 2 arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002705 return proptools.ConfigurableValueUndefined()
2706 }
Cole Faust8afc5142024-04-26 16:30:19 -07002707 namespace := condition.Arg(0)
2708 variable := condition.Arg(1)
Cole Faust02987bd2024-03-21 17:58:43 -07002709 if n, ok := ctx.Config().productVariables.VendorVars[namespace]; ok {
2710 if v, ok := n[variable]; ok {
Cole Faust46f6e2f2024-06-20 12:57:43 -07002711 ty := ""
2712 if namespaces, ok := ctx.Config().productVariables.VendorVarTypes[namespace]; ok {
2713 ty = namespaces[variable]
2714 }
2715 switch ty {
2716 case "":
2717 // strings are the default, we don't bother writing them to the soong variables json file
2718 return proptools.ConfigurableValueString(v)
2719 case "bool":
2720 return proptools.ConfigurableValueBool(v == "true")
Cole Faust764aaca2025-03-18 11:24:39 -07002721 case "int":
2722 i, err := strconv.ParseInt(v, 10, 64)
2723 if err != nil {
2724 ctx.OtherModulePropertyErrorf(m, property, "integer soong_config_variable was not an int: %q", v)
2725 return proptools.ConfigurableValueUndefined()
2726 }
2727 return proptools.ConfigurableValueInt(i)
Cole Faust4143ee82024-11-21 11:20:06 -08002728 case "string_list":
2729 return proptools.ConfigurableValueStringList(strings.Split(v, " "))
Cole Faust46f6e2f2024-06-20 12:57:43 -07002730 default:
2731 panic("unhandled soong config variable type: " + ty)
2732 }
2733
Cole Faust02987bd2024-03-21 17:58:43 -07002734 }
2735 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002736 return proptools.ConfigurableValueUndefined()
Cole Faustfc57d402024-04-11 12:09:44 -07002737 case "arch":
Cole Faust8afc5142024-04-26 16:30:19 -07002738 if condition.NumArgs() != 0 {
2739 ctx.OtherModulePropertyErrorf(m, property, "arch requires no arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002740 return proptools.ConfigurableValueUndefined()
2741 }
Cole Faustfc57d402024-04-11 12:09:44 -07002742 if !m.base().ArchReady() {
2743 ctx.OtherModulePropertyErrorf(m, property, "A select on arch was attempted before the arch mutator ran")
2744 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002745 }
Cole Faustfc57d402024-04-11 12:09:44 -07002746 return proptools.ConfigurableValueString(m.base().Arch().ArchType.Name)
2747 case "os":
Cole Faust8afc5142024-04-26 16:30:19 -07002748 if condition.NumArgs() != 0 {
2749 ctx.OtherModulePropertyErrorf(m, property, "os requires no arguments, found %d", condition.NumArgs())
Cole Faustfc57d402024-04-11 12:09:44 -07002750 return proptools.ConfigurableValueUndefined()
2751 }
2752 // the arch mutator runs after the os mutator, we can just use this to enforce that os is ready.
2753 if !m.base().ArchReady() {
2754 ctx.OtherModulePropertyErrorf(m, property, "A select on os was attempted before the arch mutator ran (arch runs after os, we use it to lazily detect that os is ready)")
2755 return proptools.ConfigurableValueUndefined()
2756 }
2757 return proptools.ConfigurableValueString(m.base().Os().Name)
Cole Faustfdbf5d42024-04-10 15:01:23 -07002758 case "boolean_var_for_testing":
2759 // We currently don't have any other boolean variables (we should add support for typing
2760 // the soong config variables), so add this fake one for testing the boolean select
2761 // functionality.
Cole Faust8afc5142024-04-26 16:30:19 -07002762 if condition.NumArgs() != 0 {
2763 ctx.OtherModulePropertyErrorf(m, property, "boolean_var_for_testing requires 0 arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002764 return proptools.ConfigurableValueUndefined()
2765 }
2766
2767 if n, ok := ctx.Config().productVariables.VendorVars["boolean_var"]; ok {
2768 if v, ok := n["for_testing"]; ok {
2769 switch v {
2770 case "true":
2771 return proptools.ConfigurableValueBool(true)
2772 case "false":
2773 return proptools.ConfigurableValueBool(false)
2774 default:
2775 ctx.OtherModulePropertyErrorf(m, property, "testing:my_boolean_var can only be true or false, found %q", v)
2776 }
2777 }
2778 }
2779 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002780 default:
Cole Faustfdbf5d42024-04-10 15:01:23 -07002781 ctx.OtherModulePropertyErrorf(m, property, "Unknown select condition %s", condition.FunctionName)
2782 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002783 }
2784}
2785
Colin Crossb63d7b32023-12-07 16:54:51 -08002786// ModuleNameWithPossibleOverride returns the name of the OverrideModule that overrides the current
2787// variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule
2788// or if this variant is not overridden.
2789func ModuleNameWithPossibleOverride(ctx BaseModuleContext) string {
2790 if overridable, ok := ctx.Module().(OverridableModule); ok {
2791 if o := overridable.GetOverriddenBy(); o != "" {
2792 return o
2793 }
2794 }
2795 return ctx.ModuleName()
2796}
2797
Paul Duffine6ba0722021-07-12 20:12:12 +01002798// SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name"
2799// into the module name, or empty string if the input was not a module reference.
Colin Cross41955e82019-05-29 14:40:35 -07002800func SrcIsModule(s string) (module string) {
Paul Duffine6ba0722021-07-12 20:12:12 +01002801 if len(s) > 1 {
2802 if s[0] == ':' {
2803 module = s[1:]
2804 if !isUnqualifiedModuleName(module) {
2805 // The module name should be unqualified but is not so do not treat it as a module.
2806 module = ""
2807 }
2808 } else if s[0] == '/' && s[1] == '/' {
2809 module = s
2810 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002811 }
Paul Duffine6ba0722021-07-12 20:12:12 +01002812 return module
Colin Cross068e0fe2016-12-13 15:23:47 -08002813}
2814
Yi-Yo Chiangba9ea322021-07-15 17:18:21 +08002815// SrcIsModuleWithTag decodes module references in the format ":unqualified-name{.tag}" or
2816// "//namespace:name{.tag}" into the module name and tag, ":unqualified-name" or "//namespace:name"
2817// into the module name and an empty string for the tag, or empty strings if the input was not a
2818// module reference.
Colin Cross41955e82019-05-29 14:40:35 -07002819func SrcIsModuleWithTag(s string) (module, tag string) {
Paul Duffine6ba0722021-07-12 20:12:12 +01002820 if len(s) > 1 {
2821 if s[0] == ':' {
2822 module = s[1:]
2823 } else if s[0] == '/' && s[1] == '/' {
2824 module = s
2825 }
2826
2827 if module != "" {
2828 if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
2829 if module[len(module)-1] == '}' {
2830 tag = module[tagStart+1 : len(module)-1]
2831 module = module[:tagStart]
2832 }
2833 }
2834
2835 if s[0] == ':' && !isUnqualifiedModuleName(module) {
2836 // The module name should be unqualified but is not so do not treat it as a module.
2837 module = ""
2838 tag = ""
Colin Cross41955e82019-05-29 14:40:35 -07002839 }
2840 }
Colin Cross41955e82019-05-29 14:40:35 -07002841 }
Paul Duffine6ba0722021-07-12 20:12:12 +01002842
2843 return module, tag
2844}
2845
2846// isUnqualifiedModuleName makes sure that the supplied module is an unqualified module name, i.e.
2847// does not contain any /.
2848func isUnqualifiedModuleName(module string) bool {
2849 return strings.IndexByte(module, '/') == -1
Colin Cross068e0fe2016-12-13 15:23:47 -08002850}
2851
Paul Duffin40131a32021-07-09 17:10:35 +01002852// sourceOrOutputDependencyTag is the dependency tag added automatically by pathDepsMutator for any
2853// module reference in a property annotated with `android:"path"` or passed to ExtractSourceDeps
2854// or ExtractSourcesDeps.
2855//
2856// If uniquely identifies the dependency that was added as it contains both the module name used to
2857// add the dependency as well as the tag. That makes it very simple to find the matching dependency
2858// in GetModuleFromPathDep as all it needs to do is find the dependency whose tag matches the tag
2859// used to add it. It does not need to check that the module name as returned by one of
2860// Module.Name(), BaseModuleContext.OtherModuleName() or ModuleBase.BaseModuleName() matches the
2861// name supplied in the tag. That means it does not need to handle differences in module names
2862// caused by prebuilt_ prefix, or fully qualified module names.
Colin Cross41955e82019-05-29 14:40:35 -07002863type sourceOrOutputDependencyTag struct {
2864 blueprint.BaseDependencyTag
Yu Liu67a28422024-03-05 00:36:31 +00002865 AlwaysPropagateAconfigValidationDependencyTag
Paul Duffin40131a32021-07-09 17:10:35 +01002866
2867 // The name of the module.
2868 moduleName string
2869
mrziwangd38e63d2024-07-15 13:43:37 -07002870 // The tag that will be used to get the specific output file(s).
Colin Cross41955e82019-05-29 14:40:35 -07002871 tag string
2872}
2873
Paul Duffin40131a32021-07-09 17:10:35 +01002874func sourceOrOutputDepTag(moduleName, tag string) blueprint.DependencyTag {
2875 return sourceOrOutputDependencyTag{moduleName: moduleName, tag: tag}
Colin Cross41955e82019-05-29 14:40:35 -07002876}
2877
Paul Duffind5cf92e2021-07-09 17:38:55 +01002878// IsSourceDepTagWithOutputTag returns true if the supplied blueprint.DependencyTag is one that was
2879// used to add dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for
2880// properties tagged with `android:"path"` AND it was added using a module reference of
2881// :moduleName{outputTag}.
2882func IsSourceDepTagWithOutputTag(depTag blueprint.DependencyTag, outputTag string) bool {
2883 t, ok := depTag.(sourceOrOutputDependencyTag)
2884 return ok && t.tag == outputTag
2885}
2886
Colin Cross366938f2017-12-11 16:29:02 -08002887// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
2888// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08002889//
2890// Deprecated: tag the property with `android:"path"` instead.
Colin Cross068e0fe2016-12-13 15:23:47 -08002891func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
Nan Zhang2439eb72017-04-10 11:27:50 -07002892 set := make(map[string]bool)
2893
Colin Cross068e0fe2016-12-13 15:23:47 -08002894 for _, s := range srcFiles {
Colin Cross41955e82019-05-29 14:40:35 -07002895 if m, t := SrcIsModuleWithTag(s); m != "" {
2896 if _, found := set[s]; found {
2897 ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
Nan Zhang2439eb72017-04-10 11:27:50 -07002898 } else {
Colin Cross41955e82019-05-29 14:40:35 -07002899 set[s] = true
Paul Duffin40131a32021-07-09 17:10:35 +01002900 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
Nan Zhang2439eb72017-04-10 11:27:50 -07002901 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002902 }
2903 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002904}
2905
Colin Cross366938f2017-12-11 16:29:02 -08002906// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
2907// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08002908//
2909// Deprecated: tag the property with `android:"path"` instead.
Colin Cross366938f2017-12-11 16:29:02 -08002910func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
2911 if s != nil {
Colin Cross41955e82019-05-29 14:40:35 -07002912 if m, t := SrcIsModuleWithTag(*s); m != "" {
Paul Duffin40131a32021-07-09 17:10:35 +01002913 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
Colin Cross366938f2017-12-11 16:29:02 -08002914 }
2915 }
2916}
2917
Colin Cross41955e82019-05-29 14:40:35 -07002918// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"`
2919// 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 -08002920type SourceFileProducer interface {
2921 Srcs() Paths
2922}
2923
mrziwangd38e63d2024-07-15 13:43:37 -07002924// OutputFilesForModule returns the output file paths with the given tag. On error, including if the
Colin Cross5e708052019-08-06 13:59:50 -07002925// module produced zero paths, it reports errors to the ctx and returns nil.
Yu Liud3228ac2024-11-08 23:11:47 +00002926func OutputFilesForModule(ctx PathContext, module Module, tag string) Paths {
Colin Cross5e708052019-08-06 13:59:50 -07002927 paths, err := outputFilesForModule(ctx, module, tag)
2928 if err != nil {
2929 reportPathError(ctx, err)
2930 return nil
2931 }
2932 return paths
2933}
2934
mrziwangd38e63d2024-07-15 13:43:37 -07002935// OutputFileForModule returns the output file paths with the given tag. On error, including if the
Colin Cross5e708052019-08-06 13:59:50 -07002936// module produced zero or multiple paths, it reports errors to the ctx and returns nil.
Yu Liu2a815b62025-02-21 20:46:25 +00002937// TODO(b/397766191): Change the signature to take ModuleProxy
2938// Please only access the module's internal data through providers.
Yu Liud3228ac2024-11-08 23:11:47 +00002939func OutputFileForModule(ctx PathContext, module Module, tag string) Path {
Colin Cross5e708052019-08-06 13:59:50 -07002940 paths, err := outputFilesForModule(ctx, module, tag)
2941 if err != nil {
2942 reportPathError(ctx, err)
2943 return nil
2944 }
Colin Cross14ec66c2022-10-03 21:02:27 -07002945 if len(paths) == 0 {
2946 type addMissingDependenciesIntf interface {
2947 AddMissingDependencies([]string)
2948 OtherModuleName(blueprint.Module) string
2949 }
2950 if mctx, ok := ctx.(addMissingDependenciesIntf); ok && ctx.Config().AllowMissingDependencies() {
2951 mctx.AddMissingDependencies([]string{mctx.OtherModuleName(module)})
2952 } else {
2953 ReportPathErrorf(ctx, "failed to get output files from module %q", pathContextName(ctx, module))
2954 }
2955 // Return a fake output file to avoid nil dereferences of Path objects later.
2956 // This should never get used for an actual build as the error or missing
2957 // dependency has already been reported.
2958 p, err := pathForSource(ctx, filepath.Join("missing_output_file", pathContextName(ctx, module)))
2959 if err != nil {
2960 reportPathError(ctx, err)
2961 return nil
2962 }
2963 return p
2964 }
Colin Cross5e708052019-08-06 13:59:50 -07002965 if len(paths) > 1 {
Ulya Trafimovich5ab276a2020-08-25 12:45:15 +01002966 ReportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
Colin Cross5e708052019-08-06 13:59:50 -07002967 pathContextName(ctx, module))
Colin Cross5e708052019-08-06 13:59:50 -07002968 }
2969 return paths[0]
2970}
2971
Yu Liud3228ac2024-11-08 23:11:47 +00002972type OutputFilesProviderModuleContext interface {
2973 OtherModuleProviderContext
2974 Module() Module
2975 GetOutputFiles() OutputFilesInfo
Yu Liud3228ac2024-11-08 23:11:47 +00002976}
2977
Yu Liu2a815b62025-02-21 20:46:25 +00002978// TODO(b/397766191): Change the signature to take ModuleProxy
2979// Please only access the module's internal data through providers.
Yu Liud3228ac2024-11-08 23:11:47 +00002980func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, error) {
mrziwange6c85812024-05-22 14:36:09 -07002981 outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag)
mrziwangabdb2932024-06-18 12:43:41 -07002982 if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet {
mrziwange6c85812024-05-22 14:36:09 -07002983 return outputFilesFromProvider, err
2984 }
Yu Liud3228ac2024-11-08 23:11:47 +00002985
2986 if octx, ok := ctx.(OutputFilesProviderModuleContext); ok {
Yu Liue472c1d2025-02-26 20:13:04 +00002987 if EqualModules(octx.Module(), module) {
Yu Liu5697f8f2024-12-13 23:31:08 +00002988 // It is the current module, we can access the srcs through interface
Yu Liud3228ac2024-11-08 23:11:47 +00002989 if sourceFileProducer, ok := module.(SourceFileProducer); ok {
2990 return sourceFileProducer.Srcs(), nil
2991 }
Yu Liuc41eae52025-01-14 01:03:08 +00002992 } else if sourceFiles, ok := OtherModuleProvider(octx, module, SourceFilesInfoProvider); ok {
Yu Liud3228ac2024-11-08 23:11:47 +00002993 if tag != "" {
2994 return nil, fmt.Errorf("module %q is a SourceFileProducer, which does not support tag %q", pathContextName(ctx, module), tag)
2995 }
2996 paths := sourceFiles.Srcs
2997 return paths, nil
Colin Cross74b1e2b2020-11-22 20:23:02 -08002998 }
Colin Cross5e708052019-08-06 13:59:50 -07002999 }
Yu Liud3228ac2024-11-08 23:11:47 +00003000
3001 return nil, fmt.Errorf("module %q is not a SourceFileProducer or having valid output file for tag %q", pathContextName(ctx, module), tag)
Colin Cross5e708052019-08-06 13:59:50 -07003002}
3003
mrziwange6c85812024-05-22 14:36:09 -07003004// This method uses OutputFilesProvider for output files
3005// *inter-module-communication*.
3006// If mctx module is the same as the param module the output files are obtained
3007// from outputFiles property of module base, to avoid both setting and
mrziwang42953592024-06-20 09:53:33 -07003008// reading OutputFilesProvider before GenerateBuildActions is finished.
mrziwange6c85812024-05-22 14:36:09 -07003009// If a module doesn't have the OutputFilesProvider, nil is returned.
Yu Liud3228ac2024-11-08 23:11:47 +00003010func outputFilesForModuleFromProvider(ctx PathContext, module Module, tag string) (Paths, error) {
mrziwangabdb2932024-06-18 12:43:41 -07003011 var outputFiles OutputFilesInfo
mrziwang0cbd3b02024-06-20 16:39:25 -07003012
mrziwang1ea01e32024-07-12 12:26:34 -07003013 if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx {
Yu Liue472c1d2025-02-26 20:13:04 +00003014 if !EqualModules(mctx.Module(), module) {
mrziwangabdb2932024-06-18 12:43:41 -07003015 outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider)
mrziwang0cbd3b02024-06-20 16:39:25 -07003016 } else {
Yu Liu876b7ce2024-08-21 18:20:13 +00003017 outputFiles = mctx.GetOutputFiles()
mrziwange6c85812024-05-22 14:36:09 -07003018 }
mrziwang0cbd3b02024-06-20 16:39:25 -07003019 } else if cta, isCta := ctx.(*singletonContextAdaptor); isCta {
Yu Liud3228ac2024-11-08 23:11:47 +00003020 outputFiles, _ = OtherModuleProvider(cta, module, OutputFilesProvider)
mrziwang7a47bd32024-07-17 11:11:05 -07003021 } else {
3022 return nil, fmt.Errorf("unsupported context %q in method outputFilesForModuleFromProvider", reflect.TypeOf(ctx))
mrziwang0cbd3b02024-06-20 16:39:25 -07003023 }
mrziwang0cbd3b02024-06-20 16:39:25 -07003024
mrziwangabdb2932024-06-18 12:43:41 -07003025 if outputFiles.isEmpty() {
mrziwangabdb2932024-06-18 12:43:41 -07003026 return nil, OutputFilesProviderNotSet
3027 }
3028
3029 if tag == "" {
3030 return outputFiles.DefaultOutputFiles, nil
3031 } else if taggedOutputFiles, hasTag := outputFiles.TaggedOutputFiles[tag]; hasTag {
3032 return taggedOutputFiles, nil
3033 } else {
Cole Fausta8437c52025-02-25 14:45:43 -08003034 return nil, UnsupportedOutputTagError{
3035 tag: tag,
mrziwange6c85812024-05-22 14:36:09 -07003036 }
3037 }
mrziwange6c85812024-05-22 14:36:09 -07003038}
3039
mrziwang0cbd3b02024-06-20 16:39:25 -07003040func (o OutputFilesInfo) isEmpty() bool {
3041 return o.DefaultOutputFiles == nil && o.TaggedOutputFiles == nil
3042}
3043
mrziwange6c85812024-05-22 14:36:09 -07003044type OutputFilesInfo struct {
3045 // default output files when tag is an empty string ""
3046 DefaultOutputFiles Paths
3047
3048 // the corresponding output files for given tags
3049 TaggedOutputFiles map[string]Paths
3050}
3051
3052var OutputFilesProvider = blueprint.NewProvider[OutputFilesInfo]()
3053
Cole Fausta8437c52025-02-25 14:45:43 -08003054type UnsupportedOutputTagError struct {
3055 tag string
3056}
3057
3058func (u UnsupportedOutputTagError) Error() string {
3059 return fmt.Sprintf("unsupported output tag %q", u.tag)
3060}
3061
3062func (u UnsupportedOutputTagError) Is(e error) bool {
3063 _, ok := e.(UnsupportedOutputTagError)
3064 return ok
3065}
3066
3067var _ error = UnsupportedOutputTagError{}
3068
mrziwangabdb2932024-06-18 12:43:41 -07003069// This is used to mark the case where OutputFilesProvider is not set on some modules.
3070var OutputFilesProviderNotSet = fmt.Errorf("No output files from provider")
Cole Fausta8437c52025-02-25 14:45:43 -08003071var ErrUnsupportedOutputTag = UnsupportedOutputTagError{}
mrziwangabdb2932024-06-18 12:43:41 -07003072
Colin Cross41589502020-12-01 14:00:21 -08003073// Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to
3074// specify that they can be used as a tool by a genrule module.
Colin Crossfe17f6f2019-03-28 19:30:56 -07003075type HostToolProvider interface {
Colin Crossba9e4032020-11-24 16:32:22 -08003076 Module
Colin Cross41589502020-12-01 14:00:21 -08003077 // HostToolPath returns the path to the host tool for the module if it is one, or an invalid
3078 // OptionalPath.
Colin Crossfe17f6f2019-03-28 19:30:56 -07003079 HostToolPath() OptionalPath
3080}
3081
Colin Cross463a90e2015-06-17 14:20:06 -07003082func init() {
LaMont Jones0c10e4d2023-05-16 00:58:37 +00003083 RegisterParallelSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07003084}
3085
Colin Cross0875c522017-11-28 17:34:01 -08003086func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07003087 return &buildTargetSingleton{}
3088}
3089
Colin Cross87d8b562017-04-25 10:01:55 -07003090func parentDir(dir string) string {
3091 dir, _ = filepath.Split(dir)
3092 return filepath.Clean(dir)
3093}
3094
Colin Cross1f8c52b2015-06-16 16:38:17 -07003095type buildTargetSingleton struct{}
3096
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003097func AddAncestors(ctx SingletonContext, dirMap map[string]Paths, mmName func(string) string) ([]string, []string) {
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003098 // Ensure ancestor directories are in dirMap
3099 // Make directories build their direct subdirectories
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003100 // Returns a slice of all directories and a slice of top-level directories.
Cole Faust18994c72023-02-28 16:02:16 -08003101 dirs := SortedKeys(dirMap)
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003102 for _, dir := range dirs {
3103 dir := parentDir(dir)
3104 for dir != "." && dir != "/" {
3105 if _, exists := dirMap[dir]; exists {
3106 break
3107 }
3108 dirMap[dir] = nil
3109 dir = parentDir(dir)
3110 }
3111 }
Cole Faust18994c72023-02-28 16:02:16 -08003112 dirs = SortedKeys(dirMap)
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003113 var topDirs []string
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003114 for _, dir := range dirs {
3115 p := parentDir(dir)
3116 if p != "." && p != "/" {
3117 dirMap[p] = append(dirMap[p], PathForPhony(ctx, mmName(dir)))
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003118 } else if dir != "." && dir != "/" && dir != "" {
3119 topDirs = append(topDirs, dir)
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003120 }
3121 }
Cole Faust18994c72023-02-28 16:02:16 -08003122 return SortedKeys(dirMap), topDirs
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003123}
3124
Colin Cross0875c522017-11-28 17:34:01 -08003125func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
3126 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07003127
LaMont Jones825f8ff2025-02-12 11:52:00 -08003128 // Create a top level partialcompileclean target for modules to add dependencies to.
3129 ctx.Phony("partialcompileclean")
3130
Colin Crossc3d87d32020-06-04 13:25:17 -07003131 mmTarget := func(dir string) string {
3132 return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
Colin Cross87d8b562017-04-25 10:01:55 -07003133 }
3134
Colin Cross0875c522017-11-28 17:34:01 -08003135 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003136
Yu Liu2a815b62025-02-21 20:46:25 +00003137 ctx.VisitAllModuleProxies(func(module ModuleProxy) {
Cole Faust0523b8f2025-03-03 15:11:32 -08003138 info := OtherModuleProviderOrDefault(ctx, module, ModuleBuildTargetsProvider)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003139
Yu Liuddc2e1a2024-08-20 21:31:22 +00003140 if info.CheckbuildTarget != nil {
3141 checkbuildDeps = append(checkbuildDeps, info.CheckbuildTarget)
3142 modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.CheckbuildTarget)
Colin Cross0875c522017-11-28 17:34:01 -08003143 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07003144
Yu Liuddc2e1a2024-08-20 21:31:22 +00003145 if info.InstallTarget != nil {
3146 modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.InstallTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003147 }
3148 })
3149
Dan Willemsen5ba07e82015-12-11 13:51:06 -08003150 suffix := ""
Jingwen Chencda22c92020-11-23 00:22:30 -05003151 if ctx.Config().KatiEnabled() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08003152 suffix = "-soong"
3153 }
3154
Colin Cross1f8c52b2015-06-16 16:38:17 -07003155 // Create a top-level checkbuild target that depends on all modules
Colin Crossc3d87d32020-06-04 13:25:17 -07003156 ctx.Phony("checkbuild"+suffix, checkbuildDeps...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003157
Dan Willemsend2e95fb2017-09-20 14:30:50 -07003158 // Make will generate the MODULES-IN-* targets
Jingwen Chencda22c92020-11-23 00:22:30 -05003159 if ctx.Config().KatiEnabled() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07003160 return
3161 }
3162
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003163 dirs, _ := AddAncestors(ctx, modulesInDir, mmTarget)
Colin Cross87d8b562017-04-25 10:01:55 -07003164
Dan Willemsend2e95fb2017-09-20 14:30:50 -07003165 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
3166 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
3167 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07003168 for _, dir := range dirs {
Colin Crossc3d87d32020-06-04 13:25:17 -07003169 ctx.Phony(mmTarget(dir), modulesInDir[dir]...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003170 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07003171
3172 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
Jiyong Park1613e552020-09-14 19:43:17 +09003173 type osAndCross struct {
3174 os OsType
3175 hostCross bool
3176 }
3177 osDeps := map[osAndCross]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08003178 ctx.VisitAllModules(func(module Module) {
Cole Fausta963b942024-04-11 17:43:00 -07003179 if module.Enabled(ctx) {
Jiyong Park1613e552020-09-14 19:43:17 +09003180 key := osAndCross{os: module.Target().Os, hostCross: module.Target().HostCross}
Yu Liud46e5ae2024-08-15 18:46:17 +00003181 osDeps[key] = append(osDeps[key], OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).CheckbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07003182 }
3183 })
3184
Colin Cross0875c522017-11-28 17:34:01 -08003185 osClass := make(map[string]Paths)
Jiyong Park1613e552020-09-14 19:43:17 +09003186 for key, deps := range osDeps {
Dan Willemsen61d88b82017-09-20 17:29:08 -07003187 var className string
3188
Jiyong Park1613e552020-09-14 19:43:17 +09003189 switch key.os.Class {
Dan Willemsen61d88b82017-09-20 17:29:08 -07003190 case Host:
Jiyong Park1613e552020-09-14 19:43:17 +09003191 if key.hostCross {
3192 className = "host-cross"
3193 } else {
3194 className = "host"
3195 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07003196 case Device:
3197 className = "target"
3198 default:
3199 continue
3200 }
3201
Jiyong Park1613e552020-09-14 19:43:17 +09003202 name := className + "-" + key.os.Name
Colin Crossc3d87d32020-06-04 13:25:17 -07003203 osClass[className] = append(osClass[className], PathForPhony(ctx, name))
Dan Willemsen61d88b82017-09-20 17:29:08 -07003204
Colin Crossc3d87d32020-06-04 13:25:17 -07003205 ctx.Phony(name, deps...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07003206 }
3207
3208 // Wrap those into host|host-cross|target phony rules
Cole Faust18994c72023-02-28 16:02:16 -08003209 for _, class := range SortedKeys(osClass) {
Colin Crossc3d87d32020-06-04 13:25:17 -07003210 ctx.Phony(class, osClass[class]...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07003211 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07003212}
Colin Crossd779da42015-12-17 18:00:23 -08003213
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003214// Collect information for opening IDE project files in java/jdeps.go.
3215type IDEInfo interface {
Cole Faustb36d31d2024-08-27 16:04:28 -07003216 IDEInfo(ctx BaseModuleContext, ideInfo *IdeInfo)
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003217 BaseModuleName() string
3218}
3219
Cole Faust08c7f862024-08-27 15:03:59 -07003220// Collect information for opening IDE project files in java/jdeps.go.
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003221type IdeInfo struct {
Cole Faust08c7f862024-08-27 15:03:59 -07003222 BaseModuleName string `json:"-"`
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003223 Deps []string `json:"dependencies,omitempty"`
3224 Srcs []string `json:"srcs,omitempty"`
3225 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
3226 Jarjar_rules []string `json:"jarjar_rules,omitempty"`
3227 Jars []string `json:"jars,omitempty"`
3228 Classes []string `json:"class,omitempty"`
3229 Installed_paths []string `json:"installed,omitempty"`
patricktu18c82ff2019-05-10 15:48:50 +08003230 SrcJars []string `json:"srcjars,omitempty"`
bralee1fbf4402020-05-21 10:11:59 +08003231 Paths []string `json:"path,omitempty"`
Yikef6282022022-04-13 20:41:01 +08003232 Static_libs []string `json:"static_libs,omitempty"`
3233 Libs []string `json:"libs,omitempty"`
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003234}
Paul Duffinf88d8e02020-05-07 20:21:34 +01003235
Cole Faust08c7f862024-08-27 15:03:59 -07003236// Merge merges two IdeInfos and produces a new one, leaving the origional unchanged
3237func (i IdeInfo) Merge(other IdeInfo) IdeInfo {
3238 return IdeInfo{
3239 Deps: mergeStringLists(i.Deps, other.Deps),
3240 Srcs: mergeStringLists(i.Srcs, other.Srcs),
3241 Aidl_include_dirs: mergeStringLists(i.Aidl_include_dirs, other.Aidl_include_dirs),
3242 Jarjar_rules: mergeStringLists(i.Jarjar_rules, other.Jarjar_rules),
3243 Jars: mergeStringLists(i.Jars, other.Jars),
3244 Classes: mergeStringLists(i.Classes, other.Classes),
3245 Installed_paths: mergeStringLists(i.Installed_paths, other.Installed_paths),
3246 SrcJars: mergeStringLists(i.SrcJars, other.SrcJars),
3247 Paths: mergeStringLists(i.Paths, other.Paths),
3248 Static_libs: mergeStringLists(i.Static_libs, other.Static_libs),
3249 Libs: mergeStringLists(i.Libs, other.Libs),
3250 }
3251}
3252
3253// mergeStringLists appends the two string lists together and returns a new string list,
3254// leaving the originals unchanged. Duplicate strings will be deduplicated.
3255func mergeStringLists(a, b []string) []string {
3256 return FirstUniqueStrings(Concat(a, b))
3257}
3258
3259var IdeInfoProviderKey = blueprint.NewProvider[IdeInfo]()
3260
Paul Duffinf88d8e02020-05-07 20:21:34 +01003261func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error {
3262 bpctx := ctx.blueprintBaseModuleContext()
3263 return blueprint.CheckBlueprintSyntax(bpctx.ModuleFactories(), filename, contents)
3264}