blob: bc7f5e63a17045796a2e7a6ef8b170733c2bb306 [file] [log] [blame]
Colin Cross3f40fa42015-01-30 17:27:36 -08001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Colin Cross3f40fa42015-01-30 17:27:36 -080016
17import (
Colin Cross6ff51382015-12-17 16:39:19 -080018 "fmt"
Bob Badour4101c712022-02-09 11:54:35 -080019 "net/url"
Colin Cross3f40fa42015-01-30 17:27:36 -080020 "path/filepath"
Liz Kammer9525e712022-01-05 13:46:24 -050021 "reflect"
Colin Crossd6fd0132023-11-06 13:54:06 -080022 "slices"
Bob Badour4101c712022-02-09 11:54:35 -080023 "sort"
Colin Cross6ff51382015-12-17 16:39:19 -080024 "strings"
Tahsin Loqman77dc7d02022-12-19 16:27:25 +000025
Colin Crossf6566ed2015-03-24 11:13:38 -070026 "github.com/google/blueprint"
Yu Liu3cadf7d2024-10-24 18:47:06 +000027 "github.com/google/blueprint/depset"
28 "github.com/google/blueprint/gobtools"
Colin Crossfe4bc362018-09-12 10:02:13 -070029 "github.com/google/blueprint/proptools"
Colin Cross3f40fa42015-01-30 17:27:36 -080030)
31
32var (
33 DeviceSharedLibrary = "shared_library"
34 DeviceStaticLibrary = "static_library"
Joe Onorato349ae8d2024-02-05 22:46:00 +000035 jarJarPrefixHandler func(ctx ModuleContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080036)
37
Colin Cross635c3b02016-05-18 15:37:25 -070038type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080039 blueprint.Module
40
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070041 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
42 // but GenerateAndroidBuildActions also has access to Android-specific information.
43 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -070044 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070045
Paul Duffin44f1d842020-06-26 20:17:02 +010046 // Add dependencies to the components of a module, i.e. modules that are created
47 // by the module and which are considered to be part of the creating module.
48 //
49 // This is called before prebuilts are renamed so as to allow a dependency to be
50 // added directly to a prebuilt child module instead of depending on a source module
51 // and relying on prebuilt processing to switch to the prebuilt module if preferred.
52 //
53 // A dependency on a prebuilt must include the "prebuilt_" prefix.
54 ComponentDepsMutator(ctx BottomUpMutatorContext)
55
Colin Cross1e676be2016-10-12 14:38:15 -070056 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080057
Colin Cross635c3b02016-05-18 15:37:25 -070058 base() *ModuleBase
Inseob Kimeec88e12020-01-22 11:11:29 +090059 Disable()
Cole Fauste8a87832024-09-11 11:35:46 -070060 Enabled(ctx ConfigurableEvaluatorContext) bool
Colin Crossa1ad8d12016-06-01 17:09:44 -070061 Target() Target
Paul Duffinc04fb9e2021-03-01 12:25:10 +000062 MultiTargets() []Target
Paul Duffinb42fa672021-09-09 16:37:49 +010063
64 // ImageVariation returns the image variation of this module.
65 //
66 // The returned structure has its Mutator field set to "image" and its Variation field set to the
67 // image variation, e.g. recovery, ramdisk, etc.. The Variation field is "" for host modules and
68 // device modules that have no image variation.
69 ImageVariation() blueprint.Variation
70
Anton Hansson1ee62c02020-06-30 11:51:53 +010071 Owner() string
Dan Willemsen782a2d12015-12-21 14:55:28 -080072 InstallInData() bool
Jaewoong Jung0949f312019-09-11 10:25:18 -070073 InstallInTestcases() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -070074 InstallInSanitizerDir() bool
Yifan Hong1b3348d2020-01-21 15:53:22 -080075 InstallInRamdisk() bool
Yifan Hong60e0cfb2020-10-21 15:17:56 -070076 InstallInVendorRamdisk() bool
Inseob Kim08758f02021-04-08 21:13:22 +090077 InstallInDebugRamdisk() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +090078 InstallInRecovery() bool
Colin Cross90ba5f42019-10-02 11:10:58 -070079 InstallInRoot() bool
Colin Crossea30d852023-11-29 16:00:16 -080080 InstallInOdm() bool
81 InstallInProduct() bool
Kiyoung Kimae11c232021-07-19 11:38:04 +090082 InstallInVendor() bool
Spandan Das950deca2024-10-01 18:35:23 +000083 InstallInSystemExt() bool
Jiyong Park87788b52020-09-01 12:37:45 +090084 InstallForceOS() (*OsType, *ArchType)
Jiyong Parkce243632023-02-17 18:22:25 +090085 PartitionTag(DeviceConfig) string
Colin Crossa9c8c9f2020-12-16 10:20:23 -080086 HideFromMake()
87 IsHideFromMake() bool
Martin Stjernholm9e7f45e2020-12-23 03:50:30 +000088 IsSkipInstall() bool
Iván Budnik295da162023-03-10 16:11:26 +000089 MakeUninstallable()
Liz Kammer5ca3a622020-08-05 15:40:41 -070090 ReplacedByPrebuilt()
91 IsReplacedByPrebuilt() bool
Jiyong Park374510b2018-03-19 18:23:01 +090092 ExportedToMake() bool
Justin Yun1871f902023-04-07 20:13:19 +090093 EffectiveLicenseKinds() []string
Justin Yun885a7de2021-06-29 20:34:53 +090094 EffectiveLicenseFiles() Paths
Colin Cross36242852017-06-23 15:06:31 -070095
96 AddProperties(props ...interface{})
97 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -070098
Colin Crossae887032017-10-23 17:16:14 -070099 BuildParamsForTests() []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800100 RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800101 VariablesForTests() map[string]string
Paul Duffine2453c72019-05-31 14:00:04 +0100102
Colin Cross9a362232019-07-01 15:32:45 -0700103 // String returns a string that includes the module name and variants for printing during debugging.
104 String() string
105
Paul Duffine2453c72019-05-31 14:00:04 +0100106 // Get the qualified module id for this module.
107 qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName
108
109 // Get information about the properties that can contain visibility rules.
110 visibilityProperties() []visibilityProperty
Paul Duffin63c6e182019-07-24 14:24:38 +0100111
Cole Fauste8a87832024-09-11 11:35:46 -0700112 RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string
Jiyong Park6a8cf5f2019-12-30 16:31:09 +0900113 HostRequiredModuleNames() []string
114 TargetRequiredModuleNames() []string
Cole Fauste8a87832024-09-11 11:35:46 -0700115 VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string
Colin Cross897266e2020-02-13 13:22:08 -0800116
Cole Fauste8a87832024-09-11 11:35:46 -0700117 ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator
Jihoon Kang0d545b82024-10-11 00:21:57 +0000118
119 // The usage of this method is experimental and should not be used outside of fsgen package.
120 // This will be removed once product packaging migration to Soong is complete.
121 DecodeMultilib(ctx ConfigContext) (string, string)
Spandan Dase1860e42024-10-24 22:29:50 +0000122
123 // WARNING: This should not be used outside build/soong/fsgen
124 // Overrides returns the list of modules which should not be installed if this module is installed.
125 Overrides() []string
Paul Duffine2453c72019-05-31 14:00:04 +0100126}
127
128// Qualified id for a module
129type qualifiedModuleName struct {
130 // The package (i.e. directory) in which the module is defined, without trailing /
131 pkg string
132
133 // The name of the module, empty string if package.
134 name string
135}
136
137func (q qualifiedModuleName) String() string {
138 if q.name == "" {
139 return "//" + q.pkg
140 }
141 return "//" + q.pkg + ":" + q.name
142}
143
Paul Duffine484f472019-06-20 16:38:08 +0100144func (q qualifiedModuleName) isRootPackage() bool {
145 return q.pkg == "" && q.name == ""
146}
147
Paul Duffine2453c72019-05-31 14:00:04 +0100148// Get the id for the package containing this module.
149func (q qualifiedModuleName) getContainingPackageId() qualifiedModuleName {
150 pkg := q.pkg
151 if q.name == "" {
Paul Duffine484f472019-06-20 16:38:08 +0100152 if pkg == "" {
153 panic(fmt.Errorf("Cannot get containing package id of root package"))
154 }
155
156 index := strings.LastIndex(pkg, "/")
157 if index == -1 {
158 pkg = ""
159 } else {
160 pkg = pkg[:index]
161 }
Paul Duffine2453c72019-05-31 14:00:04 +0100162 }
163 return newPackageId(pkg)
164}
165
166func newPackageId(pkg string) qualifiedModuleName {
167 // A qualified id for a package module has no name.
168 return qualifiedModuleName{pkg: pkg, name: ""}
Colin Cross3f40fa42015-01-30 17:27:36 -0800169}
170
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000171type Dist struct {
172 // Copy the output of this module to the $DIST_DIR when `dist` is specified on the
173 // command line and any of these targets are also on the command line, or otherwise
174 // built
175 Targets []string `android:"arch_variant"`
176
177 // The name of the output artifact. This defaults to the basename of the output of
178 // the module.
179 Dest *string `android:"arch_variant"`
180
181 // The directory within the dist directory to store the artifact. Defaults to the
182 // top level directory ("").
183 Dir *string `android:"arch_variant"`
184
185 // A suffix to add to the artifact file name (before any extension).
186 Suffix *string `android:"arch_variant"`
187
Trevor Radcliffe90727f42022-03-21 19:34:02 +0000188 // If true, then the artifact file will be appended with _<product name>. For
189 // example, if the product is coral and the module is an android_app module
190 // of name foo, then the artifact would be foo_coral.apk. If false, there is
191 // no change to the artifact file name.
192 Append_artifact_with_product *bool `android:"arch_variant"`
193
Paul Duffin74f05592020-11-25 16:37:46 +0000194 // A string tag to select the OutputFiles associated with the tag.
195 //
196 // If no tag is specified then it will select the default dist paths provided
197 // by the module type. If a tag of "" is specified then it will return the
198 // default output files provided by the modules, i.e. the result of calling
199 // OutputFiles("").
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000200 Tag *string `android:"arch_variant"`
201}
202
Bob Badour4101c712022-02-09 11:54:35 -0800203// NamedPath associates a path with a name. e.g. a license text path with a package name
204type NamedPath struct {
205 Path Path
206 Name string
207}
208
209// String returns an escaped string representing the `NamedPath`.
210func (p NamedPath) String() string {
211 if len(p.Name) > 0 {
212 return p.Path.String() + ":" + url.QueryEscape(p.Name)
213 }
214 return p.Path.String()
215}
216
217// NamedPaths describes a list of paths each associated with a name.
218type NamedPaths []NamedPath
219
220// Strings returns a list of escaped strings representing each `NamedPath` in the list.
221func (l NamedPaths) Strings() []string {
222 result := make([]string, 0, len(l))
223 for _, p := range l {
224 result = append(result, p.String())
225 }
226 return result
227}
228
229// SortedUniqueNamedPaths modifies `l` in place to return the sorted unique subset.
230func SortedUniqueNamedPaths(l NamedPaths) NamedPaths {
231 if len(l) == 0 {
232 return l
233 }
234 sort.Slice(l, func(i, j int) bool {
235 return l[i].String() < l[j].String()
236 })
237 k := 0
238 for i := 1; i < len(l); i++ {
239 if l[i].String() == l[k].String() {
240 continue
241 }
242 k++
243 if k < i {
244 l[k] = l[i]
245 }
246 }
247 return l[:k+1]
248}
249
Colin Crossfc754582016-05-17 16:34:16 -0700250type nameProperties struct {
251 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800252 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700253}
254
Colin Cross08d6f8f2020-11-19 02:33:19 +0000255type commonProperties struct {
Dan Willemsen0effe062015-11-30 16:06:01 -0800256 // emit build rules for this module
Paul Duffin54d9bb72020-02-12 10:20:56 +0000257 //
258 // Disabling a module should only be done for those modules that cannot be built
259 // in the current environment. Modules that can build in the current environment
260 // but are not usually required (e.g. superceded by a prebuilt) should not be
261 // disabled as that will prevent them from being built by the checkbuild target
262 // and so prevent early detection of changes that have broken those modules.
Cole Fausta963b942024-04-11 17:43:00 -0700263 Enabled proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800264
Paul Duffin2e61fa62019-03-28 14:10:57 +0000265 // Controls the visibility of this module to other modules. Allowable values are one or more of
266 // these formats:
267 //
268 // ["//visibility:public"]: Anyone can use this module.
269 // ["//visibility:private"]: Only rules in the module's package (not its subpackages) can use
270 // this module.
Paul Duffin51084ff2020-05-05 19:19:22 +0100271 // ["//visibility:override"]: Discards any rules inherited from defaults or a creating module.
272 // Can only be used at the beginning of a list of visibility rules.
Paul Duffin2e61fa62019-03-28 14:10:57 +0000273 // ["//some/package:__pkg__", "//other/package:__pkg__"]: Only modules in some/package and
274 // other/package (defined in some/package/*.bp and other/package/*.bp) have access to
275 // this module. Note that sub-packages do not have access to the rule; for example,
276 // //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__
277 // is a special module and must be used verbatim. It represents all of the modules in the
278 // package.
279 // ["//project:__subpackages__", "//other:__subpackages__"]: Only modules in packages project
280 // or other or in one of their sub-packages have access to this module. For example,
281 // //project:rule, //project/library:lib or //other/testing/internal:munge are allowed
282 // to depend on this rule (but not //independent:evil)
283 // ["//project"]: This is shorthand for ["//project:__pkg__"]
284 // [":__subpackages__"]: This is shorthand for ["//project:__subpackages__"] where
285 // //project is the module's package. e.g. using [":__subpackages__"] in
286 // packages/apps/Settings/Android.bp is equivalent to
287 // //packages/apps/Settings:__subpackages__.
288 // ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public
289 // for now. It is an error if it is used in a module.
Paul Duffine2453c72019-05-31 14:00:04 +0100290 //
291 // If a module does not specify the `visibility` property then it uses the
292 // `default_visibility` property of the `package` module in the module's package.
293 //
294 // If the `default_visibility` property is not set for the module's package then
Paul Duffine484f472019-06-20 16:38:08 +0100295 // it will use the `default_visibility` of its closest ancestor package for which
296 // a `default_visibility` property is specified.
297 //
298 // If no `default_visibility` property can be found then the module uses the
299 // global default of `//visibility:legacy_public`.
Paul Duffine2453c72019-05-31 14:00:04 +0100300 //
Paul Duffin95d53b52019-07-24 13:45:05 +0100301 // The `visibility` property has no effect on a defaults module although it does
302 // apply to any non-defaults module that uses it. To set the visibility of a
303 // defaults module, use the `defaults_visibility` property on the defaults module;
304 // not to be confused with the `default_visibility` property on the package module.
305 //
Elliott Hughes10363162024-01-09 22:02:03 +0000306 // See https://android.googlesource.com/platform/build/soong/+/main/README.md#visibility for
Paul Duffin2e61fa62019-03-28 14:10:57 +0000307 // more details.
308 Visibility []string
309
Bob Badour37af0462021-01-07 03:34:31 +0000310 // Describes the licenses applicable to this module. Must reference license modules.
311 Licenses []string
312
313 // Flattened from direct license dependencies. Equal to Licenses unless particular module adds more.
314 Effective_licenses []string `blueprint:"mutated"`
315 // Override of module name when reporting licenses
316 Effective_package_name *string `blueprint:"mutated"`
317 // Notice files
Bob Badour4101c712022-02-09 11:54:35 -0800318 Effective_license_text NamedPaths `blueprint:"mutated"`
Bob Badour37af0462021-01-07 03:34:31 +0000319 // License names
320 Effective_license_kinds []string `blueprint:"mutated"`
321 // License conditions
322 Effective_license_conditions []string `blueprint:"mutated"`
323
Colin Cross7d5136f2015-05-11 13:39:40 -0700324 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800325 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
326 // 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 +0000327 // platform).
Colin Cross7d716ba2017-11-01 10:38:29 -0700328 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700329
330 Target struct {
331 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700332 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700333 }
334 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700335 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700336 }
337 }
338
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000339 // If set to true then the archMutator will create variants for each arch specific target
340 // (e.g. 32/64) that the module is required to produce. If set to false then it will only
341 // create a variant for the architecture and will list the additional arch specific targets
342 // that the variant needs to produce in the CompileMultiTargets property.
Colin Crossee0bc3b2018-10-02 22:01:37 -0700343 UseTargetVariants bool `blueprint:"mutated"`
344 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800345
Dan Willemsen782a2d12015-12-21 14:55:28 -0800346 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700347 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800348
Colin Cross55708f32017-03-20 13:23:34 -0700349 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700350 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700351
Jiyong Park2db76922017-11-08 16:03:48 +0900352 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
353 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
354 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700355 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700356
Jiyong Park2db76922017-11-08 16:03:48 +0900357 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
358 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
359 Soc_specific *bool
360
361 // whether this module is specific to a device, not only for SoC, but also for off-chip
362 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
363 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
364 // This implies `soc_specific:true`.
365 Device_specific *bool
366
367 // whether this module is specific to a software configuration of a product (e.g. country,
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900368 // network operator, etc). When set to true, it is installed into /product (or
369 // /system/product if product partition does not exist).
Jiyong Park2db76922017-11-08 16:03:48 +0900370 Product_specific *bool
371
Justin Yund5f6c822019-06-25 16:47:17 +0900372 // whether this module extends system. When set to true, it is installed into /system_ext
373 // (or /system/system_ext if system_ext partition does not exist).
374 System_ext_specific *bool
375
Jiyong Parkf9332f12018-02-01 00:54:12 +0900376 // Whether this module is installed to recovery partition
377 Recovery *bool
378
Yifan Hong1b3348d2020-01-21 15:53:22 -0800379 // Whether this module is installed to ramdisk
380 Ramdisk *bool
381
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700382 // Whether this module is installed to vendor ramdisk
383 Vendor_ramdisk *bool
384
Inseob Kim08758f02021-04-08 21:13:22 +0900385 // Whether this module is installed to debug ramdisk
386 Debug_ramdisk *bool
387
Jaewoong Jung8e93aba2021-03-02 16:58:08 -0800388 // Whether this module is built for non-native architectures (also known as native bridge binary)
dimitry1f33e402019-03-26 12:39:31 +0100389 Native_bridge_supported *bool `android:"arch_variant"`
390
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700391 // init.rc files to be installed if this module is installed
Inseob Kim713b87d2024-09-13 11:29:54 +0900392 Init_rc proptools.Configurable[[]string] `android:"arch_variant,path"`
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700393
Steven Moreland57a23d22018-04-04 15:42:19 -0700394 // VINTF manifest fragments to be installed if this module is installed
Inseob Kimf2237022024-07-23 13:36:31 +0900395 Vintf_fragments proptools.Configurable[[]string] `android:"path"`
Steven Moreland57a23d22018-04-04 15:42:19 -0700396
Chris Wolfe998306e2016-08-15 14:47:23 -0400397 // names of other modules to install if this module is installed
Cole Faust43ddd082024-06-17 12:32:40 -0700398 Required proptools.Configurable[[]string] `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400399
Sasha Smundakb6d23052019-04-01 18:37:36 -0700400 // names of other modules to install on host if this module is installed
401 Host_required []string `android:"arch_variant"`
402
403 // names of other modules to install on target if this module is installed
404 Target_required []string `android:"arch_variant"`
405
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000406 // The OsType of artifacts that this module variant is responsible for creating.
407 //
408 // Set by osMutator
409 CompileOS OsType `blueprint:"mutated"`
410
Cole Faust0aa21cc2024-03-20 12:28:03 -0700411 // Set to true after the arch mutator has run on this module and set CompileTarget,
412 // CompileMultiTargets, and CompilePrimary
413 ArchReady bool `blueprint:"mutated"`
414
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000415 // The Target of artifacts that this module variant is responsible for creating.
416 //
417 // Set by archMutator
418 CompileTarget Target `blueprint:"mutated"`
419
420 // The additional arch specific targets (e.g. 32/64 bit) that this module variant is
421 // responsible for creating.
422 //
423 // By default this is nil as, where necessary, separate variants are created for the
424 // different multilib types supported and that information is encapsulated in the
425 // CompileTarget so the module variant simply needs to create artifacts for that.
426 //
427 // However, if UseTargetVariants is set to false (e.g. by
428 // InitAndroidMultiTargetsArchModule) then no separate variants are created for the
429 // multilib targets. Instead a single variant is created for the architecture and
430 // this contains the multilib specific targets that this variant should create.
431 //
432 // Set by archMutator
Colin Crossee0bc3b2018-10-02 22:01:37 -0700433 CompileMultiTargets []Target `blueprint:"mutated"`
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000434
435 // True if the module variant's CompileTarget is the primary target
436 //
437 // Set by archMutator
438 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800439
440 // Set by InitAndroidModule
441 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700442 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700443
Paul Duffin1356d8c2020-02-25 19:26:33 +0000444 // If set to true then a CommonOS variant will be created which will have dependencies
445 // on all its OsType specific variants. Used by sdk/module_exports to create a snapshot
446 // that covers all os and architecture variants.
447 //
448 // The OsType specific variants can be retrieved by calling
449 // GetOsSpecificVariantsOfCommonOSVariant
450 //
451 // Set at module initialization time by calling InitCommonOSAndroidMultiTargetsArchModule
452 CreateCommonOSVariant bool `blueprint:"mutated"`
453
Jiyong Park3f627e62024-05-01 16:14:38 +0900454 // When set to true, this module is not installed to the full install path (ex: under
455 // out/target/product/<name>/<partition>). It can be installed only to the packaging
456 // modules like android_filesystem.
457 No_full_install *bool
458
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800459 // When HideFromMake is set to true, no entry for this variant will be emitted in the
460 // generated Android.mk file.
461 HideFromMake bool `blueprint:"mutated"`
462
463 // When SkipInstall is set to true, calls to ctx.InstallFile, ctx.InstallExecutable,
464 // ctx.InstallSymlink and ctx.InstallAbsoluteSymlink act like calls to ctx.PackageFile
465 // and don't create a rule to install the file.
Colin Crossce75d2c2016-10-06 16:12:58 -0700466 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800467
Colin Crossbd3a16b2023-04-25 11:30:51 -0700468 // UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex
469 // mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant
470 // is used to avoid adding install or packaging dependencies into libraries provided
471 // by apexes.
472 UninstallableApexPlatformVariant bool `blueprint:"mutated"`
473
Liz Kammer5ca3a622020-08-05 15:40:41 -0700474 // Whether the module has been replaced by a prebuilt
475 ReplacedByPrebuilt bool `blueprint:"mutated"`
476
Justin Yun32f053b2020-07-31 23:07:17 +0900477 // Disabled by mutators. If set to true, it overrides Enabled property.
478 ForcedDisabled bool `blueprint:"mutated"`
479
Jeff Gaston088e29e2017-11-29 16:47:17 -0800480 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross6c4f21f2019-06-06 15:41:36 -0700481
Liz Kammerc13f7852023-05-17 13:01:48 -0400482 MissingDeps []string `blueprint:"mutated"`
483 CheckedMissingDeps bool `blueprint:"mutated"`
Colin Cross9a362232019-07-01 15:32:45 -0700484
485 // Name and variant strings stored by mutators to enable Module.String()
486 DebugName string `blueprint:"mutated"`
487 DebugMutators []string `blueprint:"mutated"`
488 DebugVariations []string `blueprint:"mutated"`
Colin Cross7228ecd2019-11-18 16:00:16 -0800489
Colin Crossa6845402020-11-16 15:08:19 -0800490 // ImageVariation is set by ImageMutator to specify which image this variation is for,
491 // for example "" for core or "recovery" for recovery. It will often be set to one of the
492 // constants in image.go, but can also be set to a custom value by individual module types.
Colin Cross7228ecd2019-11-18 16:00:16 -0800493 ImageVariation string `blueprint:"mutated"`
Liz Kammer2ada09a2021-08-11 00:17:36 -0400494
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800495 // The team (defined by the owner/vendor) who owns the property.
496 Team *string `android:"path"`
Kiyoung Kimfaf6af32024-08-12 11:15:19 +0900497
498 // vintf_fragment Modules required from this module.
499 Vintf_fragment_modules proptools.Configurable[[]string] `android:"path"`
Jiyong Parka574d532024-08-28 18:06:43 +0900500
501 // List of module names that are prevented from being installed when this module gets
502 // installed.
503 Overrides []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800504}
505
Paul Duffined875132020-09-02 13:08:57 +0100506type distProperties struct {
507 // configuration to distribute output files from this module to the distribution
508 // directory (default: $OUT/dist, configurable with $DIST_DIR)
509 Dist Dist `android:"arch_variant"`
510
511 // a list of configurations to distribute output files from this module to the
512 // distribution directory (default: $OUT/dist, configurable with $DIST_DIR)
513 Dists []Dist `android:"arch_variant"`
514}
515
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800516type TeamDepTagType struct {
517 blueprint.BaseDependencyTag
518}
519
520var teamDepTag = TeamDepTagType{}
521
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900522// Dependency tag for required, host_required, and target_required modules.
523var RequiredDepTag = struct {
524 blueprint.BaseDependencyTag
525 InstallAlwaysNeededDependencyTag
526 // Requiring disabled module has been supported (as a side effect of this being implemented
527 // in Make). We may want to make it an error, but for now, let's keep the existing behavior.
528 AlwaysAllowDisabledModuleDependencyTag
529}{}
530
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800531// CommonTestOptions represents the common `test_options` properties in
532// Android.bp.
533type CommonTestOptions struct {
534 // If the test is a hostside (no device required) unittest that shall be run
535 // during presubmit check.
536 Unit_test *bool
Zhenhuang Wang409d2772022-08-22 16:00:05 +0800537
538 // Tags provide additional metadata to customize test execution by downstream
539 // test runners. The tags have no special meaning to Soong.
540 Tags []string
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800541}
542
543// SetAndroidMkEntries sets AndroidMkEntries according to the value of base
544// `test_options`.
545func (t *CommonTestOptions) SetAndroidMkEntries(entries *AndroidMkEntries) {
546 entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test))
Zhenhuang Wang409d2772022-08-22 16:00:05 +0800547 if len(t.Tags) > 0 {
548 entries.AddStrings("LOCAL_TEST_OPTIONS_TAGS", t.Tags...)
549 }
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800550}
551
Paul Duffin74f05592020-11-25 16:37:46 +0000552// The key to use in TaggedDistFiles when a Dist structure does not specify a
553// tag property. This intentionally does not use "" as the default because that
554// would mean that an empty tag would have a different meaning when used in a dist
555// structure that when used to reference a specific set of output paths using the
556// :module{tag} syntax, which passes tag to the OutputFiles(tag) method.
557const DefaultDistTag = "<default-dist-tag>"
558
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000559// A map of OutputFile tag keys to Paths, for disting purposes.
560type TaggedDistFiles map[string]Paths
561
Paul Duffin74f05592020-11-25 16:37:46 +0000562// addPathsForTag adds a mapping from the tag to the paths. If the map is nil
563// then it will create a map, update it and then return it. If a mapping already
564// exists for the tag then the paths are appended to the end of the current list
565// of paths, ignoring any duplicates.
566func (t TaggedDistFiles) addPathsForTag(tag string, paths ...Path) TaggedDistFiles {
567 if t == nil {
568 t = make(TaggedDistFiles)
569 }
570
571 for _, distFile := range paths {
572 if distFile != nil && !t[tag].containsPath(distFile) {
573 t[tag] = append(t[tag], distFile)
574 }
575 }
576
577 return t
578}
579
580// merge merges the entries from the other TaggedDistFiles object into this one.
581// If the TaggedDistFiles is nil then it will create a new instance, merge the
582// other into it, and then return it.
583func (t TaggedDistFiles) merge(other TaggedDistFiles) TaggedDistFiles {
584 for tag, paths := range other {
585 t = t.addPathsForTag(tag, paths...)
586 }
587
588 return t
589}
590
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000591func MakeDefaultDistFiles(paths ...Path) TaggedDistFiles {
Sasha Smundake198eaf2022-08-04 13:07:02 -0700592 for _, p := range paths {
593 if p == nil {
Jingwen Chen7b27ca72020-07-24 09:13:49 +0000594 panic("The path to a dist file cannot be nil.")
595 }
596 }
597
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000598 // The default OutputFile tag is the empty "" string.
Paul Duffin74f05592020-11-25 16:37:46 +0000599 return TaggedDistFiles{DefaultDistTag: paths}
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000600}
601
Colin Cross3f40fa42015-01-30 17:27:36 -0800602type hostAndDeviceProperties struct {
Colin Cross4e81d702018-11-09 10:36:55 -0800603 // If set to true, build a variant of the module for the host. Defaults to false.
604 Host_supported *bool
605
606 // If set to true, build a variant of the module for the device. Defaults to true.
Colin Crossa4190c12016-07-12 13:11:25 -0700607 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800608}
609
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000610type hostCrossProperties struct {
611 // If set to true, build a variant of the module for the host cross. Defaults to true.
612 Host_cross_supported *bool
613}
614
Colin Crossc472d572015-03-17 15:06:21 -0700615type Multilib string
616
617const (
Cole Faustb9c67e22024-10-08 16:39:56 -0700618 MultilibBoth Multilib = "both"
619 MultilibFirst Multilib = "first"
620 MultilibCommon Multilib = "common"
Colin Crossc472d572015-03-17 15:06:21 -0700621)
622
Colin Crossa1ad8d12016-06-01 17:09:44 -0700623type HostOrDeviceSupported int
624
625const (
Colin Cross34037c62020-11-17 13:19:17 -0800626 hostSupported = 1 << iota
627 hostCrossSupported
628 deviceSupported
629 hostDefault
630 deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700631
632 // Host and HostCross are built by default. Device is not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800633 HostSupported = hostSupported | hostCrossSupported | hostDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700634
635 // Host is built by default. HostCross and Device are not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800636 HostSupportedNoCross = hostSupported | hostDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700637
638 // Device is built by default. Host and HostCross are not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800639 DeviceSupported = deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700640
Liz Kammer8631cc72021-08-23 21:12:07 +0000641 // By default, _only_ device variant is built. Device variant can be disabled with `device_supported: false`
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -0700642 // Host and HostCross are disabled by default and can be enabled with `host_supported: true`
Colin Cross34037c62020-11-17 13:19:17 -0800643 HostAndDeviceSupported = hostSupported | hostCrossSupported | deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700644
645 // Host, HostCross, and Device are built by default.
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -0700646 // Building Device can be disabled with `device_supported: false`
647 // Building Host and HostCross can be disabled with `host_supported: false`
Colin Cross34037c62020-11-17 13:19:17 -0800648 HostAndDeviceDefault = hostSupported | hostCrossSupported | hostDefault |
649 deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700650
651 // Nothing is supported. This is not exposed to the user, but used to mark a
652 // host only module as unsupported when the module type is not supported on
653 // the host OS. E.g. benchmarks are supported on Linux but not Darwin.
Colin Cross34037c62020-11-17 13:19:17 -0800654 NeitherHostNorDeviceSupported = 0
Colin Crossa1ad8d12016-06-01 17:09:44 -0700655)
656
Jiyong Park2db76922017-11-08 16:03:48 +0900657type moduleKind int
658
659const (
660 platformModule moduleKind = iota
661 deviceSpecificModule
662 socSpecificModule
663 productSpecificModule
Justin Yund5f6c822019-06-25 16:47:17 +0900664 systemExtSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900665)
666
667func (k moduleKind) String() string {
668 switch k {
669 case platformModule:
670 return "platform"
671 case deviceSpecificModule:
672 return "device-specific"
673 case socSpecificModule:
674 return "soc-specific"
675 case productSpecificModule:
676 return "product-specific"
Justin Yund5f6c822019-06-25 16:47:17 +0900677 case systemExtSpecificModule:
678 return "systemext-specific"
Jiyong Park2db76922017-11-08 16:03:48 +0900679 default:
680 panic(fmt.Errorf("unknown module kind %d", k))
681 }
682}
683
Colin Cross9d34f352019-11-22 16:03:51 -0800684func initAndroidModuleBase(m Module) {
685 m.base().module = m
686}
687
Colin Crossa6845402020-11-16 15:08:19 -0800688// InitAndroidModule initializes the Module as an Android module that is not architecture-specific.
689// It adds the common properties, for example "name" and "enabled".
Colin Cross36242852017-06-23 15:06:31 -0700690func InitAndroidModule(m Module) {
Colin Cross9d34f352019-11-22 16:03:51 -0800691 initAndroidModuleBase(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800692 base := m.base()
Colin Cross5049f022015-03-18 13:28:46 -0700693
Colin Cross36242852017-06-23 15:06:31 -0700694 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700695 &base.nameProperties,
Paul Duffined875132020-09-02 13:08:57 +0100696 &base.commonProperties,
697 &base.distProperties)
Colin Cross18c46802019-09-24 22:19:02 -0700698
Colin Crosseabaedd2020-02-06 17:01:55 -0800699 initProductVariableModule(m)
Colin Cross18c46802019-09-24 22:19:02 -0700700
Paul Duffin63c6e182019-07-24 14:24:38 +0100701 // The default_visibility property needs to be checked and parsed by the visibility module during
Paul Duffin5ec73ec2020-05-01 17:52:01 +0100702 // its checking and parsing phases so make it the primary visibility property.
703 setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility)
Bob Badour37af0462021-01-07 03:34:31 +0000704
705 // The default_applicable_licenses property needs to be checked and parsed by the licenses module during
706 // its checking and parsing phases so make it the primary licenses property.
707 setPrimaryLicensesProperty(m, "licenses", &base.commonProperties.Licenses)
Colin Cross5049f022015-03-18 13:28:46 -0700708}
709
Colin Crossa6845402020-11-16 15:08:19 -0800710// InitAndroidArchModule initializes the Module as an Android module that is architecture-specific.
711// It adds the common properties, for example "name" and "enabled", as well as runtime generated
712// property structs for architecture-specific versions of generic properties tagged with
713// `android:"arch_variant"`.
714//
Colin Crossd079e0b2022-08-16 10:27:33 -0700715// InitAndroidModule should not be called if InitAndroidArchModule was called.
Colin Cross36242852017-06-23 15:06:31 -0700716func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
717 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700718
719 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800720 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700721 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700722 base.commonProperties.ArchSpecific = true
Colin Crossee0bc3b2018-10-02 22:01:37 -0700723 base.commonProperties.UseTargetVariants = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800724
Colin Cross34037c62020-11-17 13:19:17 -0800725 if hod&hostSupported != 0 && hod&deviceSupported != 0 {
Colin Cross36242852017-06-23 15:06:31 -0700726 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800727 }
728
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000729 if hod&hostCrossSupported != 0 {
730 m.AddProperties(&base.hostCrossProperties)
731 }
732
Colin Crossa6845402020-11-16 15:08:19 -0800733 initArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800734}
735
Colin Crossa6845402020-11-16 15:08:19 -0800736// InitAndroidMultiTargetsArchModule initializes the Module as an Android module that is
737// architecture-specific, but will only have a single variant per OS that handles all the
738// architectures simultaneously. The list of Targets that it must handle will be available from
739// ModuleContext.MultiTargets. It adds the common properties, for example "name" and "enabled", as
740// well as runtime generated property structs for architecture-specific versions of generic
741// properties tagged with `android:"arch_variant"`.
742//
743// InitAndroidModule or InitAndroidArchModule should not be called if
744// InitAndroidMultiTargetsArchModule was called.
Colin Crossee0bc3b2018-10-02 22:01:37 -0700745func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
746 InitAndroidArchModule(m, hod, defaultMultilib)
747 m.base().commonProperties.UseTargetVariants = false
748}
749
Colin Crossa6845402020-11-16 15:08:19 -0800750// InitCommonOSAndroidMultiTargetsArchModule initializes the Module as an Android module that is
751// architecture-specific, but will only have a single variant per OS that handles all the
752// architectures simultaneously, and will also have an additional CommonOS variant that has
753// dependencies on all the OS-specific variants. The list of Targets that it must handle will be
754// available from ModuleContext.MultiTargets. It adds the common properties, for example "name" and
755// "enabled", as well as runtime generated property structs for architecture-specific versions of
756// generic properties tagged with `android:"arch_variant"`.
757//
758// InitAndroidModule, InitAndroidArchModule or InitAndroidMultiTargetsArchModule should not be
759// called if InitCommonOSAndroidMultiTargetsArchModule was called.
Paul Duffin1356d8c2020-02-25 19:26:33 +0000760func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
761 InitAndroidArchModule(m, hod, defaultMultilib)
762 m.base().commonProperties.UseTargetVariants = false
763 m.base().commonProperties.CreateCommonOSVariant = true
764}
765
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800766// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800767// modules. It should be included as an anonymous field in every module
768// struct definition. InitAndroidModule should then be called from the module's
769// factory function, and the return values from InitAndroidModule should be
770// returned from the factory function.
771//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800772// The ModuleBase type is responsible for implementing the GenerateBuildActions
773// method to support the blueprint.Module interface. This method will then call
774// the module's GenerateAndroidBuildActions method once for each build variant
Colin Cross25de6c32019-06-06 14:29:25 -0700775// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext
776// rather than the usual blueprint.ModuleContext.
777// ModuleContext exposes extra functionality specific to the Android build
Colin Cross3f40fa42015-01-30 17:27:36 -0800778// system including details about the particular build variant that is to be
779// generated.
780//
781// For example:
782//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800783// import (
784// "android/soong/android"
785// )
Colin Cross3f40fa42015-01-30 17:27:36 -0800786//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800787// type myModule struct {
788// android.ModuleBase
789// properties struct {
790// MyProperty string
791// }
792// }
Colin Cross3f40fa42015-01-30 17:27:36 -0800793//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800794// func NewMyModule() android.Module {
795// m := &myModule{}
796// m.AddProperties(&m.properties)
797// android.InitAndroidModule(m)
798// return m
799// }
Colin Cross3f40fa42015-01-30 17:27:36 -0800800//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800801// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
802// // Get the CPU architecture for the current build variant.
803// variantArch := ctx.Arch()
Colin Cross3f40fa42015-01-30 17:27:36 -0800804//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800805// // ...
806// }
Colin Cross635c3b02016-05-18 15:37:25 -0700807type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800808 // Putting the curiously recurring thing pointing to the thing that contains
809 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700810 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700811 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800812
Colin Crossfc754582016-05-17 16:34:16 -0700813 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800814 commonProperties commonProperties
Paul Duffined875132020-09-02 13:08:57 +0100815 distProperties distProperties
Colin Cross18c46802019-09-24 22:19:02 -0700816 variableProperties interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800817 hostAndDeviceProperties hostAndDeviceProperties
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000818 hostCrossProperties hostCrossProperties
Jingwen Chen5d864492021-02-24 07:20:12 -0500819
Usta851a3272022-01-05 23:42:33 -0500820 // Arch specific versions of structs in GetProperties() prior to
821 // initialization in InitAndroidArchModule, lets call it `generalProperties`.
822 // The outer index has the same order as generalProperties and the inner index
823 // chooses the props specific to the architecture. The interface{} value is an
824 // archPropRoot that is filled with arch specific values by the arch mutator.
Jingwen Chen5d864492021-02-24 07:20:12 -0500825 archProperties [][]interface{}
826
Paul Duffin63c6e182019-07-24 14:24:38 +0100827 // Information about all the properties on the module that contains visibility rules that need
828 // checking.
829 visibilityPropertyInfo []visibilityProperty
830
831 // The primary visibility property, may be nil, that controls access to the module.
832 primaryVisibilityProperty visibilityProperty
833
Bob Badour37af0462021-01-07 03:34:31 +0000834 // The primary licenses property, may be nil, records license metadata for the module.
835 primaryLicensesProperty applicableLicensesProperty
836
Yu Liueb6d7052024-08-27 22:35:54 +0000837 noAddressSanitizer bool
Colin Cross1f8c52b2015-06-16 16:38:17 -0700838
Colin Cross178a5092016-09-13 13:42:32 -0700839 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700840
841 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700842
843 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700844 buildParams []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800845 ruleParams map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800846 variables map[string]string
Colin Cross36242852017-06-23 15:06:31 -0700847}
848
Lukacs T. Berkid18d8ca2021-06-25 09:11:22 +0200849func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
Liz Kammer9525e712022-01-05 13:46:24 -0500850 (*d)["Android"] = map[string]interface{}{
851 // Properties set in Blueprint or in blueprint of a defaults modules
852 "SetProperties": m.propertiesWithValues(),
853 }
854}
855
856type propInfo struct {
Liz Kammer898e0762022-03-22 11:27:26 -0400857 Name string
858 Type string
859 Value string
860 Values []string
Liz Kammer9525e712022-01-05 13:46:24 -0500861}
862
863func (m *ModuleBase) propertiesWithValues() []propInfo {
864 var info []propInfo
865 props := m.GetProperties()
866
867 var propsWithValues func(name string, v reflect.Value)
868 propsWithValues = func(name string, v reflect.Value) {
869 kind := v.Kind()
870 switch kind {
871 case reflect.Ptr, reflect.Interface:
872 if v.IsNil() {
873 return
874 }
875 propsWithValues(name, v.Elem())
876 case reflect.Struct:
877 if v.IsZero() {
878 return
879 }
880 for i := 0; i < v.NumField(); i++ {
881 namePrefix := name
882 sTyp := v.Type().Field(i)
883 if proptools.ShouldSkipProperty(sTyp) {
884 continue
885 }
886 if name != "" && !strings.HasSuffix(namePrefix, ".") {
887 namePrefix += "."
888 }
889 if !proptools.IsEmbedded(sTyp) {
890 namePrefix += sTyp.Name
891 }
892 sVal := v.Field(i)
893 propsWithValues(namePrefix, sVal)
894 }
895 case reflect.Array, reflect.Slice:
896 if v.IsNil() {
897 return
898 }
899 elKind := v.Type().Elem().Kind()
Liz Kammer898e0762022-03-22 11:27:26 -0400900 info = append(info, propInfo{Name: name, Type: elKind.String() + " " + kind.String(), Values: sliceReflectionValue(v)})
Liz Kammer9525e712022-01-05 13:46:24 -0500901 default:
Liz Kammer898e0762022-03-22 11:27:26 -0400902 info = append(info, propInfo{Name: name, Type: kind.String(), Value: reflectionValue(v)})
Liz Kammer9525e712022-01-05 13:46:24 -0500903 }
904 }
905
906 for _, p := range props {
907 propsWithValues("", reflect.ValueOf(p).Elem())
908 }
Liz Kammer898e0762022-03-22 11:27:26 -0400909 sort.Slice(info, func(i, j int) bool {
910 return info[i].Name < info[j].Name
911 })
Liz Kammer9525e712022-01-05 13:46:24 -0500912 return info
Lukacs T. Berkid18d8ca2021-06-25 09:11:22 +0200913}
914
Liz Kammer898e0762022-03-22 11:27:26 -0400915func reflectionValue(value reflect.Value) string {
916 switch value.Kind() {
917 case reflect.Bool:
918 return fmt.Sprintf("%t", value.Bool())
919 case reflect.Int64:
920 return fmt.Sprintf("%d", value.Int())
921 case reflect.String:
922 return fmt.Sprintf("%s", value.String())
923 case reflect.Struct:
924 if value.IsZero() {
925 return "{}"
926 }
927 length := value.NumField()
928 vals := make([]string, length, length)
929 for i := 0; i < length; i++ {
930 sTyp := value.Type().Field(i)
931 if proptools.ShouldSkipProperty(sTyp) {
932 continue
933 }
934 name := sTyp.Name
935 vals[i] = fmt.Sprintf("%s: %s", name, reflectionValue(value.Field(i)))
936 }
937 return fmt.Sprintf("%s{%s}", value.Type(), strings.Join(vals, ", "))
938 case reflect.Array, reflect.Slice:
939 vals := sliceReflectionValue(value)
940 return fmt.Sprintf("[%s]", strings.Join(vals, ", "))
941 }
942 return ""
943}
944
945func sliceReflectionValue(value reflect.Value) []string {
946 length := value.Len()
947 vals := make([]string, length, length)
948 for i := 0; i < length; i++ {
949 vals[i] = reflectionValue(value.Index(i))
950 }
951 return vals
952}
953
Paul Duffin44f1d842020-06-26 20:17:02 +0100954func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {}
955
Colin Cross4157e882019-06-06 16:57:04 -0700956func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
Colin Cross5f692ec2019-02-01 16:53:07 -0800957
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800958func (m *ModuleBase) baseDepsMutator(ctx BottomUpMutatorContext) {
959 if m.Team() != "" {
960 ctx.AddDependency(ctx.Module(), teamDepTag, m.Team())
961 }
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900962
963 // TODO(jiyong): remove below case. This is to work around build errors happening
964 // on branches with reduced manifest like aosp_kernel-build-tools.
965 // In the branch, a build error occurs as follows.
966 // 1. aosp_kernel-build-tools is a reduced manifest branch. It doesn't have some git
967 // projects like external/bouncycastle
968 // 2. `boot_signer` is `required` by modules like `build_image` which is explicitly list as
969 // the top-level build goal (in the shell file that invokes Soong).
970 // 3. `boot_signer` depends on `bouncycastle-unbundled` which is in the missing git project.
971 // 4. aosp_kernel-build-tools invokes soong with `--skip-make`. Therefore, the absence of
972 // ALLOW_MISSING_DEPENDENCIES didn't cause a problem.
973 // 5. Now, since Soong understands `required` deps, it tries to build `boot_signer` and the
974 // absence of external/bouncycastle fails the build.
975 //
976 // Unfortunately, there's no way for Soong to correctly determine if it's running in a
977 // reduced manifest branch. Instead, here, we use the absence of DeviceArch or DeviceName as
978 // a strong signal, because that's very common across reduced manifest branches.
979 pv := ctx.Config().productVariables
980 fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil
981 if fullManifest {
Jiyong Parkf21dd652024-04-17 05:22:37 +0000982 addRequiredDeps(ctx)
Kiyoung Kimfaf6af32024-08-12 11:15:19 +0900983 addVintfFragmentDeps(ctx)
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900984 }
985}
986
987// addRequiredDeps adds required, target_required, and host_required as dependencies.
Jiyong Parkf21dd652024-04-17 05:22:37 +0000988func addRequiredDeps(ctx BottomUpMutatorContext) {
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900989 addDep := func(target Target, depName string) {
990 if !ctx.OtherModuleExists(depName) {
991 if ctx.Config().AllowMissingDependencies() {
992 return
993 }
994 }
995
996 // If Android native module requires another Android native module, ensure that
997 // they have the same bitness. This mimics the policy in select-bitness-of-required-modules
998 // in build/make/core/main.mk.
999 // TODO(jiyong): the Make-side does this only when the required module is a shared
1000 // library or a native test.
Jiyong Parkf21dd652024-04-17 05:22:37 +00001001 bothInAndroid := ctx.Device() && target.Os.Class == Device
Jiyong Parkc4b1d552024-05-13 16:47:30 +09001002 nativeArch := InList(ctx.Arch().ArchType.Multilib, []string{"lib32", "lib64"}) &&
1003 InList(target.Arch.ArchType.Multilib, []string{"lib32", "lib64"})
Jiyong Parkf21dd652024-04-17 05:22:37 +00001004 sameBitness := ctx.Arch().ArchType.Multilib == target.Arch.ArchType.Multilib
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001005 if bothInAndroid && nativeArch && !sameBitness {
1006 return
1007 }
1008
Jiyong Park8db44152024-05-28 12:22:04 +09001009 // ... also don't make a dependency between native bridge arch and non-native bridge
1010 // arches. b/342945184
1011 if ctx.Target().NativeBridge != target.NativeBridge {
1012 return
1013 }
1014
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001015 variation := target.Variations()
1016 if ctx.OtherModuleFarDependencyVariantExists(variation, depName) {
1017 ctx.AddFarVariationDependencies(variation, RequiredDepTag, depName)
1018 }
1019 }
1020
Jiyong Park73e5bab2024-04-05 13:37:21 +09001021 var deviceTargets []Target
1022 deviceTargets = append(deviceTargets, ctx.Config().Targets[Android]...)
1023 deviceTargets = append(deviceTargets, ctx.Config().AndroidCommonTarget)
1024
1025 var hostTargets []Target
1026 hostTargets = append(hostTargets, ctx.Config().Targets[ctx.Config().BuildOS]...)
1027 hostTargets = append(hostTargets, ctx.Config().BuildOSCommonTarget)
1028
Jiyong Parkf21dd652024-04-17 05:22:37 +00001029 if ctx.Device() {
Cole Faust43ddd082024-06-17 12:32:40 -07001030 for _, depName := range ctx.Module().RequiredModuleNames(ctx) {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001031 for _, target := range deviceTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001032 addDep(target, depName)
1033 }
1034 }
Jiyong Parkf21dd652024-04-17 05:22:37 +00001035 for _, depName := range ctx.Module().HostRequiredModuleNames() {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001036 for _, target := range hostTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001037 addDep(target, depName)
1038 }
1039 }
1040 }
1041
Jiyong Parkf21dd652024-04-17 05:22:37 +00001042 if ctx.Host() {
Cole Faust43ddd082024-06-17 12:32:40 -07001043 for _, depName := range ctx.Module().RequiredModuleNames(ctx) {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001044 for _, target := range hostTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001045 // When a host module requires another host module, don't make a
1046 // dependency if they have different OSes (i.e. hostcross).
Jiyong Parkf21dd652024-04-17 05:22:37 +00001047 if ctx.Target().HostCross != target.HostCross {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001048 continue
1049 }
1050 addDep(target, depName)
1051 }
1052 }
Jiyong Parkf21dd652024-04-17 05:22:37 +00001053 for _, depName := range ctx.Module().TargetRequiredModuleNames() {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001054 for _, target := range deviceTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001055 addDep(target, depName)
1056 }
1057 }
1058 }
Ronald Braunstein73b08ff2023-12-19 10:24:47 -08001059}
1060
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001061var vintfDepTag = struct {
1062 blueprint.BaseDependencyTag
1063 InstallAlwaysNeededDependencyTag
1064}{}
1065
1066func addVintfFragmentDeps(ctx BottomUpMutatorContext) {
Kiyoung Kim55234812024-09-11 17:00:24 +09001067 // Vintf manifests in the recovery partition will be ignored.
1068 if !ctx.Device() || ctx.Module().InstallInRecovery() {
1069 return
1070 }
1071
1072 deviceConfig := ctx.DeviceConfig()
1073
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001074 mod := ctx.Module()
Kiyoung Kim55234812024-09-11 17:00:24 +09001075 vintfModules := ctx.AddDependency(mod, vintfDepTag, mod.VintfFragmentModuleNames(ctx)...)
1076
1077 modPartition := mod.PartitionTag(deviceConfig)
1078 for _, vintf := range vintfModules {
Cole Faust69788792024-10-10 11:00:36 -07001079 if vintf == nil {
1080 // TODO(b/372091092): Remove this. Having it gives us missing dependency errors instead
1081 // of nil pointer dereference errors, but we should resolve the missing dependencies.
1082 continue
1083 }
Kiyoung Kim55234812024-09-11 17:00:24 +09001084 if vintfModule, ok := vintf.(*vintfFragmentModule); ok {
1085 vintfPartition := vintfModule.PartitionTag(deviceConfig)
1086 if modPartition != vintfPartition {
1087 ctx.ModuleErrorf("Module %q(%q) and Vintf_fragment %q(%q) are installed to different partitions.",
1088 mod.Name(), modPartition,
1089 vintfModule.Name(), vintfPartition)
1090 }
1091 } else {
1092 ctx.ModuleErrorf("Only vintf_fragment type module should be listed in vintf_fragment_modules : %q", vintf.Name())
1093 }
1094 }
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001095}
1096
Usta355a5872021-12-01 15:16:32 -05001097// AddProperties "registers" the provided props
1098// each value in props MUST be a pointer to a struct
Colin Cross4157e882019-06-06 16:57:04 -07001099func (m *ModuleBase) AddProperties(props ...interface{}) {
1100 m.registerProps = append(m.registerProps, props...)
Colin Cross36242852017-06-23 15:06:31 -07001101}
1102
Colin Cross4157e882019-06-06 16:57:04 -07001103func (m *ModuleBase) GetProperties() []interface{} {
1104 return m.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -08001105}
1106
Colin Cross4157e882019-06-06 16:57:04 -07001107func (m *ModuleBase) BuildParamsForTests() []BuildParams {
Chih-Hung Hsiehb8082292021-09-09 23:20:39 -07001108 // Expand the references to module variables like $flags[0-9]*,
1109 // so we do not need to change many existing unit tests.
1110 // This looks like undoing the shareFlags optimization in cc's
1111 // transformSourceToObj, and should only affects unit tests.
1112 vars := m.VariablesForTests()
1113 buildParams := append([]BuildParams(nil), m.buildParams...)
Sasha Smundake198eaf2022-08-04 13:07:02 -07001114 for i := range buildParams {
Chih-Hung Hsiehb8082292021-09-09 23:20:39 -07001115 newArgs := make(map[string]string)
1116 for k, v := range buildParams[i].Args {
1117 newArgs[k] = v
1118 // Replaces both ${flags1} and $flags1 syntax.
1119 if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") {
1120 if value, found := vars[v[2:len(v)-1]]; found {
1121 newArgs[k] = value
1122 }
1123 } else if strings.HasPrefix(v, "$") {
1124 if value, found := vars[v[1:]]; found {
1125 newArgs[k] = value
1126 }
1127 }
1128 }
1129 buildParams[i].Args = newArgs
1130 }
1131 return buildParams
Colin Crosscec81712017-07-13 14:43:27 -07001132}
1133
Colin Cross4157e882019-06-06 16:57:04 -07001134func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
1135 return m.ruleParams
Colin Cross4c83e5c2019-02-25 14:54:28 -08001136}
1137
Colin Cross4157e882019-06-06 16:57:04 -07001138func (m *ModuleBase) VariablesForTests() map[string]string {
1139 return m.variables
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001140}
1141
Colin Crossce75d2c2016-10-06 16:12:58 -07001142// Name returns the name of the module. It may be overridden by individual module types, for
1143// example prebuilts will prepend prebuilt_ to the name.
Colin Cross4157e882019-06-06 16:57:04 -07001144func (m *ModuleBase) Name() string {
1145 return String(m.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -07001146}
1147
Colin Cross9a362232019-07-01 15:32:45 -07001148// String returns a string that includes the module name and variants for printing during debugging.
1149func (m *ModuleBase) String() string {
1150 sb := strings.Builder{}
1151 sb.WriteString(m.commonProperties.DebugName)
1152 sb.WriteString("{")
1153 for i := range m.commonProperties.DebugMutators {
1154 if i != 0 {
1155 sb.WriteString(",")
1156 }
1157 sb.WriteString(m.commonProperties.DebugMutators[i])
1158 sb.WriteString(":")
1159 sb.WriteString(m.commonProperties.DebugVariations[i])
1160 }
1161 sb.WriteString("}")
1162 return sb.String()
1163}
1164
Colin Crossce75d2c2016-10-06 16:12:58 -07001165// BaseModuleName returns the name of the module as specified in the blueprints file.
Colin Cross4157e882019-06-06 16:57:04 -07001166func (m *ModuleBase) BaseModuleName() string {
1167 return String(m.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -07001168}
1169
Colin Cross4157e882019-06-06 16:57:04 -07001170func (m *ModuleBase) base() *ModuleBase {
1171 return m
Colin Cross3f40fa42015-01-30 17:27:36 -08001172}
1173
Paul Duffine2453c72019-05-31 14:00:04 +01001174func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName {
1175 return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()}
1176}
1177
1178func (m *ModuleBase) visibilityProperties() []visibilityProperty {
Paul Duffin63c6e182019-07-24 14:24:38 +01001179 return m.visibilityPropertyInfo
1180}
1181
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001182func (m *ModuleBase) Dists() []Dist {
Paul Duffined875132020-09-02 13:08:57 +01001183 if len(m.distProperties.Dist.Targets) > 0 {
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001184 // Make a copy of the underlying Dists slice to protect against
1185 // backing array modifications with repeated calls to this method.
Paul Duffined875132020-09-02 13:08:57 +01001186 distsCopy := append([]Dist(nil), m.distProperties.Dists...)
1187 return append(distsCopy, m.distProperties.Dist)
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001188 } else {
Paul Duffined875132020-09-02 13:08:57 +01001189 return m.distProperties.Dists
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001190 }
1191}
1192
1193func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFiles {
Paul Duffin74f05592020-11-25 16:37:46 +00001194 var distFiles TaggedDistFiles
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001195 for _, dist := range m.Dists() {
Paul Duffin74f05592020-11-25 16:37:46 +00001196 // If no tag is specified then it means to use the default dist paths so use
1197 // the special tag name which represents that.
1198 tag := proptools.StringDefault(dist.Tag, DefaultDistTag)
1199
mrziwangabdb2932024-06-18 12:43:41 -07001200 distFileForTagFromProvider, err := outputFilesForModuleFromProvider(ctx, m.module, tag)
1201 if err != OutputFilesProviderNotSet {
1202 if err != nil && tag != DefaultDistTag {
1203 ctx.PropertyErrorf("dist.tag", "%s", err.Error())
1204 } else {
1205 distFiles = distFiles.addPathsForTag(tag, distFileForTagFromProvider...)
1206 continue
1207 }
1208 }
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001209 }
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001210 return distFiles
1211}
1212
Cole Faust02987bd2024-03-21 17:58:43 -07001213func (m *ModuleBase) ArchReady() bool {
1214 return m.commonProperties.ArchReady
1215}
1216
Colin Cross4157e882019-06-06 16:57:04 -07001217func (m *ModuleBase) Target() Target {
1218 return m.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -08001219}
1220
Colin Cross4157e882019-06-06 16:57:04 -07001221func (m *ModuleBase) TargetPrimary() bool {
1222 return m.commonProperties.CompilePrimary
Colin Cross8b74d172016-09-13 09:59:14 -07001223}
1224
Colin Cross4157e882019-06-06 16:57:04 -07001225func (m *ModuleBase) MultiTargets() []Target {
1226 return m.commonProperties.CompileMultiTargets
Colin Crossee0bc3b2018-10-02 22:01:37 -07001227}
1228
Colin Cross4157e882019-06-06 16:57:04 -07001229func (m *ModuleBase) Os() OsType {
1230 return m.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -08001231}
1232
Colin Cross4157e882019-06-06 16:57:04 -07001233func (m *ModuleBase) Host() bool {
Jiyong Park1613e552020-09-14 19:43:17 +09001234 return m.Os().Class == Host
Dan Willemsen97750522016-02-09 17:43:51 -08001235}
1236
Yo Chiangbba545e2020-06-09 16:15:37 +08001237func (m *ModuleBase) Device() bool {
1238 return m.Os().Class == Device
1239}
1240
Colin Cross4157e882019-06-06 16:57:04 -07001241func (m *ModuleBase) Arch() Arch {
1242 return m.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -08001243}
1244
Colin Cross4157e882019-06-06 16:57:04 -07001245func (m *ModuleBase) ArchSpecific() bool {
1246 return m.commonProperties.ArchSpecific
Dan Willemsen0b24c742016-10-04 15:13:37 -07001247}
1248
Paul Duffin1356d8c2020-02-25 19:26:33 +00001249// True if the current variant is a CommonOS variant, false otherwise.
1250func (m *ModuleBase) IsCommonOSVariant() bool {
Colin Cross8bbc3d52024-09-11 15:33:54 -07001251 return m.commonProperties.CompileOS == CommonOS
Paul Duffin1356d8c2020-02-25 19:26:33 +00001252}
1253
Colin Cross34037c62020-11-17 13:19:17 -08001254// supportsTarget returns true if the given Target is supported by the current module.
1255func (m *ModuleBase) supportsTarget(target Target) bool {
1256 switch target.Os.Class {
1257 case Host:
1258 if target.HostCross {
1259 return m.HostCrossSupported()
1260 } else {
1261 return m.HostSupported()
Colin Crossa1ad8d12016-06-01 17:09:44 -07001262 }
Colin Cross34037c62020-11-17 13:19:17 -08001263 case Device:
1264 return m.DeviceSupported()
Colin Crossa1ad8d12016-06-01 17:09:44 -07001265 default:
Jiyong Park1613e552020-09-14 19:43:17 +09001266 return false
Colin Crossa1ad8d12016-06-01 17:09:44 -07001267 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001268}
1269
Colin Cross34037c62020-11-17 13:19:17 -08001270// DeviceSupported returns true if the current module is supported and enabled for device targets,
1271// i.e. the factory method set the HostOrDeviceSupported value to include device support and
1272// the device support is enabled by default or enabled by the device_supported property.
Colin Cross4157e882019-06-06 16:57:04 -07001273func (m *ModuleBase) DeviceSupported() bool {
Colin Cross34037c62020-11-17 13:19:17 -08001274 hod := m.commonProperties.HostOrDeviceSupported
1275 // deviceEnabled is true if the device_supported property is true or the HostOrDeviceSupported
1276 // value has the deviceDefault bit set.
1277 deviceEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Device_supported, hod&deviceDefault != 0)
1278 return hod&deviceSupported != 0 && deviceEnabled
Colin Cross3f40fa42015-01-30 17:27:36 -08001279}
1280
Colin Cross34037c62020-11-17 13:19:17 -08001281// HostSupported returns true if the current module is supported and enabled for host targets,
1282// i.e. the factory method set the HostOrDeviceSupported value to include host support and
1283// the host support is enabled by default or enabled by the host_supported property.
Paul Duffine44358f2019-11-26 18:04:12 +00001284func (m *ModuleBase) HostSupported() bool {
Colin Cross34037c62020-11-17 13:19:17 -08001285 hod := m.commonProperties.HostOrDeviceSupported
1286 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1287 // value has the hostDefault bit set.
1288 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
1289 return hod&hostSupported != 0 && hostEnabled
1290}
1291
1292// HostCrossSupported returns true if the current module is supported and enabled for host cross
1293// targets, i.e. the factory method set the HostOrDeviceSupported value to include host cross
1294// support and the host cross support is enabled by default or enabled by the
1295// host_supported property.
1296func (m *ModuleBase) HostCrossSupported() bool {
1297 hod := m.commonProperties.HostOrDeviceSupported
1298 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1299 // value has the hostDefault bit set.
1300 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
Ivan Lozanoc7eafa72024-07-16 17:55:33 +00001301
1302 // Default true for the Host_cross_supported property
1303 hostCrossEnabled := proptools.BoolDefault(m.hostCrossProperties.Host_cross_supported, true)
1304
1305 return hod&hostCrossSupported != 0 && hostEnabled && hostCrossEnabled
Paul Duffine44358f2019-11-26 18:04:12 +00001306}
1307
Colin Cross4157e882019-06-06 16:57:04 -07001308func (m *ModuleBase) Platform() bool {
Justin Yund5f6c822019-06-25 16:47:17 +09001309 return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.SystemExtSpecific()
Jiyong Parkc678ad32018-04-10 13:07:10 +09001310}
1311
Colin Cross4157e882019-06-06 16:57:04 -07001312func (m *ModuleBase) DeviceSpecific() bool {
1313 return Bool(m.commonProperties.Device_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001314}
1315
Colin Cross4157e882019-06-06 16:57:04 -07001316func (m *ModuleBase) SocSpecific() bool {
1317 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001318}
1319
Colin Cross4157e882019-06-06 16:57:04 -07001320func (m *ModuleBase) ProductSpecific() bool {
1321 return Bool(m.commonProperties.Product_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001322}
1323
Justin Yund5f6c822019-06-25 16:47:17 +09001324func (m *ModuleBase) SystemExtSpecific() bool {
1325 return Bool(m.commonProperties.System_ext_specific)
Dario Frenifd05a742018-05-29 13:28:54 +01001326}
1327
Colin Crossc2d24052020-05-13 11:05:02 -07001328// RequiresStableAPIs returns true if the module will be installed to a partition that may
1329// be updated separately from the system image.
1330func (m *ModuleBase) RequiresStableAPIs(ctx BaseModuleContext) bool {
1331 return m.SocSpecific() || m.DeviceSpecific() ||
1332 (m.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface())
1333}
1334
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001335func (m *ModuleBase) PartitionTag(config DeviceConfig) string {
1336 partition := "system"
1337 if m.SocSpecific() {
1338 // A SoC-specific module could be on the vendor partition at
1339 // "vendor" or the system partition at "system/vendor".
1340 if config.VendorPath() == "vendor" {
1341 partition = "vendor"
1342 }
1343 } else if m.DeviceSpecific() {
1344 // A device-specific module could be on the odm partition at
1345 // "odm", the vendor partition at "vendor/odm", or the system
1346 // partition at "system/vendor/odm".
1347 if config.OdmPath() == "odm" {
1348 partition = "odm"
Ramy Medhat944839a2020-03-31 22:14:52 -04001349 } else if strings.HasPrefix(config.OdmPath(), "vendor/") {
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001350 partition = "vendor"
1351 }
1352 } else if m.ProductSpecific() {
1353 // A product-specific module could be on the product partition
1354 // at "product" or the system partition at "system/product".
1355 if config.ProductPath() == "product" {
1356 partition = "product"
1357 }
1358 } else if m.SystemExtSpecific() {
1359 // A system_ext-specific module could be on the system_ext
1360 // partition at "system_ext" or the system partition at
1361 // "system/system_ext".
1362 if config.SystemExtPath() == "system_ext" {
1363 partition = "system_ext"
1364 }
1365 }
1366 return partition
1367}
1368
Cole Fauste8a87832024-09-11 11:35:46 -07001369func (m *ModuleBase) Enabled(ctx ConfigurableEvaluatorContext) bool {
Justin Yun32f053b2020-07-31 23:07:17 +09001370 if m.commonProperties.ForcedDisabled {
1371 return false
1372 }
Cole Fausta963b942024-04-11 17:43:00 -07001373 return m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled)
Colin Cross3f40fa42015-01-30 17:27:36 -08001374}
1375
Cole Faust8eeae4b2024-09-12 11:51:04 -07001376// Returns a copy of the enabled property, useful for passing it on to sub-modules
1377func (m *ModuleBase) EnabledProperty() proptools.Configurable[bool] {
1378 if m.commonProperties.ForcedDisabled {
1379 return proptools.NewSimpleConfigurable(false)
1380 }
1381 return m.commonProperties.Enabled.Clone()
1382}
1383
Inseob Kimeec88e12020-01-22 11:11:29 +09001384func (m *ModuleBase) Disable() {
Justin Yun32f053b2020-07-31 23:07:17 +09001385 m.commonProperties.ForcedDisabled = true
Inseob Kimeec88e12020-01-22 11:11:29 +09001386}
1387
Colin Crossa9c8c9f2020-12-16 10:20:23 -08001388// HideFromMake marks this variant so that it is not emitted in the generated Android.mk file.
1389func (m *ModuleBase) HideFromMake() {
1390 m.commonProperties.HideFromMake = true
1391}
1392
1393// IsHideFromMake returns true if HideFromMake was previously called.
1394func (m *ModuleBase) IsHideFromMake() bool {
1395 return m.commonProperties.HideFromMake == true
1396}
1397
1398// SkipInstall marks this variant to not create install rules when ctx.Install* are called.
Colin Cross4157e882019-06-06 16:57:04 -07001399func (m *ModuleBase) SkipInstall() {
1400 m.commonProperties.SkipInstall = true
Colin Crossce75d2c2016-10-06 16:12:58 -07001401}
1402
Martin Stjernholm9e7f45e2020-12-23 03:50:30 +00001403// IsSkipInstall returns true if this variant is marked to not create install
1404// rules when ctx.Install* are called.
1405func (m *ModuleBase) IsSkipInstall() bool {
1406 return m.commonProperties.SkipInstall
1407}
1408
Iván Budnik295da162023-03-10 16:11:26 +00001409// Similar to HideFromMake, but if the AndroidMk entry would set
1410// LOCAL_UNINSTALLABLE_MODULE then this variant may still output that entry
1411// rather than leaving it out altogether. That happens in cases where it would
1412// have other side effects, in particular when it adds a NOTICE file target,
1413// which other install targets might depend on.
1414func (m *ModuleBase) MakeUninstallable() {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001415 m.commonProperties.UninstallableApexPlatformVariant = true
Iván Budnik295da162023-03-10 16:11:26 +00001416 m.HideFromMake()
1417}
1418
Liz Kammer5ca3a622020-08-05 15:40:41 -07001419func (m *ModuleBase) ReplacedByPrebuilt() {
1420 m.commonProperties.ReplacedByPrebuilt = true
Colin Crossa9c8c9f2020-12-16 10:20:23 -08001421 m.HideFromMake()
Liz Kammer5ca3a622020-08-05 15:40:41 -07001422}
1423
1424func (m *ModuleBase) IsReplacedByPrebuilt() bool {
1425 return m.commonProperties.ReplacedByPrebuilt
1426}
1427
Colin Cross4157e882019-06-06 16:57:04 -07001428func (m *ModuleBase) ExportedToMake() bool {
1429 return m.commonProperties.NamespaceExportedToMake
Jiyong Park374510b2018-03-19 18:23:01 +09001430}
1431
Justin Yun1871f902023-04-07 20:13:19 +09001432func (m *ModuleBase) EffectiveLicenseKinds() []string {
1433 return m.commonProperties.Effective_license_kinds
1434}
1435
Justin Yun885a7de2021-06-29 20:34:53 +09001436func (m *ModuleBase) EffectiveLicenseFiles() Paths {
Bob Badour4101c712022-02-09 11:54:35 -08001437 result := make(Paths, 0, len(m.commonProperties.Effective_license_text))
1438 for _, p := range m.commonProperties.Effective_license_text {
1439 result = append(result, p.Path)
1440 }
1441 return result
Justin Yun885a7de2021-06-29 20:34:53 +09001442}
1443
Colin Crosse9fe2942020-11-10 18:12:15 -08001444// computeInstallDeps finds the installed paths of all dependencies that have a dependency
Colin Crossbd3a16b2023-04-25 11:30:51 -07001445// tag that is annotated as needing installation via the isInstallDepNeeded method.
Colin Crossa14fb6a2024-10-23 16:57:06 -07001446func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]depset.DepSet[InstallPath], []depset.DepSet[PackagingSpec]) {
1447 var installDeps []depset.DepSet[InstallPath]
1448 var packagingSpecs []depset.DepSet[PackagingSpec]
Colin Cross5d583952020-11-24 16:21:24 -08001449 ctx.VisitDirectDeps(func(dep Module) {
Jiyong Park1d4907e2024-05-15 02:09:42 +09001450 if isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001451 // Installation is still handled by Make, so anything hidden from Make is not
1452 // installable.
Yu Liubad1eef2024-08-21 22:37:35 +00001453 info := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider)
Colin Crossbd3a16b2023-04-25 11:30:51 -07001454 if !dep.IsHideFromMake() && !dep.IsSkipInstall() {
Yu Liubad1eef2024-08-21 22:37:35 +00001455 installDeps = append(installDeps, info.TransitiveInstallFiles)
Colin Crossbd3a16b2023-04-25 11:30:51 -07001456 }
1457 // Add packaging deps even when the dependency is not installed so that uninstallable
1458 // modules can still be packaged. Often the package will be installed instead.
Yu Liubad1eef2024-08-21 22:37:35 +00001459 packagingSpecs = append(packagingSpecs, info.TransitivePackagingSpecs)
Colin Cross897266e2020-02-13 13:22:08 -08001460 }
1461 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001462
Colin Crossffe6b9d2020-12-01 15:40:06 -08001463 return installDeps, packagingSpecs
Colin Cross3f40fa42015-01-30 17:27:36 -08001464}
1465
Colin Crossbd3a16b2023-04-25 11:30:51 -07001466// isInstallDepNeeded returns true if installing the output files of the current module
1467// should also install the output files of the given dependency and dependency tag.
1468func isInstallDepNeeded(dep Module, tag blueprint.DependencyTag) bool {
1469 // Don't add a dependency from the platform to a library provided by an apex.
1470 if dep.base().commonProperties.UninstallableApexPlatformVariant {
1471 return false
1472 }
1473 // Only install modules if the dependency tag is an InstallDepNeeded tag.
1474 return IsInstallDepNeededTag(tag)
1475}
1476
Colin Cross4157e882019-06-06 16:57:04 -07001477func (m *ModuleBase) NoAddressSanitizer() bool {
1478 return m.noAddressSanitizer
Colin Cross3f40fa42015-01-30 17:27:36 -08001479}
1480
Colin Cross4157e882019-06-06 16:57:04 -07001481func (m *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -08001482 return false
1483}
1484
Jaewoong Jung0949f312019-09-11 10:25:18 -07001485func (m *ModuleBase) InstallInTestcases() bool {
1486 return false
1487}
1488
Colin Cross4157e882019-06-06 16:57:04 -07001489func (m *ModuleBase) InstallInSanitizerDir() bool {
Vishwath Mohan1dd88392017-03-29 22:00:18 -07001490 return false
1491}
1492
Yifan Hong1b3348d2020-01-21 15:53:22 -08001493func (m *ModuleBase) InstallInRamdisk() bool {
1494 return Bool(m.commonProperties.Ramdisk)
1495}
1496
Yifan Hong60e0cfb2020-10-21 15:17:56 -07001497func (m *ModuleBase) InstallInVendorRamdisk() bool {
1498 return Bool(m.commonProperties.Vendor_ramdisk)
1499}
1500
Inseob Kim08758f02021-04-08 21:13:22 +09001501func (m *ModuleBase) InstallInDebugRamdisk() bool {
1502 return Bool(m.commonProperties.Debug_ramdisk)
1503}
1504
Colin Cross4157e882019-06-06 16:57:04 -07001505func (m *ModuleBase) InstallInRecovery() bool {
1506 return Bool(m.commonProperties.Recovery)
Jiyong Parkf9332f12018-02-01 00:54:12 +09001507}
1508
Colin Crossea30d852023-11-29 16:00:16 -08001509func (m *ModuleBase) InstallInOdm() bool {
1510 return false
1511}
1512
1513func (m *ModuleBase) InstallInProduct() bool {
1514 return false
1515}
1516
Kiyoung Kimae11c232021-07-19 11:38:04 +09001517func (m *ModuleBase) InstallInVendor() bool {
Kiyoung Kimf160f7f2022-11-29 10:58:08 +09001518 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Soc_specific) || Bool(m.commonProperties.Proprietary)
Kiyoung Kimae11c232021-07-19 11:38:04 +09001519}
1520
Spandan Das950deca2024-10-01 18:35:23 +00001521func (m *ModuleBase) InstallInSystemExt() bool {
1522 return Bool(m.commonProperties.System_ext_specific)
1523}
1524
Colin Cross90ba5f42019-10-02 11:10:58 -07001525func (m *ModuleBase) InstallInRoot() bool {
1526 return false
1527}
1528
Jiyong Park87788b52020-09-01 12:37:45 +09001529func (m *ModuleBase) InstallForceOS() (*OsType, *ArchType) {
1530 return nil, nil
Colin Cross6e359402020-02-10 15:29:54 -08001531}
1532
Colin Cross4157e882019-06-06 16:57:04 -07001533func (m *ModuleBase) Owner() string {
1534 return String(m.commonProperties.Owner)
Sundong Ahn4fd04bb2018-08-31 18:01:37 +09001535}
1536
Ronald Braunstein73b08ff2023-12-19 10:24:47 -08001537func (m *ModuleBase) Team() string {
1538 return String(m.commonProperties.Team)
1539}
1540
Colin Cross7228ecd2019-11-18 16:00:16 -08001541func (m *ModuleBase) setImageVariation(variant string) {
1542 m.commonProperties.ImageVariation = variant
1543}
1544
1545func (m *ModuleBase) ImageVariation() blueprint.Variation {
1546 return blueprint.Variation{
1547 Mutator: "image",
1548 Variation: m.base().commonProperties.ImageVariation,
1549 }
1550}
1551
Paul Duffin9b76c0b2020-03-12 10:24:35 +00001552func (m *ModuleBase) getVariationByMutatorName(mutator string) string {
1553 for i, v := range m.commonProperties.DebugMutators {
1554 if v == mutator {
1555 return m.commonProperties.DebugVariations[i]
1556 }
1557 }
1558
1559 return ""
1560}
1561
Yifan Hong1b3348d2020-01-21 15:53:22 -08001562func (m *ModuleBase) InRamdisk() bool {
1563 return m.base().commonProperties.ImageVariation == RamdiskVariation
1564}
1565
Yifan Hong60e0cfb2020-10-21 15:17:56 -07001566func (m *ModuleBase) InVendorRamdisk() bool {
1567 return m.base().commonProperties.ImageVariation == VendorRamdiskVariation
1568}
1569
Inseob Kim08758f02021-04-08 21:13:22 +09001570func (m *ModuleBase) InDebugRamdisk() bool {
1571 return m.base().commonProperties.ImageVariation == DebugRamdiskVariation
1572}
1573
Colin Cross7228ecd2019-11-18 16:00:16 -08001574func (m *ModuleBase) InRecovery() bool {
1575 return m.base().commonProperties.ImageVariation == RecoveryVariation
1576}
1577
Cole Fauste8a87832024-09-11 11:35:46 -07001578func (m *ModuleBase) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string {
Cole Faust43ddd082024-06-17 12:32:40 -07001579 return m.base().commonProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09001580}
1581
1582func (m *ModuleBase) HostRequiredModuleNames() []string {
1583 return m.base().commonProperties.Host_required
1584}
1585
1586func (m *ModuleBase) TargetRequiredModuleNames() []string {
1587 return m.base().commonProperties.Target_required
1588}
1589
Cole Fauste8a87832024-09-11 11:35:46 -07001590func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string {
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001591 return m.base().commonProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
1592}
1593
Colin Crossa6182ab2024-08-21 10:47:44 -07001594func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) {
1595 namespacePrefix := ctx.Namespace().id
1596 if namespacePrefix != "" {
1597 namespacePrefix = namespacePrefix + "-"
1598 }
1599
1600 if !ctx.uncheckedModule {
1601 name := namespacePrefix + ctx.ModuleName() + "-" + ctx.ModuleSubDir() + "-checkbuild"
1602 ctx.Phony(name, ctx.checkbuildFiles...)
1603 ctx.checkbuildTarget = PathForPhony(ctx, name)
1604 }
1605
1606}
1607
Yu Liuddc28332024-08-09 22:48:30 +00001608func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) {
Colin Cross897266e2020-02-13 13:22:08 -08001609 var allInstalledFiles InstallPaths
Colin Crossa6182ab2024-08-21 10:47:44 -07001610 var allCheckbuildTargets Paths
Colin Cross0875c522017-11-28 17:34:01 -08001611 ctx.VisitAllModuleVariants(func(module Module) {
1612 a := module.base()
Colin Crossa6182ab2024-08-21 10:47:44 -07001613 var checkbuildTarget Path
1614 var uncheckedModule bool
Yu Liuddc28332024-08-09 22:48:30 +00001615 if a == m {
1616 allInstalledFiles = append(allInstalledFiles, ctx.installFiles...)
Colin Crossa6182ab2024-08-21 10:47:44 -07001617 checkbuildTarget = ctx.checkbuildTarget
1618 uncheckedModule = ctx.uncheckedModule
Yu Liuddc28332024-08-09 22:48:30 +00001619 } else {
Yu Liud46e5ae2024-08-15 18:46:17 +00001620 info := OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider)
1621 allInstalledFiles = append(allInstalledFiles, info.InstallFiles...)
Colin Crossa6182ab2024-08-21 10:47:44 -07001622 checkbuildTarget = info.CheckbuildTarget
1623 uncheckedModule = info.UncheckedModule
Yu Liuddc28332024-08-09 22:48:30 +00001624 }
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07001625 // A module's -checkbuild phony targets should
Chih-Hung Hsieha3d135b2021-10-14 20:32:53 -07001626 // not be created if the module is not exported to make.
1627 // Those could depend on the build target and fail to compile
1628 // for the current build target.
Colin Crossa6182ab2024-08-21 10:47:44 -07001629 if (!ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, a)) && !uncheckedModule && checkbuildTarget != nil {
1630 allCheckbuildTargets = append(allCheckbuildTargets, checkbuildTarget)
Chih-Hung Hsieha3d135b2021-10-14 20:32:53 -07001631 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001632 })
1633
Colin Cross0875c522017-11-28 17:34:01 -08001634 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -07001635
Yu Liu460c0fa2024-08-20 19:31:15 +00001636 var namespacePrefix string
1637 nameSpace := ctx.Namespace().Path
1638 if nameSpace != "." {
1639 namespacePrefix = strings.ReplaceAll(nameSpace, "/", ".") + "-"
Jeff Gaston088e29e2017-11-29 16:47:17 -08001640 }
1641
Yu Liuddc2e1a2024-08-20 21:31:22 +00001642 var info FinalModuleBuildTargetsInfo
1643
Colin Cross3f40fa42015-01-30 17:27:36 -08001644 if len(allInstalledFiles) > 0 {
Colin Crossc3d87d32020-06-04 13:25:17 -07001645 name := namespacePrefix + ctx.ModuleName() + "-install"
1646 ctx.Phony(name, allInstalledFiles.Paths()...)
Yu Liuddc2e1a2024-08-20 21:31:22 +00001647 info.InstallTarget = PathForPhony(ctx, name)
1648 deps = append(deps, info.InstallTarget)
Colin Cross9454bfa2015-03-17 13:24:18 -07001649 }
1650
Colin Crossa6182ab2024-08-21 10:47:44 -07001651 if len(allCheckbuildTargets) > 0 {
Colin Crossc3d87d32020-06-04 13:25:17 -07001652 name := namespacePrefix + ctx.ModuleName() + "-checkbuild"
Colin Crossa6182ab2024-08-21 10:47:44 -07001653 ctx.Phony(name, allCheckbuildTargets...)
1654 deps = append(deps, PathForPhony(ctx, name))
Colin Cross9454bfa2015-03-17 13:24:18 -07001655 }
1656
1657 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001658 suffix := ""
Jingwen Chencda22c92020-11-23 00:22:30 -05001659 if ctx.Config().KatiEnabled() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001660 suffix = "-soong"
1661 }
1662
Colin Crossc3d87d32020-06-04 13:25:17 -07001663 ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001664
Yu Liuddc2e1a2024-08-20 21:31:22 +00001665 info.BlueprintDir = ctx.ModuleDir()
1666 SetProvider(ctx, FinalModuleBuildTargetsProvider, info)
Colin Cross3f40fa42015-01-30 17:27:36 -08001667 }
1668}
1669
Colin Crossc34d2322020-01-03 15:23:27 -08001670func determineModuleKind(m *ModuleBase, ctx blueprint.EarlyModuleContext) moduleKind {
Colin Cross4157e882019-06-06 16:57:04 -07001671 var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
1672 var deviceSpecific = Bool(m.commonProperties.Device_specific)
1673 var productSpecific = Bool(m.commonProperties.Product_specific)
Justin Yund5f6c822019-06-25 16:47:17 +09001674 var systemExtSpecific = Bool(m.commonProperties.System_ext_specific)
Jiyong Park2db76922017-11-08 16:03:48 +09001675
Dario Frenifd05a742018-05-29 13:28:54 +01001676 msg := "conflicting value set here"
1677 if socSpecific && deviceSpecific {
1678 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
Colin Cross4157e882019-06-06 16:57:04 -07001679 if Bool(m.commonProperties.Vendor) {
Jiyong Park2db76922017-11-08 16:03:48 +09001680 ctx.PropertyErrorf("vendor", msg)
1681 }
Colin Cross4157e882019-06-06 16:57:04 -07001682 if Bool(m.commonProperties.Proprietary) {
Jiyong Park2db76922017-11-08 16:03:48 +09001683 ctx.PropertyErrorf("proprietary", msg)
1684 }
Colin Cross4157e882019-06-06 16:57:04 -07001685 if Bool(m.commonProperties.Soc_specific) {
Jiyong Park2db76922017-11-08 16:03:48 +09001686 ctx.PropertyErrorf("soc_specific", msg)
1687 }
1688 }
1689
Justin Yund5f6c822019-06-25 16:47:17 +09001690 if productSpecific && systemExtSpecific {
1691 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and system_ext at the same time.")
1692 ctx.PropertyErrorf("system_ext_specific", msg)
Dario Frenifd05a742018-05-29 13:28:54 +01001693 }
1694
Justin Yund5f6c822019-06-25 16:47:17 +09001695 if (socSpecific || deviceSpecific) && (productSpecific || systemExtSpecific) {
Dario Frenifd05a742018-05-29 13:28:54 +01001696 if productSpecific {
1697 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
1698 } else {
Justin Yund5f6c822019-06-25 16:47:17 +09001699 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 +01001700 }
1701 if deviceSpecific {
1702 ctx.PropertyErrorf("device_specific", msg)
1703 } else {
Colin Cross4157e882019-06-06 16:57:04 -07001704 if Bool(m.commonProperties.Vendor) {
Dario Frenifd05a742018-05-29 13:28:54 +01001705 ctx.PropertyErrorf("vendor", msg)
1706 }
Colin Cross4157e882019-06-06 16:57:04 -07001707 if Bool(m.commonProperties.Proprietary) {
Dario Frenifd05a742018-05-29 13:28:54 +01001708 ctx.PropertyErrorf("proprietary", msg)
1709 }
Colin Cross4157e882019-06-06 16:57:04 -07001710 if Bool(m.commonProperties.Soc_specific) {
Dario Frenifd05a742018-05-29 13:28:54 +01001711 ctx.PropertyErrorf("soc_specific", msg)
1712 }
1713 }
1714 }
1715
Jiyong Park2db76922017-11-08 16:03:48 +09001716 if productSpecific {
1717 return productSpecificModule
Justin Yund5f6c822019-06-25 16:47:17 +09001718 } else if systemExtSpecific {
1719 return systemExtSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +09001720 } else if deviceSpecific {
1721 return deviceSpecificModule
1722 } else if socSpecific {
1723 return socSpecificModule
1724 } else {
1725 return platformModule
1726 }
1727}
1728
Colin Crossc34d2322020-01-03 15:23:27 -08001729func (m *ModuleBase) earlyModuleContextFactory(ctx blueprint.EarlyModuleContext) earlyModuleContext {
Colin Cross1184b642019-12-30 18:43:07 -08001730 return earlyModuleContext{
Colin Crossc34d2322020-01-03 15:23:27 -08001731 EarlyModuleContext: ctx,
1732 kind: determineModuleKind(m, ctx),
1733 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -08001734 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001735}
1736
Colin Cross1184b642019-12-30 18:43:07 -08001737func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext {
1738 return baseModuleContext{
1739 bp: ctx,
Colin Cross1d3d9f12024-01-18 14:30:22 -08001740 archModuleContext: m.archModuleContextFactory(ctx),
Colin Cross1184b642019-12-30 18:43:07 -08001741 earlyModuleContext: m.earlyModuleContextFactory(ctx),
Colin Cross1184b642019-12-30 18:43:07 -08001742 }
1743}
1744
Colin Crosse1a85552024-06-14 12:17:37 -07001745type archModuleContextFactoryContext interface {
1746 Config() interface{}
1747}
1748
1749func (m *ModuleBase) archModuleContextFactory(ctx archModuleContextFactoryContext) archModuleContext {
Colin Cross1d3d9f12024-01-18 14:30:22 -08001750 config := ctx.Config().(Config)
1751 target := m.Target()
1752 primaryArch := false
1753 if len(config.Targets[target.Os]) <= 1 {
1754 primaryArch = true
1755 } else {
1756 primaryArch = target.Arch.ArchType == config.Targets[target.Os][0].Arch.ArchType
1757 }
1758
1759 return archModuleContext{
Cole Faust0aa21cc2024-03-20 12:28:03 -07001760 ready: m.commonProperties.ArchReady,
Colin Cross1d3d9f12024-01-18 14:30:22 -08001761 os: m.commonProperties.CompileOS,
1762 target: m.commonProperties.CompileTarget,
1763 targetPrimary: m.commonProperties.CompilePrimary,
1764 multiTargets: m.commonProperties.CompileMultiTargets,
1765 primaryArch: primaryArch,
1766 }
1767
1768}
1769
Yu Liuddc28332024-08-09 22:48:30 +00001770type InstallFilesInfo struct {
Colin Crossa6182ab2024-08-21 10:47:44 -07001771 InstallFiles InstallPaths
1772 CheckbuildFiles Paths
1773 CheckbuildTarget Path
1774 UncheckedModule bool
1775 PackagingSpecs []PackagingSpec
Yu Liud46e5ae2024-08-15 18:46:17 +00001776 // katiInstalls tracks the install rules that were created by Soong but are being exported
1777 // to Make to convert to ninja rules so that Make can add additional dependencies.
Yu Liuec810542024-08-26 18:09:15 +00001778 KatiInstalls katiInstalls
1779 KatiSymlinks katiInstalls
1780 TestData []DataPath
Colin Crossa14fb6a2024-10-23 16:57:06 -07001781 TransitivePackagingSpecs depset.DepSet[PackagingSpec]
Yu Liuec810542024-08-26 18:09:15 +00001782 LicenseMetadataFile WritablePath
1783
1784 // The following fields are private before, make it private again once we have
1785 // better solution.
Colin Crossa14fb6a2024-10-23 16:57:06 -07001786 TransitiveInstallFiles depset.DepSet[InstallPath]
Yu Liu82a6d142024-08-27 19:02:29 +00001787 // katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
1788 // allowed to have duplicates across modules and variants.
1789 KatiInitRcInstalls katiInstalls
1790 KatiVintfInstalls katiInstalls
1791 InitRcPaths Paths
1792 VintfFragmentsPaths Paths
1793 InstalledInitRcPaths InstallPaths
1794 InstalledVintfFragmentsPaths InstallPaths
1795
Yu Liuec810542024-08-26 18:09:15 +00001796 // The files to copy to the dist as explicitly specified in the .bp file.
1797 DistFiles TaggedDistFiles
Yu Liuddc28332024-08-09 22:48:30 +00001798}
1799
Yu Liubad1eef2024-08-21 22:37:35 +00001800var InstallFilesProvider = blueprint.NewProvider[InstallFilesInfo]()
Yu Liuddc2e1a2024-08-20 21:31:22 +00001801
1802type FinalModuleBuildTargetsInfo struct {
1803 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
1804 // Only set on the final variant of each module
1805 InstallTarget WritablePath
1806 CheckbuildTarget WritablePath
1807 BlueprintDir string
1808}
1809
Yu Liubad1eef2024-08-21 22:37:35 +00001810var FinalModuleBuildTargetsProvider = blueprint.NewProvider[FinalModuleBuildTargetsInfo]()
Yu Liuddc28332024-08-09 22:48:30 +00001811
Yu Liudd9ccb42024-10-07 17:07:44 +00001812type CommonPropertiesProviderData struct {
1813 Enabled bool
1814 // Whether the module has been replaced by a prebuilt
1815 ReplacedByPrebuilt bool
1816}
1817
1818var CommonPropertiesProviderKey = blueprint.NewProvider[CommonPropertiesProviderData]()
1819
1820type PrebuiltModuleProviderData struct {
1821 // Empty for now
1822}
1823
1824var PrebuiltModuleProviderKey = blueprint.NewProvider[PrebuiltModuleProviderData]()
1825
1826type HostToolProviderData struct {
1827 HostToolPath OptionalPath
1828}
1829
1830var HostToolProviderKey = blueprint.NewProvider[HostToolProviderData]()
1831
Colin Cross4157e882019-06-06 16:57:04 -07001832func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
Colin Cross25de6c32019-06-06 14:29:25 -07001833 ctx := &moduleContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -07001834 module: m.module,
Colin Crossdc35e212019-06-06 16:13:11 -07001835 bp: blueprintCtx,
Colin Cross0ea8ba82019-06-06 14:33:29 -07001836 baseModuleContext: m.baseModuleContextFactory(blueprintCtx),
Colin Cross0ea8ba82019-06-06 14:33:29 -07001837 variables: make(map[string]string),
Yu Liu54513622024-08-19 20:00:32 +00001838 phonies: make(map[string]Paths),
Colin Cross3f40fa42015-01-30 17:27:36 -08001839 }
1840
Jihoon Kangc3d4e112024-06-24 22:16:27 +00001841 setContainerInfo(ctx)
Jihoon Kang85bc1932024-07-01 17:04:46 +00001842 if ctx.Config().Getenv("DISABLE_CONTAINER_CHECK") != "true" {
1843 checkContainerViolations(ctx)
1844 }
Jihoon Kangc3d4e112024-06-24 22:16:27 +00001845
Yu Liuec810542024-08-26 18:09:15 +00001846 ctx.licenseMetadataFile = PathForModuleOut(ctx, "meta_lic")
Colin Crossaa1cab02022-01-28 14:49:24 -08001847
Colin Crossffe6b9d2020-12-01 15:40:06 -08001848 dependencyInstallFiles, dependencyPackagingSpecs := m.computeInstallDeps(ctx)
Yu Liubad1eef2024-08-21 22:37:35 +00001849 // set the TransitiveInstallFiles to only the transitive dependencies to be used as the dependencies
Colin Cross5d583952020-11-24 16:21:24 -08001850 // of installed files of this module. It will be replaced by a depset including the installed
1851 // files of this module at the end for use by modules that depend on this one.
Colin Crossa14fb6a2024-10-23 16:57:06 -07001852 ctx.TransitiveInstallFiles = depset.New[InstallPath](depset.TOPOLOGICAL, nil, dependencyInstallFiles)
Colin Cross5d583952020-11-24 16:21:24 -08001853
Colin Cross6c4f21f2019-06-06 15:41:36 -07001854 // Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never
1855 // reporting missing dependency errors in Blueprint when AllowMissingDependencies == true.
1856 // TODO: This will be removed once defaults modules handle missing dependency errors
1857 blueprintCtx.GetMissingDependencies()
1858
Colin Crossdc35e212019-06-06 16:13:11 -07001859 // For the final GenerateAndroidBuildActions pass, require that all visited dependencies Soong modules and
Paul Duffin1356d8c2020-02-25 19:26:33 +00001860 // are enabled. Unless the module is a CommonOS variant which may have dependencies on disabled variants
1861 // (because the dependencies are added before the modules are disabled). The
1862 // GetOsSpecificVariantsOfCommonOSVariant(...) method will ensure that the disabled variants are
1863 // ignored.
1864 ctx.baseModuleContext.strictVisitDeps = !m.IsCommonOSVariant()
Colin Crossdc35e212019-06-06 16:13:11 -07001865
Colin Cross4c83e5c2019-02-25 14:54:28 -08001866 if ctx.config.captureBuild {
1867 ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
1868 }
1869
Colin Cross67a5c132017-05-09 13:45:28 -07001870 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
1871 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -08001872 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
1873 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -07001874 }
Colin Cross0875c522017-11-28 17:34:01 -08001875 if !ctx.PrimaryArch() {
1876 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -07001877 }
Colin Crossff694a82023-12-13 15:54:49 -08001878 if apexInfo, _ := ModuleProvider(ctx, ApexInfoProvider); !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -07001879 suffix = append(suffix, apexInfo.ApexVariationName)
Dan Willemsenb13a9482020-02-14 11:25:54 -08001880 }
Colin Cross67a5c132017-05-09 13:45:28 -07001881
1882 ctx.Variable(pctx, "moduleDesc", desc)
1883
1884 s := ""
1885 if len(suffix) > 0 {
1886 s = " [" + strings.Join(suffix, " ") + "]"
1887 }
1888 ctx.Variable(pctx, "moduleDescSuffix", s)
1889
Dan Willemsen569edc52018-11-19 09:33:29 -08001890 // Some common property checks for properties that will be used later in androidmk.go
Paul Duffin89968e32020-11-23 18:17:03 +00001891 checkDistProperties(ctx, "dist", &m.distProperties.Dist)
Sasha Smundake198eaf2022-08-04 13:07:02 -07001892 for i := range m.distProperties.Dists {
Paul Duffin89968e32020-11-23 18:17:03 +00001893 checkDistProperties(ctx, fmt.Sprintf("dists[%d]", i), &m.distProperties.Dists[i])
Dan Willemsen569edc52018-11-19 09:33:29 -08001894 }
1895
Yu Liubad1eef2024-08-21 22:37:35 +00001896 var installFiles InstallFilesInfo
1897
Cole Fausta963b942024-04-11 17:43:00 -07001898 if m.Enabled(ctx) {
Jooyung Hand48f3c32019-08-23 11:18:57 +09001899 // ensure all direct android.Module deps are enabled
Colin Cross648daea2024-09-12 14:35:29 -07001900 ctx.VisitDirectDeps(func(m Module) {
1901 ctx.validateAndroidModule(m, ctx.OtherModuleDependencyTag(m), ctx.baseModuleContext.strictVisitDeps)
Jooyung Hand48f3c32019-08-23 11:18:57 +09001902 })
1903
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001904 if m.Device() {
1905 // Handle any init.rc and vintf fragment files requested by the module. All files installed by this
1906 // module will automatically have a dependency on the installed init.rc or vintf fragment file.
1907 // The same init.rc or vintf fragment file may be requested by multiple modules or variants,
1908 // so instead of installing them now just compute the install path and store it for later.
1909 // The full list of all init.rc and vintf fragment install rules will be deduplicated later
1910 // so only a single rule is created for each init.rc or vintf fragment file.
1911
1912 if !m.InVendorRamdisk() {
Inseob Kim713b87d2024-09-13 11:29:54 +09001913 ctx.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc.GetOrDefault(ctx, nil))
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001914 rcDir := PathForModuleInstall(ctx, "etc", "init")
Yu Liu82a6d142024-08-27 19:02:29 +00001915 for _, src := range ctx.initRcPaths {
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001916 installedInitRc := rcDir.Join(ctx, src.Base())
Yu Liu82a6d142024-08-27 19:02:29 +00001917 ctx.katiInitRcInstalls = append(ctx.katiInitRcInstalls, katiInstall{
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001918 from: src,
1919 to: installedInitRc,
1920 })
1921 ctx.PackageFile(rcDir, src.Base(), src)
Yu Liu82a6d142024-08-27 19:02:29 +00001922 ctx.installedInitRcPaths = append(ctx.installedInitRcPaths, installedInitRc)
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001923 }
Yu Liu82a6d142024-08-27 19:02:29 +00001924 installFiles.InitRcPaths = ctx.initRcPaths
1925 installFiles.KatiInitRcInstalls = ctx.katiInitRcInstalls
1926 installFiles.InstalledInitRcPaths = ctx.installedInitRcPaths
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001927 }
1928
Yu Liu82a6d142024-08-27 19:02:29 +00001929 ctx.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments.GetOrDefault(ctx, nil))
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001930 vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest")
Yu Liu82a6d142024-08-27 19:02:29 +00001931 for _, src := range ctx.vintfFragmentsPaths {
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001932 installedVintfFragment := vintfDir.Join(ctx, src.Base())
Yu Liu82a6d142024-08-27 19:02:29 +00001933 ctx.katiVintfInstalls = append(ctx.katiVintfInstalls, katiInstall{
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001934 from: src,
1935 to: installedVintfFragment,
1936 })
1937 ctx.PackageFile(vintfDir, src.Base(), src)
Yu Liu82a6d142024-08-27 19:02:29 +00001938 ctx.installedVintfFragmentsPaths = append(ctx.installedVintfFragmentsPaths, installedVintfFragment)
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001939 }
Yu Liu82a6d142024-08-27 19:02:29 +00001940 installFiles.VintfFragmentsPaths = ctx.vintfFragmentsPaths
1941 installFiles.KatiVintfInstalls = ctx.katiVintfInstalls
1942 installFiles.InstalledVintfFragmentsPaths = ctx.installedVintfFragmentsPaths
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001943 }
1944
Bob Badour37af0462021-01-07 03:34:31 +00001945 licensesPropertyFlattener(ctx)
1946 if ctx.Failed() {
1947 return
1948 }
1949
Joe Onorato349ae8d2024-02-05 22:46:00 +00001950 if jarJarPrefixHandler != nil {
1951 jarJarPrefixHandler(ctx)
1952 if ctx.Failed() {
1953 return
1954 }
1955 }
1956
Justin Yun40182b62024-05-07 10:22:19 +09001957 // Call aconfigUpdateAndroidBuildActions to collect merged aconfig files before being used
1958 // in m.module.GenerateAndroidBuildActions
1959 aconfigUpdateAndroidBuildActions(ctx)
Jaewoong Jung5b425e22019-06-17 17:40:56 -07001960 if ctx.Failed() {
1961 return
1962 }
1963
Yu Liu26a716d2024-08-30 23:40:32 +00001964 m.module.GenerateAndroidBuildActions(ctx)
1965 if ctx.Failed() {
1966 return
Yu Liufa297642024-06-11 00:13:02 +00001967 }
1968
Yu Liu26a716d2024-08-30 23:40:32 +00001969 if x, ok := m.module.(IDEInfo); ok {
1970 var result IdeInfo
1971 x.IDEInfo(ctx, &result)
1972 result.BaseModuleName = x.BaseModuleName()
1973 SetProvider(ctx, IdeInfoProviderKey, result)
LaMont Jonesb5099382024-01-10 23:42:36 +00001974 }
1975
Paul Duffinaf970a22020-11-23 23:32:56 +00001976 // Create the set of tagged dist files after calling GenerateAndroidBuildActions
1977 // as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
1978 // output paths being set which must be done before or during
1979 // GenerateAndroidBuildActions.
Yu Liuec810542024-08-26 18:09:15 +00001980 installFiles.DistFiles = m.GenerateTaggedDistFiles(ctx)
Paul Duffinaf970a22020-11-23 23:32:56 +00001981 if ctx.Failed() {
1982 return
1983 }
1984
Colin Crossa6182ab2024-08-21 10:47:44 -07001985 m.generateVariantTarget(ctx)
1986
Yu Liuec810542024-08-26 18:09:15 +00001987 installFiles.LicenseMetadataFile = ctx.licenseMetadataFile
Yu Liubad1eef2024-08-21 22:37:35 +00001988 installFiles.InstallFiles = ctx.installFiles
1989 installFiles.CheckbuildFiles = ctx.checkbuildFiles
Colin Crossa6182ab2024-08-21 10:47:44 -07001990 installFiles.CheckbuildTarget = ctx.checkbuildTarget
1991 installFiles.UncheckedModule = ctx.uncheckedModule
Yu Liubad1eef2024-08-21 22:37:35 +00001992 installFiles.PackagingSpecs = ctx.packagingSpecs
1993 installFiles.KatiInstalls = ctx.katiInstalls
1994 installFiles.KatiSymlinks = ctx.katiSymlinks
1995 installFiles.TestData = ctx.testData
Colin Crossdc35e212019-06-06 16:13:11 -07001996 } else if ctx.Config().AllowMissingDependencies() {
1997 // If the module is not enabled it will not create any build rules, nothing will call
1998 // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
1999 // and report them as an error even when AllowMissingDependencies = true. Call
2000 // ctx.GetMissingDependencies() here to tell blueprint not to handle them.
2001 ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08002002 }
2003
Colin Cross4157e882019-06-06 16:57:04 -07002004 if m == ctx.FinalModule().(Module).base() {
2005 m.generateModuleTarget(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -07002006 if ctx.Failed() {
2007 return
2008 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002009 }
Colin Crosscec81712017-07-13 14:43:27 -07002010
Colin Crossa14fb6a2024-10-23 16:57:06 -07002011 ctx.TransitiveInstallFiles = depset.New[InstallPath](depset.TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles)
Yu Liubad1eef2024-08-21 22:37:35 +00002012 installFiles.TransitiveInstallFiles = ctx.TransitiveInstallFiles
Colin Crossa14fb6a2024-10-23 16:57:06 -07002013 installFiles.TransitivePackagingSpecs = depset.New[PackagingSpec](depset.TOPOLOGICAL, ctx.packagingSpecs, dependencyPackagingSpecs)
Colin Cross5d583952020-11-24 16:21:24 -08002014
Yu Liubad1eef2024-08-21 22:37:35 +00002015 SetProvider(ctx, InstallFilesProvider, installFiles)
Yu Liuec810542024-08-26 18:09:15 +00002016 buildLicenseMetadata(ctx, ctx.licenseMetadataFile)
Colin Cross4acaea92021-12-10 23:05:02 +00002017
Yu Liu4297ad92024-08-27 19:50:13 +00002018 if ctx.moduleInfoJSON != nil {
Colin Crossd6fd0132023-11-06 13:54:06 -08002019 var installed InstallPaths
Yu Liud46e5ae2024-08-15 18:46:17 +00002020 installed = append(installed, ctx.katiInstalls.InstallPaths()...)
2021 installed = append(installed, ctx.katiSymlinks.InstallPaths()...)
Yu Liu82a6d142024-08-27 19:02:29 +00002022 installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...)
2023 installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...)
Colin Crossd6fd0132023-11-06 13:54:06 -08002024 installedStrings := installed.Strings()
2025
2026 var targetRequired, hostRequired []string
2027 if ctx.Host() {
2028 targetRequired = m.commonProperties.Target_required
2029 } else {
2030 hostRequired = m.commonProperties.Host_required
2031 }
2032
2033 var data []string
Yu Liud46e5ae2024-08-15 18:46:17 +00002034 for _, d := range ctx.testData {
Colin Crossd6fd0132023-11-06 13:54:06 -08002035 data = append(data, d.ToRelativeInstallPath())
2036 }
2037
Yu Liu4297ad92024-08-27 19:50:13 +00002038 if ctx.moduleInfoJSON.Uninstallable {
Colin Crossd6fd0132023-11-06 13:54:06 -08002039 installedStrings = nil
Yu Liu4297ad92024-08-27 19:50:13 +00002040 if len(ctx.moduleInfoJSON.CompatibilitySuites) == 1 && ctx.moduleInfoJSON.CompatibilitySuites[0] == "null-suite" {
2041 ctx.moduleInfoJSON.CompatibilitySuites = nil
2042 ctx.moduleInfoJSON.TestConfig = nil
2043 ctx.moduleInfoJSON.AutoTestConfig = nil
Colin Crossd6fd0132023-11-06 13:54:06 -08002044 data = nil
2045 }
2046 }
2047
Yu Liu4297ad92024-08-27 19:50:13 +00002048 ctx.moduleInfoJSON.core = CoreModuleInfoJSON{
2049 RegisterName: m.moduleInfoRegisterName(ctx, ctx.moduleInfoJSON.SubName),
Colin Crossd6fd0132023-11-06 13:54:06 -08002050 Path: []string{ctx.ModuleDir()},
2051 Installed: installedStrings,
Yu Liu4297ad92024-08-27 19:50:13 +00002052 ModuleName: m.BaseModuleName() + ctx.moduleInfoJSON.SubName,
Colin Crossd6fd0132023-11-06 13:54:06 -08002053 SupportedVariants: []string{m.moduleInfoVariant(ctx)},
2054 TargetDependencies: targetRequired,
2055 HostDependencies: hostRequired,
2056 Data: data,
Kiyoung Kim74408202024-08-29 17:39:07 +09002057 Required: append(m.RequiredModuleNames(ctx), m.VintfFragmentModuleNames(ctx)...),
Colin Crossd6fd0132023-11-06 13:54:06 -08002058 }
Yu Liu4297ad92024-08-27 19:50:13 +00002059 SetProvider(ctx, ModuleInfoJSONProvider, ctx.moduleInfoJSON)
Colin Crossd6fd0132023-11-06 13:54:06 -08002060 }
2061
Colin Cross4157e882019-06-06 16:57:04 -07002062 m.buildParams = ctx.buildParams
2063 m.ruleParams = ctx.ruleParams
2064 m.variables = ctx.variables
mrziwange6c85812024-05-22 14:36:09 -07002065
Yu Liu876b7ce2024-08-21 18:20:13 +00002066 outputFiles := ctx.GetOutputFiles()
2067 if outputFiles.DefaultOutputFiles != nil || outputFiles.TaggedOutputFiles != nil {
2068 SetProvider(ctx, OutputFilesProvider, outputFiles)
mrziwange6c85812024-05-22 14:36:09 -07002069 }
Wei Lia1aa2972024-06-21 13:08:51 -07002070
Yu Liu54513622024-08-19 20:00:32 +00002071 if len(ctx.phonies) > 0 {
2072 SetProvider(ctx, ModulePhonyProvider, ModulePhonyInfo{
2073 Phonies: ctx.phonies,
2074 })
2075 }
Wei Lia1aa2972024-06-21 13:08:51 -07002076 buildComplianceMetadataProvider(ctx, m)
Yu Liudd9ccb42024-10-07 17:07:44 +00002077
2078 commonData := CommonPropertiesProviderData{
2079 ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt,
2080 }
2081 if m.commonProperties.ForcedDisabled {
2082 commonData.Enabled = false
2083 } else {
2084 commonData.Enabled = m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled)
2085 }
2086 SetProvider(ctx, CommonPropertiesProviderKey, commonData)
2087 if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil {
2088 SetProvider(ctx, PrebuiltModuleProviderKey, PrebuiltModuleProviderData{})
2089 }
2090 if h, ok := m.module.(HostToolProvider); ok {
2091 SetProvider(ctx, HostToolProviderKey, HostToolProviderData{
2092 HostToolPath: h.HostToolPath()})
2093 }
Colin Cross3f40fa42015-01-30 17:27:36 -08002094}
2095
Joe Onorato349ae8d2024-02-05 22:46:00 +00002096func SetJarJarPrefixHandler(handler func(ModuleContext)) {
2097 if jarJarPrefixHandler != nil {
2098 panic("jarJarPrefixHandler already set")
2099 }
2100 jarJarPrefixHandler = handler
2101}
2102
Colin Crossd6fd0132023-11-06 13:54:06 -08002103func (m *ModuleBase) moduleInfoRegisterName(ctx ModuleContext, subName string) string {
2104 name := m.BaseModuleName()
2105
2106 prefix := ""
2107 if ctx.Host() {
2108 if ctx.Os() != ctx.Config().BuildOS {
2109 prefix = "host_cross_"
2110 }
2111 }
2112 suffix := ""
2113 arches := slices.Clone(ctx.Config().Targets[ctx.Os()])
2114 arches = slices.DeleteFunc(arches, func(target Target) bool {
2115 return target.NativeBridge != ctx.Target().NativeBridge
2116 })
2117 if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType {
2118 if ctx.Arch().ArchType.Multilib == "lib32" {
2119 suffix = "_32"
2120 } else {
2121 suffix = "_64"
2122 }
2123 }
2124 return prefix + name + subName + suffix
2125}
2126
2127func (m *ModuleBase) moduleInfoVariant(ctx ModuleContext) string {
2128 variant := "DEVICE"
2129 if ctx.Host() {
2130 if ctx.Os() != ctx.Config().BuildOS {
2131 variant = "HOST_CROSS"
2132 } else {
2133 variant = "HOST"
2134 }
2135 }
2136 return variant
2137}
2138
Paul Duffin89968e32020-11-23 18:17:03 +00002139// Check the supplied dist structure to make sure that it is valid.
2140//
2141// property - the base property, e.g. dist or dists[1], which is combined with the
2142// name of the nested property to produce the full property, e.g. dist.dest or
2143// dists[1].dir.
2144func checkDistProperties(ctx *moduleContext, property string, dist *Dist) {
2145 if dist.Dest != nil {
2146 _, err := validateSafePath(*dist.Dest)
2147 if err != nil {
2148 ctx.PropertyErrorf(property+".dest", "%s", err.Error())
2149 }
2150 }
2151 if dist.Dir != nil {
2152 _, err := validateSafePath(*dist.Dir)
2153 if err != nil {
2154 ctx.PropertyErrorf(property+".dir", "%s", err.Error())
2155 }
2156 }
2157 if dist.Suffix != nil {
2158 if strings.Contains(*dist.Suffix, "/") {
2159 ctx.PropertyErrorf(property+".suffix", "Suffix may not contain a '/' character.")
2160 }
2161 }
2162
2163}
2164
Colin Cross6301c3c2021-09-28 17:40:21 -07002165// katiInstall stores a request from Soong to Make to create an install rule.
2166type katiInstall struct {
2167 from Path
2168 to InstallPath
2169 implicitDeps Paths
2170 orderOnlyDeps Paths
2171 executable bool
Colin Cross50ed1f92021-11-12 17:41:02 -08002172 extraFiles *extraFilesZip
Yu Liu467d7c52024-09-18 21:54:44 +00002173 absFrom string
Colin Cross6301c3c2021-09-28 17:40:21 -07002174}
2175
Yu Liu467d7c52024-09-18 21:54:44 +00002176type katiInstallGob struct {
2177 From Path
2178 To InstallPath
2179 ImplicitDeps Paths
2180 OrderOnlyDeps Paths
2181 Executable bool
2182 ExtraFiles *extraFilesZip
2183 AbsFrom string
Yu Liu26a716d2024-08-30 23:40:32 +00002184}
2185
Yu Liu467d7c52024-09-18 21:54:44 +00002186func (k *katiInstall) ToGob() *katiInstallGob {
2187 return &katiInstallGob{
2188 From: k.from,
2189 To: k.to,
2190 ImplicitDeps: k.implicitDeps,
2191 OrderOnlyDeps: k.orderOnlyDeps,
2192 Executable: k.executable,
2193 ExtraFiles: k.extraFiles,
2194 AbsFrom: k.absFrom,
Yu Liu26a716d2024-08-30 23:40:32 +00002195 }
Yu Liu467d7c52024-09-18 21:54:44 +00002196}
Yu Liu26a716d2024-08-30 23:40:32 +00002197
Yu Liu467d7c52024-09-18 21:54:44 +00002198func (k *katiInstall) FromGob(data *katiInstallGob) {
2199 k.from = data.From
2200 k.to = data.To
2201 k.implicitDeps = data.ImplicitDeps
2202 k.orderOnlyDeps = data.OrderOnlyDeps
2203 k.executable = data.Executable
2204 k.extraFiles = data.ExtraFiles
2205 k.absFrom = data.AbsFrom
2206}
2207
2208func (k *katiInstall) GobEncode() ([]byte, error) {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002209 return gobtools.CustomGobEncode[katiInstallGob](k)
Yu Liu467d7c52024-09-18 21:54:44 +00002210}
2211
2212func (k *katiInstall) GobDecode(data []byte) error {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002213 return gobtools.CustomGobDecode[katiInstallGob](data, k)
Yu Liu26a716d2024-08-30 23:40:32 +00002214}
2215
Colin Cross50ed1f92021-11-12 17:41:02 -08002216type extraFilesZip struct {
2217 zip Path
2218 dir InstallPath
2219}
2220
Yu Liu467d7c52024-09-18 21:54:44 +00002221type extraFilesZipGob struct {
2222 Zip Path
2223 Dir InstallPath
Yu Liu26a716d2024-08-30 23:40:32 +00002224}
2225
Yu Liu467d7c52024-09-18 21:54:44 +00002226func (e *extraFilesZip) ToGob() *extraFilesZipGob {
2227 return &extraFilesZipGob{
2228 Zip: e.zip,
2229 Dir: e.dir,
Yu Liu26a716d2024-08-30 23:40:32 +00002230 }
Yu Liu467d7c52024-09-18 21:54:44 +00002231}
Yu Liu26a716d2024-08-30 23:40:32 +00002232
Yu Liu467d7c52024-09-18 21:54:44 +00002233func (e *extraFilesZip) FromGob(data *extraFilesZipGob) {
2234 e.zip = data.Zip
2235 e.dir = data.Dir
2236}
2237
2238func (e *extraFilesZip) GobEncode() ([]byte, error) {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002239 return gobtools.CustomGobEncode[extraFilesZipGob](e)
Yu Liu467d7c52024-09-18 21:54:44 +00002240}
2241
2242func (e *extraFilesZip) GobDecode(data []byte) error {
Yu Liu3cadf7d2024-10-24 18:47:06 +00002243 return gobtools.CustomGobDecode[extraFilesZipGob](data, e)
Yu Liu26a716d2024-08-30 23:40:32 +00002244}
2245
Colin Cross6301c3c2021-09-28 17:40:21 -07002246type katiInstalls []katiInstall
2247
2248// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
2249// space separated list of from:to tuples.
2250func (installs katiInstalls) BuiltInstalled() string {
2251 sb := strings.Builder{}
2252 for i, install := range installs {
2253 if i != 0 {
2254 sb.WriteRune(' ')
2255 }
2256 sb.WriteString(install.from.String())
2257 sb.WriteRune(':')
2258 sb.WriteString(install.to.String())
2259 }
2260 return sb.String()
2261}
2262
2263// InstallPaths returns the install path of each entry.
2264func (installs katiInstalls) InstallPaths() InstallPaths {
2265 paths := make(InstallPaths, 0, len(installs))
2266 for _, install := range installs {
2267 paths = append(paths, install.to)
2268 }
2269 return paths
2270}
2271
Jiyong Park5baac542018-08-28 09:55:37 +09002272// Makes this module a platform module, i.e. not specific to soc, device,
Justin Yund5f6c822019-06-25 16:47:17 +09002273// product, or system_ext.
Colin Cross4157e882019-06-06 16:57:04 -07002274func (m *ModuleBase) MakeAsPlatform() {
2275 m.commonProperties.Vendor = boolPtr(false)
2276 m.commonProperties.Proprietary = boolPtr(false)
2277 m.commonProperties.Soc_specific = boolPtr(false)
2278 m.commonProperties.Product_specific = boolPtr(false)
Justin Yund5f6c822019-06-25 16:47:17 +09002279 m.commonProperties.System_ext_specific = boolPtr(false)
Jiyong Park5baac542018-08-28 09:55:37 +09002280}
2281
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09002282func (m *ModuleBase) MakeAsSystemExt() {
Jooyung Han91df2082019-11-20 01:49:42 +09002283 m.commonProperties.Vendor = boolPtr(false)
2284 m.commonProperties.Proprietary = boolPtr(false)
2285 m.commonProperties.Soc_specific = boolPtr(false)
2286 m.commonProperties.Product_specific = boolPtr(false)
2287 m.commonProperties.System_ext_specific = boolPtr(true)
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09002288}
2289
Jooyung Han344d5432019-08-23 11:17:39 +09002290// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true"
2291func (m *ModuleBase) IsNativeBridgeSupported() bool {
2292 return proptools.Bool(m.commonProperties.Native_bridge_supported)
2293}
2294
Jihoon Kang0d545b82024-10-11 00:21:57 +00002295func (m *ModuleBase) DecodeMultilib(ctx ConfigContext) (string, string) {
2296 return decodeMultilib(ctx, m)
2297}
2298
Spandan Dase1860e42024-10-24 22:29:50 +00002299func (m *ModuleBase) Overrides() []string {
2300 return m.commonProperties.Overrides
2301}
2302
Colin Cross8bbc3d52024-09-11 15:33:54 -07002303type ConfigContext interface {
2304 Config() Config
2305}
2306
Cole Fauste8a87832024-09-11 11:35:46 -07002307type ConfigurableEvaluatorContext interface {
Cole Faust55b56fe2024-08-23 12:06:11 -07002308 OtherModuleProviderContext
Cole Faust02987bd2024-03-21 17:58:43 -07002309 Config() Config
2310 OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{})
Cole Faustd7067092024-09-13 13:37:59 -07002311 HasMutatorFinished(mutatorName string) bool
Cole Faust02987bd2024-03-21 17:58:43 -07002312}
2313
2314type configurationEvalutor struct {
Cole Fauste8a87832024-09-11 11:35:46 -07002315 ctx ConfigurableEvaluatorContext
Cole Faust02987bd2024-03-21 17:58:43 -07002316 m Module
2317}
2318
Cole Fauste8a87832024-09-11 11:35:46 -07002319func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator {
Cole Faust02987bd2024-03-21 17:58:43 -07002320 return configurationEvalutor{
2321 ctx: ctx,
2322 m: m.module,
2323 }
2324}
2325
2326func (e configurationEvalutor) PropertyErrorf(property string, fmt string, args ...interface{}) {
Cole Fausta963b942024-04-11 17:43:00 -07002327 e.ctx.OtherModulePropertyErrorf(e.m, property, fmt, args...)
Cole Faust02987bd2024-03-21 17:58:43 -07002328}
2329
Cole Faustfdbf5d42024-04-10 15:01:23 -07002330func (e configurationEvalutor) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue {
Cole Faust02987bd2024-03-21 17:58:43 -07002331 ctx := e.ctx
2332 m := e.m
Cole Faustd7067092024-09-13 13:37:59 -07002333
2334 if !ctx.HasMutatorFinished("defaults") {
2335 ctx.OtherModulePropertyErrorf(m, property, "Cannot evaluate configurable property before the defaults mutator has run")
2336 return proptools.ConfigurableValueUndefined()
2337 }
2338
Cole Faust8afc5142024-04-26 16:30:19 -07002339 switch condition.FunctionName() {
Cole Fauste19f7412024-05-09 15:14:04 -07002340 case "release_flag":
Cole Faust8afc5142024-04-26 16:30:19 -07002341 if condition.NumArgs() != 1 {
Cole Fauste19f7412024-05-09 15:14:04 -07002342 ctx.OtherModulePropertyErrorf(m, property, "release_flag requires 1 argument, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002343 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002344 }
Cole Faust751a4a52024-05-21 16:51:59 -07002345 if ty, ok := ctx.Config().productVariables.BuildFlagTypes[condition.Arg(0)]; ok {
2346 v := ctx.Config().productVariables.BuildFlags[condition.Arg(0)]
2347 switch ty {
2348 case "unspecified", "obsolete":
2349 return proptools.ConfigurableValueUndefined()
2350 case "string":
2351 return proptools.ConfigurableValueString(v)
2352 case "bool":
2353 return proptools.ConfigurableValueBool(v == "true")
2354 default:
2355 panic("unhandled release flag type: " + ty)
2356 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002357 }
2358 return proptools.ConfigurableValueUndefined()
2359 case "product_variable":
Jiyong Parke3250752024-05-17 14:56:10 +09002360 if condition.NumArgs() != 1 {
2361 ctx.OtherModulePropertyErrorf(m, property, "product_variable requires 1 argument, found %d", condition.NumArgs())
2362 return proptools.ConfigurableValueUndefined()
2363 }
2364 variable := condition.Arg(0)
2365 switch variable {
Jihoon Kang82bea762024-09-30 18:50:54 +00002366 case "build_from_text_stub":
2367 return proptools.ConfigurableValueBool(ctx.Config().BuildFromTextStub())
Jiyong Parke3250752024-05-17 14:56:10 +09002368 case "debuggable":
2369 return proptools.ConfigurableValueBool(ctx.Config().Debuggable())
Kiyoung Kim881e4652024-07-08 11:02:23 +09002370 case "use_debug_art":
2371 // TODO(b/234351700): Remove once ART does not have separated debug APEX
2372 return proptools.ConfigurableValueBool(ctx.Config().UseDebugArt())
kellyhung1e613d22024-07-29 12:56:51 +00002373 case "selinux_ignore_neverallows":
2374 return proptools.ConfigurableValueBool(ctx.Config().SelinuxIgnoreNeverallows())
Jiyong Parke3250752024-05-17 14:56:10 +09002375 default:
2376 // TODO(b/323382414): Might add these on a case-by-case basis
2377 ctx.OtherModulePropertyErrorf(m, property, fmt.Sprintf("TODO(b/323382414): Product variable %q is not yet supported in selects", variable))
2378 return proptools.ConfigurableValueUndefined()
2379 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002380 case "soong_config_variable":
Cole Faust8afc5142024-04-26 16:30:19 -07002381 if condition.NumArgs() != 2 {
2382 ctx.OtherModulePropertyErrorf(m, property, "soong_config_variable requires 2 arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002383 return proptools.ConfigurableValueUndefined()
2384 }
Cole Faust8afc5142024-04-26 16:30:19 -07002385 namespace := condition.Arg(0)
2386 variable := condition.Arg(1)
Cole Faust02987bd2024-03-21 17:58:43 -07002387 if n, ok := ctx.Config().productVariables.VendorVars[namespace]; ok {
2388 if v, ok := n[variable]; ok {
Cole Faust46f6e2f2024-06-20 12:57:43 -07002389 ty := ""
2390 if namespaces, ok := ctx.Config().productVariables.VendorVarTypes[namespace]; ok {
2391 ty = namespaces[variable]
2392 }
2393 switch ty {
2394 case "":
2395 // strings are the default, we don't bother writing them to the soong variables json file
2396 return proptools.ConfigurableValueString(v)
2397 case "bool":
2398 return proptools.ConfigurableValueBool(v == "true")
2399 default:
2400 panic("unhandled soong config variable type: " + ty)
2401 }
2402
Cole Faust02987bd2024-03-21 17:58:43 -07002403 }
2404 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002405 return proptools.ConfigurableValueUndefined()
Cole Faustfc57d402024-04-11 12:09:44 -07002406 case "arch":
Cole Faust8afc5142024-04-26 16:30:19 -07002407 if condition.NumArgs() != 0 {
2408 ctx.OtherModulePropertyErrorf(m, property, "arch requires no arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002409 return proptools.ConfigurableValueUndefined()
2410 }
Cole Faustfc57d402024-04-11 12:09:44 -07002411 if !m.base().ArchReady() {
2412 ctx.OtherModulePropertyErrorf(m, property, "A select on arch was attempted before the arch mutator ran")
2413 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002414 }
Cole Faustfc57d402024-04-11 12:09:44 -07002415 return proptools.ConfigurableValueString(m.base().Arch().ArchType.Name)
2416 case "os":
Cole Faust8afc5142024-04-26 16:30:19 -07002417 if condition.NumArgs() != 0 {
2418 ctx.OtherModulePropertyErrorf(m, property, "os requires no arguments, found %d", condition.NumArgs())
Cole Faustfc57d402024-04-11 12:09:44 -07002419 return proptools.ConfigurableValueUndefined()
2420 }
2421 // the arch mutator runs after the os mutator, we can just use this to enforce that os is ready.
2422 if !m.base().ArchReady() {
2423 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)")
2424 return proptools.ConfigurableValueUndefined()
2425 }
2426 return proptools.ConfigurableValueString(m.base().Os().Name)
Cole Faustfdbf5d42024-04-10 15:01:23 -07002427 case "boolean_var_for_testing":
2428 // We currently don't have any other boolean variables (we should add support for typing
2429 // the soong config variables), so add this fake one for testing the boolean select
2430 // functionality.
Cole Faust8afc5142024-04-26 16:30:19 -07002431 if condition.NumArgs() != 0 {
2432 ctx.OtherModulePropertyErrorf(m, property, "boolean_var_for_testing requires 0 arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002433 return proptools.ConfigurableValueUndefined()
2434 }
2435
2436 if n, ok := ctx.Config().productVariables.VendorVars["boolean_var"]; ok {
2437 if v, ok := n["for_testing"]; ok {
2438 switch v {
2439 case "true":
2440 return proptools.ConfigurableValueBool(true)
2441 case "false":
2442 return proptools.ConfigurableValueBool(false)
2443 default:
2444 ctx.OtherModulePropertyErrorf(m, property, "testing:my_boolean_var can only be true or false, found %q", v)
2445 }
2446 }
2447 }
2448 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002449 default:
Cole Faustfdbf5d42024-04-10 15:01:23 -07002450 ctx.OtherModulePropertyErrorf(m, property, "Unknown select condition %s", condition.FunctionName)
2451 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002452 }
2453}
2454
Colin Crossb63d7b32023-12-07 16:54:51 -08002455// ModuleNameWithPossibleOverride returns the name of the OverrideModule that overrides the current
2456// variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule
2457// or if this variant is not overridden.
2458func ModuleNameWithPossibleOverride(ctx BaseModuleContext) string {
2459 if overridable, ok := ctx.Module().(OverridableModule); ok {
2460 if o := overridable.GetOverriddenBy(); o != "" {
2461 return o
2462 }
2463 }
2464 return ctx.ModuleName()
2465}
2466
Paul Duffine6ba0722021-07-12 20:12:12 +01002467// SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name"
2468// into the module name, or empty string if the input was not a module reference.
Colin Cross41955e82019-05-29 14:40:35 -07002469func SrcIsModule(s string) (module string) {
Paul Duffine6ba0722021-07-12 20:12:12 +01002470 if len(s) > 1 {
2471 if s[0] == ':' {
2472 module = s[1:]
2473 if !isUnqualifiedModuleName(module) {
2474 // The module name should be unqualified but is not so do not treat it as a module.
2475 module = ""
2476 }
2477 } else if s[0] == '/' && s[1] == '/' {
2478 module = s
2479 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002480 }
Paul Duffine6ba0722021-07-12 20:12:12 +01002481 return module
Colin Cross068e0fe2016-12-13 15:23:47 -08002482}
2483
Yi-Yo Chiangba9ea322021-07-15 17:18:21 +08002484// SrcIsModuleWithTag decodes module references in the format ":unqualified-name{.tag}" or
2485// "//namespace:name{.tag}" into the module name and tag, ":unqualified-name" or "//namespace:name"
2486// into the module name and an empty string for the tag, or empty strings if the input was not a
2487// module reference.
Colin Cross41955e82019-05-29 14:40:35 -07002488func SrcIsModuleWithTag(s string) (module, tag string) {
Paul Duffine6ba0722021-07-12 20:12:12 +01002489 if len(s) > 1 {
2490 if s[0] == ':' {
2491 module = s[1:]
2492 } else if s[0] == '/' && s[1] == '/' {
2493 module = s
2494 }
2495
2496 if module != "" {
2497 if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
2498 if module[len(module)-1] == '}' {
2499 tag = module[tagStart+1 : len(module)-1]
2500 module = module[:tagStart]
2501 }
2502 }
2503
2504 if s[0] == ':' && !isUnqualifiedModuleName(module) {
2505 // The module name should be unqualified but is not so do not treat it as a module.
2506 module = ""
2507 tag = ""
Colin Cross41955e82019-05-29 14:40:35 -07002508 }
2509 }
Colin Cross41955e82019-05-29 14:40:35 -07002510 }
Paul Duffine6ba0722021-07-12 20:12:12 +01002511
2512 return module, tag
2513}
2514
2515// isUnqualifiedModuleName makes sure that the supplied module is an unqualified module name, i.e.
2516// does not contain any /.
2517func isUnqualifiedModuleName(module string) bool {
2518 return strings.IndexByte(module, '/') == -1
Colin Cross068e0fe2016-12-13 15:23:47 -08002519}
2520
Paul Duffin40131a32021-07-09 17:10:35 +01002521// sourceOrOutputDependencyTag is the dependency tag added automatically by pathDepsMutator for any
2522// module reference in a property annotated with `android:"path"` or passed to ExtractSourceDeps
2523// or ExtractSourcesDeps.
2524//
2525// If uniquely identifies the dependency that was added as it contains both the module name used to
2526// add the dependency as well as the tag. That makes it very simple to find the matching dependency
2527// in GetModuleFromPathDep as all it needs to do is find the dependency whose tag matches the tag
2528// used to add it. It does not need to check that the module name as returned by one of
2529// Module.Name(), BaseModuleContext.OtherModuleName() or ModuleBase.BaseModuleName() matches the
2530// name supplied in the tag. That means it does not need to handle differences in module names
2531// caused by prebuilt_ prefix, or fully qualified module names.
Colin Cross41955e82019-05-29 14:40:35 -07002532type sourceOrOutputDependencyTag struct {
2533 blueprint.BaseDependencyTag
Yu Liu67a28422024-03-05 00:36:31 +00002534 AlwaysPropagateAconfigValidationDependencyTag
Paul Duffin40131a32021-07-09 17:10:35 +01002535
2536 // The name of the module.
2537 moduleName string
2538
mrziwangd38e63d2024-07-15 13:43:37 -07002539 // The tag that will be used to get the specific output file(s).
Colin Cross41955e82019-05-29 14:40:35 -07002540 tag string
2541}
2542
Paul Duffin40131a32021-07-09 17:10:35 +01002543func sourceOrOutputDepTag(moduleName, tag string) blueprint.DependencyTag {
2544 return sourceOrOutputDependencyTag{moduleName: moduleName, tag: tag}
Colin Cross41955e82019-05-29 14:40:35 -07002545}
2546
Paul Duffind5cf92e2021-07-09 17:38:55 +01002547// IsSourceDepTagWithOutputTag returns true if the supplied blueprint.DependencyTag is one that was
2548// used to add dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for
2549// properties tagged with `android:"path"` AND it was added using a module reference of
2550// :moduleName{outputTag}.
2551func IsSourceDepTagWithOutputTag(depTag blueprint.DependencyTag, outputTag string) bool {
2552 t, ok := depTag.(sourceOrOutputDependencyTag)
2553 return ok && t.tag == outputTag
2554}
2555
Colin Cross366938f2017-12-11 16:29:02 -08002556// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
2557// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08002558//
2559// Deprecated: tag the property with `android:"path"` instead.
Colin Cross068e0fe2016-12-13 15:23:47 -08002560func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
Nan Zhang2439eb72017-04-10 11:27:50 -07002561 set := make(map[string]bool)
2562
Colin Cross068e0fe2016-12-13 15:23:47 -08002563 for _, s := range srcFiles {
Colin Cross41955e82019-05-29 14:40:35 -07002564 if m, t := SrcIsModuleWithTag(s); m != "" {
2565 if _, found := set[s]; found {
2566 ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
Nan Zhang2439eb72017-04-10 11:27:50 -07002567 } else {
Colin Cross41955e82019-05-29 14:40:35 -07002568 set[s] = true
Paul Duffin40131a32021-07-09 17:10:35 +01002569 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
Nan Zhang2439eb72017-04-10 11:27:50 -07002570 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002571 }
2572 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002573}
2574
Colin Cross366938f2017-12-11 16:29:02 -08002575// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
2576// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08002577//
2578// Deprecated: tag the property with `android:"path"` instead.
Colin Cross366938f2017-12-11 16:29:02 -08002579func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
2580 if s != nil {
Colin Cross41955e82019-05-29 14:40:35 -07002581 if m, t := SrcIsModuleWithTag(*s); m != "" {
Paul Duffin40131a32021-07-09 17:10:35 +01002582 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
Colin Cross366938f2017-12-11 16:29:02 -08002583 }
2584 }
2585}
2586
Colin Cross41955e82019-05-29 14:40:35 -07002587// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"`
2588// 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 -08002589type SourceFileProducer interface {
2590 Srcs() Paths
2591}
2592
mrziwangd38e63d2024-07-15 13:43:37 -07002593// OutputFilesForModule returns the output file paths with the given tag. On error, including if the
Colin Cross5e708052019-08-06 13:59:50 -07002594// module produced zero paths, it reports errors to the ctx and returns nil.
2595func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) Paths {
2596 paths, err := outputFilesForModule(ctx, module, tag)
2597 if err != nil {
2598 reportPathError(ctx, err)
2599 return nil
2600 }
2601 return paths
2602}
2603
mrziwangd38e63d2024-07-15 13:43:37 -07002604// OutputFileForModule returns the output file paths with the given tag. On error, including if the
Colin Cross5e708052019-08-06 13:59:50 -07002605// module produced zero or multiple paths, it reports errors to the ctx and returns nil.
2606func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) Path {
2607 paths, err := outputFilesForModule(ctx, module, tag)
2608 if err != nil {
2609 reportPathError(ctx, err)
2610 return nil
2611 }
Colin Cross14ec66c2022-10-03 21:02:27 -07002612 if len(paths) == 0 {
2613 type addMissingDependenciesIntf interface {
2614 AddMissingDependencies([]string)
2615 OtherModuleName(blueprint.Module) string
2616 }
2617 if mctx, ok := ctx.(addMissingDependenciesIntf); ok && ctx.Config().AllowMissingDependencies() {
2618 mctx.AddMissingDependencies([]string{mctx.OtherModuleName(module)})
2619 } else {
2620 ReportPathErrorf(ctx, "failed to get output files from module %q", pathContextName(ctx, module))
2621 }
2622 // Return a fake output file to avoid nil dereferences of Path objects later.
2623 // This should never get used for an actual build as the error or missing
2624 // dependency has already been reported.
2625 p, err := pathForSource(ctx, filepath.Join("missing_output_file", pathContextName(ctx, module)))
2626 if err != nil {
2627 reportPathError(ctx, err)
2628 return nil
2629 }
2630 return p
2631 }
Colin Cross5e708052019-08-06 13:59:50 -07002632 if len(paths) > 1 {
Ulya Trafimovich5ab276a2020-08-25 12:45:15 +01002633 ReportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
Colin Cross5e708052019-08-06 13:59:50 -07002634 pathContextName(ctx, module))
Colin Cross5e708052019-08-06 13:59:50 -07002635 }
2636 return paths[0]
2637}
2638
2639func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
mrziwange6c85812024-05-22 14:36:09 -07002640 outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag)
mrziwangabdb2932024-06-18 12:43:41 -07002641 if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet {
mrziwange6c85812024-05-22 14:36:09 -07002642 return outputFilesFromProvider, err
2643 }
mrziwang1ea01e32024-07-12 12:26:34 -07002644 if sourceFileProducer, ok := module.(SourceFileProducer); ok {
Colin Cross74b1e2b2020-11-22 20:23:02 -08002645 if tag != "" {
mrziwang1ea01e32024-07-12 12:26:34 -07002646 return nil, fmt.Errorf("module %q is a SourceFileProducer, which does not support tag %q", pathContextName(ctx, module), tag)
Colin Cross74b1e2b2020-11-22 20:23:02 -08002647 }
2648 paths := sourceFileProducer.Srcs()
Colin Cross74b1e2b2020-11-22 20:23:02 -08002649 return paths, nil
Colin Cross5e708052019-08-06 13:59:50 -07002650 } else {
mrziwang68b25942024-07-11 09:58:30 -07002651 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 -07002652 }
2653}
2654
mrziwange6c85812024-05-22 14:36:09 -07002655// This method uses OutputFilesProvider for output files
2656// *inter-module-communication*.
2657// If mctx module is the same as the param module the output files are obtained
2658// from outputFiles property of module base, to avoid both setting and
mrziwang42953592024-06-20 09:53:33 -07002659// reading OutputFilesProvider before GenerateBuildActions is finished.
mrziwange6c85812024-05-22 14:36:09 -07002660// If a module doesn't have the OutputFilesProvider, nil is returned.
2661func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
mrziwangabdb2932024-06-18 12:43:41 -07002662 var outputFiles OutputFilesInfo
2663 fromProperty := false
mrziwang0cbd3b02024-06-20 16:39:25 -07002664
mrziwang1ea01e32024-07-12 12:26:34 -07002665 type OutputFilesProviderModuleContext interface {
2666 OtherModuleProviderContext
2667 Module() Module
Yu Liu876b7ce2024-08-21 18:20:13 +00002668 GetOutputFiles() OutputFilesInfo
mrziwang1ea01e32024-07-12 12:26:34 -07002669 }
2670
2671 if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx {
mrziwang0cbd3b02024-06-20 16:39:25 -07002672 if mctx.Module() != module {
mrziwangabdb2932024-06-18 12:43:41 -07002673 outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider)
mrziwang0cbd3b02024-06-20 16:39:25 -07002674 } else {
Yu Liu876b7ce2024-08-21 18:20:13 +00002675 outputFiles = mctx.GetOutputFiles()
mrziwangabdb2932024-06-18 12:43:41 -07002676 fromProperty = true
mrziwange6c85812024-05-22 14:36:09 -07002677 }
mrziwang0cbd3b02024-06-20 16:39:25 -07002678 } else if cta, isCta := ctx.(*singletonContextAdaptor); isCta {
Yu Liu663e4502024-08-12 18:23:59 +00002679 providerData, _ := cta.otherModuleProvider(module, OutputFilesProvider)
mrziwangabdb2932024-06-18 12:43:41 -07002680 outputFiles, _ = providerData.(OutputFilesInfo)
mrziwang7a47bd32024-07-17 11:11:05 -07002681 } else {
2682 return nil, fmt.Errorf("unsupported context %q in method outputFilesForModuleFromProvider", reflect.TypeOf(ctx))
mrziwang0cbd3b02024-06-20 16:39:25 -07002683 }
mrziwang0cbd3b02024-06-20 16:39:25 -07002684
mrziwangabdb2932024-06-18 12:43:41 -07002685 if outputFiles.isEmpty() {
mrziwangabdb2932024-06-18 12:43:41 -07002686 return nil, OutputFilesProviderNotSet
2687 }
2688
2689 if tag == "" {
2690 return outputFiles.DefaultOutputFiles, nil
2691 } else if taggedOutputFiles, hasTag := outputFiles.TaggedOutputFiles[tag]; hasTag {
2692 return taggedOutputFiles, nil
2693 } else {
2694 if fromProperty {
2695 return nil, fmt.Errorf("unsupported tag %q for module getting its own output files", tag)
mrziwange6c85812024-05-22 14:36:09 -07002696 } else {
mrziwang0cbd3b02024-06-20 16:39:25 -07002697 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
mrziwange6c85812024-05-22 14:36:09 -07002698 }
2699 }
mrziwange6c85812024-05-22 14:36:09 -07002700}
2701
mrziwang0cbd3b02024-06-20 16:39:25 -07002702func (o OutputFilesInfo) isEmpty() bool {
2703 return o.DefaultOutputFiles == nil && o.TaggedOutputFiles == nil
2704}
2705
mrziwange6c85812024-05-22 14:36:09 -07002706type OutputFilesInfo struct {
2707 // default output files when tag is an empty string ""
2708 DefaultOutputFiles Paths
2709
2710 // the corresponding output files for given tags
2711 TaggedOutputFiles map[string]Paths
2712}
2713
2714var OutputFilesProvider = blueprint.NewProvider[OutputFilesInfo]()
2715
mrziwangabdb2932024-06-18 12:43:41 -07002716// This is used to mark the case where OutputFilesProvider is not set on some modules.
2717var OutputFilesProviderNotSet = fmt.Errorf("No output files from provider")
2718
Colin Cross41589502020-12-01 14:00:21 -08002719// Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to
2720// specify that they can be used as a tool by a genrule module.
Colin Crossfe17f6f2019-03-28 19:30:56 -07002721type HostToolProvider interface {
Colin Crossba9e4032020-11-24 16:32:22 -08002722 Module
Colin Cross41589502020-12-01 14:00:21 -08002723 // HostToolPath returns the path to the host tool for the module if it is one, or an invalid
2724 // OptionalPath.
Colin Crossfe17f6f2019-03-28 19:30:56 -07002725 HostToolPath() OptionalPath
2726}
2727
Colin Cross463a90e2015-06-17 14:20:06 -07002728func init() {
LaMont Jones0c10e4d2023-05-16 00:58:37 +00002729 RegisterParallelSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07002730}
2731
Colin Cross0875c522017-11-28 17:34:01 -08002732func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07002733 return &buildTargetSingleton{}
2734}
2735
Colin Cross87d8b562017-04-25 10:01:55 -07002736func parentDir(dir string) string {
2737 dir, _ = filepath.Split(dir)
2738 return filepath.Clean(dir)
2739}
2740
Colin Cross1f8c52b2015-06-16 16:38:17 -07002741type buildTargetSingleton struct{}
2742
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002743func AddAncestors(ctx SingletonContext, dirMap map[string]Paths, mmName func(string) string) ([]string, []string) {
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002744 // Ensure ancestor directories are in dirMap
2745 // Make directories build their direct subdirectories
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002746 // Returns a slice of all directories and a slice of top-level directories.
Cole Faust18994c72023-02-28 16:02:16 -08002747 dirs := SortedKeys(dirMap)
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002748 for _, dir := range dirs {
2749 dir := parentDir(dir)
2750 for dir != "." && dir != "/" {
2751 if _, exists := dirMap[dir]; exists {
2752 break
2753 }
2754 dirMap[dir] = nil
2755 dir = parentDir(dir)
2756 }
2757 }
Cole Faust18994c72023-02-28 16:02:16 -08002758 dirs = SortedKeys(dirMap)
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002759 var topDirs []string
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002760 for _, dir := range dirs {
2761 p := parentDir(dir)
2762 if p != "." && p != "/" {
2763 dirMap[p] = append(dirMap[p], PathForPhony(ctx, mmName(dir)))
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002764 } else if dir != "." && dir != "/" && dir != "" {
2765 topDirs = append(topDirs, dir)
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002766 }
2767 }
Cole Faust18994c72023-02-28 16:02:16 -08002768 return SortedKeys(dirMap), topDirs
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002769}
2770
Colin Cross0875c522017-11-28 17:34:01 -08002771func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
2772 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07002773
Colin Crossc3d87d32020-06-04 13:25:17 -07002774 mmTarget := func(dir string) string {
2775 return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
Colin Cross87d8b562017-04-25 10:01:55 -07002776 }
2777
Colin Cross0875c522017-11-28 17:34:01 -08002778 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002779
Colin Cross0875c522017-11-28 17:34:01 -08002780 ctx.VisitAllModules(func(module Module) {
Yu Liuddc2e1a2024-08-20 21:31:22 +00002781 info := OtherModuleProviderOrDefault(ctx, module, FinalModuleBuildTargetsProvider)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002782
Yu Liuddc2e1a2024-08-20 21:31:22 +00002783 if info.CheckbuildTarget != nil {
2784 checkbuildDeps = append(checkbuildDeps, info.CheckbuildTarget)
2785 modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.CheckbuildTarget)
Colin Cross0875c522017-11-28 17:34:01 -08002786 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07002787
Yu Liuddc2e1a2024-08-20 21:31:22 +00002788 if info.InstallTarget != nil {
2789 modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.InstallTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002790 }
2791 })
2792
Dan Willemsen5ba07e82015-12-11 13:51:06 -08002793 suffix := ""
Jingwen Chencda22c92020-11-23 00:22:30 -05002794 if ctx.Config().KatiEnabled() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08002795 suffix = "-soong"
2796 }
2797
Colin Cross1f8c52b2015-06-16 16:38:17 -07002798 // Create a top-level checkbuild target that depends on all modules
Colin Crossc3d87d32020-06-04 13:25:17 -07002799 ctx.Phony("checkbuild"+suffix, checkbuildDeps...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002800
Dan Willemsend2e95fb2017-09-20 14:30:50 -07002801 // Make will generate the MODULES-IN-* targets
Jingwen Chencda22c92020-11-23 00:22:30 -05002802 if ctx.Config().KatiEnabled() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07002803 return
2804 }
2805
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002806 dirs, _ := AddAncestors(ctx, modulesInDir, mmTarget)
Colin Cross87d8b562017-04-25 10:01:55 -07002807
Dan Willemsend2e95fb2017-09-20 14:30:50 -07002808 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
2809 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
2810 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07002811 for _, dir := range dirs {
Colin Crossc3d87d32020-06-04 13:25:17 -07002812 ctx.Phony(mmTarget(dir), modulesInDir[dir]...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002813 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07002814
2815 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
Jiyong Park1613e552020-09-14 19:43:17 +09002816 type osAndCross struct {
2817 os OsType
2818 hostCross bool
2819 }
2820 osDeps := map[osAndCross]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08002821 ctx.VisitAllModules(func(module Module) {
Cole Fausta963b942024-04-11 17:43:00 -07002822 if module.Enabled(ctx) {
Jiyong Park1613e552020-09-14 19:43:17 +09002823 key := osAndCross{os: module.Target().Os, hostCross: module.Target().HostCross}
Yu Liud46e5ae2024-08-15 18:46:17 +00002824 osDeps[key] = append(osDeps[key], OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).CheckbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07002825 }
2826 })
2827
Colin Cross0875c522017-11-28 17:34:01 -08002828 osClass := make(map[string]Paths)
Jiyong Park1613e552020-09-14 19:43:17 +09002829 for key, deps := range osDeps {
Dan Willemsen61d88b82017-09-20 17:29:08 -07002830 var className string
2831
Jiyong Park1613e552020-09-14 19:43:17 +09002832 switch key.os.Class {
Dan Willemsen61d88b82017-09-20 17:29:08 -07002833 case Host:
Jiyong Park1613e552020-09-14 19:43:17 +09002834 if key.hostCross {
2835 className = "host-cross"
2836 } else {
2837 className = "host"
2838 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07002839 case Device:
2840 className = "target"
2841 default:
2842 continue
2843 }
2844
Jiyong Park1613e552020-09-14 19:43:17 +09002845 name := className + "-" + key.os.Name
Colin Crossc3d87d32020-06-04 13:25:17 -07002846 osClass[className] = append(osClass[className], PathForPhony(ctx, name))
Dan Willemsen61d88b82017-09-20 17:29:08 -07002847
Colin Crossc3d87d32020-06-04 13:25:17 -07002848 ctx.Phony(name, deps...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07002849 }
2850
2851 // Wrap those into host|host-cross|target phony rules
Cole Faust18994c72023-02-28 16:02:16 -08002852 for _, class := range SortedKeys(osClass) {
Colin Crossc3d87d32020-06-04 13:25:17 -07002853 ctx.Phony(class, osClass[class]...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07002854 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07002855}
Colin Crossd779da42015-12-17 18:00:23 -08002856
Brandon Lee5d45c6f2018-08-15 15:35:38 -07002857// Collect information for opening IDE project files in java/jdeps.go.
2858type IDEInfo interface {
Cole Faustb36d31d2024-08-27 16:04:28 -07002859 IDEInfo(ctx BaseModuleContext, ideInfo *IdeInfo)
Brandon Lee5d45c6f2018-08-15 15:35:38 -07002860 BaseModuleName() string
2861}
2862
2863// Extract the base module name from the Import name.
2864// Often the Import name has a prefix "prebuilt_".
2865// Remove the prefix explicitly if needed
2866// until we find a better solution to get the Import name.
2867type IDECustomizedModuleName interface {
2868 IDECustomizedModuleName() string
2869}
2870
Cole Faust08c7f862024-08-27 15:03:59 -07002871// Collect information for opening IDE project files in java/jdeps.go.
Brandon Lee5d45c6f2018-08-15 15:35:38 -07002872type IdeInfo struct {
Cole Faust08c7f862024-08-27 15:03:59 -07002873 BaseModuleName string `json:"-"`
Brandon Lee5d45c6f2018-08-15 15:35:38 -07002874 Deps []string `json:"dependencies,omitempty"`
2875 Srcs []string `json:"srcs,omitempty"`
2876 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
2877 Jarjar_rules []string `json:"jarjar_rules,omitempty"`
2878 Jars []string `json:"jars,omitempty"`
2879 Classes []string `json:"class,omitempty"`
2880 Installed_paths []string `json:"installed,omitempty"`
patricktu18c82ff2019-05-10 15:48:50 +08002881 SrcJars []string `json:"srcjars,omitempty"`
bralee1fbf4402020-05-21 10:11:59 +08002882 Paths []string `json:"path,omitempty"`
Yikef6282022022-04-13 20:41:01 +08002883 Static_libs []string `json:"static_libs,omitempty"`
2884 Libs []string `json:"libs,omitempty"`
Brandon Lee5d45c6f2018-08-15 15:35:38 -07002885}
Paul Duffinf88d8e02020-05-07 20:21:34 +01002886
Cole Faust08c7f862024-08-27 15:03:59 -07002887// Merge merges two IdeInfos and produces a new one, leaving the origional unchanged
2888func (i IdeInfo) Merge(other IdeInfo) IdeInfo {
2889 return IdeInfo{
2890 Deps: mergeStringLists(i.Deps, other.Deps),
2891 Srcs: mergeStringLists(i.Srcs, other.Srcs),
2892 Aidl_include_dirs: mergeStringLists(i.Aidl_include_dirs, other.Aidl_include_dirs),
2893 Jarjar_rules: mergeStringLists(i.Jarjar_rules, other.Jarjar_rules),
2894 Jars: mergeStringLists(i.Jars, other.Jars),
2895 Classes: mergeStringLists(i.Classes, other.Classes),
2896 Installed_paths: mergeStringLists(i.Installed_paths, other.Installed_paths),
2897 SrcJars: mergeStringLists(i.SrcJars, other.SrcJars),
2898 Paths: mergeStringLists(i.Paths, other.Paths),
2899 Static_libs: mergeStringLists(i.Static_libs, other.Static_libs),
2900 Libs: mergeStringLists(i.Libs, other.Libs),
2901 }
2902}
2903
2904// mergeStringLists appends the two string lists together and returns a new string list,
2905// leaving the originals unchanged. Duplicate strings will be deduplicated.
2906func mergeStringLists(a, b []string) []string {
2907 return FirstUniqueStrings(Concat(a, b))
2908}
2909
2910var IdeInfoProviderKey = blueprint.NewProvider[IdeInfo]()
2911
Paul Duffinf88d8e02020-05-07 20:21:34 +01002912func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error {
2913 bpctx := ctx.blueprintBaseModuleContext()
2914 return blueprint.CheckBlueprintSyntax(bpctx.ModuleFactories(), filename, contents)
2915}