blob: c0abfd0a3d2e849c06761cfeef0ce8a8d285993d [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
Paul Duffin74f05592020-11-25 16:37:46 +0000211 // A string tag to select the OutputFiles associated with the tag.
212 //
213 // If no tag is specified then it will select the default dist paths provided
214 // by the module type. If a tag of "" is specified then it will return the
215 // default output files provided by the modules, i.e. the result of calling
216 // OutputFiles("").
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000217 Tag *string `android:"arch_variant"`
218}
219
Bob Badour4101c712022-02-09 11:54:35 -0800220// NamedPath associates a path with a name. e.g. a license text path with a package name
221type NamedPath struct {
222 Path Path
223 Name string
224}
225
226// String returns an escaped string representing the `NamedPath`.
227func (p NamedPath) String() string {
228 if len(p.Name) > 0 {
229 return p.Path.String() + ":" + url.QueryEscape(p.Name)
230 }
231 return p.Path.String()
232}
233
234// NamedPaths describes a list of paths each associated with a name.
235type NamedPaths []NamedPath
236
237// Strings returns a list of escaped strings representing each `NamedPath` in the list.
238func (l NamedPaths) Strings() []string {
239 result := make([]string, 0, len(l))
240 for _, p := range l {
241 result = append(result, p.String())
242 }
243 return result
244}
245
246// SortedUniqueNamedPaths modifies `l` in place to return the sorted unique subset.
247func SortedUniqueNamedPaths(l NamedPaths) NamedPaths {
248 if len(l) == 0 {
249 return l
250 }
251 sort.Slice(l, func(i, j int) bool {
252 return l[i].String() < l[j].String()
253 })
254 k := 0
255 for i := 1; i < len(l); i++ {
256 if l[i].String() == l[k].String() {
257 continue
258 }
259 k++
260 if k < i {
261 l[k] = l[i]
262 }
263 }
264 return l[:k+1]
265}
266
Colin Crossfc754582016-05-17 16:34:16 -0700267type nameProperties struct {
268 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800269 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700270}
271
Cole Faust2239ae62025-01-27 15:32:11 -0800272// Properties common to all modules inheriting from ModuleBase. These properties are automatically
273// inherited by sub-modules created with ctx.CreateModule()
Colin Cross08d6f8f2020-11-19 02:33:19 +0000274type commonProperties struct {
Dan Willemsen0effe062015-11-30 16:06:01 -0800275 // emit build rules for this module
Paul Duffin54d9bb72020-02-12 10:20:56 +0000276 //
277 // Disabling a module should only be done for those modules that cannot be built
278 // in the current environment. Modules that can build in the current environment
279 // but are not usually required (e.g. superceded by a prebuilt) should not be
280 // disabled as that will prevent them from being built by the checkbuild target
281 // and so prevent early detection of changes that have broken those modules.
Cole Fausta963b942024-04-11 17:43:00 -0700282 Enabled proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800283
Paul Duffin2e61fa62019-03-28 14:10:57 +0000284 // Controls the visibility of this module to other modules. Allowable values are one or more of
285 // these formats:
286 //
287 // ["//visibility:public"]: Anyone can use this module.
288 // ["//visibility:private"]: Only rules in the module's package (not its subpackages) can use
289 // this module.
Paul Duffin51084ff2020-05-05 19:19:22 +0100290 // ["//visibility:override"]: Discards any rules inherited from defaults or a creating module.
291 // Can only be used at the beginning of a list of visibility rules.
Paul Duffin2e61fa62019-03-28 14:10:57 +0000292 // ["//some/package:__pkg__", "//other/package:__pkg__"]: Only modules in some/package and
293 // other/package (defined in some/package/*.bp and other/package/*.bp) have access to
294 // this module. Note that sub-packages do not have access to the rule; for example,
295 // //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__
296 // is a special module and must be used verbatim. It represents all of the modules in the
297 // package.
298 // ["//project:__subpackages__", "//other:__subpackages__"]: Only modules in packages project
299 // or other or in one of their sub-packages have access to this module. For example,
300 // //project:rule, //project/library:lib or //other/testing/internal:munge are allowed
301 // to depend on this rule (but not //independent:evil)
302 // ["//project"]: This is shorthand for ["//project:__pkg__"]
303 // [":__subpackages__"]: This is shorthand for ["//project:__subpackages__"] where
304 // //project is the module's package. e.g. using [":__subpackages__"] in
305 // packages/apps/Settings/Android.bp is equivalent to
306 // //packages/apps/Settings:__subpackages__.
307 // ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public
308 // for now. It is an error if it is used in a module.
Paul Duffine2453c72019-05-31 14:00:04 +0100309 //
310 // If a module does not specify the `visibility` property then it uses the
311 // `default_visibility` property of the `package` module in the module's package.
312 //
313 // If the `default_visibility` property is not set for the module's package then
Paul Duffine484f472019-06-20 16:38:08 +0100314 // it will use the `default_visibility` of its closest ancestor package for which
315 // a `default_visibility` property is specified.
316 //
317 // If no `default_visibility` property can be found then the module uses the
318 // global default of `//visibility:legacy_public`.
Paul Duffine2453c72019-05-31 14:00:04 +0100319 //
Paul Duffin95d53b52019-07-24 13:45:05 +0100320 // The `visibility` property has no effect on a defaults module although it does
321 // apply to any non-defaults module that uses it. To set the visibility of a
322 // defaults module, use the `defaults_visibility` property on the defaults module;
323 // not to be confused with the `default_visibility` property on the package module.
324 //
Elliott Hughes10363162024-01-09 22:02:03 +0000325 // See https://android.googlesource.com/platform/build/soong/+/main/README.md#visibility for
Paul Duffin2e61fa62019-03-28 14:10:57 +0000326 // more details.
327 Visibility []string
328
Bob Badour37af0462021-01-07 03:34:31 +0000329 // Describes the licenses applicable to this module. Must reference license modules.
330 Licenses []string
331
Bob Badour37af0462021-01-07 03:34:31 +0000332 // Override of module name when reporting licenses
333 Effective_package_name *string `blueprint:"mutated"`
334 // Notice files
Bob Badour4101c712022-02-09 11:54:35 -0800335 Effective_license_text NamedPaths `blueprint:"mutated"`
Bob Badour37af0462021-01-07 03:34:31 +0000336 // License names
337 Effective_license_kinds []string `blueprint:"mutated"`
338 // License conditions
339 Effective_license_conditions []string `blueprint:"mutated"`
340
Colin Cross7d5136f2015-05-11 13:39:40 -0700341 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800342 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
343 // 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 +0000344 // platform).
Colin Cross7d716ba2017-11-01 10:38:29 -0700345 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700346
347 Target struct {
348 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700349 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700350 }
351 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700352 Compile_multilib *string
Spandan Dasde588a32024-12-03 22:52:24 +0000353 Enabled *bool
Colin Cross69617d32016-09-06 10:39:07 -0700354 }
355 }
356
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000357 // If set to true then the archMutator will create variants for each arch specific target
358 // (e.g. 32/64) that the module is required to produce. If set to false then it will only
359 // create a variant for the architecture and will list the additional arch specific targets
360 // that the variant needs to produce in the CompileMultiTargets property.
Colin Crossee0bc3b2018-10-02 22:01:37 -0700361 UseTargetVariants bool `blueprint:"mutated"`
362 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800363
Dan Willemsen782a2d12015-12-21 14:55:28 -0800364 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700365 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800366
Colin Cross55708f32017-03-20 13:23:34 -0700367 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700368 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700369
Jiyong Park2db76922017-11-08 16:03:48 +0900370 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
371 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
372 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700373 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700374
Jiyong Park2db76922017-11-08 16:03:48 +0900375 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
376 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
377 Soc_specific *bool
378
379 // whether this module is specific to a device, not only for SoC, but also for off-chip
380 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
381 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
382 // This implies `soc_specific:true`.
383 Device_specific *bool
384
385 // whether this module is specific to a software configuration of a product (e.g. country,
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900386 // network operator, etc). When set to true, it is installed into /product (or
387 // /system/product if product partition does not exist).
Jiyong Park2db76922017-11-08 16:03:48 +0900388 Product_specific *bool
389
Justin Yund5f6c822019-06-25 16:47:17 +0900390 // whether this module extends system. When set to true, it is installed into /system_ext
391 // (or /system/system_ext if system_ext partition does not exist).
392 System_ext_specific *bool
393
Jiyong Parkf9332f12018-02-01 00:54:12 +0900394 // Whether this module is installed to recovery partition
395 Recovery *bool
396
Yifan Hong1b3348d2020-01-21 15:53:22 -0800397 // Whether this module is installed to ramdisk
398 Ramdisk *bool
399
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700400 // Whether this module is installed to vendor ramdisk
401 Vendor_ramdisk *bool
402
Inseob Kim08758f02021-04-08 21:13:22 +0900403 // Whether this module is installed to debug ramdisk
404 Debug_ramdisk *bool
405
Spandan Das27ff7672024-11-06 19:23:57 +0000406 // Install to partition system_dlkm when set to true.
407 System_dlkm_specific *bool
408
409 // Install to partition vendor_dlkm when set to true.
410 Vendor_dlkm_specific *bool
411
412 // Install to partition odm_dlkm when set to true.
413 Odm_dlkm_specific *bool
414
Jaewoong Jung8e93aba2021-03-02 16:58:08 -0800415 // Whether this module is built for non-native architectures (also known as native bridge binary)
dimitry1f33e402019-03-26 12:39:31 +0100416 Native_bridge_supported *bool `android:"arch_variant"`
417
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700418 // init.rc files to be installed if this module is installed
Inseob Kim713b87d2024-09-13 11:29:54 +0900419 Init_rc proptools.Configurable[[]string] `android:"arch_variant,path"`
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700420
Steven Moreland57a23d22018-04-04 15:42:19 -0700421 // VINTF manifest fragments to be installed if this module is installed
Inseob Kimf2237022024-07-23 13:36:31 +0900422 Vintf_fragments proptools.Configurable[[]string] `android:"path"`
Steven Moreland57a23d22018-04-04 15:42:19 -0700423
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000424 // The OsType of artifacts that this module variant is responsible for creating.
425 //
426 // Set by osMutator
427 CompileOS OsType `blueprint:"mutated"`
428
Cole Faust0aa21cc2024-03-20 12:28:03 -0700429 // Set to true after the arch mutator has run on this module and set CompileTarget,
430 // CompileMultiTargets, and CompilePrimary
431 ArchReady bool `blueprint:"mutated"`
432
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000433 // The Target of artifacts that this module variant is responsible for creating.
434 //
435 // Set by archMutator
436 CompileTarget Target `blueprint:"mutated"`
437
438 // The additional arch specific targets (e.g. 32/64 bit) that this module variant is
439 // responsible for creating.
440 //
441 // By default this is nil as, where necessary, separate variants are created for the
442 // different multilib types supported and that information is encapsulated in the
443 // CompileTarget so the module variant simply needs to create artifacts for that.
444 //
445 // However, if UseTargetVariants is set to false (e.g. by
446 // InitAndroidMultiTargetsArchModule) then no separate variants are created for the
447 // multilib targets. Instead a single variant is created for the architecture and
448 // this contains the multilib specific targets that this variant should create.
449 //
450 // Set by archMutator
Colin Crossee0bc3b2018-10-02 22:01:37 -0700451 CompileMultiTargets []Target `blueprint:"mutated"`
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000452
453 // True if the module variant's CompileTarget is the primary target
454 //
455 // Set by archMutator
456 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800457
458 // Set by InitAndroidModule
459 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700460 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700461
Paul Duffin1356d8c2020-02-25 19:26:33 +0000462 // If set to true then a CommonOS variant will be created which will have dependencies
463 // on all its OsType specific variants. Used by sdk/module_exports to create a snapshot
464 // that covers all os and architecture variants.
465 //
466 // The OsType specific variants can be retrieved by calling
467 // GetOsSpecificVariantsOfCommonOSVariant
468 //
469 // Set at module initialization time by calling InitCommonOSAndroidMultiTargetsArchModule
470 CreateCommonOSVariant bool `blueprint:"mutated"`
471
Jiyong Park3f627e62024-05-01 16:14:38 +0900472 // When set to true, this module is not installed to the full install path (ex: under
473 // out/target/product/<name>/<partition>). It can be installed only to the packaging
474 // modules like android_filesystem.
475 No_full_install *bool
476
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800477 // When HideFromMake is set to true, no entry for this variant will be emitted in the
478 // generated Android.mk file.
479 HideFromMake bool `blueprint:"mutated"`
480
481 // When SkipInstall is set to true, calls to ctx.InstallFile, ctx.InstallExecutable,
482 // ctx.InstallSymlink and ctx.InstallAbsoluteSymlink act like calls to ctx.PackageFile
483 // and don't create a rule to install the file.
Colin Crossce75d2c2016-10-06 16:12:58 -0700484 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800485
Colin Crossbd3a16b2023-04-25 11:30:51 -0700486 // UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex
487 // mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant
488 // is used to avoid adding install or packaging dependencies into libraries provided
489 // by apexes.
490 UninstallableApexPlatformVariant bool `blueprint:"mutated"`
491
Liz Kammer5ca3a622020-08-05 15:40:41 -0700492 // Whether the module has been replaced by a prebuilt
493 ReplacedByPrebuilt bool `blueprint:"mutated"`
494
Justin Yun32f053b2020-07-31 23:07:17 +0900495 // Disabled by mutators. If set to true, it overrides Enabled property.
496 ForcedDisabled bool `blueprint:"mutated"`
497
Jeff Gaston088e29e2017-11-29 16:47:17 -0800498 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross6c4f21f2019-06-06 15:41:36 -0700499
Liz Kammerc13f7852023-05-17 13:01:48 -0400500 MissingDeps []string `blueprint:"mutated"`
501 CheckedMissingDeps bool `blueprint:"mutated"`
Colin Cross9a362232019-07-01 15:32:45 -0700502
503 // Name and variant strings stored by mutators to enable Module.String()
504 DebugName string `blueprint:"mutated"`
505 DebugMutators []string `blueprint:"mutated"`
506 DebugVariations []string `blueprint:"mutated"`
Colin Cross7228ecd2019-11-18 16:00:16 -0800507
Colin Crossa6845402020-11-16 15:08:19 -0800508 // ImageVariation is set by ImageMutator to specify which image this variation is for,
509 // for example "" for core or "recovery" for recovery. It will often be set to one of the
510 // constants in image.go, but can also be set to a custom value by individual module types.
Colin Cross7228ecd2019-11-18 16:00:16 -0800511 ImageVariation string `blueprint:"mutated"`
Liz Kammer2ada09a2021-08-11 00:17:36 -0400512
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800513 // The team (defined by the owner/vendor) who owns the property.
514 Team *string `android:"path"`
Kiyoung Kimfaf6af32024-08-12 11:15:19 +0900515
516 // vintf_fragment Modules required from this module.
517 Vintf_fragment_modules proptools.Configurable[[]string] `android:"path"`
Jiyong Parka574d532024-08-28 18:06:43 +0900518
519 // List of module names that are prevented from being installed when this module gets
520 // installed.
521 Overrides []string
Justin Yunbe6f81d2024-12-17 21:15:59 +0900522
523 // Set to true if this module must be generic and does not require product-specific information.
524 // To be included in the system image, this property must be set to true.
525 Use_generic_config *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800526}
527
Cole Faust2239ae62025-01-27 15:32:11 -0800528// Properties common to all modules inheriting from ModuleBase. Unlike commonProperties, these
529// properties are NOT automatically inherited by sub-modules created with ctx.CreateModule()
530type baseProperties struct {
531 // names of other modules to install if this module is installed
532 Required proptools.Configurable[[]string] `android:"arch_variant"`
533
534 // names of other modules to install on host if this module is installed
535 Host_required []string `android:"arch_variant"`
536
537 // names of other modules to install on target if this module is installed
538 Target_required []string `android:"arch_variant"`
Cole Faust55c03f02025-03-10 15:52:36 -0700539
540 // If this is a soong config module, this property will be set to the name of the original
541 // module type. This is used by neverallow to ensure you can't bypass a ModuleType() matcher
542 // just by creating a soong config module type.
543 Soong_config_base_module_type *string `blueprint:"mutated"`
Cole Faust2239ae62025-01-27 15:32:11 -0800544}
545
Paul Duffined875132020-09-02 13:08:57 +0100546type distProperties struct {
547 // configuration to distribute output files from this module to the distribution
548 // directory (default: $OUT/dist, configurable with $DIST_DIR)
549 Dist Dist `android:"arch_variant"`
550
551 // a list of configurations to distribute output files from this module to the
552 // distribution directory (default: $OUT/dist, configurable with $DIST_DIR)
553 Dists []Dist `android:"arch_variant"`
554}
555
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800556type TeamDepTagType struct {
557 blueprint.BaseDependencyTag
558}
559
560var teamDepTag = TeamDepTagType{}
561
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900562// Dependency tag for required, host_required, and target_required modules.
563var RequiredDepTag = struct {
564 blueprint.BaseDependencyTag
565 InstallAlwaysNeededDependencyTag
566 // Requiring disabled module has been supported (as a side effect of this being implemented
567 // in Make). We may want to make it an error, but for now, let's keep the existing behavior.
568 AlwaysAllowDisabledModuleDependencyTag
569}{}
570
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800571// CommonTestOptions represents the common `test_options` properties in
572// Android.bp.
573type CommonTestOptions struct {
574 // If the test is a hostside (no device required) unittest that shall be run
575 // during presubmit check.
576 Unit_test *bool
Zhenhuang Wang409d2772022-08-22 16:00:05 +0800577
578 // Tags provide additional metadata to customize test execution by downstream
579 // test runners. The tags have no special meaning to Soong.
580 Tags []string
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800581}
582
583// SetAndroidMkEntries sets AndroidMkEntries according to the value of base
584// `test_options`.
585func (t *CommonTestOptions) SetAndroidMkEntries(entries *AndroidMkEntries) {
586 entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test))
Zhenhuang Wang409d2772022-08-22 16:00:05 +0800587 if len(t.Tags) > 0 {
588 entries.AddStrings("LOCAL_TEST_OPTIONS_TAGS", t.Tags...)
589 }
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800590}
591
Yu Liue70976d2024-10-15 20:45:35 +0000592func (t *CommonTestOptions) SetAndroidMkInfoEntries(entries *AndroidMkInfo) {
593 entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test))
594 if len(t.Tags) > 0 {
595 entries.AddStrings("LOCAL_TEST_OPTIONS_TAGS", t.Tags...)
596 }
597}
598
Paul Duffin74f05592020-11-25 16:37:46 +0000599// The key to use in TaggedDistFiles when a Dist structure does not specify a
600// tag property. This intentionally does not use "" as the default because that
601// would mean that an empty tag would have a different meaning when used in a dist
602// structure that when used to reference a specific set of output paths using the
603// :module{tag} syntax, which passes tag to the OutputFiles(tag) method.
604const DefaultDistTag = "<default-dist-tag>"
605
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000606// A map of OutputFile tag keys to Paths, for disting purposes.
607type TaggedDistFiles map[string]Paths
608
Paul Duffin74f05592020-11-25 16:37:46 +0000609// addPathsForTag adds a mapping from the tag to the paths. If the map is nil
610// then it will create a map, update it and then return it. If a mapping already
611// exists for the tag then the paths are appended to the end of the current list
612// of paths, ignoring any duplicates.
613func (t TaggedDistFiles) addPathsForTag(tag string, paths ...Path) TaggedDistFiles {
614 if t == nil {
615 t = make(TaggedDistFiles)
616 }
617
618 for _, distFile := range paths {
619 if distFile != nil && !t[tag].containsPath(distFile) {
620 t[tag] = append(t[tag], distFile)
621 }
622 }
623
624 return t
625}
626
627// merge merges the entries from the other TaggedDistFiles object into this one.
628// If the TaggedDistFiles is nil then it will create a new instance, merge the
629// other into it, and then return it.
630func (t TaggedDistFiles) merge(other TaggedDistFiles) TaggedDistFiles {
631 for tag, paths := range other {
632 t = t.addPathsForTag(tag, paths...)
633 }
634
635 return t
636}
637
Colin Cross3f40fa42015-01-30 17:27:36 -0800638type hostAndDeviceProperties struct {
Colin Cross4e81d702018-11-09 10:36:55 -0800639 // If set to true, build a variant of the module for the host. Defaults to false.
640 Host_supported *bool
641
642 // If set to true, build a variant of the module for the device. Defaults to true.
Colin Crossa4190c12016-07-12 13:11:25 -0700643 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800644}
645
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000646type hostCrossProperties struct {
647 // If set to true, build a variant of the module for the host cross. Defaults to true.
648 Host_cross_supported *bool
649}
650
Colin Crossc472d572015-03-17 15:06:21 -0700651type Multilib string
652
653const (
Cole Faustb9c67e22024-10-08 16:39:56 -0700654 MultilibBoth Multilib = "both"
655 MultilibFirst Multilib = "first"
656 MultilibCommon Multilib = "common"
Colin Crossc472d572015-03-17 15:06:21 -0700657)
658
Colin Crossa1ad8d12016-06-01 17:09:44 -0700659type HostOrDeviceSupported int
660
661const (
Colin Cross34037c62020-11-17 13:19:17 -0800662 hostSupported = 1 << iota
663 hostCrossSupported
664 deviceSupported
665 hostDefault
666 deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700667
668 // Host and HostCross are built by default. Device is not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800669 HostSupported = hostSupported | hostCrossSupported | hostDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700670
671 // Host is built by default. HostCross and Device are not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800672 HostSupportedNoCross = hostSupported | hostDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700673
674 // Device is built by default. Host and HostCross are not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800675 DeviceSupported = deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700676
Liz Kammer8631cc72021-08-23 21:12:07 +0000677 // By default, _only_ device variant is built. Device variant can be disabled with `device_supported: false`
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -0700678 // Host and HostCross are disabled by default and can be enabled with `host_supported: true`
Colin Cross34037c62020-11-17 13:19:17 -0800679 HostAndDeviceSupported = hostSupported | hostCrossSupported | deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700680
681 // Host, HostCross, and Device are built by default.
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -0700682 // Building Device can be disabled with `device_supported: false`
683 // Building Host and HostCross can be disabled with `host_supported: false`
Colin Cross34037c62020-11-17 13:19:17 -0800684 HostAndDeviceDefault = hostSupported | hostCrossSupported | hostDefault |
685 deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700686
687 // Nothing is supported. This is not exposed to the user, but used to mark a
688 // host only module as unsupported when the module type is not supported on
689 // the host OS. E.g. benchmarks are supported on Linux but not Darwin.
Colin Cross34037c62020-11-17 13:19:17 -0800690 NeitherHostNorDeviceSupported = 0
Colin Crossa1ad8d12016-06-01 17:09:44 -0700691)
692
Jiyong Park2db76922017-11-08 16:03:48 +0900693type moduleKind int
694
695const (
696 platformModule moduleKind = iota
697 deviceSpecificModule
698 socSpecificModule
699 productSpecificModule
Justin Yund5f6c822019-06-25 16:47:17 +0900700 systemExtSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900701)
702
703func (k moduleKind) String() string {
704 switch k {
705 case platformModule:
706 return "platform"
707 case deviceSpecificModule:
708 return "device-specific"
709 case socSpecificModule:
710 return "soc-specific"
711 case productSpecificModule:
712 return "product-specific"
Justin Yund5f6c822019-06-25 16:47:17 +0900713 case systemExtSpecificModule:
714 return "systemext-specific"
Jiyong Park2db76922017-11-08 16:03:48 +0900715 default:
716 panic(fmt.Errorf("unknown module kind %d", k))
717 }
718}
719
Colin Cross9d34f352019-11-22 16:03:51 -0800720func initAndroidModuleBase(m Module) {
721 m.base().module = m
722}
723
Colin Crossa6845402020-11-16 15:08:19 -0800724// InitAndroidModule initializes the Module as an Android module that is not architecture-specific.
725// It adds the common properties, for example "name" and "enabled".
Colin Cross36242852017-06-23 15:06:31 -0700726func InitAndroidModule(m Module) {
Colin Cross9d34f352019-11-22 16:03:51 -0800727 initAndroidModuleBase(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800728 base := m.base()
Colin Cross5049f022015-03-18 13:28:46 -0700729
Colin Cross36242852017-06-23 15:06:31 -0700730 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700731 &base.nameProperties,
Paul Duffined875132020-09-02 13:08:57 +0100732 &base.commonProperties,
Cole Faust2239ae62025-01-27 15:32:11 -0800733 &base.baseProperties,
Paul Duffined875132020-09-02 13:08:57 +0100734 &base.distProperties)
Colin Cross18c46802019-09-24 22:19:02 -0700735
Colin Crosseabaedd2020-02-06 17:01:55 -0800736 initProductVariableModule(m)
Colin Cross18c46802019-09-24 22:19:02 -0700737
Paul Duffin63c6e182019-07-24 14:24:38 +0100738 // The default_visibility property needs to be checked and parsed by the visibility module during
Paul Duffin5ec73ec2020-05-01 17:52:01 +0100739 // its checking and parsing phases so make it the primary visibility property.
740 setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility)
Bob Badour37af0462021-01-07 03:34:31 +0000741
742 // The default_applicable_licenses property needs to be checked and parsed by the licenses module during
743 // its checking and parsing phases so make it the primary licenses property.
744 setPrimaryLicensesProperty(m, "licenses", &base.commonProperties.Licenses)
Colin Cross5049f022015-03-18 13:28:46 -0700745}
746
Colin Crossa6845402020-11-16 15:08:19 -0800747// InitAndroidArchModule initializes the Module as an Android module that is architecture-specific.
748// It adds the common properties, for example "name" and "enabled", as well as runtime generated
749// property structs for architecture-specific versions of generic properties tagged with
750// `android:"arch_variant"`.
751//
Colin Crossd079e0b2022-08-16 10:27:33 -0700752// InitAndroidModule should not be called if InitAndroidArchModule was called.
Colin Cross36242852017-06-23 15:06:31 -0700753func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
754 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700755
756 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800757 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700758 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700759 base.commonProperties.ArchSpecific = true
Colin Crossee0bc3b2018-10-02 22:01:37 -0700760 base.commonProperties.UseTargetVariants = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800761
Colin Cross34037c62020-11-17 13:19:17 -0800762 if hod&hostSupported != 0 && hod&deviceSupported != 0 {
Colin Cross36242852017-06-23 15:06:31 -0700763 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800764 }
765
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000766 if hod&hostCrossSupported != 0 {
767 m.AddProperties(&base.hostCrossProperties)
768 }
769
Colin Crossa6845402020-11-16 15:08:19 -0800770 initArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800771}
772
Colin Crossa6845402020-11-16 15:08:19 -0800773// InitAndroidMultiTargetsArchModule initializes the Module as an Android module that is
774// architecture-specific, but will only have a single variant per OS that handles all the
775// architectures simultaneously. The list of Targets that it must handle will be available from
776// ModuleContext.MultiTargets. It adds the common properties, for example "name" and "enabled", as
777// well as runtime generated property structs for architecture-specific versions of generic
778// properties tagged with `android:"arch_variant"`.
779//
780// InitAndroidModule or InitAndroidArchModule should not be called if
781// InitAndroidMultiTargetsArchModule was called.
Colin Crossee0bc3b2018-10-02 22:01:37 -0700782func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
783 InitAndroidArchModule(m, hod, defaultMultilib)
784 m.base().commonProperties.UseTargetVariants = false
785}
786
Colin Crossa6845402020-11-16 15:08:19 -0800787// InitCommonOSAndroidMultiTargetsArchModule initializes the Module as an Android module that is
788// architecture-specific, but will only have a single variant per OS that handles all the
789// architectures simultaneously, and will also have an additional CommonOS variant that has
790// dependencies on all the OS-specific variants. The list of Targets that it must handle will be
791// available from ModuleContext.MultiTargets. It adds the common properties, for example "name" and
792// "enabled", as well as runtime generated property structs for architecture-specific versions of
793// generic properties tagged with `android:"arch_variant"`.
794//
795// InitAndroidModule, InitAndroidArchModule or InitAndroidMultiTargetsArchModule should not be
796// called if InitCommonOSAndroidMultiTargetsArchModule was called.
Paul Duffin1356d8c2020-02-25 19:26:33 +0000797func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
798 InitAndroidArchModule(m, hod, defaultMultilib)
799 m.base().commonProperties.UseTargetVariants = false
800 m.base().commonProperties.CreateCommonOSVariant = true
801}
802
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800803// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800804// modules. It should be included as an anonymous field in every module
805// struct definition. InitAndroidModule should then be called from the module's
806// factory function, and the return values from InitAndroidModule should be
807// returned from the factory function.
808//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800809// The ModuleBase type is responsible for implementing the GenerateBuildActions
810// method to support the blueprint.Module interface. This method will then call
811// the module's GenerateAndroidBuildActions method once for each build variant
Colin Cross25de6c32019-06-06 14:29:25 -0700812// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext
813// rather than the usual blueprint.ModuleContext.
814// ModuleContext exposes extra functionality specific to the Android build
Colin Cross3f40fa42015-01-30 17:27:36 -0800815// system including details about the particular build variant that is to be
816// generated.
817//
818// For example:
819//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800820// import (
821// "android/soong/android"
822// )
Colin Cross3f40fa42015-01-30 17:27:36 -0800823//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800824// type myModule struct {
825// android.ModuleBase
826// properties struct {
827// MyProperty string
828// }
829// }
Colin Cross3f40fa42015-01-30 17:27:36 -0800830//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800831// func NewMyModule() android.Module {
832// m := &myModule{}
833// m.AddProperties(&m.properties)
834// android.InitAndroidModule(m)
835// return m
836// }
Colin Cross3f40fa42015-01-30 17:27:36 -0800837//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800838// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
839// // Get the CPU architecture for the current build variant.
840// variantArch := ctx.Arch()
Colin Cross3f40fa42015-01-30 17:27:36 -0800841//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800842// // ...
843// }
Colin Cross635c3b02016-05-18 15:37:25 -0700844type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800845 // Putting the curiously recurring thing pointing to the thing that contains
846 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700847 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700848 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800849
Colin Crossfc754582016-05-17 16:34:16 -0700850 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800851 commonProperties commonProperties
Cole Faust2239ae62025-01-27 15:32:11 -0800852 baseProperties baseProperties
Paul Duffined875132020-09-02 13:08:57 +0100853 distProperties distProperties
Colin Cross18c46802019-09-24 22:19:02 -0700854 variableProperties interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800855 hostAndDeviceProperties hostAndDeviceProperties
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000856 hostCrossProperties hostCrossProperties
Jingwen Chen5d864492021-02-24 07:20:12 -0500857
Usta851a3272022-01-05 23:42:33 -0500858 // Arch specific versions of structs in GetProperties() prior to
859 // initialization in InitAndroidArchModule, lets call it `generalProperties`.
860 // The outer index has the same order as generalProperties and the inner index
861 // chooses the props specific to the architecture. The interface{} value is an
862 // archPropRoot that is filled with arch specific values by the arch mutator.
Jingwen Chen5d864492021-02-24 07:20:12 -0500863 archProperties [][]interface{}
864
Paul Duffin63c6e182019-07-24 14:24:38 +0100865 // Information about all the properties on the module that contains visibility rules that need
866 // checking.
867 visibilityPropertyInfo []visibilityProperty
868
869 // The primary visibility property, may be nil, that controls access to the module.
870 primaryVisibilityProperty visibilityProperty
871
Bob Badour37af0462021-01-07 03:34:31 +0000872 // The primary licenses property, may be nil, records license metadata for the module.
873 primaryLicensesProperty applicableLicensesProperty
874
Yu Liueb6d7052024-08-27 22:35:54 +0000875 noAddressSanitizer bool
Colin Cross1f8c52b2015-06-16 16:38:17 -0700876
Colin Cross178a5092016-09-13 13:42:32 -0700877 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700878
879 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700880
881 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700882 buildParams []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800883 ruleParams map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800884 variables map[string]string
Colin Cross36242852017-06-23 15:06:31 -0700885}
886
Lukacs T. Berkid18d8ca2021-06-25 09:11:22 +0200887func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
Liz Kammer9525e712022-01-05 13:46:24 -0500888 (*d)["Android"] = map[string]interface{}{
889 // Properties set in Blueprint or in blueprint of a defaults modules
890 "SetProperties": m.propertiesWithValues(),
891 }
892}
893
894type propInfo struct {
Liz Kammer898e0762022-03-22 11:27:26 -0400895 Name string
896 Type string
897 Value string
898 Values []string
Liz Kammer9525e712022-01-05 13:46:24 -0500899}
900
901func (m *ModuleBase) propertiesWithValues() []propInfo {
902 var info []propInfo
903 props := m.GetProperties()
904
905 var propsWithValues func(name string, v reflect.Value)
906 propsWithValues = func(name string, v reflect.Value) {
907 kind := v.Kind()
908 switch kind {
909 case reflect.Ptr, reflect.Interface:
910 if v.IsNil() {
911 return
912 }
913 propsWithValues(name, v.Elem())
914 case reflect.Struct:
915 if v.IsZero() {
916 return
917 }
918 for i := 0; i < v.NumField(); i++ {
919 namePrefix := name
920 sTyp := v.Type().Field(i)
921 if proptools.ShouldSkipProperty(sTyp) {
922 continue
923 }
924 if name != "" && !strings.HasSuffix(namePrefix, ".") {
925 namePrefix += "."
926 }
927 if !proptools.IsEmbedded(sTyp) {
928 namePrefix += sTyp.Name
929 }
930 sVal := v.Field(i)
931 propsWithValues(namePrefix, sVal)
932 }
933 case reflect.Array, reflect.Slice:
934 if v.IsNil() {
935 return
936 }
937 elKind := v.Type().Elem().Kind()
Liz Kammer898e0762022-03-22 11:27:26 -0400938 info = append(info, propInfo{Name: name, Type: elKind.String() + " " + kind.String(), Values: sliceReflectionValue(v)})
Liz Kammer9525e712022-01-05 13:46:24 -0500939 default:
Liz Kammer898e0762022-03-22 11:27:26 -0400940 info = append(info, propInfo{Name: name, Type: kind.String(), Value: reflectionValue(v)})
Liz Kammer9525e712022-01-05 13:46:24 -0500941 }
942 }
943
944 for _, p := range props {
945 propsWithValues("", reflect.ValueOf(p).Elem())
946 }
Liz Kammer898e0762022-03-22 11:27:26 -0400947 sort.Slice(info, func(i, j int) bool {
948 return info[i].Name < info[j].Name
949 })
Liz Kammer9525e712022-01-05 13:46:24 -0500950 return info
Lukacs T. Berkid18d8ca2021-06-25 09:11:22 +0200951}
952
Liz Kammer898e0762022-03-22 11:27:26 -0400953func reflectionValue(value reflect.Value) string {
954 switch value.Kind() {
955 case reflect.Bool:
956 return fmt.Sprintf("%t", value.Bool())
957 case reflect.Int64:
958 return fmt.Sprintf("%d", value.Int())
959 case reflect.String:
960 return fmt.Sprintf("%s", value.String())
961 case reflect.Struct:
962 if value.IsZero() {
963 return "{}"
964 }
965 length := value.NumField()
966 vals := make([]string, length, length)
967 for i := 0; i < length; i++ {
968 sTyp := value.Type().Field(i)
969 if proptools.ShouldSkipProperty(sTyp) {
970 continue
971 }
972 name := sTyp.Name
973 vals[i] = fmt.Sprintf("%s: %s", name, reflectionValue(value.Field(i)))
974 }
975 return fmt.Sprintf("%s{%s}", value.Type(), strings.Join(vals, ", "))
976 case reflect.Array, reflect.Slice:
977 vals := sliceReflectionValue(value)
978 return fmt.Sprintf("[%s]", strings.Join(vals, ", "))
979 }
980 return ""
981}
982
983func sliceReflectionValue(value reflect.Value) []string {
984 length := value.Len()
985 vals := make([]string, length, length)
986 for i := 0; i < length; i++ {
987 vals[i] = reflectionValue(value.Index(i))
988 }
989 return vals
990}
991
Paul Duffin44f1d842020-06-26 20:17:02 +0100992func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {}
993
Colin Cross4157e882019-06-06 16:57:04 -0700994func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
Colin Cross5f692ec2019-02-01 16:53:07 -0800995
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800996func (m *ModuleBase) baseDepsMutator(ctx BottomUpMutatorContext) {
997 if m.Team() != "" {
998 ctx.AddDependency(ctx.Module(), teamDepTag, m.Team())
999 }
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001000
1001 // TODO(jiyong): remove below case. This is to work around build errors happening
1002 // on branches with reduced manifest like aosp_kernel-build-tools.
1003 // In the branch, a build error occurs as follows.
1004 // 1. aosp_kernel-build-tools is a reduced manifest branch. It doesn't have some git
1005 // projects like external/bouncycastle
1006 // 2. `boot_signer` is `required` by modules like `build_image` which is explicitly list as
1007 // the top-level build goal (in the shell file that invokes Soong).
1008 // 3. `boot_signer` depends on `bouncycastle-unbundled` which is in the missing git project.
Cole Faust88f469e2025-01-21 13:05:05 -08001009 // 4. aosp_kernel-build-tools invokes soong with `--soong-only`. Therefore, the absence of
1010 // ALLOW_MISSING_DEPENDENCIES didn't cause a problem, as previously only make processed required
1011 // dependencies.
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001012 // 5. Now, since Soong understands `required` deps, it tries to build `boot_signer` and the
1013 // absence of external/bouncycastle fails the build.
1014 //
1015 // Unfortunately, there's no way for Soong to correctly determine if it's running in a
1016 // reduced manifest branch. Instead, here, we use the absence of DeviceArch or DeviceName as
1017 // a strong signal, because that's very common across reduced manifest branches.
1018 pv := ctx.Config().productVariables
1019 fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil
1020 if fullManifest {
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001021 addVintfFragmentDeps(ctx)
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001022 }
1023}
1024
Inseob Kim0c67c8e2025-03-14 18:33:55 +09001025// required property can be overridden too; handle it separately
1026func (m *ModuleBase) baseOverridablePropertiesDepsMutator(ctx BottomUpMutatorContext) {
1027 pv := ctx.Config().productVariables
1028 fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil
1029 if fullManifest {
1030 addRequiredDeps(ctx)
1031 }
1032}
1033
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001034// addRequiredDeps adds required, target_required, and host_required as dependencies.
Jiyong Parkf21dd652024-04-17 05:22:37 +00001035func addRequiredDeps(ctx BottomUpMutatorContext) {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001036 addDep := func(target Target, depName string) {
1037 if !ctx.OtherModuleExists(depName) {
1038 if ctx.Config().AllowMissingDependencies() {
1039 return
1040 }
1041 }
1042
1043 // If Android native module requires another Android native module, ensure that
1044 // they have the same bitness. This mimics the policy in select-bitness-of-required-modules
1045 // in build/make/core/main.mk.
1046 // TODO(jiyong): the Make-side does this only when the required module is a shared
1047 // library or a native test.
Jiyong Parkf21dd652024-04-17 05:22:37 +00001048 bothInAndroid := ctx.Device() && target.Os.Class == Device
Jiyong Parkc4b1d552024-05-13 16:47:30 +09001049 nativeArch := InList(ctx.Arch().ArchType.Multilib, []string{"lib32", "lib64"}) &&
1050 InList(target.Arch.ArchType.Multilib, []string{"lib32", "lib64"})
Jiyong Parkf21dd652024-04-17 05:22:37 +00001051 sameBitness := ctx.Arch().ArchType.Multilib == target.Arch.ArchType.Multilib
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001052 if bothInAndroid && nativeArch && !sameBitness {
1053 return
1054 }
1055
Jiyong Park8db44152024-05-28 12:22:04 +09001056 // ... also don't make a dependency between native bridge arch and non-native bridge
1057 // arches. b/342945184
1058 if ctx.Target().NativeBridge != target.NativeBridge {
1059 return
1060 }
1061
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001062 variation := target.Variations()
1063 if ctx.OtherModuleFarDependencyVariantExists(variation, depName) {
1064 ctx.AddFarVariationDependencies(variation, RequiredDepTag, depName)
1065 }
1066 }
1067
Jiyong Park73e5bab2024-04-05 13:37:21 +09001068 var deviceTargets []Target
1069 deviceTargets = append(deviceTargets, ctx.Config().Targets[Android]...)
1070 deviceTargets = append(deviceTargets, ctx.Config().AndroidCommonTarget)
1071
1072 var hostTargets []Target
1073 hostTargets = append(hostTargets, ctx.Config().Targets[ctx.Config().BuildOS]...)
1074 hostTargets = append(hostTargets, ctx.Config().BuildOSCommonTarget)
1075
Jiyong Parkf21dd652024-04-17 05:22:37 +00001076 if ctx.Device() {
Jihoon Kangd1a01422024-12-26 19:07:13 +00001077 for _, depName := range append(ctx.Module().RequiredModuleNames(ctx), ctx.Module().VintfFragmentModuleNames(ctx)...) {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001078 for _, target := range deviceTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001079 addDep(target, depName)
1080 }
1081 }
Jiyong Parkf21dd652024-04-17 05:22:37 +00001082 for _, depName := range ctx.Module().HostRequiredModuleNames() {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001083 for _, target := range hostTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001084 addDep(target, depName)
1085 }
1086 }
1087 }
1088
Jiyong Parkf21dd652024-04-17 05:22:37 +00001089 if ctx.Host() {
Jihoon Kangd1a01422024-12-26 19:07:13 +00001090 for _, depName := range append(ctx.Module().RequiredModuleNames(ctx), ctx.Module().VintfFragmentModuleNames(ctx)...) {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001091 for _, target := range hostTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001092 // When a host module requires another host module, don't make a
1093 // dependency if they have different OSes (i.e. hostcross).
Jiyong Parkf21dd652024-04-17 05:22:37 +00001094 if ctx.Target().HostCross != target.HostCross {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001095 continue
1096 }
1097 addDep(target, depName)
1098 }
1099 }
Jiyong Parkf21dd652024-04-17 05:22:37 +00001100 for _, depName := range ctx.Module().TargetRequiredModuleNames() {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001101 for _, target := range deviceTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001102 addDep(target, depName)
1103 }
1104 }
1105 }
Ronald Braunstein73b08ff2023-12-19 10:24:47 -08001106}
1107
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001108var vintfDepTag = struct {
1109 blueprint.BaseDependencyTag
1110 InstallAlwaysNeededDependencyTag
1111}{}
1112
Kiyoung Kim11ad4e92024-09-04 14:16:47 +09001113func IsVintfDepTag(depTag blueprint.DependencyTag) bool {
1114 return depTag == vintfDepTag
1115}
1116
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001117func addVintfFragmentDeps(ctx BottomUpMutatorContext) {
Kiyoung Kim55234812024-09-11 17:00:24 +09001118 // Vintf manifests in the recovery partition will be ignored.
1119 if !ctx.Device() || ctx.Module().InstallInRecovery() {
1120 return
1121 }
1122
1123 deviceConfig := ctx.DeviceConfig()
1124
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001125 mod := ctx.Module()
Kiyoung Kim55234812024-09-11 17:00:24 +09001126 vintfModules := ctx.AddDependency(mod, vintfDepTag, mod.VintfFragmentModuleNames(ctx)...)
1127
1128 modPartition := mod.PartitionTag(deviceConfig)
1129 for _, vintf := range vintfModules {
Cole Faust69788792024-10-10 11:00:36 -07001130 if vintf == nil {
1131 // TODO(b/372091092): Remove this. Having it gives us missing dependency errors instead
1132 // of nil pointer dereference errors, but we should resolve the missing dependencies.
1133 continue
1134 }
Kiyoung Kim11ad4e92024-09-04 14:16:47 +09001135 if vintfModule, ok := vintf.(*VintfFragmentModule); ok {
Kiyoung Kim55234812024-09-11 17:00:24 +09001136 vintfPartition := vintfModule.PartitionTag(deviceConfig)
1137 if modPartition != vintfPartition {
1138 ctx.ModuleErrorf("Module %q(%q) and Vintf_fragment %q(%q) are installed to different partitions.",
1139 mod.Name(), modPartition,
1140 vintfModule.Name(), vintfPartition)
1141 }
1142 } else {
1143 ctx.ModuleErrorf("Only vintf_fragment type module should be listed in vintf_fragment_modules : %q", vintf.Name())
1144 }
1145 }
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001146}
1147
Usta355a5872021-12-01 15:16:32 -05001148// AddProperties "registers" the provided props
1149// each value in props MUST be a pointer to a struct
Colin Cross4157e882019-06-06 16:57:04 -07001150func (m *ModuleBase) AddProperties(props ...interface{}) {
1151 m.registerProps = append(m.registerProps, props...)
Colin Cross36242852017-06-23 15:06:31 -07001152}
1153
Colin Cross4157e882019-06-06 16:57:04 -07001154func (m *ModuleBase) GetProperties() []interface{} {
1155 return m.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -08001156}
1157
Colin Cross4157e882019-06-06 16:57:04 -07001158func (m *ModuleBase) BuildParamsForTests() []BuildParams {
Chih-Hung Hsiehb8082292021-09-09 23:20:39 -07001159 // Expand the references to module variables like $flags[0-9]*,
1160 // so we do not need to change many existing unit tests.
1161 // This looks like undoing the shareFlags optimization in cc's
1162 // transformSourceToObj, and should only affects unit tests.
1163 vars := m.VariablesForTests()
1164 buildParams := append([]BuildParams(nil), m.buildParams...)
Sasha Smundake198eaf2022-08-04 13:07:02 -07001165 for i := range buildParams {
Chih-Hung Hsiehb8082292021-09-09 23:20:39 -07001166 newArgs := make(map[string]string)
1167 for k, v := range buildParams[i].Args {
1168 newArgs[k] = v
1169 // Replaces both ${flags1} and $flags1 syntax.
1170 if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") {
1171 if value, found := vars[v[2:len(v)-1]]; found {
1172 newArgs[k] = value
1173 }
1174 } else if strings.HasPrefix(v, "$") {
1175 if value, found := vars[v[1:]]; found {
1176 newArgs[k] = value
1177 }
1178 }
1179 }
1180 buildParams[i].Args = newArgs
1181 }
1182 return buildParams
Colin Crosscec81712017-07-13 14:43:27 -07001183}
1184
Colin Cross4157e882019-06-06 16:57:04 -07001185func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
1186 return m.ruleParams
Colin Cross4c83e5c2019-02-25 14:54:28 -08001187}
1188
Colin Cross4157e882019-06-06 16:57:04 -07001189func (m *ModuleBase) VariablesForTests() map[string]string {
1190 return m.variables
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001191}
1192
Colin Crossce75d2c2016-10-06 16:12:58 -07001193// Name returns the name of the module. It may be overridden by individual module types, for
1194// example prebuilts will prepend prebuilt_ to the name.
Colin Cross4157e882019-06-06 16:57:04 -07001195func (m *ModuleBase) Name() string {
1196 return String(m.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -07001197}
1198
Colin Cross9a362232019-07-01 15:32:45 -07001199// String returns a string that includes the module name and variants for printing during debugging.
1200func (m *ModuleBase) String() string {
1201 sb := strings.Builder{}
1202 sb.WriteString(m.commonProperties.DebugName)
1203 sb.WriteString("{")
1204 for i := range m.commonProperties.DebugMutators {
1205 if i != 0 {
1206 sb.WriteString(",")
1207 }
1208 sb.WriteString(m.commonProperties.DebugMutators[i])
1209 sb.WriteString(":")
1210 sb.WriteString(m.commonProperties.DebugVariations[i])
1211 }
1212 sb.WriteString("}")
1213 return sb.String()
1214}
1215
Colin Crossce75d2c2016-10-06 16:12:58 -07001216// BaseModuleName returns the name of the module as specified in the blueprints file.
Colin Cross4157e882019-06-06 16:57:04 -07001217func (m *ModuleBase) BaseModuleName() string {
1218 return String(m.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -07001219}
1220
Colin Cross4157e882019-06-06 16:57:04 -07001221func (m *ModuleBase) base() *ModuleBase {
1222 return m
Colin Cross3f40fa42015-01-30 17:27:36 -08001223}
1224
Paul Duffine2453c72019-05-31 14:00:04 +01001225func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName {
1226 return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()}
1227}
1228
1229func (m *ModuleBase) visibilityProperties() []visibilityProperty {
Paul Duffin63c6e182019-07-24 14:24:38 +01001230 return m.visibilityPropertyInfo
1231}
1232
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001233func (m *ModuleBase) Dists() []Dist {
Paul Duffined875132020-09-02 13:08:57 +01001234 if len(m.distProperties.Dist.Targets) > 0 {
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001235 // Make a copy of the underlying Dists slice to protect against
1236 // backing array modifications with repeated calls to this method.
Paul Duffined875132020-09-02 13:08:57 +01001237 distsCopy := append([]Dist(nil), m.distProperties.Dists...)
1238 return append(distsCopy, m.distProperties.Dist)
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001239 } else {
Paul Duffined875132020-09-02 13:08:57 +01001240 return m.distProperties.Dists
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001241 }
1242}
1243
1244func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFiles {
Paul Duffin74f05592020-11-25 16:37:46 +00001245 var distFiles TaggedDistFiles
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001246 for _, dist := range m.Dists() {
Paul Duffin74f05592020-11-25 16:37:46 +00001247 // If no tag is specified then it means to use the default dist paths so use
1248 // the special tag name which represents that.
1249 tag := proptools.StringDefault(dist.Tag, DefaultDistTag)
1250
mrziwangabdb2932024-06-18 12:43:41 -07001251 distFileForTagFromProvider, err := outputFilesForModuleFromProvider(ctx, m.module, tag)
Cole Fausta8437c52025-02-25 14:45:43 -08001252
1253 // If the module doesn't define output files for the DefaultDistTag, try the files under
1254 // the "" tag.
1255 if tag == DefaultDistTag && errors.Is(err, ErrUnsupportedOutputTag) {
1256 distFileForTagFromProvider, err = outputFilesForModuleFromProvider(ctx, m.module, "")
1257 }
1258
mrziwangabdb2932024-06-18 12:43:41 -07001259 if err != OutputFilesProviderNotSet {
1260 if err != nil && tag != DefaultDistTag {
1261 ctx.PropertyErrorf("dist.tag", "%s", err.Error())
1262 } else {
1263 distFiles = distFiles.addPathsForTag(tag, distFileForTagFromProvider...)
1264 continue
1265 }
1266 }
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001267 }
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001268 return distFiles
1269}
1270
Cole Faust02987bd2024-03-21 17:58:43 -07001271func (m *ModuleBase) ArchReady() bool {
1272 return m.commonProperties.ArchReady
1273}
1274
Colin Cross4157e882019-06-06 16:57:04 -07001275func (m *ModuleBase) Target() Target {
1276 return m.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -08001277}
1278
Colin Cross4157e882019-06-06 16:57:04 -07001279func (m *ModuleBase) TargetPrimary() bool {
1280 return m.commonProperties.CompilePrimary
Colin Cross8b74d172016-09-13 09:59:14 -07001281}
1282
Colin Cross4157e882019-06-06 16:57:04 -07001283func (m *ModuleBase) MultiTargets() []Target {
1284 return m.commonProperties.CompileMultiTargets
Colin Crossee0bc3b2018-10-02 22:01:37 -07001285}
1286
Colin Cross4157e882019-06-06 16:57:04 -07001287func (m *ModuleBase) Os() OsType {
1288 return m.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -08001289}
1290
Colin Cross4157e882019-06-06 16:57:04 -07001291func (m *ModuleBase) Host() bool {
Jiyong Park1613e552020-09-14 19:43:17 +09001292 return m.Os().Class == Host
Dan Willemsen97750522016-02-09 17:43:51 -08001293}
1294
Yo Chiangbba545e2020-06-09 16:15:37 +08001295func (m *ModuleBase) Device() bool {
1296 return m.Os().Class == Device
1297}
1298
Colin Cross4157e882019-06-06 16:57:04 -07001299func (m *ModuleBase) Arch() Arch {
1300 return m.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -08001301}
1302
Colin Cross4157e882019-06-06 16:57:04 -07001303func (m *ModuleBase) ArchSpecific() bool {
1304 return m.commonProperties.ArchSpecific
Dan Willemsen0b24c742016-10-04 15:13:37 -07001305}
1306
Paul Duffin1356d8c2020-02-25 19:26:33 +00001307// True if the current variant is a CommonOS variant, false otherwise.
1308func (m *ModuleBase) IsCommonOSVariant() bool {
Colin Cross8bbc3d52024-09-11 15:33:54 -07001309 return m.commonProperties.CompileOS == CommonOS
Paul Duffin1356d8c2020-02-25 19:26:33 +00001310}
1311
Colin Cross34037c62020-11-17 13:19:17 -08001312// supportsTarget returns true if the given Target is supported by the current module.
1313func (m *ModuleBase) supportsTarget(target Target) bool {
1314 switch target.Os.Class {
1315 case Host:
1316 if target.HostCross {
1317 return m.HostCrossSupported()
1318 } else {
1319 return m.HostSupported()
Colin Crossa1ad8d12016-06-01 17:09:44 -07001320 }
Colin Cross34037c62020-11-17 13:19:17 -08001321 case Device:
1322 return m.DeviceSupported()
Colin Crossa1ad8d12016-06-01 17:09:44 -07001323 default:
Jiyong Park1613e552020-09-14 19:43:17 +09001324 return false
Colin Crossa1ad8d12016-06-01 17:09:44 -07001325 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001326}
1327
Colin Cross34037c62020-11-17 13:19:17 -08001328// DeviceSupported returns true if the current module is supported and enabled for device targets,
1329// i.e. the factory method set the HostOrDeviceSupported value to include device support and
1330// the device support is enabled by default or enabled by the device_supported property.
Colin Cross4157e882019-06-06 16:57:04 -07001331func (m *ModuleBase) DeviceSupported() bool {
Colin Cross34037c62020-11-17 13:19:17 -08001332 hod := m.commonProperties.HostOrDeviceSupported
1333 // deviceEnabled is true if the device_supported property is true or the HostOrDeviceSupported
1334 // value has the deviceDefault bit set.
1335 deviceEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Device_supported, hod&deviceDefault != 0)
1336 return hod&deviceSupported != 0 && deviceEnabled
Colin Cross3f40fa42015-01-30 17:27:36 -08001337}
1338
Colin Cross34037c62020-11-17 13:19:17 -08001339// HostSupported returns true if the current module is supported and enabled for host targets,
1340// i.e. the factory method set the HostOrDeviceSupported value to include host support and
1341// the host support is enabled by default or enabled by the host_supported property.
Paul Duffine44358f2019-11-26 18:04:12 +00001342func (m *ModuleBase) HostSupported() bool {
Colin Cross34037c62020-11-17 13:19:17 -08001343 hod := m.commonProperties.HostOrDeviceSupported
1344 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1345 // value has the hostDefault bit set.
1346 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
1347 return hod&hostSupported != 0 && hostEnabled
1348}
1349
1350// HostCrossSupported returns true if the current module is supported and enabled for host cross
1351// targets, i.e. the factory method set the HostOrDeviceSupported value to include host cross
1352// support and the host cross support is enabled by default or enabled by the
1353// host_supported property.
1354func (m *ModuleBase) HostCrossSupported() bool {
1355 hod := m.commonProperties.HostOrDeviceSupported
1356 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1357 // value has the hostDefault bit set.
1358 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
Ivan Lozanoc7eafa72024-07-16 17:55:33 +00001359
1360 // Default true for the Host_cross_supported property
1361 hostCrossEnabled := proptools.BoolDefault(m.hostCrossProperties.Host_cross_supported, true)
1362
1363 return hod&hostCrossSupported != 0 && hostEnabled && hostCrossEnabled
Paul Duffine44358f2019-11-26 18:04:12 +00001364}
1365
Colin Cross4157e882019-06-06 16:57:04 -07001366func (m *ModuleBase) Platform() bool {
Justin Yund5f6c822019-06-25 16:47:17 +09001367 return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.SystemExtSpecific()
Jiyong Parkc678ad32018-04-10 13:07:10 +09001368}
1369
Colin Cross4157e882019-06-06 16:57:04 -07001370func (m *ModuleBase) DeviceSpecific() bool {
1371 return Bool(m.commonProperties.Device_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001372}
1373
Colin Cross4157e882019-06-06 16:57:04 -07001374func (m *ModuleBase) SocSpecific() bool {
1375 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001376}
1377
Colin Cross4157e882019-06-06 16:57:04 -07001378func (m *ModuleBase) ProductSpecific() bool {
1379 return Bool(m.commonProperties.Product_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001380}
1381
Justin Yund5f6c822019-06-25 16:47:17 +09001382func (m *ModuleBase) SystemExtSpecific() bool {
1383 return Bool(m.commonProperties.System_ext_specific)
Dario Frenifd05a742018-05-29 13:28:54 +01001384}
1385
Colin Crossc2d24052020-05-13 11:05:02 -07001386// RequiresStableAPIs returns true if the module will be installed to a partition that may
1387// be updated separately from the system image.
1388func (m *ModuleBase) RequiresStableAPIs(ctx BaseModuleContext) bool {
1389 return m.SocSpecific() || m.DeviceSpecific() ||
1390 (m.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface())
1391}
1392
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001393func (m *ModuleBase) PartitionTag(config DeviceConfig) string {
1394 partition := "system"
1395 if m.SocSpecific() {
1396 // A SoC-specific module could be on the vendor partition at
1397 // "vendor" or the system partition at "system/vendor".
1398 if config.VendorPath() == "vendor" {
1399 partition = "vendor"
1400 }
1401 } else if m.DeviceSpecific() {
1402 // A device-specific module could be on the odm partition at
1403 // "odm", the vendor partition at "vendor/odm", or the system
1404 // partition at "system/vendor/odm".
1405 if config.OdmPath() == "odm" {
1406 partition = "odm"
Ramy Medhat944839a2020-03-31 22:14:52 -04001407 } else if strings.HasPrefix(config.OdmPath(), "vendor/") {
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001408 partition = "vendor"
1409 }
1410 } else if m.ProductSpecific() {
1411 // A product-specific module could be on the product partition
1412 // at "product" or the system partition at "system/product".
1413 if config.ProductPath() == "product" {
1414 partition = "product"
1415 }
1416 } else if m.SystemExtSpecific() {
1417 // A system_ext-specific module could be on the system_ext
1418 // partition at "system_ext" or the system partition at
1419 // "system/system_ext".
1420 if config.SystemExtPath() == "system_ext" {
1421 partition = "system_ext"
1422 }
Cole Faust76a6e952024-11-07 16:56:45 -08001423 } else if m.InstallInRamdisk() {
1424 partition = "ramdisk"
Jihoon Kang30bf8f62024-11-26 21:50:55 +00001425 } else if m.InstallInVendorRamdisk() {
1426 partition = "vendor_ramdisk"
Jihoon Kang3216c982024-12-02 19:42:20 +00001427 } else if m.InstallInRecovery() {
1428 partition = "recovery"
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001429 }
1430 return partition
1431}
1432
Cole Fauste8a87832024-09-11 11:35:46 -07001433func (m *ModuleBase) Enabled(ctx ConfigurableEvaluatorContext) bool {
Justin Yun32f053b2020-07-31 23:07:17 +09001434 if m.commonProperties.ForcedDisabled {
1435 return false
1436 }
Cole Fausta963b942024-04-11 17:43:00 -07001437 return m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled)
Colin Cross3f40fa42015-01-30 17:27:36 -08001438}
1439
Cole Faust8eeae4b2024-09-12 11:51:04 -07001440// Returns a copy of the enabled property, useful for passing it on to sub-modules
1441func (m *ModuleBase) EnabledProperty() proptools.Configurable[bool] {
1442 if m.commonProperties.ForcedDisabled {
1443 return proptools.NewSimpleConfigurable(false)
1444 }
1445 return m.commonProperties.Enabled.Clone()
1446}
1447
Inseob Kimeec88e12020-01-22 11:11:29 +09001448func (m *ModuleBase) Disable() {
Justin Yun32f053b2020-07-31 23:07:17 +09001449 m.commonProperties.ForcedDisabled = true
Inseob Kimeec88e12020-01-22 11:11:29 +09001450}
1451
Colin Crossa9c8c9f2020-12-16 10:20:23 -08001452// HideFromMake marks this variant so that it is not emitted in the generated Android.mk file.
1453func (m *ModuleBase) HideFromMake() {
1454 m.commonProperties.HideFromMake = true
1455}
1456
1457// IsHideFromMake returns true if HideFromMake was previously called.
1458func (m *ModuleBase) IsHideFromMake() bool {
1459 return m.commonProperties.HideFromMake == true
1460}
1461
1462// SkipInstall marks this variant to not create install rules when ctx.Install* are called.
Colin Cross4157e882019-06-06 16:57:04 -07001463func (m *ModuleBase) SkipInstall() {
1464 m.commonProperties.SkipInstall = true
Colin Crossce75d2c2016-10-06 16:12:58 -07001465}
1466
Martin Stjernholm9e7f45e2020-12-23 03:50:30 +00001467// IsSkipInstall returns true if this variant is marked to not create install
1468// rules when ctx.Install* are called.
1469func (m *ModuleBase) IsSkipInstall() bool {
1470 return m.commonProperties.SkipInstall
1471}
1472
Iván Budnik295da162023-03-10 16:11:26 +00001473// Similar to HideFromMake, but if the AndroidMk entry would set
1474// LOCAL_UNINSTALLABLE_MODULE then this variant may still output that entry
1475// rather than leaving it out altogether. That happens in cases where it would
1476// have other side effects, in particular when it adds a NOTICE file target,
1477// which other install targets might depend on.
1478func (m *ModuleBase) MakeUninstallable() {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001479 m.commonProperties.UninstallableApexPlatformVariant = true
Iván Budnik295da162023-03-10 16:11:26 +00001480 m.HideFromMake()
Spandan Das034af2c2024-10-30 21:45:09 +00001481 m.SkipInstall()
Iván Budnik295da162023-03-10 16:11:26 +00001482}
1483
Liz Kammer5ca3a622020-08-05 15:40:41 -07001484func (m *ModuleBase) ReplacedByPrebuilt() {
1485 m.commonProperties.ReplacedByPrebuilt = true
Colin Crossa9c8c9f2020-12-16 10:20:23 -08001486 m.HideFromMake()
Liz Kammer5ca3a622020-08-05 15:40:41 -07001487}
1488
1489func (m *ModuleBase) IsReplacedByPrebuilt() bool {
1490 return m.commonProperties.ReplacedByPrebuilt
1491}
1492
Colin Cross4157e882019-06-06 16:57:04 -07001493func (m *ModuleBase) ExportedToMake() bool {
1494 return m.commonProperties.NamespaceExportedToMake
Jiyong Park374510b2018-03-19 18:23:01 +09001495}
1496
Justin Yun885a7de2021-06-29 20:34:53 +09001497func (m *ModuleBase) EffectiveLicenseFiles() Paths {
Bob Badour4101c712022-02-09 11:54:35 -08001498 result := make(Paths, 0, len(m.commonProperties.Effective_license_text))
1499 for _, p := range m.commonProperties.Effective_license_text {
1500 result = append(result, p.Path)
1501 }
1502 return result
Justin Yun885a7de2021-06-29 20:34:53 +09001503}
1504
Colin Crosse9fe2942020-11-10 18:12:15 -08001505// computeInstallDeps finds the installed paths of all dependencies that have a dependency
Colin Crossbd3a16b2023-04-25 11:30:51 -07001506// tag that is annotated as needing installation via the isInstallDepNeeded method.
Colin Crossa14fb6a2024-10-23 16:57:06 -07001507func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]depset.DepSet[InstallPath], []depset.DepSet[PackagingSpec]) {
1508 var installDeps []depset.DepSet[InstallPath]
1509 var packagingSpecs []depset.DepSet[PackagingSpec]
Yu Liu5697f8f2024-12-13 23:31:08 +00001510 ctx.VisitDirectDepsProxy(func(dep ModuleProxy) {
1511 if isInstallDepNeeded(ctx, dep) {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001512 // Installation is still handled by Make, so anything hidden from Make is not
1513 // installable.
Yu Liubad1eef2024-08-21 22:37:35 +00001514 info := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider)
Yu Liuf22120f2025-03-13 18:36:35 +00001515 commonInfo := OtherModulePointerProviderOrDefault(ctx, dep, CommonModuleInfoProvider)
Yu Liu5697f8f2024-12-13 23:31:08 +00001516 if !commonInfo.HideFromMake && !commonInfo.SkipInstall {
Yu Liubad1eef2024-08-21 22:37:35 +00001517 installDeps = append(installDeps, info.TransitiveInstallFiles)
Colin Crossbd3a16b2023-04-25 11:30:51 -07001518 }
1519 // Add packaging deps even when the dependency is not installed so that uninstallable
1520 // modules can still be packaged. Often the package will be installed instead.
Yu Liubad1eef2024-08-21 22:37:35 +00001521 packagingSpecs = append(packagingSpecs, info.TransitivePackagingSpecs)
Colin Cross897266e2020-02-13 13:22:08 -08001522 }
1523 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001524
Colin Crossffe6b9d2020-12-01 15:40:06 -08001525 return installDeps, packagingSpecs
Colin Cross3f40fa42015-01-30 17:27:36 -08001526}
1527
Colin Crossbd3a16b2023-04-25 11:30:51 -07001528// isInstallDepNeeded returns true if installing the output files of the current module
1529// should also install the output files of the given dependency and dependency tag.
Yu Liu5697f8f2024-12-13 23:31:08 +00001530func isInstallDepNeeded(ctx ModuleContext, dep ModuleProxy) bool {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001531 // Don't add a dependency from the platform to a library provided by an apex.
Yu Liuf22120f2025-03-13 18:36:35 +00001532 if OtherModulePointerProviderOrDefault(ctx, dep, CommonModuleInfoProvider).UninstallableApexPlatformVariant {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001533 return false
1534 }
1535 // Only install modules if the dependency tag is an InstallDepNeeded tag.
Yu Liu5697f8f2024-12-13 23:31:08 +00001536 return IsInstallDepNeededTag(ctx.OtherModuleDependencyTag(dep))
Colin Crossbd3a16b2023-04-25 11:30:51 -07001537}
1538
Colin Cross4157e882019-06-06 16:57:04 -07001539func (m *ModuleBase) NoAddressSanitizer() bool {
1540 return m.noAddressSanitizer
Colin Cross3f40fa42015-01-30 17:27:36 -08001541}
1542
Colin Cross4157e882019-06-06 16:57:04 -07001543func (m *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -08001544 return false
1545}
1546
Jaewoong Jung0949f312019-09-11 10:25:18 -07001547func (m *ModuleBase) InstallInTestcases() bool {
1548 return false
1549}
1550
Colin Cross4157e882019-06-06 16:57:04 -07001551func (m *ModuleBase) InstallInSanitizerDir() bool {
Vishwath Mohan1dd88392017-03-29 22:00:18 -07001552 return false
1553}
1554
Yifan Hong1b3348d2020-01-21 15:53:22 -08001555func (m *ModuleBase) InstallInRamdisk() bool {
1556 return Bool(m.commonProperties.Ramdisk)
1557}
1558
Yifan Hong60e0cfb2020-10-21 15:17:56 -07001559func (m *ModuleBase) InstallInVendorRamdisk() bool {
1560 return Bool(m.commonProperties.Vendor_ramdisk)
1561}
1562
Inseob Kim08758f02021-04-08 21:13:22 +09001563func (m *ModuleBase) InstallInDebugRamdisk() bool {
1564 return Bool(m.commonProperties.Debug_ramdisk)
1565}
1566
Colin Cross4157e882019-06-06 16:57:04 -07001567func (m *ModuleBase) InstallInRecovery() bool {
1568 return Bool(m.commonProperties.Recovery)
Jiyong Parkf9332f12018-02-01 00:54:12 +09001569}
1570
Colin Crossea30d852023-11-29 16:00:16 -08001571func (m *ModuleBase) InstallInOdm() bool {
1572 return false
1573}
1574
1575func (m *ModuleBase) InstallInProduct() bool {
1576 return false
1577}
1578
Kiyoung Kimae11c232021-07-19 11:38:04 +09001579func (m *ModuleBase) InstallInVendor() bool {
Kiyoung Kimf160f7f2022-11-29 10:58:08 +09001580 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Soc_specific) || Bool(m.commonProperties.Proprietary)
Kiyoung Kimae11c232021-07-19 11:38:04 +09001581}
1582
Spandan Das950deca2024-10-01 18:35:23 +00001583func (m *ModuleBase) InstallInSystemExt() bool {
1584 return Bool(m.commonProperties.System_ext_specific)
1585}
1586
Colin Cross90ba5f42019-10-02 11:10:58 -07001587func (m *ModuleBase) InstallInRoot() bool {
1588 return false
1589}
1590
Spandan Das27ff7672024-11-06 19:23:57 +00001591func (m *ModuleBase) InstallInSystemDlkm() bool {
1592 return Bool(m.commonProperties.System_dlkm_specific)
1593}
1594
1595func (m *ModuleBase) InstallInVendorDlkm() bool {
1596 return Bool(m.commonProperties.Vendor_dlkm_specific)
1597}
1598
1599func (m *ModuleBase) InstallInOdmDlkm() bool {
1600 return Bool(m.commonProperties.Odm_dlkm_specific)
1601}
1602
Jiyong Park87788b52020-09-01 12:37:45 +09001603func (m *ModuleBase) InstallForceOS() (*OsType, *ArchType) {
1604 return nil, nil
Colin Cross6e359402020-02-10 15:29:54 -08001605}
1606
Colin Cross4157e882019-06-06 16:57:04 -07001607func (m *ModuleBase) Owner() string {
1608 return String(m.commonProperties.Owner)
Sundong Ahn4fd04bb2018-08-31 18:01:37 +09001609}
1610
Ronald Braunstein73b08ff2023-12-19 10:24:47 -08001611func (m *ModuleBase) Team() string {
1612 return String(m.commonProperties.Team)
1613}
1614
Colin Cross7228ecd2019-11-18 16:00:16 -08001615func (m *ModuleBase) setImageVariation(variant string) {
1616 m.commonProperties.ImageVariation = variant
1617}
1618
1619func (m *ModuleBase) ImageVariation() blueprint.Variation {
1620 return blueprint.Variation{
1621 Mutator: "image",
1622 Variation: m.base().commonProperties.ImageVariation,
1623 }
1624}
1625
Paul Duffin9b76c0b2020-03-12 10:24:35 +00001626func (m *ModuleBase) getVariationByMutatorName(mutator string) string {
1627 for i, v := range m.commonProperties.DebugMutators {
1628 if v == mutator {
1629 return m.commonProperties.DebugVariations[i]
1630 }
1631 }
1632
1633 return ""
1634}
1635
Yifan Hong1b3348d2020-01-21 15:53:22 -08001636func (m *ModuleBase) InRamdisk() bool {
1637 return m.base().commonProperties.ImageVariation == RamdiskVariation
1638}
1639
Yifan Hong60e0cfb2020-10-21 15:17:56 -07001640func (m *ModuleBase) InVendorRamdisk() bool {
1641 return m.base().commonProperties.ImageVariation == VendorRamdiskVariation
1642}
1643
Inseob Kim08758f02021-04-08 21:13:22 +09001644func (m *ModuleBase) InDebugRamdisk() bool {
1645 return m.base().commonProperties.ImageVariation == DebugRamdiskVariation
1646}
1647
Colin Cross7228ecd2019-11-18 16:00:16 -08001648func (m *ModuleBase) InRecovery() bool {
1649 return m.base().commonProperties.ImageVariation == RecoveryVariation
1650}
1651
Cole Fauste8a87832024-09-11 11:35:46 -07001652func (m *ModuleBase) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string {
Cole Faust2239ae62025-01-27 15:32:11 -08001653 return m.base().baseProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09001654}
1655
1656func (m *ModuleBase) HostRequiredModuleNames() []string {
Cole Faust2239ae62025-01-27 15:32:11 -08001657 return m.base().baseProperties.Host_required
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09001658}
1659
1660func (m *ModuleBase) TargetRequiredModuleNames() []string {
Cole Faust2239ae62025-01-27 15:32:11 -08001661 return m.base().baseProperties.Target_required
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09001662}
1663
Cole Fauste8a87832024-09-11 11:35:46 -07001664func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string {
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001665 return m.base().commonProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
1666}
1667
Kiyoung Kim23be5bb2024-11-27 00:50:30 +00001668func (m *ModuleBase) VintfFragments(ctx ConfigurableEvaluatorContext) []string {
1669 return m.base().commonProperties.Vintf_fragments.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
1670}
1671
Colin Crossa6182ab2024-08-21 10:47:44 -07001672func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) {
1673 namespacePrefix := ctx.Namespace().id
1674 if namespacePrefix != "" {
1675 namespacePrefix = namespacePrefix + "-"
1676 }
1677
1678 if !ctx.uncheckedModule {
1679 name := namespacePrefix + ctx.ModuleName() + "-" + ctx.ModuleSubDir() + "-checkbuild"
1680 ctx.Phony(name, ctx.checkbuildFiles...)
1681 ctx.checkbuildTarget = PathForPhony(ctx, name)
1682 }
1683
1684}
1685
Cole Faust0523b8f2025-03-03 15:11:32 -08001686// generateModuleTarget generates phony targets so that you can do `m <module-name>`.
1687// It will be run on every variant of the module, so it relies on the fact that phony targets
1688// are deduped to merge all the deps from different variants together.
Yu Liuddc28332024-08-09 22:48:30 +00001689func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) {
Yu Liu460c0fa2024-08-20 19:31:15 +00001690 var namespacePrefix string
1691 nameSpace := ctx.Namespace().Path
1692 if nameSpace != "." {
1693 namespacePrefix = strings.ReplaceAll(nameSpace, "/", ".") + "-"
Jeff Gaston088e29e2017-11-29 16:47:17 -08001694 }
1695
Cole Faustc5bfbdd2025-01-08 13:05:40 -08001696 var deps Paths
Cole Faust0523b8f2025-03-03 15:11:32 -08001697 var info ModuleBuildTargetsInfo
Yu Liuddc2e1a2024-08-20 21:31:22 +00001698
Cole Faust0523b8f2025-03-03 15:11:32 -08001699 if len(ctx.installFiles) > 0 {
Colin Crossc3d87d32020-06-04 13:25:17 -07001700 name := namespacePrefix + ctx.ModuleName() + "-install"
Cole Faustd1bf2722025-03-05 10:42:50 -08001701 installFiles := ctx.installFiles.Paths()
1702 ctx.Phony(name, installFiles...)
Yu Liuddc2e1a2024-08-20 21:31:22 +00001703 info.InstallTarget = PathForPhony(ctx, name)
Cole Faustd1bf2722025-03-05 10:42:50 -08001704 deps = append(deps, installFiles...)
Colin Cross9454bfa2015-03-17 13:24:18 -07001705 }
1706
Cole Faust0523b8f2025-03-03 15:11:32 -08001707 // A module's -checkbuild phony targets should
1708 // not be created if the module is not exported to make.
1709 // Those could depend on the build target and fail to compile
1710 // for the current build target.
1711 if (!ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, m)) && !ctx.uncheckedModule && ctx.checkbuildTarget != nil {
Colin Crossc3d87d32020-06-04 13:25:17 -07001712 name := namespacePrefix + ctx.ModuleName() + "-checkbuild"
Cole Faust0523b8f2025-03-03 15:11:32 -08001713 ctx.Phony(name, ctx.checkbuildTarget)
Cole Faustd1bf2722025-03-05 10:42:50 -08001714 deps = append(deps, ctx.checkbuildTarget)
Colin Cross9454bfa2015-03-17 13:24:18 -07001715 }
1716
Cole Faust0523b8f2025-03-03 15:11:32 -08001717 if outputFiles, err := outputFilesForModule(ctx, ctx.Module(), ""); err == nil && len(outputFiles) > 0 {
Cole Faust71e3e7a2025-01-22 10:44:36 -08001718 name := namespacePrefix + ctx.ModuleName() + "-outputs"
Cole Faust0523b8f2025-03-03 15:11:32 -08001719 ctx.Phony(name, outputFiles...)
Cole Faustd1bf2722025-03-05 10:42:50 -08001720 deps = append(deps, outputFiles...)
Cole Faust71e3e7a2025-01-22 10:44:36 -08001721 }
1722
Colin Cross9454bfa2015-03-17 13:24:18 -07001723 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001724 suffix := ""
Jingwen Chencda22c92020-11-23 00:22:30 -05001725 if ctx.Config().KatiEnabled() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001726 suffix = "-soong"
1727 }
1728
Colin Crossc3d87d32020-06-04 13:25:17 -07001729 ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...)
Spandan Das25301f12025-01-24 22:22:37 +00001730 if ctx.Device() {
1731 // Generate a target suffix for use in atest etc.
1732 ctx.Phony(namespacePrefix+ctx.ModuleName()+"-target"+suffix, deps...)
Spandan Das25301f12025-01-24 22:22:37 +00001733 } else {
1734 // Generate a host suffix for use in atest etc.
1735 ctx.Phony(namespacePrefix+ctx.ModuleName()+"-host"+suffix, deps...)
Spandan Das481ec672025-01-27 19:55:52 +00001736 if ctx.Target().HostCross {
1737 // Generate a host-cross suffix for use in atest etc.
1738 ctx.Phony(namespacePrefix+ctx.ModuleName()+"-host-cross"+suffix, deps...)
1739 }
Spandan Das25301f12025-01-24 22:22:37 +00001740 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001741
Yu Liuddc2e1a2024-08-20 21:31:22 +00001742 info.BlueprintDir = ctx.ModuleDir()
Cole Faust0523b8f2025-03-03 15:11:32 -08001743 SetProvider(ctx, ModuleBuildTargetsProvider, info)
Colin Cross3f40fa42015-01-30 17:27:36 -08001744 }
1745}
1746
Cole Faust5b7635d2024-10-28 13:01:12 -07001747func determineModuleKind(m *ModuleBase, ctx ModuleErrorContext) moduleKind {
Colin Cross4157e882019-06-06 16:57:04 -07001748 var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
1749 var deviceSpecific = Bool(m.commonProperties.Device_specific)
1750 var productSpecific = Bool(m.commonProperties.Product_specific)
Justin Yund5f6c822019-06-25 16:47:17 +09001751 var systemExtSpecific = Bool(m.commonProperties.System_ext_specific)
Jiyong Park2db76922017-11-08 16:03:48 +09001752
Dario Frenifd05a742018-05-29 13:28:54 +01001753 msg := "conflicting value set here"
1754 if socSpecific && deviceSpecific {
1755 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
Colin Cross4157e882019-06-06 16:57:04 -07001756 if Bool(m.commonProperties.Vendor) {
Jiyong Park2db76922017-11-08 16:03:48 +09001757 ctx.PropertyErrorf("vendor", msg)
1758 }
Colin Cross4157e882019-06-06 16:57:04 -07001759 if Bool(m.commonProperties.Proprietary) {
Jiyong Park2db76922017-11-08 16:03:48 +09001760 ctx.PropertyErrorf("proprietary", msg)
1761 }
Colin Cross4157e882019-06-06 16:57:04 -07001762 if Bool(m.commonProperties.Soc_specific) {
Jiyong Park2db76922017-11-08 16:03:48 +09001763 ctx.PropertyErrorf("soc_specific", msg)
1764 }
1765 }
1766
Justin Yund5f6c822019-06-25 16:47:17 +09001767 if productSpecific && systemExtSpecific {
1768 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and system_ext at the same time.")
1769 ctx.PropertyErrorf("system_ext_specific", msg)
Dario Frenifd05a742018-05-29 13:28:54 +01001770 }
1771
Justin Yund5f6c822019-06-25 16:47:17 +09001772 if (socSpecific || deviceSpecific) && (productSpecific || systemExtSpecific) {
Dario Frenifd05a742018-05-29 13:28:54 +01001773 if productSpecific {
1774 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
1775 } else {
Justin Yund5f6c822019-06-25 16:47:17 +09001776 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 +01001777 }
1778 if deviceSpecific {
1779 ctx.PropertyErrorf("device_specific", msg)
1780 } else {
Colin Cross4157e882019-06-06 16:57:04 -07001781 if Bool(m.commonProperties.Vendor) {
Dario Frenifd05a742018-05-29 13:28:54 +01001782 ctx.PropertyErrorf("vendor", msg)
1783 }
Colin Cross4157e882019-06-06 16:57:04 -07001784 if Bool(m.commonProperties.Proprietary) {
Dario Frenifd05a742018-05-29 13:28:54 +01001785 ctx.PropertyErrorf("proprietary", msg)
1786 }
Colin Cross4157e882019-06-06 16:57:04 -07001787 if Bool(m.commonProperties.Soc_specific) {
Dario Frenifd05a742018-05-29 13:28:54 +01001788 ctx.PropertyErrorf("soc_specific", msg)
1789 }
1790 }
1791 }
1792
Jiyong Park2db76922017-11-08 16:03:48 +09001793 if productSpecific {
1794 return productSpecificModule
Justin Yund5f6c822019-06-25 16:47:17 +09001795 } else if systemExtSpecific {
1796 return systemExtSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +09001797 } else if deviceSpecific {
1798 return deviceSpecificModule
1799 } else if socSpecific {
1800 return socSpecificModule
1801 } else {
1802 return platformModule
1803 }
1804}
1805
Colin Crossc34d2322020-01-03 15:23:27 -08001806func (m *ModuleBase) earlyModuleContextFactory(ctx blueprint.EarlyModuleContext) earlyModuleContext {
Colin Cross1184b642019-12-30 18:43:07 -08001807 return earlyModuleContext{
Colin Crossc34d2322020-01-03 15:23:27 -08001808 EarlyModuleContext: ctx,
1809 kind: determineModuleKind(m, ctx),
1810 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -08001811 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001812}
1813
Colin Cross1184b642019-12-30 18:43:07 -08001814func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext {
1815 return baseModuleContext{
1816 bp: ctx,
Colin Cross1d3d9f12024-01-18 14:30:22 -08001817 archModuleContext: m.archModuleContextFactory(ctx),
Colin Cross1184b642019-12-30 18:43:07 -08001818 earlyModuleContext: m.earlyModuleContextFactory(ctx),
Colin Cross1184b642019-12-30 18:43:07 -08001819 }
1820}
1821
Colin Crosse1a85552024-06-14 12:17:37 -07001822type archModuleContextFactoryContext interface {
1823 Config() interface{}
1824}
1825
1826func (m *ModuleBase) archModuleContextFactory(ctx archModuleContextFactoryContext) archModuleContext {
Colin Cross1d3d9f12024-01-18 14:30:22 -08001827 config := ctx.Config().(Config)
1828 target := m.Target()
1829 primaryArch := false
1830 if len(config.Targets[target.Os]) <= 1 {
1831 primaryArch = true
1832 } else {
1833 primaryArch = target.Arch.ArchType == config.Targets[target.Os][0].Arch.ArchType
1834 }
1835
1836 return archModuleContext{
Cole Faust0aa21cc2024-03-20 12:28:03 -07001837 ready: m.commonProperties.ArchReady,
Colin Cross1d3d9f12024-01-18 14:30:22 -08001838 os: m.commonProperties.CompileOS,
1839 target: m.commonProperties.CompileTarget,
1840 targetPrimary: m.commonProperties.CompilePrimary,
1841 multiTargets: m.commonProperties.CompileMultiTargets,
1842 primaryArch: primaryArch,
1843 }
1844
1845}
1846
Yu Liuddc28332024-08-09 22:48:30 +00001847type InstallFilesInfo struct {
Colin Crossa6182ab2024-08-21 10:47:44 -07001848 InstallFiles InstallPaths
1849 CheckbuildFiles Paths
1850 CheckbuildTarget Path
1851 UncheckedModule bool
1852 PackagingSpecs []PackagingSpec
Yu Liud46e5ae2024-08-15 18:46:17 +00001853 // katiInstalls tracks the install rules that were created by Soong but are being exported
1854 // to Make to convert to ninja rules so that Make can add additional dependencies.
Yu Liuec810542024-08-26 18:09:15 +00001855 KatiInstalls katiInstalls
1856 KatiSymlinks katiInstalls
1857 TestData []DataPath
Colin Crossa14fb6a2024-10-23 16:57:06 -07001858 TransitivePackagingSpecs depset.DepSet[PackagingSpec]
Yu Liuec810542024-08-26 18:09:15 +00001859 LicenseMetadataFile WritablePath
1860
1861 // The following fields are private before, make it private again once we have
1862 // better solution.
Colin Crossa14fb6a2024-10-23 16:57:06 -07001863 TransitiveInstallFiles depset.DepSet[InstallPath]
Yu Liu82a6d142024-08-27 19:02:29 +00001864 // katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
1865 // allowed to have duplicates across modules and variants.
1866 KatiInitRcInstalls katiInstalls
1867 KatiVintfInstalls katiInstalls
1868 InitRcPaths Paths
1869 VintfFragmentsPaths Paths
1870 InstalledInitRcPaths InstallPaths
1871 InstalledVintfFragmentsPaths InstallPaths
1872
Yu Liuec810542024-08-26 18:09:15 +00001873 // The files to copy to the dist as explicitly specified in the .bp file.
1874 DistFiles TaggedDistFiles
Yu Liuddc28332024-08-09 22:48:30 +00001875}
1876
Yu Liubad1eef2024-08-21 22:37:35 +00001877var InstallFilesProvider = blueprint.NewProvider[InstallFilesInfo]()
Yu Liuddc2e1a2024-08-20 21:31:22 +00001878
Yu Liud3228ac2024-11-08 23:11:47 +00001879type SourceFilesInfo struct {
1880 Srcs Paths
1881}
1882
Yu Liuc41eae52025-01-14 01:03:08 +00001883var SourceFilesInfoProvider = blueprint.NewProvider[SourceFilesInfo]()
Yu Liud3228ac2024-11-08 23:11:47 +00001884
Cole Faust0523b8f2025-03-03 15:11:32 -08001885// ModuleBuildTargetsInfo is used by buildTargetSingleton to create checkbuild and
1886// per-directory build targets.
1887type ModuleBuildTargetsInfo struct {
Yu Liuddc2e1a2024-08-20 21:31:22 +00001888 InstallTarget WritablePath
1889 CheckbuildTarget WritablePath
1890 BlueprintDir string
1891}
1892
Cole Faust0523b8f2025-03-03 15:11:32 -08001893var ModuleBuildTargetsProvider = blueprint.NewProvider[ModuleBuildTargetsInfo]()
Yu Liuddc28332024-08-09 22:48:30 +00001894
Yu Liub5275322024-11-13 18:40:43 +00001895type CommonModuleInfo struct {
Yu Liudd9ccb42024-10-07 17:07:44 +00001896 Enabled bool
1897 // Whether the module has been replaced by a prebuilt
1898 ReplacedByPrebuilt bool
Yu Liuec7043d2024-11-05 18:22:20 +00001899 // The Target of artifacts that this module variant is responsible for creating.
Yu Liu8024b922024-12-20 23:31:32 +00001900 Target Target
Yu Liub5275322024-11-13 18:40:43 +00001901 SkipAndroidMkProcessing bool
Yu Liu63bdf632024-12-03 19:54:05 +00001902 BaseModuleName string
Yu Liub1bfa9d2024-12-05 18:57:51 +00001903 CanHaveApexVariants bool
Yu Liu5d3a2cf2025-02-06 00:25:22 +00001904 MinSdkVersion ApiLevelOrPlatform
Yu Liuf6f85492025-01-13 21:02:36 +00001905 SdkVersion string
Yu Liu8f2c5c02024-12-06 00:40:39 +00001906 NotAvailableForPlatform bool
Yu Liu8024b922024-12-20 23:31:32 +00001907 // There some subtle differences between this one and the one above.
1908 NotInPlatform bool
Yu Liu5697f8f2024-12-13 23:31:08 +00001909 // UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex
1910 // mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant
1911 // is used to avoid adding install or packaging dependencies into libraries provided
1912 // by apexes.
1913 UninstallableApexPlatformVariant bool
Yu Liudf0b8392025-02-12 18:27:03 +00001914 MinSdkVersionSupported ApiLevel
1915 ModuleWithMinSdkVersionCheck bool
Yu Liu0a37d422025-02-13 02:05:00 +00001916 // Tests if this module can be installed to APEX as a file. For example, this would return
1917 // true for shared libs while return false for static libs because static libs are not
1918 // installable module (but it can still be mutated for APEX)
1919 IsInstallableToApex bool
1920 HideFromMake bool
1921 SkipInstall bool
1922 IsStubsModule bool
1923 Host bool
1924 IsApexModule bool
Yu Liu367827f2025-02-15 00:18:33 +00001925 // The primary licenses property, may be nil, records license metadata for the module.
1926 PrimaryLicensesProperty applicableLicensesProperty
1927 Owner string
Yu Liu64371e02025-02-19 23:44:48 +00001928 Vendor bool
1929 Proprietary bool
1930 SocSpecific bool
1931 ProductSpecific bool
1932 SystemExtSpecific bool
1933 DeviceSpecific bool
1934 // When set to true, this module is not installed to the full install path (ex: under
1935 // out/target/product/<name>/<partition>). It can be installed only to the packaging
1936 // modules like android_filesystem.
1937 NoFullInstall bool
1938 InVendorRamdisk bool
1939 ExemptFromRequiredApplicableLicensesProperty bool
1940 RequiredModuleNames []string
1941 HostRequiredModuleNames []string
1942 TargetRequiredModuleNames []string
1943 VintfFragmentModuleNames []string
1944 Dists []Dist
Yu Liu2a815b62025-02-21 20:46:25 +00001945 ExportedToMake bool
Yu Liu95cef3a2025-02-25 00:54:20 +00001946 Team string
Spandan Das31769ef2025-03-06 00:49:57 +00001947 PartitionTag string
Yu Liudd9ccb42024-10-07 17:07:44 +00001948}
1949
Yu Liu5d3a2cf2025-02-06 00:25:22 +00001950type ApiLevelOrPlatform struct {
1951 ApiLevel *ApiLevel
1952 IsPlatform bool
1953}
1954
Yu Liuf22120f2025-03-13 18:36:35 +00001955var CommonModuleInfoProvider = blueprint.NewProvider[*CommonModuleInfo]()
Yu Liudd9ccb42024-10-07 17:07:44 +00001956
Yu Liu8a8d5b42025-01-07 00:48:08 +00001957type PrebuiltModuleInfo struct {
1958 SourceExists bool
Yu Liu2da9d9a2025-01-15 00:27:02 +00001959 UsePrebuilt bool
Yu Liudd9ccb42024-10-07 17:07:44 +00001960}
1961
Yu Liu8a8d5b42025-01-07 00:48:08 +00001962var PrebuiltModuleInfoProvider = blueprint.NewProvider[PrebuiltModuleInfo]()
Yu Liudd9ccb42024-10-07 17:07:44 +00001963
Yu Liu2da9d9a2025-01-15 00:27:02 +00001964type HostToolProviderInfo struct {
Yu Liudd9ccb42024-10-07 17:07:44 +00001965 HostToolPath OptionalPath
1966}
1967
Yu Liu2da9d9a2025-01-15 00:27:02 +00001968var HostToolProviderInfoProvider = blueprint.NewProvider[HostToolProviderInfo]()
Yu Liudd9ccb42024-10-07 17:07:44 +00001969
Cole Faustd62a4892025-02-07 16:55:11 -08001970type DistInfo struct {
1971 Dists []dist
1972}
1973
1974var DistProvider = blueprint.NewProvider[DistInfo]()
1975
Yu Liu8024b922024-12-20 23:31:32 +00001976type SourceFileGenerator interface {
1977 GeneratedSourceFiles() Paths
1978 GeneratedHeaderDirs() Paths
1979 GeneratedDeps() Paths
1980}
1981
1982type GeneratedSourceInfo struct {
1983 GeneratedSourceFiles Paths
1984 GeneratedHeaderDirs Paths
1985 GeneratedDeps Paths
1986}
1987
1988var GeneratedSourceInfoProvider = blueprint.NewProvider[GeneratedSourceInfo]()
1989
Colin Cross4157e882019-06-06 16:57:04 -07001990func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
Colin Cross25de6c32019-06-06 14:29:25 -07001991 ctx := &moduleContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -07001992 module: m.module,
Colin Crossdc35e212019-06-06 16:13:11 -07001993 bp: blueprintCtx,
Colin Cross0ea8ba82019-06-06 14:33:29 -07001994 baseModuleContext: m.baseModuleContextFactory(blueprintCtx),
Colin Cross0ea8ba82019-06-06 14:33:29 -07001995 variables: make(map[string]string),
Yu Liu54513622024-08-19 20:00:32 +00001996 phonies: make(map[string]Paths),
Colin Cross3f40fa42015-01-30 17:27:36 -08001997 }
1998
Jihoon Kangc3d4e112024-06-24 22:16:27 +00001999 setContainerInfo(ctx)
Jihoon Kang85bc1932024-07-01 17:04:46 +00002000 if ctx.Config().Getenv("DISABLE_CONTAINER_CHECK") != "true" {
2001 checkContainerViolations(ctx)
2002 }
Jihoon Kangc3d4e112024-06-24 22:16:27 +00002003
Yu Liuec810542024-08-26 18:09:15 +00002004 ctx.licenseMetadataFile = PathForModuleOut(ctx, "meta_lic")
Colin Crossaa1cab02022-01-28 14:49:24 -08002005
Colin Crossffe6b9d2020-12-01 15:40:06 -08002006 dependencyInstallFiles, dependencyPackagingSpecs := m.computeInstallDeps(ctx)
Yu Liubad1eef2024-08-21 22:37:35 +00002007 // set the TransitiveInstallFiles to only the transitive dependencies to be used as the dependencies
Colin Cross5d583952020-11-24 16:21:24 -08002008 // of installed files of this module. It will be replaced by a depset including the installed
2009 // files of this module at the end for use by modules that depend on this one.
Colin Crossa14fb6a2024-10-23 16:57:06 -07002010 ctx.TransitiveInstallFiles = depset.New[InstallPath](depset.TOPOLOGICAL, nil, dependencyInstallFiles)
Colin Cross5d583952020-11-24 16:21:24 -08002011
Colin Cross6c4f21f2019-06-06 15:41:36 -07002012 // Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never
2013 // reporting missing dependency errors in Blueprint when AllowMissingDependencies == true.
2014 // TODO: This will be removed once defaults modules handle missing dependency errors
2015 blueprintCtx.GetMissingDependencies()
2016
Colin Crossdc35e212019-06-06 16:13:11 -07002017 // For the final GenerateAndroidBuildActions pass, require that all visited dependencies Soong modules and
Paul Duffin1356d8c2020-02-25 19:26:33 +00002018 // are enabled. Unless the module is a CommonOS variant which may have dependencies on disabled variants
2019 // (because the dependencies are added before the modules are disabled). The
2020 // GetOsSpecificVariantsOfCommonOSVariant(...) method will ensure that the disabled variants are
2021 // ignored.
2022 ctx.baseModuleContext.strictVisitDeps = !m.IsCommonOSVariant()
Colin Crossdc35e212019-06-06 16:13:11 -07002023
Colin Cross4c83e5c2019-02-25 14:54:28 -08002024 if ctx.config.captureBuild {
2025 ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
2026 }
2027
Colin Cross67a5c132017-05-09 13:45:28 -07002028 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
2029 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -08002030 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
2031 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -07002032 }
Colin Cross0875c522017-11-28 17:34:01 -08002033 if !ctx.PrimaryArch() {
2034 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -07002035 }
Colin Crossff694a82023-12-13 15:54:49 -08002036 if apexInfo, _ := ModuleProvider(ctx, ApexInfoProvider); !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -07002037 suffix = append(suffix, apexInfo.ApexVariationName)
Dan Willemsenb13a9482020-02-14 11:25:54 -08002038 }
Colin Cross67a5c132017-05-09 13:45:28 -07002039
2040 ctx.Variable(pctx, "moduleDesc", desc)
2041
2042 s := ""
2043 if len(suffix) > 0 {
2044 s = " [" + strings.Join(suffix, " ") + "]"
2045 }
2046 ctx.Variable(pctx, "moduleDescSuffix", s)
2047
Dan Willemsen569edc52018-11-19 09:33:29 -08002048 // Some common property checks for properties that will be used later in androidmk.go
Paul Duffin89968e32020-11-23 18:17:03 +00002049 checkDistProperties(ctx, "dist", &m.distProperties.Dist)
Sasha Smundake198eaf2022-08-04 13:07:02 -07002050 for i := range m.distProperties.Dists {
Paul Duffin89968e32020-11-23 18:17:03 +00002051 checkDistProperties(ctx, fmt.Sprintf("dists[%d]", i), &m.distProperties.Dists[i])
Dan Willemsen569edc52018-11-19 09:33:29 -08002052 }
2053
Yu Liubad1eef2024-08-21 22:37:35 +00002054 var installFiles InstallFilesInfo
2055
Cole Fausta963b942024-04-11 17:43:00 -07002056 if m.Enabled(ctx) {
Jooyung Hand48f3c32019-08-23 11:18:57 +09002057 // ensure all direct android.Module deps are enabled
Yu Liu4552aeb2024-11-13 00:59:49 +00002058 ctx.VisitDirectDepsProxy(func(m ModuleProxy) {})
Jooyung Hand48f3c32019-08-23 11:18:57 +09002059
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002060 if m.Device() {
2061 // Handle any init.rc and vintf fragment files requested by the module. All files installed by this
2062 // module will automatically have a dependency on the installed init.rc or vintf fragment file.
2063 // The same init.rc or vintf fragment file may be requested by multiple modules or variants,
2064 // so instead of installing them now just compute the install path and store it for later.
2065 // The full list of all init.rc and vintf fragment install rules will be deduplicated later
2066 // so only a single rule is created for each init.rc or vintf fragment file.
2067
2068 if !m.InVendorRamdisk() {
Inseob Kim713b87d2024-09-13 11:29:54 +09002069 ctx.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc.GetOrDefault(ctx, nil))
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002070 rcDir := PathForModuleInstall(ctx, "etc", "init")
Yu Liu82a6d142024-08-27 19:02:29 +00002071 for _, src := range ctx.initRcPaths {
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002072 installedInitRc := rcDir.Join(ctx, src.Base())
Yu Liu82a6d142024-08-27 19:02:29 +00002073 ctx.katiInitRcInstalls = append(ctx.katiInitRcInstalls, katiInstall{
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002074 from: src,
2075 to: installedInitRc,
2076 })
2077 ctx.PackageFile(rcDir, src.Base(), src)
Yu Liu82a6d142024-08-27 19:02:29 +00002078 ctx.installedInitRcPaths = append(ctx.installedInitRcPaths, installedInitRc)
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002079 }
Yu Liu82a6d142024-08-27 19:02:29 +00002080 installFiles.InitRcPaths = ctx.initRcPaths
2081 installFiles.KatiInitRcInstalls = ctx.katiInitRcInstalls
2082 installFiles.InstalledInitRcPaths = ctx.installedInitRcPaths
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002083 }
2084
Yu Liu82a6d142024-08-27 19:02:29 +00002085 ctx.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments.GetOrDefault(ctx, nil))
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002086 vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest")
Yu Liu82a6d142024-08-27 19:02:29 +00002087 for _, src := range ctx.vintfFragmentsPaths {
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002088 installedVintfFragment := vintfDir.Join(ctx, src.Base())
Yu Liu82a6d142024-08-27 19:02:29 +00002089 ctx.katiVintfInstalls = append(ctx.katiVintfInstalls, katiInstall{
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002090 from: src,
2091 to: installedVintfFragment,
2092 })
2093 ctx.PackageFile(vintfDir, src.Base(), src)
Yu Liu82a6d142024-08-27 19:02:29 +00002094 ctx.installedVintfFragmentsPaths = append(ctx.installedVintfFragmentsPaths, installedVintfFragment)
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002095 }
Yu Liu82a6d142024-08-27 19:02:29 +00002096 installFiles.VintfFragmentsPaths = ctx.vintfFragmentsPaths
2097 installFiles.KatiVintfInstalls = ctx.katiVintfInstalls
2098 installFiles.InstalledVintfFragmentsPaths = ctx.installedVintfFragmentsPaths
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002099 }
2100
Bob Badour37af0462021-01-07 03:34:31 +00002101 licensesPropertyFlattener(ctx)
2102 if ctx.Failed() {
2103 return
2104 }
2105
Joe Onorato349ae8d2024-02-05 22:46:00 +00002106 if jarJarPrefixHandler != nil {
2107 jarJarPrefixHandler(ctx)
2108 if ctx.Failed() {
2109 return
2110 }
2111 }
2112
Justin Yun40182b62024-05-07 10:22:19 +09002113 // Call aconfigUpdateAndroidBuildActions to collect merged aconfig files before being used
2114 // in m.module.GenerateAndroidBuildActions
2115 aconfigUpdateAndroidBuildActions(ctx)
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002116 if ctx.Failed() {
2117 return
2118 }
2119
Yu Liu26a716d2024-08-30 23:40:32 +00002120 m.module.GenerateAndroidBuildActions(ctx)
2121 if ctx.Failed() {
2122 return
Yu Liufa297642024-06-11 00:13:02 +00002123 }
2124
Yu Liu26a716d2024-08-30 23:40:32 +00002125 if x, ok := m.module.(IDEInfo); ok {
2126 var result IdeInfo
2127 x.IDEInfo(ctx, &result)
2128 result.BaseModuleName = x.BaseModuleName()
2129 SetProvider(ctx, IdeInfoProviderKey, result)
LaMont Jonesb5099382024-01-10 23:42:36 +00002130 }
2131
Paul Duffinaf970a22020-11-23 23:32:56 +00002132 // Create the set of tagged dist files after calling GenerateAndroidBuildActions
2133 // as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
2134 // output paths being set which must be done before or during
2135 // GenerateAndroidBuildActions.
Yu Liuec810542024-08-26 18:09:15 +00002136 installFiles.DistFiles = m.GenerateTaggedDistFiles(ctx)
Paul Duffinaf970a22020-11-23 23:32:56 +00002137 if ctx.Failed() {
2138 return
2139 }
2140
Colin Crossa6182ab2024-08-21 10:47:44 -07002141 m.generateVariantTarget(ctx)
2142
Yu Liuec810542024-08-26 18:09:15 +00002143 installFiles.LicenseMetadataFile = ctx.licenseMetadataFile
Yu Liubad1eef2024-08-21 22:37:35 +00002144 installFiles.InstallFiles = ctx.installFiles
2145 installFiles.CheckbuildFiles = ctx.checkbuildFiles
Colin Crossa6182ab2024-08-21 10:47:44 -07002146 installFiles.CheckbuildTarget = ctx.checkbuildTarget
2147 installFiles.UncheckedModule = ctx.uncheckedModule
Yu Liubad1eef2024-08-21 22:37:35 +00002148 installFiles.PackagingSpecs = ctx.packagingSpecs
2149 installFiles.KatiInstalls = ctx.katiInstalls
2150 installFiles.KatiSymlinks = ctx.katiSymlinks
2151 installFiles.TestData = ctx.testData
Colin Crossdc35e212019-06-06 16:13:11 -07002152 } else if ctx.Config().AllowMissingDependencies() {
2153 // If the module is not enabled it will not create any build rules, nothing will call
2154 // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
2155 // and report them as an error even when AllowMissingDependencies = true. Call
2156 // ctx.GetMissingDependencies() here to tell blueprint not to handle them.
2157 ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08002158 }
2159
Yu Liud3228ac2024-11-08 23:11:47 +00002160 if sourceFileProducer, ok := m.module.(SourceFileProducer); ok {
Cole Faust0523b8f2025-03-03 15:11:32 -08002161 srcs := sourceFileProducer.Srcs()
2162 for _, src := range srcs {
2163 if src == nil {
2164 ctx.ModuleErrorf("SourceFileProducer cannot return nil srcs")
2165 return
2166 }
2167 }
Yu Liuc41eae52025-01-14 01:03:08 +00002168 SetProvider(ctx, SourceFilesInfoProvider, SourceFilesInfo{Srcs: sourceFileProducer.Srcs()})
Yu Liud3228ac2024-11-08 23:11:47 +00002169 }
2170
Cole Faust0523b8f2025-03-03 15:11:32 -08002171 m.generateModuleTarget(ctx)
2172 if ctx.Failed() {
2173 return
Colin Cross3f40fa42015-01-30 17:27:36 -08002174 }
Colin Crosscec81712017-07-13 14:43:27 -07002175
Colin Crossa14fb6a2024-10-23 16:57:06 -07002176 ctx.TransitiveInstallFiles = depset.New[InstallPath](depset.TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles)
Yu Liubad1eef2024-08-21 22:37:35 +00002177 installFiles.TransitiveInstallFiles = ctx.TransitiveInstallFiles
Colin Crossa14fb6a2024-10-23 16:57:06 -07002178 installFiles.TransitivePackagingSpecs = depset.New[PackagingSpec](depset.TOPOLOGICAL, ctx.packagingSpecs, dependencyPackagingSpecs)
Colin Cross5d583952020-11-24 16:21:24 -08002179
Yu Liubad1eef2024-08-21 22:37:35 +00002180 SetProvider(ctx, InstallFilesProvider, installFiles)
Yu Liuec810542024-08-26 18:09:15 +00002181 buildLicenseMetadata(ctx, ctx.licenseMetadataFile)
Colin Cross4acaea92021-12-10 23:05:02 +00002182
Jihoon Kangd4063812025-01-24 00:25:30 +00002183 if len(ctx.moduleInfoJSON) > 0 {
2184 for _, moduleInfoJSON := range ctx.moduleInfoJSON {
2185 if moduleInfoJSON.Disabled {
2186 continue
2187 }
2188 var installed InstallPaths
2189 installed = append(installed, ctx.katiInstalls.InstallPaths()...)
2190 installed = append(installed, ctx.katiSymlinks.InstallPaths()...)
2191 installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...)
2192 installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...)
2193 installedStrings := installed.Strings()
Colin Crossd6fd0132023-11-06 13:54:06 -08002194
Jihoon Kangd4063812025-01-24 00:25:30 +00002195 var targetRequired, hostRequired []string
2196 if ctx.Host() {
2197 targetRequired = m.baseProperties.Target_required
2198 } else {
2199 hostRequired = m.baseProperties.Host_required
2200 }
Cole Faust156085b2025-03-04 11:34:55 -08002201 hostRequired = append(hostRequired, moduleInfoJSON.ExtraHostRequired...)
Colin Crossd6fd0132023-11-06 13:54:06 -08002202
Jihoon Kangd4063812025-01-24 00:25:30 +00002203 var data []string
2204 for _, d := range ctx.testData {
2205 data = append(data, d.ToRelativeInstallPath())
2206 }
Colin Crossd6fd0132023-11-06 13:54:06 -08002207
Jihoon Kangd4063812025-01-24 00:25:30 +00002208 if moduleInfoJSON.Uninstallable {
2209 installedStrings = nil
2210 if len(moduleInfoJSON.CompatibilitySuites) == 1 && moduleInfoJSON.CompatibilitySuites[0] == "null-suite" {
2211 moduleInfoJSON.CompatibilitySuites = nil
2212 moduleInfoJSON.TestConfig = nil
2213 moduleInfoJSON.AutoTestConfig = nil
2214 data = nil
2215 }
2216 }
2217
2218 // M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}.
2219 // To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite,
2220 // we add the full test suite to our list. This was inherited from
2221 // AndroidMkEntries.AddCompatibilityTestSuites.
2222 suites := moduleInfoJSON.CompatibilitySuites
2223 if PrefixInList(suites, "mts-") && !InList("mts", suites) {
2224 suites = append(suites, "mts")
2225 }
2226 if PrefixInList(suites, "mcts-") && !InList("mcts", suites) {
2227 suites = append(suites, "mcts")
2228 }
2229 moduleInfoJSON.CompatibilitySuites = suites
2230
2231 required := append(m.RequiredModuleNames(ctx), m.VintfFragmentModuleNames(ctx)...)
2232 required = append(required, moduleInfoJSON.ExtraRequired...)
2233
2234 registerName := moduleInfoJSON.RegisterNameOverride
2235 if len(registerName) == 0 {
2236 registerName = m.moduleInfoRegisterName(ctx, moduleInfoJSON.SubName)
2237 }
2238
2239 moduleName := moduleInfoJSON.ModuleNameOverride
2240 if len(moduleName) == 0 {
2241 moduleName = m.BaseModuleName() + moduleInfoJSON.SubName
2242 }
2243
2244 supportedVariants := moduleInfoJSON.SupportedVariantsOverride
2245 if moduleInfoJSON.SupportedVariantsOverride == nil {
2246 supportedVariants = []string{m.moduleInfoVariant(ctx)}
2247 }
2248
2249 moduleInfoJSON.core = CoreModuleInfoJSON{
2250 RegisterName: registerName,
2251 Path: []string{ctx.ModuleDir()},
2252 Installed: installedStrings,
2253 ModuleName: moduleName,
2254 SupportedVariants: supportedVariants,
2255 TargetDependencies: targetRequired,
2256 HostDependencies: hostRequired,
2257 Data: data,
2258 Required: required,
Colin Crossd6fd0132023-11-06 13:54:06 -08002259 }
2260 }
2261
Yu Liu4297ad92024-08-27 19:50:13 +00002262 SetProvider(ctx, ModuleInfoJSONProvider, ctx.moduleInfoJSON)
Colin Crossd6fd0132023-11-06 13:54:06 -08002263 }
2264
Colin Cross4157e882019-06-06 16:57:04 -07002265 m.buildParams = ctx.buildParams
2266 m.ruleParams = ctx.ruleParams
2267 m.variables = ctx.variables
mrziwange6c85812024-05-22 14:36:09 -07002268
Yu Liu876b7ce2024-08-21 18:20:13 +00002269 outputFiles := ctx.GetOutputFiles()
2270 if outputFiles.DefaultOutputFiles != nil || outputFiles.TaggedOutputFiles != nil {
2271 SetProvider(ctx, OutputFilesProvider, outputFiles)
mrziwange6c85812024-05-22 14:36:09 -07002272 }
Wei Lia1aa2972024-06-21 13:08:51 -07002273
Yu Liu54513622024-08-19 20:00:32 +00002274 if len(ctx.phonies) > 0 {
2275 SetProvider(ctx, ModulePhonyProvider, ModulePhonyInfo{
2276 Phonies: ctx.phonies,
2277 })
2278 }
Cole Faustd62a4892025-02-07 16:55:11 -08002279
2280 if len(ctx.dists) > 0 {
2281 SetProvider(ctx, DistProvider, DistInfo{
2282 Dists: ctx.dists,
2283 })
2284 }
2285
Wei Lia1aa2972024-06-21 13:08:51 -07002286 buildComplianceMetadataProvider(ctx, m)
Yu Liudd9ccb42024-10-07 17:07:44 +00002287
Yu Liub5275322024-11-13 18:40:43 +00002288 commonData := CommonModuleInfo{
Yu Liu367827f2025-02-15 00:18:33 +00002289 Enabled: m.Enabled(ctx),
Yu Liu5697f8f2024-12-13 23:31:08 +00002290 ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt,
Yu Liu8024b922024-12-20 23:31:32 +00002291 Target: m.commonProperties.CompileTarget,
Yu Liu5697f8f2024-12-13 23:31:08 +00002292 SkipAndroidMkProcessing: shouldSkipAndroidMkProcessing(ctx, m),
Yu Liu5697f8f2024-12-13 23:31:08 +00002293 UninstallableApexPlatformVariant: m.commonProperties.UninstallableApexPlatformVariant,
2294 HideFromMake: m.commonProperties.HideFromMake,
2295 SkipInstall: m.commonProperties.SkipInstall,
Yu Liu68a70b72025-01-08 22:54:44 +00002296 Host: m.Host(),
Yu Liu367827f2025-02-15 00:18:33 +00002297 PrimaryLicensesProperty: m.primaryLicensesProperty,
Yu Liu64371e02025-02-19 23:44:48 +00002298 Owner: m.module.Owner(),
2299 SocSpecific: Bool(m.commonProperties.Soc_specific),
2300 Vendor: Bool(m.commonProperties.Vendor),
2301 Proprietary: Bool(m.commonProperties.Proprietary),
2302 ProductSpecific: Bool(m.commonProperties.Product_specific),
2303 SystemExtSpecific: Bool(m.commonProperties.System_ext_specific),
2304 DeviceSpecific: Bool(m.commonProperties.Device_specific),
2305 NoFullInstall: proptools.Bool(m.commonProperties.No_full_install),
2306 InVendorRamdisk: m.InVendorRamdisk(),
2307 ExemptFromRequiredApplicableLicensesProperty: exemptFromRequiredApplicableLicensesProperty(m.module),
2308 RequiredModuleNames: m.module.RequiredModuleNames(ctx),
2309 HostRequiredModuleNames: m.module.HostRequiredModuleNames(),
2310 TargetRequiredModuleNames: m.module.TargetRequiredModuleNames(),
2311 VintfFragmentModuleNames: m.module.VintfFragmentModuleNames(ctx),
2312 Dists: m.Dists(),
Yu Liu2a815b62025-02-21 20:46:25 +00002313 ExportedToMake: m.ExportedToMake(),
Yu Liu95cef3a2025-02-25 00:54:20 +00002314 Team: m.Team(),
Spandan Das31769ef2025-03-06 00:49:57 +00002315 PartitionTag: m.PartitionTag(ctx.DeviceConfig()),
Yu Liudd9ccb42024-10-07 17:07:44 +00002316 }
Yu Liu8f2c5c02024-12-06 00:40:39 +00002317 if mm, ok := m.module.(interface {
2318 MinSdkVersion(ctx EarlyModuleContext) ApiLevel
2319 }); ok {
2320 ver := mm.MinSdkVersion(ctx)
Yu Liu5d3a2cf2025-02-06 00:25:22 +00002321 commonData.MinSdkVersion.ApiLevel = &ver
Yu Liu8f2c5c02024-12-06 00:40:39 +00002322 } else if mm, ok := m.module.(interface{ MinSdkVersion() string }); ok {
Yu Liu5d3a2cf2025-02-06 00:25:22 +00002323 ver := mm.MinSdkVersion()
2324 // Compile against the current platform
2325 if ver == "" {
2326 commonData.MinSdkVersion.IsPlatform = true
2327 } else {
2328 api := ApiLevelFrom(ctx, ver)
2329 commonData.MinSdkVersion.ApiLevel = &api
2330 }
Yu Liu8f2c5c02024-12-06 00:40:39 +00002331 }
2332
Yu Liuf6f85492025-01-13 21:02:36 +00002333 if mm, ok := m.module.(interface {
2334 SdkVersion(ctx EarlyModuleContext) ApiLevel
2335 }); ok {
2336 ver := mm.SdkVersion(ctx)
2337 if !ver.IsNone() {
2338 commonData.SdkVersion = ver.String()
2339 }
2340 } else if mm, ok := m.module.(interface{ SdkVersion() string }); ok {
2341 commonData.SdkVersion = mm.SdkVersion()
2342 }
2343
Yu Liu8f2c5c02024-12-06 00:40:39 +00002344 if am, ok := m.module.(ApexModule); ok {
2345 commonData.CanHaveApexVariants = am.CanHaveApexVariants()
2346 commonData.NotAvailableForPlatform = am.NotAvailableForPlatform()
Yu Liu8024b922024-12-20 23:31:32 +00002347 commonData.NotInPlatform = am.NotInPlatform()
Yu Liudf0b8392025-02-12 18:27:03 +00002348 commonData.MinSdkVersionSupported = am.MinSdkVersionSupported(ctx)
Yu Liu0a37d422025-02-13 02:05:00 +00002349 commonData.IsInstallableToApex = am.IsInstallableToApex()
2350 commonData.IsApexModule = true
Yu Liu8f2c5c02024-12-06 00:40:39 +00002351 }
Yu Liudf0b8392025-02-12 18:27:03 +00002352
2353 if _, ok := m.module.(ModuleWithMinSdkVersionCheck); ok {
2354 commonData.ModuleWithMinSdkVersionCheck = true
2355 }
2356
Yu Liu97880e12025-01-07 19:03:34 +00002357 if st, ok := m.module.(StubsAvailableModule); ok {
2358 commonData.IsStubsModule = st.IsStubsModule()
2359 }
Yu Liu0a37d422025-02-13 02:05:00 +00002360 if mm, ok := m.module.(interface{ BaseModuleName() string }); ok {
2361 commonData.BaseModuleName = mm.BaseModuleName()
2362 }
Yu Liuf22120f2025-03-13 18:36:35 +00002363 SetProvider(ctx, CommonModuleInfoProvider, &commonData)
Yu Liudd9ccb42024-10-07 17:07:44 +00002364 if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil {
Yu Liu8a8d5b42025-01-07 00:48:08 +00002365 SetProvider(ctx, PrebuiltModuleInfoProvider, PrebuiltModuleInfo{
2366 SourceExists: p.Prebuilt().SourceExists(),
Yu Liu2da9d9a2025-01-15 00:27:02 +00002367 UsePrebuilt: p.Prebuilt().UsePrebuilt(),
Yu Liu8a8d5b42025-01-07 00:48:08 +00002368 })
Yu Liudd9ccb42024-10-07 17:07:44 +00002369 }
2370 if h, ok := m.module.(HostToolProvider); ok {
Yu Liu2da9d9a2025-01-15 00:27:02 +00002371 SetProvider(ctx, HostToolProviderInfoProvider, HostToolProviderInfo{
Yu Liudd9ccb42024-10-07 17:07:44 +00002372 HostToolPath: h.HostToolPath()})
2373 }
Yu Liue70976d2024-10-15 20:45:35 +00002374
Yu Liub5275322024-11-13 18:40:43 +00002375 if p, ok := m.module.(AndroidMkProviderInfoProducer); ok && !commonData.SkipAndroidMkProcessing {
Yu Liue70976d2024-10-15 20:45:35 +00002376 SetProvider(ctx, AndroidMkInfoProvider, p.PrepareAndroidMKProviderInfo(ctx.Config()))
2377 }
Yu Liu8024b922024-12-20 23:31:32 +00002378
2379 if s, ok := m.module.(SourceFileGenerator); ok {
2380 SetProvider(ctx, GeneratedSourceInfoProvider, GeneratedSourceInfo{
2381 GeneratedSourceFiles: s.GeneratedSourceFiles(),
2382 GeneratedHeaderDirs: s.GeneratedHeaderDirs(),
2383 GeneratedDeps: s.GeneratedDeps(),
2384 })
2385 }
Yu Liu2a815b62025-02-21 20:46:25 +00002386
Yu Liu71f1ea32025-02-26 23:39:20 +00002387 if m.Enabled(ctx) {
2388 if v, ok := m.module.(ModuleMakeVarsProvider); ok {
2389 SetProvider(ctx, ModuleMakeVarsInfoProvider, v.MakeVars(ctx))
2390 }
2391
2392 if am, ok := m.module.(AndroidMkDataProvider); ok {
2393 SetProvider(ctx, AndroidMkDataInfoProvider, AndroidMkDataInfo{
2394 Class: am.AndroidMk().Class,
2395 })
2396 }
Yu Liu2a815b62025-02-21 20:46:25 +00002397 }
Colin Crossb790b9c2025-03-19 14:12:09 -07002398
2399 m.module.CleanupAfterBuildActions()
Colin Cross3f40fa42015-01-30 17:27:36 -08002400}
2401
Colin Crossb790b9c2025-03-19 14:12:09 -07002402func (m *ModuleBase) CleanupAfterBuildActions() {}
2403
Joe Onorato349ae8d2024-02-05 22:46:00 +00002404func SetJarJarPrefixHandler(handler func(ModuleContext)) {
2405 if jarJarPrefixHandler != nil {
2406 panic("jarJarPrefixHandler already set")
2407 }
2408 jarJarPrefixHandler = handler
2409}
2410
Colin Crossd6fd0132023-11-06 13:54:06 -08002411func (m *ModuleBase) moduleInfoRegisterName(ctx ModuleContext, subName string) string {
2412 name := m.BaseModuleName()
2413
2414 prefix := ""
2415 if ctx.Host() {
2416 if ctx.Os() != ctx.Config().BuildOS {
2417 prefix = "host_cross_"
2418 }
2419 }
2420 suffix := ""
2421 arches := slices.Clone(ctx.Config().Targets[ctx.Os()])
2422 arches = slices.DeleteFunc(arches, func(target Target) bool {
2423 return target.NativeBridge != ctx.Target().NativeBridge
2424 })
Cole Faust866ab392025-01-23 12:56:20 -08002425 if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType && ctx.Arch().ArchType != Common {
Colin Crossd6fd0132023-11-06 13:54:06 -08002426 if ctx.Arch().ArchType.Multilib == "lib32" {
2427 suffix = "_32"
2428 } else {
2429 suffix = "_64"
2430 }
2431 }
2432 return prefix + name + subName + suffix
2433}
2434
2435func (m *ModuleBase) moduleInfoVariant(ctx ModuleContext) string {
2436 variant := "DEVICE"
2437 if ctx.Host() {
2438 if ctx.Os() != ctx.Config().BuildOS {
2439 variant = "HOST_CROSS"
2440 } else {
2441 variant = "HOST"
2442 }
2443 }
2444 return variant
2445}
2446
Paul Duffin89968e32020-11-23 18:17:03 +00002447// Check the supplied dist structure to make sure that it is valid.
2448//
2449// property - the base property, e.g. dist or dists[1], which is combined with the
2450// name of the nested property to produce the full property, e.g. dist.dest or
2451// dists[1].dir.
2452func checkDistProperties(ctx *moduleContext, property string, dist *Dist) {
2453 if dist.Dest != nil {
2454 _, err := validateSafePath(*dist.Dest)
2455 if err != nil {
2456 ctx.PropertyErrorf(property+".dest", "%s", err.Error())
2457 }
2458 }
2459 if dist.Dir != nil {
2460 _, err := validateSafePath(*dist.Dir)
2461 if err != nil {
2462 ctx.PropertyErrorf(property+".dir", "%s", err.Error())
2463 }
2464 }
2465 if dist.Suffix != nil {
2466 if strings.Contains(*dist.Suffix, "/") {
2467 ctx.PropertyErrorf(property+".suffix", "Suffix may not contain a '/' character.")
2468 }
2469 }
2470
2471}
2472
Colin Cross6301c3c2021-09-28 17:40:21 -07002473// katiInstall stores a request from Soong to Make to create an install rule.
2474type katiInstall struct {
2475 from Path
2476 to InstallPath
2477 implicitDeps Paths
2478 orderOnlyDeps Paths
2479 executable bool
Colin Cross50ed1f92021-11-12 17:41:02 -08002480 extraFiles *extraFilesZip
Yu Liu467d7c52024-09-18 21:54:44 +00002481 absFrom string
Colin Cross6301c3c2021-09-28 17:40:21 -07002482}
2483
Yu Liu467d7c52024-09-18 21:54:44 +00002484type katiInstallGob struct {
2485 From Path
2486 To InstallPath
2487 ImplicitDeps Paths
2488 OrderOnlyDeps Paths
2489 Executable bool
2490 ExtraFiles *extraFilesZip
2491 AbsFrom string
Yu Liu26a716d2024-08-30 23:40:32 +00002492}
2493
Yu Liu467d7c52024-09-18 21:54:44 +00002494func (k *katiInstall) ToGob() *katiInstallGob {
2495 return &katiInstallGob{
2496 From: k.from,
2497 To: k.to,
2498 ImplicitDeps: k.implicitDeps,
2499 OrderOnlyDeps: k.orderOnlyDeps,
2500 Executable: k.executable,
2501 ExtraFiles: k.extraFiles,
2502 AbsFrom: k.absFrom,
Yu Liu26a716d2024-08-30 23:40:32 +00002503 }
Yu Liu467d7c52024-09-18 21:54:44 +00002504}
Yu Liu26a716d2024-08-30 23:40:32 +00002505
Yu Liu467d7c52024-09-18 21:54:44 +00002506func (k *katiInstall) FromGob(data *katiInstallGob) {
2507 k.from = data.From
2508 k.to = data.To
2509 k.implicitDeps = data.ImplicitDeps
2510 k.orderOnlyDeps = data.OrderOnlyDeps
2511 k.executable = data.Executable
2512 k.extraFiles = data.ExtraFiles
2513 k.absFrom = data.AbsFrom
2514}
2515
2516func (k *katiInstall) GobEncode() ([]byte, error) {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002517 return gobtools.CustomGobEncode[katiInstallGob](k)
Yu Liu467d7c52024-09-18 21:54:44 +00002518}
2519
2520func (k *katiInstall) GobDecode(data []byte) error {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002521 return gobtools.CustomGobDecode[katiInstallGob](data, k)
Yu Liu26a716d2024-08-30 23:40:32 +00002522}
2523
Colin Cross50ed1f92021-11-12 17:41:02 -08002524type extraFilesZip struct {
2525 zip Path
2526 dir InstallPath
2527}
2528
Yu Liu467d7c52024-09-18 21:54:44 +00002529type extraFilesZipGob struct {
2530 Zip Path
2531 Dir InstallPath
Yu Liu26a716d2024-08-30 23:40:32 +00002532}
2533
Yu Liu467d7c52024-09-18 21:54:44 +00002534func (e *extraFilesZip) ToGob() *extraFilesZipGob {
2535 return &extraFilesZipGob{
2536 Zip: e.zip,
2537 Dir: e.dir,
Yu Liu26a716d2024-08-30 23:40:32 +00002538 }
Yu Liu467d7c52024-09-18 21:54:44 +00002539}
Yu Liu26a716d2024-08-30 23:40:32 +00002540
Yu Liu467d7c52024-09-18 21:54:44 +00002541func (e *extraFilesZip) FromGob(data *extraFilesZipGob) {
2542 e.zip = data.Zip
2543 e.dir = data.Dir
2544}
2545
2546func (e *extraFilesZip) GobEncode() ([]byte, error) {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002547 return gobtools.CustomGobEncode[extraFilesZipGob](e)
Yu Liu467d7c52024-09-18 21:54:44 +00002548}
2549
2550func (e *extraFilesZip) GobDecode(data []byte) error {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002551 return gobtools.CustomGobDecode[extraFilesZipGob](data, e)
Yu Liu26a716d2024-08-30 23:40:32 +00002552}
2553
Colin Cross6301c3c2021-09-28 17:40:21 -07002554type katiInstalls []katiInstall
2555
2556// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
2557// space separated list of from:to tuples.
2558func (installs katiInstalls) BuiltInstalled() string {
2559 sb := strings.Builder{}
2560 for i, install := range installs {
2561 if i != 0 {
2562 sb.WriteRune(' ')
2563 }
2564 sb.WriteString(install.from.String())
2565 sb.WriteRune(':')
2566 sb.WriteString(install.to.String())
2567 }
2568 return sb.String()
2569}
2570
2571// InstallPaths returns the install path of each entry.
2572func (installs katiInstalls) InstallPaths() InstallPaths {
2573 paths := make(InstallPaths, 0, len(installs))
2574 for _, install := range installs {
2575 paths = append(paths, install.to)
2576 }
2577 return paths
2578}
2579
Jiyong Park5baac542018-08-28 09:55:37 +09002580// Makes this module a platform module, i.e. not specific to soc, device,
Justin Yund5f6c822019-06-25 16:47:17 +09002581// product, or system_ext.
Colin Cross4157e882019-06-06 16:57:04 -07002582func (m *ModuleBase) MakeAsPlatform() {
2583 m.commonProperties.Vendor = boolPtr(false)
2584 m.commonProperties.Proprietary = boolPtr(false)
2585 m.commonProperties.Soc_specific = boolPtr(false)
2586 m.commonProperties.Product_specific = boolPtr(false)
Justin Yund5f6c822019-06-25 16:47:17 +09002587 m.commonProperties.System_ext_specific = boolPtr(false)
Jiyong Park5baac542018-08-28 09:55:37 +09002588}
2589
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09002590func (m *ModuleBase) MakeAsSystemExt() {
Jooyung Han91df2082019-11-20 01:49:42 +09002591 m.commonProperties.Vendor = boolPtr(false)
2592 m.commonProperties.Proprietary = boolPtr(false)
2593 m.commonProperties.Soc_specific = boolPtr(false)
2594 m.commonProperties.Product_specific = boolPtr(false)
2595 m.commonProperties.System_ext_specific = boolPtr(true)
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09002596}
2597
Jooyung Han344d5432019-08-23 11:17:39 +09002598// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true"
2599func (m *ModuleBase) IsNativeBridgeSupported() bool {
2600 return proptools.Bool(m.commonProperties.Native_bridge_supported)
2601}
2602
Jihoon Kang0d545b82024-10-11 00:21:57 +00002603func (m *ModuleBase) DecodeMultilib(ctx ConfigContext) (string, string) {
2604 return decodeMultilib(ctx, m)
2605}
2606
Spandan Dase1860e42024-10-24 22:29:50 +00002607func (m *ModuleBase) Overrides() []string {
2608 return m.commonProperties.Overrides
2609}
2610
Justin Yunbe6f81d2024-12-17 21:15:59 +09002611func (m *ModuleBase) UseGenericConfig() bool {
2612 return proptools.Bool(m.commonProperties.Use_generic_config)
2613}
2614
Colin Cross8bbc3d52024-09-11 15:33:54 -07002615type ConfigContext interface {
2616 Config() Config
2617}
2618
Cole Fauste8a87832024-09-11 11:35:46 -07002619type ConfigurableEvaluatorContext interface {
Cole Faust55b56fe2024-08-23 12:06:11 -07002620 OtherModuleProviderContext
Cole Faust02987bd2024-03-21 17:58:43 -07002621 Config() Config
2622 OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{})
Cole Faustd7067092024-09-13 13:37:59 -07002623 HasMutatorFinished(mutatorName string) bool
Cole Faust02987bd2024-03-21 17:58:43 -07002624}
2625
2626type configurationEvalutor struct {
Cole Fauste8a87832024-09-11 11:35:46 -07002627 ctx ConfigurableEvaluatorContext
Cole Faust02987bd2024-03-21 17:58:43 -07002628 m Module
2629}
2630
Cole Fauste8a87832024-09-11 11:35:46 -07002631func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator {
Cole Faust02987bd2024-03-21 17:58:43 -07002632 return configurationEvalutor{
2633 ctx: ctx,
2634 m: m.module,
2635 }
2636}
2637
2638func (e configurationEvalutor) PropertyErrorf(property string, fmt string, args ...interface{}) {
Cole Fausta963b942024-04-11 17:43:00 -07002639 e.ctx.OtherModulePropertyErrorf(e.m, property, fmt, args...)
Cole Faust02987bd2024-03-21 17:58:43 -07002640}
2641
Cole Faustfdbf5d42024-04-10 15:01:23 -07002642func (e configurationEvalutor) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue {
Cole Faust02987bd2024-03-21 17:58:43 -07002643 ctx := e.ctx
2644 m := e.m
Cole Faustd7067092024-09-13 13:37:59 -07002645
2646 if !ctx.HasMutatorFinished("defaults") {
2647 ctx.OtherModulePropertyErrorf(m, property, "Cannot evaluate configurable property before the defaults mutator has run")
2648 return proptools.ConfigurableValueUndefined()
2649 }
2650
Cole Faust8afc5142024-04-26 16:30:19 -07002651 switch condition.FunctionName() {
Cole Fauste19f7412024-05-09 15:14:04 -07002652 case "release_flag":
Cole Faust8afc5142024-04-26 16:30:19 -07002653 if condition.NumArgs() != 1 {
Cole Fauste19f7412024-05-09 15:14:04 -07002654 ctx.OtherModulePropertyErrorf(m, property, "release_flag requires 1 argument, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002655 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002656 }
Cole Faust751a4a52024-05-21 16:51:59 -07002657 if ty, ok := ctx.Config().productVariables.BuildFlagTypes[condition.Arg(0)]; ok {
2658 v := ctx.Config().productVariables.BuildFlags[condition.Arg(0)]
2659 switch ty {
2660 case "unspecified", "obsolete":
2661 return proptools.ConfigurableValueUndefined()
2662 case "string":
2663 return proptools.ConfigurableValueString(v)
2664 case "bool":
2665 return proptools.ConfigurableValueBool(v == "true")
2666 default:
2667 panic("unhandled release flag type: " + ty)
2668 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002669 }
2670 return proptools.ConfigurableValueUndefined()
2671 case "product_variable":
Jiyong Parke3250752024-05-17 14:56:10 +09002672 if condition.NumArgs() != 1 {
2673 ctx.OtherModulePropertyErrorf(m, property, "product_variable requires 1 argument, found %d", condition.NumArgs())
2674 return proptools.ConfigurableValueUndefined()
2675 }
2676 variable := condition.Arg(0)
2677 switch variable {
Jihoon Kang82bea762024-09-30 18:50:54 +00002678 case "build_from_text_stub":
2679 return proptools.ConfigurableValueBool(ctx.Config().BuildFromTextStub())
Jiyong Parke3250752024-05-17 14:56:10 +09002680 case "debuggable":
2681 return proptools.ConfigurableValueBool(ctx.Config().Debuggable())
kellyhungf833fba2025-01-14 10:05:46 +00002682 case "eng":
2683 return proptools.ConfigurableValueBool(ctx.Config().Eng())
Kiyoung Kim881e4652024-07-08 11:02:23 +09002684 case "use_debug_art":
2685 // TODO(b/234351700): Remove once ART does not have separated debug APEX
2686 return proptools.ConfigurableValueBool(ctx.Config().UseDebugArt())
kellyhung1e613d22024-07-29 12:56:51 +00002687 case "selinux_ignore_neverallows":
2688 return proptools.ConfigurableValueBool(ctx.Config().SelinuxIgnoreNeverallows())
Spandan Dasdd604262025-03-14 18:27:33 +00002689 case "always_use_prebuilt_sdks":
2690 return proptools.ConfigurableValueBool(ctx.Config().AlwaysUsePrebuiltSdks())
Jiyong Parke3250752024-05-17 14:56:10 +09002691 default:
2692 // TODO(b/323382414): Might add these on a case-by-case basis
2693 ctx.OtherModulePropertyErrorf(m, property, fmt.Sprintf("TODO(b/323382414): Product variable %q is not yet supported in selects", variable))
2694 return proptools.ConfigurableValueUndefined()
2695 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002696 case "soong_config_variable":
Cole Faust8afc5142024-04-26 16:30:19 -07002697 if condition.NumArgs() != 2 {
2698 ctx.OtherModulePropertyErrorf(m, property, "soong_config_variable requires 2 arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002699 return proptools.ConfigurableValueUndefined()
2700 }
Cole Faust8afc5142024-04-26 16:30:19 -07002701 namespace := condition.Arg(0)
2702 variable := condition.Arg(1)
Cole Faust02987bd2024-03-21 17:58:43 -07002703 if n, ok := ctx.Config().productVariables.VendorVars[namespace]; ok {
2704 if v, ok := n[variable]; ok {
Cole Faust46f6e2f2024-06-20 12:57:43 -07002705 ty := ""
2706 if namespaces, ok := ctx.Config().productVariables.VendorVarTypes[namespace]; ok {
2707 ty = namespaces[variable]
2708 }
2709 switch ty {
2710 case "":
2711 // strings are the default, we don't bother writing them to the soong variables json file
2712 return proptools.ConfigurableValueString(v)
2713 case "bool":
2714 return proptools.ConfigurableValueBool(v == "true")
Cole Faust764aaca2025-03-18 11:24:39 -07002715 case "int":
2716 i, err := strconv.ParseInt(v, 10, 64)
2717 if err != nil {
2718 ctx.OtherModulePropertyErrorf(m, property, "integer soong_config_variable was not an int: %q", v)
2719 return proptools.ConfigurableValueUndefined()
2720 }
2721 return proptools.ConfigurableValueInt(i)
Cole Faust4143ee82024-11-21 11:20:06 -08002722 case "string_list":
2723 return proptools.ConfigurableValueStringList(strings.Split(v, " "))
Cole Faust46f6e2f2024-06-20 12:57:43 -07002724 default:
2725 panic("unhandled soong config variable type: " + ty)
2726 }
2727
Cole Faust02987bd2024-03-21 17:58:43 -07002728 }
2729 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002730 return proptools.ConfigurableValueUndefined()
Cole Faustfc57d402024-04-11 12:09:44 -07002731 case "arch":
Cole Faust8afc5142024-04-26 16:30:19 -07002732 if condition.NumArgs() != 0 {
2733 ctx.OtherModulePropertyErrorf(m, property, "arch requires no arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002734 return proptools.ConfigurableValueUndefined()
2735 }
Cole Faustfc57d402024-04-11 12:09:44 -07002736 if !m.base().ArchReady() {
2737 ctx.OtherModulePropertyErrorf(m, property, "A select on arch was attempted before the arch mutator ran")
2738 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002739 }
Cole Faustfc57d402024-04-11 12:09:44 -07002740 return proptools.ConfigurableValueString(m.base().Arch().ArchType.Name)
2741 case "os":
Cole Faust8afc5142024-04-26 16:30:19 -07002742 if condition.NumArgs() != 0 {
2743 ctx.OtherModulePropertyErrorf(m, property, "os requires no arguments, found %d", condition.NumArgs())
Cole Faustfc57d402024-04-11 12:09:44 -07002744 return proptools.ConfigurableValueUndefined()
2745 }
2746 // the arch mutator runs after the os mutator, we can just use this to enforce that os is ready.
2747 if !m.base().ArchReady() {
2748 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)")
2749 return proptools.ConfigurableValueUndefined()
2750 }
2751 return proptools.ConfigurableValueString(m.base().Os().Name)
Cole Faustfdbf5d42024-04-10 15:01:23 -07002752 case "boolean_var_for_testing":
2753 // We currently don't have any other boolean variables (we should add support for typing
2754 // the soong config variables), so add this fake one for testing the boolean select
2755 // functionality.
Cole Faust8afc5142024-04-26 16:30:19 -07002756 if condition.NumArgs() != 0 {
2757 ctx.OtherModulePropertyErrorf(m, property, "boolean_var_for_testing requires 0 arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002758 return proptools.ConfigurableValueUndefined()
2759 }
2760
2761 if n, ok := ctx.Config().productVariables.VendorVars["boolean_var"]; ok {
2762 if v, ok := n["for_testing"]; ok {
2763 switch v {
2764 case "true":
2765 return proptools.ConfigurableValueBool(true)
2766 case "false":
2767 return proptools.ConfigurableValueBool(false)
2768 default:
2769 ctx.OtherModulePropertyErrorf(m, property, "testing:my_boolean_var can only be true or false, found %q", v)
2770 }
2771 }
2772 }
2773 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002774 default:
Cole Faustfdbf5d42024-04-10 15:01:23 -07002775 ctx.OtherModulePropertyErrorf(m, property, "Unknown select condition %s", condition.FunctionName)
2776 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002777 }
2778}
2779
Colin Crossb63d7b32023-12-07 16:54:51 -08002780// ModuleNameWithPossibleOverride returns the name of the OverrideModule that overrides the current
2781// variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule
2782// or if this variant is not overridden.
2783func ModuleNameWithPossibleOverride(ctx BaseModuleContext) string {
2784 if overridable, ok := ctx.Module().(OverridableModule); ok {
2785 if o := overridable.GetOverriddenBy(); o != "" {
2786 return o
2787 }
2788 }
2789 return ctx.ModuleName()
2790}
2791
Paul Duffine6ba0722021-07-12 20:12:12 +01002792// SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name"
2793// into the module name, or empty string if the input was not a module reference.
Colin Cross41955e82019-05-29 14:40:35 -07002794func SrcIsModule(s string) (module string) {
Paul Duffine6ba0722021-07-12 20:12:12 +01002795 if len(s) > 1 {
2796 if s[0] == ':' {
2797 module = s[1:]
2798 if !isUnqualifiedModuleName(module) {
2799 // The module name should be unqualified but is not so do not treat it as a module.
2800 module = ""
2801 }
2802 } else if s[0] == '/' && s[1] == '/' {
2803 module = s
2804 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002805 }
Paul Duffine6ba0722021-07-12 20:12:12 +01002806 return module
Colin Cross068e0fe2016-12-13 15:23:47 -08002807}
2808
Yi-Yo Chiangba9ea322021-07-15 17:18:21 +08002809// SrcIsModuleWithTag decodes module references in the format ":unqualified-name{.tag}" or
2810// "//namespace:name{.tag}" into the module name and tag, ":unqualified-name" or "//namespace:name"
2811// into the module name and an empty string for the tag, or empty strings if the input was not a
2812// module reference.
Colin Cross41955e82019-05-29 14:40:35 -07002813func SrcIsModuleWithTag(s string) (module, tag string) {
Paul Duffine6ba0722021-07-12 20:12:12 +01002814 if len(s) > 1 {
2815 if s[0] == ':' {
2816 module = s[1:]
2817 } else if s[0] == '/' && s[1] == '/' {
2818 module = s
2819 }
2820
2821 if module != "" {
2822 if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
2823 if module[len(module)-1] == '}' {
2824 tag = module[tagStart+1 : len(module)-1]
2825 module = module[:tagStart]
2826 }
2827 }
2828
2829 if s[0] == ':' && !isUnqualifiedModuleName(module) {
2830 // The module name should be unqualified but is not so do not treat it as a module.
2831 module = ""
2832 tag = ""
Colin Cross41955e82019-05-29 14:40:35 -07002833 }
2834 }
Colin Cross41955e82019-05-29 14:40:35 -07002835 }
Paul Duffine6ba0722021-07-12 20:12:12 +01002836
2837 return module, tag
2838}
2839
2840// isUnqualifiedModuleName makes sure that the supplied module is an unqualified module name, i.e.
2841// does not contain any /.
2842func isUnqualifiedModuleName(module string) bool {
2843 return strings.IndexByte(module, '/') == -1
Colin Cross068e0fe2016-12-13 15:23:47 -08002844}
2845
Paul Duffin40131a32021-07-09 17:10:35 +01002846// sourceOrOutputDependencyTag is the dependency tag added automatically by pathDepsMutator for any
2847// module reference in a property annotated with `android:"path"` or passed to ExtractSourceDeps
2848// or ExtractSourcesDeps.
2849//
2850// If uniquely identifies the dependency that was added as it contains both the module name used to
2851// add the dependency as well as the tag. That makes it very simple to find the matching dependency
2852// in GetModuleFromPathDep as all it needs to do is find the dependency whose tag matches the tag
2853// used to add it. It does not need to check that the module name as returned by one of
2854// Module.Name(), BaseModuleContext.OtherModuleName() or ModuleBase.BaseModuleName() matches the
2855// name supplied in the tag. That means it does not need to handle differences in module names
2856// caused by prebuilt_ prefix, or fully qualified module names.
Colin Cross41955e82019-05-29 14:40:35 -07002857type sourceOrOutputDependencyTag struct {
2858 blueprint.BaseDependencyTag
Yu Liu67a28422024-03-05 00:36:31 +00002859 AlwaysPropagateAconfigValidationDependencyTag
Paul Duffin40131a32021-07-09 17:10:35 +01002860
2861 // The name of the module.
2862 moduleName string
2863
mrziwangd38e63d2024-07-15 13:43:37 -07002864 // The tag that will be used to get the specific output file(s).
Colin Cross41955e82019-05-29 14:40:35 -07002865 tag string
2866}
2867
Paul Duffin40131a32021-07-09 17:10:35 +01002868func sourceOrOutputDepTag(moduleName, tag string) blueprint.DependencyTag {
2869 return sourceOrOutputDependencyTag{moduleName: moduleName, tag: tag}
Colin Cross41955e82019-05-29 14:40:35 -07002870}
2871
Paul Duffind5cf92e2021-07-09 17:38:55 +01002872// IsSourceDepTagWithOutputTag returns true if the supplied blueprint.DependencyTag is one that was
2873// used to add dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for
2874// properties tagged with `android:"path"` AND it was added using a module reference of
2875// :moduleName{outputTag}.
2876func IsSourceDepTagWithOutputTag(depTag blueprint.DependencyTag, outputTag string) bool {
2877 t, ok := depTag.(sourceOrOutputDependencyTag)
2878 return ok && t.tag == outputTag
2879}
2880
Colin Cross366938f2017-12-11 16:29:02 -08002881// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
2882// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08002883//
2884// Deprecated: tag the property with `android:"path"` instead.
Colin Cross068e0fe2016-12-13 15:23:47 -08002885func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
Nan Zhang2439eb72017-04-10 11:27:50 -07002886 set := make(map[string]bool)
2887
Colin Cross068e0fe2016-12-13 15:23:47 -08002888 for _, s := range srcFiles {
Colin Cross41955e82019-05-29 14:40:35 -07002889 if m, t := SrcIsModuleWithTag(s); m != "" {
2890 if _, found := set[s]; found {
2891 ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
Nan Zhang2439eb72017-04-10 11:27:50 -07002892 } else {
Colin Cross41955e82019-05-29 14:40:35 -07002893 set[s] = true
Paul Duffin40131a32021-07-09 17:10:35 +01002894 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
Nan Zhang2439eb72017-04-10 11:27:50 -07002895 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002896 }
2897 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002898}
2899
Colin Cross366938f2017-12-11 16:29:02 -08002900// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
2901// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08002902//
2903// Deprecated: tag the property with `android:"path"` instead.
Colin Cross366938f2017-12-11 16:29:02 -08002904func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
2905 if s != nil {
Colin Cross41955e82019-05-29 14:40:35 -07002906 if m, t := SrcIsModuleWithTag(*s); m != "" {
Paul Duffin40131a32021-07-09 17:10:35 +01002907 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
Colin Cross366938f2017-12-11 16:29:02 -08002908 }
2909 }
2910}
2911
Colin Cross41955e82019-05-29 14:40:35 -07002912// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"`
2913// 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 -08002914type SourceFileProducer interface {
2915 Srcs() Paths
2916}
2917
mrziwangd38e63d2024-07-15 13:43:37 -07002918// OutputFilesForModule returns the output file paths with the given tag. On error, including if the
Colin Cross5e708052019-08-06 13:59:50 -07002919// module produced zero paths, it reports errors to the ctx and returns nil.
Yu Liud3228ac2024-11-08 23:11:47 +00002920func OutputFilesForModule(ctx PathContext, module Module, tag string) Paths {
Colin Cross5e708052019-08-06 13:59:50 -07002921 paths, err := outputFilesForModule(ctx, module, tag)
2922 if err != nil {
2923 reportPathError(ctx, err)
2924 return nil
2925 }
2926 return paths
2927}
2928
mrziwangd38e63d2024-07-15 13:43:37 -07002929// OutputFileForModule returns the output file paths with the given tag. On error, including if the
Colin Cross5e708052019-08-06 13:59:50 -07002930// module produced zero or multiple paths, it reports errors to the ctx and returns nil.
Yu Liu2a815b62025-02-21 20:46:25 +00002931// TODO(b/397766191): Change the signature to take ModuleProxy
2932// Please only access the module's internal data through providers.
Yu Liud3228ac2024-11-08 23:11:47 +00002933func OutputFileForModule(ctx PathContext, module Module, tag string) Path {
Colin Cross5e708052019-08-06 13:59:50 -07002934 paths, err := outputFilesForModule(ctx, module, tag)
2935 if err != nil {
2936 reportPathError(ctx, err)
2937 return nil
2938 }
Colin Cross14ec66c2022-10-03 21:02:27 -07002939 if len(paths) == 0 {
2940 type addMissingDependenciesIntf interface {
2941 AddMissingDependencies([]string)
2942 OtherModuleName(blueprint.Module) string
2943 }
2944 if mctx, ok := ctx.(addMissingDependenciesIntf); ok && ctx.Config().AllowMissingDependencies() {
2945 mctx.AddMissingDependencies([]string{mctx.OtherModuleName(module)})
2946 } else {
2947 ReportPathErrorf(ctx, "failed to get output files from module %q", pathContextName(ctx, module))
2948 }
2949 // Return a fake output file to avoid nil dereferences of Path objects later.
2950 // This should never get used for an actual build as the error or missing
2951 // dependency has already been reported.
2952 p, err := pathForSource(ctx, filepath.Join("missing_output_file", pathContextName(ctx, module)))
2953 if err != nil {
2954 reportPathError(ctx, err)
2955 return nil
2956 }
2957 return p
2958 }
Colin Cross5e708052019-08-06 13:59:50 -07002959 if len(paths) > 1 {
Ulya Trafimovich5ab276a2020-08-25 12:45:15 +01002960 ReportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
Colin Cross5e708052019-08-06 13:59:50 -07002961 pathContextName(ctx, module))
Colin Cross5e708052019-08-06 13:59:50 -07002962 }
2963 return paths[0]
2964}
2965
Yu Liud3228ac2024-11-08 23:11:47 +00002966type OutputFilesProviderModuleContext interface {
2967 OtherModuleProviderContext
2968 Module() Module
2969 GetOutputFiles() OutputFilesInfo
Yu Liud3228ac2024-11-08 23:11:47 +00002970}
2971
Yu Liu2a815b62025-02-21 20:46:25 +00002972// TODO(b/397766191): Change the signature to take ModuleProxy
2973// Please only access the module's internal data through providers.
Yu Liud3228ac2024-11-08 23:11:47 +00002974func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, error) {
mrziwange6c85812024-05-22 14:36:09 -07002975 outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag)
mrziwangabdb2932024-06-18 12:43:41 -07002976 if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet {
mrziwange6c85812024-05-22 14:36:09 -07002977 return outputFilesFromProvider, err
2978 }
Yu Liud3228ac2024-11-08 23:11:47 +00002979
2980 if octx, ok := ctx.(OutputFilesProviderModuleContext); ok {
Yu Liue472c1d2025-02-26 20:13:04 +00002981 if EqualModules(octx.Module(), module) {
Yu Liu5697f8f2024-12-13 23:31:08 +00002982 // It is the current module, we can access the srcs through interface
Yu Liud3228ac2024-11-08 23:11:47 +00002983 if sourceFileProducer, ok := module.(SourceFileProducer); ok {
2984 return sourceFileProducer.Srcs(), nil
2985 }
Yu Liuc41eae52025-01-14 01:03:08 +00002986 } else if sourceFiles, ok := OtherModuleProvider(octx, module, SourceFilesInfoProvider); ok {
Yu Liud3228ac2024-11-08 23:11:47 +00002987 if tag != "" {
2988 return nil, fmt.Errorf("module %q is a SourceFileProducer, which does not support tag %q", pathContextName(ctx, module), tag)
2989 }
2990 paths := sourceFiles.Srcs
2991 return paths, nil
Colin Cross74b1e2b2020-11-22 20:23:02 -08002992 }
Colin Cross5e708052019-08-06 13:59:50 -07002993 }
Yu Liud3228ac2024-11-08 23:11:47 +00002994
2995 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 -07002996}
2997
mrziwange6c85812024-05-22 14:36:09 -07002998// This method uses OutputFilesProvider for output files
2999// *inter-module-communication*.
3000// If mctx module is the same as the param module the output files are obtained
3001// from outputFiles property of module base, to avoid both setting and
mrziwang42953592024-06-20 09:53:33 -07003002// reading OutputFilesProvider before GenerateBuildActions is finished.
mrziwange6c85812024-05-22 14:36:09 -07003003// If a module doesn't have the OutputFilesProvider, nil is returned.
Yu Liud3228ac2024-11-08 23:11:47 +00003004func outputFilesForModuleFromProvider(ctx PathContext, module Module, tag string) (Paths, error) {
mrziwangabdb2932024-06-18 12:43:41 -07003005 var outputFiles OutputFilesInfo
mrziwang0cbd3b02024-06-20 16:39:25 -07003006
mrziwang1ea01e32024-07-12 12:26:34 -07003007 if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx {
Yu Liue472c1d2025-02-26 20:13:04 +00003008 if !EqualModules(mctx.Module(), module) {
mrziwangabdb2932024-06-18 12:43:41 -07003009 outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider)
mrziwang0cbd3b02024-06-20 16:39:25 -07003010 } else {
Yu Liu876b7ce2024-08-21 18:20:13 +00003011 outputFiles = mctx.GetOutputFiles()
mrziwange6c85812024-05-22 14:36:09 -07003012 }
mrziwang0cbd3b02024-06-20 16:39:25 -07003013 } else if cta, isCta := ctx.(*singletonContextAdaptor); isCta {
Yu Liud3228ac2024-11-08 23:11:47 +00003014 outputFiles, _ = OtherModuleProvider(cta, module, OutputFilesProvider)
mrziwang7a47bd32024-07-17 11:11:05 -07003015 } else {
3016 return nil, fmt.Errorf("unsupported context %q in method outputFilesForModuleFromProvider", reflect.TypeOf(ctx))
mrziwang0cbd3b02024-06-20 16:39:25 -07003017 }
mrziwang0cbd3b02024-06-20 16:39:25 -07003018
mrziwangabdb2932024-06-18 12:43:41 -07003019 if outputFiles.isEmpty() {
mrziwangabdb2932024-06-18 12:43:41 -07003020 return nil, OutputFilesProviderNotSet
3021 }
3022
3023 if tag == "" {
3024 return outputFiles.DefaultOutputFiles, nil
3025 } else if taggedOutputFiles, hasTag := outputFiles.TaggedOutputFiles[tag]; hasTag {
3026 return taggedOutputFiles, nil
3027 } else {
Cole Fausta8437c52025-02-25 14:45:43 -08003028 return nil, UnsupportedOutputTagError{
3029 tag: tag,
mrziwange6c85812024-05-22 14:36:09 -07003030 }
3031 }
mrziwange6c85812024-05-22 14:36:09 -07003032}
3033
mrziwang0cbd3b02024-06-20 16:39:25 -07003034func (o OutputFilesInfo) isEmpty() bool {
3035 return o.DefaultOutputFiles == nil && o.TaggedOutputFiles == nil
3036}
3037
mrziwange6c85812024-05-22 14:36:09 -07003038type OutputFilesInfo struct {
3039 // default output files when tag is an empty string ""
3040 DefaultOutputFiles Paths
3041
3042 // the corresponding output files for given tags
3043 TaggedOutputFiles map[string]Paths
3044}
3045
3046var OutputFilesProvider = blueprint.NewProvider[OutputFilesInfo]()
3047
Cole Fausta8437c52025-02-25 14:45:43 -08003048type UnsupportedOutputTagError struct {
3049 tag string
3050}
3051
3052func (u UnsupportedOutputTagError) Error() string {
3053 return fmt.Sprintf("unsupported output tag %q", u.tag)
3054}
3055
3056func (u UnsupportedOutputTagError) Is(e error) bool {
3057 _, ok := e.(UnsupportedOutputTagError)
3058 return ok
3059}
3060
3061var _ error = UnsupportedOutputTagError{}
3062
mrziwangabdb2932024-06-18 12:43:41 -07003063// This is used to mark the case where OutputFilesProvider is not set on some modules.
3064var OutputFilesProviderNotSet = fmt.Errorf("No output files from provider")
Cole Fausta8437c52025-02-25 14:45:43 -08003065var ErrUnsupportedOutputTag = UnsupportedOutputTagError{}
mrziwangabdb2932024-06-18 12:43:41 -07003066
Colin Cross41589502020-12-01 14:00:21 -08003067// Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to
3068// specify that they can be used as a tool by a genrule module.
Colin Crossfe17f6f2019-03-28 19:30:56 -07003069type HostToolProvider interface {
Colin Crossba9e4032020-11-24 16:32:22 -08003070 Module
Colin Cross41589502020-12-01 14:00:21 -08003071 // HostToolPath returns the path to the host tool for the module if it is one, or an invalid
3072 // OptionalPath.
Colin Crossfe17f6f2019-03-28 19:30:56 -07003073 HostToolPath() OptionalPath
3074}
3075
Colin Cross463a90e2015-06-17 14:20:06 -07003076func init() {
LaMont Jones0c10e4d2023-05-16 00:58:37 +00003077 RegisterParallelSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07003078}
3079
Colin Cross0875c522017-11-28 17:34:01 -08003080func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07003081 return &buildTargetSingleton{}
3082}
3083
Colin Cross87d8b562017-04-25 10:01:55 -07003084func parentDir(dir string) string {
3085 dir, _ = filepath.Split(dir)
3086 return filepath.Clean(dir)
3087}
3088
Colin Cross1f8c52b2015-06-16 16:38:17 -07003089type buildTargetSingleton struct{}
3090
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003091func AddAncestors(ctx SingletonContext, dirMap map[string]Paths, mmName func(string) string) ([]string, []string) {
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003092 // Ensure ancestor directories are in dirMap
3093 // Make directories build their direct subdirectories
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003094 // Returns a slice of all directories and a slice of top-level directories.
Cole Faust18994c72023-02-28 16:02:16 -08003095 dirs := SortedKeys(dirMap)
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003096 for _, dir := range dirs {
3097 dir := parentDir(dir)
3098 for dir != "." && dir != "/" {
3099 if _, exists := dirMap[dir]; exists {
3100 break
3101 }
3102 dirMap[dir] = nil
3103 dir = parentDir(dir)
3104 }
3105 }
Cole Faust18994c72023-02-28 16:02:16 -08003106 dirs = SortedKeys(dirMap)
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003107 var topDirs []string
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003108 for _, dir := range dirs {
3109 p := parentDir(dir)
3110 if p != "." && p != "/" {
3111 dirMap[p] = append(dirMap[p], PathForPhony(ctx, mmName(dir)))
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003112 } else if dir != "." && dir != "/" && dir != "" {
3113 topDirs = append(topDirs, dir)
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003114 }
3115 }
Cole Faust18994c72023-02-28 16:02:16 -08003116 return SortedKeys(dirMap), topDirs
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003117}
3118
Colin Cross0875c522017-11-28 17:34:01 -08003119func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
3120 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07003121
LaMont Jones825f8ff2025-02-12 11:52:00 -08003122 // Create a top level partialcompileclean target for modules to add dependencies to.
3123 ctx.Phony("partialcompileclean")
3124
Colin Crossc3d87d32020-06-04 13:25:17 -07003125 mmTarget := func(dir string) string {
3126 return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
Colin Cross87d8b562017-04-25 10:01:55 -07003127 }
3128
Colin Cross0875c522017-11-28 17:34:01 -08003129 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003130
Yu Liu2a815b62025-02-21 20:46:25 +00003131 ctx.VisitAllModuleProxies(func(module ModuleProxy) {
Cole Faust0523b8f2025-03-03 15:11:32 -08003132 info := OtherModuleProviderOrDefault(ctx, module, ModuleBuildTargetsProvider)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003133
Yu Liuddc2e1a2024-08-20 21:31:22 +00003134 if info.CheckbuildTarget != nil {
3135 checkbuildDeps = append(checkbuildDeps, info.CheckbuildTarget)
3136 modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.CheckbuildTarget)
Colin Cross0875c522017-11-28 17:34:01 -08003137 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07003138
Yu Liuddc2e1a2024-08-20 21:31:22 +00003139 if info.InstallTarget != nil {
3140 modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.InstallTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003141 }
3142 })
3143
Dan Willemsen5ba07e82015-12-11 13:51:06 -08003144 suffix := ""
Jingwen Chencda22c92020-11-23 00:22:30 -05003145 if ctx.Config().KatiEnabled() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08003146 suffix = "-soong"
3147 }
3148
Colin Cross1f8c52b2015-06-16 16:38:17 -07003149 // Create a top-level checkbuild target that depends on all modules
Colin Crossc3d87d32020-06-04 13:25:17 -07003150 ctx.Phony("checkbuild"+suffix, checkbuildDeps...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003151
Dan Willemsend2e95fb2017-09-20 14:30:50 -07003152 // Make will generate the MODULES-IN-* targets
Jingwen Chencda22c92020-11-23 00:22:30 -05003153 if ctx.Config().KatiEnabled() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07003154 return
3155 }
3156
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003157 dirs, _ := AddAncestors(ctx, modulesInDir, mmTarget)
Colin Cross87d8b562017-04-25 10:01:55 -07003158
Dan Willemsend2e95fb2017-09-20 14:30:50 -07003159 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
3160 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
3161 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07003162 for _, dir := range dirs {
Colin Crossc3d87d32020-06-04 13:25:17 -07003163 ctx.Phony(mmTarget(dir), modulesInDir[dir]...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003164 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07003165
3166 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
Jiyong Park1613e552020-09-14 19:43:17 +09003167 type osAndCross struct {
3168 os OsType
3169 hostCross bool
3170 }
3171 osDeps := map[osAndCross]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08003172 ctx.VisitAllModules(func(module Module) {
Cole Fausta963b942024-04-11 17:43:00 -07003173 if module.Enabled(ctx) {
Jiyong Park1613e552020-09-14 19:43:17 +09003174 key := osAndCross{os: module.Target().Os, hostCross: module.Target().HostCross}
Yu Liud46e5ae2024-08-15 18:46:17 +00003175 osDeps[key] = append(osDeps[key], OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).CheckbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07003176 }
3177 })
3178
Colin Cross0875c522017-11-28 17:34:01 -08003179 osClass := make(map[string]Paths)
Jiyong Park1613e552020-09-14 19:43:17 +09003180 for key, deps := range osDeps {
Dan Willemsen61d88b82017-09-20 17:29:08 -07003181 var className string
3182
Jiyong Park1613e552020-09-14 19:43:17 +09003183 switch key.os.Class {
Dan Willemsen61d88b82017-09-20 17:29:08 -07003184 case Host:
Jiyong Park1613e552020-09-14 19:43:17 +09003185 if key.hostCross {
3186 className = "host-cross"
3187 } else {
3188 className = "host"
3189 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07003190 case Device:
3191 className = "target"
3192 default:
3193 continue
3194 }
3195
Jiyong Park1613e552020-09-14 19:43:17 +09003196 name := className + "-" + key.os.Name
Colin Crossc3d87d32020-06-04 13:25:17 -07003197 osClass[className] = append(osClass[className], PathForPhony(ctx, name))
Dan Willemsen61d88b82017-09-20 17:29:08 -07003198
Colin Crossc3d87d32020-06-04 13:25:17 -07003199 ctx.Phony(name, deps...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07003200 }
3201
3202 // Wrap those into host|host-cross|target phony rules
Cole Faust18994c72023-02-28 16:02:16 -08003203 for _, class := range SortedKeys(osClass) {
Colin Crossc3d87d32020-06-04 13:25:17 -07003204 ctx.Phony(class, osClass[class]...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07003205 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07003206}
Colin Crossd779da42015-12-17 18:00:23 -08003207
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003208// Collect information for opening IDE project files in java/jdeps.go.
3209type IDEInfo interface {
Cole Faustb36d31d2024-08-27 16:04:28 -07003210 IDEInfo(ctx BaseModuleContext, ideInfo *IdeInfo)
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003211 BaseModuleName() string
3212}
3213
Cole Faust08c7f862024-08-27 15:03:59 -07003214// Collect information for opening IDE project files in java/jdeps.go.
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003215type IdeInfo struct {
Cole Faust08c7f862024-08-27 15:03:59 -07003216 BaseModuleName string `json:"-"`
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003217 Deps []string `json:"dependencies,omitempty"`
3218 Srcs []string `json:"srcs,omitempty"`
3219 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
3220 Jarjar_rules []string `json:"jarjar_rules,omitempty"`
3221 Jars []string `json:"jars,omitempty"`
3222 Classes []string `json:"class,omitempty"`
3223 Installed_paths []string `json:"installed,omitempty"`
patricktu18c82ff2019-05-10 15:48:50 +08003224 SrcJars []string `json:"srcjars,omitempty"`
bralee1fbf4402020-05-21 10:11:59 +08003225 Paths []string `json:"path,omitempty"`
Yikef6282022022-04-13 20:41:01 +08003226 Static_libs []string `json:"static_libs,omitempty"`
3227 Libs []string `json:"libs,omitempty"`
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003228}
Paul Duffinf88d8e02020-05-07 20:21:34 +01003229
Cole Faust08c7f862024-08-27 15:03:59 -07003230// Merge merges two IdeInfos and produces a new one, leaving the origional unchanged
3231func (i IdeInfo) Merge(other IdeInfo) IdeInfo {
3232 return IdeInfo{
3233 Deps: mergeStringLists(i.Deps, other.Deps),
3234 Srcs: mergeStringLists(i.Srcs, other.Srcs),
3235 Aidl_include_dirs: mergeStringLists(i.Aidl_include_dirs, other.Aidl_include_dirs),
3236 Jarjar_rules: mergeStringLists(i.Jarjar_rules, other.Jarjar_rules),
3237 Jars: mergeStringLists(i.Jars, other.Jars),
3238 Classes: mergeStringLists(i.Classes, other.Classes),
3239 Installed_paths: mergeStringLists(i.Installed_paths, other.Installed_paths),
3240 SrcJars: mergeStringLists(i.SrcJars, other.SrcJars),
3241 Paths: mergeStringLists(i.Paths, other.Paths),
3242 Static_libs: mergeStringLists(i.Static_libs, other.Static_libs),
3243 Libs: mergeStringLists(i.Libs, other.Libs),
3244 }
3245}
3246
3247// mergeStringLists appends the two string lists together and returns a new string list,
3248// leaving the originals unchanged. Duplicate strings will be deduplicated.
3249func mergeStringLists(a, b []string) []string {
3250 return FirstUniqueStrings(Concat(a, b))
3251}
3252
3253var IdeInfoProviderKey = blueprint.NewProvider[IdeInfo]()
3254
Paul Duffinf88d8e02020-05-07 20:21:34 +01003255func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error {
3256 bpctx := ctx.blueprintBaseModuleContext()
3257 return blueprint.CheckBlueprintSyntax(bpctx.ModuleFactories(), filename, contents)
3258}