blob: 45a20a061978e42050c79a4409c9ea57f67db0c4 [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
Paul Duffin44f1d842020-06-26 20:17:02 +010048 // Add dependencies to the components of a module, i.e. modules that are created
49 // by the module and which are considered to be part of the creating module.
50 //
51 // This is called before prebuilts are renamed so as to allow a dependency to be
52 // added directly to a prebuilt child module instead of depending on a source module
53 // and relying on prebuilt processing to switch to the prebuilt module if preferred.
54 //
55 // A dependency on a prebuilt must include the "prebuilt_" prefix.
56 ComponentDepsMutator(ctx BottomUpMutatorContext)
57
Colin Cross1e676be2016-10-12 14:38:15 -070058 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080059
Colin Cross635c3b02016-05-18 15:37:25 -070060 base() *ModuleBase
Inseob Kimeec88e12020-01-22 11:11:29 +090061 Disable()
Cole Fauste8a87832024-09-11 11:35:46 -070062 Enabled(ctx ConfigurableEvaluatorContext) bool
Colin Crossa1ad8d12016-06-01 17:09:44 -070063 Target() Target
Paul Duffinc04fb9e2021-03-01 12:25:10 +000064 MultiTargets() []Target
Paul Duffinb42fa672021-09-09 16:37:49 +010065
66 // ImageVariation returns the image variation of this module.
67 //
68 // The returned structure has its Mutator field set to "image" and its Variation field set to the
69 // image variation, e.g. recovery, ramdisk, etc.. The Variation field is "" for host modules and
70 // device modules that have no image variation.
71 ImageVariation() blueprint.Variation
72
Anton Hansson1ee62c02020-06-30 11:51:53 +010073 Owner() string
Dan Willemsen782a2d12015-12-21 14:55:28 -080074 InstallInData() bool
Jaewoong Jung0949f312019-09-11 10:25:18 -070075 InstallInTestcases() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -070076 InstallInSanitizerDir() bool
Yifan Hong1b3348d2020-01-21 15:53:22 -080077 InstallInRamdisk() bool
Yifan Hong60e0cfb2020-10-21 15:17:56 -070078 InstallInVendorRamdisk() bool
Inseob Kim08758f02021-04-08 21:13:22 +090079 InstallInDebugRamdisk() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +090080 InstallInRecovery() bool
Colin Cross90ba5f42019-10-02 11:10:58 -070081 InstallInRoot() bool
Colin Crossea30d852023-11-29 16:00:16 -080082 InstallInOdm() bool
83 InstallInProduct() bool
Kiyoung Kimae11c232021-07-19 11:38:04 +090084 InstallInVendor() bool
Spandan Das950deca2024-10-01 18:35:23 +000085 InstallInSystemExt() bool
Spandan Das27ff7672024-11-06 19:23:57 +000086 InstallInSystemDlkm() bool
87 InstallInVendorDlkm() bool
88 InstallInOdmDlkm() bool
Jiyong Park87788b52020-09-01 12:37:45 +090089 InstallForceOS() (*OsType, *ArchType)
Jiyong Parkce243632023-02-17 18:22:25 +090090 PartitionTag(DeviceConfig) string
Colin Crossa9c8c9f2020-12-16 10:20:23 -080091 HideFromMake()
92 IsHideFromMake() bool
Spandan Das034af2c2024-10-30 21:45:09 +000093 SkipInstall()
Martin Stjernholm9e7f45e2020-12-23 03:50:30 +000094 IsSkipInstall() bool
Iván Budnik295da162023-03-10 16:11:26 +000095 MakeUninstallable()
Liz Kammer5ca3a622020-08-05 15:40:41 -070096 ReplacedByPrebuilt()
97 IsReplacedByPrebuilt() bool
Jiyong Park374510b2018-03-19 18:23:01 +090098 ExportedToMake() bool
Justin Yun885a7de2021-06-29 20:34:53 +090099 EffectiveLicenseFiles() Paths
Colin Cross36242852017-06-23 15:06:31 -0700100
101 AddProperties(props ...interface{})
102 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700103
Colin Crossae887032017-10-23 17:16:14 -0700104 BuildParamsForTests() []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800105 RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800106 VariablesForTests() map[string]string
Paul Duffine2453c72019-05-31 14:00:04 +0100107
Colin Cross9a362232019-07-01 15:32:45 -0700108 // String returns a string that includes the module name and variants for printing during debugging.
109 String() string
110
Paul Duffine2453c72019-05-31 14:00:04 +0100111 // Get the qualified module id for this module.
112 qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName
113
114 // Get information about the properties that can contain visibility rules.
115 visibilityProperties() []visibilityProperty
Paul Duffin63c6e182019-07-24 14:24:38 +0100116
Cole Fauste8a87832024-09-11 11:35:46 -0700117 RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string
Jiyong Park6a8cf5f2019-12-30 16:31:09 +0900118 HostRequiredModuleNames() []string
119 TargetRequiredModuleNames() []string
Cole Fauste8a87832024-09-11 11:35:46 -0700120 VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string
Kiyoung Kim23be5bb2024-11-27 00:50:30 +0000121 VintfFragments(ctx ConfigurableEvaluatorContext) []string
Colin Cross897266e2020-02-13 13:22:08 -0800122
Cole Fauste8a87832024-09-11 11:35:46 -0700123 ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator
Jihoon Kang0d545b82024-10-11 00:21:57 +0000124
125 // The usage of this method is experimental and should not be used outside of fsgen package.
126 // This will be removed once product packaging migration to Soong is complete.
127 DecodeMultilib(ctx ConfigContext) (string, string)
Spandan Dase1860e42024-10-24 22:29:50 +0000128
129 // WARNING: This should not be used outside build/soong/fsgen
130 // Overrides returns the list of modules which should not be installed if this module is installed.
131 Overrides() []string
Paul Duffine2453c72019-05-31 14:00:04 +0100132}
133
134// Qualified id for a module
135type qualifiedModuleName struct {
136 // The package (i.e. directory) in which the module is defined, without trailing /
137 pkg string
138
139 // The name of the module, empty string if package.
140 name string
141}
142
143func (q qualifiedModuleName) String() string {
144 if q.name == "" {
145 return "//" + q.pkg
146 }
147 return "//" + q.pkg + ":" + q.name
148}
149
Paul Duffine484f472019-06-20 16:38:08 +0100150func (q qualifiedModuleName) isRootPackage() bool {
151 return q.pkg == "" && q.name == ""
152}
153
Paul Duffine2453c72019-05-31 14:00:04 +0100154// Get the id for the package containing this module.
155func (q qualifiedModuleName) getContainingPackageId() qualifiedModuleName {
156 pkg := q.pkg
157 if q.name == "" {
Paul Duffine484f472019-06-20 16:38:08 +0100158 if pkg == "" {
159 panic(fmt.Errorf("Cannot get containing package id of root package"))
160 }
161
162 index := strings.LastIndex(pkg, "/")
163 if index == -1 {
164 pkg = ""
165 } else {
166 pkg = pkg[:index]
167 }
Paul Duffine2453c72019-05-31 14:00:04 +0100168 }
169 return newPackageId(pkg)
170}
171
172func newPackageId(pkg string) qualifiedModuleName {
173 // A qualified id for a package module has no name.
174 return qualifiedModuleName{pkg: pkg, name: ""}
Colin Cross3f40fa42015-01-30 17:27:36 -0800175}
176
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000177type Dist struct {
178 // Copy the output of this module to the $DIST_DIR when `dist` is specified on the
179 // command line and any of these targets are also on the command line, or otherwise
180 // built
181 Targets []string `android:"arch_variant"`
182
183 // The name of the output artifact. This defaults to the basename of the output of
184 // the module.
185 Dest *string `android:"arch_variant"`
186
187 // The directory within the dist directory to store the artifact. Defaults to the
188 // top level directory ("").
189 Dir *string `android:"arch_variant"`
190
191 // A suffix to add to the artifact file name (before any extension).
192 Suffix *string `android:"arch_variant"`
193
Trevor Radcliffe90727f42022-03-21 19:34:02 +0000194 // If true, then the artifact file will be appended with _<product name>. For
195 // example, if the product is coral and the module is an android_app module
196 // of name foo, then the artifact would be foo_coral.apk. If false, there is
197 // no change to the artifact file name.
198 Append_artifact_with_product *bool `android:"arch_variant"`
199
Paul Duffin74f05592020-11-25 16:37:46 +0000200 // A string tag to select the OutputFiles associated with the tag.
201 //
202 // If no tag is specified then it will select the default dist paths provided
203 // by the module type. If a tag of "" is specified then it will return the
204 // default output files provided by the modules, i.e. the result of calling
205 // OutputFiles("").
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000206 Tag *string `android:"arch_variant"`
207}
208
Bob Badour4101c712022-02-09 11:54:35 -0800209// NamedPath associates a path with a name. e.g. a license text path with a package name
210type NamedPath struct {
211 Path Path
212 Name string
213}
214
215// String returns an escaped string representing the `NamedPath`.
216func (p NamedPath) String() string {
217 if len(p.Name) > 0 {
218 return p.Path.String() + ":" + url.QueryEscape(p.Name)
219 }
220 return p.Path.String()
221}
222
223// NamedPaths describes a list of paths each associated with a name.
224type NamedPaths []NamedPath
225
226// Strings returns a list of escaped strings representing each `NamedPath` in the list.
227func (l NamedPaths) Strings() []string {
228 result := make([]string, 0, len(l))
229 for _, p := range l {
230 result = append(result, p.String())
231 }
232 return result
233}
234
235// SortedUniqueNamedPaths modifies `l` in place to return the sorted unique subset.
236func SortedUniqueNamedPaths(l NamedPaths) NamedPaths {
237 if len(l) == 0 {
238 return l
239 }
240 sort.Slice(l, func(i, j int) bool {
241 return l[i].String() < l[j].String()
242 })
243 k := 0
244 for i := 1; i < len(l); i++ {
245 if l[i].String() == l[k].String() {
246 continue
247 }
248 k++
249 if k < i {
250 l[k] = l[i]
251 }
252 }
253 return l[:k+1]
254}
255
Colin Crossfc754582016-05-17 16:34:16 -0700256type nameProperties struct {
257 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800258 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700259}
260
Cole Faust2239ae62025-01-27 15:32:11 -0800261// Properties common to all modules inheriting from ModuleBase. These properties are automatically
262// inherited by sub-modules created with ctx.CreateModule()
Colin Cross08d6f8f2020-11-19 02:33:19 +0000263type commonProperties struct {
Dan Willemsen0effe062015-11-30 16:06:01 -0800264 // emit build rules for this module
Paul Duffin54d9bb72020-02-12 10:20:56 +0000265 //
266 // Disabling a module should only be done for those modules that cannot be built
267 // in the current environment. Modules that can build in the current environment
268 // but are not usually required (e.g. superceded by a prebuilt) should not be
269 // disabled as that will prevent them from being built by the checkbuild target
270 // and so prevent early detection of changes that have broken those modules.
Cole Fausta963b942024-04-11 17:43:00 -0700271 Enabled proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800272
Paul Duffin2e61fa62019-03-28 14:10:57 +0000273 // Controls the visibility of this module to other modules. Allowable values are one or more of
274 // these formats:
275 //
276 // ["//visibility:public"]: Anyone can use this module.
277 // ["//visibility:private"]: Only rules in the module's package (not its subpackages) can use
278 // this module.
Paul Duffin51084ff2020-05-05 19:19:22 +0100279 // ["//visibility:override"]: Discards any rules inherited from defaults or a creating module.
280 // Can only be used at the beginning of a list of visibility rules.
Paul Duffin2e61fa62019-03-28 14:10:57 +0000281 // ["//some/package:__pkg__", "//other/package:__pkg__"]: Only modules in some/package and
282 // other/package (defined in some/package/*.bp and other/package/*.bp) have access to
283 // this module. Note that sub-packages do not have access to the rule; for example,
284 // //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__
285 // is a special module and must be used verbatim. It represents all of the modules in the
286 // package.
287 // ["//project:__subpackages__", "//other:__subpackages__"]: Only modules in packages project
288 // or other or in one of their sub-packages have access to this module. For example,
289 // //project:rule, //project/library:lib or //other/testing/internal:munge are allowed
290 // to depend on this rule (but not //independent:evil)
291 // ["//project"]: This is shorthand for ["//project:__pkg__"]
292 // [":__subpackages__"]: This is shorthand for ["//project:__subpackages__"] where
293 // //project is the module's package. e.g. using [":__subpackages__"] in
294 // packages/apps/Settings/Android.bp is equivalent to
295 // //packages/apps/Settings:__subpackages__.
296 // ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public
297 // for now. It is an error if it is used in a module.
Paul Duffine2453c72019-05-31 14:00:04 +0100298 //
299 // If a module does not specify the `visibility` property then it uses the
300 // `default_visibility` property of the `package` module in the module's package.
301 //
302 // If the `default_visibility` property is not set for the module's package then
Paul Duffine484f472019-06-20 16:38:08 +0100303 // it will use the `default_visibility` of its closest ancestor package for which
304 // a `default_visibility` property is specified.
305 //
306 // If no `default_visibility` property can be found then the module uses the
307 // global default of `//visibility:legacy_public`.
Paul Duffine2453c72019-05-31 14:00:04 +0100308 //
Paul Duffin95d53b52019-07-24 13:45:05 +0100309 // The `visibility` property has no effect on a defaults module although it does
310 // apply to any non-defaults module that uses it. To set the visibility of a
311 // defaults module, use the `defaults_visibility` property on the defaults module;
312 // not to be confused with the `default_visibility` property on the package module.
313 //
Elliott Hughes10363162024-01-09 22:02:03 +0000314 // See https://android.googlesource.com/platform/build/soong/+/main/README.md#visibility for
Paul Duffin2e61fa62019-03-28 14:10:57 +0000315 // more details.
316 Visibility []string
317
Bob Badour37af0462021-01-07 03:34:31 +0000318 // Describes the licenses applicable to this module. Must reference license modules.
319 Licenses []string
320
Bob Badour37af0462021-01-07 03:34:31 +0000321 // Override of module name when reporting licenses
322 Effective_package_name *string `blueprint:"mutated"`
323 // Notice files
Bob Badour4101c712022-02-09 11:54:35 -0800324 Effective_license_text NamedPaths `blueprint:"mutated"`
Bob Badour37af0462021-01-07 03:34:31 +0000325 // License names
326 Effective_license_kinds []string `blueprint:"mutated"`
327 // License conditions
328 Effective_license_conditions []string `blueprint:"mutated"`
329
Colin Cross7d5136f2015-05-11 13:39:40 -0700330 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800331 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
332 // 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 +0000333 // platform).
Colin Cross7d716ba2017-11-01 10:38:29 -0700334 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700335
336 Target struct {
337 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700338 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700339 }
340 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700341 Compile_multilib *string
Spandan Dasde588a32024-12-03 22:52:24 +0000342 Enabled *bool
Colin Cross69617d32016-09-06 10:39:07 -0700343 }
344 }
345
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000346 // If set to true then the archMutator will create variants for each arch specific target
347 // (e.g. 32/64) that the module is required to produce. If set to false then it will only
348 // create a variant for the architecture and will list the additional arch specific targets
349 // that the variant needs to produce in the CompileMultiTargets property.
Colin Crossee0bc3b2018-10-02 22:01:37 -0700350 UseTargetVariants bool `blueprint:"mutated"`
351 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800352
Dan Willemsen782a2d12015-12-21 14:55:28 -0800353 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700354 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800355
Colin Cross55708f32017-03-20 13:23:34 -0700356 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700357 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700358
Jiyong Park2db76922017-11-08 16:03:48 +0900359 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
360 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
361 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700362 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700363
Jiyong Park2db76922017-11-08 16:03:48 +0900364 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
365 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
366 Soc_specific *bool
367
368 // whether this module is specific to a device, not only for SoC, but also for off-chip
369 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
370 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
371 // This implies `soc_specific:true`.
372 Device_specific *bool
373
374 // whether this module is specific to a software configuration of a product (e.g. country,
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900375 // network operator, etc). When set to true, it is installed into /product (or
376 // /system/product if product partition does not exist).
Jiyong Park2db76922017-11-08 16:03:48 +0900377 Product_specific *bool
378
Justin Yund5f6c822019-06-25 16:47:17 +0900379 // whether this module extends system. When set to true, it is installed into /system_ext
380 // (or /system/system_ext if system_ext partition does not exist).
381 System_ext_specific *bool
382
Jiyong Parkf9332f12018-02-01 00:54:12 +0900383 // Whether this module is installed to recovery partition
384 Recovery *bool
385
Yifan Hong1b3348d2020-01-21 15:53:22 -0800386 // Whether this module is installed to ramdisk
387 Ramdisk *bool
388
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700389 // Whether this module is installed to vendor ramdisk
390 Vendor_ramdisk *bool
391
Inseob Kim08758f02021-04-08 21:13:22 +0900392 // Whether this module is installed to debug ramdisk
393 Debug_ramdisk *bool
394
Spandan Das27ff7672024-11-06 19:23:57 +0000395 // Install to partition system_dlkm when set to true.
396 System_dlkm_specific *bool
397
398 // Install to partition vendor_dlkm when set to true.
399 Vendor_dlkm_specific *bool
400
401 // Install to partition odm_dlkm when set to true.
402 Odm_dlkm_specific *bool
403
Jaewoong Jung8e93aba2021-03-02 16:58:08 -0800404 // Whether this module is built for non-native architectures (also known as native bridge binary)
dimitry1f33e402019-03-26 12:39:31 +0100405 Native_bridge_supported *bool `android:"arch_variant"`
406
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700407 // init.rc files to be installed if this module is installed
Inseob Kim713b87d2024-09-13 11:29:54 +0900408 Init_rc proptools.Configurable[[]string] `android:"arch_variant,path"`
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700409
Steven Moreland57a23d22018-04-04 15:42:19 -0700410 // VINTF manifest fragments to be installed if this module is installed
Inseob Kimf2237022024-07-23 13:36:31 +0900411 Vintf_fragments proptools.Configurable[[]string] `android:"path"`
Steven Moreland57a23d22018-04-04 15:42:19 -0700412
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000413 // The OsType of artifacts that this module variant is responsible for creating.
414 //
415 // Set by osMutator
416 CompileOS OsType `blueprint:"mutated"`
417
Cole Faust0aa21cc2024-03-20 12:28:03 -0700418 // Set to true after the arch mutator has run on this module and set CompileTarget,
419 // CompileMultiTargets, and CompilePrimary
420 ArchReady bool `blueprint:"mutated"`
421
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000422 // The Target of artifacts that this module variant is responsible for creating.
423 //
424 // Set by archMutator
425 CompileTarget Target `blueprint:"mutated"`
426
427 // The additional arch specific targets (e.g. 32/64 bit) that this module variant is
428 // responsible for creating.
429 //
430 // By default this is nil as, where necessary, separate variants are created for the
431 // different multilib types supported and that information is encapsulated in the
432 // CompileTarget so the module variant simply needs to create artifacts for that.
433 //
434 // However, if UseTargetVariants is set to false (e.g. by
435 // InitAndroidMultiTargetsArchModule) then no separate variants are created for the
436 // multilib targets. Instead a single variant is created for the architecture and
437 // this contains the multilib specific targets that this variant should create.
438 //
439 // Set by archMutator
Colin Crossee0bc3b2018-10-02 22:01:37 -0700440 CompileMultiTargets []Target `blueprint:"mutated"`
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000441
442 // True if the module variant's CompileTarget is the primary target
443 //
444 // Set by archMutator
445 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800446
447 // Set by InitAndroidModule
448 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700449 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700450
Paul Duffin1356d8c2020-02-25 19:26:33 +0000451 // If set to true then a CommonOS variant will be created which will have dependencies
452 // on all its OsType specific variants. Used by sdk/module_exports to create a snapshot
453 // that covers all os and architecture variants.
454 //
455 // The OsType specific variants can be retrieved by calling
456 // GetOsSpecificVariantsOfCommonOSVariant
457 //
458 // Set at module initialization time by calling InitCommonOSAndroidMultiTargetsArchModule
459 CreateCommonOSVariant bool `blueprint:"mutated"`
460
Jiyong Park3f627e62024-05-01 16:14:38 +0900461 // When set to true, this module is not installed to the full install path (ex: under
462 // out/target/product/<name>/<partition>). It can be installed only to the packaging
463 // modules like android_filesystem.
464 No_full_install *bool
465
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800466 // When HideFromMake is set to true, no entry for this variant will be emitted in the
467 // generated Android.mk file.
468 HideFromMake bool `blueprint:"mutated"`
469
470 // When SkipInstall is set to true, calls to ctx.InstallFile, ctx.InstallExecutable,
471 // ctx.InstallSymlink and ctx.InstallAbsoluteSymlink act like calls to ctx.PackageFile
472 // and don't create a rule to install the file.
Colin Crossce75d2c2016-10-06 16:12:58 -0700473 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800474
Colin Crossbd3a16b2023-04-25 11:30:51 -0700475 // UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex
476 // mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant
477 // is used to avoid adding install or packaging dependencies into libraries provided
478 // by apexes.
479 UninstallableApexPlatformVariant bool `blueprint:"mutated"`
480
Liz Kammer5ca3a622020-08-05 15:40:41 -0700481 // Whether the module has been replaced by a prebuilt
482 ReplacedByPrebuilt bool `blueprint:"mutated"`
483
Justin Yun32f053b2020-07-31 23:07:17 +0900484 // Disabled by mutators. If set to true, it overrides Enabled property.
485 ForcedDisabled bool `blueprint:"mutated"`
486
Jeff Gaston088e29e2017-11-29 16:47:17 -0800487 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross6c4f21f2019-06-06 15:41:36 -0700488
Liz Kammerc13f7852023-05-17 13:01:48 -0400489 MissingDeps []string `blueprint:"mutated"`
490 CheckedMissingDeps bool `blueprint:"mutated"`
Colin Cross9a362232019-07-01 15:32:45 -0700491
492 // Name and variant strings stored by mutators to enable Module.String()
493 DebugName string `blueprint:"mutated"`
494 DebugMutators []string `blueprint:"mutated"`
495 DebugVariations []string `blueprint:"mutated"`
Colin Cross7228ecd2019-11-18 16:00:16 -0800496
Colin Crossa6845402020-11-16 15:08:19 -0800497 // ImageVariation is set by ImageMutator to specify which image this variation is for,
498 // for example "" for core or "recovery" for recovery. It will often be set to one of the
499 // constants in image.go, but can also be set to a custom value by individual module types.
Colin Cross7228ecd2019-11-18 16:00:16 -0800500 ImageVariation string `blueprint:"mutated"`
Liz Kammer2ada09a2021-08-11 00:17:36 -0400501
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800502 // The team (defined by the owner/vendor) who owns the property.
503 Team *string `android:"path"`
Kiyoung Kimfaf6af32024-08-12 11:15:19 +0900504
505 // vintf_fragment Modules required from this module.
506 Vintf_fragment_modules proptools.Configurable[[]string] `android:"path"`
Jiyong Parka574d532024-08-28 18:06:43 +0900507
508 // List of module names that are prevented from being installed when this module gets
509 // installed.
510 Overrides []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800511}
512
Cole Faust2239ae62025-01-27 15:32:11 -0800513// Properties common to all modules inheriting from ModuleBase. Unlike commonProperties, these
514// properties are NOT automatically inherited by sub-modules created with ctx.CreateModule()
515type baseProperties struct {
516 // names of other modules to install if this module is installed
517 Required proptools.Configurable[[]string] `android:"arch_variant"`
518
519 // names of other modules to install on host if this module is installed
520 Host_required []string `android:"arch_variant"`
521
522 // names of other modules to install on target if this module is installed
523 Target_required []string `android:"arch_variant"`
Cole Faust55c03f02025-03-10 15:52:36 -0700524
525 // If this is a soong config module, this property will be set to the name of the original
526 // module type. This is used by neverallow to ensure you can't bypass a ModuleType() matcher
527 // just by creating a soong config module type.
528 Soong_config_base_module_type *string `blueprint:"mutated"`
Cole Faust2239ae62025-01-27 15:32:11 -0800529}
530
Paul Duffined875132020-09-02 13:08:57 +0100531type distProperties struct {
532 // configuration to distribute output files from this module to the distribution
533 // directory (default: $OUT/dist, configurable with $DIST_DIR)
534 Dist Dist `android:"arch_variant"`
535
536 // a list of configurations to distribute output files from this module to the
537 // distribution directory (default: $OUT/dist, configurable with $DIST_DIR)
538 Dists []Dist `android:"arch_variant"`
539}
540
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800541type TeamDepTagType struct {
542 blueprint.BaseDependencyTag
543}
544
545var teamDepTag = TeamDepTagType{}
546
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900547// Dependency tag for required, host_required, and target_required modules.
548var RequiredDepTag = struct {
549 blueprint.BaseDependencyTag
550 InstallAlwaysNeededDependencyTag
551 // Requiring disabled module has been supported (as a side effect of this being implemented
552 // in Make). We may want to make it an error, but for now, let's keep the existing behavior.
553 AlwaysAllowDisabledModuleDependencyTag
554}{}
555
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800556// CommonTestOptions represents the common `test_options` properties in
557// Android.bp.
558type CommonTestOptions struct {
559 // If the test is a hostside (no device required) unittest that shall be run
560 // during presubmit check.
561 Unit_test *bool
Zhenhuang Wang409d2772022-08-22 16:00:05 +0800562
563 // Tags provide additional metadata to customize test execution by downstream
564 // test runners. The tags have no special meaning to Soong.
565 Tags []string
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800566}
567
568// SetAndroidMkEntries sets AndroidMkEntries according to the value of base
569// `test_options`.
570func (t *CommonTestOptions) SetAndroidMkEntries(entries *AndroidMkEntries) {
571 entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test))
Zhenhuang Wang409d2772022-08-22 16:00:05 +0800572 if len(t.Tags) > 0 {
573 entries.AddStrings("LOCAL_TEST_OPTIONS_TAGS", t.Tags...)
574 }
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800575}
576
Yu Liue70976d2024-10-15 20:45:35 +0000577func (t *CommonTestOptions) SetAndroidMkInfoEntries(entries *AndroidMkInfo) {
578 entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test))
579 if len(t.Tags) > 0 {
580 entries.AddStrings("LOCAL_TEST_OPTIONS_TAGS", t.Tags...)
581 }
582}
583
Paul Duffin74f05592020-11-25 16:37:46 +0000584// The key to use in TaggedDistFiles when a Dist structure does not specify a
585// tag property. This intentionally does not use "" as the default because that
586// would mean that an empty tag would have a different meaning when used in a dist
587// structure that when used to reference a specific set of output paths using the
588// :module{tag} syntax, which passes tag to the OutputFiles(tag) method.
589const DefaultDistTag = "<default-dist-tag>"
590
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000591// A map of OutputFile tag keys to Paths, for disting purposes.
592type TaggedDistFiles map[string]Paths
593
Paul Duffin74f05592020-11-25 16:37:46 +0000594// addPathsForTag adds a mapping from the tag to the paths. If the map is nil
595// then it will create a map, update it and then return it. If a mapping already
596// exists for the tag then the paths are appended to the end of the current list
597// of paths, ignoring any duplicates.
598func (t TaggedDistFiles) addPathsForTag(tag string, paths ...Path) TaggedDistFiles {
599 if t == nil {
600 t = make(TaggedDistFiles)
601 }
602
603 for _, distFile := range paths {
604 if distFile != nil && !t[tag].containsPath(distFile) {
605 t[tag] = append(t[tag], distFile)
606 }
607 }
608
609 return t
610}
611
612// merge merges the entries from the other TaggedDistFiles object into this one.
613// If the TaggedDistFiles is nil then it will create a new instance, merge the
614// other into it, and then return it.
615func (t TaggedDistFiles) merge(other TaggedDistFiles) TaggedDistFiles {
616 for tag, paths := range other {
617 t = t.addPathsForTag(tag, paths...)
618 }
619
620 return t
621}
622
Colin Cross3f40fa42015-01-30 17:27:36 -0800623type hostAndDeviceProperties struct {
Colin Cross4e81d702018-11-09 10:36:55 -0800624 // If set to true, build a variant of the module for the host. Defaults to false.
625 Host_supported *bool
626
627 // If set to true, build a variant of the module for the device. Defaults to true.
Colin Crossa4190c12016-07-12 13:11:25 -0700628 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800629}
630
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000631type hostCrossProperties struct {
632 // If set to true, build a variant of the module for the host cross. Defaults to true.
633 Host_cross_supported *bool
634}
635
Colin Crossc472d572015-03-17 15:06:21 -0700636type Multilib string
637
638const (
Cole Faustb9c67e22024-10-08 16:39:56 -0700639 MultilibBoth Multilib = "both"
640 MultilibFirst Multilib = "first"
641 MultilibCommon Multilib = "common"
Colin Crossc472d572015-03-17 15:06:21 -0700642)
643
Colin Crossa1ad8d12016-06-01 17:09:44 -0700644type HostOrDeviceSupported int
645
646const (
Colin Cross34037c62020-11-17 13:19:17 -0800647 hostSupported = 1 << iota
648 hostCrossSupported
649 deviceSupported
650 hostDefault
651 deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700652
653 // Host and HostCross are built by default. Device is not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800654 HostSupported = hostSupported | hostCrossSupported | hostDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700655
656 // Host is built by default. HostCross and Device are not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800657 HostSupportedNoCross = hostSupported | hostDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700658
659 // Device is built by default. Host and HostCross are not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800660 DeviceSupported = deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700661
Liz Kammer8631cc72021-08-23 21:12:07 +0000662 // By default, _only_ device variant is built. Device variant can be disabled with `device_supported: false`
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -0700663 // Host and HostCross are disabled by default and can be enabled with `host_supported: true`
Colin Cross34037c62020-11-17 13:19:17 -0800664 HostAndDeviceSupported = hostSupported | hostCrossSupported | deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700665
666 // Host, HostCross, and Device are built by default.
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -0700667 // Building Device can be disabled with `device_supported: false`
668 // Building Host and HostCross can be disabled with `host_supported: false`
Colin Cross34037c62020-11-17 13:19:17 -0800669 HostAndDeviceDefault = hostSupported | hostCrossSupported | hostDefault |
670 deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700671
672 // Nothing is supported. This is not exposed to the user, but used to mark a
673 // host only module as unsupported when the module type is not supported on
674 // the host OS. E.g. benchmarks are supported on Linux but not Darwin.
Colin Cross34037c62020-11-17 13:19:17 -0800675 NeitherHostNorDeviceSupported = 0
Colin Crossa1ad8d12016-06-01 17:09:44 -0700676)
677
Jiyong Park2db76922017-11-08 16:03:48 +0900678type moduleKind int
679
680const (
681 platformModule moduleKind = iota
682 deviceSpecificModule
683 socSpecificModule
684 productSpecificModule
Justin Yund5f6c822019-06-25 16:47:17 +0900685 systemExtSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900686)
687
688func (k moduleKind) String() string {
689 switch k {
690 case platformModule:
691 return "platform"
692 case deviceSpecificModule:
693 return "device-specific"
694 case socSpecificModule:
695 return "soc-specific"
696 case productSpecificModule:
697 return "product-specific"
Justin Yund5f6c822019-06-25 16:47:17 +0900698 case systemExtSpecificModule:
699 return "systemext-specific"
Jiyong Park2db76922017-11-08 16:03:48 +0900700 default:
701 panic(fmt.Errorf("unknown module kind %d", k))
702 }
703}
704
Colin Cross9d34f352019-11-22 16:03:51 -0800705func initAndroidModuleBase(m Module) {
706 m.base().module = m
707}
708
Colin Crossa6845402020-11-16 15:08:19 -0800709// InitAndroidModule initializes the Module as an Android module that is not architecture-specific.
710// It adds the common properties, for example "name" and "enabled".
Colin Cross36242852017-06-23 15:06:31 -0700711func InitAndroidModule(m Module) {
Colin Cross9d34f352019-11-22 16:03:51 -0800712 initAndroidModuleBase(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800713 base := m.base()
Colin Cross5049f022015-03-18 13:28:46 -0700714
Colin Cross36242852017-06-23 15:06:31 -0700715 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700716 &base.nameProperties,
Paul Duffined875132020-09-02 13:08:57 +0100717 &base.commonProperties,
Cole Faust2239ae62025-01-27 15:32:11 -0800718 &base.baseProperties,
Paul Duffined875132020-09-02 13:08:57 +0100719 &base.distProperties)
Colin Cross18c46802019-09-24 22:19:02 -0700720
Colin Crosseabaedd2020-02-06 17:01:55 -0800721 initProductVariableModule(m)
Colin Cross18c46802019-09-24 22:19:02 -0700722
Paul Duffin63c6e182019-07-24 14:24:38 +0100723 // The default_visibility property needs to be checked and parsed by the visibility module during
Paul Duffin5ec73ec2020-05-01 17:52:01 +0100724 // its checking and parsing phases so make it the primary visibility property.
725 setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility)
Bob Badour37af0462021-01-07 03:34:31 +0000726
727 // The default_applicable_licenses property needs to be checked and parsed by the licenses module during
728 // its checking and parsing phases so make it the primary licenses property.
729 setPrimaryLicensesProperty(m, "licenses", &base.commonProperties.Licenses)
Colin Cross5049f022015-03-18 13:28:46 -0700730}
731
Colin Crossa6845402020-11-16 15:08:19 -0800732// InitAndroidArchModule initializes the Module as an Android module that is architecture-specific.
733// It adds the common properties, for example "name" and "enabled", as well as runtime generated
734// property structs for architecture-specific versions of generic properties tagged with
735// `android:"arch_variant"`.
736//
Colin Crossd079e0b2022-08-16 10:27:33 -0700737// InitAndroidModule should not be called if InitAndroidArchModule was called.
Colin Cross36242852017-06-23 15:06:31 -0700738func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
739 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700740
741 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800742 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700743 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700744 base.commonProperties.ArchSpecific = true
Colin Crossee0bc3b2018-10-02 22:01:37 -0700745 base.commonProperties.UseTargetVariants = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800746
Colin Cross34037c62020-11-17 13:19:17 -0800747 if hod&hostSupported != 0 && hod&deviceSupported != 0 {
Colin Cross36242852017-06-23 15:06:31 -0700748 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800749 }
750
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000751 if hod&hostCrossSupported != 0 {
752 m.AddProperties(&base.hostCrossProperties)
753 }
754
Colin Crossa6845402020-11-16 15:08:19 -0800755 initArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800756}
757
Colin Crossa6845402020-11-16 15:08:19 -0800758// InitAndroidMultiTargetsArchModule initializes the Module as an Android module that is
759// architecture-specific, but will only have a single variant per OS that handles all the
760// architectures simultaneously. The list of Targets that it must handle will be available from
761// ModuleContext.MultiTargets. It adds the common properties, for example "name" and "enabled", as
762// well as runtime generated property structs for architecture-specific versions of generic
763// properties tagged with `android:"arch_variant"`.
764//
765// InitAndroidModule or InitAndroidArchModule should not be called if
766// InitAndroidMultiTargetsArchModule was called.
Colin Crossee0bc3b2018-10-02 22:01:37 -0700767func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
768 InitAndroidArchModule(m, hod, defaultMultilib)
769 m.base().commonProperties.UseTargetVariants = false
770}
771
Colin Crossa6845402020-11-16 15:08:19 -0800772// InitCommonOSAndroidMultiTargetsArchModule initializes the Module as an Android module that is
773// architecture-specific, but will only have a single variant per OS that handles all the
774// architectures simultaneously, and will also have an additional CommonOS variant that has
775// dependencies on all the OS-specific variants. The list of Targets that it must handle will be
776// available from ModuleContext.MultiTargets. It adds the common properties, for example "name" and
777// "enabled", as well as runtime generated property structs for architecture-specific versions of
778// generic properties tagged with `android:"arch_variant"`.
779//
780// InitAndroidModule, InitAndroidArchModule or InitAndroidMultiTargetsArchModule should not be
781// called if InitCommonOSAndroidMultiTargetsArchModule was called.
Paul Duffin1356d8c2020-02-25 19:26:33 +0000782func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
783 InitAndroidArchModule(m, hod, defaultMultilib)
784 m.base().commonProperties.UseTargetVariants = false
785 m.base().commonProperties.CreateCommonOSVariant = true
786}
787
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800788// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800789// modules. It should be included as an anonymous field in every module
790// struct definition. InitAndroidModule should then be called from the module's
791// factory function, and the return values from InitAndroidModule should be
792// returned from the factory function.
793//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800794// The ModuleBase type is responsible for implementing the GenerateBuildActions
795// method to support the blueprint.Module interface. This method will then call
796// the module's GenerateAndroidBuildActions method once for each build variant
Colin Cross25de6c32019-06-06 14:29:25 -0700797// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext
798// rather than the usual blueprint.ModuleContext.
799// ModuleContext exposes extra functionality specific to the Android build
Colin Cross3f40fa42015-01-30 17:27:36 -0800800// system including details about the particular build variant that is to be
801// generated.
802//
803// For example:
804//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800805// import (
806// "android/soong/android"
807// )
Colin Cross3f40fa42015-01-30 17:27:36 -0800808//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800809// type myModule struct {
810// android.ModuleBase
811// properties struct {
812// MyProperty string
813// }
814// }
Colin Cross3f40fa42015-01-30 17:27:36 -0800815//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800816// func NewMyModule() android.Module {
817// m := &myModule{}
818// m.AddProperties(&m.properties)
819// android.InitAndroidModule(m)
820// return m
821// }
Colin Cross3f40fa42015-01-30 17:27:36 -0800822//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800823// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
824// // Get the CPU architecture for the current build variant.
825// variantArch := ctx.Arch()
Colin Cross3f40fa42015-01-30 17:27:36 -0800826//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800827// // ...
828// }
Colin Cross635c3b02016-05-18 15:37:25 -0700829type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800830 // Putting the curiously recurring thing pointing to the thing that contains
831 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700832 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700833 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800834
Colin Crossfc754582016-05-17 16:34:16 -0700835 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800836 commonProperties commonProperties
Cole Faust2239ae62025-01-27 15:32:11 -0800837 baseProperties baseProperties
Paul Duffined875132020-09-02 13:08:57 +0100838 distProperties distProperties
Colin Cross18c46802019-09-24 22:19:02 -0700839 variableProperties interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800840 hostAndDeviceProperties hostAndDeviceProperties
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000841 hostCrossProperties hostCrossProperties
Jingwen Chen5d864492021-02-24 07:20:12 -0500842
Usta851a3272022-01-05 23:42:33 -0500843 // Arch specific versions of structs in GetProperties() prior to
844 // initialization in InitAndroidArchModule, lets call it `generalProperties`.
845 // The outer index has the same order as generalProperties and the inner index
846 // chooses the props specific to the architecture. The interface{} value is an
847 // archPropRoot that is filled with arch specific values by the arch mutator.
Jingwen Chen5d864492021-02-24 07:20:12 -0500848 archProperties [][]interface{}
849
Paul Duffin63c6e182019-07-24 14:24:38 +0100850 // Information about all the properties on the module that contains visibility rules that need
851 // checking.
852 visibilityPropertyInfo []visibilityProperty
853
854 // The primary visibility property, may be nil, that controls access to the module.
855 primaryVisibilityProperty visibilityProperty
856
Bob Badour37af0462021-01-07 03:34:31 +0000857 // The primary licenses property, may be nil, records license metadata for the module.
858 primaryLicensesProperty applicableLicensesProperty
859
Yu Liueb6d7052024-08-27 22:35:54 +0000860 noAddressSanitizer bool
Colin Cross1f8c52b2015-06-16 16:38:17 -0700861
Colin Cross178a5092016-09-13 13:42:32 -0700862 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700863
864 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700865
866 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700867 buildParams []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800868 ruleParams map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800869 variables map[string]string
Colin Cross36242852017-06-23 15:06:31 -0700870}
871
Lukacs T. Berkid18d8ca2021-06-25 09:11:22 +0200872func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
Liz Kammer9525e712022-01-05 13:46:24 -0500873 (*d)["Android"] = map[string]interface{}{
874 // Properties set in Blueprint or in blueprint of a defaults modules
875 "SetProperties": m.propertiesWithValues(),
876 }
877}
878
879type propInfo struct {
Liz Kammer898e0762022-03-22 11:27:26 -0400880 Name string
881 Type string
882 Value string
883 Values []string
Liz Kammer9525e712022-01-05 13:46:24 -0500884}
885
886func (m *ModuleBase) propertiesWithValues() []propInfo {
887 var info []propInfo
888 props := m.GetProperties()
889
890 var propsWithValues func(name string, v reflect.Value)
891 propsWithValues = func(name string, v reflect.Value) {
892 kind := v.Kind()
893 switch kind {
894 case reflect.Ptr, reflect.Interface:
895 if v.IsNil() {
896 return
897 }
898 propsWithValues(name, v.Elem())
899 case reflect.Struct:
900 if v.IsZero() {
901 return
902 }
903 for i := 0; i < v.NumField(); i++ {
904 namePrefix := name
905 sTyp := v.Type().Field(i)
906 if proptools.ShouldSkipProperty(sTyp) {
907 continue
908 }
909 if name != "" && !strings.HasSuffix(namePrefix, ".") {
910 namePrefix += "."
911 }
912 if !proptools.IsEmbedded(sTyp) {
913 namePrefix += sTyp.Name
914 }
915 sVal := v.Field(i)
916 propsWithValues(namePrefix, sVal)
917 }
918 case reflect.Array, reflect.Slice:
919 if v.IsNil() {
920 return
921 }
922 elKind := v.Type().Elem().Kind()
Liz Kammer898e0762022-03-22 11:27:26 -0400923 info = append(info, propInfo{Name: name, Type: elKind.String() + " " + kind.String(), Values: sliceReflectionValue(v)})
Liz Kammer9525e712022-01-05 13:46:24 -0500924 default:
Liz Kammer898e0762022-03-22 11:27:26 -0400925 info = append(info, propInfo{Name: name, Type: kind.String(), Value: reflectionValue(v)})
Liz Kammer9525e712022-01-05 13:46:24 -0500926 }
927 }
928
929 for _, p := range props {
930 propsWithValues("", reflect.ValueOf(p).Elem())
931 }
Liz Kammer898e0762022-03-22 11:27:26 -0400932 sort.Slice(info, func(i, j int) bool {
933 return info[i].Name < info[j].Name
934 })
Liz Kammer9525e712022-01-05 13:46:24 -0500935 return info
Lukacs T. Berkid18d8ca2021-06-25 09:11:22 +0200936}
937
Liz Kammer898e0762022-03-22 11:27:26 -0400938func reflectionValue(value reflect.Value) string {
939 switch value.Kind() {
940 case reflect.Bool:
941 return fmt.Sprintf("%t", value.Bool())
942 case reflect.Int64:
943 return fmt.Sprintf("%d", value.Int())
944 case reflect.String:
945 return fmt.Sprintf("%s", value.String())
946 case reflect.Struct:
947 if value.IsZero() {
948 return "{}"
949 }
950 length := value.NumField()
951 vals := make([]string, length, length)
952 for i := 0; i < length; i++ {
953 sTyp := value.Type().Field(i)
954 if proptools.ShouldSkipProperty(sTyp) {
955 continue
956 }
957 name := sTyp.Name
958 vals[i] = fmt.Sprintf("%s: %s", name, reflectionValue(value.Field(i)))
959 }
960 return fmt.Sprintf("%s{%s}", value.Type(), strings.Join(vals, ", "))
961 case reflect.Array, reflect.Slice:
962 vals := sliceReflectionValue(value)
963 return fmt.Sprintf("[%s]", strings.Join(vals, ", "))
964 }
965 return ""
966}
967
968func sliceReflectionValue(value reflect.Value) []string {
969 length := value.Len()
970 vals := make([]string, length, length)
971 for i := 0; i < length; i++ {
972 vals[i] = reflectionValue(value.Index(i))
973 }
974 return vals
975}
976
Paul Duffin44f1d842020-06-26 20:17:02 +0100977func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {}
978
Colin Cross4157e882019-06-06 16:57:04 -0700979func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
Colin Cross5f692ec2019-02-01 16:53:07 -0800980
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800981func (m *ModuleBase) baseDepsMutator(ctx BottomUpMutatorContext) {
982 if m.Team() != "" {
983 ctx.AddDependency(ctx.Module(), teamDepTag, m.Team())
984 }
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900985
986 // TODO(jiyong): remove below case. This is to work around build errors happening
987 // on branches with reduced manifest like aosp_kernel-build-tools.
988 // In the branch, a build error occurs as follows.
989 // 1. aosp_kernel-build-tools is a reduced manifest branch. It doesn't have some git
990 // projects like external/bouncycastle
991 // 2. `boot_signer` is `required` by modules like `build_image` which is explicitly list as
992 // the top-level build goal (in the shell file that invokes Soong).
993 // 3. `boot_signer` depends on `bouncycastle-unbundled` which is in the missing git project.
Cole Faust88f469e2025-01-21 13:05:05 -0800994 // 4. aosp_kernel-build-tools invokes soong with `--soong-only`. Therefore, the absence of
995 // ALLOW_MISSING_DEPENDENCIES didn't cause a problem, as previously only make processed required
996 // dependencies.
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900997 // 5. Now, since Soong understands `required` deps, it tries to build `boot_signer` and the
998 // absence of external/bouncycastle fails the build.
999 //
1000 // Unfortunately, there's no way for Soong to correctly determine if it's running in a
1001 // reduced manifest branch. Instead, here, we use the absence of DeviceArch or DeviceName as
1002 // a strong signal, because that's very common across reduced manifest branches.
1003 pv := ctx.Config().productVariables
1004 fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil
1005 if fullManifest {
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001006 addVintfFragmentDeps(ctx)
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001007 }
1008}
1009
Inseob Kim0c67c8e2025-03-14 18:33:55 +09001010// required property can be overridden too; handle it separately
1011func (m *ModuleBase) baseOverridablePropertiesDepsMutator(ctx BottomUpMutatorContext) {
1012 pv := ctx.Config().productVariables
1013 fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil
1014 if fullManifest {
1015 addRequiredDeps(ctx)
1016 }
1017}
1018
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001019// addRequiredDeps adds required, target_required, and host_required as dependencies.
Jiyong Parkf21dd652024-04-17 05:22:37 +00001020func addRequiredDeps(ctx BottomUpMutatorContext) {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001021 addDep := func(target Target, depName string) {
1022 if !ctx.OtherModuleExists(depName) {
1023 if ctx.Config().AllowMissingDependencies() {
1024 return
1025 }
1026 }
1027
1028 // If Android native module requires another Android native module, ensure that
1029 // they have the same bitness. This mimics the policy in select-bitness-of-required-modules
1030 // in build/make/core/main.mk.
1031 // TODO(jiyong): the Make-side does this only when the required module is a shared
1032 // library or a native test.
Jiyong Parkf21dd652024-04-17 05:22:37 +00001033 bothInAndroid := ctx.Device() && target.Os.Class == Device
Jiyong Parkc4b1d552024-05-13 16:47:30 +09001034 nativeArch := InList(ctx.Arch().ArchType.Multilib, []string{"lib32", "lib64"}) &&
1035 InList(target.Arch.ArchType.Multilib, []string{"lib32", "lib64"})
Jiyong Parkf21dd652024-04-17 05:22:37 +00001036 sameBitness := ctx.Arch().ArchType.Multilib == target.Arch.ArchType.Multilib
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001037 if bothInAndroid && nativeArch && !sameBitness {
1038 return
1039 }
1040
Jiyong Park8db44152024-05-28 12:22:04 +09001041 // ... also don't make a dependency between native bridge arch and non-native bridge
1042 // arches. b/342945184
1043 if ctx.Target().NativeBridge != target.NativeBridge {
1044 return
1045 }
1046
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001047 variation := target.Variations()
1048 if ctx.OtherModuleFarDependencyVariantExists(variation, depName) {
1049 ctx.AddFarVariationDependencies(variation, RequiredDepTag, depName)
1050 }
1051 }
1052
Jiyong Park73e5bab2024-04-05 13:37:21 +09001053 var deviceTargets []Target
1054 deviceTargets = append(deviceTargets, ctx.Config().Targets[Android]...)
1055 deviceTargets = append(deviceTargets, ctx.Config().AndroidCommonTarget)
1056
1057 var hostTargets []Target
1058 hostTargets = append(hostTargets, ctx.Config().Targets[ctx.Config().BuildOS]...)
1059 hostTargets = append(hostTargets, ctx.Config().BuildOSCommonTarget)
1060
Jiyong Parkf21dd652024-04-17 05:22:37 +00001061 if ctx.Device() {
Jihoon Kangd1a01422024-12-26 19:07:13 +00001062 for _, depName := range append(ctx.Module().RequiredModuleNames(ctx), ctx.Module().VintfFragmentModuleNames(ctx)...) {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001063 for _, target := range deviceTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001064 addDep(target, depName)
1065 }
1066 }
Jiyong Parkf21dd652024-04-17 05:22:37 +00001067 for _, depName := range ctx.Module().HostRequiredModuleNames() {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001068 for _, target := range hostTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001069 addDep(target, depName)
1070 }
1071 }
1072 }
1073
Jiyong Parkf21dd652024-04-17 05:22:37 +00001074 if ctx.Host() {
Jihoon Kangd1a01422024-12-26 19:07:13 +00001075 for _, depName := range append(ctx.Module().RequiredModuleNames(ctx), ctx.Module().VintfFragmentModuleNames(ctx)...) {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001076 for _, target := range hostTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001077 // When a host module requires another host module, don't make a
1078 // dependency if they have different OSes (i.e. hostcross).
Jiyong Parkf21dd652024-04-17 05:22:37 +00001079 if ctx.Target().HostCross != target.HostCross {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001080 continue
1081 }
1082 addDep(target, depName)
1083 }
1084 }
Jiyong Parkf21dd652024-04-17 05:22:37 +00001085 for _, depName := range ctx.Module().TargetRequiredModuleNames() {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001086 for _, target := range deviceTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001087 addDep(target, depName)
1088 }
1089 }
1090 }
Ronald Braunstein73b08ff2023-12-19 10:24:47 -08001091}
1092
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001093var vintfDepTag = struct {
1094 blueprint.BaseDependencyTag
1095 InstallAlwaysNeededDependencyTag
1096}{}
1097
Kiyoung Kim11ad4e92024-09-04 14:16:47 +09001098func IsVintfDepTag(depTag blueprint.DependencyTag) bool {
1099 return depTag == vintfDepTag
1100}
1101
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001102func addVintfFragmentDeps(ctx BottomUpMutatorContext) {
Kiyoung Kim55234812024-09-11 17:00:24 +09001103 // Vintf manifests in the recovery partition will be ignored.
1104 if !ctx.Device() || ctx.Module().InstallInRecovery() {
1105 return
1106 }
1107
1108 deviceConfig := ctx.DeviceConfig()
1109
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001110 mod := ctx.Module()
Kiyoung Kim55234812024-09-11 17:00:24 +09001111 vintfModules := ctx.AddDependency(mod, vintfDepTag, mod.VintfFragmentModuleNames(ctx)...)
1112
1113 modPartition := mod.PartitionTag(deviceConfig)
1114 for _, vintf := range vintfModules {
Cole Faust69788792024-10-10 11:00:36 -07001115 if vintf == nil {
1116 // TODO(b/372091092): Remove this. Having it gives us missing dependency errors instead
1117 // of nil pointer dereference errors, but we should resolve the missing dependencies.
1118 continue
1119 }
Kiyoung Kim11ad4e92024-09-04 14:16:47 +09001120 if vintfModule, ok := vintf.(*VintfFragmentModule); ok {
Kiyoung Kim55234812024-09-11 17:00:24 +09001121 vintfPartition := vintfModule.PartitionTag(deviceConfig)
1122 if modPartition != vintfPartition {
1123 ctx.ModuleErrorf("Module %q(%q) and Vintf_fragment %q(%q) are installed to different partitions.",
1124 mod.Name(), modPartition,
1125 vintfModule.Name(), vintfPartition)
1126 }
1127 } else {
1128 ctx.ModuleErrorf("Only vintf_fragment type module should be listed in vintf_fragment_modules : %q", vintf.Name())
1129 }
1130 }
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001131}
1132
Usta355a5872021-12-01 15:16:32 -05001133// AddProperties "registers" the provided props
1134// each value in props MUST be a pointer to a struct
Colin Cross4157e882019-06-06 16:57:04 -07001135func (m *ModuleBase) AddProperties(props ...interface{}) {
1136 m.registerProps = append(m.registerProps, props...)
Colin Cross36242852017-06-23 15:06:31 -07001137}
1138
Colin Cross4157e882019-06-06 16:57:04 -07001139func (m *ModuleBase) GetProperties() []interface{} {
1140 return m.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -08001141}
1142
Colin Cross4157e882019-06-06 16:57:04 -07001143func (m *ModuleBase) BuildParamsForTests() []BuildParams {
Chih-Hung Hsiehb8082292021-09-09 23:20:39 -07001144 // Expand the references to module variables like $flags[0-9]*,
1145 // so we do not need to change many existing unit tests.
1146 // This looks like undoing the shareFlags optimization in cc's
1147 // transformSourceToObj, and should only affects unit tests.
1148 vars := m.VariablesForTests()
1149 buildParams := append([]BuildParams(nil), m.buildParams...)
Sasha Smundake198eaf2022-08-04 13:07:02 -07001150 for i := range buildParams {
Chih-Hung Hsiehb8082292021-09-09 23:20:39 -07001151 newArgs := make(map[string]string)
1152 for k, v := range buildParams[i].Args {
1153 newArgs[k] = v
1154 // Replaces both ${flags1} and $flags1 syntax.
1155 if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") {
1156 if value, found := vars[v[2:len(v)-1]]; found {
1157 newArgs[k] = value
1158 }
1159 } else if strings.HasPrefix(v, "$") {
1160 if value, found := vars[v[1:]]; found {
1161 newArgs[k] = value
1162 }
1163 }
1164 }
1165 buildParams[i].Args = newArgs
1166 }
1167 return buildParams
Colin Crosscec81712017-07-13 14:43:27 -07001168}
1169
Colin Cross4157e882019-06-06 16:57:04 -07001170func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
1171 return m.ruleParams
Colin Cross4c83e5c2019-02-25 14:54:28 -08001172}
1173
Colin Cross4157e882019-06-06 16:57:04 -07001174func (m *ModuleBase) VariablesForTests() map[string]string {
1175 return m.variables
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001176}
1177
Colin Crossce75d2c2016-10-06 16:12:58 -07001178// Name returns the name of the module. It may be overridden by individual module types, for
1179// example prebuilts will prepend prebuilt_ to the name.
Colin Cross4157e882019-06-06 16:57:04 -07001180func (m *ModuleBase) Name() string {
1181 return String(m.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -07001182}
1183
Colin Cross9a362232019-07-01 15:32:45 -07001184// String returns a string that includes the module name and variants for printing during debugging.
1185func (m *ModuleBase) String() string {
1186 sb := strings.Builder{}
1187 sb.WriteString(m.commonProperties.DebugName)
1188 sb.WriteString("{")
1189 for i := range m.commonProperties.DebugMutators {
1190 if i != 0 {
1191 sb.WriteString(",")
1192 }
1193 sb.WriteString(m.commonProperties.DebugMutators[i])
1194 sb.WriteString(":")
1195 sb.WriteString(m.commonProperties.DebugVariations[i])
1196 }
1197 sb.WriteString("}")
1198 return sb.String()
1199}
1200
Colin Crossce75d2c2016-10-06 16:12:58 -07001201// BaseModuleName returns the name of the module as specified in the blueprints file.
Colin Cross4157e882019-06-06 16:57:04 -07001202func (m *ModuleBase) BaseModuleName() string {
1203 return String(m.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -07001204}
1205
Colin Cross4157e882019-06-06 16:57:04 -07001206func (m *ModuleBase) base() *ModuleBase {
1207 return m
Colin Cross3f40fa42015-01-30 17:27:36 -08001208}
1209
Paul Duffine2453c72019-05-31 14:00:04 +01001210func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName {
1211 return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()}
1212}
1213
1214func (m *ModuleBase) visibilityProperties() []visibilityProperty {
Paul Duffin63c6e182019-07-24 14:24:38 +01001215 return m.visibilityPropertyInfo
1216}
1217
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001218func (m *ModuleBase) Dists() []Dist {
Paul Duffined875132020-09-02 13:08:57 +01001219 if len(m.distProperties.Dist.Targets) > 0 {
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001220 // Make a copy of the underlying Dists slice to protect against
1221 // backing array modifications with repeated calls to this method.
Paul Duffined875132020-09-02 13:08:57 +01001222 distsCopy := append([]Dist(nil), m.distProperties.Dists...)
1223 return append(distsCopy, m.distProperties.Dist)
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001224 } else {
Paul Duffined875132020-09-02 13:08:57 +01001225 return m.distProperties.Dists
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001226 }
1227}
1228
1229func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFiles {
Paul Duffin74f05592020-11-25 16:37:46 +00001230 var distFiles TaggedDistFiles
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001231 for _, dist := range m.Dists() {
Paul Duffin74f05592020-11-25 16:37:46 +00001232 // If no tag is specified then it means to use the default dist paths so use
1233 // the special tag name which represents that.
1234 tag := proptools.StringDefault(dist.Tag, DefaultDistTag)
1235
mrziwangabdb2932024-06-18 12:43:41 -07001236 distFileForTagFromProvider, err := outputFilesForModuleFromProvider(ctx, m.module, tag)
Cole Fausta8437c52025-02-25 14:45:43 -08001237
1238 // If the module doesn't define output files for the DefaultDistTag, try the files under
1239 // the "" tag.
1240 if tag == DefaultDistTag && errors.Is(err, ErrUnsupportedOutputTag) {
1241 distFileForTagFromProvider, err = outputFilesForModuleFromProvider(ctx, m.module, "")
1242 }
1243
mrziwangabdb2932024-06-18 12:43:41 -07001244 if err != OutputFilesProviderNotSet {
1245 if err != nil && tag != DefaultDistTag {
1246 ctx.PropertyErrorf("dist.tag", "%s", err.Error())
1247 } else {
1248 distFiles = distFiles.addPathsForTag(tag, distFileForTagFromProvider...)
1249 continue
1250 }
1251 }
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001252 }
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001253 return distFiles
1254}
1255
Cole Faust02987bd2024-03-21 17:58:43 -07001256func (m *ModuleBase) ArchReady() bool {
1257 return m.commonProperties.ArchReady
1258}
1259
Colin Cross4157e882019-06-06 16:57:04 -07001260func (m *ModuleBase) Target() Target {
1261 return m.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -08001262}
1263
Colin Cross4157e882019-06-06 16:57:04 -07001264func (m *ModuleBase) TargetPrimary() bool {
1265 return m.commonProperties.CompilePrimary
Colin Cross8b74d172016-09-13 09:59:14 -07001266}
1267
Colin Cross4157e882019-06-06 16:57:04 -07001268func (m *ModuleBase) MultiTargets() []Target {
1269 return m.commonProperties.CompileMultiTargets
Colin Crossee0bc3b2018-10-02 22:01:37 -07001270}
1271
Colin Cross4157e882019-06-06 16:57:04 -07001272func (m *ModuleBase) Os() OsType {
1273 return m.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -08001274}
1275
Colin Cross4157e882019-06-06 16:57:04 -07001276func (m *ModuleBase) Host() bool {
Jiyong Park1613e552020-09-14 19:43:17 +09001277 return m.Os().Class == Host
Dan Willemsen97750522016-02-09 17:43:51 -08001278}
1279
Yo Chiangbba545e2020-06-09 16:15:37 +08001280func (m *ModuleBase) Device() bool {
1281 return m.Os().Class == Device
1282}
1283
Colin Cross4157e882019-06-06 16:57:04 -07001284func (m *ModuleBase) Arch() Arch {
1285 return m.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -08001286}
1287
Colin Cross4157e882019-06-06 16:57:04 -07001288func (m *ModuleBase) ArchSpecific() bool {
1289 return m.commonProperties.ArchSpecific
Dan Willemsen0b24c742016-10-04 15:13:37 -07001290}
1291
Paul Duffin1356d8c2020-02-25 19:26:33 +00001292// True if the current variant is a CommonOS variant, false otherwise.
1293func (m *ModuleBase) IsCommonOSVariant() bool {
Colin Cross8bbc3d52024-09-11 15:33:54 -07001294 return m.commonProperties.CompileOS == CommonOS
Paul Duffin1356d8c2020-02-25 19:26:33 +00001295}
1296
Colin Cross34037c62020-11-17 13:19:17 -08001297// supportsTarget returns true if the given Target is supported by the current module.
1298func (m *ModuleBase) supportsTarget(target Target) bool {
1299 switch target.Os.Class {
1300 case Host:
1301 if target.HostCross {
1302 return m.HostCrossSupported()
1303 } else {
1304 return m.HostSupported()
Colin Crossa1ad8d12016-06-01 17:09:44 -07001305 }
Colin Cross34037c62020-11-17 13:19:17 -08001306 case Device:
1307 return m.DeviceSupported()
Colin Crossa1ad8d12016-06-01 17:09:44 -07001308 default:
Jiyong Park1613e552020-09-14 19:43:17 +09001309 return false
Colin Crossa1ad8d12016-06-01 17:09:44 -07001310 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001311}
1312
Colin Cross34037c62020-11-17 13:19:17 -08001313// DeviceSupported returns true if the current module is supported and enabled for device targets,
1314// i.e. the factory method set the HostOrDeviceSupported value to include device support and
1315// the device support is enabled by default or enabled by the device_supported property.
Colin Cross4157e882019-06-06 16:57:04 -07001316func (m *ModuleBase) DeviceSupported() bool {
Colin Cross34037c62020-11-17 13:19:17 -08001317 hod := m.commonProperties.HostOrDeviceSupported
1318 // deviceEnabled is true if the device_supported property is true or the HostOrDeviceSupported
1319 // value has the deviceDefault bit set.
1320 deviceEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Device_supported, hod&deviceDefault != 0)
1321 return hod&deviceSupported != 0 && deviceEnabled
Colin Cross3f40fa42015-01-30 17:27:36 -08001322}
1323
Colin Cross34037c62020-11-17 13:19:17 -08001324// HostSupported returns true if the current module is supported and enabled for host targets,
1325// i.e. the factory method set the HostOrDeviceSupported value to include host support and
1326// the host support is enabled by default or enabled by the host_supported property.
Paul Duffine44358f2019-11-26 18:04:12 +00001327func (m *ModuleBase) HostSupported() bool {
Colin Cross34037c62020-11-17 13:19:17 -08001328 hod := m.commonProperties.HostOrDeviceSupported
1329 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1330 // value has the hostDefault bit set.
1331 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
1332 return hod&hostSupported != 0 && hostEnabled
1333}
1334
1335// HostCrossSupported returns true if the current module is supported and enabled for host cross
1336// targets, i.e. the factory method set the HostOrDeviceSupported value to include host cross
1337// support and the host cross support is enabled by default or enabled by the
1338// host_supported property.
1339func (m *ModuleBase) HostCrossSupported() bool {
1340 hod := m.commonProperties.HostOrDeviceSupported
1341 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1342 // value has the hostDefault bit set.
1343 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
Ivan Lozanoc7eafa72024-07-16 17:55:33 +00001344
1345 // Default true for the Host_cross_supported property
1346 hostCrossEnabled := proptools.BoolDefault(m.hostCrossProperties.Host_cross_supported, true)
1347
1348 return hod&hostCrossSupported != 0 && hostEnabled && hostCrossEnabled
Paul Duffine44358f2019-11-26 18:04:12 +00001349}
1350
Colin Cross4157e882019-06-06 16:57:04 -07001351func (m *ModuleBase) Platform() bool {
Justin Yund5f6c822019-06-25 16:47:17 +09001352 return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.SystemExtSpecific()
Jiyong Parkc678ad32018-04-10 13:07:10 +09001353}
1354
Colin Cross4157e882019-06-06 16:57:04 -07001355func (m *ModuleBase) DeviceSpecific() bool {
1356 return Bool(m.commonProperties.Device_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001357}
1358
Colin Cross4157e882019-06-06 16:57:04 -07001359func (m *ModuleBase) SocSpecific() bool {
1360 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001361}
1362
Colin Cross4157e882019-06-06 16:57:04 -07001363func (m *ModuleBase) ProductSpecific() bool {
1364 return Bool(m.commonProperties.Product_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001365}
1366
Justin Yund5f6c822019-06-25 16:47:17 +09001367func (m *ModuleBase) SystemExtSpecific() bool {
1368 return Bool(m.commonProperties.System_ext_specific)
Dario Frenifd05a742018-05-29 13:28:54 +01001369}
1370
Colin Crossc2d24052020-05-13 11:05:02 -07001371// RequiresStableAPIs returns true if the module will be installed to a partition that may
1372// be updated separately from the system image.
1373func (m *ModuleBase) RequiresStableAPIs(ctx BaseModuleContext) bool {
1374 return m.SocSpecific() || m.DeviceSpecific() ||
1375 (m.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface())
1376}
1377
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001378func (m *ModuleBase) PartitionTag(config DeviceConfig) string {
1379 partition := "system"
1380 if m.SocSpecific() {
1381 // A SoC-specific module could be on the vendor partition at
1382 // "vendor" or the system partition at "system/vendor".
1383 if config.VendorPath() == "vendor" {
1384 partition = "vendor"
1385 }
1386 } else if m.DeviceSpecific() {
1387 // A device-specific module could be on the odm partition at
1388 // "odm", the vendor partition at "vendor/odm", or the system
1389 // partition at "system/vendor/odm".
1390 if config.OdmPath() == "odm" {
1391 partition = "odm"
Ramy Medhat944839a2020-03-31 22:14:52 -04001392 } else if strings.HasPrefix(config.OdmPath(), "vendor/") {
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001393 partition = "vendor"
1394 }
1395 } else if m.ProductSpecific() {
1396 // A product-specific module could be on the product partition
1397 // at "product" or the system partition at "system/product".
1398 if config.ProductPath() == "product" {
1399 partition = "product"
1400 }
1401 } else if m.SystemExtSpecific() {
1402 // A system_ext-specific module could be on the system_ext
1403 // partition at "system_ext" or the system partition at
1404 // "system/system_ext".
1405 if config.SystemExtPath() == "system_ext" {
1406 partition = "system_ext"
1407 }
Cole Faust76a6e952024-11-07 16:56:45 -08001408 } else if m.InstallInRamdisk() {
1409 partition = "ramdisk"
Jihoon Kang30bf8f62024-11-26 21:50:55 +00001410 } else if m.InstallInVendorRamdisk() {
1411 partition = "vendor_ramdisk"
Jihoon Kang3216c982024-12-02 19:42:20 +00001412 } else if m.InstallInRecovery() {
1413 partition = "recovery"
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001414 }
1415 return partition
1416}
1417
Cole Fauste8a87832024-09-11 11:35:46 -07001418func (m *ModuleBase) Enabled(ctx ConfigurableEvaluatorContext) bool {
Justin Yun32f053b2020-07-31 23:07:17 +09001419 if m.commonProperties.ForcedDisabled {
1420 return false
1421 }
Cole Fausta963b942024-04-11 17:43:00 -07001422 return m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled)
Colin Cross3f40fa42015-01-30 17:27:36 -08001423}
1424
Cole Faust8eeae4b2024-09-12 11:51:04 -07001425// Returns a copy of the enabled property, useful for passing it on to sub-modules
1426func (m *ModuleBase) EnabledProperty() proptools.Configurable[bool] {
1427 if m.commonProperties.ForcedDisabled {
1428 return proptools.NewSimpleConfigurable(false)
1429 }
1430 return m.commonProperties.Enabled.Clone()
1431}
1432
Inseob Kimeec88e12020-01-22 11:11:29 +09001433func (m *ModuleBase) Disable() {
Justin Yun32f053b2020-07-31 23:07:17 +09001434 m.commonProperties.ForcedDisabled = true
Inseob Kimeec88e12020-01-22 11:11:29 +09001435}
1436
Colin Crossa9c8c9f2020-12-16 10:20:23 -08001437// HideFromMake marks this variant so that it is not emitted in the generated Android.mk file.
1438func (m *ModuleBase) HideFromMake() {
1439 m.commonProperties.HideFromMake = true
1440}
1441
1442// IsHideFromMake returns true if HideFromMake was previously called.
1443func (m *ModuleBase) IsHideFromMake() bool {
1444 return m.commonProperties.HideFromMake == true
1445}
1446
1447// SkipInstall marks this variant to not create install rules when ctx.Install* are called.
Colin Cross4157e882019-06-06 16:57:04 -07001448func (m *ModuleBase) SkipInstall() {
1449 m.commonProperties.SkipInstall = true
Colin Crossce75d2c2016-10-06 16:12:58 -07001450}
1451
Martin Stjernholm9e7f45e2020-12-23 03:50:30 +00001452// IsSkipInstall returns true if this variant is marked to not create install
1453// rules when ctx.Install* are called.
1454func (m *ModuleBase) IsSkipInstall() bool {
1455 return m.commonProperties.SkipInstall
1456}
1457
Iván Budnik295da162023-03-10 16:11:26 +00001458// Similar to HideFromMake, but if the AndroidMk entry would set
1459// LOCAL_UNINSTALLABLE_MODULE then this variant may still output that entry
1460// rather than leaving it out altogether. That happens in cases where it would
1461// have other side effects, in particular when it adds a NOTICE file target,
1462// which other install targets might depend on.
1463func (m *ModuleBase) MakeUninstallable() {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001464 m.commonProperties.UninstallableApexPlatformVariant = true
Iván Budnik295da162023-03-10 16:11:26 +00001465 m.HideFromMake()
Spandan Das034af2c2024-10-30 21:45:09 +00001466 m.SkipInstall()
Iván Budnik295da162023-03-10 16:11:26 +00001467}
1468
Liz Kammer5ca3a622020-08-05 15:40:41 -07001469func (m *ModuleBase) ReplacedByPrebuilt() {
1470 m.commonProperties.ReplacedByPrebuilt = true
Colin Crossa9c8c9f2020-12-16 10:20:23 -08001471 m.HideFromMake()
Liz Kammer5ca3a622020-08-05 15:40:41 -07001472}
1473
1474func (m *ModuleBase) IsReplacedByPrebuilt() bool {
1475 return m.commonProperties.ReplacedByPrebuilt
1476}
1477
Colin Cross4157e882019-06-06 16:57:04 -07001478func (m *ModuleBase) ExportedToMake() bool {
1479 return m.commonProperties.NamespaceExportedToMake
Jiyong Park374510b2018-03-19 18:23:01 +09001480}
1481
Justin Yun885a7de2021-06-29 20:34:53 +09001482func (m *ModuleBase) EffectiveLicenseFiles() Paths {
Bob Badour4101c712022-02-09 11:54:35 -08001483 result := make(Paths, 0, len(m.commonProperties.Effective_license_text))
1484 for _, p := range m.commonProperties.Effective_license_text {
1485 result = append(result, p.Path)
1486 }
1487 return result
Justin Yun885a7de2021-06-29 20:34:53 +09001488}
1489
Colin Crosse9fe2942020-11-10 18:12:15 -08001490// computeInstallDeps finds the installed paths of all dependencies that have a dependency
Colin Crossbd3a16b2023-04-25 11:30:51 -07001491// tag that is annotated as needing installation via the isInstallDepNeeded method.
Colin Crossa14fb6a2024-10-23 16:57:06 -07001492func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]depset.DepSet[InstallPath], []depset.DepSet[PackagingSpec]) {
1493 var installDeps []depset.DepSet[InstallPath]
1494 var packagingSpecs []depset.DepSet[PackagingSpec]
Yu Liu5697f8f2024-12-13 23:31:08 +00001495 ctx.VisitDirectDepsProxy(func(dep ModuleProxy) {
1496 if isInstallDepNeeded(ctx, dep) {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001497 // Installation is still handled by Make, so anything hidden from Make is not
1498 // installable.
Yu Liubad1eef2024-08-21 22:37:35 +00001499 info := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider)
Yu Liuf22120f2025-03-13 18:36:35 +00001500 commonInfo := OtherModulePointerProviderOrDefault(ctx, dep, CommonModuleInfoProvider)
Yu Liu5697f8f2024-12-13 23:31:08 +00001501 if !commonInfo.HideFromMake && !commonInfo.SkipInstall {
Yu Liubad1eef2024-08-21 22:37:35 +00001502 installDeps = append(installDeps, info.TransitiveInstallFiles)
Colin Crossbd3a16b2023-04-25 11:30:51 -07001503 }
1504 // Add packaging deps even when the dependency is not installed so that uninstallable
1505 // modules can still be packaged. Often the package will be installed instead.
Yu Liubad1eef2024-08-21 22:37:35 +00001506 packagingSpecs = append(packagingSpecs, info.TransitivePackagingSpecs)
Colin Cross897266e2020-02-13 13:22:08 -08001507 }
1508 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001509
Colin Crossffe6b9d2020-12-01 15:40:06 -08001510 return installDeps, packagingSpecs
Colin Cross3f40fa42015-01-30 17:27:36 -08001511}
1512
Colin Crossbd3a16b2023-04-25 11:30:51 -07001513// isInstallDepNeeded returns true if installing the output files of the current module
1514// should also install the output files of the given dependency and dependency tag.
Yu Liu5697f8f2024-12-13 23:31:08 +00001515func isInstallDepNeeded(ctx ModuleContext, dep ModuleProxy) bool {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001516 // Don't add a dependency from the platform to a library provided by an apex.
Yu Liuf22120f2025-03-13 18:36:35 +00001517 if OtherModulePointerProviderOrDefault(ctx, dep, CommonModuleInfoProvider).UninstallableApexPlatformVariant {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001518 return false
1519 }
1520 // Only install modules if the dependency tag is an InstallDepNeeded tag.
Yu Liu5697f8f2024-12-13 23:31:08 +00001521 return IsInstallDepNeededTag(ctx.OtherModuleDependencyTag(dep))
Colin Crossbd3a16b2023-04-25 11:30:51 -07001522}
1523
Colin Cross4157e882019-06-06 16:57:04 -07001524func (m *ModuleBase) NoAddressSanitizer() bool {
1525 return m.noAddressSanitizer
Colin Cross3f40fa42015-01-30 17:27:36 -08001526}
1527
Colin Cross4157e882019-06-06 16:57:04 -07001528func (m *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -08001529 return false
1530}
1531
Jaewoong Jung0949f312019-09-11 10:25:18 -07001532func (m *ModuleBase) InstallInTestcases() bool {
1533 return false
1534}
1535
Colin Cross4157e882019-06-06 16:57:04 -07001536func (m *ModuleBase) InstallInSanitizerDir() bool {
Vishwath Mohan1dd88392017-03-29 22:00:18 -07001537 return false
1538}
1539
Yifan Hong1b3348d2020-01-21 15:53:22 -08001540func (m *ModuleBase) InstallInRamdisk() bool {
1541 return Bool(m.commonProperties.Ramdisk)
1542}
1543
Yifan Hong60e0cfb2020-10-21 15:17:56 -07001544func (m *ModuleBase) InstallInVendorRamdisk() bool {
1545 return Bool(m.commonProperties.Vendor_ramdisk)
1546}
1547
Inseob Kim08758f02021-04-08 21:13:22 +09001548func (m *ModuleBase) InstallInDebugRamdisk() bool {
1549 return Bool(m.commonProperties.Debug_ramdisk)
1550}
1551
Colin Cross4157e882019-06-06 16:57:04 -07001552func (m *ModuleBase) InstallInRecovery() bool {
1553 return Bool(m.commonProperties.Recovery)
Jiyong Parkf9332f12018-02-01 00:54:12 +09001554}
1555
Colin Crossea30d852023-11-29 16:00:16 -08001556func (m *ModuleBase) InstallInOdm() bool {
1557 return false
1558}
1559
1560func (m *ModuleBase) InstallInProduct() bool {
1561 return false
1562}
1563
Kiyoung Kimae11c232021-07-19 11:38:04 +09001564func (m *ModuleBase) InstallInVendor() bool {
Kiyoung Kimf160f7f2022-11-29 10:58:08 +09001565 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Soc_specific) || Bool(m.commonProperties.Proprietary)
Kiyoung Kimae11c232021-07-19 11:38:04 +09001566}
1567
Spandan Das950deca2024-10-01 18:35:23 +00001568func (m *ModuleBase) InstallInSystemExt() bool {
1569 return Bool(m.commonProperties.System_ext_specific)
1570}
1571
Colin Cross90ba5f42019-10-02 11:10:58 -07001572func (m *ModuleBase) InstallInRoot() bool {
1573 return false
1574}
1575
Spandan Das27ff7672024-11-06 19:23:57 +00001576func (m *ModuleBase) InstallInSystemDlkm() bool {
1577 return Bool(m.commonProperties.System_dlkm_specific)
1578}
1579
1580func (m *ModuleBase) InstallInVendorDlkm() bool {
1581 return Bool(m.commonProperties.Vendor_dlkm_specific)
1582}
1583
1584func (m *ModuleBase) InstallInOdmDlkm() bool {
1585 return Bool(m.commonProperties.Odm_dlkm_specific)
1586}
1587
Jiyong Park87788b52020-09-01 12:37:45 +09001588func (m *ModuleBase) InstallForceOS() (*OsType, *ArchType) {
1589 return nil, nil
Colin Cross6e359402020-02-10 15:29:54 -08001590}
1591
Colin Cross4157e882019-06-06 16:57:04 -07001592func (m *ModuleBase) Owner() string {
1593 return String(m.commonProperties.Owner)
Sundong Ahn4fd04bb2018-08-31 18:01:37 +09001594}
1595
Ronald Braunstein73b08ff2023-12-19 10:24:47 -08001596func (m *ModuleBase) Team() string {
1597 return String(m.commonProperties.Team)
1598}
1599
Colin Cross7228ecd2019-11-18 16:00:16 -08001600func (m *ModuleBase) setImageVariation(variant string) {
1601 m.commonProperties.ImageVariation = variant
1602}
1603
1604func (m *ModuleBase) ImageVariation() blueprint.Variation {
1605 return blueprint.Variation{
1606 Mutator: "image",
1607 Variation: m.base().commonProperties.ImageVariation,
1608 }
1609}
1610
Paul Duffin9b76c0b2020-03-12 10:24:35 +00001611func (m *ModuleBase) getVariationByMutatorName(mutator string) string {
1612 for i, v := range m.commonProperties.DebugMutators {
1613 if v == mutator {
1614 return m.commonProperties.DebugVariations[i]
1615 }
1616 }
1617
1618 return ""
1619}
1620
Yifan Hong1b3348d2020-01-21 15:53:22 -08001621func (m *ModuleBase) InRamdisk() bool {
1622 return m.base().commonProperties.ImageVariation == RamdiskVariation
1623}
1624
Yifan Hong60e0cfb2020-10-21 15:17:56 -07001625func (m *ModuleBase) InVendorRamdisk() bool {
1626 return m.base().commonProperties.ImageVariation == VendorRamdiskVariation
1627}
1628
Inseob Kim08758f02021-04-08 21:13:22 +09001629func (m *ModuleBase) InDebugRamdisk() bool {
1630 return m.base().commonProperties.ImageVariation == DebugRamdiskVariation
1631}
1632
Colin Cross7228ecd2019-11-18 16:00:16 -08001633func (m *ModuleBase) InRecovery() bool {
1634 return m.base().commonProperties.ImageVariation == RecoveryVariation
1635}
1636
Cole Fauste8a87832024-09-11 11:35:46 -07001637func (m *ModuleBase) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string {
Cole Faust2239ae62025-01-27 15:32:11 -08001638 return m.base().baseProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09001639}
1640
1641func (m *ModuleBase) HostRequiredModuleNames() []string {
Cole Faust2239ae62025-01-27 15:32:11 -08001642 return m.base().baseProperties.Host_required
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09001643}
1644
1645func (m *ModuleBase) TargetRequiredModuleNames() []string {
Cole Faust2239ae62025-01-27 15:32:11 -08001646 return m.base().baseProperties.Target_required
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09001647}
1648
Cole Fauste8a87832024-09-11 11:35:46 -07001649func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string {
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001650 return m.base().commonProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
1651}
1652
Kiyoung Kim23be5bb2024-11-27 00:50:30 +00001653func (m *ModuleBase) VintfFragments(ctx ConfigurableEvaluatorContext) []string {
1654 return m.base().commonProperties.Vintf_fragments.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
1655}
1656
Colin Crossa6182ab2024-08-21 10:47:44 -07001657func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) {
1658 namespacePrefix := ctx.Namespace().id
1659 if namespacePrefix != "" {
1660 namespacePrefix = namespacePrefix + "-"
1661 }
1662
1663 if !ctx.uncheckedModule {
1664 name := namespacePrefix + ctx.ModuleName() + "-" + ctx.ModuleSubDir() + "-checkbuild"
1665 ctx.Phony(name, ctx.checkbuildFiles...)
1666 ctx.checkbuildTarget = PathForPhony(ctx, name)
1667 }
1668
1669}
1670
Cole Faust0523b8f2025-03-03 15:11:32 -08001671// generateModuleTarget generates phony targets so that you can do `m <module-name>`.
1672// It will be run on every variant of the module, so it relies on the fact that phony targets
1673// are deduped to merge all the deps from different variants together.
Yu Liuddc28332024-08-09 22:48:30 +00001674func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) {
Yu Liu460c0fa2024-08-20 19:31:15 +00001675 var namespacePrefix string
1676 nameSpace := ctx.Namespace().Path
1677 if nameSpace != "." {
1678 namespacePrefix = strings.ReplaceAll(nameSpace, "/", ".") + "-"
Jeff Gaston088e29e2017-11-29 16:47:17 -08001679 }
1680
Cole Faustc5bfbdd2025-01-08 13:05:40 -08001681 var deps Paths
Cole Faust0523b8f2025-03-03 15:11:32 -08001682 var info ModuleBuildTargetsInfo
Yu Liuddc2e1a2024-08-20 21:31:22 +00001683
Cole Faust0523b8f2025-03-03 15:11:32 -08001684 if len(ctx.installFiles) > 0 {
Colin Crossc3d87d32020-06-04 13:25:17 -07001685 name := namespacePrefix + ctx.ModuleName() + "-install"
Cole Faustd1bf2722025-03-05 10:42:50 -08001686 installFiles := ctx.installFiles.Paths()
1687 ctx.Phony(name, installFiles...)
Yu Liuddc2e1a2024-08-20 21:31:22 +00001688 info.InstallTarget = PathForPhony(ctx, name)
Cole Faustd1bf2722025-03-05 10:42:50 -08001689 deps = append(deps, installFiles...)
Colin Cross9454bfa2015-03-17 13:24:18 -07001690 }
1691
Cole Faust0523b8f2025-03-03 15:11:32 -08001692 // A module's -checkbuild phony targets should
1693 // not be created if the module is not exported to make.
1694 // Those could depend on the build target and fail to compile
1695 // for the current build target.
1696 if (!ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, m)) && !ctx.uncheckedModule && ctx.checkbuildTarget != nil {
Colin Crossc3d87d32020-06-04 13:25:17 -07001697 name := namespacePrefix + ctx.ModuleName() + "-checkbuild"
Cole Faust0523b8f2025-03-03 15:11:32 -08001698 ctx.Phony(name, ctx.checkbuildTarget)
Cole Faustd1bf2722025-03-05 10:42:50 -08001699 deps = append(deps, ctx.checkbuildTarget)
Colin Cross9454bfa2015-03-17 13:24:18 -07001700 }
1701
Cole Faust0523b8f2025-03-03 15:11:32 -08001702 if outputFiles, err := outputFilesForModule(ctx, ctx.Module(), ""); err == nil && len(outputFiles) > 0 {
Cole Faust71e3e7a2025-01-22 10:44:36 -08001703 name := namespacePrefix + ctx.ModuleName() + "-outputs"
Cole Faust0523b8f2025-03-03 15:11:32 -08001704 ctx.Phony(name, outputFiles...)
Cole Faustd1bf2722025-03-05 10:42:50 -08001705 deps = append(deps, outputFiles...)
Cole Faust71e3e7a2025-01-22 10:44:36 -08001706 }
1707
Colin Cross9454bfa2015-03-17 13:24:18 -07001708 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001709 suffix := ""
Jingwen Chencda22c92020-11-23 00:22:30 -05001710 if ctx.Config().KatiEnabled() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001711 suffix = "-soong"
1712 }
1713
Colin Crossc3d87d32020-06-04 13:25:17 -07001714 ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...)
Spandan Das25301f12025-01-24 22:22:37 +00001715 if ctx.Device() {
1716 // Generate a target suffix for use in atest etc.
1717 ctx.Phony(namespacePrefix+ctx.ModuleName()+"-target"+suffix, deps...)
Spandan Das25301f12025-01-24 22:22:37 +00001718 } else {
1719 // Generate a host suffix for use in atest etc.
1720 ctx.Phony(namespacePrefix+ctx.ModuleName()+"-host"+suffix, deps...)
Spandan Das481ec672025-01-27 19:55:52 +00001721 if ctx.Target().HostCross {
1722 // Generate a host-cross suffix for use in atest etc.
1723 ctx.Phony(namespacePrefix+ctx.ModuleName()+"-host-cross"+suffix, deps...)
1724 }
Spandan Das25301f12025-01-24 22:22:37 +00001725 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07001726
Yu Liuddc2e1a2024-08-20 21:31:22 +00001727 info.BlueprintDir = ctx.ModuleDir()
Cole Faust0523b8f2025-03-03 15:11:32 -08001728 SetProvider(ctx, ModuleBuildTargetsProvider, info)
Colin Cross3f40fa42015-01-30 17:27:36 -08001729 }
1730}
1731
Cole Faust5b7635d2024-10-28 13:01:12 -07001732func determineModuleKind(m *ModuleBase, ctx ModuleErrorContext) moduleKind {
Colin Cross4157e882019-06-06 16:57:04 -07001733 var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
1734 var deviceSpecific = Bool(m.commonProperties.Device_specific)
1735 var productSpecific = Bool(m.commonProperties.Product_specific)
Justin Yund5f6c822019-06-25 16:47:17 +09001736 var systemExtSpecific = Bool(m.commonProperties.System_ext_specific)
Jiyong Park2db76922017-11-08 16:03:48 +09001737
Dario Frenifd05a742018-05-29 13:28:54 +01001738 msg := "conflicting value set here"
1739 if socSpecific && deviceSpecific {
1740 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
Colin Cross4157e882019-06-06 16:57:04 -07001741 if Bool(m.commonProperties.Vendor) {
Jiyong Park2db76922017-11-08 16:03:48 +09001742 ctx.PropertyErrorf("vendor", msg)
1743 }
Colin Cross4157e882019-06-06 16:57:04 -07001744 if Bool(m.commonProperties.Proprietary) {
Jiyong Park2db76922017-11-08 16:03:48 +09001745 ctx.PropertyErrorf("proprietary", msg)
1746 }
Colin Cross4157e882019-06-06 16:57:04 -07001747 if Bool(m.commonProperties.Soc_specific) {
Jiyong Park2db76922017-11-08 16:03:48 +09001748 ctx.PropertyErrorf("soc_specific", msg)
1749 }
1750 }
1751
Justin Yund5f6c822019-06-25 16:47:17 +09001752 if productSpecific && systemExtSpecific {
1753 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and system_ext at the same time.")
1754 ctx.PropertyErrorf("system_ext_specific", msg)
Dario Frenifd05a742018-05-29 13:28:54 +01001755 }
1756
Justin Yund5f6c822019-06-25 16:47:17 +09001757 if (socSpecific || deviceSpecific) && (productSpecific || systemExtSpecific) {
Dario Frenifd05a742018-05-29 13:28:54 +01001758 if productSpecific {
1759 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
1760 } else {
Justin Yund5f6c822019-06-25 16:47:17 +09001761 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 +01001762 }
1763 if deviceSpecific {
1764 ctx.PropertyErrorf("device_specific", msg)
1765 } else {
Colin Cross4157e882019-06-06 16:57:04 -07001766 if Bool(m.commonProperties.Vendor) {
Dario Frenifd05a742018-05-29 13:28:54 +01001767 ctx.PropertyErrorf("vendor", msg)
1768 }
Colin Cross4157e882019-06-06 16:57:04 -07001769 if Bool(m.commonProperties.Proprietary) {
Dario Frenifd05a742018-05-29 13:28:54 +01001770 ctx.PropertyErrorf("proprietary", msg)
1771 }
Colin Cross4157e882019-06-06 16:57:04 -07001772 if Bool(m.commonProperties.Soc_specific) {
Dario Frenifd05a742018-05-29 13:28:54 +01001773 ctx.PropertyErrorf("soc_specific", msg)
1774 }
1775 }
1776 }
1777
Jiyong Park2db76922017-11-08 16:03:48 +09001778 if productSpecific {
1779 return productSpecificModule
Justin Yund5f6c822019-06-25 16:47:17 +09001780 } else if systemExtSpecific {
1781 return systemExtSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +09001782 } else if deviceSpecific {
1783 return deviceSpecificModule
1784 } else if socSpecific {
1785 return socSpecificModule
1786 } else {
1787 return platformModule
1788 }
1789}
1790
Colin Crossc34d2322020-01-03 15:23:27 -08001791func (m *ModuleBase) earlyModuleContextFactory(ctx blueprint.EarlyModuleContext) earlyModuleContext {
Colin Cross1184b642019-12-30 18:43:07 -08001792 return earlyModuleContext{
Colin Crossc34d2322020-01-03 15:23:27 -08001793 EarlyModuleContext: ctx,
1794 kind: determineModuleKind(m, ctx),
1795 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -08001796 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001797}
1798
Colin Cross1184b642019-12-30 18:43:07 -08001799func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext {
1800 return baseModuleContext{
1801 bp: ctx,
Colin Cross1d3d9f12024-01-18 14:30:22 -08001802 archModuleContext: m.archModuleContextFactory(ctx),
Colin Cross1184b642019-12-30 18:43:07 -08001803 earlyModuleContext: m.earlyModuleContextFactory(ctx),
Colin Cross1184b642019-12-30 18:43:07 -08001804 }
1805}
1806
Colin Crosse1a85552024-06-14 12:17:37 -07001807type archModuleContextFactoryContext interface {
1808 Config() interface{}
1809}
1810
1811func (m *ModuleBase) archModuleContextFactory(ctx archModuleContextFactoryContext) archModuleContext {
Colin Cross1d3d9f12024-01-18 14:30:22 -08001812 config := ctx.Config().(Config)
1813 target := m.Target()
1814 primaryArch := false
1815 if len(config.Targets[target.Os]) <= 1 {
1816 primaryArch = true
1817 } else {
1818 primaryArch = target.Arch.ArchType == config.Targets[target.Os][0].Arch.ArchType
1819 }
1820
1821 return archModuleContext{
Cole Faust0aa21cc2024-03-20 12:28:03 -07001822 ready: m.commonProperties.ArchReady,
Colin Cross1d3d9f12024-01-18 14:30:22 -08001823 os: m.commonProperties.CompileOS,
1824 target: m.commonProperties.CompileTarget,
1825 targetPrimary: m.commonProperties.CompilePrimary,
1826 multiTargets: m.commonProperties.CompileMultiTargets,
1827 primaryArch: primaryArch,
1828 }
1829
1830}
1831
Yu Liuddc28332024-08-09 22:48:30 +00001832type InstallFilesInfo struct {
Colin Crossa6182ab2024-08-21 10:47:44 -07001833 InstallFiles InstallPaths
1834 CheckbuildFiles Paths
1835 CheckbuildTarget Path
1836 UncheckedModule bool
1837 PackagingSpecs []PackagingSpec
Yu Liud46e5ae2024-08-15 18:46:17 +00001838 // katiInstalls tracks the install rules that were created by Soong but are being exported
1839 // to Make to convert to ninja rules so that Make can add additional dependencies.
Yu Liuec810542024-08-26 18:09:15 +00001840 KatiInstalls katiInstalls
1841 KatiSymlinks katiInstalls
1842 TestData []DataPath
Colin Crossa14fb6a2024-10-23 16:57:06 -07001843 TransitivePackagingSpecs depset.DepSet[PackagingSpec]
Yu Liuec810542024-08-26 18:09:15 +00001844 LicenseMetadataFile WritablePath
1845
1846 // The following fields are private before, make it private again once we have
1847 // better solution.
Colin Crossa14fb6a2024-10-23 16:57:06 -07001848 TransitiveInstallFiles depset.DepSet[InstallPath]
Yu Liu82a6d142024-08-27 19:02:29 +00001849 // katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
1850 // allowed to have duplicates across modules and variants.
1851 KatiInitRcInstalls katiInstalls
1852 KatiVintfInstalls katiInstalls
1853 InitRcPaths Paths
1854 VintfFragmentsPaths Paths
1855 InstalledInitRcPaths InstallPaths
1856 InstalledVintfFragmentsPaths InstallPaths
1857
Yu Liuec810542024-08-26 18:09:15 +00001858 // The files to copy to the dist as explicitly specified in the .bp file.
1859 DistFiles TaggedDistFiles
Yu Liuddc28332024-08-09 22:48:30 +00001860}
1861
Yu Liubad1eef2024-08-21 22:37:35 +00001862var InstallFilesProvider = blueprint.NewProvider[InstallFilesInfo]()
Yu Liuddc2e1a2024-08-20 21:31:22 +00001863
Yu Liud3228ac2024-11-08 23:11:47 +00001864type SourceFilesInfo struct {
1865 Srcs Paths
1866}
1867
Yu Liuc41eae52025-01-14 01:03:08 +00001868var SourceFilesInfoProvider = blueprint.NewProvider[SourceFilesInfo]()
Yu Liud3228ac2024-11-08 23:11:47 +00001869
Cole Faust0523b8f2025-03-03 15:11:32 -08001870// ModuleBuildTargetsInfo is used by buildTargetSingleton to create checkbuild and
1871// per-directory build targets.
1872type ModuleBuildTargetsInfo struct {
Yu Liuddc2e1a2024-08-20 21:31:22 +00001873 InstallTarget WritablePath
1874 CheckbuildTarget WritablePath
1875 BlueprintDir string
1876}
1877
Cole Faust0523b8f2025-03-03 15:11:32 -08001878var ModuleBuildTargetsProvider = blueprint.NewProvider[ModuleBuildTargetsInfo]()
Yu Liuddc28332024-08-09 22:48:30 +00001879
Yu Liub5275322024-11-13 18:40:43 +00001880type CommonModuleInfo struct {
Yu Liudd9ccb42024-10-07 17:07:44 +00001881 Enabled bool
1882 // Whether the module has been replaced by a prebuilt
1883 ReplacedByPrebuilt bool
Yu Liuec7043d2024-11-05 18:22:20 +00001884 // The Target of artifacts that this module variant is responsible for creating.
Yu Liu8024b922024-12-20 23:31:32 +00001885 Target Target
Yu Liub5275322024-11-13 18:40:43 +00001886 SkipAndroidMkProcessing bool
Yu Liu63bdf632024-12-03 19:54:05 +00001887 BaseModuleName string
Yu Liub1bfa9d2024-12-05 18:57:51 +00001888 CanHaveApexVariants bool
Yu Liu5d3a2cf2025-02-06 00:25:22 +00001889 MinSdkVersion ApiLevelOrPlatform
Yu Liuf6f85492025-01-13 21:02:36 +00001890 SdkVersion string
Yu Liu8f2c5c02024-12-06 00:40:39 +00001891 NotAvailableForPlatform bool
Yu Liu8024b922024-12-20 23:31:32 +00001892 // There some subtle differences between this one and the one above.
1893 NotInPlatform bool
Yu Liu5697f8f2024-12-13 23:31:08 +00001894 // UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex
1895 // mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant
1896 // is used to avoid adding install or packaging dependencies into libraries provided
1897 // by apexes.
1898 UninstallableApexPlatformVariant bool
Yu Liudf0b8392025-02-12 18:27:03 +00001899 MinSdkVersionSupported ApiLevel
1900 ModuleWithMinSdkVersionCheck bool
Yu Liu0a37d422025-02-13 02:05:00 +00001901 // Tests if this module can be installed to APEX as a file. For example, this would return
1902 // true for shared libs while return false for static libs because static libs are not
1903 // installable module (but it can still be mutated for APEX)
1904 IsInstallableToApex bool
1905 HideFromMake bool
1906 SkipInstall bool
1907 IsStubsModule bool
1908 Host bool
1909 IsApexModule bool
Yu Liu367827f2025-02-15 00:18:33 +00001910 // The primary licenses property, may be nil, records license metadata for the module.
1911 PrimaryLicensesProperty applicableLicensesProperty
1912 Owner string
Yu Liu64371e02025-02-19 23:44:48 +00001913 Vendor bool
1914 Proprietary bool
1915 SocSpecific bool
1916 ProductSpecific bool
1917 SystemExtSpecific bool
1918 DeviceSpecific bool
1919 // When set to true, this module is not installed to the full install path (ex: under
1920 // out/target/product/<name>/<partition>). It can be installed only to the packaging
1921 // modules like android_filesystem.
1922 NoFullInstall bool
1923 InVendorRamdisk bool
1924 ExemptFromRequiredApplicableLicensesProperty bool
1925 RequiredModuleNames []string
1926 HostRequiredModuleNames []string
1927 TargetRequiredModuleNames []string
1928 VintfFragmentModuleNames []string
1929 Dists []Dist
Yu Liu2a815b62025-02-21 20:46:25 +00001930 ExportedToMake bool
Yu Liu95cef3a2025-02-25 00:54:20 +00001931 Team string
Spandan Das31769ef2025-03-06 00:49:57 +00001932 PartitionTag string
Yu Liudd9ccb42024-10-07 17:07:44 +00001933}
1934
Yu Liu5d3a2cf2025-02-06 00:25:22 +00001935type ApiLevelOrPlatform struct {
1936 ApiLevel *ApiLevel
1937 IsPlatform bool
1938}
1939
Yu Liuf22120f2025-03-13 18:36:35 +00001940var CommonModuleInfoProvider = blueprint.NewProvider[*CommonModuleInfo]()
Yu Liudd9ccb42024-10-07 17:07:44 +00001941
Yu Liu8a8d5b42025-01-07 00:48:08 +00001942type PrebuiltModuleInfo struct {
1943 SourceExists bool
Yu Liu2da9d9a2025-01-15 00:27:02 +00001944 UsePrebuilt bool
Yu Liudd9ccb42024-10-07 17:07:44 +00001945}
1946
Yu Liu8a8d5b42025-01-07 00:48:08 +00001947var PrebuiltModuleInfoProvider = blueprint.NewProvider[PrebuiltModuleInfo]()
Yu Liudd9ccb42024-10-07 17:07:44 +00001948
Yu Liu2da9d9a2025-01-15 00:27:02 +00001949type HostToolProviderInfo struct {
Yu Liudd9ccb42024-10-07 17:07:44 +00001950 HostToolPath OptionalPath
1951}
1952
Yu Liu2da9d9a2025-01-15 00:27:02 +00001953var HostToolProviderInfoProvider = blueprint.NewProvider[HostToolProviderInfo]()
Yu Liudd9ccb42024-10-07 17:07:44 +00001954
Cole Faustd62a4892025-02-07 16:55:11 -08001955type DistInfo struct {
1956 Dists []dist
1957}
1958
1959var DistProvider = blueprint.NewProvider[DistInfo]()
1960
Yu Liu8024b922024-12-20 23:31:32 +00001961type SourceFileGenerator interface {
1962 GeneratedSourceFiles() Paths
1963 GeneratedHeaderDirs() Paths
1964 GeneratedDeps() Paths
1965}
1966
1967type GeneratedSourceInfo struct {
1968 GeneratedSourceFiles Paths
1969 GeneratedHeaderDirs Paths
1970 GeneratedDeps Paths
1971}
1972
1973var GeneratedSourceInfoProvider = blueprint.NewProvider[GeneratedSourceInfo]()
1974
Colin Cross4157e882019-06-06 16:57:04 -07001975func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
Colin Cross25de6c32019-06-06 14:29:25 -07001976 ctx := &moduleContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -07001977 module: m.module,
Colin Crossdc35e212019-06-06 16:13:11 -07001978 bp: blueprintCtx,
Colin Cross0ea8ba82019-06-06 14:33:29 -07001979 baseModuleContext: m.baseModuleContextFactory(blueprintCtx),
Colin Cross0ea8ba82019-06-06 14:33:29 -07001980 variables: make(map[string]string),
Yu Liu54513622024-08-19 20:00:32 +00001981 phonies: make(map[string]Paths),
Colin Cross3f40fa42015-01-30 17:27:36 -08001982 }
1983
Jihoon Kangc3d4e112024-06-24 22:16:27 +00001984 setContainerInfo(ctx)
Jihoon Kang85bc1932024-07-01 17:04:46 +00001985 if ctx.Config().Getenv("DISABLE_CONTAINER_CHECK") != "true" {
1986 checkContainerViolations(ctx)
1987 }
Jihoon Kangc3d4e112024-06-24 22:16:27 +00001988
Yu Liuec810542024-08-26 18:09:15 +00001989 ctx.licenseMetadataFile = PathForModuleOut(ctx, "meta_lic")
Colin Crossaa1cab02022-01-28 14:49:24 -08001990
Colin Crossffe6b9d2020-12-01 15:40:06 -08001991 dependencyInstallFiles, dependencyPackagingSpecs := m.computeInstallDeps(ctx)
Yu Liubad1eef2024-08-21 22:37:35 +00001992 // set the TransitiveInstallFiles to only the transitive dependencies to be used as the dependencies
Colin Cross5d583952020-11-24 16:21:24 -08001993 // of installed files of this module. It will be replaced by a depset including the installed
1994 // files of this module at the end for use by modules that depend on this one.
Colin Crossa14fb6a2024-10-23 16:57:06 -07001995 ctx.TransitiveInstallFiles = depset.New[InstallPath](depset.TOPOLOGICAL, nil, dependencyInstallFiles)
Colin Cross5d583952020-11-24 16:21:24 -08001996
Colin Cross6c4f21f2019-06-06 15:41:36 -07001997 // Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never
1998 // reporting missing dependency errors in Blueprint when AllowMissingDependencies == true.
1999 // TODO: This will be removed once defaults modules handle missing dependency errors
2000 blueprintCtx.GetMissingDependencies()
2001
Colin Crossdc35e212019-06-06 16:13:11 -07002002 // For the final GenerateAndroidBuildActions pass, require that all visited dependencies Soong modules and
Paul Duffin1356d8c2020-02-25 19:26:33 +00002003 // are enabled. Unless the module is a CommonOS variant which may have dependencies on disabled variants
2004 // (because the dependencies are added before the modules are disabled). The
2005 // GetOsSpecificVariantsOfCommonOSVariant(...) method will ensure that the disabled variants are
2006 // ignored.
2007 ctx.baseModuleContext.strictVisitDeps = !m.IsCommonOSVariant()
Colin Crossdc35e212019-06-06 16:13:11 -07002008
Colin Cross4c83e5c2019-02-25 14:54:28 -08002009 if ctx.config.captureBuild {
2010 ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
2011 }
2012
Colin Cross67a5c132017-05-09 13:45:28 -07002013 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
2014 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -08002015 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
2016 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -07002017 }
Colin Cross0875c522017-11-28 17:34:01 -08002018 if !ctx.PrimaryArch() {
2019 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -07002020 }
Colin Crossff694a82023-12-13 15:54:49 -08002021 if apexInfo, _ := ModuleProvider(ctx, ApexInfoProvider); !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -07002022 suffix = append(suffix, apexInfo.ApexVariationName)
Dan Willemsenb13a9482020-02-14 11:25:54 -08002023 }
Colin Cross67a5c132017-05-09 13:45:28 -07002024
2025 ctx.Variable(pctx, "moduleDesc", desc)
2026
2027 s := ""
2028 if len(suffix) > 0 {
2029 s = " [" + strings.Join(suffix, " ") + "]"
2030 }
2031 ctx.Variable(pctx, "moduleDescSuffix", s)
2032
Dan Willemsen569edc52018-11-19 09:33:29 -08002033 // Some common property checks for properties that will be used later in androidmk.go
Paul Duffin89968e32020-11-23 18:17:03 +00002034 checkDistProperties(ctx, "dist", &m.distProperties.Dist)
Sasha Smundake198eaf2022-08-04 13:07:02 -07002035 for i := range m.distProperties.Dists {
Paul Duffin89968e32020-11-23 18:17:03 +00002036 checkDistProperties(ctx, fmt.Sprintf("dists[%d]", i), &m.distProperties.Dists[i])
Dan Willemsen569edc52018-11-19 09:33:29 -08002037 }
2038
Yu Liubad1eef2024-08-21 22:37:35 +00002039 var installFiles InstallFilesInfo
2040
Cole Fausta963b942024-04-11 17:43:00 -07002041 if m.Enabled(ctx) {
Jooyung Hand48f3c32019-08-23 11:18:57 +09002042 // ensure all direct android.Module deps are enabled
Yu Liu4552aeb2024-11-13 00:59:49 +00002043 ctx.VisitDirectDepsProxy(func(m ModuleProxy) {})
Jooyung Hand48f3c32019-08-23 11:18:57 +09002044
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002045 if m.Device() {
2046 // Handle any init.rc and vintf fragment files requested by the module. All files installed by this
2047 // module will automatically have a dependency on the installed init.rc or vintf fragment file.
2048 // The same init.rc or vintf fragment file may be requested by multiple modules or variants,
2049 // so instead of installing them now just compute the install path and store it for later.
2050 // The full list of all init.rc and vintf fragment install rules will be deduplicated later
2051 // so only a single rule is created for each init.rc or vintf fragment file.
2052
2053 if !m.InVendorRamdisk() {
Inseob Kim713b87d2024-09-13 11:29:54 +09002054 ctx.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc.GetOrDefault(ctx, nil))
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002055 rcDir := PathForModuleInstall(ctx, "etc", "init")
Yu Liu82a6d142024-08-27 19:02:29 +00002056 for _, src := range ctx.initRcPaths {
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002057 installedInitRc := rcDir.Join(ctx, src.Base())
Yu Liu82a6d142024-08-27 19:02:29 +00002058 ctx.katiInitRcInstalls = append(ctx.katiInitRcInstalls, katiInstall{
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002059 from: src,
2060 to: installedInitRc,
2061 })
2062 ctx.PackageFile(rcDir, src.Base(), src)
Yu Liu82a6d142024-08-27 19:02:29 +00002063 ctx.installedInitRcPaths = append(ctx.installedInitRcPaths, installedInitRc)
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002064 }
Yu Liu82a6d142024-08-27 19:02:29 +00002065 installFiles.InitRcPaths = ctx.initRcPaths
2066 installFiles.KatiInitRcInstalls = ctx.katiInitRcInstalls
2067 installFiles.InstalledInitRcPaths = ctx.installedInitRcPaths
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002068 }
2069
Yu Liu82a6d142024-08-27 19:02:29 +00002070 ctx.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments.GetOrDefault(ctx, nil))
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002071 vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest")
Yu Liu82a6d142024-08-27 19:02:29 +00002072 for _, src := range ctx.vintfFragmentsPaths {
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002073 installedVintfFragment := vintfDir.Join(ctx, src.Base())
Yu Liu82a6d142024-08-27 19:02:29 +00002074 ctx.katiVintfInstalls = append(ctx.katiVintfInstalls, katiInstall{
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002075 from: src,
2076 to: installedVintfFragment,
2077 })
2078 ctx.PackageFile(vintfDir, src.Base(), src)
Yu Liu82a6d142024-08-27 19:02:29 +00002079 ctx.installedVintfFragmentsPaths = append(ctx.installedVintfFragmentsPaths, installedVintfFragment)
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002080 }
Yu Liu82a6d142024-08-27 19:02:29 +00002081 installFiles.VintfFragmentsPaths = ctx.vintfFragmentsPaths
2082 installFiles.KatiVintfInstalls = ctx.katiVintfInstalls
2083 installFiles.InstalledVintfFragmentsPaths = ctx.installedVintfFragmentsPaths
Colin Crossd9bbf4b2023-11-17 16:23:48 -08002084 }
2085
Bob Badour37af0462021-01-07 03:34:31 +00002086 licensesPropertyFlattener(ctx)
2087 if ctx.Failed() {
2088 return
2089 }
2090
Joe Onorato349ae8d2024-02-05 22:46:00 +00002091 if jarJarPrefixHandler != nil {
2092 jarJarPrefixHandler(ctx)
2093 if ctx.Failed() {
2094 return
2095 }
2096 }
2097
Justin Yun40182b62024-05-07 10:22:19 +09002098 // Call aconfigUpdateAndroidBuildActions to collect merged aconfig files before being used
2099 // in m.module.GenerateAndroidBuildActions
2100 aconfigUpdateAndroidBuildActions(ctx)
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002101 if ctx.Failed() {
2102 return
2103 }
2104
Yu Liu26a716d2024-08-30 23:40:32 +00002105 m.module.GenerateAndroidBuildActions(ctx)
2106 if ctx.Failed() {
2107 return
Yu Liufa297642024-06-11 00:13:02 +00002108 }
2109
Yu Liu26a716d2024-08-30 23:40:32 +00002110 if x, ok := m.module.(IDEInfo); ok {
2111 var result IdeInfo
2112 x.IDEInfo(ctx, &result)
2113 result.BaseModuleName = x.BaseModuleName()
2114 SetProvider(ctx, IdeInfoProviderKey, result)
LaMont Jonesb5099382024-01-10 23:42:36 +00002115 }
2116
Paul Duffinaf970a22020-11-23 23:32:56 +00002117 // Create the set of tagged dist files after calling GenerateAndroidBuildActions
2118 // as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
2119 // output paths being set which must be done before or during
2120 // GenerateAndroidBuildActions.
Yu Liuec810542024-08-26 18:09:15 +00002121 installFiles.DistFiles = m.GenerateTaggedDistFiles(ctx)
Paul Duffinaf970a22020-11-23 23:32:56 +00002122 if ctx.Failed() {
2123 return
2124 }
2125
Colin Crossa6182ab2024-08-21 10:47:44 -07002126 m.generateVariantTarget(ctx)
2127
Yu Liuec810542024-08-26 18:09:15 +00002128 installFiles.LicenseMetadataFile = ctx.licenseMetadataFile
Yu Liubad1eef2024-08-21 22:37:35 +00002129 installFiles.InstallFiles = ctx.installFiles
2130 installFiles.CheckbuildFiles = ctx.checkbuildFiles
Colin Crossa6182ab2024-08-21 10:47:44 -07002131 installFiles.CheckbuildTarget = ctx.checkbuildTarget
2132 installFiles.UncheckedModule = ctx.uncheckedModule
Yu Liubad1eef2024-08-21 22:37:35 +00002133 installFiles.PackagingSpecs = ctx.packagingSpecs
2134 installFiles.KatiInstalls = ctx.katiInstalls
2135 installFiles.KatiSymlinks = ctx.katiSymlinks
2136 installFiles.TestData = ctx.testData
Colin Crossdc35e212019-06-06 16:13:11 -07002137 } else if ctx.Config().AllowMissingDependencies() {
2138 // If the module is not enabled it will not create any build rules, nothing will call
2139 // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
2140 // and report them as an error even when AllowMissingDependencies = true. Call
2141 // ctx.GetMissingDependencies() here to tell blueprint not to handle them.
2142 ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08002143 }
2144
Yu Liud3228ac2024-11-08 23:11:47 +00002145 if sourceFileProducer, ok := m.module.(SourceFileProducer); ok {
Cole Faust0523b8f2025-03-03 15:11:32 -08002146 srcs := sourceFileProducer.Srcs()
2147 for _, src := range srcs {
2148 if src == nil {
2149 ctx.ModuleErrorf("SourceFileProducer cannot return nil srcs")
2150 return
2151 }
2152 }
Yu Liuc41eae52025-01-14 01:03:08 +00002153 SetProvider(ctx, SourceFilesInfoProvider, SourceFilesInfo{Srcs: sourceFileProducer.Srcs()})
Yu Liud3228ac2024-11-08 23:11:47 +00002154 }
2155
Cole Faust0523b8f2025-03-03 15:11:32 -08002156 m.generateModuleTarget(ctx)
2157 if ctx.Failed() {
2158 return
Colin Cross3f40fa42015-01-30 17:27:36 -08002159 }
Colin Crosscec81712017-07-13 14:43:27 -07002160
Colin Crossa14fb6a2024-10-23 16:57:06 -07002161 ctx.TransitiveInstallFiles = depset.New[InstallPath](depset.TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles)
Yu Liubad1eef2024-08-21 22:37:35 +00002162 installFiles.TransitiveInstallFiles = ctx.TransitiveInstallFiles
Colin Crossa14fb6a2024-10-23 16:57:06 -07002163 installFiles.TransitivePackagingSpecs = depset.New[PackagingSpec](depset.TOPOLOGICAL, ctx.packagingSpecs, dependencyPackagingSpecs)
Colin Cross5d583952020-11-24 16:21:24 -08002164
Yu Liubad1eef2024-08-21 22:37:35 +00002165 SetProvider(ctx, InstallFilesProvider, installFiles)
Yu Liuec810542024-08-26 18:09:15 +00002166 buildLicenseMetadata(ctx, ctx.licenseMetadataFile)
Colin Cross4acaea92021-12-10 23:05:02 +00002167
Jihoon Kangd4063812025-01-24 00:25:30 +00002168 if len(ctx.moduleInfoJSON) > 0 {
2169 for _, moduleInfoJSON := range ctx.moduleInfoJSON {
2170 if moduleInfoJSON.Disabled {
2171 continue
2172 }
2173 var installed InstallPaths
2174 installed = append(installed, ctx.katiInstalls.InstallPaths()...)
2175 installed = append(installed, ctx.katiSymlinks.InstallPaths()...)
2176 installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...)
2177 installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...)
2178 installedStrings := installed.Strings()
Colin Crossd6fd0132023-11-06 13:54:06 -08002179
Jihoon Kangd4063812025-01-24 00:25:30 +00002180 var targetRequired, hostRequired []string
2181 if ctx.Host() {
2182 targetRequired = m.baseProperties.Target_required
2183 } else {
2184 hostRequired = m.baseProperties.Host_required
2185 }
Cole Faust156085b2025-03-04 11:34:55 -08002186 hostRequired = append(hostRequired, moduleInfoJSON.ExtraHostRequired...)
Colin Crossd6fd0132023-11-06 13:54:06 -08002187
Jihoon Kangd4063812025-01-24 00:25:30 +00002188 var data []string
2189 for _, d := range ctx.testData {
2190 data = append(data, d.ToRelativeInstallPath())
2191 }
Colin Crossd6fd0132023-11-06 13:54:06 -08002192
Jihoon Kangd4063812025-01-24 00:25:30 +00002193 if moduleInfoJSON.Uninstallable {
2194 installedStrings = nil
2195 if len(moduleInfoJSON.CompatibilitySuites) == 1 && moduleInfoJSON.CompatibilitySuites[0] == "null-suite" {
2196 moduleInfoJSON.CompatibilitySuites = nil
2197 moduleInfoJSON.TestConfig = nil
2198 moduleInfoJSON.AutoTestConfig = nil
2199 data = nil
2200 }
2201 }
2202
2203 // M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}.
2204 // To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite,
2205 // we add the full test suite to our list. This was inherited from
2206 // AndroidMkEntries.AddCompatibilityTestSuites.
2207 suites := moduleInfoJSON.CompatibilitySuites
2208 if PrefixInList(suites, "mts-") && !InList("mts", suites) {
2209 suites = append(suites, "mts")
2210 }
2211 if PrefixInList(suites, "mcts-") && !InList("mcts", suites) {
2212 suites = append(suites, "mcts")
2213 }
2214 moduleInfoJSON.CompatibilitySuites = suites
2215
2216 required := append(m.RequiredModuleNames(ctx), m.VintfFragmentModuleNames(ctx)...)
2217 required = append(required, moduleInfoJSON.ExtraRequired...)
2218
2219 registerName := moduleInfoJSON.RegisterNameOverride
2220 if len(registerName) == 0 {
2221 registerName = m.moduleInfoRegisterName(ctx, moduleInfoJSON.SubName)
2222 }
2223
2224 moduleName := moduleInfoJSON.ModuleNameOverride
2225 if len(moduleName) == 0 {
2226 moduleName = m.BaseModuleName() + moduleInfoJSON.SubName
2227 }
2228
2229 supportedVariants := moduleInfoJSON.SupportedVariantsOverride
2230 if moduleInfoJSON.SupportedVariantsOverride == nil {
2231 supportedVariants = []string{m.moduleInfoVariant(ctx)}
2232 }
2233
2234 moduleInfoJSON.core = CoreModuleInfoJSON{
2235 RegisterName: registerName,
2236 Path: []string{ctx.ModuleDir()},
2237 Installed: installedStrings,
2238 ModuleName: moduleName,
2239 SupportedVariants: supportedVariants,
2240 TargetDependencies: targetRequired,
2241 HostDependencies: hostRequired,
2242 Data: data,
2243 Required: required,
Colin Crossd6fd0132023-11-06 13:54:06 -08002244 }
2245 }
2246
Yu Liu4297ad92024-08-27 19:50:13 +00002247 SetProvider(ctx, ModuleInfoJSONProvider, ctx.moduleInfoJSON)
Colin Crossd6fd0132023-11-06 13:54:06 -08002248 }
2249
Colin Cross4157e882019-06-06 16:57:04 -07002250 m.buildParams = ctx.buildParams
2251 m.ruleParams = ctx.ruleParams
2252 m.variables = ctx.variables
mrziwange6c85812024-05-22 14:36:09 -07002253
Yu Liu876b7ce2024-08-21 18:20:13 +00002254 outputFiles := ctx.GetOutputFiles()
2255 if outputFiles.DefaultOutputFiles != nil || outputFiles.TaggedOutputFiles != nil {
2256 SetProvider(ctx, OutputFilesProvider, outputFiles)
mrziwange6c85812024-05-22 14:36:09 -07002257 }
Wei Lia1aa2972024-06-21 13:08:51 -07002258
Yu Liu54513622024-08-19 20:00:32 +00002259 if len(ctx.phonies) > 0 {
2260 SetProvider(ctx, ModulePhonyProvider, ModulePhonyInfo{
2261 Phonies: ctx.phonies,
2262 })
2263 }
Cole Faustd62a4892025-02-07 16:55:11 -08002264
2265 if len(ctx.dists) > 0 {
2266 SetProvider(ctx, DistProvider, DistInfo{
2267 Dists: ctx.dists,
2268 })
2269 }
2270
Wei Lia1aa2972024-06-21 13:08:51 -07002271 buildComplianceMetadataProvider(ctx, m)
Yu Liudd9ccb42024-10-07 17:07:44 +00002272
Yu Liub5275322024-11-13 18:40:43 +00002273 commonData := CommonModuleInfo{
Yu Liu367827f2025-02-15 00:18:33 +00002274 Enabled: m.Enabled(ctx),
Yu Liu5697f8f2024-12-13 23:31:08 +00002275 ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt,
Yu Liu8024b922024-12-20 23:31:32 +00002276 Target: m.commonProperties.CompileTarget,
Yu Liu5697f8f2024-12-13 23:31:08 +00002277 SkipAndroidMkProcessing: shouldSkipAndroidMkProcessing(ctx, m),
Yu Liu5697f8f2024-12-13 23:31:08 +00002278 UninstallableApexPlatformVariant: m.commonProperties.UninstallableApexPlatformVariant,
2279 HideFromMake: m.commonProperties.HideFromMake,
2280 SkipInstall: m.commonProperties.SkipInstall,
Yu Liu68a70b72025-01-08 22:54:44 +00002281 Host: m.Host(),
Yu Liu367827f2025-02-15 00:18:33 +00002282 PrimaryLicensesProperty: m.primaryLicensesProperty,
Yu Liu64371e02025-02-19 23:44:48 +00002283 Owner: m.module.Owner(),
2284 SocSpecific: Bool(m.commonProperties.Soc_specific),
2285 Vendor: Bool(m.commonProperties.Vendor),
2286 Proprietary: Bool(m.commonProperties.Proprietary),
2287 ProductSpecific: Bool(m.commonProperties.Product_specific),
2288 SystemExtSpecific: Bool(m.commonProperties.System_ext_specific),
2289 DeviceSpecific: Bool(m.commonProperties.Device_specific),
2290 NoFullInstall: proptools.Bool(m.commonProperties.No_full_install),
2291 InVendorRamdisk: m.InVendorRamdisk(),
2292 ExemptFromRequiredApplicableLicensesProperty: exemptFromRequiredApplicableLicensesProperty(m.module),
2293 RequiredModuleNames: m.module.RequiredModuleNames(ctx),
2294 HostRequiredModuleNames: m.module.HostRequiredModuleNames(),
2295 TargetRequiredModuleNames: m.module.TargetRequiredModuleNames(),
2296 VintfFragmentModuleNames: m.module.VintfFragmentModuleNames(ctx),
2297 Dists: m.Dists(),
Yu Liu2a815b62025-02-21 20:46:25 +00002298 ExportedToMake: m.ExportedToMake(),
Yu Liu95cef3a2025-02-25 00:54:20 +00002299 Team: m.Team(),
Spandan Das31769ef2025-03-06 00:49:57 +00002300 PartitionTag: m.PartitionTag(ctx.DeviceConfig()),
Yu Liudd9ccb42024-10-07 17:07:44 +00002301 }
Yu Liu8f2c5c02024-12-06 00:40:39 +00002302 if mm, ok := m.module.(interface {
2303 MinSdkVersion(ctx EarlyModuleContext) ApiLevel
2304 }); ok {
2305 ver := mm.MinSdkVersion(ctx)
Yu Liu5d3a2cf2025-02-06 00:25:22 +00002306 commonData.MinSdkVersion.ApiLevel = &ver
Yu Liu8f2c5c02024-12-06 00:40:39 +00002307 } else if mm, ok := m.module.(interface{ MinSdkVersion() string }); ok {
Yu Liu5d3a2cf2025-02-06 00:25:22 +00002308 ver := mm.MinSdkVersion()
2309 // Compile against the current platform
2310 if ver == "" {
2311 commonData.MinSdkVersion.IsPlatform = true
2312 } else {
2313 api := ApiLevelFrom(ctx, ver)
2314 commonData.MinSdkVersion.ApiLevel = &api
2315 }
Yu Liu8f2c5c02024-12-06 00:40:39 +00002316 }
2317
Yu Liuf6f85492025-01-13 21:02:36 +00002318 if mm, ok := m.module.(interface {
2319 SdkVersion(ctx EarlyModuleContext) ApiLevel
2320 }); ok {
2321 ver := mm.SdkVersion(ctx)
2322 if !ver.IsNone() {
2323 commonData.SdkVersion = ver.String()
2324 }
2325 } else if mm, ok := m.module.(interface{ SdkVersion() string }); ok {
2326 commonData.SdkVersion = mm.SdkVersion()
2327 }
2328
Yu Liu8f2c5c02024-12-06 00:40:39 +00002329 if am, ok := m.module.(ApexModule); ok {
2330 commonData.CanHaveApexVariants = am.CanHaveApexVariants()
2331 commonData.NotAvailableForPlatform = am.NotAvailableForPlatform()
Yu Liu8024b922024-12-20 23:31:32 +00002332 commonData.NotInPlatform = am.NotInPlatform()
Yu Liudf0b8392025-02-12 18:27:03 +00002333 commonData.MinSdkVersionSupported = am.MinSdkVersionSupported(ctx)
Yu Liu0a37d422025-02-13 02:05:00 +00002334 commonData.IsInstallableToApex = am.IsInstallableToApex()
2335 commonData.IsApexModule = true
Yu Liu8f2c5c02024-12-06 00:40:39 +00002336 }
Yu Liudf0b8392025-02-12 18:27:03 +00002337
2338 if _, ok := m.module.(ModuleWithMinSdkVersionCheck); ok {
2339 commonData.ModuleWithMinSdkVersionCheck = true
2340 }
2341
Yu Liu97880e12025-01-07 19:03:34 +00002342 if st, ok := m.module.(StubsAvailableModule); ok {
2343 commonData.IsStubsModule = st.IsStubsModule()
2344 }
Yu Liu0a37d422025-02-13 02:05:00 +00002345 if mm, ok := m.module.(interface{ BaseModuleName() string }); ok {
2346 commonData.BaseModuleName = mm.BaseModuleName()
2347 }
Yu Liuf22120f2025-03-13 18:36:35 +00002348 SetProvider(ctx, CommonModuleInfoProvider, &commonData)
Yu Liudd9ccb42024-10-07 17:07:44 +00002349 if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil {
Yu Liu8a8d5b42025-01-07 00:48:08 +00002350 SetProvider(ctx, PrebuiltModuleInfoProvider, PrebuiltModuleInfo{
2351 SourceExists: p.Prebuilt().SourceExists(),
Yu Liu2da9d9a2025-01-15 00:27:02 +00002352 UsePrebuilt: p.Prebuilt().UsePrebuilt(),
Yu Liu8a8d5b42025-01-07 00:48:08 +00002353 })
Yu Liudd9ccb42024-10-07 17:07:44 +00002354 }
2355 if h, ok := m.module.(HostToolProvider); ok {
Yu Liu2da9d9a2025-01-15 00:27:02 +00002356 SetProvider(ctx, HostToolProviderInfoProvider, HostToolProviderInfo{
Yu Liudd9ccb42024-10-07 17:07:44 +00002357 HostToolPath: h.HostToolPath()})
2358 }
Yu Liue70976d2024-10-15 20:45:35 +00002359
Yu Liub5275322024-11-13 18:40:43 +00002360 if p, ok := m.module.(AndroidMkProviderInfoProducer); ok && !commonData.SkipAndroidMkProcessing {
Yu Liue70976d2024-10-15 20:45:35 +00002361 SetProvider(ctx, AndroidMkInfoProvider, p.PrepareAndroidMKProviderInfo(ctx.Config()))
2362 }
Yu Liu8024b922024-12-20 23:31:32 +00002363
2364 if s, ok := m.module.(SourceFileGenerator); ok {
2365 SetProvider(ctx, GeneratedSourceInfoProvider, GeneratedSourceInfo{
2366 GeneratedSourceFiles: s.GeneratedSourceFiles(),
2367 GeneratedHeaderDirs: s.GeneratedHeaderDirs(),
2368 GeneratedDeps: s.GeneratedDeps(),
2369 })
2370 }
Yu Liu2a815b62025-02-21 20:46:25 +00002371
Yu Liu71f1ea32025-02-26 23:39:20 +00002372 if m.Enabled(ctx) {
2373 if v, ok := m.module.(ModuleMakeVarsProvider); ok {
2374 SetProvider(ctx, ModuleMakeVarsInfoProvider, v.MakeVars(ctx))
2375 }
2376
2377 if am, ok := m.module.(AndroidMkDataProvider); ok {
2378 SetProvider(ctx, AndroidMkDataInfoProvider, AndroidMkDataInfo{
2379 Class: am.AndroidMk().Class,
2380 })
2381 }
Yu Liu2a815b62025-02-21 20:46:25 +00002382 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002383}
2384
Joe Onorato349ae8d2024-02-05 22:46:00 +00002385func SetJarJarPrefixHandler(handler func(ModuleContext)) {
2386 if jarJarPrefixHandler != nil {
2387 panic("jarJarPrefixHandler already set")
2388 }
2389 jarJarPrefixHandler = handler
2390}
2391
Colin Crossd6fd0132023-11-06 13:54:06 -08002392func (m *ModuleBase) moduleInfoRegisterName(ctx ModuleContext, subName string) string {
2393 name := m.BaseModuleName()
2394
2395 prefix := ""
2396 if ctx.Host() {
2397 if ctx.Os() != ctx.Config().BuildOS {
2398 prefix = "host_cross_"
2399 }
2400 }
2401 suffix := ""
2402 arches := slices.Clone(ctx.Config().Targets[ctx.Os()])
2403 arches = slices.DeleteFunc(arches, func(target Target) bool {
2404 return target.NativeBridge != ctx.Target().NativeBridge
2405 })
Cole Faust866ab392025-01-23 12:56:20 -08002406 if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType && ctx.Arch().ArchType != Common {
Colin Crossd6fd0132023-11-06 13:54:06 -08002407 if ctx.Arch().ArchType.Multilib == "lib32" {
2408 suffix = "_32"
2409 } else {
2410 suffix = "_64"
2411 }
2412 }
2413 return prefix + name + subName + suffix
2414}
2415
2416func (m *ModuleBase) moduleInfoVariant(ctx ModuleContext) string {
2417 variant := "DEVICE"
2418 if ctx.Host() {
2419 if ctx.Os() != ctx.Config().BuildOS {
2420 variant = "HOST_CROSS"
2421 } else {
2422 variant = "HOST"
2423 }
2424 }
2425 return variant
2426}
2427
Paul Duffin89968e32020-11-23 18:17:03 +00002428// Check the supplied dist structure to make sure that it is valid.
2429//
2430// property - the base property, e.g. dist or dists[1], which is combined with the
2431// name of the nested property to produce the full property, e.g. dist.dest or
2432// dists[1].dir.
2433func checkDistProperties(ctx *moduleContext, property string, dist *Dist) {
2434 if dist.Dest != nil {
2435 _, err := validateSafePath(*dist.Dest)
2436 if err != nil {
2437 ctx.PropertyErrorf(property+".dest", "%s", err.Error())
2438 }
2439 }
2440 if dist.Dir != nil {
2441 _, err := validateSafePath(*dist.Dir)
2442 if err != nil {
2443 ctx.PropertyErrorf(property+".dir", "%s", err.Error())
2444 }
2445 }
2446 if dist.Suffix != nil {
2447 if strings.Contains(*dist.Suffix, "/") {
2448 ctx.PropertyErrorf(property+".suffix", "Suffix may not contain a '/' character.")
2449 }
2450 }
2451
2452}
2453
Colin Cross6301c3c2021-09-28 17:40:21 -07002454// katiInstall stores a request from Soong to Make to create an install rule.
2455type katiInstall struct {
2456 from Path
2457 to InstallPath
2458 implicitDeps Paths
2459 orderOnlyDeps Paths
2460 executable bool
Colin Cross50ed1f92021-11-12 17:41:02 -08002461 extraFiles *extraFilesZip
Yu Liu467d7c52024-09-18 21:54:44 +00002462 absFrom string
Colin Cross6301c3c2021-09-28 17:40:21 -07002463}
2464
Yu Liu467d7c52024-09-18 21:54:44 +00002465type katiInstallGob struct {
2466 From Path
2467 To InstallPath
2468 ImplicitDeps Paths
2469 OrderOnlyDeps Paths
2470 Executable bool
2471 ExtraFiles *extraFilesZip
2472 AbsFrom string
Yu Liu26a716d2024-08-30 23:40:32 +00002473}
2474
Yu Liu467d7c52024-09-18 21:54:44 +00002475func (k *katiInstall) ToGob() *katiInstallGob {
2476 return &katiInstallGob{
2477 From: k.from,
2478 To: k.to,
2479 ImplicitDeps: k.implicitDeps,
2480 OrderOnlyDeps: k.orderOnlyDeps,
2481 Executable: k.executable,
2482 ExtraFiles: k.extraFiles,
2483 AbsFrom: k.absFrom,
Yu Liu26a716d2024-08-30 23:40:32 +00002484 }
Yu Liu467d7c52024-09-18 21:54:44 +00002485}
Yu Liu26a716d2024-08-30 23:40:32 +00002486
Yu Liu467d7c52024-09-18 21:54:44 +00002487func (k *katiInstall) FromGob(data *katiInstallGob) {
2488 k.from = data.From
2489 k.to = data.To
2490 k.implicitDeps = data.ImplicitDeps
2491 k.orderOnlyDeps = data.OrderOnlyDeps
2492 k.executable = data.Executable
2493 k.extraFiles = data.ExtraFiles
2494 k.absFrom = data.AbsFrom
2495}
2496
2497func (k *katiInstall) GobEncode() ([]byte, error) {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002498 return gobtools.CustomGobEncode[katiInstallGob](k)
Yu Liu467d7c52024-09-18 21:54:44 +00002499}
2500
2501func (k *katiInstall) GobDecode(data []byte) error {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002502 return gobtools.CustomGobDecode[katiInstallGob](data, k)
Yu Liu26a716d2024-08-30 23:40:32 +00002503}
2504
Colin Cross50ed1f92021-11-12 17:41:02 -08002505type extraFilesZip struct {
2506 zip Path
2507 dir InstallPath
2508}
2509
Yu Liu467d7c52024-09-18 21:54:44 +00002510type extraFilesZipGob struct {
2511 Zip Path
2512 Dir InstallPath
Yu Liu26a716d2024-08-30 23:40:32 +00002513}
2514
Yu Liu467d7c52024-09-18 21:54:44 +00002515func (e *extraFilesZip) ToGob() *extraFilesZipGob {
2516 return &extraFilesZipGob{
2517 Zip: e.zip,
2518 Dir: e.dir,
Yu Liu26a716d2024-08-30 23:40:32 +00002519 }
Yu Liu467d7c52024-09-18 21:54:44 +00002520}
Yu Liu26a716d2024-08-30 23:40:32 +00002521
Yu Liu467d7c52024-09-18 21:54:44 +00002522func (e *extraFilesZip) FromGob(data *extraFilesZipGob) {
2523 e.zip = data.Zip
2524 e.dir = data.Dir
2525}
2526
2527func (e *extraFilesZip) GobEncode() ([]byte, error) {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002528 return gobtools.CustomGobEncode[extraFilesZipGob](e)
Yu Liu467d7c52024-09-18 21:54:44 +00002529}
2530
2531func (e *extraFilesZip) GobDecode(data []byte) error {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002532 return gobtools.CustomGobDecode[extraFilesZipGob](data, e)
Yu Liu26a716d2024-08-30 23:40:32 +00002533}
2534
Colin Cross6301c3c2021-09-28 17:40:21 -07002535type katiInstalls []katiInstall
2536
2537// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
2538// space separated list of from:to tuples.
2539func (installs katiInstalls) BuiltInstalled() string {
2540 sb := strings.Builder{}
2541 for i, install := range installs {
2542 if i != 0 {
2543 sb.WriteRune(' ')
2544 }
2545 sb.WriteString(install.from.String())
2546 sb.WriteRune(':')
2547 sb.WriteString(install.to.String())
2548 }
2549 return sb.String()
2550}
2551
2552// InstallPaths returns the install path of each entry.
2553func (installs katiInstalls) InstallPaths() InstallPaths {
2554 paths := make(InstallPaths, 0, len(installs))
2555 for _, install := range installs {
2556 paths = append(paths, install.to)
2557 }
2558 return paths
2559}
2560
Jiyong Park5baac542018-08-28 09:55:37 +09002561// Makes this module a platform module, i.e. not specific to soc, device,
Justin Yund5f6c822019-06-25 16:47:17 +09002562// product, or system_ext.
Colin Cross4157e882019-06-06 16:57:04 -07002563func (m *ModuleBase) MakeAsPlatform() {
2564 m.commonProperties.Vendor = boolPtr(false)
2565 m.commonProperties.Proprietary = boolPtr(false)
2566 m.commonProperties.Soc_specific = boolPtr(false)
2567 m.commonProperties.Product_specific = boolPtr(false)
Justin Yund5f6c822019-06-25 16:47:17 +09002568 m.commonProperties.System_ext_specific = boolPtr(false)
Jiyong Park5baac542018-08-28 09:55:37 +09002569}
2570
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09002571func (m *ModuleBase) MakeAsSystemExt() {
Jooyung Han91df2082019-11-20 01:49:42 +09002572 m.commonProperties.Vendor = boolPtr(false)
2573 m.commonProperties.Proprietary = boolPtr(false)
2574 m.commonProperties.Soc_specific = boolPtr(false)
2575 m.commonProperties.Product_specific = boolPtr(false)
2576 m.commonProperties.System_ext_specific = boolPtr(true)
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09002577}
2578
Jooyung Han344d5432019-08-23 11:17:39 +09002579// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true"
2580func (m *ModuleBase) IsNativeBridgeSupported() bool {
2581 return proptools.Bool(m.commonProperties.Native_bridge_supported)
2582}
2583
Jihoon Kang0d545b82024-10-11 00:21:57 +00002584func (m *ModuleBase) DecodeMultilib(ctx ConfigContext) (string, string) {
2585 return decodeMultilib(ctx, m)
2586}
2587
Spandan Dase1860e42024-10-24 22:29:50 +00002588func (m *ModuleBase) Overrides() []string {
2589 return m.commonProperties.Overrides
2590}
2591
Colin Cross8bbc3d52024-09-11 15:33:54 -07002592type ConfigContext interface {
2593 Config() Config
2594}
2595
Cole Fauste8a87832024-09-11 11:35:46 -07002596type ConfigurableEvaluatorContext interface {
Cole Faust55b56fe2024-08-23 12:06:11 -07002597 OtherModuleProviderContext
Cole Faust02987bd2024-03-21 17:58:43 -07002598 Config() Config
2599 OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{})
Cole Faustd7067092024-09-13 13:37:59 -07002600 HasMutatorFinished(mutatorName string) bool
Cole Faust02987bd2024-03-21 17:58:43 -07002601}
2602
2603type configurationEvalutor struct {
Cole Fauste8a87832024-09-11 11:35:46 -07002604 ctx ConfigurableEvaluatorContext
Cole Faust02987bd2024-03-21 17:58:43 -07002605 m Module
2606}
2607
Cole Fauste8a87832024-09-11 11:35:46 -07002608func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator {
Cole Faust02987bd2024-03-21 17:58:43 -07002609 return configurationEvalutor{
2610 ctx: ctx,
2611 m: m.module,
2612 }
2613}
2614
2615func (e configurationEvalutor) PropertyErrorf(property string, fmt string, args ...interface{}) {
Cole Fausta963b942024-04-11 17:43:00 -07002616 e.ctx.OtherModulePropertyErrorf(e.m, property, fmt, args...)
Cole Faust02987bd2024-03-21 17:58:43 -07002617}
2618
Cole Faustfdbf5d42024-04-10 15:01:23 -07002619func (e configurationEvalutor) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue {
Cole Faust02987bd2024-03-21 17:58:43 -07002620 ctx := e.ctx
2621 m := e.m
Cole Faustd7067092024-09-13 13:37:59 -07002622
2623 if !ctx.HasMutatorFinished("defaults") {
2624 ctx.OtherModulePropertyErrorf(m, property, "Cannot evaluate configurable property before the defaults mutator has run")
2625 return proptools.ConfigurableValueUndefined()
2626 }
2627
Cole Faust8afc5142024-04-26 16:30:19 -07002628 switch condition.FunctionName() {
Cole Fauste19f7412024-05-09 15:14:04 -07002629 case "release_flag":
Cole Faust8afc5142024-04-26 16:30:19 -07002630 if condition.NumArgs() != 1 {
Cole Fauste19f7412024-05-09 15:14:04 -07002631 ctx.OtherModulePropertyErrorf(m, property, "release_flag requires 1 argument, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002632 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002633 }
Cole Faust751a4a52024-05-21 16:51:59 -07002634 if ty, ok := ctx.Config().productVariables.BuildFlagTypes[condition.Arg(0)]; ok {
2635 v := ctx.Config().productVariables.BuildFlags[condition.Arg(0)]
2636 switch ty {
2637 case "unspecified", "obsolete":
2638 return proptools.ConfigurableValueUndefined()
2639 case "string":
2640 return proptools.ConfigurableValueString(v)
2641 case "bool":
2642 return proptools.ConfigurableValueBool(v == "true")
2643 default:
2644 panic("unhandled release flag type: " + ty)
2645 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002646 }
2647 return proptools.ConfigurableValueUndefined()
2648 case "product_variable":
Jiyong Parke3250752024-05-17 14:56:10 +09002649 if condition.NumArgs() != 1 {
2650 ctx.OtherModulePropertyErrorf(m, property, "product_variable requires 1 argument, found %d", condition.NumArgs())
2651 return proptools.ConfigurableValueUndefined()
2652 }
2653 variable := condition.Arg(0)
2654 switch variable {
Jihoon Kang82bea762024-09-30 18:50:54 +00002655 case "build_from_text_stub":
2656 return proptools.ConfigurableValueBool(ctx.Config().BuildFromTextStub())
Jiyong Parke3250752024-05-17 14:56:10 +09002657 case "debuggable":
2658 return proptools.ConfigurableValueBool(ctx.Config().Debuggable())
kellyhungf833fba2025-01-14 10:05:46 +00002659 case "eng":
2660 return proptools.ConfigurableValueBool(ctx.Config().Eng())
Kiyoung Kim881e4652024-07-08 11:02:23 +09002661 case "use_debug_art":
2662 // TODO(b/234351700): Remove once ART does not have separated debug APEX
2663 return proptools.ConfigurableValueBool(ctx.Config().UseDebugArt())
kellyhung1e613d22024-07-29 12:56:51 +00002664 case "selinux_ignore_neverallows":
2665 return proptools.ConfigurableValueBool(ctx.Config().SelinuxIgnoreNeverallows())
Spandan Dasdd604262025-03-14 18:27:33 +00002666 case "always_use_prebuilt_sdks":
2667 return proptools.ConfigurableValueBool(ctx.Config().AlwaysUsePrebuiltSdks())
Jiyong Parke3250752024-05-17 14:56:10 +09002668 default:
2669 // TODO(b/323382414): Might add these on a case-by-case basis
2670 ctx.OtherModulePropertyErrorf(m, property, fmt.Sprintf("TODO(b/323382414): Product variable %q is not yet supported in selects", variable))
2671 return proptools.ConfigurableValueUndefined()
2672 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002673 case "soong_config_variable":
Cole Faust8afc5142024-04-26 16:30:19 -07002674 if condition.NumArgs() != 2 {
2675 ctx.OtherModulePropertyErrorf(m, property, "soong_config_variable requires 2 arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002676 return proptools.ConfigurableValueUndefined()
2677 }
Cole Faust8afc5142024-04-26 16:30:19 -07002678 namespace := condition.Arg(0)
2679 variable := condition.Arg(1)
Cole Faust02987bd2024-03-21 17:58:43 -07002680 if n, ok := ctx.Config().productVariables.VendorVars[namespace]; ok {
2681 if v, ok := n[variable]; ok {
Cole Faust46f6e2f2024-06-20 12:57:43 -07002682 ty := ""
2683 if namespaces, ok := ctx.Config().productVariables.VendorVarTypes[namespace]; ok {
2684 ty = namespaces[variable]
2685 }
2686 switch ty {
2687 case "":
2688 // strings are the default, we don't bother writing them to the soong variables json file
2689 return proptools.ConfigurableValueString(v)
2690 case "bool":
2691 return proptools.ConfigurableValueBool(v == "true")
Cole Faust764aaca2025-03-18 11:24:39 -07002692 case "int":
2693 i, err := strconv.ParseInt(v, 10, 64)
2694 if err != nil {
2695 ctx.OtherModulePropertyErrorf(m, property, "integer soong_config_variable was not an int: %q", v)
2696 return proptools.ConfigurableValueUndefined()
2697 }
2698 return proptools.ConfigurableValueInt(i)
Cole Faust4143ee82024-11-21 11:20:06 -08002699 case "string_list":
2700 return proptools.ConfigurableValueStringList(strings.Split(v, " "))
Cole Faust46f6e2f2024-06-20 12:57:43 -07002701 default:
2702 panic("unhandled soong config variable type: " + ty)
2703 }
2704
Cole Faust02987bd2024-03-21 17:58:43 -07002705 }
2706 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002707 return proptools.ConfigurableValueUndefined()
Cole Faustfc57d402024-04-11 12:09:44 -07002708 case "arch":
Cole Faust8afc5142024-04-26 16:30:19 -07002709 if condition.NumArgs() != 0 {
2710 ctx.OtherModulePropertyErrorf(m, property, "arch requires no arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002711 return proptools.ConfigurableValueUndefined()
2712 }
Cole Faustfc57d402024-04-11 12:09:44 -07002713 if !m.base().ArchReady() {
2714 ctx.OtherModulePropertyErrorf(m, property, "A select on arch was attempted before the arch mutator ran")
2715 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002716 }
Cole Faustfc57d402024-04-11 12:09:44 -07002717 return proptools.ConfigurableValueString(m.base().Arch().ArchType.Name)
2718 case "os":
Cole Faust8afc5142024-04-26 16:30:19 -07002719 if condition.NumArgs() != 0 {
2720 ctx.OtherModulePropertyErrorf(m, property, "os requires no arguments, found %d", condition.NumArgs())
Cole Faustfc57d402024-04-11 12:09:44 -07002721 return proptools.ConfigurableValueUndefined()
2722 }
2723 // the arch mutator runs after the os mutator, we can just use this to enforce that os is ready.
2724 if !m.base().ArchReady() {
2725 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)")
2726 return proptools.ConfigurableValueUndefined()
2727 }
2728 return proptools.ConfigurableValueString(m.base().Os().Name)
Cole Faustfdbf5d42024-04-10 15:01:23 -07002729 case "boolean_var_for_testing":
2730 // We currently don't have any other boolean variables (we should add support for typing
2731 // the soong config variables), so add this fake one for testing the boolean select
2732 // functionality.
Cole Faust8afc5142024-04-26 16:30:19 -07002733 if condition.NumArgs() != 0 {
2734 ctx.OtherModulePropertyErrorf(m, property, "boolean_var_for_testing requires 0 arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002735 return proptools.ConfigurableValueUndefined()
2736 }
2737
2738 if n, ok := ctx.Config().productVariables.VendorVars["boolean_var"]; ok {
2739 if v, ok := n["for_testing"]; ok {
2740 switch v {
2741 case "true":
2742 return proptools.ConfigurableValueBool(true)
2743 case "false":
2744 return proptools.ConfigurableValueBool(false)
2745 default:
2746 ctx.OtherModulePropertyErrorf(m, property, "testing:my_boolean_var can only be true or false, found %q", v)
2747 }
2748 }
2749 }
2750 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002751 default:
Cole Faustfdbf5d42024-04-10 15:01:23 -07002752 ctx.OtherModulePropertyErrorf(m, property, "Unknown select condition %s", condition.FunctionName)
2753 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002754 }
2755}
2756
Colin Crossb63d7b32023-12-07 16:54:51 -08002757// ModuleNameWithPossibleOverride returns the name of the OverrideModule that overrides the current
2758// variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule
2759// or if this variant is not overridden.
2760func ModuleNameWithPossibleOverride(ctx BaseModuleContext) string {
2761 if overridable, ok := ctx.Module().(OverridableModule); ok {
2762 if o := overridable.GetOverriddenBy(); o != "" {
2763 return o
2764 }
2765 }
2766 return ctx.ModuleName()
2767}
2768
Paul Duffine6ba0722021-07-12 20:12:12 +01002769// SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name"
2770// into the module name, or empty string if the input was not a module reference.
Colin Cross41955e82019-05-29 14:40:35 -07002771func SrcIsModule(s string) (module string) {
Paul Duffine6ba0722021-07-12 20:12:12 +01002772 if len(s) > 1 {
2773 if s[0] == ':' {
2774 module = s[1:]
2775 if !isUnqualifiedModuleName(module) {
2776 // The module name should be unqualified but is not so do not treat it as a module.
2777 module = ""
2778 }
2779 } else if s[0] == '/' && s[1] == '/' {
2780 module = s
2781 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002782 }
Paul Duffine6ba0722021-07-12 20:12:12 +01002783 return module
Colin Cross068e0fe2016-12-13 15:23:47 -08002784}
2785
Yi-Yo Chiangba9ea322021-07-15 17:18:21 +08002786// SrcIsModuleWithTag decodes module references in the format ":unqualified-name{.tag}" or
2787// "//namespace:name{.tag}" into the module name and tag, ":unqualified-name" or "//namespace:name"
2788// into the module name and an empty string for the tag, or empty strings if the input was not a
2789// module reference.
Colin Cross41955e82019-05-29 14:40:35 -07002790func SrcIsModuleWithTag(s string) (module, tag string) {
Paul Duffine6ba0722021-07-12 20:12:12 +01002791 if len(s) > 1 {
2792 if s[0] == ':' {
2793 module = s[1:]
2794 } else if s[0] == '/' && s[1] == '/' {
2795 module = s
2796 }
2797
2798 if module != "" {
2799 if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
2800 if module[len(module)-1] == '}' {
2801 tag = module[tagStart+1 : len(module)-1]
2802 module = module[:tagStart]
2803 }
2804 }
2805
2806 if s[0] == ':' && !isUnqualifiedModuleName(module) {
2807 // The module name should be unqualified but is not so do not treat it as a module.
2808 module = ""
2809 tag = ""
Colin Cross41955e82019-05-29 14:40:35 -07002810 }
2811 }
Colin Cross41955e82019-05-29 14:40:35 -07002812 }
Paul Duffine6ba0722021-07-12 20:12:12 +01002813
2814 return module, tag
2815}
2816
2817// isUnqualifiedModuleName makes sure that the supplied module is an unqualified module name, i.e.
2818// does not contain any /.
2819func isUnqualifiedModuleName(module string) bool {
2820 return strings.IndexByte(module, '/') == -1
Colin Cross068e0fe2016-12-13 15:23:47 -08002821}
2822
Paul Duffin40131a32021-07-09 17:10:35 +01002823// sourceOrOutputDependencyTag is the dependency tag added automatically by pathDepsMutator for any
2824// module reference in a property annotated with `android:"path"` or passed to ExtractSourceDeps
2825// or ExtractSourcesDeps.
2826//
2827// If uniquely identifies the dependency that was added as it contains both the module name used to
2828// add the dependency as well as the tag. That makes it very simple to find the matching dependency
2829// in GetModuleFromPathDep as all it needs to do is find the dependency whose tag matches the tag
2830// used to add it. It does not need to check that the module name as returned by one of
2831// Module.Name(), BaseModuleContext.OtherModuleName() or ModuleBase.BaseModuleName() matches the
2832// name supplied in the tag. That means it does not need to handle differences in module names
2833// caused by prebuilt_ prefix, or fully qualified module names.
Colin Cross41955e82019-05-29 14:40:35 -07002834type sourceOrOutputDependencyTag struct {
2835 blueprint.BaseDependencyTag
Yu Liu67a28422024-03-05 00:36:31 +00002836 AlwaysPropagateAconfigValidationDependencyTag
Paul Duffin40131a32021-07-09 17:10:35 +01002837
2838 // The name of the module.
2839 moduleName string
2840
mrziwangd38e63d2024-07-15 13:43:37 -07002841 // The tag that will be used to get the specific output file(s).
Colin Cross41955e82019-05-29 14:40:35 -07002842 tag string
2843}
2844
Paul Duffin40131a32021-07-09 17:10:35 +01002845func sourceOrOutputDepTag(moduleName, tag string) blueprint.DependencyTag {
2846 return sourceOrOutputDependencyTag{moduleName: moduleName, tag: tag}
Colin Cross41955e82019-05-29 14:40:35 -07002847}
2848
Paul Duffind5cf92e2021-07-09 17:38:55 +01002849// IsSourceDepTagWithOutputTag returns true if the supplied blueprint.DependencyTag is one that was
2850// used to add dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for
2851// properties tagged with `android:"path"` AND it was added using a module reference of
2852// :moduleName{outputTag}.
2853func IsSourceDepTagWithOutputTag(depTag blueprint.DependencyTag, outputTag string) bool {
2854 t, ok := depTag.(sourceOrOutputDependencyTag)
2855 return ok && t.tag == outputTag
2856}
2857
Colin Cross366938f2017-12-11 16:29:02 -08002858// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
2859// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08002860//
2861// Deprecated: tag the property with `android:"path"` instead.
Colin Cross068e0fe2016-12-13 15:23:47 -08002862func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
Nan Zhang2439eb72017-04-10 11:27:50 -07002863 set := make(map[string]bool)
2864
Colin Cross068e0fe2016-12-13 15:23:47 -08002865 for _, s := range srcFiles {
Colin Cross41955e82019-05-29 14:40:35 -07002866 if m, t := SrcIsModuleWithTag(s); m != "" {
2867 if _, found := set[s]; found {
2868 ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
Nan Zhang2439eb72017-04-10 11:27:50 -07002869 } else {
Colin Cross41955e82019-05-29 14:40:35 -07002870 set[s] = true
Paul Duffin40131a32021-07-09 17:10:35 +01002871 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
Nan Zhang2439eb72017-04-10 11:27:50 -07002872 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002873 }
2874 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002875}
2876
Colin Cross366938f2017-12-11 16:29:02 -08002877// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
2878// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08002879//
2880// Deprecated: tag the property with `android:"path"` instead.
Colin Cross366938f2017-12-11 16:29:02 -08002881func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
2882 if s != nil {
Colin Cross41955e82019-05-29 14:40:35 -07002883 if m, t := SrcIsModuleWithTag(*s); m != "" {
Paul Duffin40131a32021-07-09 17:10:35 +01002884 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
Colin Cross366938f2017-12-11 16:29:02 -08002885 }
2886 }
2887}
2888
Colin Cross41955e82019-05-29 14:40:35 -07002889// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"`
2890// 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 -08002891type SourceFileProducer interface {
2892 Srcs() Paths
2893}
2894
mrziwangd38e63d2024-07-15 13:43:37 -07002895// OutputFilesForModule returns the output file paths with the given tag. On error, including if the
Colin Cross5e708052019-08-06 13:59:50 -07002896// module produced zero paths, it reports errors to the ctx and returns nil.
Yu Liud3228ac2024-11-08 23:11:47 +00002897func OutputFilesForModule(ctx PathContext, module Module, tag string) Paths {
Colin Cross5e708052019-08-06 13:59:50 -07002898 paths, err := outputFilesForModule(ctx, module, tag)
2899 if err != nil {
2900 reportPathError(ctx, err)
2901 return nil
2902 }
2903 return paths
2904}
2905
mrziwangd38e63d2024-07-15 13:43:37 -07002906// OutputFileForModule returns the output file paths with the given tag. On error, including if the
Colin Cross5e708052019-08-06 13:59:50 -07002907// module produced zero or multiple paths, it reports errors to the ctx and returns nil.
Yu Liu2a815b62025-02-21 20:46:25 +00002908// TODO(b/397766191): Change the signature to take ModuleProxy
2909// Please only access the module's internal data through providers.
Yu Liud3228ac2024-11-08 23:11:47 +00002910func OutputFileForModule(ctx PathContext, module Module, tag string) Path {
Colin Cross5e708052019-08-06 13:59:50 -07002911 paths, err := outputFilesForModule(ctx, module, tag)
2912 if err != nil {
2913 reportPathError(ctx, err)
2914 return nil
2915 }
Colin Cross14ec66c2022-10-03 21:02:27 -07002916 if len(paths) == 0 {
2917 type addMissingDependenciesIntf interface {
2918 AddMissingDependencies([]string)
2919 OtherModuleName(blueprint.Module) string
2920 }
2921 if mctx, ok := ctx.(addMissingDependenciesIntf); ok && ctx.Config().AllowMissingDependencies() {
2922 mctx.AddMissingDependencies([]string{mctx.OtherModuleName(module)})
2923 } else {
2924 ReportPathErrorf(ctx, "failed to get output files from module %q", pathContextName(ctx, module))
2925 }
2926 // Return a fake output file to avoid nil dereferences of Path objects later.
2927 // This should never get used for an actual build as the error or missing
2928 // dependency has already been reported.
2929 p, err := pathForSource(ctx, filepath.Join("missing_output_file", pathContextName(ctx, module)))
2930 if err != nil {
2931 reportPathError(ctx, err)
2932 return nil
2933 }
2934 return p
2935 }
Colin Cross5e708052019-08-06 13:59:50 -07002936 if len(paths) > 1 {
Ulya Trafimovich5ab276a2020-08-25 12:45:15 +01002937 ReportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
Colin Cross5e708052019-08-06 13:59:50 -07002938 pathContextName(ctx, module))
Colin Cross5e708052019-08-06 13:59:50 -07002939 }
2940 return paths[0]
2941}
2942
Yu Liud3228ac2024-11-08 23:11:47 +00002943type OutputFilesProviderModuleContext interface {
2944 OtherModuleProviderContext
2945 Module() Module
2946 GetOutputFiles() OutputFilesInfo
Yu Liud3228ac2024-11-08 23:11:47 +00002947}
2948
Yu Liu2a815b62025-02-21 20:46:25 +00002949// TODO(b/397766191): Change the signature to take ModuleProxy
2950// Please only access the module's internal data through providers.
Yu Liud3228ac2024-11-08 23:11:47 +00002951func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, error) {
mrziwange6c85812024-05-22 14:36:09 -07002952 outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag)
mrziwangabdb2932024-06-18 12:43:41 -07002953 if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet {
mrziwange6c85812024-05-22 14:36:09 -07002954 return outputFilesFromProvider, err
2955 }
Yu Liud3228ac2024-11-08 23:11:47 +00002956
2957 if octx, ok := ctx.(OutputFilesProviderModuleContext); ok {
Yu Liue472c1d2025-02-26 20:13:04 +00002958 if EqualModules(octx.Module(), module) {
Yu Liu5697f8f2024-12-13 23:31:08 +00002959 // It is the current module, we can access the srcs through interface
Yu Liud3228ac2024-11-08 23:11:47 +00002960 if sourceFileProducer, ok := module.(SourceFileProducer); ok {
2961 return sourceFileProducer.Srcs(), nil
2962 }
Yu Liuc41eae52025-01-14 01:03:08 +00002963 } else if sourceFiles, ok := OtherModuleProvider(octx, module, SourceFilesInfoProvider); ok {
Yu Liud3228ac2024-11-08 23:11:47 +00002964 if tag != "" {
2965 return nil, fmt.Errorf("module %q is a SourceFileProducer, which does not support tag %q", pathContextName(ctx, module), tag)
2966 }
2967 paths := sourceFiles.Srcs
2968 return paths, nil
Colin Cross74b1e2b2020-11-22 20:23:02 -08002969 }
Colin Cross5e708052019-08-06 13:59:50 -07002970 }
Yu Liud3228ac2024-11-08 23:11:47 +00002971
2972 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 -07002973}
2974
mrziwange6c85812024-05-22 14:36:09 -07002975// This method uses OutputFilesProvider for output files
2976// *inter-module-communication*.
2977// If mctx module is the same as the param module the output files are obtained
2978// from outputFiles property of module base, to avoid both setting and
mrziwang42953592024-06-20 09:53:33 -07002979// reading OutputFilesProvider before GenerateBuildActions is finished.
mrziwange6c85812024-05-22 14:36:09 -07002980// If a module doesn't have the OutputFilesProvider, nil is returned.
Yu Liud3228ac2024-11-08 23:11:47 +00002981func outputFilesForModuleFromProvider(ctx PathContext, module Module, tag string) (Paths, error) {
mrziwangabdb2932024-06-18 12:43:41 -07002982 var outputFiles OutputFilesInfo
mrziwang0cbd3b02024-06-20 16:39:25 -07002983
mrziwang1ea01e32024-07-12 12:26:34 -07002984 if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx {
Yu Liue472c1d2025-02-26 20:13:04 +00002985 if !EqualModules(mctx.Module(), module) {
mrziwangabdb2932024-06-18 12:43:41 -07002986 outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider)
mrziwang0cbd3b02024-06-20 16:39:25 -07002987 } else {
Yu Liu876b7ce2024-08-21 18:20:13 +00002988 outputFiles = mctx.GetOutputFiles()
mrziwange6c85812024-05-22 14:36:09 -07002989 }
mrziwang0cbd3b02024-06-20 16:39:25 -07002990 } else if cta, isCta := ctx.(*singletonContextAdaptor); isCta {
Yu Liud3228ac2024-11-08 23:11:47 +00002991 outputFiles, _ = OtherModuleProvider(cta, module, OutputFilesProvider)
mrziwang7a47bd32024-07-17 11:11:05 -07002992 } else {
2993 return nil, fmt.Errorf("unsupported context %q in method outputFilesForModuleFromProvider", reflect.TypeOf(ctx))
mrziwang0cbd3b02024-06-20 16:39:25 -07002994 }
mrziwang0cbd3b02024-06-20 16:39:25 -07002995
mrziwangabdb2932024-06-18 12:43:41 -07002996 if outputFiles.isEmpty() {
mrziwangabdb2932024-06-18 12:43:41 -07002997 return nil, OutputFilesProviderNotSet
2998 }
2999
3000 if tag == "" {
3001 return outputFiles.DefaultOutputFiles, nil
3002 } else if taggedOutputFiles, hasTag := outputFiles.TaggedOutputFiles[tag]; hasTag {
3003 return taggedOutputFiles, nil
3004 } else {
Cole Fausta8437c52025-02-25 14:45:43 -08003005 return nil, UnsupportedOutputTagError{
3006 tag: tag,
mrziwange6c85812024-05-22 14:36:09 -07003007 }
3008 }
mrziwange6c85812024-05-22 14:36:09 -07003009}
3010
mrziwang0cbd3b02024-06-20 16:39:25 -07003011func (o OutputFilesInfo) isEmpty() bool {
3012 return o.DefaultOutputFiles == nil && o.TaggedOutputFiles == nil
3013}
3014
mrziwange6c85812024-05-22 14:36:09 -07003015type OutputFilesInfo struct {
3016 // default output files when tag is an empty string ""
3017 DefaultOutputFiles Paths
3018
3019 // the corresponding output files for given tags
3020 TaggedOutputFiles map[string]Paths
3021}
3022
3023var OutputFilesProvider = blueprint.NewProvider[OutputFilesInfo]()
3024
Cole Fausta8437c52025-02-25 14:45:43 -08003025type UnsupportedOutputTagError struct {
3026 tag string
3027}
3028
3029func (u UnsupportedOutputTagError) Error() string {
3030 return fmt.Sprintf("unsupported output tag %q", u.tag)
3031}
3032
3033func (u UnsupportedOutputTagError) Is(e error) bool {
3034 _, ok := e.(UnsupportedOutputTagError)
3035 return ok
3036}
3037
3038var _ error = UnsupportedOutputTagError{}
3039
mrziwangabdb2932024-06-18 12:43:41 -07003040// This is used to mark the case where OutputFilesProvider is not set on some modules.
3041var OutputFilesProviderNotSet = fmt.Errorf("No output files from provider")
Cole Fausta8437c52025-02-25 14:45:43 -08003042var ErrUnsupportedOutputTag = UnsupportedOutputTagError{}
mrziwangabdb2932024-06-18 12:43:41 -07003043
Colin Cross41589502020-12-01 14:00:21 -08003044// Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to
3045// specify that they can be used as a tool by a genrule module.
Colin Crossfe17f6f2019-03-28 19:30:56 -07003046type HostToolProvider interface {
Colin Crossba9e4032020-11-24 16:32:22 -08003047 Module
Colin Cross41589502020-12-01 14:00:21 -08003048 // HostToolPath returns the path to the host tool for the module if it is one, or an invalid
3049 // OptionalPath.
Colin Crossfe17f6f2019-03-28 19:30:56 -07003050 HostToolPath() OptionalPath
3051}
3052
Colin Cross463a90e2015-06-17 14:20:06 -07003053func init() {
LaMont Jones0c10e4d2023-05-16 00:58:37 +00003054 RegisterParallelSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07003055}
3056
Colin Cross0875c522017-11-28 17:34:01 -08003057func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07003058 return &buildTargetSingleton{}
3059}
3060
Colin Cross87d8b562017-04-25 10:01:55 -07003061func parentDir(dir string) string {
3062 dir, _ = filepath.Split(dir)
3063 return filepath.Clean(dir)
3064}
3065
Colin Cross1f8c52b2015-06-16 16:38:17 -07003066type buildTargetSingleton struct{}
3067
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003068func AddAncestors(ctx SingletonContext, dirMap map[string]Paths, mmName func(string) string) ([]string, []string) {
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003069 // Ensure ancestor directories are in dirMap
3070 // Make directories build their direct subdirectories
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003071 // Returns a slice of all directories and a slice of top-level directories.
Cole Faust18994c72023-02-28 16:02:16 -08003072 dirs := SortedKeys(dirMap)
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003073 for _, dir := range dirs {
3074 dir := parentDir(dir)
3075 for dir != "." && dir != "/" {
3076 if _, exists := dirMap[dir]; exists {
3077 break
3078 }
3079 dirMap[dir] = nil
3080 dir = parentDir(dir)
3081 }
3082 }
Cole Faust18994c72023-02-28 16:02:16 -08003083 dirs = SortedKeys(dirMap)
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003084 var topDirs []string
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003085 for _, dir := range dirs {
3086 p := parentDir(dir)
3087 if p != "." && p != "/" {
3088 dirMap[p] = append(dirMap[p], PathForPhony(ctx, mmName(dir)))
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003089 } else if dir != "." && dir != "/" && dir != "" {
3090 topDirs = append(topDirs, dir)
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003091 }
3092 }
Cole Faust18994c72023-02-28 16:02:16 -08003093 return SortedKeys(dirMap), topDirs
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07003094}
3095
Colin Cross0875c522017-11-28 17:34:01 -08003096func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
3097 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07003098
LaMont Jones825f8ff2025-02-12 11:52:00 -08003099 // Create a top level partialcompileclean target for modules to add dependencies to.
3100 ctx.Phony("partialcompileclean")
3101
Colin Crossc3d87d32020-06-04 13:25:17 -07003102 mmTarget := func(dir string) string {
3103 return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
Colin Cross87d8b562017-04-25 10:01:55 -07003104 }
3105
Colin Cross0875c522017-11-28 17:34:01 -08003106 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003107
Yu Liu2a815b62025-02-21 20:46:25 +00003108 ctx.VisitAllModuleProxies(func(module ModuleProxy) {
Cole Faust0523b8f2025-03-03 15:11:32 -08003109 info := OtherModuleProviderOrDefault(ctx, module, ModuleBuildTargetsProvider)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003110
Yu Liuddc2e1a2024-08-20 21:31:22 +00003111 if info.CheckbuildTarget != nil {
3112 checkbuildDeps = append(checkbuildDeps, info.CheckbuildTarget)
3113 modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.CheckbuildTarget)
Colin Cross0875c522017-11-28 17:34:01 -08003114 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07003115
Yu Liuddc2e1a2024-08-20 21:31:22 +00003116 if info.InstallTarget != nil {
3117 modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.InstallTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003118 }
3119 })
3120
Dan Willemsen5ba07e82015-12-11 13:51:06 -08003121 suffix := ""
Jingwen Chencda22c92020-11-23 00:22:30 -05003122 if ctx.Config().KatiEnabled() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08003123 suffix = "-soong"
3124 }
3125
Colin Cross1f8c52b2015-06-16 16:38:17 -07003126 // Create a top-level checkbuild target that depends on all modules
Colin Crossc3d87d32020-06-04 13:25:17 -07003127 ctx.Phony("checkbuild"+suffix, checkbuildDeps...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003128
Dan Willemsend2e95fb2017-09-20 14:30:50 -07003129 // Make will generate the MODULES-IN-* targets
Jingwen Chencda22c92020-11-23 00:22:30 -05003130 if ctx.Config().KatiEnabled() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07003131 return
3132 }
3133
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07003134 dirs, _ := AddAncestors(ctx, modulesInDir, mmTarget)
Colin Cross87d8b562017-04-25 10:01:55 -07003135
Dan Willemsend2e95fb2017-09-20 14:30:50 -07003136 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
3137 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
3138 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07003139 for _, dir := range dirs {
Colin Crossc3d87d32020-06-04 13:25:17 -07003140 ctx.Phony(mmTarget(dir), modulesInDir[dir]...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07003141 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07003142
3143 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
Jiyong Park1613e552020-09-14 19:43:17 +09003144 type osAndCross struct {
3145 os OsType
3146 hostCross bool
3147 }
3148 osDeps := map[osAndCross]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08003149 ctx.VisitAllModules(func(module Module) {
Cole Fausta963b942024-04-11 17:43:00 -07003150 if module.Enabled(ctx) {
Jiyong Park1613e552020-09-14 19:43:17 +09003151 key := osAndCross{os: module.Target().Os, hostCross: module.Target().HostCross}
Yu Liud46e5ae2024-08-15 18:46:17 +00003152 osDeps[key] = append(osDeps[key], OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).CheckbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07003153 }
3154 })
3155
Colin Cross0875c522017-11-28 17:34:01 -08003156 osClass := make(map[string]Paths)
Jiyong Park1613e552020-09-14 19:43:17 +09003157 for key, deps := range osDeps {
Dan Willemsen61d88b82017-09-20 17:29:08 -07003158 var className string
3159
Jiyong Park1613e552020-09-14 19:43:17 +09003160 switch key.os.Class {
Dan Willemsen61d88b82017-09-20 17:29:08 -07003161 case Host:
Jiyong Park1613e552020-09-14 19:43:17 +09003162 if key.hostCross {
3163 className = "host-cross"
3164 } else {
3165 className = "host"
3166 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07003167 case Device:
3168 className = "target"
3169 default:
3170 continue
3171 }
3172
Jiyong Park1613e552020-09-14 19:43:17 +09003173 name := className + "-" + key.os.Name
Colin Crossc3d87d32020-06-04 13:25:17 -07003174 osClass[className] = append(osClass[className], PathForPhony(ctx, name))
Dan Willemsen61d88b82017-09-20 17:29:08 -07003175
Colin Crossc3d87d32020-06-04 13:25:17 -07003176 ctx.Phony(name, deps...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07003177 }
3178
3179 // Wrap those into host|host-cross|target phony rules
Cole Faust18994c72023-02-28 16:02:16 -08003180 for _, class := range SortedKeys(osClass) {
Colin Crossc3d87d32020-06-04 13:25:17 -07003181 ctx.Phony(class, osClass[class]...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07003182 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07003183}
Colin Crossd779da42015-12-17 18:00:23 -08003184
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003185// Collect information for opening IDE project files in java/jdeps.go.
3186type IDEInfo interface {
Cole Faustb36d31d2024-08-27 16:04:28 -07003187 IDEInfo(ctx BaseModuleContext, ideInfo *IdeInfo)
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003188 BaseModuleName() string
3189}
3190
Cole Faust08c7f862024-08-27 15:03:59 -07003191// Collect information for opening IDE project files in java/jdeps.go.
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003192type IdeInfo struct {
Cole Faust08c7f862024-08-27 15:03:59 -07003193 BaseModuleName string `json:"-"`
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003194 Deps []string `json:"dependencies,omitempty"`
3195 Srcs []string `json:"srcs,omitempty"`
3196 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
3197 Jarjar_rules []string `json:"jarjar_rules,omitempty"`
3198 Jars []string `json:"jars,omitempty"`
3199 Classes []string `json:"class,omitempty"`
3200 Installed_paths []string `json:"installed,omitempty"`
patricktu18c82ff2019-05-10 15:48:50 +08003201 SrcJars []string `json:"srcjars,omitempty"`
bralee1fbf4402020-05-21 10:11:59 +08003202 Paths []string `json:"path,omitempty"`
Yikef6282022022-04-13 20:41:01 +08003203 Static_libs []string `json:"static_libs,omitempty"`
3204 Libs []string `json:"libs,omitempty"`
Brandon Lee5d45c6f2018-08-15 15:35:38 -07003205}
Paul Duffinf88d8e02020-05-07 20:21:34 +01003206
Cole Faust08c7f862024-08-27 15:03:59 -07003207// Merge merges two IdeInfos and produces a new one, leaving the origional unchanged
3208func (i IdeInfo) Merge(other IdeInfo) IdeInfo {
3209 return IdeInfo{
3210 Deps: mergeStringLists(i.Deps, other.Deps),
3211 Srcs: mergeStringLists(i.Srcs, other.Srcs),
3212 Aidl_include_dirs: mergeStringLists(i.Aidl_include_dirs, other.Aidl_include_dirs),
3213 Jarjar_rules: mergeStringLists(i.Jarjar_rules, other.Jarjar_rules),
3214 Jars: mergeStringLists(i.Jars, other.Jars),
3215 Classes: mergeStringLists(i.Classes, other.Classes),
3216 Installed_paths: mergeStringLists(i.Installed_paths, other.Installed_paths),
3217 SrcJars: mergeStringLists(i.SrcJars, other.SrcJars),
3218 Paths: mergeStringLists(i.Paths, other.Paths),
3219 Static_libs: mergeStringLists(i.Static_libs, other.Static_libs),
3220 Libs: mergeStringLists(i.Libs, other.Libs),
3221 }
3222}
3223
3224// mergeStringLists appends the two string lists together and returns a new string list,
3225// leaving the originals unchanged. Duplicate strings will be deduplicated.
3226func mergeStringLists(a, b []string) []string {
3227 return FirstUniqueStrings(Concat(a, b))
3228}
3229
3230var IdeInfoProviderKey = blueprint.NewProvider[IdeInfo]()
3231
Paul Duffinf88d8e02020-05-07 20:21:34 +01003232func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error {
3233 bpctx := ctx.blueprintBaseModuleContext()
3234 return blueprint.CheckBlueprintSyntax(bpctx.ModuleFactories(), filename, contents)
3235}