blob: a1a9a4ad2e6bd5eb2bded8e91b693a03b59135a0 [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 (
Yu Liu26a716d2024-08-30 23:40:32 +000018 "bytes"
19 "encoding/gob"
20 "errors"
Colin Cross6ff51382015-12-17 16:39:19 -080021 "fmt"
Bob Badour4101c712022-02-09 11:54:35 -080022 "net/url"
Colin Cross3f40fa42015-01-30 17:27:36 -080023 "path/filepath"
Liz Kammer9525e712022-01-05 13:46:24 -050024 "reflect"
Colin Crossd6fd0132023-11-06 13:54:06 -080025 "slices"
Bob Badour4101c712022-02-09 11:54:35 -080026 "sort"
Colin Cross6ff51382015-12-17 16:39:19 -080027 "strings"
Tahsin Loqman77dc7d02022-12-19 16:27:25 +000028
Colin Crossf6566ed2015-03-24 11:13:38 -070029 "github.com/google/blueprint"
Colin Crossfe4bc362018-09-12 10:02:13 -070030 "github.com/google/blueprint/proptools"
Colin Cross3f40fa42015-01-30 17:27:36 -080031)
32
33var (
34 DeviceSharedLibrary = "shared_library"
35 DeviceStaticLibrary = "static_library"
Joe Onorato349ae8d2024-02-05 22:46:00 +000036 jarJarPrefixHandler func(ctx ModuleContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080037)
38
Colin Cross635c3b02016-05-18 15:37:25 -070039type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080040 blueprint.Module
41
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070042 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
43 // but GenerateAndroidBuildActions also has access to Android-specific information.
44 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -070045 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070046
Paul Duffin44f1d842020-06-26 20:17:02 +010047 // Add dependencies to the components of a module, i.e. modules that are created
48 // by the module and which are considered to be part of the creating module.
49 //
50 // This is called before prebuilts are renamed so as to allow a dependency to be
51 // added directly to a prebuilt child module instead of depending on a source module
52 // and relying on prebuilt processing to switch to the prebuilt module if preferred.
53 //
54 // A dependency on a prebuilt must include the "prebuilt_" prefix.
55 ComponentDepsMutator(ctx BottomUpMutatorContext)
56
Colin Cross1e676be2016-10-12 14:38:15 -070057 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080058
Colin Cross635c3b02016-05-18 15:37:25 -070059 base() *ModuleBase
Inseob Kimeec88e12020-01-22 11:11:29 +090060 Disable()
Cole Fauste8a87832024-09-11 11:35:46 -070061 Enabled(ctx ConfigurableEvaluatorContext) bool
Colin Crossa1ad8d12016-06-01 17:09:44 -070062 Target() Target
Paul Duffinc04fb9e2021-03-01 12:25:10 +000063 MultiTargets() []Target
Paul Duffinb42fa672021-09-09 16:37:49 +010064
65 // ImageVariation returns the image variation of this module.
66 //
67 // The returned structure has its Mutator field set to "image" and its Variation field set to the
68 // image variation, e.g. recovery, ramdisk, etc.. The Variation field is "" for host modules and
69 // device modules that have no image variation.
70 ImageVariation() blueprint.Variation
71
Anton Hansson1ee62c02020-06-30 11:51:53 +010072 Owner() string
Dan Willemsen782a2d12015-12-21 14:55:28 -080073 InstallInData() bool
Jaewoong Jung0949f312019-09-11 10:25:18 -070074 InstallInTestcases() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -070075 InstallInSanitizerDir() bool
Yifan Hong1b3348d2020-01-21 15:53:22 -080076 InstallInRamdisk() bool
Yifan Hong60e0cfb2020-10-21 15:17:56 -070077 InstallInVendorRamdisk() bool
Inseob Kim08758f02021-04-08 21:13:22 +090078 InstallInDebugRamdisk() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +090079 InstallInRecovery() bool
Colin Cross90ba5f42019-10-02 11:10:58 -070080 InstallInRoot() bool
Colin Crossea30d852023-11-29 16:00:16 -080081 InstallInOdm() bool
82 InstallInProduct() bool
Kiyoung Kimae11c232021-07-19 11:38:04 +090083 InstallInVendor() bool
Spandan Das950deca2024-10-01 18:35:23 +000084 InstallInSystemExt() bool
Jiyong Park87788b52020-09-01 12:37:45 +090085 InstallForceOS() (*OsType, *ArchType)
Jiyong Parkce243632023-02-17 18:22:25 +090086 PartitionTag(DeviceConfig) string
Colin Crossa9c8c9f2020-12-16 10:20:23 -080087 HideFromMake()
88 IsHideFromMake() bool
Martin Stjernholm9e7f45e2020-12-23 03:50:30 +000089 IsSkipInstall() bool
Iván Budnik295da162023-03-10 16:11:26 +000090 MakeUninstallable()
Liz Kammer5ca3a622020-08-05 15:40:41 -070091 ReplacedByPrebuilt()
92 IsReplacedByPrebuilt() bool
Jiyong Park374510b2018-03-19 18:23:01 +090093 ExportedToMake() bool
Justin Yun1871f902023-04-07 20:13:19 +090094 EffectiveLicenseKinds() []string
Justin Yun885a7de2021-06-29 20:34:53 +090095 EffectiveLicenseFiles() Paths
Colin Cross36242852017-06-23 15:06:31 -070096
97 AddProperties(props ...interface{})
98 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -070099
Colin Crossae887032017-10-23 17:16:14 -0700100 BuildParamsForTests() []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800101 RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800102 VariablesForTests() map[string]string
Paul Duffine2453c72019-05-31 14:00:04 +0100103
Colin Cross9a362232019-07-01 15:32:45 -0700104 // String returns a string that includes the module name and variants for printing during debugging.
105 String() string
106
Paul Duffine2453c72019-05-31 14:00:04 +0100107 // Get the qualified module id for this module.
108 qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName
109
110 // Get information about the properties that can contain visibility rules.
111 visibilityProperties() []visibilityProperty
Paul Duffin63c6e182019-07-24 14:24:38 +0100112
Cole Fauste8a87832024-09-11 11:35:46 -0700113 RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string
Jiyong Park6a8cf5f2019-12-30 16:31:09 +0900114 HostRequiredModuleNames() []string
115 TargetRequiredModuleNames() []string
Cole Fauste8a87832024-09-11 11:35:46 -0700116 VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string
Colin Cross897266e2020-02-13 13:22:08 -0800117
Cole Fauste8a87832024-09-11 11:35:46 -0700118 ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator
Paul Duffine2453c72019-05-31 14:00:04 +0100119}
120
121// Qualified id for a module
122type qualifiedModuleName struct {
123 // The package (i.e. directory) in which the module is defined, without trailing /
124 pkg string
125
126 // The name of the module, empty string if package.
127 name string
128}
129
130func (q qualifiedModuleName) String() string {
131 if q.name == "" {
132 return "//" + q.pkg
133 }
134 return "//" + q.pkg + ":" + q.name
135}
136
Paul Duffine484f472019-06-20 16:38:08 +0100137func (q qualifiedModuleName) isRootPackage() bool {
138 return q.pkg == "" && q.name == ""
139}
140
Paul Duffine2453c72019-05-31 14:00:04 +0100141// Get the id for the package containing this module.
142func (q qualifiedModuleName) getContainingPackageId() qualifiedModuleName {
143 pkg := q.pkg
144 if q.name == "" {
Paul Duffine484f472019-06-20 16:38:08 +0100145 if pkg == "" {
146 panic(fmt.Errorf("Cannot get containing package id of root package"))
147 }
148
149 index := strings.LastIndex(pkg, "/")
150 if index == -1 {
151 pkg = ""
152 } else {
153 pkg = pkg[:index]
154 }
Paul Duffine2453c72019-05-31 14:00:04 +0100155 }
156 return newPackageId(pkg)
157}
158
159func newPackageId(pkg string) qualifiedModuleName {
160 // A qualified id for a package module has no name.
161 return qualifiedModuleName{pkg: pkg, name: ""}
Colin Cross3f40fa42015-01-30 17:27:36 -0800162}
163
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000164type Dist struct {
165 // Copy the output of this module to the $DIST_DIR when `dist` is specified on the
166 // command line and any of these targets are also on the command line, or otherwise
167 // built
168 Targets []string `android:"arch_variant"`
169
170 // The name of the output artifact. This defaults to the basename of the output of
171 // the module.
172 Dest *string `android:"arch_variant"`
173
174 // The directory within the dist directory to store the artifact. Defaults to the
175 // top level directory ("").
176 Dir *string `android:"arch_variant"`
177
178 // A suffix to add to the artifact file name (before any extension).
179 Suffix *string `android:"arch_variant"`
180
Trevor Radcliffe90727f42022-03-21 19:34:02 +0000181 // If true, then the artifact file will be appended with _<product name>. For
182 // example, if the product is coral and the module is an android_app module
183 // of name foo, then the artifact would be foo_coral.apk. If false, there is
184 // no change to the artifact file name.
185 Append_artifact_with_product *bool `android:"arch_variant"`
186
Paul Duffin74f05592020-11-25 16:37:46 +0000187 // A string tag to select the OutputFiles associated with the tag.
188 //
189 // If no tag is specified then it will select the default dist paths provided
190 // by the module type. If a tag of "" is specified then it will return the
191 // default output files provided by the modules, i.e. the result of calling
192 // OutputFiles("").
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000193 Tag *string `android:"arch_variant"`
194}
195
Bob Badour4101c712022-02-09 11:54:35 -0800196// NamedPath associates a path with a name. e.g. a license text path with a package name
197type NamedPath struct {
198 Path Path
199 Name string
200}
201
202// String returns an escaped string representing the `NamedPath`.
203func (p NamedPath) String() string {
204 if len(p.Name) > 0 {
205 return p.Path.String() + ":" + url.QueryEscape(p.Name)
206 }
207 return p.Path.String()
208}
209
210// NamedPaths describes a list of paths each associated with a name.
211type NamedPaths []NamedPath
212
213// Strings returns a list of escaped strings representing each `NamedPath` in the list.
214func (l NamedPaths) Strings() []string {
215 result := make([]string, 0, len(l))
216 for _, p := range l {
217 result = append(result, p.String())
218 }
219 return result
220}
221
222// SortedUniqueNamedPaths modifies `l` in place to return the sorted unique subset.
223func SortedUniqueNamedPaths(l NamedPaths) NamedPaths {
224 if len(l) == 0 {
225 return l
226 }
227 sort.Slice(l, func(i, j int) bool {
228 return l[i].String() < l[j].String()
229 })
230 k := 0
231 for i := 1; i < len(l); i++ {
232 if l[i].String() == l[k].String() {
233 continue
234 }
235 k++
236 if k < i {
237 l[k] = l[i]
238 }
239 }
240 return l[:k+1]
241}
242
Colin Crossfc754582016-05-17 16:34:16 -0700243type nameProperties struct {
244 // The name of the module. Must be unique across all modules.
Nan Zhang0007d812017-11-07 10:57:05 -0800245 Name *string
Colin Crossfc754582016-05-17 16:34:16 -0700246}
247
Colin Cross08d6f8f2020-11-19 02:33:19 +0000248type commonProperties struct {
Dan Willemsen0effe062015-11-30 16:06:01 -0800249 // emit build rules for this module
Paul Duffin54d9bb72020-02-12 10:20:56 +0000250 //
251 // Disabling a module should only be done for those modules that cannot be built
252 // in the current environment. Modules that can build in the current environment
253 // but are not usually required (e.g. superceded by a prebuilt) should not be
254 // disabled as that will prevent them from being built by the checkbuild target
255 // and so prevent early detection of changes that have broken those modules.
Cole Fausta963b942024-04-11 17:43:00 -0700256 Enabled proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800257
Paul Duffin2e61fa62019-03-28 14:10:57 +0000258 // Controls the visibility of this module to other modules. Allowable values are one or more of
259 // these formats:
260 //
261 // ["//visibility:public"]: Anyone can use this module.
262 // ["//visibility:private"]: Only rules in the module's package (not its subpackages) can use
263 // this module.
Paul Duffin51084ff2020-05-05 19:19:22 +0100264 // ["//visibility:override"]: Discards any rules inherited from defaults or a creating module.
265 // Can only be used at the beginning of a list of visibility rules.
Paul Duffin2e61fa62019-03-28 14:10:57 +0000266 // ["//some/package:__pkg__", "//other/package:__pkg__"]: Only modules in some/package and
267 // other/package (defined in some/package/*.bp and other/package/*.bp) have access to
268 // this module. Note that sub-packages do not have access to the rule; for example,
269 // //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__
270 // is a special module and must be used verbatim. It represents all of the modules in the
271 // package.
272 // ["//project:__subpackages__", "//other:__subpackages__"]: Only modules in packages project
273 // or other or in one of their sub-packages have access to this module. For example,
274 // //project:rule, //project/library:lib or //other/testing/internal:munge are allowed
275 // to depend on this rule (but not //independent:evil)
276 // ["//project"]: This is shorthand for ["//project:__pkg__"]
277 // [":__subpackages__"]: This is shorthand for ["//project:__subpackages__"] where
278 // //project is the module's package. e.g. using [":__subpackages__"] in
279 // packages/apps/Settings/Android.bp is equivalent to
280 // //packages/apps/Settings:__subpackages__.
281 // ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public
282 // for now. It is an error if it is used in a module.
Paul Duffine2453c72019-05-31 14:00:04 +0100283 //
284 // If a module does not specify the `visibility` property then it uses the
285 // `default_visibility` property of the `package` module in the module's package.
286 //
287 // If the `default_visibility` property is not set for the module's package then
Paul Duffine484f472019-06-20 16:38:08 +0100288 // it will use the `default_visibility` of its closest ancestor package for which
289 // a `default_visibility` property is specified.
290 //
291 // If no `default_visibility` property can be found then the module uses the
292 // global default of `//visibility:legacy_public`.
Paul Duffine2453c72019-05-31 14:00:04 +0100293 //
Paul Duffin95d53b52019-07-24 13:45:05 +0100294 // The `visibility` property has no effect on a defaults module although it does
295 // apply to any non-defaults module that uses it. To set the visibility of a
296 // defaults module, use the `defaults_visibility` property on the defaults module;
297 // not to be confused with the `default_visibility` property on the package module.
298 //
Elliott Hughes10363162024-01-09 22:02:03 +0000299 // See https://android.googlesource.com/platform/build/soong/+/main/README.md#visibility for
Paul Duffin2e61fa62019-03-28 14:10:57 +0000300 // more details.
301 Visibility []string
302
Bob Badour37af0462021-01-07 03:34:31 +0000303 // Describes the licenses applicable to this module. Must reference license modules.
304 Licenses []string
305
306 // Flattened from direct license dependencies. Equal to Licenses unless particular module adds more.
307 Effective_licenses []string `blueprint:"mutated"`
308 // Override of module name when reporting licenses
309 Effective_package_name *string `blueprint:"mutated"`
310 // Notice files
Bob Badour4101c712022-02-09 11:54:35 -0800311 Effective_license_text NamedPaths `blueprint:"mutated"`
Bob Badour37af0462021-01-07 03:34:31 +0000312 // License names
313 Effective_license_kinds []string `blueprint:"mutated"`
314 // License conditions
315 Effective_license_conditions []string `blueprint:"mutated"`
316
Colin Cross7d5136f2015-05-11 13:39:40 -0700317 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values
Colin Cross3f40fa42015-01-30 17:27:36 -0800318 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
319 // 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 +0000320 // platform).
Colin Cross7d716ba2017-11-01 10:38:29 -0700321 Compile_multilib *string `android:"arch_variant"`
Colin Cross69617d32016-09-06 10:39:07 -0700322
323 Target struct {
324 Host struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700325 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700326 }
327 Android struct {
Colin Cross7d716ba2017-11-01 10:38:29 -0700328 Compile_multilib *string
Colin Cross69617d32016-09-06 10:39:07 -0700329 }
330 }
331
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000332 // If set to true then the archMutator will create variants for each arch specific target
333 // (e.g. 32/64) that the module is required to produce. If set to false then it will only
334 // create a variant for the architecture and will list the additional arch specific targets
335 // that the variant needs to produce in the CompileMultiTargets property.
Colin Crossee0bc3b2018-10-02 22:01:37 -0700336 UseTargetVariants bool `blueprint:"mutated"`
337 Default_multilib string `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800338
Dan Willemsen782a2d12015-12-21 14:55:28 -0800339 // whether this is a proprietary vendor module, and should be installed into /vendor
Colin Cross7d716ba2017-11-01 10:38:29 -0700340 Proprietary *bool
Dan Willemsen782a2d12015-12-21 14:55:28 -0800341
Colin Cross55708f32017-03-20 13:23:34 -0700342 // vendor who owns this module
Dan Willemsenefac4a82017-07-18 19:42:09 -0700343 Owner *string
Colin Cross55708f32017-03-20 13:23:34 -0700344
Jiyong Park2db76922017-11-08 16:03:48 +0900345 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
346 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
347 // Use `soc_specific` instead for better meaning.
Colin Cross7d716ba2017-11-01 10:38:29 -0700348 Vendor *bool
Dan Willemsenaa118f92017-04-06 12:49:58 -0700349
Jiyong Park2db76922017-11-08 16:03:48 +0900350 // whether this module is specific to an SoC (System-On-a-Chip). When set to true,
351 // it is installed into /vendor (or /system/vendor if vendor partition does not exist).
352 Soc_specific *bool
353
354 // whether this module is specific to a device, not only for SoC, but also for off-chip
355 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition
356 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist).
357 // This implies `soc_specific:true`.
358 Device_specific *bool
359
360 // whether this module is specific to a software configuration of a product (e.g. country,
Jaekyun Seok5cfbfbb2018-01-10 19:00:15 +0900361 // network operator, etc). When set to true, it is installed into /product (or
362 // /system/product if product partition does not exist).
Jiyong Park2db76922017-11-08 16:03:48 +0900363 Product_specific *bool
364
Justin Yund5f6c822019-06-25 16:47:17 +0900365 // whether this module extends system. When set to true, it is installed into /system_ext
366 // (or /system/system_ext if system_ext partition does not exist).
367 System_ext_specific *bool
368
Jiyong Parkf9332f12018-02-01 00:54:12 +0900369 // Whether this module is installed to recovery partition
370 Recovery *bool
371
Yifan Hong1b3348d2020-01-21 15:53:22 -0800372 // Whether this module is installed to ramdisk
373 Ramdisk *bool
374
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700375 // Whether this module is installed to vendor ramdisk
376 Vendor_ramdisk *bool
377
Inseob Kim08758f02021-04-08 21:13:22 +0900378 // Whether this module is installed to debug ramdisk
379 Debug_ramdisk *bool
380
Jaewoong Jung8e93aba2021-03-02 16:58:08 -0800381 // Whether this module is built for non-native architectures (also known as native bridge binary)
dimitry1f33e402019-03-26 12:39:31 +0100382 Native_bridge_supported *bool `android:"arch_variant"`
383
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700384 // init.rc files to be installed if this module is installed
Inseob Kim713b87d2024-09-13 11:29:54 +0900385 Init_rc proptools.Configurable[[]string] `android:"arch_variant,path"`
Dan Willemsen2277bcb2016-07-25 20:27:39 -0700386
Steven Moreland57a23d22018-04-04 15:42:19 -0700387 // VINTF manifest fragments to be installed if this module is installed
Inseob Kimf2237022024-07-23 13:36:31 +0900388 Vintf_fragments proptools.Configurable[[]string] `android:"path"`
Steven Moreland57a23d22018-04-04 15:42:19 -0700389
Chris Wolfe998306e2016-08-15 14:47:23 -0400390 // names of other modules to install if this module is installed
Cole Faust43ddd082024-06-17 12:32:40 -0700391 Required proptools.Configurable[[]string] `android:"arch_variant"`
Chris Wolfe998306e2016-08-15 14:47:23 -0400392
Sasha Smundakb6d23052019-04-01 18:37:36 -0700393 // names of other modules to install on host if this module is installed
394 Host_required []string `android:"arch_variant"`
395
396 // names of other modules to install on target if this module is installed
397 Target_required []string `android:"arch_variant"`
398
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000399 // The OsType of artifacts that this module variant is responsible for creating.
400 //
401 // Set by osMutator
402 CompileOS OsType `blueprint:"mutated"`
403
Cole Faust0aa21cc2024-03-20 12:28:03 -0700404 // Set to true after the arch mutator has run on this module and set CompileTarget,
405 // CompileMultiTargets, and CompilePrimary
406 ArchReady bool `blueprint:"mutated"`
407
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000408 // The Target of artifacts that this module variant is responsible for creating.
409 //
410 // Set by archMutator
411 CompileTarget Target `blueprint:"mutated"`
412
413 // The additional arch specific targets (e.g. 32/64 bit) that this module variant is
414 // responsible for creating.
415 //
416 // By default this is nil as, where necessary, separate variants are created for the
417 // different multilib types supported and that information is encapsulated in the
418 // CompileTarget so the module variant simply needs to create artifacts for that.
419 //
420 // However, if UseTargetVariants is set to false (e.g. by
421 // InitAndroidMultiTargetsArchModule) then no separate variants are created for the
422 // multilib targets. Instead a single variant is created for the architecture and
423 // this contains the multilib specific targets that this variant should create.
424 //
425 // Set by archMutator
Colin Crossee0bc3b2018-10-02 22:01:37 -0700426 CompileMultiTargets []Target `blueprint:"mutated"`
Paul Duffinca7f0ef2020-02-25 15:50:49 +0000427
428 // True if the module variant's CompileTarget is the primary target
429 //
430 // Set by archMutator
431 CompilePrimary bool `blueprint:"mutated"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800432
433 // Set by InitAndroidModule
434 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
Dan Willemsen0b24c742016-10-04 15:13:37 -0700435 ArchSpecific bool `blueprint:"mutated"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700436
Paul Duffin1356d8c2020-02-25 19:26:33 +0000437 // If set to true then a CommonOS variant will be created which will have dependencies
438 // on all its OsType specific variants. Used by sdk/module_exports to create a snapshot
439 // that covers all os and architecture variants.
440 //
441 // The OsType specific variants can be retrieved by calling
442 // GetOsSpecificVariantsOfCommonOSVariant
443 //
444 // Set at module initialization time by calling InitCommonOSAndroidMultiTargetsArchModule
445 CreateCommonOSVariant bool `blueprint:"mutated"`
446
Jiyong Park3f627e62024-05-01 16:14:38 +0900447 // When set to true, this module is not installed to the full install path (ex: under
448 // out/target/product/<name>/<partition>). It can be installed only to the packaging
449 // modules like android_filesystem.
450 No_full_install *bool
451
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800452 // When HideFromMake is set to true, no entry for this variant will be emitted in the
453 // generated Android.mk file.
454 HideFromMake bool `blueprint:"mutated"`
455
456 // When SkipInstall is set to true, calls to ctx.InstallFile, ctx.InstallExecutable,
457 // ctx.InstallSymlink and ctx.InstallAbsoluteSymlink act like calls to ctx.PackageFile
458 // and don't create a rule to install the file.
Colin Crossce75d2c2016-10-06 16:12:58 -0700459 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800460
Colin Crossbd3a16b2023-04-25 11:30:51 -0700461 // UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex
462 // mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant
463 // is used to avoid adding install or packaging dependencies into libraries provided
464 // by apexes.
465 UninstallableApexPlatformVariant bool `blueprint:"mutated"`
466
Liz Kammer5ca3a622020-08-05 15:40:41 -0700467 // Whether the module has been replaced by a prebuilt
468 ReplacedByPrebuilt bool `blueprint:"mutated"`
469
Justin Yun32f053b2020-07-31 23:07:17 +0900470 // Disabled by mutators. If set to true, it overrides Enabled property.
471 ForcedDisabled bool `blueprint:"mutated"`
472
Jeff Gaston088e29e2017-11-29 16:47:17 -0800473 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross6c4f21f2019-06-06 15:41:36 -0700474
Liz Kammerc13f7852023-05-17 13:01:48 -0400475 MissingDeps []string `blueprint:"mutated"`
476 CheckedMissingDeps bool `blueprint:"mutated"`
Colin Cross9a362232019-07-01 15:32:45 -0700477
478 // Name and variant strings stored by mutators to enable Module.String()
479 DebugName string `blueprint:"mutated"`
480 DebugMutators []string `blueprint:"mutated"`
481 DebugVariations []string `blueprint:"mutated"`
Colin Cross7228ecd2019-11-18 16:00:16 -0800482
Colin Crossa6845402020-11-16 15:08:19 -0800483 // ImageVariation is set by ImageMutator to specify which image this variation is for,
484 // for example "" for core or "recovery" for recovery. It will often be set to one of the
485 // constants in image.go, but can also be set to a custom value by individual module types.
Colin Cross7228ecd2019-11-18 16:00:16 -0800486 ImageVariation string `blueprint:"mutated"`
Liz Kammer2ada09a2021-08-11 00:17:36 -0400487
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800488 // The team (defined by the owner/vendor) who owns the property.
489 Team *string `android:"path"`
Kiyoung Kimfaf6af32024-08-12 11:15:19 +0900490
491 // vintf_fragment Modules required from this module.
492 Vintf_fragment_modules proptools.Configurable[[]string] `android:"path"`
Jiyong Parka574d532024-08-28 18:06:43 +0900493
494 // List of module names that are prevented from being installed when this module gets
495 // installed.
496 Overrides []string
Colin Cross3f40fa42015-01-30 17:27:36 -0800497}
498
Paul Duffined875132020-09-02 13:08:57 +0100499type distProperties struct {
500 // configuration to distribute output files from this module to the distribution
501 // directory (default: $OUT/dist, configurable with $DIST_DIR)
502 Dist Dist `android:"arch_variant"`
503
504 // a list of configurations to distribute output files from this module to the
505 // distribution directory (default: $OUT/dist, configurable with $DIST_DIR)
506 Dists []Dist `android:"arch_variant"`
507}
508
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800509type TeamDepTagType struct {
510 blueprint.BaseDependencyTag
511}
512
513var teamDepTag = TeamDepTagType{}
514
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900515// Dependency tag for required, host_required, and target_required modules.
516var RequiredDepTag = struct {
517 blueprint.BaseDependencyTag
518 InstallAlwaysNeededDependencyTag
519 // Requiring disabled module has been supported (as a side effect of this being implemented
520 // in Make). We may want to make it an error, but for now, let's keep the existing behavior.
521 AlwaysAllowDisabledModuleDependencyTag
522}{}
523
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800524// CommonTestOptions represents the common `test_options` properties in
525// Android.bp.
526type CommonTestOptions struct {
527 // If the test is a hostside (no device required) unittest that shall be run
528 // during presubmit check.
529 Unit_test *bool
Zhenhuang Wang409d2772022-08-22 16:00:05 +0800530
531 // Tags provide additional metadata to customize test execution by downstream
532 // test runners. The tags have no special meaning to Soong.
533 Tags []string
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800534}
535
536// SetAndroidMkEntries sets AndroidMkEntries according to the value of base
537// `test_options`.
538func (t *CommonTestOptions) SetAndroidMkEntries(entries *AndroidMkEntries) {
539 entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test))
Zhenhuang Wang409d2772022-08-22 16:00:05 +0800540 if len(t.Tags) > 0 {
541 entries.AddStrings("LOCAL_TEST_OPTIONS_TAGS", t.Tags...)
542 }
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800543}
544
Paul Duffin74f05592020-11-25 16:37:46 +0000545// The key to use in TaggedDistFiles when a Dist structure does not specify a
546// tag property. This intentionally does not use "" as the default because that
547// would mean that an empty tag would have a different meaning when used in a dist
548// structure that when used to reference a specific set of output paths using the
549// :module{tag} syntax, which passes tag to the OutputFiles(tag) method.
550const DefaultDistTag = "<default-dist-tag>"
551
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000552// A map of OutputFile tag keys to Paths, for disting purposes.
553type TaggedDistFiles map[string]Paths
554
Paul Duffin74f05592020-11-25 16:37:46 +0000555// addPathsForTag adds a mapping from the tag to the paths. If the map is nil
556// then it will create a map, update it and then return it. If a mapping already
557// exists for the tag then the paths are appended to the end of the current list
558// of paths, ignoring any duplicates.
559func (t TaggedDistFiles) addPathsForTag(tag string, paths ...Path) TaggedDistFiles {
560 if t == nil {
561 t = make(TaggedDistFiles)
562 }
563
564 for _, distFile := range paths {
565 if distFile != nil && !t[tag].containsPath(distFile) {
566 t[tag] = append(t[tag], distFile)
567 }
568 }
569
570 return t
571}
572
573// merge merges the entries from the other TaggedDistFiles object into this one.
574// If the TaggedDistFiles is nil then it will create a new instance, merge the
575// other into it, and then return it.
576func (t TaggedDistFiles) merge(other TaggedDistFiles) TaggedDistFiles {
577 for tag, paths := range other {
578 t = t.addPathsForTag(tag, paths...)
579 }
580
581 return t
582}
583
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000584func MakeDefaultDistFiles(paths ...Path) TaggedDistFiles {
Sasha Smundake198eaf2022-08-04 13:07:02 -0700585 for _, p := range paths {
586 if p == nil {
Jingwen Chen7b27ca72020-07-24 09:13:49 +0000587 panic("The path to a dist file cannot be nil.")
588 }
589 }
590
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000591 // The default OutputFile tag is the empty "" string.
Paul Duffin74f05592020-11-25 16:37:46 +0000592 return TaggedDistFiles{DefaultDistTag: paths}
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000593}
594
Colin Cross3f40fa42015-01-30 17:27:36 -0800595type hostAndDeviceProperties struct {
Colin Cross4e81d702018-11-09 10:36:55 -0800596 // If set to true, build a variant of the module for the host. Defaults to false.
597 Host_supported *bool
598
599 // If set to true, build a variant of the module for the device. Defaults to true.
Colin Crossa4190c12016-07-12 13:11:25 -0700600 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800601}
602
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000603type hostCrossProperties struct {
604 // If set to true, build a variant of the module for the host cross. Defaults to true.
605 Host_cross_supported *bool
606}
607
Colin Crossc472d572015-03-17 15:06:21 -0700608type Multilib string
609
610const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800611 MultilibBoth Multilib = "both"
612 MultilibFirst Multilib = "first"
613 MultilibCommon Multilib = "common"
614 MultilibCommonFirst Multilib = "common_first"
Colin Crossc472d572015-03-17 15:06:21 -0700615)
616
Colin Crossa1ad8d12016-06-01 17:09:44 -0700617type HostOrDeviceSupported int
618
619const (
Colin Cross34037c62020-11-17 13:19:17 -0800620 hostSupported = 1 << iota
621 hostCrossSupported
622 deviceSupported
623 hostDefault
624 deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700625
626 // Host and HostCross are built by default. Device is not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800627 HostSupported = hostSupported | hostCrossSupported | hostDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700628
629 // Host is built by default. HostCross and Device are not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800630 HostSupportedNoCross = hostSupported | hostDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700631
632 // Device is built by default. Host and HostCross are not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800633 DeviceSupported = deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700634
Liz Kammer8631cc72021-08-23 21:12:07 +0000635 // By default, _only_ device variant is built. Device variant can be disabled with `device_supported: false`
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -0700636 // Host and HostCross are disabled by default and can be enabled with `host_supported: true`
Colin Cross34037c62020-11-17 13:19:17 -0800637 HostAndDeviceSupported = hostSupported | hostCrossSupported | deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700638
639 // Host, HostCross, and Device are built by default.
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -0700640 // Building Device can be disabled with `device_supported: false`
641 // Building Host and HostCross can be disabled with `host_supported: false`
Colin Cross34037c62020-11-17 13:19:17 -0800642 HostAndDeviceDefault = hostSupported | hostCrossSupported | hostDefault |
643 deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700644
645 // Nothing is supported. This is not exposed to the user, but used to mark a
646 // host only module as unsupported when the module type is not supported on
647 // the host OS. E.g. benchmarks are supported on Linux but not Darwin.
Colin Cross34037c62020-11-17 13:19:17 -0800648 NeitherHostNorDeviceSupported = 0
Colin Crossa1ad8d12016-06-01 17:09:44 -0700649)
650
Jiyong Park2db76922017-11-08 16:03:48 +0900651type moduleKind int
652
653const (
654 platformModule moduleKind = iota
655 deviceSpecificModule
656 socSpecificModule
657 productSpecificModule
Justin Yund5f6c822019-06-25 16:47:17 +0900658 systemExtSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900659)
660
661func (k moduleKind) String() string {
662 switch k {
663 case platformModule:
664 return "platform"
665 case deviceSpecificModule:
666 return "device-specific"
667 case socSpecificModule:
668 return "soc-specific"
669 case productSpecificModule:
670 return "product-specific"
Justin Yund5f6c822019-06-25 16:47:17 +0900671 case systemExtSpecificModule:
672 return "systemext-specific"
Jiyong Park2db76922017-11-08 16:03:48 +0900673 default:
674 panic(fmt.Errorf("unknown module kind %d", k))
675 }
676}
677
Colin Cross9d34f352019-11-22 16:03:51 -0800678func initAndroidModuleBase(m Module) {
679 m.base().module = m
680}
681
Colin Crossa6845402020-11-16 15:08:19 -0800682// InitAndroidModule initializes the Module as an Android module that is not architecture-specific.
683// It adds the common properties, for example "name" and "enabled".
Colin Cross36242852017-06-23 15:06:31 -0700684func InitAndroidModule(m Module) {
Colin Cross9d34f352019-11-22 16:03:51 -0800685 initAndroidModuleBase(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800686 base := m.base()
Colin Cross5049f022015-03-18 13:28:46 -0700687
Colin Cross36242852017-06-23 15:06:31 -0700688 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700689 &base.nameProperties,
Paul Duffined875132020-09-02 13:08:57 +0100690 &base.commonProperties,
691 &base.distProperties)
Colin Cross18c46802019-09-24 22:19:02 -0700692
Colin Crosseabaedd2020-02-06 17:01:55 -0800693 initProductVariableModule(m)
Colin Cross18c46802019-09-24 22:19:02 -0700694
Paul Duffin63c6e182019-07-24 14:24:38 +0100695 // The default_visibility property needs to be checked and parsed by the visibility module during
Paul Duffin5ec73ec2020-05-01 17:52:01 +0100696 // its checking and parsing phases so make it the primary visibility property.
697 setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility)
Bob Badour37af0462021-01-07 03:34:31 +0000698
699 // The default_applicable_licenses property needs to be checked and parsed by the licenses module during
700 // its checking and parsing phases so make it the primary licenses property.
701 setPrimaryLicensesProperty(m, "licenses", &base.commonProperties.Licenses)
Colin Cross5049f022015-03-18 13:28:46 -0700702}
703
Colin Crossa6845402020-11-16 15:08:19 -0800704// InitAndroidArchModule initializes the Module as an Android module that is architecture-specific.
705// It adds the common properties, for example "name" and "enabled", as well as runtime generated
706// property structs for architecture-specific versions of generic properties tagged with
707// `android:"arch_variant"`.
708//
Colin Crossd079e0b2022-08-16 10:27:33 -0700709// InitAndroidModule should not be called if InitAndroidArchModule was called.
Colin Cross36242852017-06-23 15:06:31 -0700710func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
711 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700712
713 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800714 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700715 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700716 base.commonProperties.ArchSpecific = true
Colin Crossee0bc3b2018-10-02 22:01:37 -0700717 base.commonProperties.UseTargetVariants = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800718
Colin Cross34037c62020-11-17 13:19:17 -0800719 if hod&hostSupported != 0 && hod&deviceSupported != 0 {
Colin Cross36242852017-06-23 15:06:31 -0700720 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800721 }
722
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000723 if hod&hostCrossSupported != 0 {
724 m.AddProperties(&base.hostCrossProperties)
725 }
726
Colin Crossa6845402020-11-16 15:08:19 -0800727 initArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800728}
729
Colin Crossa6845402020-11-16 15:08:19 -0800730// InitAndroidMultiTargetsArchModule initializes the Module as an Android module that is
731// architecture-specific, but will only have a single variant per OS that handles all the
732// architectures simultaneously. The list of Targets that it must handle will be available from
733// ModuleContext.MultiTargets. It adds the common properties, for example "name" and "enabled", as
734// well as runtime generated property structs for architecture-specific versions of generic
735// properties tagged with `android:"arch_variant"`.
736//
737// InitAndroidModule or InitAndroidArchModule should not be called if
738// InitAndroidMultiTargetsArchModule was called.
Colin Crossee0bc3b2018-10-02 22:01:37 -0700739func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
740 InitAndroidArchModule(m, hod, defaultMultilib)
741 m.base().commonProperties.UseTargetVariants = false
742}
743
Colin Crossa6845402020-11-16 15:08:19 -0800744// InitCommonOSAndroidMultiTargetsArchModule initializes the Module as an Android module that is
745// architecture-specific, but will only have a single variant per OS that handles all the
746// architectures simultaneously, and will also have an additional CommonOS variant that has
747// dependencies on all the OS-specific variants. The list of Targets that it must handle will be
748// available from ModuleContext.MultiTargets. It adds the common properties, for example "name" and
749// "enabled", as well as runtime generated property structs for architecture-specific versions of
750// generic properties tagged with `android:"arch_variant"`.
751//
752// InitAndroidModule, InitAndroidArchModule or InitAndroidMultiTargetsArchModule should not be
753// called if InitCommonOSAndroidMultiTargetsArchModule was called.
Paul Duffin1356d8c2020-02-25 19:26:33 +0000754func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
755 InitAndroidArchModule(m, hod, defaultMultilib)
756 m.base().commonProperties.UseTargetVariants = false
757 m.base().commonProperties.CreateCommonOSVariant = true
758}
759
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800760// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800761// modules. It should be included as an anonymous field in every module
762// struct definition. InitAndroidModule should then be called from the module's
763// factory function, and the return values from InitAndroidModule should be
764// returned from the factory function.
765//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800766// The ModuleBase type is responsible for implementing the GenerateBuildActions
767// method to support the blueprint.Module interface. This method will then call
768// the module's GenerateAndroidBuildActions method once for each build variant
Colin Cross25de6c32019-06-06 14:29:25 -0700769// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext
770// rather than the usual blueprint.ModuleContext.
771// ModuleContext exposes extra functionality specific to the Android build
Colin Cross3f40fa42015-01-30 17:27:36 -0800772// system including details about the particular build variant that is to be
773// generated.
774//
775// For example:
776//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800777// import (
778// "android/soong/android"
779// )
Colin Cross3f40fa42015-01-30 17:27:36 -0800780//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800781// type myModule struct {
782// android.ModuleBase
783// properties struct {
784// MyProperty string
785// }
786// }
Colin Cross3f40fa42015-01-30 17:27:36 -0800787//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800788// func NewMyModule() android.Module {
789// m := &myModule{}
790// m.AddProperties(&m.properties)
791// android.InitAndroidModule(m)
792// return m
793// }
Colin Cross3f40fa42015-01-30 17:27:36 -0800794//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800795// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
796// // Get the CPU architecture for the current build variant.
797// variantArch := ctx.Arch()
Colin Cross3f40fa42015-01-30 17:27:36 -0800798//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800799// // ...
800// }
Colin Cross635c3b02016-05-18 15:37:25 -0700801type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800802 // Putting the curiously recurring thing pointing to the thing that contains
803 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700804 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700805 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800806
Colin Crossfc754582016-05-17 16:34:16 -0700807 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800808 commonProperties commonProperties
Paul Duffined875132020-09-02 13:08:57 +0100809 distProperties distProperties
Colin Cross18c46802019-09-24 22:19:02 -0700810 variableProperties interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800811 hostAndDeviceProperties hostAndDeviceProperties
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000812 hostCrossProperties hostCrossProperties
Jingwen Chen5d864492021-02-24 07:20:12 -0500813
Usta851a3272022-01-05 23:42:33 -0500814 // Arch specific versions of structs in GetProperties() prior to
815 // initialization in InitAndroidArchModule, lets call it `generalProperties`.
816 // The outer index has the same order as generalProperties and the inner index
817 // chooses the props specific to the architecture. The interface{} value is an
818 // archPropRoot that is filled with arch specific values by the arch mutator.
Jingwen Chen5d864492021-02-24 07:20:12 -0500819 archProperties [][]interface{}
820
Paul Duffin63c6e182019-07-24 14:24:38 +0100821 // Information about all the properties on the module that contains visibility rules that need
822 // checking.
823 visibilityPropertyInfo []visibilityProperty
824
825 // The primary visibility property, may be nil, that controls access to the module.
826 primaryVisibilityProperty visibilityProperty
827
Bob Badour37af0462021-01-07 03:34:31 +0000828 // The primary licenses property, may be nil, records license metadata for the module.
829 primaryLicensesProperty applicableLicensesProperty
830
Yu Liueb6d7052024-08-27 22:35:54 +0000831 noAddressSanitizer bool
Colin Cross1f8c52b2015-06-16 16:38:17 -0700832
Colin Cross178a5092016-09-13 13:42:32 -0700833 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700834
835 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700836
837 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700838 buildParams []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800839 ruleParams map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800840 variables map[string]string
Colin Cross36242852017-06-23 15:06:31 -0700841}
842
Lukacs T. Berkid18d8ca2021-06-25 09:11:22 +0200843func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
Liz Kammer9525e712022-01-05 13:46:24 -0500844 (*d)["Android"] = map[string]interface{}{
845 // Properties set in Blueprint or in blueprint of a defaults modules
846 "SetProperties": m.propertiesWithValues(),
847 }
848}
849
850type propInfo struct {
Liz Kammer898e0762022-03-22 11:27:26 -0400851 Name string
852 Type string
853 Value string
854 Values []string
Liz Kammer9525e712022-01-05 13:46:24 -0500855}
856
857func (m *ModuleBase) propertiesWithValues() []propInfo {
858 var info []propInfo
859 props := m.GetProperties()
860
861 var propsWithValues func(name string, v reflect.Value)
862 propsWithValues = func(name string, v reflect.Value) {
863 kind := v.Kind()
864 switch kind {
865 case reflect.Ptr, reflect.Interface:
866 if v.IsNil() {
867 return
868 }
869 propsWithValues(name, v.Elem())
870 case reflect.Struct:
871 if v.IsZero() {
872 return
873 }
874 for i := 0; i < v.NumField(); i++ {
875 namePrefix := name
876 sTyp := v.Type().Field(i)
877 if proptools.ShouldSkipProperty(sTyp) {
878 continue
879 }
880 if name != "" && !strings.HasSuffix(namePrefix, ".") {
881 namePrefix += "."
882 }
883 if !proptools.IsEmbedded(sTyp) {
884 namePrefix += sTyp.Name
885 }
886 sVal := v.Field(i)
887 propsWithValues(namePrefix, sVal)
888 }
889 case reflect.Array, reflect.Slice:
890 if v.IsNil() {
891 return
892 }
893 elKind := v.Type().Elem().Kind()
Liz Kammer898e0762022-03-22 11:27:26 -0400894 info = append(info, propInfo{Name: name, Type: elKind.String() + " " + kind.String(), Values: sliceReflectionValue(v)})
Liz Kammer9525e712022-01-05 13:46:24 -0500895 default:
Liz Kammer898e0762022-03-22 11:27:26 -0400896 info = append(info, propInfo{Name: name, Type: kind.String(), Value: reflectionValue(v)})
Liz Kammer9525e712022-01-05 13:46:24 -0500897 }
898 }
899
900 for _, p := range props {
901 propsWithValues("", reflect.ValueOf(p).Elem())
902 }
Liz Kammer898e0762022-03-22 11:27:26 -0400903 sort.Slice(info, func(i, j int) bool {
904 return info[i].Name < info[j].Name
905 })
Liz Kammer9525e712022-01-05 13:46:24 -0500906 return info
Lukacs T. Berkid18d8ca2021-06-25 09:11:22 +0200907}
908
Liz Kammer898e0762022-03-22 11:27:26 -0400909func reflectionValue(value reflect.Value) string {
910 switch value.Kind() {
911 case reflect.Bool:
912 return fmt.Sprintf("%t", value.Bool())
913 case reflect.Int64:
914 return fmt.Sprintf("%d", value.Int())
915 case reflect.String:
916 return fmt.Sprintf("%s", value.String())
917 case reflect.Struct:
918 if value.IsZero() {
919 return "{}"
920 }
921 length := value.NumField()
922 vals := make([]string, length, length)
923 for i := 0; i < length; i++ {
924 sTyp := value.Type().Field(i)
925 if proptools.ShouldSkipProperty(sTyp) {
926 continue
927 }
928 name := sTyp.Name
929 vals[i] = fmt.Sprintf("%s: %s", name, reflectionValue(value.Field(i)))
930 }
931 return fmt.Sprintf("%s{%s}", value.Type(), strings.Join(vals, ", "))
932 case reflect.Array, reflect.Slice:
933 vals := sliceReflectionValue(value)
934 return fmt.Sprintf("[%s]", strings.Join(vals, ", "))
935 }
936 return ""
937}
938
939func sliceReflectionValue(value reflect.Value) []string {
940 length := value.Len()
941 vals := make([]string, length, length)
942 for i := 0; i < length; i++ {
943 vals[i] = reflectionValue(value.Index(i))
944 }
945 return vals
946}
947
Paul Duffin44f1d842020-06-26 20:17:02 +0100948func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {}
949
Colin Cross4157e882019-06-06 16:57:04 -0700950func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
Colin Cross5f692ec2019-02-01 16:53:07 -0800951
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800952func (m *ModuleBase) baseDepsMutator(ctx BottomUpMutatorContext) {
953 if m.Team() != "" {
954 ctx.AddDependency(ctx.Module(), teamDepTag, m.Team())
955 }
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900956
957 // TODO(jiyong): remove below case. This is to work around build errors happening
958 // on branches with reduced manifest like aosp_kernel-build-tools.
959 // In the branch, a build error occurs as follows.
960 // 1. aosp_kernel-build-tools is a reduced manifest branch. It doesn't have some git
961 // projects like external/bouncycastle
962 // 2. `boot_signer` is `required` by modules like `build_image` which is explicitly list as
963 // the top-level build goal (in the shell file that invokes Soong).
964 // 3. `boot_signer` depends on `bouncycastle-unbundled` which is in the missing git project.
965 // 4. aosp_kernel-build-tools invokes soong with `--skip-make`. Therefore, the absence of
966 // ALLOW_MISSING_DEPENDENCIES didn't cause a problem.
967 // 5. Now, since Soong understands `required` deps, it tries to build `boot_signer` and the
968 // absence of external/bouncycastle fails the build.
969 //
970 // Unfortunately, there's no way for Soong to correctly determine if it's running in a
971 // reduced manifest branch. Instead, here, we use the absence of DeviceArch or DeviceName as
972 // a strong signal, because that's very common across reduced manifest branches.
973 pv := ctx.Config().productVariables
974 fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil
975 if fullManifest {
Jiyong Parkf21dd652024-04-17 05:22:37 +0000976 addRequiredDeps(ctx)
Kiyoung Kimfaf6af32024-08-12 11:15:19 +0900977 addVintfFragmentDeps(ctx)
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900978 }
979}
980
981// addRequiredDeps adds required, target_required, and host_required as dependencies.
Jiyong Parkf21dd652024-04-17 05:22:37 +0000982func addRequiredDeps(ctx BottomUpMutatorContext) {
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900983 addDep := func(target Target, depName string) {
984 if !ctx.OtherModuleExists(depName) {
985 if ctx.Config().AllowMissingDependencies() {
986 return
987 }
988 }
989
990 // If Android native module requires another Android native module, ensure that
991 // they have the same bitness. This mimics the policy in select-bitness-of-required-modules
992 // in build/make/core/main.mk.
993 // TODO(jiyong): the Make-side does this only when the required module is a shared
994 // library or a native test.
Jiyong Parkf21dd652024-04-17 05:22:37 +0000995 bothInAndroid := ctx.Device() && target.Os.Class == Device
Jiyong Parkc4b1d552024-05-13 16:47:30 +0900996 nativeArch := InList(ctx.Arch().ArchType.Multilib, []string{"lib32", "lib64"}) &&
997 InList(target.Arch.ArchType.Multilib, []string{"lib32", "lib64"})
Jiyong Parkf21dd652024-04-17 05:22:37 +0000998 sameBitness := ctx.Arch().ArchType.Multilib == target.Arch.ArchType.Multilib
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900999 if bothInAndroid && nativeArch && !sameBitness {
1000 return
1001 }
1002
Jiyong Park8db44152024-05-28 12:22:04 +09001003 // ... also don't make a dependency between native bridge arch and non-native bridge
1004 // arches. b/342945184
1005 if ctx.Target().NativeBridge != target.NativeBridge {
1006 return
1007 }
1008
Spandan Das77e27d42024-09-26 23:53:58 +00001009 // Do not create a dependency from common variant to arch variant for `common_first` modules
1010 if multilib, _ := decodeMultilib(ctx, ctx.Module().base()); multilib == string(MultilibCommonFirst) {
1011 commonVariant := ctx.Arch().ArchType.Multilib == ""
1012 if bothInAndroid && commonVariant && InList(target.Arch.ArchType.Multilib, []string{"lib32", "lib64"}) {
1013 return
1014 }
1015 }
1016
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001017 variation := target.Variations()
1018 if ctx.OtherModuleFarDependencyVariantExists(variation, depName) {
1019 ctx.AddFarVariationDependencies(variation, RequiredDepTag, depName)
1020 }
1021 }
1022
Jiyong Park73e5bab2024-04-05 13:37:21 +09001023 var deviceTargets []Target
1024 deviceTargets = append(deviceTargets, ctx.Config().Targets[Android]...)
1025 deviceTargets = append(deviceTargets, ctx.Config().AndroidCommonTarget)
1026
1027 var hostTargets []Target
1028 hostTargets = append(hostTargets, ctx.Config().Targets[ctx.Config().BuildOS]...)
1029 hostTargets = append(hostTargets, ctx.Config().BuildOSCommonTarget)
1030
Jiyong Parkf21dd652024-04-17 05:22:37 +00001031 if ctx.Device() {
Cole Faust43ddd082024-06-17 12:32:40 -07001032 for _, depName := range ctx.Module().RequiredModuleNames(ctx) {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001033 for _, target := range deviceTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001034 addDep(target, depName)
1035 }
1036 }
Jiyong Parkf21dd652024-04-17 05:22:37 +00001037 for _, depName := range ctx.Module().HostRequiredModuleNames() {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001038 for _, target := range hostTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001039 addDep(target, depName)
1040 }
1041 }
1042 }
1043
Jiyong Parkf21dd652024-04-17 05:22:37 +00001044 if ctx.Host() {
Cole Faust43ddd082024-06-17 12:32:40 -07001045 for _, depName := range ctx.Module().RequiredModuleNames(ctx) {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001046 for _, target := range hostTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001047 // When a host module requires another host module, don't make a
1048 // dependency if they have different OSes (i.e. hostcross).
Jiyong Parkf21dd652024-04-17 05:22:37 +00001049 if ctx.Target().HostCross != target.HostCross {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001050 continue
1051 }
1052 addDep(target, depName)
1053 }
1054 }
Jiyong Parkf21dd652024-04-17 05:22:37 +00001055 for _, depName := range ctx.Module().TargetRequiredModuleNames() {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001056 for _, target := range deviceTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001057 addDep(target, depName)
1058 }
1059 }
1060 }
Ronald Braunstein73b08ff2023-12-19 10:24:47 -08001061}
1062
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001063var vintfDepTag = struct {
1064 blueprint.BaseDependencyTag
1065 InstallAlwaysNeededDependencyTag
1066}{}
1067
1068func addVintfFragmentDeps(ctx BottomUpMutatorContext) {
Kiyoung Kim55234812024-09-11 17:00:24 +09001069 // Vintf manifests in the recovery partition will be ignored.
1070 if !ctx.Device() || ctx.Module().InstallInRecovery() {
1071 return
1072 }
1073
1074 deviceConfig := ctx.DeviceConfig()
1075
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001076 mod := ctx.Module()
Kiyoung Kim55234812024-09-11 17:00:24 +09001077 vintfModules := ctx.AddDependency(mod, vintfDepTag, mod.VintfFragmentModuleNames(ctx)...)
1078
1079 modPartition := mod.PartitionTag(deviceConfig)
1080 for _, vintf := range vintfModules {
1081 if vintfModule, ok := vintf.(*vintfFragmentModule); ok {
1082 vintfPartition := vintfModule.PartitionTag(deviceConfig)
1083 if modPartition != vintfPartition {
1084 ctx.ModuleErrorf("Module %q(%q) and Vintf_fragment %q(%q) are installed to different partitions.",
1085 mod.Name(), modPartition,
1086 vintfModule.Name(), vintfPartition)
1087 }
1088 } else {
1089 ctx.ModuleErrorf("Only vintf_fragment type module should be listed in vintf_fragment_modules : %q", vintf.Name())
1090 }
1091 }
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001092}
1093
Usta355a5872021-12-01 15:16:32 -05001094// AddProperties "registers" the provided props
1095// each value in props MUST be a pointer to a struct
Colin Cross4157e882019-06-06 16:57:04 -07001096func (m *ModuleBase) AddProperties(props ...interface{}) {
1097 m.registerProps = append(m.registerProps, props...)
Colin Cross36242852017-06-23 15:06:31 -07001098}
1099
Colin Cross4157e882019-06-06 16:57:04 -07001100func (m *ModuleBase) GetProperties() []interface{} {
1101 return m.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -08001102}
1103
Colin Cross4157e882019-06-06 16:57:04 -07001104func (m *ModuleBase) BuildParamsForTests() []BuildParams {
Chih-Hung Hsiehb8082292021-09-09 23:20:39 -07001105 // Expand the references to module variables like $flags[0-9]*,
1106 // so we do not need to change many existing unit tests.
1107 // This looks like undoing the shareFlags optimization in cc's
1108 // transformSourceToObj, and should only affects unit tests.
1109 vars := m.VariablesForTests()
1110 buildParams := append([]BuildParams(nil), m.buildParams...)
Sasha Smundake198eaf2022-08-04 13:07:02 -07001111 for i := range buildParams {
Chih-Hung Hsiehb8082292021-09-09 23:20:39 -07001112 newArgs := make(map[string]string)
1113 for k, v := range buildParams[i].Args {
1114 newArgs[k] = v
1115 // Replaces both ${flags1} and $flags1 syntax.
1116 if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") {
1117 if value, found := vars[v[2:len(v)-1]]; found {
1118 newArgs[k] = value
1119 }
1120 } else if strings.HasPrefix(v, "$") {
1121 if value, found := vars[v[1:]]; found {
1122 newArgs[k] = value
1123 }
1124 }
1125 }
1126 buildParams[i].Args = newArgs
1127 }
1128 return buildParams
Colin Crosscec81712017-07-13 14:43:27 -07001129}
1130
Colin Cross4157e882019-06-06 16:57:04 -07001131func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
1132 return m.ruleParams
Colin Cross4c83e5c2019-02-25 14:54:28 -08001133}
1134
Colin Cross4157e882019-06-06 16:57:04 -07001135func (m *ModuleBase) VariablesForTests() map[string]string {
1136 return m.variables
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001137}
1138
Colin Crossce75d2c2016-10-06 16:12:58 -07001139// Name returns the name of the module. It may be overridden by individual module types, for
1140// example prebuilts will prepend prebuilt_ to the name.
Colin Cross4157e882019-06-06 16:57:04 -07001141func (m *ModuleBase) Name() string {
1142 return String(m.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -07001143}
1144
Colin Cross9a362232019-07-01 15:32:45 -07001145// String returns a string that includes the module name and variants for printing during debugging.
1146func (m *ModuleBase) String() string {
1147 sb := strings.Builder{}
1148 sb.WriteString(m.commonProperties.DebugName)
1149 sb.WriteString("{")
1150 for i := range m.commonProperties.DebugMutators {
1151 if i != 0 {
1152 sb.WriteString(",")
1153 }
1154 sb.WriteString(m.commonProperties.DebugMutators[i])
1155 sb.WriteString(":")
1156 sb.WriteString(m.commonProperties.DebugVariations[i])
1157 }
1158 sb.WriteString("}")
1159 return sb.String()
1160}
1161
Colin Crossce75d2c2016-10-06 16:12:58 -07001162// BaseModuleName returns the name of the module as specified in the blueprints file.
Colin Cross4157e882019-06-06 16:57:04 -07001163func (m *ModuleBase) BaseModuleName() string {
1164 return String(m.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -07001165}
1166
Colin Cross4157e882019-06-06 16:57:04 -07001167func (m *ModuleBase) base() *ModuleBase {
1168 return m
Colin Cross3f40fa42015-01-30 17:27:36 -08001169}
1170
Paul Duffine2453c72019-05-31 14:00:04 +01001171func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName {
1172 return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()}
1173}
1174
1175func (m *ModuleBase) visibilityProperties() []visibilityProperty {
Paul Duffin63c6e182019-07-24 14:24:38 +01001176 return m.visibilityPropertyInfo
1177}
1178
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001179func (m *ModuleBase) Dists() []Dist {
Paul Duffined875132020-09-02 13:08:57 +01001180 if len(m.distProperties.Dist.Targets) > 0 {
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001181 // Make a copy of the underlying Dists slice to protect against
1182 // backing array modifications with repeated calls to this method.
Paul Duffined875132020-09-02 13:08:57 +01001183 distsCopy := append([]Dist(nil), m.distProperties.Dists...)
1184 return append(distsCopy, m.distProperties.Dist)
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001185 } else {
Paul Duffined875132020-09-02 13:08:57 +01001186 return m.distProperties.Dists
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001187 }
1188}
1189
1190func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFiles {
Paul Duffin74f05592020-11-25 16:37:46 +00001191 var distFiles TaggedDistFiles
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001192 for _, dist := range m.Dists() {
Paul Duffin74f05592020-11-25 16:37:46 +00001193 // If no tag is specified then it means to use the default dist paths so use
1194 // the special tag name which represents that.
1195 tag := proptools.StringDefault(dist.Tag, DefaultDistTag)
1196
mrziwangabdb2932024-06-18 12:43:41 -07001197 distFileForTagFromProvider, err := outputFilesForModuleFromProvider(ctx, m.module, tag)
1198 if err != OutputFilesProviderNotSet {
1199 if err != nil && tag != DefaultDistTag {
1200 ctx.PropertyErrorf("dist.tag", "%s", err.Error())
1201 } else {
1202 distFiles = distFiles.addPathsForTag(tag, distFileForTagFromProvider...)
1203 continue
1204 }
1205 }
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001206 }
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001207 return distFiles
1208}
1209
Cole Faust02987bd2024-03-21 17:58:43 -07001210func (m *ModuleBase) ArchReady() bool {
1211 return m.commonProperties.ArchReady
1212}
1213
Colin Cross4157e882019-06-06 16:57:04 -07001214func (m *ModuleBase) Target() Target {
1215 return m.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -08001216}
1217
Colin Cross4157e882019-06-06 16:57:04 -07001218func (m *ModuleBase) TargetPrimary() bool {
1219 return m.commonProperties.CompilePrimary
Colin Cross8b74d172016-09-13 09:59:14 -07001220}
1221
Colin Cross4157e882019-06-06 16:57:04 -07001222func (m *ModuleBase) MultiTargets() []Target {
1223 return m.commonProperties.CompileMultiTargets
Colin Crossee0bc3b2018-10-02 22:01:37 -07001224}
1225
Colin Cross4157e882019-06-06 16:57:04 -07001226func (m *ModuleBase) Os() OsType {
1227 return m.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -08001228}
1229
Colin Cross4157e882019-06-06 16:57:04 -07001230func (m *ModuleBase) Host() bool {
Jiyong Park1613e552020-09-14 19:43:17 +09001231 return m.Os().Class == Host
Dan Willemsen97750522016-02-09 17:43:51 -08001232}
1233
Yo Chiangbba545e2020-06-09 16:15:37 +08001234func (m *ModuleBase) Device() bool {
1235 return m.Os().Class == Device
1236}
1237
Colin Cross4157e882019-06-06 16:57:04 -07001238func (m *ModuleBase) Arch() Arch {
1239 return m.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -08001240}
1241
Colin Cross4157e882019-06-06 16:57:04 -07001242func (m *ModuleBase) ArchSpecific() bool {
1243 return m.commonProperties.ArchSpecific
Dan Willemsen0b24c742016-10-04 15:13:37 -07001244}
1245
Paul Duffin1356d8c2020-02-25 19:26:33 +00001246// True if the current variant is a CommonOS variant, false otherwise.
1247func (m *ModuleBase) IsCommonOSVariant() bool {
Colin Cross8bbc3d52024-09-11 15:33:54 -07001248 return m.commonProperties.CompileOS == CommonOS
Paul Duffin1356d8c2020-02-25 19:26:33 +00001249}
1250
Colin Cross34037c62020-11-17 13:19:17 -08001251// supportsTarget returns true if the given Target is supported by the current module.
1252func (m *ModuleBase) supportsTarget(target Target) bool {
1253 switch target.Os.Class {
1254 case Host:
1255 if target.HostCross {
1256 return m.HostCrossSupported()
1257 } else {
1258 return m.HostSupported()
Colin Crossa1ad8d12016-06-01 17:09:44 -07001259 }
Colin Cross34037c62020-11-17 13:19:17 -08001260 case Device:
1261 return m.DeviceSupported()
Colin Crossa1ad8d12016-06-01 17:09:44 -07001262 default:
Jiyong Park1613e552020-09-14 19:43:17 +09001263 return false
Colin Crossa1ad8d12016-06-01 17:09:44 -07001264 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001265}
1266
Colin Cross34037c62020-11-17 13:19:17 -08001267// DeviceSupported returns true if the current module is supported and enabled for device targets,
1268// i.e. the factory method set the HostOrDeviceSupported value to include device support and
1269// the device support is enabled by default or enabled by the device_supported property.
Colin Cross4157e882019-06-06 16:57:04 -07001270func (m *ModuleBase) DeviceSupported() bool {
Colin Cross34037c62020-11-17 13:19:17 -08001271 hod := m.commonProperties.HostOrDeviceSupported
1272 // deviceEnabled is true if the device_supported property is true or the HostOrDeviceSupported
1273 // value has the deviceDefault bit set.
1274 deviceEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Device_supported, hod&deviceDefault != 0)
1275 return hod&deviceSupported != 0 && deviceEnabled
Colin Cross3f40fa42015-01-30 17:27:36 -08001276}
1277
Colin Cross34037c62020-11-17 13:19:17 -08001278// HostSupported returns true if the current module is supported and enabled for host targets,
1279// i.e. the factory method set the HostOrDeviceSupported value to include host support and
1280// the host support is enabled by default or enabled by the host_supported property.
Paul Duffine44358f2019-11-26 18:04:12 +00001281func (m *ModuleBase) HostSupported() bool {
Colin Cross34037c62020-11-17 13:19:17 -08001282 hod := m.commonProperties.HostOrDeviceSupported
1283 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1284 // value has the hostDefault bit set.
1285 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
1286 return hod&hostSupported != 0 && hostEnabled
1287}
1288
1289// HostCrossSupported returns true if the current module is supported and enabled for host cross
1290// targets, i.e. the factory method set the HostOrDeviceSupported value to include host cross
1291// support and the host cross support is enabled by default or enabled by the
1292// host_supported property.
1293func (m *ModuleBase) HostCrossSupported() bool {
1294 hod := m.commonProperties.HostOrDeviceSupported
1295 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1296 // value has the hostDefault bit set.
1297 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
Ivan Lozanoc7eafa72024-07-16 17:55:33 +00001298
1299 // Default true for the Host_cross_supported property
1300 hostCrossEnabled := proptools.BoolDefault(m.hostCrossProperties.Host_cross_supported, true)
1301
1302 return hod&hostCrossSupported != 0 && hostEnabled && hostCrossEnabled
Paul Duffine44358f2019-11-26 18:04:12 +00001303}
1304
Colin Cross4157e882019-06-06 16:57:04 -07001305func (m *ModuleBase) Platform() bool {
Justin Yund5f6c822019-06-25 16:47:17 +09001306 return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.SystemExtSpecific()
Jiyong Parkc678ad32018-04-10 13:07:10 +09001307}
1308
Colin Cross4157e882019-06-06 16:57:04 -07001309func (m *ModuleBase) DeviceSpecific() bool {
1310 return Bool(m.commonProperties.Device_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001311}
1312
Colin Cross4157e882019-06-06 16:57:04 -07001313func (m *ModuleBase) SocSpecific() bool {
1314 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001315}
1316
Colin Cross4157e882019-06-06 16:57:04 -07001317func (m *ModuleBase) ProductSpecific() bool {
1318 return Bool(m.commonProperties.Product_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001319}
1320
Justin Yund5f6c822019-06-25 16:47:17 +09001321func (m *ModuleBase) SystemExtSpecific() bool {
1322 return Bool(m.commonProperties.System_ext_specific)
Dario Frenifd05a742018-05-29 13:28:54 +01001323}
1324
Colin Crossc2d24052020-05-13 11:05:02 -07001325// RequiresStableAPIs returns true if the module will be installed to a partition that may
1326// be updated separately from the system image.
1327func (m *ModuleBase) RequiresStableAPIs(ctx BaseModuleContext) bool {
1328 return m.SocSpecific() || m.DeviceSpecific() ||
1329 (m.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface())
1330}
1331
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001332func (m *ModuleBase) PartitionTag(config DeviceConfig) string {
1333 partition := "system"
1334 if m.SocSpecific() {
1335 // A SoC-specific module could be on the vendor partition at
1336 // "vendor" or the system partition at "system/vendor".
1337 if config.VendorPath() == "vendor" {
1338 partition = "vendor"
1339 }
1340 } else if m.DeviceSpecific() {
1341 // A device-specific module could be on the odm partition at
1342 // "odm", the vendor partition at "vendor/odm", or the system
1343 // partition at "system/vendor/odm".
1344 if config.OdmPath() == "odm" {
1345 partition = "odm"
Ramy Medhat944839a2020-03-31 22:14:52 -04001346 } else if strings.HasPrefix(config.OdmPath(), "vendor/") {
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001347 partition = "vendor"
1348 }
1349 } else if m.ProductSpecific() {
1350 // A product-specific module could be on the product partition
1351 // at "product" or the system partition at "system/product".
1352 if config.ProductPath() == "product" {
1353 partition = "product"
1354 }
1355 } else if m.SystemExtSpecific() {
1356 // A system_ext-specific module could be on the system_ext
1357 // partition at "system_ext" or the system partition at
1358 // "system/system_ext".
1359 if config.SystemExtPath() == "system_ext" {
1360 partition = "system_ext"
1361 }
1362 }
1363 return partition
1364}
1365
Cole Fauste8a87832024-09-11 11:35:46 -07001366func (m *ModuleBase) Enabled(ctx ConfigurableEvaluatorContext) bool {
Justin Yun32f053b2020-07-31 23:07:17 +09001367 if m.commonProperties.ForcedDisabled {
1368 return false
1369 }
Cole Fausta963b942024-04-11 17:43:00 -07001370 return m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled)
Colin Cross3f40fa42015-01-30 17:27:36 -08001371}
1372
Cole Faust8eeae4b2024-09-12 11:51:04 -07001373// Returns a copy of the enabled property, useful for passing it on to sub-modules
1374func (m *ModuleBase) EnabledProperty() proptools.Configurable[bool] {
1375 if m.commonProperties.ForcedDisabled {
1376 return proptools.NewSimpleConfigurable(false)
1377 }
1378 return m.commonProperties.Enabled.Clone()
1379}
1380
Inseob Kimeec88e12020-01-22 11:11:29 +09001381func (m *ModuleBase) Disable() {
Justin Yun32f053b2020-07-31 23:07:17 +09001382 m.commonProperties.ForcedDisabled = true
Inseob Kimeec88e12020-01-22 11:11:29 +09001383}
1384
Colin Crossa9c8c9f2020-12-16 10:20:23 -08001385// HideFromMake marks this variant so that it is not emitted in the generated Android.mk file.
1386func (m *ModuleBase) HideFromMake() {
1387 m.commonProperties.HideFromMake = true
1388}
1389
1390// IsHideFromMake returns true if HideFromMake was previously called.
1391func (m *ModuleBase) IsHideFromMake() bool {
1392 return m.commonProperties.HideFromMake == true
1393}
1394
1395// SkipInstall marks this variant to not create install rules when ctx.Install* are called.
Colin Cross4157e882019-06-06 16:57:04 -07001396func (m *ModuleBase) SkipInstall() {
1397 m.commonProperties.SkipInstall = true
Colin Crossce75d2c2016-10-06 16:12:58 -07001398}
1399
Martin Stjernholm9e7f45e2020-12-23 03:50:30 +00001400// IsSkipInstall returns true if this variant is marked to not create install
1401// rules when ctx.Install* are called.
1402func (m *ModuleBase) IsSkipInstall() bool {
1403 return m.commonProperties.SkipInstall
1404}
1405
Iván Budnik295da162023-03-10 16:11:26 +00001406// Similar to HideFromMake, but if the AndroidMk entry would set
1407// LOCAL_UNINSTALLABLE_MODULE then this variant may still output that entry
1408// rather than leaving it out altogether. That happens in cases where it would
1409// have other side effects, in particular when it adds a NOTICE file target,
1410// which other install targets might depend on.
1411func (m *ModuleBase) MakeUninstallable() {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001412 m.commonProperties.UninstallableApexPlatformVariant = true
Iván Budnik295da162023-03-10 16:11:26 +00001413 m.HideFromMake()
1414}
1415
Liz Kammer5ca3a622020-08-05 15:40:41 -07001416func (m *ModuleBase) ReplacedByPrebuilt() {
1417 m.commonProperties.ReplacedByPrebuilt = true
Colin Crossa9c8c9f2020-12-16 10:20:23 -08001418 m.HideFromMake()
Liz Kammer5ca3a622020-08-05 15:40:41 -07001419}
1420
1421func (m *ModuleBase) IsReplacedByPrebuilt() bool {
1422 return m.commonProperties.ReplacedByPrebuilt
1423}
1424
Colin Cross4157e882019-06-06 16:57:04 -07001425func (m *ModuleBase) ExportedToMake() bool {
1426 return m.commonProperties.NamespaceExportedToMake
Jiyong Park374510b2018-03-19 18:23:01 +09001427}
1428
Justin Yun1871f902023-04-07 20:13:19 +09001429func (m *ModuleBase) EffectiveLicenseKinds() []string {
1430 return m.commonProperties.Effective_license_kinds
1431}
1432
Justin Yun885a7de2021-06-29 20:34:53 +09001433func (m *ModuleBase) EffectiveLicenseFiles() Paths {
Bob Badour4101c712022-02-09 11:54:35 -08001434 result := make(Paths, 0, len(m.commonProperties.Effective_license_text))
1435 for _, p := range m.commonProperties.Effective_license_text {
1436 result = append(result, p.Path)
1437 }
1438 return result
Justin Yun885a7de2021-06-29 20:34:53 +09001439}
1440
Colin Crosse9fe2942020-11-10 18:12:15 -08001441// computeInstallDeps finds the installed paths of all dependencies that have a dependency
Colin Crossbd3a16b2023-04-25 11:30:51 -07001442// tag that is annotated as needing installation via the isInstallDepNeeded method.
Colin Crossc85750b2022-04-21 12:50:51 -07001443func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]*DepSet[InstallPath], []*DepSet[PackagingSpec]) {
1444 var installDeps []*DepSet[InstallPath]
1445 var packagingSpecs []*DepSet[PackagingSpec]
Colin Cross5d583952020-11-24 16:21:24 -08001446 ctx.VisitDirectDeps(func(dep Module) {
Jiyong Park1d4907e2024-05-15 02:09:42 +09001447 if isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001448 // Installation is still handled by Make, so anything hidden from Make is not
1449 // installable.
Yu Liubad1eef2024-08-21 22:37:35 +00001450 info := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider)
Colin Crossbd3a16b2023-04-25 11:30:51 -07001451 if !dep.IsHideFromMake() && !dep.IsSkipInstall() {
Yu Liubad1eef2024-08-21 22:37:35 +00001452 installDeps = append(installDeps, info.TransitiveInstallFiles)
Colin Crossbd3a16b2023-04-25 11:30:51 -07001453 }
1454 // Add packaging deps even when the dependency is not installed so that uninstallable
1455 // modules can still be packaged. Often the package will be installed instead.
Yu Liubad1eef2024-08-21 22:37:35 +00001456 packagingSpecs = append(packagingSpecs, info.TransitivePackagingSpecs)
Colin Cross897266e2020-02-13 13:22:08 -08001457 }
1458 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001459
Colin Crossffe6b9d2020-12-01 15:40:06 -08001460 return installDeps, packagingSpecs
Colin Cross3f40fa42015-01-30 17:27:36 -08001461}
1462
Colin Crossbd3a16b2023-04-25 11:30:51 -07001463// isInstallDepNeeded returns true if installing the output files of the current module
1464// should also install the output files of the given dependency and dependency tag.
1465func isInstallDepNeeded(dep Module, tag blueprint.DependencyTag) bool {
1466 // Don't add a dependency from the platform to a library provided by an apex.
1467 if dep.base().commonProperties.UninstallableApexPlatformVariant {
1468 return false
1469 }
1470 // Only install modules if the dependency tag is an InstallDepNeeded tag.
1471 return IsInstallDepNeededTag(tag)
1472}
1473
Colin Cross4157e882019-06-06 16:57:04 -07001474func (m *ModuleBase) NoAddressSanitizer() bool {
1475 return m.noAddressSanitizer
Colin Cross3f40fa42015-01-30 17:27:36 -08001476}
1477
Colin Cross4157e882019-06-06 16:57:04 -07001478func (m *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -08001479 return false
1480}
1481
Jaewoong Jung0949f312019-09-11 10:25:18 -07001482func (m *ModuleBase) InstallInTestcases() bool {
1483 return false
1484}
1485
Colin Cross4157e882019-06-06 16:57:04 -07001486func (m *ModuleBase) InstallInSanitizerDir() bool {
Vishwath Mohan1dd88392017-03-29 22:00:18 -07001487 return false
1488}
1489
Yifan Hong1b3348d2020-01-21 15:53:22 -08001490func (m *ModuleBase) InstallInRamdisk() bool {
1491 return Bool(m.commonProperties.Ramdisk)
1492}
1493
Yifan Hong60e0cfb2020-10-21 15:17:56 -07001494func (m *ModuleBase) InstallInVendorRamdisk() bool {
1495 return Bool(m.commonProperties.Vendor_ramdisk)
1496}
1497
Inseob Kim08758f02021-04-08 21:13:22 +09001498func (m *ModuleBase) InstallInDebugRamdisk() bool {
1499 return Bool(m.commonProperties.Debug_ramdisk)
1500}
1501
Colin Cross4157e882019-06-06 16:57:04 -07001502func (m *ModuleBase) InstallInRecovery() bool {
1503 return Bool(m.commonProperties.Recovery)
Jiyong Parkf9332f12018-02-01 00:54:12 +09001504}
1505
Colin Crossea30d852023-11-29 16:00:16 -08001506func (m *ModuleBase) InstallInOdm() bool {
1507 return false
1508}
1509
1510func (m *ModuleBase) InstallInProduct() bool {
1511 return false
1512}
1513
Kiyoung Kimae11c232021-07-19 11:38:04 +09001514func (m *ModuleBase) InstallInVendor() bool {
Kiyoung Kimf160f7f2022-11-29 10:58:08 +09001515 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Soc_specific) || Bool(m.commonProperties.Proprietary)
Kiyoung Kimae11c232021-07-19 11:38:04 +09001516}
1517
Spandan Das950deca2024-10-01 18:35:23 +00001518func (m *ModuleBase) InstallInSystemExt() bool {
1519 return Bool(m.commonProperties.System_ext_specific)
1520}
1521
Colin Cross90ba5f42019-10-02 11:10:58 -07001522func (m *ModuleBase) InstallInRoot() bool {
1523 return false
1524}
1525
Jiyong Park87788b52020-09-01 12:37:45 +09001526func (m *ModuleBase) InstallForceOS() (*OsType, *ArchType) {
1527 return nil, nil
Colin Cross6e359402020-02-10 15:29:54 -08001528}
1529
Colin Cross4157e882019-06-06 16:57:04 -07001530func (m *ModuleBase) Owner() string {
1531 return String(m.commonProperties.Owner)
Sundong Ahn4fd04bb2018-08-31 18:01:37 +09001532}
1533
Ronald Braunstein73b08ff2023-12-19 10:24:47 -08001534func (m *ModuleBase) Team() string {
1535 return String(m.commonProperties.Team)
1536}
1537
Colin Cross7228ecd2019-11-18 16:00:16 -08001538func (m *ModuleBase) setImageVariation(variant string) {
1539 m.commonProperties.ImageVariation = variant
1540}
1541
1542func (m *ModuleBase) ImageVariation() blueprint.Variation {
1543 return blueprint.Variation{
1544 Mutator: "image",
1545 Variation: m.base().commonProperties.ImageVariation,
1546 }
1547}
1548
Paul Duffin9b76c0b2020-03-12 10:24:35 +00001549func (m *ModuleBase) getVariationByMutatorName(mutator string) string {
1550 for i, v := range m.commonProperties.DebugMutators {
1551 if v == mutator {
1552 return m.commonProperties.DebugVariations[i]
1553 }
1554 }
1555
1556 return ""
1557}
1558
Yifan Hong1b3348d2020-01-21 15:53:22 -08001559func (m *ModuleBase) InRamdisk() bool {
1560 return m.base().commonProperties.ImageVariation == RamdiskVariation
1561}
1562
Yifan Hong60e0cfb2020-10-21 15:17:56 -07001563func (m *ModuleBase) InVendorRamdisk() bool {
1564 return m.base().commonProperties.ImageVariation == VendorRamdiskVariation
1565}
1566
Inseob Kim08758f02021-04-08 21:13:22 +09001567func (m *ModuleBase) InDebugRamdisk() bool {
1568 return m.base().commonProperties.ImageVariation == DebugRamdiskVariation
1569}
1570
Colin Cross7228ecd2019-11-18 16:00:16 -08001571func (m *ModuleBase) InRecovery() bool {
1572 return m.base().commonProperties.ImageVariation == RecoveryVariation
1573}
1574
Cole Fauste8a87832024-09-11 11:35:46 -07001575func (m *ModuleBase) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string {
Cole Faust43ddd082024-06-17 12:32:40 -07001576 return m.base().commonProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09001577}
1578
1579func (m *ModuleBase) HostRequiredModuleNames() []string {
1580 return m.base().commonProperties.Host_required
1581}
1582
1583func (m *ModuleBase) TargetRequiredModuleNames() []string {
1584 return m.base().commonProperties.Target_required
1585}
1586
Cole Fauste8a87832024-09-11 11:35:46 -07001587func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string {
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001588 return m.base().commonProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
1589}
1590
Colin Crossa6182ab2024-08-21 10:47:44 -07001591func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) {
1592 namespacePrefix := ctx.Namespace().id
1593 if namespacePrefix != "" {
1594 namespacePrefix = namespacePrefix + "-"
1595 }
1596
1597 if !ctx.uncheckedModule {
1598 name := namespacePrefix + ctx.ModuleName() + "-" + ctx.ModuleSubDir() + "-checkbuild"
1599 ctx.Phony(name, ctx.checkbuildFiles...)
1600 ctx.checkbuildTarget = PathForPhony(ctx, name)
1601 }
1602
1603}
1604
Yu Liuddc28332024-08-09 22:48:30 +00001605func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) {
Colin Cross897266e2020-02-13 13:22:08 -08001606 var allInstalledFiles InstallPaths
Colin Crossa6182ab2024-08-21 10:47:44 -07001607 var allCheckbuildTargets Paths
Colin Cross0875c522017-11-28 17:34:01 -08001608 ctx.VisitAllModuleVariants(func(module Module) {
1609 a := module.base()
Colin Crossa6182ab2024-08-21 10:47:44 -07001610 var checkbuildTarget Path
1611 var uncheckedModule bool
Yu Liuddc28332024-08-09 22:48:30 +00001612 if a == m {
1613 allInstalledFiles = append(allInstalledFiles, ctx.installFiles...)
Colin Crossa6182ab2024-08-21 10:47:44 -07001614 checkbuildTarget = ctx.checkbuildTarget
1615 uncheckedModule = ctx.uncheckedModule
Yu Liuddc28332024-08-09 22:48:30 +00001616 } else {
Yu Liud46e5ae2024-08-15 18:46:17 +00001617 info := OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider)
1618 allInstalledFiles = append(allInstalledFiles, info.InstallFiles...)
Colin Crossa6182ab2024-08-21 10:47:44 -07001619 checkbuildTarget = info.CheckbuildTarget
1620 uncheckedModule = info.UncheckedModule
Yu Liuddc28332024-08-09 22:48:30 +00001621 }
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07001622 // A module's -checkbuild phony targets should
Chih-Hung Hsieha3d135b2021-10-14 20:32:53 -07001623 // not be created if the module is not exported to make.
1624 // Those could depend on the build target and fail to compile
1625 // for the current build target.
Colin Crossa6182ab2024-08-21 10:47:44 -07001626 if (!ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, a)) && !uncheckedModule && checkbuildTarget != nil {
1627 allCheckbuildTargets = append(allCheckbuildTargets, checkbuildTarget)
Chih-Hung Hsieha3d135b2021-10-14 20:32:53 -07001628 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001629 })
1630
Colin Cross0875c522017-11-28 17:34:01 -08001631 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -07001632
Yu Liu460c0fa2024-08-20 19:31:15 +00001633 var namespacePrefix string
1634 nameSpace := ctx.Namespace().Path
1635 if nameSpace != "." {
1636 namespacePrefix = strings.ReplaceAll(nameSpace, "/", ".") + "-"
Jeff Gaston088e29e2017-11-29 16:47:17 -08001637 }
1638
Yu Liuddc2e1a2024-08-20 21:31:22 +00001639 var info FinalModuleBuildTargetsInfo
1640
Colin Cross3f40fa42015-01-30 17:27:36 -08001641 if len(allInstalledFiles) > 0 {
Colin Crossc3d87d32020-06-04 13:25:17 -07001642 name := namespacePrefix + ctx.ModuleName() + "-install"
1643 ctx.Phony(name, allInstalledFiles.Paths()...)
Yu Liuddc2e1a2024-08-20 21:31:22 +00001644 info.InstallTarget = PathForPhony(ctx, name)
1645 deps = append(deps, info.InstallTarget)
Colin Cross9454bfa2015-03-17 13:24:18 -07001646 }
1647
Colin Crossa6182ab2024-08-21 10:47:44 -07001648 if len(allCheckbuildTargets) > 0 {
Colin Crossc3d87d32020-06-04 13:25:17 -07001649 name := namespacePrefix + ctx.ModuleName() + "-checkbuild"
Colin Crossa6182ab2024-08-21 10:47:44 -07001650 ctx.Phony(name, allCheckbuildTargets...)
1651 deps = append(deps, PathForPhony(ctx, name))
Colin Cross9454bfa2015-03-17 13:24:18 -07001652 }
1653
1654 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001655 suffix := ""
Jingwen Chencda22c92020-11-23 00:22:30 -05001656 if ctx.Config().KatiEnabled() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001657 suffix = "-soong"
1658 }
1659
Colin Crossc3d87d32020-06-04 13:25:17 -07001660 ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001661
Yu Liuddc2e1a2024-08-20 21:31:22 +00001662 info.BlueprintDir = ctx.ModuleDir()
1663 SetProvider(ctx, FinalModuleBuildTargetsProvider, info)
Colin Cross3f40fa42015-01-30 17:27:36 -08001664 }
1665}
1666
Colin Crossc34d2322020-01-03 15:23:27 -08001667func determineModuleKind(m *ModuleBase, ctx blueprint.EarlyModuleContext) moduleKind {
Colin Cross4157e882019-06-06 16:57:04 -07001668 var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
1669 var deviceSpecific = Bool(m.commonProperties.Device_specific)
1670 var productSpecific = Bool(m.commonProperties.Product_specific)
Justin Yund5f6c822019-06-25 16:47:17 +09001671 var systemExtSpecific = Bool(m.commonProperties.System_ext_specific)
Jiyong Park2db76922017-11-08 16:03:48 +09001672
Dario Frenifd05a742018-05-29 13:28:54 +01001673 msg := "conflicting value set here"
1674 if socSpecific && deviceSpecific {
1675 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
Colin Cross4157e882019-06-06 16:57:04 -07001676 if Bool(m.commonProperties.Vendor) {
Jiyong Park2db76922017-11-08 16:03:48 +09001677 ctx.PropertyErrorf("vendor", msg)
1678 }
Colin Cross4157e882019-06-06 16:57:04 -07001679 if Bool(m.commonProperties.Proprietary) {
Jiyong Park2db76922017-11-08 16:03:48 +09001680 ctx.PropertyErrorf("proprietary", msg)
1681 }
Colin Cross4157e882019-06-06 16:57:04 -07001682 if Bool(m.commonProperties.Soc_specific) {
Jiyong Park2db76922017-11-08 16:03:48 +09001683 ctx.PropertyErrorf("soc_specific", msg)
1684 }
1685 }
1686
Justin Yund5f6c822019-06-25 16:47:17 +09001687 if productSpecific && systemExtSpecific {
1688 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and system_ext at the same time.")
1689 ctx.PropertyErrorf("system_ext_specific", msg)
Dario Frenifd05a742018-05-29 13:28:54 +01001690 }
1691
Justin Yund5f6c822019-06-25 16:47:17 +09001692 if (socSpecific || deviceSpecific) && (productSpecific || systemExtSpecific) {
Dario Frenifd05a742018-05-29 13:28:54 +01001693 if productSpecific {
1694 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
1695 } else {
Justin Yund5f6c822019-06-25 16:47:17 +09001696 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 +01001697 }
1698 if deviceSpecific {
1699 ctx.PropertyErrorf("device_specific", msg)
1700 } else {
Colin Cross4157e882019-06-06 16:57:04 -07001701 if Bool(m.commonProperties.Vendor) {
Dario Frenifd05a742018-05-29 13:28:54 +01001702 ctx.PropertyErrorf("vendor", msg)
1703 }
Colin Cross4157e882019-06-06 16:57:04 -07001704 if Bool(m.commonProperties.Proprietary) {
Dario Frenifd05a742018-05-29 13:28:54 +01001705 ctx.PropertyErrorf("proprietary", msg)
1706 }
Colin Cross4157e882019-06-06 16:57:04 -07001707 if Bool(m.commonProperties.Soc_specific) {
Dario Frenifd05a742018-05-29 13:28:54 +01001708 ctx.PropertyErrorf("soc_specific", msg)
1709 }
1710 }
1711 }
1712
Jiyong Park2db76922017-11-08 16:03:48 +09001713 if productSpecific {
1714 return productSpecificModule
Justin Yund5f6c822019-06-25 16:47:17 +09001715 } else if systemExtSpecific {
1716 return systemExtSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +09001717 } else if deviceSpecific {
1718 return deviceSpecificModule
1719 } else if socSpecific {
1720 return socSpecificModule
1721 } else {
1722 return platformModule
1723 }
1724}
1725
Colin Crossc34d2322020-01-03 15:23:27 -08001726func (m *ModuleBase) earlyModuleContextFactory(ctx blueprint.EarlyModuleContext) earlyModuleContext {
Colin Cross1184b642019-12-30 18:43:07 -08001727 return earlyModuleContext{
Colin Crossc34d2322020-01-03 15:23:27 -08001728 EarlyModuleContext: ctx,
1729 kind: determineModuleKind(m, ctx),
1730 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -08001731 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001732}
1733
Colin Cross1184b642019-12-30 18:43:07 -08001734func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext {
1735 return baseModuleContext{
1736 bp: ctx,
Colin Cross1d3d9f12024-01-18 14:30:22 -08001737 archModuleContext: m.archModuleContextFactory(ctx),
Colin Cross1184b642019-12-30 18:43:07 -08001738 earlyModuleContext: m.earlyModuleContextFactory(ctx),
Colin Cross1184b642019-12-30 18:43:07 -08001739 }
1740}
1741
Colin Crosse1a85552024-06-14 12:17:37 -07001742type archModuleContextFactoryContext interface {
1743 Config() interface{}
1744}
1745
1746func (m *ModuleBase) archModuleContextFactory(ctx archModuleContextFactoryContext) archModuleContext {
Colin Cross1d3d9f12024-01-18 14:30:22 -08001747 config := ctx.Config().(Config)
1748 target := m.Target()
1749 primaryArch := false
1750 if len(config.Targets[target.Os]) <= 1 {
1751 primaryArch = true
1752 } else {
1753 primaryArch = target.Arch.ArchType == config.Targets[target.Os][0].Arch.ArchType
1754 }
1755
1756 return archModuleContext{
Cole Faust0aa21cc2024-03-20 12:28:03 -07001757 ready: m.commonProperties.ArchReady,
Colin Cross1d3d9f12024-01-18 14:30:22 -08001758 os: m.commonProperties.CompileOS,
1759 target: m.commonProperties.CompileTarget,
1760 targetPrimary: m.commonProperties.CompilePrimary,
1761 multiTargets: m.commonProperties.CompileMultiTargets,
1762 primaryArch: primaryArch,
1763 }
1764
1765}
1766
Yu Liuddc28332024-08-09 22:48:30 +00001767type InstallFilesInfo struct {
Colin Crossa6182ab2024-08-21 10:47:44 -07001768 InstallFiles InstallPaths
1769 CheckbuildFiles Paths
1770 CheckbuildTarget Path
1771 UncheckedModule bool
1772 PackagingSpecs []PackagingSpec
Yu Liud46e5ae2024-08-15 18:46:17 +00001773 // katiInstalls tracks the install rules that were created by Soong but are being exported
1774 // to Make to convert to ninja rules so that Make can add additional dependencies.
Yu Liuec810542024-08-26 18:09:15 +00001775 KatiInstalls katiInstalls
1776 KatiSymlinks katiInstalls
1777 TestData []DataPath
Yu Liubad1eef2024-08-21 22:37:35 +00001778 TransitivePackagingSpecs *DepSet[PackagingSpec]
Yu Liuec810542024-08-26 18:09:15 +00001779 LicenseMetadataFile WritablePath
1780
1781 // The following fields are private before, make it private again once we have
1782 // better solution.
1783 TransitiveInstallFiles *DepSet[InstallPath]
Yu Liu82a6d142024-08-27 19:02:29 +00001784 // katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
1785 // allowed to have duplicates across modules and variants.
1786 KatiInitRcInstalls katiInstalls
1787 KatiVintfInstalls katiInstalls
1788 InitRcPaths Paths
1789 VintfFragmentsPaths Paths
1790 InstalledInitRcPaths InstallPaths
1791 InstalledVintfFragmentsPaths InstallPaths
1792
Yu Liuec810542024-08-26 18:09:15 +00001793 // The files to copy to the dist as explicitly specified in the .bp file.
1794 DistFiles TaggedDistFiles
Yu Liuddc28332024-08-09 22:48:30 +00001795}
1796
Yu Liubad1eef2024-08-21 22:37:35 +00001797var InstallFilesProvider = blueprint.NewProvider[InstallFilesInfo]()
Yu Liuddc2e1a2024-08-20 21:31:22 +00001798
1799type FinalModuleBuildTargetsInfo struct {
1800 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
1801 // Only set on the final variant of each module
1802 InstallTarget WritablePath
1803 CheckbuildTarget WritablePath
1804 BlueprintDir string
1805}
1806
Yu Liubad1eef2024-08-21 22:37:35 +00001807var FinalModuleBuildTargetsProvider = blueprint.NewProvider[FinalModuleBuildTargetsInfo]()
Yu Liuddc28332024-08-09 22:48:30 +00001808
Colin Cross4157e882019-06-06 16:57:04 -07001809func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
Colin Cross25de6c32019-06-06 14:29:25 -07001810 ctx := &moduleContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -07001811 module: m.module,
Colin Crossdc35e212019-06-06 16:13:11 -07001812 bp: blueprintCtx,
Colin Cross0ea8ba82019-06-06 14:33:29 -07001813 baseModuleContext: m.baseModuleContextFactory(blueprintCtx),
Colin Cross0ea8ba82019-06-06 14:33:29 -07001814 variables: make(map[string]string),
Yu Liu54513622024-08-19 20:00:32 +00001815 phonies: make(map[string]Paths),
Colin Cross3f40fa42015-01-30 17:27:36 -08001816 }
1817
Jihoon Kangc3d4e112024-06-24 22:16:27 +00001818 setContainerInfo(ctx)
Jihoon Kang85bc1932024-07-01 17:04:46 +00001819 if ctx.Config().Getenv("DISABLE_CONTAINER_CHECK") != "true" {
1820 checkContainerViolations(ctx)
1821 }
Jihoon Kangc3d4e112024-06-24 22:16:27 +00001822
Yu Liuec810542024-08-26 18:09:15 +00001823 ctx.licenseMetadataFile = PathForModuleOut(ctx, "meta_lic")
Colin Crossaa1cab02022-01-28 14:49:24 -08001824
Colin Crossffe6b9d2020-12-01 15:40:06 -08001825 dependencyInstallFiles, dependencyPackagingSpecs := m.computeInstallDeps(ctx)
Yu Liubad1eef2024-08-21 22:37:35 +00001826 // set the TransitiveInstallFiles to only the transitive dependencies to be used as the dependencies
Colin Cross5d583952020-11-24 16:21:24 -08001827 // of installed files of this module. It will be replaced by a depset including the installed
1828 // files of this module at the end for use by modules that depend on this one.
Yu Liubad1eef2024-08-21 22:37:35 +00001829 ctx.TransitiveInstallFiles = NewDepSet[InstallPath](TOPOLOGICAL, nil, dependencyInstallFiles)
Colin Cross5d583952020-11-24 16:21:24 -08001830
Colin Cross6c4f21f2019-06-06 15:41:36 -07001831 // Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never
1832 // reporting missing dependency errors in Blueprint when AllowMissingDependencies == true.
1833 // TODO: This will be removed once defaults modules handle missing dependency errors
1834 blueprintCtx.GetMissingDependencies()
1835
Colin Crossdc35e212019-06-06 16:13:11 -07001836 // For the final GenerateAndroidBuildActions pass, require that all visited dependencies Soong modules and
Paul Duffin1356d8c2020-02-25 19:26:33 +00001837 // are enabled. Unless the module is a CommonOS variant which may have dependencies on disabled variants
1838 // (because the dependencies are added before the modules are disabled). The
1839 // GetOsSpecificVariantsOfCommonOSVariant(...) method will ensure that the disabled variants are
1840 // ignored.
1841 ctx.baseModuleContext.strictVisitDeps = !m.IsCommonOSVariant()
Colin Crossdc35e212019-06-06 16:13:11 -07001842
Colin Cross4c83e5c2019-02-25 14:54:28 -08001843 if ctx.config.captureBuild {
1844 ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
1845 }
1846
Colin Cross67a5c132017-05-09 13:45:28 -07001847 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
1848 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -08001849 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
1850 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -07001851 }
Colin Cross0875c522017-11-28 17:34:01 -08001852 if !ctx.PrimaryArch() {
1853 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -07001854 }
Colin Crossff694a82023-12-13 15:54:49 -08001855 if apexInfo, _ := ModuleProvider(ctx, ApexInfoProvider); !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -07001856 suffix = append(suffix, apexInfo.ApexVariationName)
Dan Willemsenb13a9482020-02-14 11:25:54 -08001857 }
Colin Cross67a5c132017-05-09 13:45:28 -07001858
1859 ctx.Variable(pctx, "moduleDesc", desc)
1860
1861 s := ""
1862 if len(suffix) > 0 {
1863 s = " [" + strings.Join(suffix, " ") + "]"
1864 }
1865 ctx.Variable(pctx, "moduleDescSuffix", s)
1866
Dan Willemsen569edc52018-11-19 09:33:29 -08001867 // Some common property checks for properties that will be used later in androidmk.go
Paul Duffin89968e32020-11-23 18:17:03 +00001868 checkDistProperties(ctx, "dist", &m.distProperties.Dist)
Sasha Smundake198eaf2022-08-04 13:07:02 -07001869 for i := range m.distProperties.Dists {
Paul Duffin89968e32020-11-23 18:17:03 +00001870 checkDistProperties(ctx, fmt.Sprintf("dists[%d]", i), &m.distProperties.Dists[i])
Dan Willemsen569edc52018-11-19 09:33:29 -08001871 }
1872
Yu Liubad1eef2024-08-21 22:37:35 +00001873 var installFiles InstallFilesInfo
1874
Cole Fausta963b942024-04-11 17:43:00 -07001875 if m.Enabled(ctx) {
Jooyung Hand48f3c32019-08-23 11:18:57 +09001876 // ensure all direct android.Module deps are enabled
Colin Cross648daea2024-09-12 14:35:29 -07001877 ctx.VisitDirectDeps(func(m Module) {
1878 ctx.validateAndroidModule(m, ctx.OtherModuleDependencyTag(m), ctx.baseModuleContext.strictVisitDeps)
Jooyung Hand48f3c32019-08-23 11:18:57 +09001879 })
1880
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001881 if m.Device() {
1882 // Handle any init.rc and vintf fragment files requested by the module. All files installed by this
1883 // module will automatically have a dependency on the installed init.rc or vintf fragment file.
1884 // The same init.rc or vintf fragment file may be requested by multiple modules or variants,
1885 // so instead of installing them now just compute the install path and store it for later.
1886 // The full list of all init.rc and vintf fragment install rules will be deduplicated later
1887 // so only a single rule is created for each init.rc or vintf fragment file.
1888
1889 if !m.InVendorRamdisk() {
Inseob Kim713b87d2024-09-13 11:29:54 +09001890 ctx.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc.GetOrDefault(ctx, nil))
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001891 rcDir := PathForModuleInstall(ctx, "etc", "init")
Yu Liu82a6d142024-08-27 19:02:29 +00001892 for _, src := range ctx.initRcPaths {
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001893 installedInitRc := rcDir.Join(ctx, src.Base())
Yu Liu82a6d142024-08-27 19:02:29 +00001894 ctx.katiInitRcInstalls = append(ctx.katiInitRcInstalls, katiInstall{
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001895 from: src,
1896 to: installedInitRc,
1897 })
1898 ctx.PackageFile(rcDir, src.Base(), src)
Yu Liu82a6d142024-08-27 19:02:29 +00001899 ctx.installedInitRcPaths = append(ctx.installedInitRcPaths, installedInitRc)
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001900 }
Yu Liu82a6d142024-08-27 19:02:29 +00001901 installFiles.InitRcPaths = ctx.initRcPaths
1902 installFiles.KatiInitRcInstalls = ctx.katiInitRcInstalls
1903 installFiles.InstalledInitRcPaths = ctx.installedInitRcPaths
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001904 }
1905
Yu Liu82a6d142024-08-27 19:02:29 +00001906 ctx.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments.GetOrDefault(ctx, nil))
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001907 vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest")
Yu Liu82a6d142024-08-27 19:02:29 +00001908 for _, src := range ctx.vintfFragmentsPaths {
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001909 installedVintfFragment := vintfDir.Join(ctx, src.Base())
Yu Liu82a6d142024-08-27 19:02:29 +00001910 ctx.katiVintfInstalls = append(ctx.katiVintfInstalls, katiInstall{
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001911 from: src,
1912 to: installedVintfFragment,
1913 })
1914 ctx.PackageFile(vintfDir, src.Base(), src)
Yu Liu82a6d142024-08-27 19:02:29 +00001915 ctx.installedVintfFragmentsPaths = append(ctx.installedVintfFragmentsPaths, installedVintfFragment)
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001916 }
Yu Liu82a6d142024-08-27 19:02:29 +00001917 installFiles.VintfFragmentsPaths = ctx.vintfFragmentsPaths
1918 installFiles.KatiVintfInstalls = ctx.katiVintfInstalls
1919 installFiles.InstalledVintfFragmentsPaths = ctx.installedVintfFragmentsPaths
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001920 }
1921
Bob Badour37af0462021-01-07 03:34:31 +00001922 licensesPropertyFlattener(ctx)
1923 if ctx.Failed() {
1924 return
1925 }
1926
Joe Onorato349ae8d2024-02-05 22:46:00 +00001927 if jarJarPrefixHandler != nil {
1928 jarJarPrefixHandler(ctx)
1929 if ctx.Failed() {
1930 return
1931 }
1932 }
1933
Justin Yun40182b62024-05-07 10:22:19 +09001934 // Call aconfigUpdateAndroidBuildActions to collect merged aconfig files before being used
1935 // in m.module.GenerateAndroidBuildActions
1936 aconfigUpdateAndroidBuildActions(ctx)
Jaewoong Jung5b425e22019-06-17 17:40:56 -07001937 if ctx.Failed() {
1938 return
1939 }
1940
Yu Liu26a716d2024-08-30 23:40:32 +00001941 m.module.GenerateAndroidBuildActions(ctx)
1942 if ctx.Failed() {
1943 return
Yu Liufa297642024-06-11 00:13:02 +00001944 }
1945
Yu Liu26a716d2024-08-30 23:40:32 +00001946 if x, ok := m.module.(IDEInfo); ok {
1947 var result IdeInfo
1948 x.IDEInfo(ctx, &result)
1949 result.BaseModuleName = x.BaseModuleName()
1950 SetProvider(ctx, IdeInfoProviderKey, result)
LaMont Jonesb5099382024-01-10 23:42:36 +00001951 }
1952
Paul Duffinaf970a22020-11-23 23:32:56 +00001953 // Create the set of tagged dist files after calling GenerateAndroidBuildActions
1954 // as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
1955 // output paths being set which must be done before or during
1956 // GenerateAndroidBuildActions.
Yu Liuec810542024-08-26 18:09:15 +00001957 installFiles.DistFiles = m.GenerateTaggedDistFiles(ctx)
Paul Duffinaf970a22020-11-23 23:32:56 +00001958 if ctx.Failed() {
1959 return
1960 }
1961
Colin Crossa6182ab2024-08-21 10:47:44 -07001962 m.generateVariantTarget(ctx)
1963
Yu Liuec810542024-08-26 18:09:15 +00001964 installFiles.LicenseMetadataFile = ctx.licenseMetadataFile
Yu Liubad1eef2024-08-21 22:37:35 +00001965 installFiles.InstallFiles = ctx.installFiles
1966 installFiles.CheckbuildFiles = ctx.checkbuildFiles
Colin Crossa6182ab2024-08-21 10:47:44 -07001967 installFiles.CheckbuildTarget = ctx.checkbuildTarget
1968 installFiles.UncheckedModule = ctx.uncheckedModule
Yu Liubad1eef2024-08-21 22:37:35 +00001969 installFiles.PackagingSpecs = ctx.packagingSpecs
1970 installFiles.KatiInstalls = ctx.katiInstalls
1971 installFiles.KatiSymlinks = ctx.katiSymlinks
1972 installFiles.TestData = ctx.testData
Colin Crossdc35e212019-06-06 16:13:11 -07001973 } else if ctx.Config().AllowMissingDependencies() {
1974 // If the module is not enabled it will not create any build rules, nothing will call
1975 // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
1976 // and report them as an error even when AllowMissingDependencies = true. Call
1977 // ctx.GetMissingDependencies() here to tell blueprint not to handle them.
1978 ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08001979 }
1980
Colin Cross4157e882019-06-06 16:57:04 -07001981 if m == ctx.FinalModule().(Module).base() {
1982 m.generateModuleTarget(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -07001983 if ctx.Failed() {
1984 return
1985 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001986 }
Colin Crosscec81712017-07-13 14:43:27 -07001987
Yu Liubad1eef2024-08-21 22:37:35 +00001988 ctx.TransitiveInstallFiles = NewDepSet[InstallPath](TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles)
1989 installFiles.TransitiveInstallFiles = ctx.TransitiveInstallFiles
Yu Liueb6d7052024-08-27 22:35:54 +00001990 installFiles.TransitivePackagingSpecs = NewDepSet[PackagingSpec](TOPOLOGICAL, ctx.packagingSpecs, dependencyPackagingSpecs)
Colin Cross5d583952020-11-24 16:21:24 -08001991
Yu Liubad1eef2024-08-21 22:37:35 +00001992 SetProvider(ctx, InstallFilesProvider, installFiles)
Yu Liuec810542024-08-26 18:09:15 +00001993 buildLicenseMetadata(ctx, ctx.licenseMetadataFile)
Colin Cross4acaea92021-12-10 23:05:02 +00001994
Yu Liu4297ad92024-08-27 19:50:13 +00001995 if ctx.moduleInfoJSON != nil {
Colin Crossd6fd0132023-11-06 13:54:06 -08001996 var installed InstallPaths
Yu Liud46e5ae2024-08-15 18:46:17 +00001997 installed = append(installed, ctx.katiInstalls.InstallPaths()...)
1998 installed = append(installed, ctx.katiSymlinks.InstallPaths()...)
Yu Liu82a6d142024-08-27 19:02:29 +00001999 installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...)
2000 installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...)
Colin Crossd6fd0132023-11-06 13:54:06 -08002001 installedStrings := installed.Strings()
2002
2003 var targetRequired, hostRequired []string
2004 if ctx.Host() {
2005 targetRequired = m.commonProperties.Target_required
2006 } else {
2007 hostRequired = m.commonProperties.Host_required
2008 }
2009
2010 var data []string
Yu Liud46e5ae2024-08-15 18:46:17 +00002011 for _, d := range ctx.testData {
Colin Crossd6fd0132023-11-06 13:54:06 -08002012 data = append(data, d.ToRelativeInstallPath())
2013 }
2014
Yu Liu4297ad92024-08-27 19:50:13 +00002015 if ctx.moduleInfoJSON.Uninstallable {
Colin Crossd6fd0132023-11-06 13:54:06 -08002016 installedStrings = nil
Yu Liu4297ad92024-08-27 19:50:13 +00002017 if len(ctx.moduleInfoJSON.CompatibilitySuites) == 1 && ctx.moduleInfoJSON.CompatibilitySuites[0] == "null-suite" {
2018 ctx.moduleInfoJSON.CompatibilitySuites = nil
2019 ctx.moduleInfoJSON.TestConfig = nil
2020 ctx.moduleInfoJSON.AutoTestConfig = nil
Colin Crossd6fd0132023-11-06 13:54:06 -08002021 data = nil
2022 }
2023 }
2024
Yu Liu4297ad92024-08-27 19:50:13 +00002025 ctx.moduleInfoJSON.core = CoreModuleInfoJSON{
2026 RegisterName: m.moduleInfoRegisterName(ctx, ctx.moduleInfoJSON.SubName),
Colin Crossd6fd0132023-11-06 13:54:06 -08002027 Path: []string{ctx.ModuleDir()},
2028 Installed: installedStrings,
Yu Liu4297ad92024-08-27 19:50:13 +00002029 ModuleName: m.BaseModuleName() + ctx.moduleInfoJSON.SubName,
Colin Crossd6fd0132023-11-06 13:54:06 -08002030 SupportedVariants: []string{m.moduleInfoVariant(ctx)},
2031 TargetDependencies: targetRequired,
2032 HostDependencies: hostRequired,
2033 Data: data,
Kiyoung Kim74408202024-08-29 17:39:07 +09002034 Required: append(m.RequiredModuleNames(ctx), m.VintfFragmentModuleNames(ctx)...),
Colin Crossd6fd0132023-11-06 13:54:06 -08002035 }
Yu Liu4297ad92024-08-27 19:50:13 +00002036 SetProvider(ctx, ModuleInfoJSONProvider, ctx.moduleInfoJSON)
Colin Crossd6fd0132023-11-06 13:54:06 -08002037 }
2038
Colin Cross4157e882019-06-06 16:57:04 -07002039 m.buildParams = ctx.buildParams
2040 m.ruleParams = ctx.ruleParams
2041 m.variables = ctx.variables
mrziwange6c85812024-05-22 14:36:09 -07002042
Yu Liu876b7ce2024-08-21 18:20:13 +00002043 outputFiles := ctx.GetOutputFiles()
2044 if outputFiles.DefaultOutputFiles != nil || outputFiles.TaggedOutputFiles != nil {
2045 SetProvider(ctx, OutputFilesProvider, outputFiles)
mrziwange6c85812024-05-22 14:36:09 -07002046 }
Wei Lia1aa2972024-06-21 13:08:51 -07002047
Yu Liu54513622024-08-19 20:00:32 +00002048 if len(ctx.phonies) > 0 {
2049 SetProvider(ctx, ModulePhonyProvider, ModulePhonyInfo{
2050 Phonies: ctx.phonies,
2051 })
2052 }
Wei Lia1aa2972024-06-21 13:08:51 -07002053 buildComplianceMetadataProvider(ctx, m)
Colin Cross3f40fa42015-01-30 17:27:36 -08002054}
2055
Joe Onorato349ae8d2024-02-05 22:46:00 +00002056func SetJarJarPrefixHandler(handler func(ModuleContext)) {
2057 if jarJarPrefixHandler != nil {
2058 panic("jarJarPrefixHandler already set")
2059 }
2060 jarJarPrefixHandler = handler
2061}
2062
Colin Crossd6fd0132023-11-06 13:54:06 -08002063func (m *ModuleBase) moduleInfoRegisterName(ctx ModuleContext, subName string) string {
2064 name := m.BaseModuleName()
2065
2066 prefix := ""
2067 if ctx.Host() {
2068 if ctx.Os() != ctx.Config().BuildOS {
2069 prefix = "host_cross_"
2070 }
2071 }
2072 suffix := ""
2073 arches := slices.Clone(ctx.Config().Targets[ctx.Os()])
2074 arches = slices.DeleteFunc(arches, func(target Target) bool {
2075 return target.NativeBridge != ctx.Target().NativeBridge
2076 })
2077 if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType {
2078 if ctx.Arch().ArchType.Multilib == "lib32" {
2079 suffix = "_32"
2080 } else {
2081 suffix = "_64"
2082 }
2083 }
2084 return prefix + name + subName + suffix
2085}
2086
2087func (m *ModuleBase) moduleInfoVariant(ctx ModuleContext) string {
2088 variant := "DEVICE"
2089 if ctx.Host() {
2090 if ctx.Os() != ctx.Config().BuildOS {
2091 variant = "HOST_CROSS"
2092 } else {
2093 variant = "HOST"
2094 }
2095 }
2096 return variant
2097}
2098
Paul Duffin89968e32020-11-23 18:17:03 +00002099// Check the supplied dist structure to make sure that it is valid.
2100//
2101// property - the base property, e.g. dist or dists[1], which is combined with the
2102// name of the nested property to produce the full property, e.g. dist.dest or
2103// dists[1].dir.
2104func checkDistProperties(ctx *moduleContext, property string, dist *Dist) {
2105 if dist.Dest != nil {
2106 _, err := validateSafePath(*dist.Dest)
2107 if err != nil {
2108 ctx.PropertyErrorf(property+".dest", "%s", err.Error())
2109 }
2110 }
2111 if dist.Dir != nil {
2112 _, err := validateSafePath(*dist.Dir)
2113 if err != nil {
2114 ctx.PropertyErrorf(property+".dir", "%s", err.Error())
2115 }
2116 }
2117 if dist.Suffix != nil {
2118 if strings.Contains(*dist.Suffix, "/") {
2119 ctx.PropertyErrorf(property+".suffix", "Suffix may not contain a '/' character.")
2120 }
2121 }
2122
2123}
2124
Colin Cross6301c3c2021-09-28 17:40:21 -07002125// katiInstall stores a request from Soong to Make to create an install rule.
2126type katiInstall struct {
2127 from Path
2128 to InstallPath
2129 implicitDeps Paths
2130 orderOnlyDeps Paths
2131 executable bool
Colin Cross50ed1f92021-11-12 17:41:02 -08002132 extraFiles *extraFilesZip
Colin Cross6301c3c2021-09-28 17:40:21 -07002133
2134 absFrom string
2135}
2136
Yu Liu26a716d2024-08-30 23:40:32 +00002137func (p *katiInstall) GobEncode() ([]byte, error) {
2138 w := new(bytes.Buffer)
2139 encoder := gob.NewEncoder(w)
2140 err := errors.Join(encoder.Encode(p.from), encoder.Encode(p.to),
2141 encoder.Encode(p.implicitDeps), encoder.Encode(p.orderOnlyDeps),
2142 encoder.Encode(p.executable), encoder.Encode(p.extraFiles),
2143 encoder.Encode(p.absFrom))
2144 if err != nil {
2145 return nil, err
2146 }
2147
2148 return w.Bytes(), nil
2149}
2150
2151func (p *katiInstall) GobDecode(data []byte) error {
2152 r := bytes.NewBuffer(data)
2153 decoder := gob.NewDecoder(r)
2154 err := errors.Join(decoder.Decode(&p.from), decoder.Decode(&p.to),
2155 decoder.Decode(&p.implicitDeps), decoder.Decode(&p.orderOnlyDeps),
2156 decoder.Decode(&p.executable), decoder.Decode(&p.extraFiles),
2157 decoder.Decode(&p.absFrom))
2158 if err != nil {
2159 return err
2160 }
2161
2162 return nil
2163}
2164
Colin Cross50ed1f92021-11-12 17:41:02 -08002165type extraFilesZip struct {
2166 zip Path
2167 dir InstallPath
2168}
2169
Yu Liu26a716d2024-08-30 23:40:32 +00002170func (p *extraFilesZip) GobEncode() ([]byte, error) {
2171 w := new(bytes.Buffer)
2172 encoder := gob.NewEncoder(w)
2173 err := errors.Join(encoder.Encode(p.zip), encoder.Encode(p.dir))
2174 if err != nil {
2175 return nil, err
2176 }
2177
2178 return w.Bytes(), nil
2179}
2180
2181func (p *extraFilesZip) GobDecode(data []byte) error {
2182 r := bytes.NewBuffer(data)
2183 decoder := gob.NewDecoder(r)
2184 err := errors.Join(decoder.Decode(&p.zip), decoder.Decode(&p.dir))
2185 if err != nil {
2186 return err
2187 }
2188
2189 return nil
2190}
2191
Colin Cross6301c3c2021-09-28 17:40:21 -07002192type katiInstalls []katiInstall
2193
2194// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
2195// space separated list of from:to tuples.
2196func (installs katiInstalls) BuiltInstalled() string {
2197 sb := strings.Builder{}
2198 for i, install := range installs {
2199 if i != 0 {
2200 sb.WriteRune(' ')
2201 }
2202 sb.WriteString(install.from.String())
2203 sb.WriteRune(':')
2204 sb.WriteString(install.to.String())
2205 }
2206 return sb.String()
2207}
2208
2209// InstallPaths returns the install path of each entry.
2210func (installs katiInstalls) InstallPaths() InstallPaths {
2211 paths := make(InstallPaths, 0, len(installs))
2212 for _, install := range installs {
2213 paths = append(paths, install.to)
2214 }
2215 return paths
2216}
2217
Jiyong Park5baac542018-08-28 09:55:37 +09002218// Makes this module a platform module, i.e. not specific to soc, device,
Justin Yund5f6c822019-06-25 16:47:17 +09002219// product, or system_ext.
Colin Cross4157e882019-06-06 16:57:04 -07002220func (m *ModuleBase) MakeAsPlatform() {
2221 m.commonProperties.Vendor = boolPtr(false)
2222 m.commonProperties.Proprietary = boolPtr(false)
2223 m.commonProperties.Soc_specific = boolPtr(false)
2224 m.commonProperties.Product_specific = boolPtr(false)
Justin Yund5f6c822019-06-25 16:47:17 +09002225 m.commonProperties.System_ext_specific = boolPtr(false)
Jiyong Park5baac542018-08-28 09:55:37 +09002226}
2227
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09002228func (m *ModuleBase) MakeAsSystemExt() {
Jooyung Han91df2082019-11-20 01:49:42 +09002229 m.commonProperties.Vendor = boolPtr(false)
2230 m.commonProperties.Proprietary = boolPtr(false)
2231 m.commonProperties.Soc_specific = boolPtr(false)
2232 m.commonProperties.Product_specific = boolPtr(false)
2233 m.commonProperties.System_ext_specific = boolPtr(true)
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09002234}
2235
Jooyung Han344d5432019-08-23 11:17:39 +09002236// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true"
2237func (m *ModuleBase) IsNativeBridgeSupported() bool {
2238 return proptools.Bool(m.commonProperties.Native_bridge_supported)
2239}
2240
Colin Cross8bbc3d52024-09-11 15:33:54 -07002241type ConfigContext interface {
2242 Config() Config
2243}
2244
Cole Fauste8a87832024-09-11 11:35:46 -07002245type ConfigurableEvaluatorContext interface {
Cole Faust55b56fe2024-08-23 12:06:11 -07002246 OtherModuleProviderContext
Cole Faust02987bd2024-03-21 17:58:43 -07002247 Config() Config
2248 OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{})
Cole Faustd7067092024-09-13 13:37:59 -07002249 HasMutatorFinished(mutatorName string) bool
Cole Faust02987bd2024-03-21 17:58:43 -07002250}
2251
2252type configurationEvalutor struct {
Cole Fauste8a87832024-09-11 11:35:46 -07002253 ctx ConfigurableEvaluatorContext
Cole Faust02987bd2024-03-21 17:58:43 -07002254 m Module
2255}
2256
Cole Fauste8a87832024-09-11 11:35:46 -07002257func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator {
Cole Faust02987bd2024-03-21 17:58:43 -07002258 return configurationEvalutor{
2259 ctx: ctx,
2260 m: m.module,
2261 }
2262}
2263
2264func (e configurationEvalutor) PropertyErrorf(property string, fmt string, args ...interface{}) {
Cole Fausta963b942024-04-11 17:43:00 -07002265 e.ctx.OtherModulePropertyErrorf(e.m, property, fmt, args...)
Cole Faust02987bd2024-03-21 17:58:43 -07002266}
2267
Cole Faustfdbf5d42024-04-10 15:01:23 -07002268func (e configurationEvalutor) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue {
Cole Faust02987bd2024-03-21 17:58:43 -07002269 ctx := e.ctx
2270 m := e.m
Cole Faustd7067092024-09-13 13:37:59 -07002271
2272 if !ctx.HasMutatorFinished("defaults") {
2273 ctx.OtherModulePropertyErrorf(m, property, "Cannot evaluate configurable property before the defaults mutator has run")
2274 return proptools.ConfigurableValueUndefined()
2275 }
2276
Cole Faust8afc5142024-04-26 16:30:19 -07002277 switch condition.FunctionName() {
Cole Fauste19f7412024-05-09 15:14:04 -07002278 case "release_flag":
Cole Faust8afc5142024-04-26 16:30:19 -07002279 if condition.NumArgs() != 1 {
Cole Fauste19f7412024-05-09 15:14:04 -07002280 ctx.OtherModulePropertyErrorf(m, property, "release_flag requires 1 argument, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002281 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002282 }
Cole Faust751a4a52024-05-21 16:51:59 -07002283 if ty, ok := ctx.Config().productVariables.BuildFlagTypes[condition.Arg(0)]; ok {
2284 v := ctx.Config().productVariables.BuildFlags[condition.Arg(0)]
2285 switch ty {
2286 case "unspecified", "obsolete":
2287 return proptools.ConfigurableValueUndefined()
2288 case "string":
2289 return proptools.ConfigurableValueString(v)
2290 case "bool":
2291 return proptools.ConfigurableValueBool(v == "true")
2292 default:
2293 panic("unhandled release flag type: " + ty)
2294 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002295 }
2296 return proptools.ConfigurableValueUndefined()
2297 case "product_variable":
Jiyong Parke3250752024-05-17 14:56:10 +09002298 if condition.NumArgs() != 1 {
2299 ctx.OtherModulePropertyErrorf(m, property, "product_variable requires 1 argument, found %d", condition.NumArgs())
2300 return proptools.ConfigurableValueUndefined()
2301 }
2302 variable := condition.Arg(0)
2303 switch variable {
Jihoon Kang82bea762024-09-30 18:50:54 +00002304 case "build_from_text_stub":
2305 return proptools.ConfigurableValueBool(ctx.Config().BuildFromTextStub())
Jiyong Parke3250752024-05-17 14:56:10 +09002306 case "debuggable":
2307 return proptools.ConfigurableValueBool(ctx.Config().Debuggable())
Kiyoung Kim881e4652024-07-08 11:02:23 +09002308 case "use_debug_art":
2309 // TODO(b/234351700): Remove once ART does not have separated debug APEX
2310 return proptools.ConfigurableValueBool(ctx.Config().UseDebugArt())
Jiyong Parke3250752024-05-17 14:56:10 +09002311 default:
2312 // TODO(b/323382414): Might add these on a case-by-case basis
2313 ctx.OtherModulePropertyErrorf(m, property, fmt.Sprintf("TODO(b/323382414): Product variable %q is not yet supported in selects", variable))
2314 return proptools.ConfigurableValueUndefined()
2315 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002316 case "soong_config_variable":
Cole Faust8afc5142024-04-26 16:30:19 -07002317 if condition.NumArgs() != 2 {
2318 ctx.OtherModulePropertyErrorf(m, property, "soong_config_variable requires 2 arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002319 return proptools.ConfigurableValueUndefined()
2320 }
Cole Faust8afc5142024-04-26 16:30:19 -07002321 namespace := condition.Arg(0)
2322 variable := condition.Arg(1)
Cole Faust02987bd2024-03-21 17:58:43 -07002323 if n, ok := ctx.Config().productVariables.VendorVars[namespace]; ok {
2324 if v, ok := n[variable]; ok {
Cole Faust46f6e2f2024-06-20 12:57:43 -07002325 ty := ""
2326 if namespaces, ok := ctx.Config().productVariables.VendorVarTypes[namespace]; ok {
2327 ty = namespaces[variable]
2328 }
2329 switch ty {
2330 case "":
2331 // strings are the default, we don't bother writing them to the soong variables json file
2332 return proptools.ConfigurableValueString(v)
2333 case "bool":
2334 return proptools.ConfigurableValueBool(v == "true")
2335 default:
2336 panic("unhandled soong config variable type: " + ty)
2337 }
2338
Cole Faust02987bd2024-03-21 17:58:43 -07002339 }
2340 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002341 return proptools.ConfigurableValueUndefined()
Cole Faustfc57d402024-04-11 12:09:44 -07002342 case "arch":
Cole Faust8afc5142024-04-26 16:30:19 -07002343 if condition.NumArgs() != 0 {
2344 ctx.OtherModulePropertyErrorf(m, property, "arch requires no arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002345 return proptools.ConfigurableValueUndefined()
2346 }
Cole Faustfc57d402024-04-11 12:09:44 -07002347 if !m.base().ArchReady() {
2348 ctx.OtherModulePropertyErrorf(m, property, "A select on arch was attempted before the arch mutator ran")
2349 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002350 }
Cole Faustfc57d402024-04-11 12:09:44 -07002351 return proptools.ConfigurableValueString(m.base().Arch().ArchType.Name)
2352 case "os":
Cole Faust8afc5142024-04-26 16:30:19 -07002353 if condition.NumArgs() != 0 {
2354 ctx.OtherModulePropertyErrorf(m, property, "os requires no arguments, found %d", condition.NumArgs())
Cole Faustfc57d402024-04-11 12:09:44 -07002355 return proptools.ConfigurableValueUndefined()
2356 }
2357 // the arch mutator runs after the os mutator, we can just use this to enforce that os is ready.
2358 if !m.base().ArchReady() {
2359 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)")
2360 return proptools.ConfigurableValueUndefined()
2361 }
2362 return proptools.ConfigurableValueString(m.base().Os().Name)
Cole Faustfdbf5d42024-04-10 15:01:23 -07002363 case "boolean_var_for_testing":
2364 // We currently don't have any other boolean variables (we should add support for typing
2365 // the soong config variables), so add this fake one for testing the boolean select
2366 // functionality.
Cole Faust8afc5142024-04-26 16:30:19 -07002367 if condition.NumArgs() != 0 {
2368 ctx.OtherModulePropertyErrorf(m, property, "boolean_var_for_testing requires 0 arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002369 return proptools.ConfigurableValueUndefined()
2370 }
2371
2372 if n, ok := ctx.Config().productVariables.VendorVars["boolean_var"]; ok {
2373 if v, ok := n["for_testing"]; ok {
2374 switch v {
2375 case "true":
2376 return proptools.ConfigurableValueBool(true)
2377 case "false":
2378 return proptools.ConfigurableValueBool(false)
2379 default:
2380 ctx.OtherModulePropertyErrorf(m, property, "testing:my_boolean_var can only be true or false, found %q", v)
2381 }
2382 }
2383 }
2384 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002385 default:
Cole Faustfdbf5d42024-04-10 15:01:23 -07002386 ctx.OtherModulePropertyErrorf(m, property, "Unknown select condition %s", condition.FunctionName)
2387 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002388 }
2389}
2390
Colin Crossb63d7b32023-12-07 16:54:51 -08002391// ModuleNameWithPossibleOverride returns the name of the OverrideModule that overrides the current
2392// variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule
2393// or if this variant is not overridden.
2394func ModuleNameWithPossibleOverride(ctx BaseModuleContext) string {
2395 if overridable, ok := ctx.Module().(OverridableModule); ok {
2396 if o := overridable.GetOverriddenBy(); o != "" {
2397 return o
2398 }
2399 }
2400 return ctx.ModuleName()
2401}
2402
Paul Duffine6ba0722021-07-12 20:12:12 +01002403// SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name"
2404// into the module name, or empty string if the input was not a module reference.
Colin Cross41955e82019-05-29 14:40:35 -07002405func SrcIsModule(s string) (module string) {
Paul Duffine6ba0722021-07-12 20:12:12 +01002406 if len(s) > 1 {
2407 if s[0] == ':' {
2408 module = s[1:]
2409 if !isUnqualifiedModuleName(module) {
2410 // The module name should be unqualified but is not so do not treat it as a module.
2411 module = ""
2412 }
2413 } else if s[0] == '/' && s[1] == '/' {
2414 module = s
2415 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002416 }
Paul Duffine6ba0722021-07-12 20:12:12 +01002417 return module
Colin Cross068e0fe2016-12-13 15:23:47 -08002418}
2419
Yi-Yo Chiangba9ea322021-07-15 17:18:21 +08002420// SrcIsModuleWithTag decodes module references in the format ":unqualified-name{.tag}" or
2421// "//namespace:name{.tag}" into the module name and tag, ":unqualified-name" or "//namespace:name"
2422// into the module name and an empty string for the tag, or empty strings if the input was not a
2423// module reference.
Colin Cross41955e82019-05-29 14:40:35 -07002424func SrcIsModuleWithTag(s string) (module, tag string) {
Paul Duffine6ba0722021-07-12 20:12:12 +01002425 if len(s) > 1 {
2426 if s[0] == ':' {
2427 module = s[1:]
2428 } else if s[0] == '/' && s[1] == '/' {
2429 module = s
2430 }
2431
2432 if module != "" {
2433 if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
2434 if module[len(module)-1] == '}' {
2435 tag = module[tagStart+1 : len(module)-1]
2436 module = module[:tagStart]
2437 }
2438 }
2439
2440 if s[0] == ':' && !isUnqualifiedModuleName(module) {
2441 // The module name should be unqualified but is not so do not treat it as a module.
2442 module = ""
2443 tag = ""
Colin Cross41955e82019-05-29 14:40:35 -07002444 }
2445 }
Colin Cross41955e82019-05-29 14:40:35 -07002446 }
Paul Duffine6ba0722021-07-12 20:12:12 +01002447
2448 return module, tag
2449}
2450
2451// isUnqualifiedModuleName makes sure that the supplied module is an unqualified module name, i.e.
2452// does not contain any /.
2453func isUnqualifiedModuleName(module string) bool {
2454 return strings.IndexByte(module, '/') == -1
Colin Cross068e0fe2016-12-13 15:23:47 -08002455}
2456
Paul Duffin40131a32021-07-09 17:10:35 +01002457// sourceOrOutputDependencyTag is the dependency tag added automatically by pathDepsMutator for any
2458// module reference in a property annotated with `android:"path"` or passed to ExtractSourceDeps
2459// or ExtractSourcesDeps.
2460//
2461// If uniquely identifies the dependency that was added as it contains both the module name used to
2462// add the dependency as well as the tag. That makes it very simple to find the matching dependency
2463// in GetModuleFromPathDep as all it needs to do is find the dependency whose tag matches the tag
2464// used to add it. It does not need to check that the module name as returned by one of
2465// Module.Name(), BaseModuleContext.OtherModuleName() or ModuleBase.BaseModuleName() matches the
2466// name supplied in the tag. That means it does not need to handle differences in module names
2467// caused by prebuilt_ prefix, or fully qualified module names.
Colin Cross41955e82019-05-29 14:40:35 -07002468type sourceOrOutputDependencyTag struct {
2469 blueprint.BaseDependencyTag
Yu Liu67a28422024-03-05 00:36:31 +00002470 AlwaysPropagateAconfigValidationDependencyTag
Paul Duffin40131a32021-07-09 17:10:35 +01002471
2472 // The name of the module.
2473 moduleName string
2474
mrziwangd38e63d2024-07-15 13:43:37 -07002475 // The tag that will be used to get the specific output file(s).
Colin Cross41955e82019-05-29 14:40:35 -07002476 tag string
2477}
2478
Paul Duffin40131a32021-07-09 17:10:35 +01002479func sourceOrOutputDepTag(moduleName, tag string) blueprint.DependencyTag {
2480 return sourceOrOutputDependencyTag{moduleName: moduleName, tag: tag}
Colin Cross41955e82019-05-29 14:40:35 -07002481}
2482
Paul Duffind5cf92e2021-07-09 17:38:55 +01002483// IsSourceDepTagWithOutputTag returns true if the supplied blueprint.DependencyTag is one that was
2484// used to add dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for
2485// properties tagged with `android:"path"` AND it was added using a module reference of
2486// :moduleName{outputTag}.
2487func IsSourceDepTagWithOutputTag(depTag blueprint.DependencyTag, outputTag string) bool {
2488 t, ok := depTag.(sourceOrOutputDependencyTag)
2489 return ok && t.tag == outputTag
2490}
2491
Colin Cross366938f2017-12-11 16:29:02 -08002492// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
2493// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08002494//
2495// Deprecated: tag the property with `android:"path"` instead.
Colin Cross068e0fe2016-12-13 15:23:47 -08002496func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
Nan Zhang2439eb72017-04-10 11:27:50 -07002497 set := make(map[string]bool)
2498
Colin Cross068e0fe2016-12-13 15:23:47 -08002499 for _, s := range srcFiles {
Colin Cross41955e82019-05-29 14:40:35 -07002500 if m, t := SrcIsModuleWithTag(s); m != "" {
2501 if _, found := set[s]; found {
2502 ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
Nan Zhang2439eb72017-04-10 11:27:50 -07002503 } else {
Colin Cross41955e82019-05-29 14:40:35 -07002504 set[s] = true
Paul Duffin40131a32021-07-09 17:10:35 +01002505 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
Nan Zhang2439eb72017-04-10 11:27:50 -07002506 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002507 }
2508 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002509}
2510
Colin Cross366938f2017-12-11 16:29:02 -08002511// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
2512// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08002513//
2514// Deprecated: tag the property with `android:"path"` instead.
Colin Cross366938f2017-12-11 16:29:02 -08002515func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
2516 if s != nil {
Colin Cross41955e82019-05-29 14:40:35 -07002517 if m, t := SrcIsModuleWithTag(*s); m != "" {
Paul Duffin40131a32021-07-09 17:10:35 +01002518 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
Colin Cross366938f2017-12-11 16:29:02 -08002519 }
2520 }
2521}
2522
Colin Cross41955e82019-05-29 14:40:35 -07002523// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"`
2524// 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 -08002525type SourceFileProducer interface {
2526 Srcs() Paths
2527}
2528
mrziwangd38e63d2024-07-15 13:43:37 -07002529// OutputFilesForModule returns the output file paths with the given tag. On error, including if the
Colin Cross5e708052019-08-06 13:59:50 -07002530// module produced zero paths, it reports errors to the ctx and returns nil.
2531func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) Paths {
2532 paths, err := outputFilesForModule(ctx, module, tag)
2533 if err != nil {
2534 reportPathError(ctx, err)
2535 return nil
2536 }
2537 return paths
2538}
2539
mrziwangd38e63d2024-07-15 13:43:37 -07002540// OutputFileForModule returns the output file paths with the given tag. On error, including if the
Colin Cross5e708052019-08-06 13:59:50 -07002541// module produced zero or multiple paths, it reports errors to the ctx and returns nil.
2542func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) Path {
2543 paths, err := outputFilesForModule(ctx, module, tag)
2544 if err != nil {
2545 reportPathError(ctx, err)
2546 return nil
2547 }
Colin Cross14ec66c2022-10-03 21:02:27 -07002548 if len(paths) == 0 {
2549 type addMissingDependenciesIntf interface {
2550 AddMissingDependencies([]string)
2551 OtherModuleName(blueprint.Module) string
2552 }
2553 if mctx, ok := ctx.(addMissingDependenciesIntf); ok && ctx.Config().AllowMissingDependencies() {
2554 mctx.AddMissingDependencies([]string{mctx.OtherModuleName(module)})
2555 } else {
2556 ReportPathErrorf(ctx, "failed to get output files from module %q", pathContextName(ctx, module))
2557 }
2558 // Return a fake output file to avoid nil dereferences of Path objects later.
2559 // This should never get used for an actual build as the error or missing
2560 // dependency has already been reported.
2561 p, err := pathForSource(ctx, filepath.Join("missing_output_file", pathContextName(ctx, module)))
2562 if err != nil {
2563 reportPathError(ctx, err)
2564 return nil
2565 }
2566 return p
2567 }
Colin Cross5e708052019-08-06 13:59:50 -07002568 if len(paths) > 1 {
Ulya Trafimovich5ab276a2020-08-25 12:45:15 +01002569 ReportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
Colin Cross5e708052019-08-06 13:59:50 -07002570 pathContextName(ctx, module))
Colin Cross5e708052019-08-06 13:59:50 -07002571 }
2572 return paths[0]
2573}
2574
2575func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
mrziwange6c85812024-05-22 14:36:09 -07002576 outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag)
mrziwangabdb2932024-06-18 12:43:41 -07002577 if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet {
mrziwange6c85812024-05-22 14:36:09 -07002578 return outputFilesFromProvider, err
2579 }
mrziwang1ea01e32024-07-12 12:26:34 -07002580 if sourceFileProducer, ok := module.(SourceFileProducer); ok {
Colin Cross74b1e2b2020-11-22 20:23:02 -08002581 if tag != "" {
mrziwang1ea01e32024-07-12 12:26:34 -07002582 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 -08002583 }
2584 paths := sourceFileProducer.Srcs()
Colin Cross74b1e2b2020-11-22 20:23:02 -08002585 return paths, nil
Colin Cross5e708052019-08-06 13:59:50 -07002586 } else {
mrziwang68b25942024-07-11 09:58:30 -07002587 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 -07002588 }
2589}
2590
mrziwange6c85812024-05-22 14:36:09 -07002591// This method uses OutputFilesProvider for output files
2592// *inter-module-communication*.
2593// If mctx module is the same as the param module the output files are obtained
2594// from outputFiles property of module base, to avoid both setting and
mrziwang42953592024-06-20 09:53:33 -07002595// reading OutputFilesProvider before GenerateBuildActions is finished.
mrziwange6c85812024-05-22 14:36:09 -07002596// If a module doesn't have the OutputFilesProvider, nil is returned.
2597func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
mrziwangabdb2932024-06-18 12:43:41 -07002598 var outputFiles OutputFilesInfo
2599 fromProperty := false
mrziwang0cbd3b02024-06-20 16:39:25 -07002600
mrziwang1ea01e32024-07-12 12:26:34 -07002601 type OutputFilesProviderModuleContext interface {
2602 OtherModuleProviderContext
2603 Module() Module
Yu Liu876b7ce2024-08-21 18:20:13 +00002604 GetOutputFiles() OutputFilesInfo
mrziwang1ea01e32024-07-12 12:26:34 -07002605 }
2606
2607 if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx {
mrziwang0cbd3b02024-06-20 16:39:25 -07002608 if mctx.Module() != module {
mrziwangabdb2932024-06-18 12:43:41 -07002609 outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider)
mrziwang0cbd3b02024-06-20 16:39:25 -07002610 } else {
Yu Liu876b7ce2024-08-21 18:20:13 +00002611 outputFiles = mctx.GetOutputFiles()
mrziwangabdb2932024-06-18 12:43:41 -07002612 fromProperty = true
mrziwange6c85812024-05-22 14:36:09 -07002613 }
mrziwang0cbd3b02024-06-20 16:39:25 -07002614 } else if cta, isCta := ctx.(*singletonContextAdaptor); isCta {
Yu Liu663e4502024-08-12 18:23:59 +00002615 providerData, _ := cta.otherModuleProvider(module, OutputFilesProvider)
mrziwangabdb2932024-06-18 12:43:41 -07002616 outputFiles, _ = providerData.(OutputFilesInfo)
mrziwang7a47bd32024-07-17 11:11:05 -07002617 } else {
2618 return nil, fmt.Errorf("unsupported context %q in method outputFilesForModuleFromProvider", reflect.TypeOf(ctx))
mrziwang0cbd3b02024-06-20 16:39:25 -07002619 }
mrziwang0cbd3b02024-06-20 16:39:25 -07002620
mrziwangabdb2932024-06-18 12:43:41 -07002621 if outputFiles.isEmpty() {
mrziwangabdb2932024-06-18 12:43:41 -07002622 return nil, OutputFilesProviderNotSet
2623 }
2624
2625 if tag == "" {
2626 return outputFiles.DefaultOutputFiles, nil
2627 } else if taggedOutputFiles, hasTag := outputFiles.TaggedOutputFiles[tag]; hasTag {
2628 return taggedOutputFiles, nil
2629 } else {
2630 if fromProperty {
2631 return nil, fmt.Errorf("unsupported tag %q for module getting its own output files", tag)
mrziwange6c85812024-05-22 14:36:09 -07002632 } else {
mrziwang0cbd3b02024-06-20 16:39:25 -07002633 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
mrziwange6c85812024-05-22 14:36:09 -07002634 }
2635 }
mrziwange6c85812024-05-22 14:36:09 -07002636}
2637
mrziwang0cbd3b02024-06-20 16:39:25 -07002638func (o OutputFilesInfo) isEmpty() bool {
2639 return o.DefaultOutputFiles == nil && o.TaggedOutputFiles == nil
2640}
2641
mrziwange6c85812024-05-22 14:36:09 -07002642type OutputFilesInfo struct {
2643 // default output files when tag is an empty string ""
2644 DefaultOutputFiles Paths
2645
2646 // the corresponding output files for given tags
2647 TaggedOutputFiles map[string]Paths
2648}
2649
2650var OutputFilesProvider = blueprint.NewProvider[OutputFilesInfo]()
2651
mrziwangabdb2932024-06-18 12:43:41 -07002652// This is used to mark the case where OutputFilesProvider is not set on some modules.
2653var OutputFilesProviderNotSet = fmt.Errorf("No output files from provider")
2654
Colin Cross41589502020-12-01 14:00:21 -08002655// Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to
2656// specify that they can be used as a tool by a genrule module.
Colin Crossfe17f6f2019-03-28 19:30:56 -07002657type HostToolProvider interface {
Colin Crossba9e4032020-11-24 16:32:22 -08002658 Module
Colin Cross41589502020-12-01 14:00:21 -08002659 // HostToolPath returns the path to the host tool for the module if it is one, or an invalid
2660 // OptionalPath.
Colin Crossfe17f6f2019-03-28 19:30:56 -07002661 HostToolPath() OptionalPath
2662}
2663
Colin Cross463a90e2015-06-17 14:20:06 -07002664func init() {
LaMont Jones0c10e4d2023-05-16 00:58:37 +00002665 RegisterParallelSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07002666}
2667
Colin Cross0875c522017-11-28 17:34:01 -08002668func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07002669 return &buildTargetSingleton{}
2670}
2671
Colin Cross87d8b562017-04-25 10:01:55 -07002672func parentDir(dir string) string {
2673 dir, _ = filepath.Split(dir)
2674 return filepath.Clean(dir)
2675}
2676
Colin Cross1f8c52b2015-06-16 16:38:17 -07002677type buildTargetSingleton struct{}
2678
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002679func AddAncestors(ctx SingletonContext, dirMap map[string]Paths, mmName func(string) string) ([]string, []string) {
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002680 // Ensure ancestor directories are in dirMap
2681 // Make directories build their direct subdirectories
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002682 // Returns a slice of all directories and a slice of top-level directories.
Cole Faust18994c72023-02-28 16:02:16 -08002683 dirs := SortedKeys(dirMap)
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002684 for _, dir := range dirs {
2685 dir := parentDir(dir)
2686 for dir != "." && dir != "/" {
2687 if _, exists := dirMap[dir]; exists {
2688 break
2689 }
2690 dirMap[dir] = nil
2691 dir = parentDir(dir)
2692 }
2693 }
Cole Faust18994c72023-02-28 16:02:16 -08002694 dirs = SortedKeys(dirMap)
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002695 var topDirs []string
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002696 for _, dir := range dirs {
2697 p := parentDir(dir)
2698 if p != "." && p != "/" {
2699 dirMap[p] = append(dirMap[p], PathForPhony(ctx, mmName(dir)))
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002700 } else if dir != "." && dir != "/" && dir != "" {
2701 topDirs = append(topDirs, dir)
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002702 }
2703 }
Cole Faust18994c72023-02-28 16:02:16 -08002704 return SortedKeys(dirMap), topDirs
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002705}
2706
Colin Cross0875c522017-11-28 17:34:01 -08002707func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
2708 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07002709
Colin Crossc3d87d32020-06-04 13:25:17 -07002710 mmTarget := func(dir string) string {
2711 return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
Colin Cross87d8b562017-04-25 10:01:55 -07002712 }
2713
Colin Cross0875c522017-11-28 17:34:01 -08002714 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002715
Colin Cross0875c522017-11-28 17:34:01 -08002716 ctx.VisitAllModules(func(module Module) {
Yu Liuddc2e1a2024-08-20 21:31:22 +00002717 info := OtherModuleProviderOrDefault(ctx, module, FinalModuleBuildTargetsProvider)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002718
Yu Liuddc2e1a2024-08-20 21:31:22 +00002719 if info.CheckbuildTarget != nil {
2720 checkbuildDeps = append(checkbuildDeps, info.CheckbuildTarget)
2721 modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.CheckbuildTarget)
Colin Cross0875c522017-11-28 17:34:01 -08002722 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07002723
Yu Liuddc2e1a2024-08-20 21:31:22 +00002724 if info.InstallTarget != nil {
2725 modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.InstallTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002726 }
2727 })
2728
Dan Willemsen5ba07e82015-12-11 13:51:06 -08002729 suffix := ""
Jingwen Chencda22c92020-11-23 00:22:30 -05002730 if ctx.Config().KatiEnabled() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08002731 suffix = "-soong"
2732 }
2733
Colin Cross1f8c52b2015-06-16 16:38:17 -07002734 // Create a top-level checkbuild target that depends on all modules
Colin Crossc3d87d32020-06-04 13:25:17 -07002735 ctx.Phony("checkbuild"+suffix, checkbuildDeps...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002736
Dan Willemsend2e95fb2017-09-20 14:30:50 -07002737 // Make will generate the MODULES-IN-* targets
Jingwen Chencda22c92020-11-23 00:22:30 -05002738 if ctx.Config().KatiEnabled() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07002739 return
2740 }
2741
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002742 dirs, _ := AddAncestors(ctx, modulesInDir, mmTarget)
Colin Cross87d8b562017-04-25 10:01:55 -07002743
Dan Willemsend2e95fb2017-09-20 14:30:50 -07002744 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
2745 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
2746 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07002747 for _, dir := range dirs {
Colin Crossc3d87d32020-06-04 13:25:17 -07002748 ctx.Phony(mmTarget(dir), modulesInDir[dir]...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002749 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07002750
2751 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
Jiyong Park1613e552020-09-14 19:43:17 +09002752 type osAndCross struct {
2753 os OsType
2754 hostCross bool
2755 }
2756 osDeps := map[osAndCross]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08002757 ctx.VisitAllModules(func(module Module) {
Cole Fausta963b942024-04-11 17:43:00 -07002758 if module.Enabled(ctx) {
Jiyong Park1613e552020-09-14 19:43:17 +09002759 key := osAndCross{os: module.Target().Os, hostCross: module.Target().HostCross}
Yu Liud46e5ae2024-08-15 18:46:17 +00002760 osDeps[key] = append(osDeps[key], OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).CheckbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07002761 }
2762 })
2763
Colin Cross0875c522017-11-28 17:34:01 -08002764 osClass := make(map[string]Paths)
Jiyong Park1613e552020-09-14 19:43:17 +09002765 for key, deps := range osDeps {
Dan Willemsen61d88b82017-09-20 17:29:08 -07002766 var className string
2767
Jiyong Park1613e552020-09-14 19:43:17 +09002768 switch key.os.Class {
Dan Willemsen61d88b82017-09-20 17:29:08 -07002769 case Host:
Jiyong Park1613e552020-09-14 19:43:17 +09002770 if key.hostCross {
2771 className = "host-cross"
2772 } else {
2773 className = "host"
2774 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07002775 case Device:
2776 className = "target"
2777 default:
2778 continue
2779 }
2780
Jiyong Park1613e552020-09-14 19:43:17 +09002781 name := className + "-" + key.os.Name
Colin Crossc3d87d32020-06-04 13:25:17 -07002782 osClass[className] = append(osClass[className], PathForPhony(ctx, name))
Dan Willemsen61d88b82017-09-20 17:29:08 -07002783
Colin Crossc3d87d32020-06-04 13:25:17 -07002784 ctx.Phony(name, deps...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07002785 }
2786
2787 // Wrap those into host|host-cross|target phony rules
Cole Faust18994c72023-02-28 16:02:16 -08002788 for _, class := range SortedKeys(osClass) {
Colin Crossc3d87d32020-06-04 13:25:17 -07002789 ctx.Phony(class, osClass[class]...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07002790 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07002791}
Colin Crossd779da42015-12-17 18:00:23 -08002792
Brandon Lee5d45c6f2018-08-15 15:35:38 -07002793// Collect information for opening IDE project files in java/jdeps.go.
2794type IDEInfo interface {
Cole Faustb36d31d2024-08-27 16:04:28 -07002795 IDEInfo(ctx BaseModuleContext, ideInfo *IdeInfo)
Brandon Lee5d45c6f2018-08-15 15:35:38 -07002796 BaseModuleName() string
2797}
2798
2799// Extract the base module name from the Import name.
2800// Often the Import name has a prefix "prebuilt_".
2801// Remove the prefix explicitly if needed
2802// until we find a better solution to get the Import name.
2803type IDECustomizedModuleName interface {
2804 IDECustomizedModuleName() string
2805}
2806
Cole Faust08c7f862024-08-27 15:03:59 -07002807// Collect information for opening IDE project files in java/jdeps.go.
Brandon Lee5d45c6f2018-08-15 15:35:38 -07002808type IdeInfo struct {
Cole Faust08c7f862024-08-27 15:03:59 -07002809 BaseModuleName string `json:"-"`
Brandon Lee5d45c6f2018-08-15 15:35:38 -07002810 Deps []string `json:"dependencies,omitempty"`
2811 Srcs []string `json:"srcs,omitempty"`
2812 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
2813 Jarjar_rules []string `json:"jarjar_rules,omitempty"`
2814 Jars []string `json:"jars,omitempty"`
2815 Classes []string `json:"class,omitempty"`
2816 Installed_paths []string `json:"installed,omitempty"`
patricktu18c82ff2019-05-10 15:48:50 +08002817 SrcJars []string `json:"srcjars,omitempty"`
bralee1fbf4402020-05-21 10:11:59 +08002818 Paths []string `json:"path,omitempty"`
Yikef6282022022-04-13 20:41:01 +08002819 Static_libs []string `json:"static_libs,omitempty"`
2820 Libs []string `json:"libs,omitempty"`
Brandon Lee5d45c6f2018-08-15 15:35:38 -07002821}
Paul Duffinf88d8e02020-05-07 20:21:34 +01002822
Cole Faust08c7f862024-08-27 15:03:59 -07002823// Merge merges two IdeInfos and produces a new one, leaving the origional unchanged
2824func (i IdeInfo) Merge(other IdeInfo) IdeInfo {
2825 return IdeInfo{
2826 Deps: mergeStringLists(i.Deps, other.Deps),
2827 Srcs: mergeStringLists(i.Srcs, other.Srcs),
2828 Aidl_include_dirs: mergeStringLists(i.Aidl_include_dirs, other.Aidl_include_dirs),
2829 Jarjar_rules: mergeStringLists(i.Jarjar_rules, other.Jarjar_rules),
2830 Jars: mergeStringLists(i.Jars, other.Jars),
2831 Classes: mergeStringLists(i.Classes, other.Classes),
2832 Installed_paths: mergeStringLists(i.Installed_paths, other.Installed_paths),
2833 SrcJars: mergeStringLists(i.SrcJars, other.SrcJars),
2834 Paths: mergeStringLists(i.Paths, other.Paths),
2835 Static_libs: mergeStringLists(i.Static_libs, other.Static_libs),
2836 Libs: mergeStringLists(i.Libs, other.Libs),
2837 }
2838}
2839
2840// mergeStringLists appends the two string lists together and returns a new string list,
2841// leaving the originals unchanged. Duplicate strings will be deduplicated.
2842func mergeStringLists(a, b []string) []string {
2843 return FirstUniqueStrings(Concat(a, b))
2844}
2845
2846var IdeInfoProviderKey = blueprint.NewProvider[IdeInfo]()
2847
Paul Duffinf88d8e02020-05-07 20:21:34 +01002848func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error {
2849 bpctx := ctx.blueprintBaseModuleContext()
2850 return blueprint.CheckBlueprintSyntax(bpctx.ModuleFactories(), filename, contents)
2851}