blob: 35513d69dc575949759f7c5aa4e0624a226e59a0 [file] [log] [blame]
Colin Cross3f40fa42015-01-30 17:27:36 -08001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Colin Cross3f40fa42015-01-30 17:27:36 -080016
17import (
Colin Cross6ff51382015-12-17 16:39:19 -080018 "fmt"
Bob Badour4101c712022-02-09 11:54:35 -080019 "net/url"
Colin Cross3f40fa42015-01-30 17:27:36 -080020 "path/filepath"
Liz Kammer9525e712022-01-05 13:46:24 -050021 "reflect"
Colin Crossd6fd0132023-11-06 13:54:06 -080022 "slices"
Bob Badour4101c712022-02-09 11:54:35 -080023 "sort"
Colin Cross6ff51382015-12-17 16:39:19 -080024 "strings"
Tahsin Loqman77dc7d02022-12-19 16:27:25 +000025
Colin Crossf6566ed2015-03-24 11:13:38 -070026 "github.com/google/blueprint"
Colin Crossfe4bc362018-09-12 10:02:13 -070027 "github.com/google/blueprint/proptools"
Colin Cross3f40fa42015-01-30 17:27:36 -080028)
29
30var (
31 DeviceSharedLibrary = "shared_library"
32 DeviceStaticLibrary = "static_library"
Joe Onorato349ae8d2024-02-05 22:46:00 +000033 jarJarPrefixHandler func(ctx ModuleContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080034)
35
Colin Cross635c3b02016-05-18 15:37:25 -070036type Module interface {
Colin Cross3f40fa42015-01-30 17:27:36 -080037 blueprint.Module
38
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070039 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions,
40 // but GenerateAndroidBuildActions also has access to Android-specific information.
41 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
Colin Cross635c3b02016-05-18 15:37:25 -070042 GenerateAndroidBuildActions(ModuleContext)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070043
Paul Duffin44f1d842020-06-26 20:17:02 +010044 // Add dependencies to the components of a module, i.e. modules that are created
45 // by the module and which are considered to be part of the creating module.
46 //
47 // This is called before prebuilts are renamed so as to allow a dependency to be
48 // added directly to a prebuilt child module instead of depending on a source module
49 // and relying on prebuilt processing to switch to the prebuilt module if preferred.
50 //
51 // A dependency on a prebuilt must include the "prebuilt_" prefix.
52 ComponentDepsMutator(ctx BottomUpMutatorContext)
53
Colin Cross1e676be2016-10-12 14:38:15 -070054 DepsMutator(BottomUpMutatorContext)
Colin Cross3f40fa42015-01-30 17:27:36 -080055
Colin Cross635c3b02016-05-18 15:37:25 -070056 base() *ModuleBase
Inseob Kimeec88e12020-01-22 11:11:29 +090057 Disable()
Cole Fausta963b942024-04-11 17:43:00 -070058 Enabled(ctx ConfigAndErrorContext) bool
Colin Crossa1ad8d12016-06-01 17:09:44 -070059 Target() Target
Paul Duffinc04fb9e2021-03-01 12:25:10 +000060 MultiTargets() []Target
Paul Duffinb42fa672021-09-09 16:37:49 +010061
62 // ImageVariation returns the image variation of this module.
63 //
64 // The returned structure has its Mutator field set to "image" and its Variation field set to the
65 // image variation, e.g. recovery, ramdisk, etc.. The Variation field is "" for host modules and
66 // device modules that have no image variation.
67 ImageVariation() blueprint.Variation
68
Anton Hansson1ee62c02020-06-30 11:51:53 +010069 Owner() string
Dan Willemsen782a2d12015-12-21 14:55:28 -080070 InstallInData() bool
Jaewoong Jung0949f312019-09-11 10:25:18 -070071 InstallInTestcases() bool
Vishwath Mohan1dd88392017-03-29 22:00:18 -070072 InstallInSanitizerDir() bool
Yifan Hong1b3348d2020-01-21 15:53:22 -080073 InstallInRamdisk() bool
Yifan Hong60e0cfb2020-10-21 15:17:56 -070074 InstallInVendorRamdisk() bool
Inseob Kim08758f02021-04-08 21:13:22 +090075 InstallInDebugRamdisk() bool
Jiyong Parkf9332f12018-02-01 00:54:12 +090076 InstallInRecovery() bool
Colin Cross90ba5f42019-10-02 11:10:58 -070077 InstallInRoot() bool
Colin Crossea30d852023-11-29 16:00:16 -080078 InstallInOdm() bool
79 InstallInProduct() bool
Kiyoung Kimae11c232021-07-19 11:38:04 +090080 InstallInVendor() bool
Jiyong Park87788b52020-09-01 12:37:45 +090081 InstallForceOS() (*OsType, *ArchType)
Jiyong Parkce243632023-02-17 18:22:25 +090082 PartitionTag(DeviceConfig) string
Colin Crossa9c8c9f2020-12-16 10:20:23 -080083 HideFromMake()
84 IsHideFromMake() bool
Martin Stjernholm9e7f45e2020-12-23 03:50:30 +000085 IsSkipInstall() bool
Iván Budnik295da162023-03-10 16:11:26 +000086 MakeUninstallable()
Liz Kammer5ca3a622020-08-05 15:40:41 -070087 ReplacedByPrebuilt()
88 IsReplacedByPrebuilt() bool
Jiyong Park374510b2018-03-19 18:23:01 +090089 ExportedToMake() bool
Justin Yun1871f902023-04-07 20:13:19 +090090 EffectiveLicenseKinds() []string
Justin Yun885a7de2021-06-29 20:34:53 +090091 EffectiveLicenseFiles() Paths
Colin Cross36242852017-06-23 15:06:31 -070092
93 AddProperties(props ...interface{})
94 GetProperties() []interface{}
Colin Crosscec81712017-07-13 14:43:27 -070095
Colin Crossae887032017-10-23 17:16:14 -070096 BuildParamsForTests() []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -080097 RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -080098 VariablesForTests() map[string]string
Paul Duffine2453c72019-05-31 14:00:04 +010099
Colin Cross9a362232019-07-01 15:32:45 -0700100 // String returns a string that includes the module name and variants for printing during debugging.
101 String() string
102
Paul Duffine2453c72019-05-31 14:00:04 +0100103 // Get the qualified module id for this module.
104 qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName
105
106 // Get information about the properties that can contain visibility rules.
107 visibilityProperties() []visibilityProperty
Paul Duffin63c6e182019-07-24 14:24:38 +0100108
Cole Faust43ddd082024-06-17 12:32:40 -0700109 RequiredModuleNames(ctx ConfigAndErrorContext) []string
Jiyong Park6a8cf5f2019-12-30 16:31:09 +0900110 HostRequiredModuleNames() []string
111 TargetRequiredModuleNames() []string
Kiyoung Kimfaf6af32024-08-12 11:15:19 +0900112 VintfFragmentModuleNames(ctx ConfigAndErrorContext) []string
Colin Cross897266e2020-02-13 13:22:08 -0800113
Colin Crossffe6b9d2020-12-01 15:40:06 -0800114 // TransitivePackagingSpecs returns the PackagingSpecs for this module and any transitive
115 // dependencies with dependency tags for which IsInstallDepNeeded() returns true.
116 TransitivePackagingSpecs() []PackagingSpec
Cole Faust02987bd2024-03-21 17:58:43 -0700117
118 ConfigurableEvaluator(ctx ConfigAndErrorContext) 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
Colin Cross0bab8772020-09-25 14:01:21 -0700385 Init_rc []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
447 // If set to true then this variant is the CommonOS variant that has dependencies on its
448 // OsType specific variants.
449 //
450 // Set by osMutator.
451 CommonOSVariant bool `blueprint:"mutated"`
452
Jiyong Park3f627e62024-05-01 16:14:38 +0900453 // When set to true, this module is not installed to the full install path (ex: under
454 // out/target/product/<name>/<partition>). It can be installed only to the packaging
455 // modules like android_filesystem.
456 No_full_install *bool
457
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800458 // When HideFromMake is set to true, no entry for this variant will be emitted in the
459 // generated Android.mk file.
460 HideFromMake bool `blueprint:"mutated"`
461
462 // When SkipInstall is set to true, calls to ctx.InstallFile, ctx.InstallExecutable,
463 // ctx.InstallSymlink and ctx.InstallAbsoluteSymlink act like calls to ctx.PackageFile
464 // and don't create a rule to install the file.
Colin Crossce75d2c2016-10-06 16:12:58 -0700465 SkipInstall bool `blueprint:"mutated"`
Jeff Gaston088e29e2017-11-29 16:47:17 -0800466
Colin Crossbd3a16b2023-04-25 11:30:51 -0700467 // UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex
468 // mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant
469 // is used to avoid adding install or packaging dependencies into libraries provided
470 // by apexes.
471 UninstallableApexPlatformVariant bool `blueprint:"mutated"`
472
Liz Kammer5ca3a622020-08-05 15:40:41 -0700473 // Whether the module has been replaced by a prebuilt
474 ReplacedByPrebuilt bool `blueprint:"mutated"`
475
Justin Yun32f053b2020-07-31 23:07:17 +0900476 // Disabled by mutators. If set to true, it overrides Enabled property.
477 ForcedDisabled bool `blueprint:"mutated"`
478
Jeff Gaston088e29e2017-11-29 16:47:17 -0800479 NamespaceExportedToMake bool `blueprint:"mutated"`
Colin Cross6c4f21f2019-06-06 15:41:36 -0700480
Liz Kammerc13f7852023-05-17 13:01:48 -0400481 MissingDeps []string `blueprint:"mutated"`
482 CheckedMissingDeps bool `blueprint:"mutated"`
Colin Cross9a362232019-07-01 15:32:45 -0700483
484 // Name and variant strings stored by mutators to enable Module.String()
485 DebugName string `blueprint:"mutated"`
486 DebugMutators []string `blueprint:"mutated"`
487 DebugVariations []string `blueprint:"mutated"`
Colin Cross7228ecd2019-11-18 16:00:16 -0800488
Colin Crossa6845402020-11-16 15:08:19 -0800489 // ImageVariation is set by ImageMutator to specify which image this variation is for,
490 // for example "" for core or "recovery" for recovery. It will often be set to one of the
491 // constants in image.go, but can also be set to a custom value by individual module types.
Colin Cross7228ecd2019-11-18 16:00:16 -0800492 ImageVariation string `blueprint:"mutated"`
Liz Kammer2ada09a2021-08-11 00:17:36 -0400493
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800494 // The team (defined by the owner/vendor) who owns the property.
495 Team *string `android:"path"`
Kiyoung Kimfaf6af32024-08-12 11:15:19 +0900496
497 // vintf_fragment Modules required from this module.
498 Vintf_fragment_modules proptools.Configurable[[]string] `android:"path"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800499}
500
Paul Duffined875132020-09-02 13:08:57 +0100501type distProperties struct {
502 // configuration to distribute output files from this module to the distribution
503 // directory (default: $OUT/dist, configurable with $DIST_DIR)
504 Dist Dist `android:"arch_variant"`
505
506 // a list of configurations to distribute output files from this module to the
507 // distribution directory (default: $OUT/dist, configurable with $DIST_DIR)
508 Dists []Dist `android:"arch_variant"`
509}
510
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800511type TeamDepTagType struct {
512 blueprint.BaseDependencyTag
513}
514
515var teamDepTag = TeamDepTagType{}
516
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900517// Dependency tag for required, host_required, and target_required modules.
518var RequiredDepTag = struct {
519 blueprint.BaseDependencyTag
520 InstallAlwaysNeededDependencyTag
521 // Requiring disabled module has been supported (as a side effect of this being implemented
522 // in Make). We may want to make it an error, but for now, let's keep the existing behavior.
523 AlwaysAllowDisabledModuleDependencyTag
524}{}
525
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800526// CommonTestOptions represents the common `test_options` properties in
527// Android.bp.
528type CommonTestOptions struct {
529 // If the test is a hostside (no device required) unittest that shall be run
530 // during presubmit check.
531 Unit_test *bool
Zhenhuang Wang409d2772022-08-22 16:00:05 +0800532
533 // Tags provide additional metadata to customize test execution by downstream
534 // test runners. The tags have no special meaning to Soong.
535 Tags []string
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800536}
537
538// SetAndroidMkEntries sets AndroidMkEntries according to the value of base
539// `test_options`.
540func (t *CommonTestOptions) SetAndroidMkEntries(entries *AndroidMkEntries) {
541 entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test))
Zhenhuang Wang409d2772022-08-22 16:00:05 +0800542 if len(t.Tags) > 0 {
543 entries.AddStrings("LOCAL_TEST_OPTIONS_TAGS", t.Tags...)
544 }
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800545}
546
Paul Duffin74f05592020-11-25 16:37:46 +0000547// The key to use in TaggedDistFiles when a Dist structure does not specify a
548// tag property. This intentionally does not use "" as the default because that
549// would mean that an empty tag would have a different meaning when used in a dist
550// structure that when used to reference a specific set of output paths using the
551// :module{tag} syntax, which passes tag to the OutputFiles(tag) method.
552const DefaultDistTag = "<default-dist-tag>"
553
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000554// A map of OutputFile tag keys to Paths, for disting purposes.
555type TaggedDistFiles map[string]Paths
556
Paul Duffin74f05592020-11-25 16:37:46 +0000557// addPathsForTag adds a mapping from the tag to the paths. If the map is nil
558// then it will create a map, update it and then return it. If a mapping already
559// exists for the tag then the paths are appended to the end of the current list
560// of paths, ignoring any duplicates.
561func (t TaggedDistFiles) addPathsForTag(tag string, paths ...Path) TaggedDistFiles {
562 if t == nil {
563 t = make(TaggedDistFiles)
564 }
565
566 for _, distFile := range paths {
567 if distFile != nil && !t[tag].containsPath(distFile) {
568 t[tag] = append(t[tag], distFile)
569 }
570 }
571
572 return t
573}
574
575// merge merges the entries from the other TaggedDistFiles object into this one.
576// If the TaggedDistFiles is nil then it will create a new instance, merge the
577// other into it, and then return it.
578func (t TaggedDistFiles) merge(other TaggedDistFiles) TaggedDistFiles {
579 for tag, paths := range other {
580 t = t.addPathsForTag(tag, paths...)
581 }
582
583 return t
584}
585
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000586func MakeDefaultDistFiles(paths ...Path) TaggedDistFiles {
Sasha Smundake198eaf2022-08-04 13:07:02 -0700587 for _, p := range paths {
588 if p == nil {
Jingwen Chen7b27ca72020-07-24 09:13:49 +0000589 panic("The path to a dist file cannot be nil.")
590 }
591 }
592
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000593 // The default OutputFile tag is the empty "" string.
Paul Duffin74f05592020-11-25 16:37:46 +0000594 return TaggedDistFiles{DefaultDistTag: paths}
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000595}
596
Colin Cross3f40fa42015-01-30 17:27:36 -0800597type hostAndDeviceProperties struct {
Colin Cross4e81d702018-11-09 10:36:55 -0800598 // If set to true, build a variant of the module for the host. Defaults to false.
599 Host_supported *bool
600
601 // If set to true, build a variant of the module for the device. Defaults to true.
Colin Crossa4190c12016-07-12 13:11:25 -0700602 Device_supported *bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800603}
604
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000605type hostCrossProperties struct {
606 // If set to true, build a variant of the module for the host cross. Defaults to true.
607 Host_cross_supported *bool
608}
609
Colin Crossc472d572015-03-17 15:06:21 -0700610type Multilib string
611
612const (
Colin Cross6b4a32d2017-12-05 13:42:45 -0800613 MultilibBoth Multilib = "both"
614 MultilibFirst Multilib = "first"
615 MultilibCommon Multilib = "common"
616 MultilibCommonFirst Multilib = "common_first"
Colin Crossc472d572015-03-17 15:06:21 -0700617)
618
Colin Crossa1ad8d12016-06-01 17:09:44 -0700619type HostOrDeviceSupported int
620
621const (
Colin Cross34037c62020-11-17 13:19:17 -0800622 hostSupported = 1 << iota
623 hostCrossSupported
624 deviceSupported
625 hostDefault
626 deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700627
628 // Host and HostCross are built by default. Device is not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800629 HostSupported = hostSupported | hostCrossSupported | hostDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700630
631 // Host is built by default. HostCross and Device are not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800632 HostSupportedNoCross = hostSupported | hostDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700633
634 // Device is built by default. Host and HostCross are not supported.
Colin Cross34037c62020-11-17 13:19:17 -0800635 DeviceSupported = deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700636
Liz Kammer8631cc72021-08-23 21:12:07 +0000637 // By default, _only_ device variant is built. Device variant can be disabled with `device_supported: false`
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -0700638 // Host and HostCross are disabled by default and can be enabled with `host_supported: true`
Colin Cross34037c62020-11-17 13:19:17 -0800639 HostAndDeviceSupported = hostSupported | hostCrossSupported | deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700640
641 // Host, HostCross, and Device are built by default.
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -0700642 // Building Device can be disabled with `device_supported: false`
643 // Building Host and HostCross can be disabled with `host_supported: false`
Colin Cross34037c62020-11-17 13:19:17 -0800644 HostAndDeviceDefault = hostSupported | hostCrossSupported | hostDefault |
645 deviceSupported | deviceDefault
Dan Albert0981b5c2018-08-02 13:46:35 -0700646
647 // Nothing is supported. This is not exposed to the user, but used to mark a
648 // host only module as unsupported when the module type is not supported on
649 // the host OS. E.g. benchmarks are supported on Linux but not Darwin.
Colin Cross34037c62020-11-17 13:19:17 -0800650 NeitherHostNorDeviceSupported = 0
Colin Crossa1ad8d12016-06-01 17:09:44 -0700651)
652
Jiyong Park2db76922017-11-08 16:03:48 +0900653type moduleKind int
654
655const (
656 platformModule moduleKind = iota
657 deviceSpecificModule
658 socSpecificModule
659 productSpecificModule
Justin Yund5f6c822019-06-25 16:47:17 +0900660 systemExtSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +0900661)
662
663func (k moduleKind) String() string {
664 switch k {
665 case platformModule:
666 return "platform"
667 case deviceSpecificModule:
668 return "device-specific"
669 case socSpecificModule:
670 return "soc-specific"
671 case productSpecificModule:
672 return "product-specific"
Justin Yund5f6c822019-06-25 16:47:17 +0900673 case systemExtSpecificModule:
674 return "systemext-specific"
Jiyong Park2db76922017-11-08 16:03:48 +0900675 default:
676 panic(fmt.Errorf("unknown module kind %d", k))
677 }
678}
679
Colin Cross9d34f352019-11-22 16:03:51 -0800680func initAndroidModuleBase(m Module) {
681 m.base().module = m
682}
683
Colin Crossa6845402020-11-16 15:08:19 -0800684// InitAndroidModule initializes the Module as an Android module that is not architecture-specific.
685// It adds the common properties, for example "name" and "enabled".
Colin Cross36242852017-06-23 15:06:31 -0700686func InitAndroidModule(m Module) {
Colin Cross9d34f352019-11-22 16:03:51 -0800687 initAndroidModuleBase(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800688 base := m.base()
Colin Cross5049f022015-03-18 13:28:46 -0700689
Colin Cross36242852017-06-23 15:06:31 -0700690 m.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700691 &base.nameProperties,
Paul Duffined875132020-09-02 13:08:57 +0100692 &base.commonProperties,
693 &base.distProperties)
Colin Cross18c46802019-09-24 22:19:02 -0700694
Colin Crosseabaedd2020-02-06 17:01:55 -0800695 initProductVariableModule(m)
Colin Cross18c46802019-09-24 22:19:02 -0700696
Paul Duffin63c6e182019-07-24 14:24:38 +0100697 // The default_visibility property needs to be checked and parsed by the visibility module during
Paul Duffin5ec73ec2020-05-01 17:52:01 +0100698 // its checking and parsing phases so make it the primary visibility property.
699 setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility)
Bob Badour37af0462021-01-07 03:34:31 +0000700
701 // The default_applicable_licenses property needs to be checked and parsed by the licenses module during
702 // its checking and parsing phases so make it the primary licenses property.
703 setPrimaryLicensesProperty(m, "licenses", &base.commonProperties.Licenses)
Colin Cross5049f022015-03-18 13:28:46 -0700704}
705
Colin Crossa6845402020-11-16 15:08:19 -0800706// InitAndroidArchModule initializes the Module as an Android module that is architecture-specific.
707// It adds the common properties, for example "name" and "enabled", as well as runtime generated
708// property structs for architecture-specific versions of generic properties tagged with
709// `android:"arch_variant"`.
710//
Colin Crossd079e0b2022-08-16 10:27:33 -0700711// InitAndroidModule should not be called if InitAndroidArchModule was called.
Colin Cross36242852017-06-23 15:06:31 -0700712func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
713 InitAndroidModule(m)
Colin Cross5049f022015-03-18 13:28:46 -0700714
715 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800716 base.commonProperties.HostOrDeviceSupported = hod
Colin Cross69617d32016-09-06 10:39:07 -0700717 base.commonProperties.Default_multilib = string(defaultMultilib)
Dan Willemsen0b24c742016-10-04 15:13:37 -0700718 base.commonProperties.ArchSpecific = true
Colin Crossee0bc3b2018-10-02 22:01:37 -0700719 base.commonProperties.UseTargetVariants = true
Colin Cross3f40fa42015-01-30 17:27:36 -0800720
Colin Cross34037c62020-11-17 13:19:17 -0800721 if hod&hostSupported != 0 && hod&deviceSupported != 0 {
Colin Cross36242852017-06-23 15:06:31 -0700722 m.AddProperties(&base.hostAndDeviceProperties)
Colin Cross3f40fa42015-01-30 17:27:36 -0800723 }
724
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000725 if hod&hostCrossSupported != 0 {
726 m.AddProperties(&base.hostCrossProperties)
727 }
728
Colin Crossa6845402020-11-16 15:08:19 -0800729 initArchModule(m)
Colin Cross3f40fa42015-01-30 17:27:36 -0800730}
731
Colin Crossa6845402020-11-16 15:08:19 -0800732// InitAndroidMultiTargetsArchModule initializes the Module as an Android module that is
733// architecture-specific, but will only have a single variant per OS that handles all the
734// architectures simultaneously. The list of Targets that it must handle will be available from
735// ModuleContext.MultiTargets. It adds the common properties, for example "name" and "enabled", as
736// well as runtime generated property structs for architecture-specific versions of generic
737// properties tagged with `android:"arch_variant"`.
738//
739// InitAndroidModule or InitAndroidArchModule should not be called if
740// InitAndroidMultiTargetsArchModule was called.
Colin Crossee0bc3b2018-10-02 22:01:37 -0700741func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
742 InitAndroidArchModule(m, hod, defaultMultilib)
743 m.base().commonProperties.UseTargetVariants = false
744}
745
Colin Crossa6845402020-11-16 15:08:19 -0800746// InitCommonOSAndroidMultiTargetsArchModule initializes the Module as an Android module that is
747// architecture-specific, but will only have a single variant per OS that handles all the
748// architectures simultaneously, and will also have an additional CommonOS variant that has
749// dependencies on all the OS-specific variants. The list of Targets that it must handle will be
750// available from ModuleContext.MultiTargets. It adds the common properties, for example "name" and
751// "enabled", as well as runtime generated property structs for architecture-specific versions of
752// generic properties tagged with `android:"arch_variant"`.
753//
754// InitAndroidModule, InitAndroidArchModule or InitAndroidMultiTargetsArchModule should not be
755// called if InitCommonOSAndroidMultiTargetsArchModule was called.
Paul Duffin1356d8c2020-02-25 19:26:33 +0000756func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
757 InitAndroidArchModule(m, hod, defaultMultilib)
758 m.base().commonProperties.UseTargetVariants = false
759 m.base().commonProperties.CreateCommonOSVariant = true
760}
761
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800762// A ModuleBase object contains the properties that are common to all Android
Colin Cross3f40fa42015-01-30 17:27:36 -0800763// modules. It should be included as an anonymous field in every module
764// struct definition. InitAndroidModule should then be called from the module's
765// factory function, and the return values from InitAndroidModule should be
766// returned from the factory function.
767//
Nan Zhangb9eeb1d2017-02-02 10:46:07 -0800768// The ModuleBase type is responsible for implementing the GenerateBuildActions
769// method to support the blueprint.Module interface. This method will then call
770// the module's GenerateAndroidBuildActions method once for each build variant
Colin Cross25de6c32019-06-06 14:29:25 -0700771// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext
772// rather than the usual blueprint.ModuleContext.
773// ModuleContext exposes extra functionality specific to the Android build
Colin Cross3f40fa42015-01-30 17:27:36 -0800774// system including details about the particular build variant that is to be
775// generated.
776//
777// For example:
778//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800779// import (
780// "android/soong/android"
781// )
Colin Cross3f40fa42015-01-30 17:27:36 -0800782//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800783// type myModule struct {
784// android.ModuleBase
785// properties struct {
786// MyProperty string
787// }
788// }
Colin Cross3f40fa42015-01-30 17:27:36 -0800789//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800790// func NewMyModule() android.Module {
791// m := &myModule{}
792// m.AddProperties(&m.properties)
793// android.InitAndroidModule(m)
794// return m
795// }
Colin Cross3f40fa42015-01-30 17:27:36 -0800796//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800797// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
798// // Get the CPU architecture for the current build variant.
799// variantArch := ctx.Arch()
Colin Cross3f40fa42015-01-30 17:27:36 -0800800//
Zhenhuang Wang0ac5a432022-08-12 18:49:20 +0800801// // ...
802// }
Colin Cross635c3b02016-05-18 15:37:25 -0700803type ModuleBase struct {
Colin Cross3f40fa42015-01-30 17:27:36 -0800804 // Putting the curiously recurring thing pointing to the thing that contains
805 // the thing pattern to good use.
Colin Cross36242852017-06-23 15:06:31 -0700806 // TODO: remove this
Colin Cross635c3b02016-05-18 15:37:25 -0700807 module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800808
Colin Crossfc754582016-05-17 16:34:16 -0700809 nameProperties nameProperties
Colin Cross3f40fa42015-01-30 17:27:36 -0800810 commonProperties commonProperties
Paul Duffined875132020-09-02 13:08:57 +0100811 distProperties distProperties
Colin Cross18c46802019-09-24 22:19:02 -0700812 variableProperties interface{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800813 hostAndDeviceProperties hostAndDeviceProperties
Ivan Lozanoc7eafa72024-07-16 17:55:33 +0000814 hostCrossProperties hostCrossProperties
Jingwen Chen5d864492021-02-24 07:20:12 -0500815
Usta851a3272022-01-05 23:42:33 -0500816 // Arch specific versions of structs in GetProperties() prior to
817 // initialization in InitAndroidArchModule, lets call it `generalProperties`.
818 // The outer index has the same order as generalProperties and the inner index
819 // chooses the props specific to the architecture. The interface{} value is an
820 // archPropRoot that is filled with arch specific values by the arch mutator.
Jingwen Chen5d864492021-02-24 07:20:12 -0500821 archProperties [][]interface{}
822
Paul Duffin63c6e182019-07-24 14:24:38 +0100823 // Information about all the properties on the module that contains visibility rules that need
824 // checking.
825 visibilityPropertyInfo []visibilityProperty
826
827 // The primary visibility property, may be nil, that controls access to the module.
828 primaryVisibilityProperty visibilityProperty
829
Bob Badour37af0462021-01-07 03:34:31 +0000830 // The primary licenses property, may be nil, records license metadata for the module.
831 primaryLicensesProperty applicableLicensesProperty
832
Colin Crossffe6b9d2020-12-01 15:40:06 -0800833 noAddressSanitizer bool
Colin Crossc85750b2022-04-21 12:50:51 -0700834 packagingSpecsDepSet *DepSet[PackagingSpec]
Colin Cross1f8c52b2015-06-16 16:38:17 -0700835
Colin Cross178a5092016-09-13 13:42:32 -0700836 hooks hooks
Colin Cross36242852017-06-23 15:06:31 -0700837
838 registerProps []interface{}
Colin Crosscec81712017-07-13 14:43:27 -0700839
840 // For tests
Colin Crossae887032017-10-23 17:16:14 -0700841 buildParams []BuildParams
Colin Cross4c83e5c2019-02-25 14:54:28 -0800842 ruleParams map[blueprint.Rule]blueprint.RuleParams
Jaewoong Jung38e4fb22018-12-12 09:01:34 -0800843 variables map[string]string
Colin Cross36242852017-06-23 15:06:31 -0700844}
845
Lukacs T. Berkid18d8ca2021-06-25 09:11:22 +0200846func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
Liz Kammer9525e712022-01-05 13:46:24 -0500847 (*d)["Android"] = map[string]interface{}{
848 // Properties set in Blueprint or in blueprint of a defaults modules
849 "SetProperties": m.propertiesWithValues(),
850 }
851}
852
853type propInfo struct {
Liz Kammer898e0762022-03-22 11:27:26 -0400854 Name string
855 Type string
856 Value string
857 Values []string
Liz Kammer9525e712022-01-05 13:46:24 -0500858}
859
860func (m *ModuleBase) propertiesWithValues() []propInfo {
861 var info []propInfo
862 props := m.GetProperties()
863
864 var propsWithValues func(name string, v reflect.Value)
865 propsWithValues = func(name string, v reflect.Value) {
866 kind := v.Kind()
867 switch kind {
868 case reflect.Ptr, reflect.Interface:
869 if v.IsNil() {
870 return
871 }
872 propsWithValues(name, v.Elem())
873 case reflect.Struct:
874 if v.IsZero() {
875 return
876 }
877 for i := 0; i < v.NumField(); i++ {
878 namePrefix := name
879 sTyp := v.Type().Field(i)
880 if proptools.ShouldSkipProperty(sTyp) {
881 continue
882 }
883 if name != "" && !strings.HasSuffix(namePrefix, ".") {
884 namePrefix += "."
885 }
886 if !proptools.IsEmbedded(sTyp) {
887 namePrefix += sTyp.Name
888 }
889 sVal := v.Field(i)
890 propsWithValues(namePrefix, sVal)
891 }
892 case reflect.Array, reflect.Slice:
893 if v.IsNil() {
894 return
895 }
896 elKind := v.Type().Elem().Kind()
Liz Kammer898e0762022-03-22 11:27:26 -0400897 info = append(info, propInfo{Name: name, Type: elKind.String() + " " + kind.String(), Values: sliceReflectionValue(v)})
Liz Kammer9525e712022-01-05 13:46:24 -0500898 default:
Liz Kammer898e0762022-03-22 11:27:26 -0400899 info = append(info, propInfo{Name: name, Type: kind.String(), Value: reflectionValue(v)})
Liz Kammer9525e712022-01-05 13:46:24 -0500900 }
901 }
902
903 for _, p := range props {
904 propsWithValues("", reflect.ValueOf(p).Elem())
905 }
Liz Kammer898e0762022-03-22 11:27:26 -0400906 sort.Slice(info, func(i, j int) bool {
907 return info[i].Name < info[j].Name
908 })
Liz Kammer9525e712022-01-05 13:46:24 -0500909 return info
Lukacs T. Berkid18d8ca2021-06-25 09:11:22 +0200910}
911
Liz Kammer898e0762022-03-22 11:27:26 -0400912func reflectionValue(value reflect.Value) string {
913 switch value.Kind() {
914 case reflect.Bool:
915 return fmt.Sprintf("%t", value.Bool())
916 case reflect.Int64:
917 return fmt.Sprintf("%d", value.Int())
918 case reflect.String:
919 return fmt.Sprintf("%s", value.String())
920 case reflect.Struct:
921 if value.IsZero() {
922 return "{}"
923 }
924 length := value.NumField()
925 vals := make([]string, length, length)
926 for i := 0; i < length; i++ {
927 sTyp := value.Type().Field(i)
928 if proptools.ShouldSkipProperty(sTyp) {
929 continue
930 }
931 name := sTyp.Name
932 vals[i] = fmt.Sprintf("%s: %s", name, reflectionValue(value.Field(i)))
933 }
934 return fmt.Sprintf("%s{%s}", value.Type(), strings.Join(vals, ", "))
935 case reflect.Array, reflect.Slice:
936 vals := sliceReflectionValue(value)
937 return fmt.Sprintf("[%s]", strings.Join(vals, ", "))
938 }
939 return ""
940}
941
942func sliceReflectionValue(value reflect.Value) []string {
943 length := value.Len()
944 vals := make([]string, length, length)
945 for i := 0; i < length; i++ {
946 vals[i] = reflectionValue(value.Index(i))
947 }
948 return vals
949}
950
Paul Duffin44f1d842020-06-26 20:17:02 +0100951func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {}
952
Colin Cross4157e882019-06-06 16:57:04 -0700953func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
Colin Cross5f692ec2019-02-01 16:53:07 -0800954
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800955func (m *ModuleBase) baseDepsMutator(ctx BottomUpMutatorContext) {
956 if m.Team() != "" {
957 ctx.AddDependency(ctx.Module(), teamDepTag, m.Team())
958 }
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900959
960 // TODO(jiyong): remove below case. This is to work around build errors happening
961 // on branches with reduced manifest like aosp_kernel-build-tools.
962 // In the branch, a build error occurs as follows.
963 // 1. aosp_kernel-build-tools is a reduced manifest branch. It doesn't have some git
964 // projects like external/bouncycastle
965 // 2. `boot_signer` is `required` by modules like `build_image` which is explicitly list as
966 // the top-level build goal (in the shell file that invokes Soong).
967 // 3. `boot_signer` depends on `bouncycastle-unbundled` which is in the missing git project.
968 // 4. aosp_kernel-build-tools invokes soong with `--skip-make`. Therefore, the absence of
969 // ALLOW_MISSING_DEPENDENCIES didn't cause a problem.
970 // 5. Now, since Soong understands `required` deps, it tries to build `boot_signer` and the
971 // absence of external/bouncycastle fails the build.
972 //
973 // Unfortunately, there's no way for Soong to correctly determine if it's running in a
974 // reduced manifest branch. Instead, here, we use the absence of DeviceArch or DeviceName as
975 // a strong signal, because that's very common across reduced manifest branches.
976 pv := ctx.Config().productVariables
977 fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil
978 if fullManifest {
Jiyong Parkf21dd652024-04-17 05:22:37 +0000979 addRequiredDeps(ctx)
Kiyoung Kimfaf6af32024-08-12 11:15:19 +0900980 addVintfFragmentDeps(ctx)
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900981 }
982}
983
984// addRequiredDeps adds required, target_required, and host_required as dependencies.
Jiyong Parkf21dd652024-04-17 05:22:37 +0000985func addRequiredDeps(ctx BottomUpMutatorContext) {
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900986 addDep := func(target Target, depName string) {
987 if !ctx.OtherModuleExists(depName) {
988 if ctx.Config().AllowMissingDependencies() {
989 return
990 }
991 }
992
993 // If Android native module requires another Android native module, ensure that
994 // they have the same bitness. This mimics the policy in select-bitness-of-required-modules
995 // in build/make/core/main.mk.
996 // TODO(jiyong): the Make-side does this only when the required module is a shared
997 // library or a native test.
Jiyong Parkf21dd652024-04-17 05:22:37 +0000998 bothInAndroid := ctx.Device() && target.Os.Class == Device
Jiyong Parkc4b1d552024-05-13 16:47:30 +0900999 nativeArch := InList(ctx.Arch().ArchType.Multilib, []string{"lib32", "lib64"}) &&
1000 InList(target.Arch.ArchType.Multilib, []string{"lib32", "lib64"})
Jiyong Parkf21dd652024-04-17 05:22:37 +00001001 sameBitness := ctx.Arch().ArchType.Multilib == target.Arch.ArchType.Multilib
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001002 if bothInAndroid && nativeArch && !sameBitness {
1003 return
1004 }
1005
Jiyong Park8db44152024-05-28 12:22:04 +09001006 // ... also don't make a dependency between native bridge arch and non-native bridge
1007 // arches. b/342945184
1008 if ctx.Target().NativeBridge != target.NativeBridge {
1009 return
1010 }
1011
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001012 variation := target.Variations()
1013 if ctx.OtherModuleFarDependencyVariantExists(variation, depName) {
1014 ctx.AddFarVariationDependencies(variation, RequiredDepTag, depName)
1015 }
1016 }
1017
Jiyong Park73e5bab2024-04-05 13:37:21 +09001018 var deviceTargets []Target
1019 deviceTargets = append(deviceTargets, ctx.Config().Targets[Android]...)
1020 deviceTargets = append(deviceTargets, ctx.Config().AndroidCommonTarget)
1021
1022 var hostTargets []Target
1023 hostTargets = append(hostTargets, ctx.Config().Targets[ctx.Config().BuildOS]...)
1024 hostTargets = append(hostTargets, ctx.Config().BuildOSCommonTarget)
1025
Jiyong Parkf21dd652024-04-17 05:22:37 +00001026 if ctx.Device() {
Cole Faust43ddd082024-06-17 12:32:40 -07001027 for _, depName := range ctx.Module().RequiredModuleNames(ctx) {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001028 for _, target := range deviceTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001029 addDep(target, depName)
1030 }
1031 }
Jiyong Parkf21dd652024-04-17 05:22:37 +00001032 for _, depName := range ctx.Module().HostRequiredModuleNames() {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001033 for _, target := range hostTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001034 addDep(target, depName)
1035 }
1036 }
1037 }
1038
Jiyong Parkf21dd652024-04-17 05:22:37 +00001039 if ctx.Host() {
Cole Faust43ddd082024-06-17 12:32:40 -07001040 for _, depName := range ctx.Module().RequiredModuleNames(ctx) {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001041 for _, target := range hostTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001042 // When a host module requires another host module, don't make a
1043 // dependency if they have different OSes (i.e. hostcross).
Jiyong Parkf21dd652024-04-17 05:22:37 +00001044 if ctx.Target().HostCross != target.HostCross {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001045 continue
1046 }
1047 addDep(target, depName)
1048 }
1049 }
Jiyong Parkf21dd652024-04-17 05:22:37 +00001050 for _, depName := range ctx.Module().TargetRequiredModuleNames() {
Jiyong Park73e5bab2024-04-05 13:37:21 +09001051 for _, target := range deviceTargets {
Jiyong Park8bcf3c62024-03-18 18:37:10 +09001052 addDep(target, depName)
1053 }
1054 }
1055 }
Ronald Braunstein73b08ff2023-12-19 10:24:47 -08001056}
1057
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001058var vintfDepTag = struct {
1059 blueprint.BaseDependencyTag
1060 InstallAlwaysNeededDependencyTag
1061}{}
1062
1063func addVintfFragmentDeps(ctx BottomUpMutatorContext) {
1064 mod := ctx.Module()
1065 ctx.AddDependency(mod, vintfDepTag, mod.VintfFragmentModuleNames(ctx)...)
1066}
1067
Usta355a5872021-12-01 15:16:32 -05001068// AddProperties "registers" the provided props
1069// each value in props MUST be a pointer to a struct
Colin Cross4157e882019-06-06 16:57:04 -07001070func (m *ModuleBase) AddProperties(props ...interface{}) {
1071 m.registerProps = append(m.registerProps, props...)
Colin Cross36242852017-06-23 15:06:31 -07001072}
1073
Colin Cross4157e882019-06-06 16:57:04 -07001074func (m *ModuleBase) GetProperties() []interface{} {
1075 return m.registerProps
Colin Cross3f40fa42015-01-30 17:27:36 -08001076}
1077
Colin Cross4157e882019-06-06 16:57:04 -07001078func (m *ModuleBase) BuildParamsForTests() []BuildParams {
Chih-Hung Hsiehb8082292021-09-09 23:20:39 -07001079 // Expand the references to module variables like $flags[0-9]*,
1080 // so we do not need to change many existing unit tests.
1081 // This looks like undoing the shareFlags optimization in cc's
1082 // transformSourceToObj, and should only affects unit tests.
1083 vars := m.VariablesForTests()
1084 buildParams := append([]BuildParams(nil), m.buildParams...)
Sasha Smundake198eaf2022-08-04 13:07:02 -07001085 for i := range buildParams {
Chih-Hung Hsiehb8082292021-09-09 23:20:39 -07001086 newArgs := make(map[string]string)
1087 for k, v := range buildParams[i].Args {
1088 newArgs[k] = v
1089 // Replaces both ${flags1} and $flags1 syntax.
1090 if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") {
1091 if value, found := vars[v[2:len(v)-1]]; found {
1092 newArgs[k] = value
1093 }
1094 } else if strings.HasPrefix(v, "$") {
1095 if value, found := vars[v[1:]]; found {
1096 newArgs[k] = value
1097 }
1098 }
1099 }
1100 buildParams[i].Args = newArgs
1101 }
1102 return buildParams
Colin Crosscec81712017-07-13 14:43:27 -07001103}
1104
Colin Cross4157e882019-06-06 16:57:04 -07001105func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
1106 return m.ruleParams
Colin Cross4c83e5c2019-02-25 14:54:28 -08001107}
1108
Colin Cross4157e882019-06-06 16:57:04 -07001109func (m *ModuleBase) VariablesForTests() map[string]string {
1110 return m.variables
Jaewoong Jung38e4fb22018-12-12 09:01:34 -08001111}
1112
Colin Crossce75d2c2016-10-06 16:12:58 -07001113// Name returns the name of the module. It may be overridden by individual module types, for
1114// example prebuilts will prepend prebuilt_ to the name.
Colin Cross4157e882019-06-06 16:57:04 -07001115func (m *ModuleBase) Name() string {
1116 return String(m.nameProperties.Name)
Colin Crossfc754582016-05-17 16:34:16 -07001117}
1118
Colin Cross9a362232019-07-01 15:32:45 -07001119// String returns a string that includes the module name and variants for printing during debugging.
1120func (m *ModuleBase) String() string {
1121 sb := strings.Builder{}
1122 sb.WriteString(m.commonProperties.DebugName)
1123 sb.WriteString("{")
1124 for i := range m.commonProperties.DebugMutators {
1125 if i != 0 {
1126 sb.WriteString(",")
1127 }
1128 sb.WriteString(m.commonProperties.DebugMutators[i])
1129 sb.WriteString(":")
1130 sb.WriteString(m.commonProperties.DebugVariations[i])
1131 }
1132 sb.WriteString("}")
1133 return sb.String()
1134}
1135
Colin Crossce75d2c2016-10-06 16:12:58 -07001136// BaseModuleName returns the name of the module as specified in the blueprints file.
Colin Cross4157e882019-06-06 16:57:04 -07001137func (m *ModuleBase) BaseModuleName() string {
1138 return String(m.nameProperties.Name)
Colin Crossce75d2c2016-10-06 16:12:58 -07001139}
1140
Colin Cross4157e882019-06-06 16:57:04 -07001141func (m *ModuleBase) base() *ModuleBase {
1142 return m
Colin Cross3f40fa42015-01-30 17:27:36 -08001143}
1144
Paul Duffine2453c72019-05-31 14:00:04 +01001145func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName {
1146 return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()}
1147}
1148
1149func (m *ModuleBase) visibilityProperties() []visibilityProperty {
Paul Duffin63c6e182019-07-24 14:24:38 +01001150 return m.visibilityPropertyInfo
1151}
1152
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001153func (m *ModuleBase) Dists() []Dist {
Paul Duffined875132020-09-02 13:08:57 +01001154 if len(m.distProperties.Dist.Targets) > 0 {
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001155 // Make a copy of the underlying Dists slice to protect against
1156 // backing array modifications with repeated calls to this method.
Paul Duffined875132020-09-02 13:08:57 +01001157 distsCopy := append([]Dist(nil), m.distProperties.Dists...)
1158 return append(distsCopy, m.distProperties.Dist)
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001159 } else {
Paul Duffined875132020-09-02 13:08:57 +01001160 return m.distProperties.Dists
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001161 }
1162}
1163
1164func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFiles {
Paul Duffin74f05592020-11-25 16:37:46 +00001165 var distFiles TaggedDistFiles
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001166 for _, dist := range m.Dists() {
Paul Duffin74f05592020-11-25 16:37:46 +00001167 // If no tag is specified then it means to use the default dist paths so use
1168 // the special tag name which represents that.
1169 tag := proptools.StringDefault(dist.Tag, DefaultDistTag)
1170
mrziwangabdb2932024-06-18 12:43:41 -07001171 distFileForTagFromProvider, err := outputFilesForModuleFromProvider(ctx, m.module, tag)
1172 if err != OutputFilesProviderNotSet {
1173 if err != nil && tag != DefaultDistTag {
1174 ctx.PropertyErrorf("dist.tag", "%s", err.Error())
1175 } else {
1176 distFiles = distFiles.addPathsForTag(tag, distFileForTagFromProvider...)
1177 continue
1178 }
1179 }
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001180 }
Jingwen Chen40fd90a2020-06-15 05:24:19 +00001181 return distFiles
1182}
1183
Cole Faust02987bd2024-03-21 17:58:43 -07001184func (m *ModuleBase) ArchReady() bool {
1185 return m.commonProperties.ArchReady
1186}
1187
Colin Cross4157e882019-06-06 16:57:04 -07001188func (m *ModuleBase) Target() Target {
1189 return m.commonProperties.CompileTarget
Dan Willemsen490fd492015-11-24 17:53:15 -08001190}
1191
Colin Cross4157e882019-06-06 16:57:04 -07001192func (m *ModuleBase) TargetPrimary() bool {
1193 return m.commonProperties.CompilePrimary
Colin Cross8b74d172016-09-13 09:59:14 -07001194}
1195
Colin Cross4157e882019-06-06 16:57:04 -07001196func (m *ModuleBase) MultiTargets() []Target {
1197 return m.commonProperties.CompileMultiTargets
Colin Crossee0bc3b2018-10-02 22:01:37 -07001198}
1199
Colin Cross4157e882019-06-06 16:57:04 -07001200func (m *ModuleBase) Os() OsType {
1201 return m.Target().Os
Dan Willemsen490fd492015-11-24 17:53:15 -08001202}
1203
Colin Cross4157e882019-06-06 16:57:04 -07001204func (m *ModuleBase) Host() bool {
Jiyong Park1613e552020-09-14 19:43:17 +09001205 return m.Os().Class == Host
Dan Willemsen97750522016-02-09 17:43:51 -08001206}
1207
Yo Chiangbba545e2020-06-09 16:15:37 +08001208func (m *ModuleBase) Device() bool {
1209 return m.Os().Class == Device
1210}
1211
Colin Cross4157e882019-06-06 16:57:04 -07001212func (m *ModuleBase) Arch() Arch {
1213 return m.Target().Arch
Dan Willemsen97750522016-02-09 17:43:51 -08001214}
1215
Colin Cross4157e882019-06-06 16:57:04 -07001216func (m *ModuleBase) ArchSpecific() bool {
1217 return m.commonProperties.ArchSpecific
Dan Willemsen0b24c742016-10-04 15:13:37 -07001218}
1219
Paul Duffin1356d8c2020-02-25 19:26:33 +00001220// True if the current variant is a CommonOS variant, false otherwise.
1221func (m *ModuleBase) IsCommonOSVariant() bool {
1222 return m.commonProperties.CommonOSVariant
1223}
1224
Colin Cross34037c62020-11-17 13:19:17 -08001225// supportsTarget returns true if the given Target is supported by the current module.
1226func (m *ModuleBase) supportsTarget(target Target) bool {
1227 switch target.Os.Class {
1228 case Host:
1229 if target.HostCross {
1230 return m.HostCrossSupported()
1231 } else {
1232 return m.HostSupported()
Colin Crossa1ad8d12016-06-01 17:09:44 -07001233 }
Colin Cross34037c62020-11-17 13:19:17 -08001234 case Device:
1235 return m.DeviceSupported()
Colin Crossa1ad8d12016-06-01 17:09:44 -07001236 default:
Jiyong Park1613e552020-09-14 19:43:17 +09001237 return false
Colin Crossa1ad8d12016-06-01 17:09:44 -07001238 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001239}
1240
Colin Cross34037c62020-11-17 13:19:17 -08001241// DeviceSupported returns true if the current module is supported and enabled for device targets,
1242// i.e. the factory method set the HostOrDeviceSupported value to include device support and
1243// the device support is enabled by default or enabled by the device_supported property.
Colin Cross4157e882019-06-06 16:57:04 -07001244func (m *ModuleBase) DeviceSupported() bool {
Colin Cross34037c62020-11-17 13:19:17 -08001245 hod := m.commonProperties.HostOrDeviceSupported
1246 // deviceEnabled is true if the device_supported property is true or the HostOrDeviceSupported
1247 // value has the deviceDefault bit set.
1248 deviceEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Device_supported, hod&deviceDefault != 0)
1249 return hod&deviceSupported != 0 && deviceEnabled
Colin Cross3f40fa42015-01-30 17:27:36 -08001250}
1251
Colin Cross34037c62020-11-17 13:19:17 -08001252// HostSupported returns true if the current module is supported and enabled for host targets,
1253// i.e. the factory method set the HostOrDeviceSupported value to include host support and
1254// the host support is enabled by default or enabled by the host_supported property.
Paul Duffine44358f2019-11-26 18:04:12 +00001255func (m *ModuleBase) HostSupported() bool {
Colin Cross34037c62020-11-17 13:19:17 -08001256 hod := m.commonProperties.HostOrDeviceSupported
1257 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1258 // value has the hostDefault bit set.
1259 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
1260 return hod&hostSupported != 0 && hostEnabled
1261}
1262
1263// HostCrossSupported returns true if the current module is supported and enabled for host cross
1264// targets, i.e. the factory method set the HostOrDeviceSupported value to include host cross
1265// support and the host cross support is enabled by default or enabled by the
1266// host_supported property.
1267func (m *ModuleBase) HostCrossSupported() bool {
1268 hod := m.commonProperties.HostOrDeviceSupported
1269 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
1270 // value has the hostDefault bit set.
1271 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
Ivan Lozanoc7eafa72024-07-16 17:55:33 +00001272
1273 // Default true for the Host_cross_supported property
1274 hostCrossEnabled := proptools.BoolDefault(m.hostCrossProperties.Host_cross_supported, true)
1275
1276 return hod&hostCrossSupported != 0 && hostEnabled && hostCrossEnabled
Paul Duffine44358f2019-11-26 18:04:12 +00001277}
1278
Colin Cross4157e882019-06-06 16:57:04 -07001279func (m *ModuleBase) Platform() bool {
Justin Yund5f6c822019-06-25 16:47:17 +09001280 return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.SystemExtSpecific()
Jiyong Parkc678ad32018-04-10 13:07:10 +09001281}
1282
Colin Cross4157e882019-06-06 16:57:04 -07001283func (m *ModuleBase) DeviceSpecific() bool {
1284 return Bool(m.commonProperties.Device_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001285}
1286
Colin Cross4157e882019-06-06 16:57:04 -07001287func (m *ModuleBase) SocSpecific() bool {
1288 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001289}
1290
Colin Cross4157e882019-06-06 16:57:04 -07001291func (m *ModuleBase) ProductSpecific() bool {
1292 return Bool(m.commonProperties.Product_specific)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001293}
1294
Justin Yund5f6c822019-06-25 16:47:17 +09001295func (m *ModuleBase) SystemExtSpecific() bool {
1296 return Bool(m.commonProperties.System_ext_specific)
Dario Frenifd05a742018-05-29 13:28:54 +01001297}
1298
Colin Crossc2d24052020-05-13 11:05:02 -07001299// RequiresStableAPIs returns true if the module will be installed to a partition that may
1300// be updated separately from the system image.
1301func (m *ModuleBase) RequiresStableAPIs(ctx BaseModuleContext) bool {
1302 return m.SocSpecific() || m.DeviceSpecific() ||
1303 (m.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface())
1304}
1305
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001306func (m *ModuleBase) PartitionTag(config DeviceConfig) string {
1307 partition := "system"
1308 if m.SocSpecific() {
1309 // A SoC-specific module could be on the vendor partition at
1310 // "vendor" or the system partition at "system/vendor".
1311 if config.VendorPath() == "vendor" {
1312 partition = "vendor"
1313 }
1314 } else if m.DeviceSpecific() {
1315 // A device-specific module could be on the odm partition at
1316 // "odm", the vendor partition at "vendor/odm", or the system
1317 // partition at "system/vendor/odm".
1318 if config.OdmPath() == "odm" {
1319 partition = "odm"
Ramy Medhat944839a2020-03-31 22:14:52 -04001320 } else if strings.HasPrefix(config.OdmPath(), "vendor/") {
Bill Peckhamfff3f8a2020-03-20 18:33:20 -07001321 partition = "vendor"
1322 }
1323 } else if m.ProductSpecific() {
1324 // A product-specific module could be on the product partition
1325 // at "product" or the system partition at "system/product".
1326 if config.ProductPath() == "product" {
1327 partition = "product"
1328 }
1329 } else if m.SystemExtSpecific() {
1330 // A system_ext-specific module could be on the system_ext
1331 // partition at "system_ext" or the system partition at
1332 // "system/system_ext".
1333 if config.SystemExtPath() == "system_ext" {
1334 partition = "system_ext"
1335 }
1336 }
1337 return partition
1338}
1339
Cole Fausta963b942024-04-11 17:43:00 -07001340func (m *ModuleBase) Enabled(ctx ConfigAndErrorContext) bool {
Justin Yun32f053b2020-07-31 23:07:17 +09001341 if m.commonProperties.ForcedDisabled {
1342 return false
1343 }
Cole Fausta963b942024-04-11 17:43:00 -07001344 return m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled)
Colin Cross3f40fa42015-01-30 17:27:36 -08001345}
1346
Inseob Kimeec88e12020-01-22 11:11:29 +09001347func (m *ModuleBase) Disable() {
Justin Yun32f053b2020-07-31 23:07:17 +09001348 m.commonProperties.ForcedDisabled = true
Inseob Kimeec88e12020-01-22 11:11:29 +09001349}
1350
Colin Crossa9c8c9f2020-12-16 10:20:23 -08001351// HideFromMake marks this variant so that it is not emitted in the generated Android.mk file.
1352func (m *ModuleBase) HideFromMake() {
1353 m.commonProperties.HideFromMake = true
1354}
1355
1356// IsHideFromMake returns true if HideFromMake was previously called.
1357func (m *ModuleBase) IsHideFromMake() bool {
1358 return m.commonProperties.HideFromMake == true
1359}
1360
1361// SkipInstall marks this variant to not create install rules when ctx.Install* are called.
Colin Cross4157e882019-06-06 16:57:04 -07001362func (m *ModuleBase) SkipInstall() {
1363 m.commonProperties.SkipInstall = true
Colin Crossce75d2c2016-10-06 16:12:58 -07001364}
1365
Martin Stjernholm9e7f45e2020-12-23 03:50:30 +00001366// IsSkipInstall returns true if this variant is marked to not create install
1367// rules when ctx.Install* are called.
1368func (m *ModuleBase) IsSkipInstall() bool {
1369 return m.commonProperties.SkipInstall
1370}
1371
Iván Budnik295da162023-03-10 16:11:26 +00001372// Similar to HideFromMake, but if the AndroidMk entry would set
1373// LOCAL_UNINSTALLABLE_MODULE then this variant may still output that entry
1374// rather than leaving it out altogether. That happens in cases where it would
1375// have other side effects, in particular when it adds a NOTICE file target,
1376// which other install targets might depend on.
1377func (m *ModuleBase) MakeUninstallable() {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001378 m.commonProperties.UninstallableApexPlatformVariant = true
Iván Budnik295da162023-03-10 16:11:26 +00001379 m.HideFromMake()
1380}
1381
Liz Kammer5ca3a622020-08-05 15:40:41 -07001382func (m *ModuleBase) ReplacedByPrebuilt() {
1383 m.commonProperties.ReplacedByPrebuilt = true
Colin Crossa9c8c9f2020-12-16 10:20:23 -08001384 m.HideFromMake()
Liz Kammer5ca3a622020-08-05 15:40:41 -07001385}
1386
1387func (m *ModuleBase) IsReplacedByPrebuilt() bool {
1388 return m.commonProperties.ReplacedByPrebuilt
1389}
1390
Colin Cross4157e882019-06-06 16:57:04 -07001391func (m *ModuleBase) ExportedToMake() bool {
1392 return m.commonProperties.NamespaceExportedToMake
Jiyong Park374510b2018-03-19 18:23:01 +09001393}
1394
Justin Yun1871f902023-04-07 20:13:19 +09001395func (m *ModuleBase) EffectiveLicenseKinds() []string {
1396 return m.commonProperties.Effective_license_kinds
1397}
1398
Justin Yun885a7de2021-06-29 20:34:53 +09001399func (m *ModuleBase) EffectiveLicenseFiles() Paths {
Bob Badour4101c712022-02-09 11:54:35 -08001400 result := make(Paths, 0, len(m.commonProperties.Effective_license_text))
1401 for _, p := range m.commonProperties.Effective_license_text {
1402 result = append(result, p.Path)
1403 }
1404 return result
Justin Yun885a7de2021-06-29 20:34:53 +09001405}
1406
Colin Crosse9fe2942020-11-10 18:12:15 -08001407// computeInstallDeps finds the installed paths of all dependencies that have a dependency
Colin Crossbd3a16b2023-04-25 11:30:51 -07001408// tag that is annotated as needing installation via the isInstallDepNeeded method.
Colin Crossc85750b2022-04-21 12:50:51 -07001409func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]*DepSet[InstallPath], []*DepSet[PackagingSpec]) {
1410 var installDeps []*DepSet[InstallPath]
1411 var packagingSpecs []*DepSet[PackagingSpec]
Colin Cross5d583952020-11-24 16:21:24 -08001412 ctx.VisitDirectDeps(func(dep Module) {
Jiyong Park1d4907e2024-05-15 02:09:42 +09001413 if isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) {
Colin Crossbd3a16b2023-04-25 11:30:51 -07001414 // Installation is still handled by Make, so anything hidden from Make is not
1415 // installable.
Yu Liubad1eef2024-08-21 22:37:35 +00001416 info := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider)
Colin Crossbd3a16b2023-04-25 11:30:51 -07001417 if !dep.IsHideFromMake() && !dep.IsSkipInstall() {
Yu Liubad1eef2024-08-21 22:37:35 +00001418 installDeps = append(installDeps, info.TransitiveInstallFiles)
Colin Crossbd3a16b2023-04-25 11:30:51 -07001419 }
1420 // Add packaging deps even when the dependency is not installed so that uninstallable
1421 // modules can still be packaged. Often the package will be installed instead.
Yu Liubad1eef2024-08-21 22:37:35 +00001422 packagingSpecs = append(packagingSpecs, info.TransitivePackagingSpecs)
Colin Cross897266e2020-02-13 13:22:08 -08001423 }
1424 })
Colin Cross3f40fa42015-01-30 17:27:36 -08001425
Colin Crossffe6b9d2020-12-01 15:40:06 -08001426 return installDeps, packagingSpecs
Colin Cross3f40fa42015-01-30 17:27:36 -08001427}
1428
Colin Crossbd3a16b2023-04-25 11:30:51 -07001429// isInstallDepNeeded returns true if installing the output files of the current module
1430// should also install the output files of the given dependency and dependency tag.
1431func isInstallDepNeeded(dep Module, tag blueprint.DependencyTag) bool {
1432 // Don't add a dependency from the platform to a library provided by an apex.
1433 if dep.base().commonProperties.UninstallableApexPlatformVariant {
1434 return false
1435 }
1436 // Only install modules if the dependency tag is an InstallDepNeeded tag.
1437 return IsInstallDepNeededTag(tag)
1438}
1439
Colin Crossffe6b9d2020-12-01 15:40:06 -08001440func (m *ModuleBase) TransitivePackagingSpecs() []PackagingSpec {
1441 return m.packagingSpecsDepSet.ToList()
1442}
1443
Colin Cross4157e882019-06-06 16:57:04 -07001444func (m *ModuleBase) NoAddressSanitizer() bool {
1445 return m.noAddressSanitizer
Colin Cross3f40fa42015-01-30 17:27:36 -08001446}
1447
Colin Cross4157e882019-06-06 16:57:04 -07001448func (m *ModuleBase) InstallInData() bool {
Dan Willemsen782a2d12015-12-21 14:55:28 -08001449 return false
1450}
1451
Jaewoong Jung0949f312019-09-11 10:25:18 -07001452func (m *ModuleBase) InstallInTestcases() bool {
1453 return false
1454}
1455
Colin Cross4157e882019-06-06 16:57:04 -07001456func (m *ModuleBase) InstallInSanitizerDir() bool {
Vishwath Mohan1dd88392017-03-29 22:00:18 -07001457 return false
1458}
1459
Yifan Hong1b3348d2020-01-21 15:53:22 -08001460func (m *ModuleBase) InstallInRamdisk() bool {
1461 return Bool(m.commonProperties.Ramdisk)
1462}
1463
Yifan Hong60e0cfb2020-10-21 15:17:56 -07001464func (m *ModuleBase) InstallInVendorRamdisk() bool {
1465 return Bool(m.commonProperties.Vendor_ramdisk)
1466}
1467
Inseob Kim08758f02021-04-08 21:13:22 +09001468func (m *ModuleBase) InstallInDebugRamdisk() bool {
1469 return Bool(m.commonProperties.Debug_ramdisk)
1470}
1471
Colin Cross4157e882019-06-06 16:57:04 -07001472func (m *ModuleBase) InstallInRecovery() bool {
1473 return Bool(m.commonProperties.Recovery)
Jiyong Parkf9332f12018-02-01 00:54:12 +09001474}
1475
Colin Crossea30d852023-11-29 16:00:16 -08001476func (m *ModuleBase) InstallInOdm() bool {
1477 return false
1478}
1479
1480func (m *ModuleBase) InstallInProduct() bool {
1481 return false
1482}
1483
Kiyoung Kimae11c232021-07-19 11:38:04 +09001484func (m *ModuleBase) InstallInVendor() bool {
Kiyoung Kimf160f7f2022-11-29 10:58:08 +09001485 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Soc_specific) || Bool(m.commonProperties.Proprietary)
Kiyoung Kimae11c232021-07-19 11:38:04 +09001486}
1487
Colin Cross90ba5f42019-10-02 11:10:58 -07001488func (m *ModuleBase) InstallInRoot() bool {
1489 return false
1490}
1491
Jiyong Park87788b52020-09-01 12:37:45 +09001492func (m *ModuleBase) InstallForceOS() (*OsType, *ArchType) {
1493 return nil, nil
Colin Cross6e359402020-02-10 15:29:54 -08001494}
1495
Colin Cross4157e882019-06-06 16:57:04 -07001496func (m *ModuleBase) Owner() string {
1497 return String(m.commonProperties.Owner)
Sundong Ahn4fd04bb2018-08-31 18:01:37 +09001498}
1499
Ronald Braunstein73b08ff2023-12-19 10:24:47 -08001500func (m *ModuleBase) Team() string {
1501 return String(m.commonProperties.Team)
1502}
1503
Colin Cross7228ecd2019-11-18 16:00:16 -08001504func (m *ModuleBase) setImageVariation(variant string) {
1505 m.commonProperties.ImageVariation = variant
1506}
1507
1508func (m *ModuleBase) ImageVariation() blueprint.Variation {
1509 return blueprint.Variation{
1510 Mutator: "image",
1511 Variation: m.base().commonProperties.ImageVariation,
1512 }
1513}
1514
Paul Duffin9b76c0b2020-03-12 10:24:35 +00001515func (m *ModuleBase) getVariationByMutatorName(mutator string) string {
1516 for i, v := range m.commonProperties.DebugMutators {
1517 if v == mutator {
1518 return m.commonProperties.DebugVariations[i]
1519 }
1520 }
1521
1522 return ""
1523}
1524
Yifan Hong1b3348d2020-01-21 15:53:22 -08001525func (m *ModuleBase) InRamdisk() bool {
1526 return m.base().commonProperties.ImageVariation == RamdiskVariation
1527}
1528
Yifan Hong60e0cfb2020-10-21 15:17:56 -07001529func (m *ModuleBase) InVendorRamdisk() bool {
1530 return m.base().commonProperties.ImageVariation == VendorRamdiskVariation
1531}
1532
Inseob Kim08758f02021-04-08 21:13:22 +09001533func (m *ModuleBase) InDebugRamdisk() bool {
1534 return m.base().commonProperties.ImageVariation == DebugRamdiskVariation
1535}
1536
Colin Cross7228ecd2019-11-18 16:00:16 -08001537func (m *ModuleBase) InRecovery() bool {
1538 return m.base().commonProperties.ImageVariation == RecoveryVariation
1539}
1540
Cole Faust43ddd082024-06-17 12:32:40 -07001541func (m *ModuleBase) RequiredModuleNames(ctx ConfigAndErrorContext) []string {
1542 return m.base().commonProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
Jiyong Park6a8cf5f2019-12-30 16:31:09 +09001543}
1544
1545func (m *ModuleBase) HostRequiredModuleNames() []string {
1546 return m.base().commonProperties.Host_required
1547}
1548
1549func (m *ModuleBase) TargetRequiredModuleNames() []string {
1550 return m.base().commonProperties.Target_required
1551}
1552
Kiyoung Kimfaf6af32024-08-12 11:15:19 +09001553func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigAndErrorContext) []string {
1554 return m.base().commonProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
1555}
1556
Yu Liuddc28332024-08-09 22:48:30 +00001557func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) {
Colin Cross897266e2020-02-13 13:22:08 -08001558 var allInstalledFiles InstallPaths
1559 var allCheckbuildFiles Paths
Colin Cross0875c522017-11-28 17:34:01 -08001560 ctx.VisitAllModuleVariants(func(module Module) {
1561 a := module.base()
Yu Liud46e5ae2024-08-15 18:46:17 +00001562 var checkBuilds Paths
Yu Liuddc28332024-08-09 22:48:30 +00001563 if a == m {
1564 allInstalledFiles = append(allInstalledFiles, ctx.installFiles...)
Yu Liud46e5ae2024-08-15 18:46:17 +00001565 checkBuilds = ctx.checkbuildFiles
Yu Liuddc28332024-08-09 22:48:30 +00001566 } else {
Yu Liud46e5ae2024-08-15 18:46:17 +00001567 info := OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider)
1568 allInstalledFiles = append(allInstalledFiles, info.InstallFiles...)
1569 checkBuilds = info.CheckbuildFiles
Yu Liuddc28332024-08-09 22:48:30 +00001570 }
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07001571 // A module's -checkbuild phony targets should
Chih-Hung Hsieha3d135b2021-10-14 20:32:53 -07001572 // not be created if the module is not exported to make.
1573 // Those could depend on the build target and fail to compile
1574 // for the current build target.
Cole Fausta963b942024-04-11 17:43:00 -07001575 if !ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, a) {
Yu Liud46e5ae2024-08-15 18:46:17 +00001576 allCheckbuildFiles = append(allCheckbuildFiles, checkBuilds...)
Chih-Hung Hsieha3d135b2021-10-14 20:32:53 -07001577 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001578 })
1579
Colin Cross0875c522017-11-28 17:34:01 -08001580 var deps Paths
Colin Cross9454bfa2015-03-17 13:24:18 -07001581
Yu Liu460c0fa2024-08-20 19:31:15 +00001582 var namespacePrefix string
1583 nameSpace := ctx.Namespace().Path
1584 if nameSpace != "." {
1585 namespacePrefix = strings.ReplaceAll(nameSpace, "/", ".") + "-"
Jeff Gaston088e29e2017-11-29 16:47:17 -08001586 }
1587
Yu Liuddc2e1a2024-08-20 21:31:22 +00001588 var info FinalModuleBuildTargetsInfo
1589
Colin Cross3f40fa42015-01-30 17:27:36 -08001590 if len(allInstalledFiles) > 0 {
Colin Crossc3d87d32020-06-04 13:25:17 -07001591 name := namespacePrefix + ctx.ModuleName() + "-install"
1592 ctx.Phony(name, allInstalledFiles.Paths()...)
Yu Liuddc2e1a2024-08-20 21:31:22 +00001593 info.InstallTarget = PathForPhony(ctx, name)
1594 deps = append(deps, info.InstallTarget)
Colin Cross9454bfa2015-03-17 13:24:18 -07001595 }
1596
1597 if len(allCheckbuildFiles) > 0 {
Colin Crossc3d87d32020-06-04 13:25:17 -07001598 name := namespacePrefix + ctx.ModuleName() + "-checkbuild"
1599 ctx.Phony(name, allCheckbuildFiles...)
Yu Liuddc2e1a2024-08-20 21:31:22 +00001600 info.CheckbuildTarget = PathForPhony(ctx, name)
1601 deps = append(deps, info.CheckbuildTarget)
Colin Cross9454bfa2015-03-17 13:24:18 -07001602 }
1603
1604 if len(deps) > 0 {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001605 suffix := ""
Jingwen Chencda22c92020-11-23 00:22:30 -05001606 if ctx.Config().KatiEnabled() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08001607 suffix = "-soong"
1608 }
1609
Colin Crossc3d87d32020-06-04 13:25:17 -07001610 ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07001611
Yu Liuddc2e1a2024-08-20 21:31:22 +00001612 info.BlueprintDir = ctx.ModuleDir()
1613 SetProvider(ctx, FinalModuleBuildTargetsProvider, info)
Colin Cross3f40fa42015-01-30 17:27:36 -08001614 }
1615}
1616
Colin Crossc34d2322020-01-03 15:23:27 -08001617func determineModuleKind(m *ModuleBase, ctx blueprint.EarlyModuleContext) moduleKind {
Colin Cross4157e882019-06-06 16:57:04 -07001618 var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
1619 var deviceSpecific = Bool(m.commonProperties.Device_specific)
1620 var productSpecific = Bool(m.commonProperties.Product_specific)
Justin Yund5f6c822019-06-25 16:47:17 +09001621 var systemExtSpecific = Bool(m.commonProperties.System_ext_specific)
Jiyong Park2db76922017-11-08 16:03:48 +09001622
Dario Frenifd05a742018-05-29 13:28:54 +01001623 msg := "conflicting value set here"
1624 if socSpecific && deviceSpecific {
1625 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
Colin Cross4157e882019-06-06 16:57:04 -07001626 if Bool(m.commonProperties.Vendor) {
Jiyong Park2db76922017-11-08 16:03:48 +09001627 ctx.PropertyErrorf("vendor", msg)
1628 }
Colin Cross4157e882019-06-06 16:57:04 -07001629 if Bool(m.commonProperties.Proprietary) {
Jiyong Park2db76922017-11-08 16:03:48 +09001630 ctx.PropertyErrorf("proprietary", msg)
1631 }
Colin Cross4157e882019-06-06 16:57:04 -07001632 if Bool(m.commonProperties.Soc_specific) {
Jiyong Park2db76922017-11-08 16:03:48 +09001633 ctx.PropertyErrorf("soc_specific", msg)
1634 }
1635 }
1636
Justin Yund5f6c822019-06-25 16:47:17 +09001637 if productSpecific && systemExtSpecific {
1638 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and system_ext at the same time.")
1639 ctx.PropertyErrorf("system_ext_specific", msg)
Dario Frenifd05a742018-05-29 13:28:54 +01001640 }
1641
Justin Yund5f6c822019-06-25 16:47:17 +09001642 if (socSpecific || deviceSpecific) && (productSpecific || systemExtSpecific) {
Dario Frenifd05a742018-05-29 13:28:54 +01001643 if productSpecific {
1644 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
1645 } else {
Justin Yund5f6c822019-06-25 16:47:17 +09001646 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 +01001647 }
1648 if deviceSpecific {
1649 ctx.PropertyErrorf("device_specific", msg)
1650 } else {
Colin Cross4157e882019-06-06 16:57:04 -07001651 if Bool(m.commonProperties.Vendor) {
Dario Frenifd05a742018-05-29 13:28:54 +01001652 ctx.PropertyErrorf("vendor", msg)
1653 }
Colin Cross4157e882019-06-06 16:57:04 -07001654 if Bool(m.commonProperties.Proprietary) {
Dario Frenifd05a742018-05-29 13:28:54 +01001655 ctx.PropertyErrorf("proprietary", msg)
1656 }
Colin Cross4157e882019-06-06 16:57:04 -07001657 if Bool(m.commonProperties.Soc_specific) {
Dario Frenifd05a742018-05-29 13:28:54 +01001658 ctx.PropertyErrorf("soc_specific", msg)
1659 }
1660 }
1661 }
1662
Jiyong Park2db76922017-11-08 16:03:48 +09001663 if productSpecific {
1664 return productSpecificModule
Justin Yund5f6c822019-06-25 16:47:17 +09001665 } else if systemExtSpecific {
1666 return systemExtSpecificModule
Jiyong Park2db76922017-11-08 16:03:48 +09001667 } else if deviceSpecific {
1668 return deviceSpecificModule
1669 } else if socSpecific {
1670 return socSpecificModule
1671 } else {
1672 return platformModule
1673 }
1674}
1675
Colin Crossc34d2322020-01-03 15:23:27 -08001676func (m *ModuleBase) earlyModuleContextFactory(ctx blueprint.EarlyModuleContext) earlyModuleContext {
Colin Cross1184b642019-12-30 18:43:07 -08001677 return earlyModuleContext{
Colin Crossc34d2322020-01-03 15:23:27 -08001678 EarlyModuleContext: ctx,
1679 kind: determineModuleKind(m, ctx),
1680 config: ctx.Config().(Config),
Colin Cross3f40fa42015-01-30 17:27:36 -08001681 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001682}
1683
Colin Cross1184b642019-12-30 18:43:07 -08001684func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext {
1685 return baseModuleContext{
1686 bp: ctx,
Colin Cross1d3d9f12024-01-18 14:30:22 -08001687 archModuleContext: m.archModuleContextFactory(ctx),
Colin Cross1184b642019-12-30 18:43:07 -08001688 earlyModuleContext: m.earlyModuleContextFactory(ctx),
Colin Cross1184b642019-12-30 18:43:07 -08001689 }
1690}
1691
Colin Crosse1a85552024-06-14 12:17:37 -07001692type archModuleContextFactoryContext interface {
1693 Config() interface{}
1694}
1695
1696func (m *ModuleBase) archModuleContextFactory(ctx archModuleContextFactoryContext) archModuleContext {
Colin Cross1d3d9f12024-01-18 14:30:22 -08001697 config := ctx.Config().(Config)
1698 target := m.Target()
1699 primaryArch := false
1700 if len(config.Targets[target.Os]) <= 1 {
1701 primaryArch = true
1702 } else {
1703 primaryArch = target.Arch.ArchType == config.Targets[target.Os][0].Arch.ArchType
1704 }
1705
1706 return archModuleContext{
Cole Faust0aa21cc2024-03-20 12:28:03 -07001707 ready: m.commonProperties.ArchReady,
Colin Cross1d3d9f12024-01-18 14:30:22 -08001708 os: m.commonProperties.CompileOS,
1709 target: m.commonProperties.CompileTarget,
1710 targetPrimary: m.commonProperties.CompilePrimary,
1711 multiTargets: m.commonProperties.CompileMultiTargets,
1712 primaryArch: primaryArch,
1713 }
1714
1715}
1716
Yu Liuddc28332024-08-09 22:48:30 +00001717type InstallFilesInfo struct {
Yu Liud46e5ae2024-08-15 18:46:17 +00001718 InstallFiles InstallPaths
1719 CheckbuildFiles Paths
1720 PackagingSpecs []PackagingSpec
1721 // katiInstalls tracks the install rules that were created by Soong but are being exported
1722 // to Make to convert to ninja rules so that Make can add additional dependencies.
Yu Liuec810542024-08-26 18:09:15 +00001723 KatiInstalls katiInstalls
1724 KatiSymlinks katiInstalls
1725 TestData []DataPath
Yu Liubad1eef2024-08-21 22:37:35 +00001726 TransitivePackagingSpecs *DepSet[PackagingSpec]
Yu Liuec810542024-08-26 18:09:15 +00001727 LicenseMetadataFile WritablePath
1728
1729 // The following fields are private before, make it private again once we have
1730 // better solution.
1731 TransitiveInstallFiles *DepSet[InstallPath]
Yu Liu82a6d142024-08-27 19:02:29 +00001732 // katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
1733 // allowed to have duplicates across modules and variants.
1734 KatiInitRcInstalls katiInstalls
1735 KatiVintfInstalls katiInstalls
1736 InitRcPaths Paths
1737 VintfFragmentsPaths Paths
1738 InstalledInitRcPaths InstallPaths
1739 InstalledVintfFragmentsPaths InstallPaths
1740
Yu Liuec810542024-08-26 18:09:15 +00001741 // The files to copy to the dist as explicitly specified in the .bp file.
1742 DistFiles TaggedDistFiles
Yu Liuddc28332024-08-09 22:48:30 +00001743}
1744
Yu Liubad1eef2024-08-21 22:37:35 +00001745var InstallFilesProvider = blueprint.NewProvider[InstallFilesInfo]()
Yu Liuddc2e1a2024-08-20 21:31:22 +00001746
1747type FinalModuleBuildTargetsInfo struct {
1748 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
1749 // Only set on the final variant of each module
1750 InstallTarget WritablePath
1751 CheckbuildTarget WritablePath
1752 BlueprintDir string
1753}
1754
Yu Liubad1eef2024-08-21 22:37:35 +00001755var FinalModuleBuildTargetsProvider = blueprint.NewProvider[FinalModuleBuildTargetsInfo]()
Yu Liuddc28332024-08-09 22:48:30 +00001756
Colin Cross4157e882019-06-06 16:57:04 -07001757func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
Colin Cross25de6c32019-06-06 14:29:25 -07001758 ctx := &moduleContext{
Colin Cross0ea8ba82019-06-06 14:33:29 -07001759 module: m.module,
Colin Crossdc35e212019-06-06 16:13:11 -07001760 bp: blueprintCtx,
Colin Cross0ea8ba82019-06-06 14:33:29 -07001761 baseModuleContext: m.baseModuleContextFactory(blueprintCtx),
Colin Cross0ea8ba82019-06-06 14:33:29 -07001762 variables: make(map[string]string),
Yu Liu54513622024-08-19 20:00:32 +00001763 phonies: make(map[string]Paths),
Colin Cross3f40fa42015-01-30 17:27:36 -08001764 }
1765
Jihoon Kangc3d4e112024-06-24 22:16:27 +00001766 setContainerInfo(ctx)
1767
Yu Liuec810542024-08-26 18:09:15 +00001768 ctx.licenseMetadataFile = PathForModuleOut(ctx, "meta_lic")
Colin Crossaa1cab02022-01-28 14:49:24 -08001769
Colin Crossffe6b9d2020-12-01 15:40:06 -08001770 dependencyInstallFiles, dependencyPackagingSpecs := m.computeInstallDeps(ctx)
Yu Liubad1eef2024-08-21 22:37:35 +00001771 // set the TransitiveInstallFiles to only the transitive dependencies to be used as the dependencies
Colin Cross5d583952020-11-24 16:21:24 -08001772 // of installed files of this module. It will be replaced by a depset including the installed
1773 // files of this module at the end for use by modules that depend on this one.
Yu Liubad1eef2024-08-21 22:37:35 +00001774 ctx.TransitiveInstallFiles = NewDepSet[InstallPath](TOPOLOGICAL, nil, dependencyInstallFiles)
Colin Cross5d583952020-11-24 16:21:24 -08001775
Colin Cross6c4f21f2019-06-06 15:41:36 -07001776 // Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never
1777 // reporting missing dependency errors in Blueprint when AllowMissingDependencies == true.
1778 // TODO: This will be removed once defaults modules handle missing dependency errors
1779 blueprintCtx.GetMissingDependencies()
1780
Colin Crossdc35e212019-06-06 16:13:11 -07001781 // For the final GenerateAndroidBuildActions pass, require that all visited dependencies Soong modules and
Paul Duffin1356d8c2020-02-25 19:26:33 +00001782 // are enabled. Unless the module is a CommonOS variant which may have dependencies on disabled variants
1783 // (because the dependencies are added before the modules are disabled). The
1784 // GetOsSpecificVariantsOfCommonOSVariant(...) method will ensure that the disabled variants are
1785 // ignored.
1786 ctx.baseModuleContext.strictVisitDeps = !m.IsCommonOSVariant()
Colin Crossdc35e212019-06-06 16:13:11 -07001787
Colin Cross4c83e5c2019-02-25 14:54:28 -08001788 if ctx.config.captureBuild {
1789 ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
1790 }
1791
Colin Cross67a5c132017-05-09 13:45:28 -07001792 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
1793 var suffix []string
Colin Cross0875c522017-11-28 17:34:01 -08001794 if ctx.Os().Class != Device && ctx.Os().Class != Generic {
1795 suffix = append(suffix, ctx.Os().String())
Colin Cross67a5c132017-05-09 13:45:28 -07001796 }
Colin Cross0875c522017-11-28 17:34:01 -08001797 if !ctx.PrimaryArch() {
1798 suffix = append(suffix, ctx.Arch().ArchType.String())
Colin Cross67a5c132017-05-09 13:45:28 -07001799 }
Colin Crossff694a82023-12-13 15:54:49 -08001800 if apexInfo, _ := ModuleProvider(ctx, ApexInfoProvider); !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -07001801 suffix = append(suffix, apexInfo.ApexVariationName)
Dan Willemsenb13a9482020-02-14 11:25:54 -08001802 }
Colin Cross67a5c132017-05-09 13:45:28 -07001803
1804 ctx.Variable(pctx, "moduleDesc", desc)
1805
1806 s := ""
1807 if len(suffix) > 0 {
1808 s = " [" + strings.Join(suffix, " ") + "]"
1809 }
1810 ctx.Variable(pctx, "moduleDescSuffix", s)
1811
Dan Willemsen569edc52018-11-19 09:33:29 -08001812 // Some common property checks for properties that will be used later in androidmk.go
Paul Duffin89968e32020-11-23 18:17:03 +00001813 checkDistProperties(ctx, "dist", &m.distProperties.Dist)
Sasha Smundake198eaf2022-08-04 13:07:02 -07001814 for i := range m.distProperties.Dists {
Paul Duffin89968e32020-11-23 18:17:03 +00001815 checkDistProperties(ctx, fmt.Sprintf("dists[%d]", i), &m.distProperties.Dists[i])
Dan Willemsen569edc52018-11-19 09:33:29 -08001816 }
1817
Yu Liubad1eef2024-08-21 22:37:35 +00001818 var installFiles InstallFilesInfo
1819
Cole Fausta963b942024-04-11 17:43:00 -07001820 if m.Enabled(ctx) {
Jooyung Hand48f3c32019-08-23 11:18:57 +09001821 // ensure all direct android.Module deps are enabled
1822 ctx.VisitDirectDepsBlueprint(func(bm blueprint.Module) {
Martin Stjernholm0e4cceb2021-05-13 02:38:35 +01001823 if m, ok := bm.(Module); ok {
LaMont Jones34314b72024-01-18 18:27:35 +00001824 ctx.validateAndroidModule(bm, ctx.OtherModuleDependencyTag(m), ctx.baseModuleContext.strictVisitDeps, false)
Jooyung Hand48f3c32019-08-23 11:18:57 +09001825 }
1826 })
1827
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001828 if m.Device() {
1829 // Handle any init.rc and vintf fragment files requested by the module. All files installed by this
1830 // module will automatically have a dependency on the installed init.rc or vintf fragment file.
1831 // The same init.rc or vintf fragment file may be requested by multiple modules or variants,
1832 // so instead of installing them now just compute the install path and store it for later.
1833 // The full list of all init.rc and vintf fragment install rules will be deduplicated later
1834 // so only a single rule is created for each init.rc or vintf fragment file.
1835
1836 if !m.InVendorRamdisk() {
Yu Liu82a6d142024-08-27 19:02:29 +00001837 ctx.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc)
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001838 rcDir := PathForModuleInstall(ctx, "etc", "init")
Yu Liu82a6d142024-08-27 19:02:29 +00001839 for _, src := range ctx.initRcPaths {
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001840 installedInitRc := rcDir.Join(ctx, src.Base())
Yu Liu82a6d142024-08-27 19:02:29 +00001841 ctx.katiInitRcInstalls = append(ctx.katiInitRcInstalls, katiInstall{
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001842 from: src,
1843 to: installedInitRc,
1844 })
1845 ctx.PackageFile(rcDir, src.Base(), src)
Yu Liu82a6d142024-08-27 19:02:29 +00001846 ctx.installedInitRcPaths = append(ctx.installedInitRcPaths, installedInitRc)
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001847 }
Yu Liu82a6d142024-08-27 19:02:29 +00001848 installFiles.InitRcPaths = ctx.initRcPaths
1849 installFiles.KatiInitRcInstalls = ctx.katiInitRcInstalls
1850 installFiles.InstalledInitRcPaths = ctx.installedInitRcPaths
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001851 }
1852
Yu Liu82a6d142024-08-27 19:02:29 +00001853 ctx.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments.GetOrDefault(ctx, nil))
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001854 vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest")
Yu Liu82a6d142024-08-27 19:02:29 +00001855 for _, src := range ctx.vintfFragmentsPaths {
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001856 installedVintfFragment := vintfDir.Join(ctx, src.Base())
Yu Liu82a6d142024-08-27 19:02:29 +00001857 ctx.katiVintfInstalls = append(ctx.katiVintfInstalls, katiInstall{
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001858 from: src,
1859 to: installedVintfFragment,
1860 })
1861 ctx.PackageFile(vintfDir, src.Base(), src)
Yu Liu82a6d142024-08-27 19:02:29 +00001862 ctx.installedVintfFragmentsPaths = append(ctx.installedVintfFragmentsPaths, installedVintfFragment)
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001863 }
Yu Liu82a6d142024-08-27 19:02:29 +00001864 installFiles.VintfFragmentsPaths = ctx.vintfFragmentsPaths
1865 installFiles.KatiVintfInstalls = ctx.katiVintfInstalls
1866 installFiles.InstalledVintfFragmentsPaths = ctx.installedVintfFragmentsPaths
Colin Crossd9bbf4b2023-11-17 16:23:48 -08001867 }
1868
Bob Badour37af0462021-01-07 03:34:31 +00001869 licensesPropertyFlattener(ctx)
1870 if ctx.Failed() {
1871 return
1872 }
1873
Joe Onorato349ae8d2024-02-05 22:46:00 +00001874 if jarJarPrefixHandler != nil {
1875 jarJarPrefixHandler(ctx)
1876 if ctx.Failed() {
1877 return
1878 }
1879 }
1880
Justin Yun40182b62024-05-07 10:22:19 +09001881 // Call aconfigUpdateAndroidBuildActions to collect merged aconfig files before being used
1882 // in m.module.GenerateAndroidBuildActions
1883 aconfigUpdateAndroidBuildActions(ctx)
Jaewoong Jung5b425e22019-06-17 17:40:56 -07001884 if ctx.Failed() {
1885 return
1886 }
1887
Yu Liufa297642024-06-11 00:13:02 +00001888 incrementalAnalysis := false
1889 incrementalEnabled := false
1890 var cacheKey *blueprint.BuildActionCacheKey = nil
1891 var incrementalModule *blueprint.Incremental = nil
1892 if ctx.bp.GetIncrementalEnabled() {
1893 if im, ok := m.module.(blueprint.Incremental); ok {
1894 incrementalModule = &im
1895 incrementalEnabled = im.IncrementalSupported()
1896 incrementalAnalysis = ctx.bp.GetIncrementalAnalysis() && incrementalEnabled
1897 }
1898 }
1899 if incrementalEnabled {
1900 hash, err := proptools.CalculateHash(m.GetProperties())
1901 if err != nil {
1902 ctx.ModuleErrorf("failed to calculate properties hash: %s", err)
1903 return
1904 }
1905 cacheInput := new(blueprint.BuildActionCacheInput)
1906 cacheInput.PropertiesHash = hash
1907 ctx.VisitDirectDeps(func(module Module) {
1908 cacheInput.ProvidersHash =
1909 append(cacheInput.ProvidersHash, ctx.bp.OtherModuleProviderInitialValueHashes(module))
1910 })
1911 hash, err = proptools.CalculateHash(&cacheInput)
1912 if err != nil {
1913 ctx.ModuleErrorf("failed to calculate cache input hash: %s", err)
1914 return
1915 }
1916 cacheKey = &blueprint.BuildActionCacheKey{
Yu Liu28006752024-07-24 18:01:55 +00001917 Id: ctx.bp.ModuleCacheKey(),
Yu Liufa297642024-06-11 00:13:02 +00001918 InputHash: hash,
1919 }
1920 }
1921
1922 restored := false
1923 if incrementalAnalysis && cacheKey != nil {
Yu Liuf0721202024-07-30 17:30:45 +00001924 restored = ctx.bp.RestoreBuildActions(cacheKey)
Yu Liufa297642024-06-11 00:13:02 +00001925 }
1926
1927 if !restored {
1928 m.module.GenerateAndroidBuildActions(ctx)
1929 if ctx.Failed() {
1930 return
1931 }
1932 }
1933
1934 if incrementalEnabled && cacheKey != nil {
1935 ctx.bp.CacheBuildActions(cacheKey, incrementalModule)
LaMont Jonesb5099382024-01-10 23:42:36 +00001936 }
1937
Paul Duffinaf970a22020-11-23 23:32:56 +00001938 // Create the set of tagged dist files after calling GenerateAndroidBuildActions
1939 // as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
1940 // output paths being set which must be done before or during
1941 // GenerateAndroidBuildActions.
Yu Liuec810542024-08-26 18:09:15 +00001942 installFiles.DistFiles = m.GenerateTaggedDistFiles(ctx)
Paul Duffinaf970a22020-11-23 23:32:56 +00001943 if ctx.Failed() {
1944 return
1945 }
1946
Yu Liuec810542024-08-26 18:09:15 +00001947 installFiles.LicenseMetadataFile = ctx.licenseMetadataFile
Yu Liubad1eef2024-08-21 22:37:35 +00001948 installFiles.InstallFiles = ctx.installFiles
1949 installFiles.CheckbuildFiles = ctx.checkbuildFiles
1950 installFiles.PackagingSpecs = ctx.packagingSpecs
1951 installFiles.KatiInstalls = ctx.katiInstalls
1952 installFiles.KatiSymlinks = ctx.katiSymlinks
1953 installFiles.TestData = ctx.testData
Colin Crossdc35e212019-06-06 16:13:11 -07001954 } else if ctx.Config().AllowMissingDependencies() {
1955 // If the module is not enabled it will not create any build rules, nothing will call
1956 // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
1957 // and report them as an error even when AllowMissingDependencies = true. Call
1958 // ctx.GetMissingDependencies() here to tell blueprint not to handle them.
1959 ctx.GetMissingDependencies()
Colin Cross3f40fa42015-01-30 17:27:36 -08001960 }
1961
Colin Cross4157e882019-06-06 16:57:04 -07001962 if m == ctx.FinalModule().(Module).base() {
1963 m.generateModuleTarget(ctx)
Colin Cross9b1d13d2016-09-19 15:18:11 -07001964 if ctx.Failed() {
1965 return
1966 }
Colin Cross3f40fa42015-01-30 17:27:36 -08001967 }
Colin Crosscec81712017-07-13 14:43:27 -07001968
Yu Liubad1eef2024-08-21 22:37:35 +00001969 ctx.TransitiveInstallFiles = NewDepSet[InstallPath](TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles)
1970 installFiles.TransitiveInstallFiles = ctx.TransitiveInstallFiles
Yu Liud46e5ae2024-08-15 18:46:17 +00001971 m.packagingSpecsDepSet = NewDepSet[PackagingSpec](TOPOLOGICAL, ctx.packagingSpecs, dependencyPackagingSpecs)
Yu Liubad1eef2024-08-21 22:37:35 +00001972 installFiles.TransitivePackagingSpecs = m.packagingSpecsDepSet
Colin Cross5d583952020-11-24 16:21:24 -08001973
Yu Liubad1eef2024-08-21 22:37:35 +00001974 SetProvider(ctx, InstallFilesProvider, installFiles)
Yu Liuec810542024-08-26 18:09:15 +00001975 buildLicenseMetadata(ctx, ctx.licenseMetadataFile)
Colin Cross4acaea92021-12-10 23:05:02 +00001976
Yu Liu4297ad92024-08-27 19:50:13 +00001977 if ctx.moduleInfoJSON != nil {
Colin Crossd6fd0132023-11-06 13:54:06 -08001978 var installed InstallPaths
Yu Liud46e5ae2024-08-15 18:46:17 +00001979 installed = append(installed, ctx.katiInstalls.InstallPaths()...)
1980 installed = append(installed, ctx.katiSymlinks.InstallPaths()...)
Yu Liu82a6d142024-08-27 19:02:29 +00001981 installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...)
1982 installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...)
Colin Crossd6fd0132023-11-06 13:54:06 -08001983 installedStrings := installed.Strings()
1984
1985 var targetRequired, hostRequired []string
1986 if ctx.Host() {
1987 targetRequired = m.commonProperties.Target_required
1988 } else {
1989 hostRequired = m.commonProperties.Host_required
1990 }
1991
1992 var data []string
Yu Liud46e5ae2024-08-15 18:46:17 +00001993 for _, d := range ctx.testData {
Colin Crossd6fd0132023-11-06 13:54:06 -08001994 data = append(data, d.ToRelativeInstallPath())
1995 }
1996
Yu Liu4297ad92024-08-27 19:50:13 +00001997 if ctx.moduleInfoJSON.Uninstallable {
Colin Crossd6fd0132023-11-06 13:54:06 -08001998 installedStrings = nil
Yu Liu4297ad92024-08-27 19:50:13 +00001999 if len(ctx.moduleInfoJSON.CompatibilitySuites) == 1 && ctx.moduleInfoJSON.CompatibilitySuites[0] == "null-suite" {
2000 ctx.moduleInfoJSON.CompatibilitySuites = nil
2001 ctx.moduleInfoJSON.TestConfig = nil
2002 ctx.moduleInfoJSON.AutoTestConfig = nil
Colin Crossd6fd0132023-11-06 13:54:06 -08002003 data = nil
2004 }
2005 }
2006
Yu Liu4297ad92024-08-27 19:50:13 +00002007 ctx.moduleInfoJSON.core = CoreModuleInfoJSON{
2008 RegisterName: m.moduleInfoRegisterName(ctx, ctx.moduleInfoJSON.SubName),
Colin Crossd6fd0132023-11-06 13:54:06 -08002009 Path: []string{ctx.ModuleDir()},
2010 Installed: installedStrings,
Yu Liu4297ad92024-08-27 19:50:13 +00002011 ModuleName: m.BaseModuleName() + ctx.moduleInfoJSON.SubName,
Colin Crossd6fd0132023-11-06 13:54:06 -08002012 SupportedVariants: []string{m.moduleInfoVariant(ctx)},
2013 TargetDependencies: targetRequired,
2014 HostDependencies: hostRequired,
2015 Data: data,
Cole Faust43ddd082024-06-17 12:32:40 -07002016 Required: m.RequiredModuleNames(ctx),
Colin Crossd6fd0132023-11-06 13:54:06 -08002017 }
Yu Liu4297ad92024-08-27 19:50:13 +00002018 SetProvider(ctx, ModuleInfoJSONProvider, ctx.moduleInfoJSON)
Colin Crossd6fd0132023-11-06 13:54:06 -08002019 }
2020
Colin Cross4157e882019-06-06 16:57:04 -07002021 m.buildParams = ctx.buildParams
2022 m.ruleParams = ctx.ruleParams
2023 m.variables = ctx.variables
mrziwange6c85812024-05-22 14:36:09 -07002024
Yu Liu876b7ce2024-08-21 18:20:13 +00002025 outputFiles := ctx.GetOutputFiles()
2026 if outputFiles.DefaultOutputFiles != nil || outputFiles.TaggedOutputFiles != nil {
2027 SetProvider(ctx, OutputFilesProvider, outputFiles)
mrziwange6c85812024-05-22 14:36:09 -07002028 }
Wei Lia1aa2972024-06-21 13:08:51 -07002029
Yu Liu54513622024-08-19 20:00:32 +00002030 if len(ctx.phonies) > 0 {
2031 SetProvider(ctx, ModulePhonyProvider, ModulePhonyInfo{
2032 Phonies: ctx.phonies,
2033 })
2034 }
Wei Lia1aa2972024-06-21 13:08:51 -07002035 buildComplianceMetadataProvider(ctx, m)
Colin Cross3f40fa42015-01-30 17:27:36 -08002036}
2037
Joe Onorato349ae8d2024-02-05 22:46:00 +00002038func SetJarJarPrefixHandler(handler func(ModuleContext)) {
2039 if jarJarPrefixHandler != nil {
2040 panic("jarJarPrefixHandler already set")
2041 }
2042 jarJarPrefixHandler = handler
2043}
2044
Colin Crossd6fd0132023-11-06 13:54:06 -08002045func (m *ModuleBase) moduleInfoRegisterName(ctx ModuleContext, subName string) string {
2046 name := m.BaseModuleName()
2047
2048 prefix := ""
2049 if ctx.Host() {
2050 if ctx.Os() != ctx.Config().BuildOS {
2051 prefix = "host_cross_"
2052 }
2053 }
2054 suffix := ""
2055 arches := slices.Clone(ctx.Config().Targets[ctx.Os()])
2056 arches = slices.DeleteFunc(arches, func(target Target) bool {
2057 return target.NativeBridge != ctx.Target().NativeBridge
2058 })
2059 if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType {
2060 if ctx.Arch().ArchType.Multilib == "lib32" {
2061 suffix = "_32"
2062 } else {
2063 suffix = "_64"
2064 }
2065 }
2066 return prefix + name + subName + suffix
2067}
2068
2069func (m *ModuleBase) moduleInfoVariant(ctx ModuleContext) string {
2070 variant := "DEVICE"
2071 if ctx.Host() {
2072 if ctx.Os() != ctx.Config().BuildOS {
2073 variant = "HOST_CROSS"
2074 } else {
2075 variant = "HOST"
2076 }
2077 }
2078 return variant
2079}
2080
Paul Duffin89968e32020-11-23 18:17:03 +00002081// Check the supplied dist structure to make sure that it is valid.
2082//
2083// property - the base property, e.g. dist or dists[1], which is combined with the
2084// name of the nested property to produce the full property, e.g. dist.dest or
2085// dists[1].dir.
2086func checkDistProperties(ctx *moduleContext, property string, dist *Dist) {
2087 if dist.Dest != nil {
2088 _, err := validateSafePath(*dist.Dest)
2089 if err != nil {
2090 ctx.PropertyErrorf(property+".dest", "%s", err.Error())
2091 }
2092 }
2093 if dist.Dir != nil {
2094 _, err := validateSafePath(*dist.Dir)
2095 if err != nil {
2096 ctx.PropertyErrorf(property+".dir", "%s", err.Error())
2097 }
2098 }
2099 if dist.Suffix != nil {
2100 if strings.Contains(*dist.Suffix, "/") {
2101 ctx.PropertyErrorf(property+".suffix", "Suffix may not contain a '/' character.")
2102 }
2103 }
2104
2105}
2106
Colin Cross6301c3c2021-09-28 17:40:21 -07002107// katiInstall stores a request from Soong to Make to create an install rule.
2108type katiInstall struct {
2109 from Path
2110 to InstallPath
2111 implicitDeps Paths
2112 orderOnlyDeps Paths
2113 executable bool
Colin Cross50ed1f92021-11-12 17:41:02 -08002114 extraFiles *extraFilesZip
Colin Cross6301c3c2021-09-28 17:40:21 -07002115
2116 absFrom string
2117}
2118
Colin Cross50ed1f92021-11-12 17:41:02 -08002119type extraFilesZip struct {
2120 zip Path
2121 dir InstallPath
2122}
2123
Colin Cross6301c3c2021-09-28 17:40:21 -07002124type katiInstalls []katiInstall
2125
2126// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
2127// space separated list of from:to tuples.
2128func (installs katiInstalls) BuiltInstalled() string {
2129 sb := strings.Builder{}
2130 for i, install := range installs {
2131 if i != 0 {
2132 sb.WriteRune(' ')
2133 }
2134 sb.WriteString(install.from.String())
2135 sb.WriteRune(':')
2136 sb.WriteString(install.to.String())
2137 }
2138 return sb.String()
2139}
2140
2141// InstallPaths returns the install path of each entry.
2142func (installs katiInstalls) InstallPaths() InstallPaths {
2143 paths := make(InstallPaths, 0, len(installs))
2144 for _, install := range installs {
2145 paths = append(paths, install.to)
2146 }
2147 return paths
2148}
2149
Jiyong Park5baac542018-08-28 09:55:37 +09002150// Makes this module a platform module, i.e. not specific to soc, device,
Justin Yund5f6c822019-06-25 16:47:17 +09002151// product, or system_ext.
Colin Cross4157e882019-06-06 16:57:04 -07002152func (m *ModuleBase) MakeAsPlatform() {
2153 m.commonProperties.Vendor = boolPtr(false)
2154 m.commonProperties.Proprietary = boolPtr(false)
2155 m.commonProperties.Soc_specific = boolPtr(false)
2156 m.commonProperties.Product_specific = boolPtr(false)
Justin Yund5f6c822019-06-25 16:47:17 +09002157 m.commonProperties.System_ext_specific = boolPtr(false)
Jiyong Park5baac542018-08-28 09:55:37 +09002158}
2159
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09002160func (m *ModuleBase) MakeAsSystemExt() {
Jooyung Han91df2082019-11-20 01:49:42 +09002161 m.commonProperties.Vendor = boolPtr(false)
2162 m.commonProperties.Proprietary = boolPtr(false)
2163 m.commonProperties.Soc_specific = boolPtr(false)
2164 m.commonProperties.Product_specific = boolPtr(false)
2165 m.commonProperties.System_ext_specific = boolPtr(true)
Sundong Ahnd95aa2d2019-10-08 19:34:03 +09002166}
2167
Jooyung Han344d5432019-08-23 11:17:39 +09002168// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true"
2169func (m *ModuleBase) IsNativeBridgeSupported() bool {
2170 return proptools.Bool(m.commonProperties.Native_bridge_supported)
2171}
2172
Cole Faust02987bd2024-03-21 17:58:43 -07002173type ConfigAndErrorContext interface {
2174 Config() Config
2175 OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{})
2176}
2177
2178type configurationEvalutor struct {
2179 ctx ConfigAndErrorContext
2180 m Module
2181}
2182
2183func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator {
2184 return configurationEvalutor{
2185 ctx: ctx,
2186 m: m.module,
2187 }
2188}
2189
2190func (e configurationEvalutor) PropertyErrorf(property string, fmt string, args ...interface{}) {
Cole Fausta963b942024-04-11 17:43:00 -07002191 e.ctx.OtherModulePropertyErrorf(e.m, property, fmt, args...)
Cole Faust02987bd2024-03-21 17:58:43 -07002192}
2193
Cole Faustfdbf5d42024-04-10 15:01:23 -07002194func (e configurationEvalutor) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue {
Cole Faust02987bd2024-03-21 17:58:43 -07002195 ctx := e.ctx
2196 m := e.m
Cole Faust8afc5142024-04-26 16:30:19 -07002197 switch condition.FunctionName() {
Cole Fauste19f7412024-05-09 15:14:04 -07002198 case "release_flag":
Cole Faust8afc5142024-04-26 16:30:19 -07002199 if condition.NumArgs() != 1 {
Cole Fauste19f7412024-05-09 15:14:04 -07002200 ctx.OtherModulePropertyErrorf(m, property, "release_flag requires 1 argument, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002201 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002202 }
Cole Faust751a4a52024-05-21 16:51:59 -07002203 if ty, ok := ctx.Config().productVariables.BuildFlagTypes[condition.Arg(0)]; ok {
2204 v := ctx.Config().productVariables.BuildFlags[condition.Arg(0)]
2205 switch ty {
2206 case "unspecified", "obsolete":
2207 return proptools.ConfigurableValueUndefined()
2208 case "string":
2209 return proptools.ConfigurableValueString(v)
2210 case "bool":
2211 return proptools.ConfigurableValueBool(v == "true")
2212 default:
2213 panic("unhandled release flag type: " + ty)
2214 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002215 }
2216 return proptools.ConfigurableValueUndefined()
2217 case "product_variable":
Jiyong Parke3250752024-05-17 14:56:10 +09002218 if condition.NumArgs() != 1 {
2219 ctx.OtherModulePropertyErrorf(m, property, "product_variable requires 1 argument, found %d", condition.NumArgs())
2220 return proptools.ConfigurableValueUndefined()
2221 }
2222 variable := condition.Arg(0)
2223 switch variable {
2224 case "debuggable":
2225 return proptools.ConfigurableValueBool(ctx.Config().Debuggable())
Kiyoung Kim881e4652024-07-08 11:02:23 +09002226 case "use_debug_art":
2227 // TODO(b/234351700): Remove once ART does not have separated debug APEX
2228 return proptools.ConfigurableValueBool(ctx.Config().UseDebugArt())
Jiyong Parke3250752024-05-17 14:56:10 +09002229 default:
2230 // TODO(b/323382414): Might add these on a case-by-case basis
2231 ctx.OtherModulePropertyErrorf(m, property, fmt.Sprintf("TODO(b/323382414): Product variable %q is not yet supported in selects", variable))
2232 return proptools.ConfigurableValueUndefined()
2233 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002234 case "soong_config_variable":
Cole Faust8afc5142024-04-26 16:30:19 -07002235 if condition.NumArgs() != 2 {
2236 ctx.OtherModulePropertyErrorf(m, property, "soong_config_variable requires 2 arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002237 return proptools.ConfigurableValueUndefined()
2238 }
Cole Faust8afc5142024-04-26 16:30:19 -07002239 namespace := condition.Arg(0)
2240 variable := condition.Arg(1)
Cole Faust02987bd2024-03-21 17:58:43 -07002241 if n, ok := ctx.Config().productVariables.VendorVars[namespace]; ok {
2242 if v, ok := n[variable]; ok {
Cole Faust46f6e2f2024-06-20 12:57:43 -07002243 ty := ""
2244 if namespaces, ok := ctx.Config().productVariables.VendorVarTypes[namespace]; ok {
2245 ty = namespaces[variable]
2246 }
2247 switch ty {
2248 case "":
2249 // strings are the default, we don't bother writing them to the soong variables json file
2250 return proptools.ConfigurableValueString(v)
2251 case "bool":
2252 return proptools.ConfigurableValueBool(v == "true")
2253 default:
2254 panic("unhandled soong config variable type: " + ty)
2255 }
2256
Cole Faust02987bd2024-03-21 17:58:43 -07002257 }
2258 }
Cole Faustfdbf5d42024-04-10 15:01:23 -07002259 return proptools.ConfigurableValueUndefined()
Cole Faustfc57d402024-04-11 12:09:44 -07002260 case "arch":
Cole Faust8afc5142024-04-26 16:30:19 -07002261 if condition.NumArgs() != 0 {
2262 ctx.OtherModulePropertyErrorf(m, property, "arch requires no arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002263 return proptools.ConfigurableValueUndefined()
2264 }
Cole Faustfc57d402024-04-11 12:09:44 -07002265 if !m.base().ArchReady() {
2266 ctx.OtherModulePropertyErrorf(m, property, "A select on arch was attempted before the arch mutator ran")
2267 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002268 }
Cole Faustfc57d402024-04-11 12:09:44 -07002269 return proptools.ConfigurableValueString(m.base().Arch().ArchType.Name)
2270 case "os":
Cole Faust8afc5142024-04-26 16:30:19 -07002271 if condition.NumArgs() != 0 {
2272 ctx.OtherModulePropertyErrorf(m, property, "os requires no arguments, found %d", condition.NumArgs())
Cole Faustfc57d402024-04-11 12:09:44 -07002273 return proptools.ConfigurableValueUndefined()
2274 }
2275 // the arch mutator runs after the os mutator, we can just use this to enforce that os is ready.
2276 if !m.base().ArchReady() {
2277 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)")
2278 return proptools.ConfigurableValueUndefined()
2279 }
2280 return proptools.ConfigurableValueString(m.base().Os().Name)
Cole Faustfdbf5d42024-04-10 15:01:23 -07002281 case "boolean_var_for_testing":
2282 // We currently don't have any other boolean variables (we should add support for typing
2283 // the soong config variables), so add this fake one for testing the boolean select
2284 // functionality.
Cole Faust8afc5142024-04-26 16:30:19 -07002285 if condition.NumArgs() != 0 {
2286 ctx.OtherModulePropertyErrorf(m, property, "boolean_var_for_testing requires 0 arguments, found %d", condition.NumArgs())
Cole Faustfdbf5d42024-04-10 15:01:23 -07002287 return proptools.ConfigurableValueUndefined()
2288 }
2289
2290 if n, ok := ctx.Config().productVariables.VendorVars["boolean_var"]; ok {
2291 if v, ok := n["for_testing"]; ok {
2292 switch v {
2293 case "true":
2294 return proptools.ConfigurableValueBool(true)
2295 case "false":
2296 return proptools.ConfigurableValueBool(false)
2297 default:
2298 ctx.OtherModulePropertyErrorf(m, property, "testing:my_boolean_var can only be true or false, found %q", v)
2299 }
2300 }
2301 }
2302 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002303 default:
Cole Faustfdbf5d42024-04-10 15:01:23 -07002304 ctx.OtherModulePropertyErrorf(m, property, "Unknown select condition %s", condition.FunctionName)
2305 return proptools.ConfigurableValueUndefined()
Cole Faust02987bd2024-03-21 17:58:43 -07002306 }
2307}
2308
Colin Crossb63d7b32023-12-07 16:54:51 -08002309// ModuleNameWithPossibleOverride returns the name of the OverrideModule that overrides the current
2310// variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule
2311// or if this variant is not overridden.
2312func ModuleNameWithPossibleOverride(ctx BaseModuleContext) string {
2313 if overridable, ok := ctx.Module().(OverridableModule); ok {
2314 if o := overridable.GetOverriddenBy(); o != "" {
2315 return o
2316 }
2317 }
2318 return ctx.ModuleName()
2319}
2320
Paul Duffine6ba0722021-07-12 20:12:12 +01002321// SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name"
2322// into the module name, or empty string if the input was not a module reference.
Colin Cross41955e82019-05-29 14:40:35 -07002323func SrcIsModule(s string) (module string) {
Paul Duffine6ba0722021-07-12 20:12:12 +01002324 if len(s) > 1 {
2325 if s[0] == ':' {
2326 module = s[1:]
2327 if !isUnqualifiedModuleName(module) {
2328 // The module name should be unqualified but is not so do not treat it as a module.
2329 module = ""
2330 }
2331 } else if s[0] == '/' && s[1] == '/' {
2332 module = s
2333 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002334 }
Paul Duffine6ba0722021-07-12 20:12:12 +01002335 return module
Colin Cross068e0fe2016-12-13 15:23:47 -08002336}
2337
Yi-Yo Chiangba9ea322021-07-15 17:18:21 +08002338// SrcIsModuleWithTag decodes module references in the format ":unqualified-name{.tag}" or
2339// "//namespace:name{.tag}" into the module name and tag, ":unqualified-name" or "//namespace:name"
2340// into the module name and an empty string for the tag, or empty strings if the input was not a
2341// module reference.
Colin Cross41955e82019-05-29 14:40:35 -07002342func SrcIsModuleWithTag(s string) (module, tag string) {
Paul Duffine6ba0722021-07-12 20:12:12 +01002343 if len(s) > 1 {
2344 if s[0] == ':' {
2345 module = s[1:]
2346 } else if s[0] == '/' && s[1] == '/' {
2347 module = s
2348 }
2349
2350 if module != "" {
2351 if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
2352 if module[len(module)-1] == '}' {
2353 tag = module[tagStart+1 : len(module)-1]
2354 module = module[:tagStart]
2355 }
2356 }
2357
2358 if s[0] == ':' && !isUnqualifiedModuleName(module) {
2359 // The module name should be unqualified but is not so do not treat it as a module.
2360 module = ""
2361 tag = ""
Colin Cross41955e82019-05-29 14:40:35 -07002362 }
2363 }
Colin Cross41955e82019-05-29 14:40:35 -07002364 }
Paul Duffine6ba0722021-07-12 20:12:12 +01002365
2366 return module, tag
2367}
2368
2369// isUnqualifiedModuleName makes sure that the supplied module is an unqualified module name, i.e.
2370// does not contain any /.
2371func isUnqualifiedModuleName(module string) bool {
2372 return strings.IndexByte(module, '/') == -1
Colin Cross068e0fe2016-12-13 15:23:47 -08002373}
2374
Paul Duffin40131a32021-07-09 17:10:35 +01002375// sourceOrOutputDependencyTag is the dependency tag added automatically by pathDepsMutator for any
2376// module reference in a property annotated with `android:"path"` or passed to ExtractSourceDeps
2377// or ExtractSourcesDeps.
2378//
2379// If uniquely identifies the dependency that was added as it contains both the module name used to
2380// add the dependency as well as the tag. That makes it very simple to find the matching dependency
2381// in GetModuleFromPathDep as all it needs to do is find the dependency whose tag matches the tag
2382// used to add it. It does not need to check that the module name as returned by one of
2383// Module.Name(), BaseModuleContext.OtherModuleName() or ModuleBase.BaseModuleName() matches the
2384// name supplied in the tag. That means it does not need to handle differences in module names
2385// caused by prebuilt_ prefix, or fully qualified module names.
Colin Cross41955e82019-05-29 14:40:35 -07002386type sourceOrOutputDependencyTag struct {
2387 blueprint.BaseDependencyTag
Yu Liu67a28422024-03-05 00:36:31 +00002388 AlwaysPropagateAconfigValidationDependencyTag
Paul Duffin40131a32021-07-09 17:10:35 +01002389
2390 // The name of the module.
2391 moduleName string
2392
mrziwangd38e63d2024-07-15 13:43:37 -07002393 // The tag that will be used to get the specific output file(s).
Colin Cross41955e82019-05-29 14:40:35 -07002394 tag string
2395}
2396
Paul Duffin40131a32021-07-09 17:10:35 +01002397func sourceOrOutputDepTag(moduleName, tag string) blueprint.DependencyTag {
2398 return sourceOrOutputDependencyTag{moduleName: moduleName, tag: tag}
Colin Cross41955e82019-05-29 14:40:35 -07002399}
2400
Paul Duffind5cf92e2021-07-09 17:38:55 +01002401// IsSourceDepTagWithOutputTag returns true if the supplied blueprint.DependencyTag is one that was
2402// used to add dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for
2403// properties tagged with `android:"path"` AND it was added using a module reference of
2404// :moduleName{outputTag}.
2405func IsSourceDepTagWithOutputTag(depTag blueprint.DependencyTag, outputTag string) bool {
2406 t, ok := depTag.(sourceOrOutputDependencyTag)
2407 return ok && t.tag == outputTag
2408}
2409
Colin Cross366938f2017-12-11 16:29:02 -08002410// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
2411// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08002412//
2413// Deprecated: tag the property with `android:"path"` instead.
Colin Cross068e0fe2016-12-13 15:23:47 -08002414func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
Nan Zhang2439eb72017-04-10 11:27:50 -07002415 set := make(map[string]bool)
2416
Colin Cross068e0fe2016-12-13 15:23:47 -08002417 for _, s := range srcFiles {
Colin Cross41955e82019-05-29 14:40:35 -07002418 if m, t := SrcIsModuleWithTag(s); m != "" {
2419 if _, found := set[s]; found {
2420 ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
Nan Zhang2439eb72017-04-10 11:27:50 -07002421 } else {
Colin Cross41955e82019-05-29 14:40:35 -07002422 set[s] = true
Paul Duffin40131a32021-07-09 17:10:35 +01002423 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
Nan Zhang2439eb72017-04-10 11:27:50 -07002424 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002425 }
2426 }
Colin Cross068e0fe2016-12-13 15:23:47 -08002427}
2428
Colin Cross366938f2017-12-11 16:29:02 -08002429// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
2430// using ":module" syntax, if any.
Colin Cross27b922f2019-03-04 22:35:41 -08002431//
2432// Deprecated: tag the property with `android:"path"` instead.
Colin Cross366938f2017-12-11 16:29:02 -08002433func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
2434 if s != nil {
Colin Cross41955e82019-05-29 14:40:35 -07002435 if m, t := SrcIsModuleWithTag(*s); m != "" {
Paul Duffin40131a32021-07-09 17:10:35 +01002436 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
Colin Cross366938f2017-12-11 16:29:02 -08002437 }
2438 }
2439}
2440
Colin Cross41955e82019-05-29 14:40:35 -07002441// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"`
2442// 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 -08002443type SourceFileProducer interface {
2444 Srcs() Paths
2445}
2446
mrziwangd38e63d2024-07-15 13:43:37 -07002447// OutputFilesForModule returns the output file paths with the given tag. On error, including if the
Colin Cross5e708052019-08-06 13:59:50 -07002448// module produced zero paths, it reports errors to the ctx and returns nil.
2449func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) Paths {
2450 paths, err := outputFilesForModule(ctx, module, tag)
2451 if err != nil {
2452 reportPathError(ctx, err)
2453 return nil
2454 }
2455 return paths
2456}
2457
mrziwangd38e63d2024-07-15 13:43:37 -07002458// OutputFileForModule returns the output file paths with the given tag. On error, including if the
Colin Cross5e708052019-08-06 13:59:50 -07002459// module produced zero or multiple paths, it reports errors to the ctx and returns nil.
2460func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) Path {
2461 paths, err := outputFilesForModule(ctx, module, tag)
2462 if err != nil {
2463 reportPathError(ctx, err)
2464 return nil
2465 }
Colin Cross14ec66c2022-10-03 21:02:27 -07002466 if len(paths) == 0 {
2467 type addMissingDependenciesIntf interface {
2468 AddMissingDependencies([]string)
2469 OtherModuleName(blueprint.Module) string
2470 }
2471 if mctx, ok := ctx.(addMissingDependenciesIntf); ok && ctx.Config().AllowMissingDependencies() {
2472 mctx.AddMissingDependencies([]string{mctx.OtherModuleName(module)})
2473 } else {
2474 ReportPathErrorf(ctx, "failed to get output files from module %q", pathContextName(ctx, module))
2475 }
2476 // Return a fake output file to avoid nil dereferences of Path objects later.
2477 // This should never get used for an actual build as the error or missing
2478 // dependency has already been reported.
2479 p, err := pathForSource(ctx, filepath.Join("missing_output_file", pathContextName(ctx, module)))
2480 if err != nil {
2481 reportPathError(ctx, err)
2482 return nil
2483 }
2484 return p
2485 }
Colin Cross5e708052019-08-06 13:59:50 -07002486 if len(paths) > 1 {
Ulya Trafimovich5ab276a2020-08-25 12:45:15 +01002487 ReportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
Colin Cross5e708052019-08-06 13:59:50 -07002488 pathContextName(ctx, module))
Colin Cross5e708052019-08-06 13:59:50 -07002489 }
2490 return paths[0]
2491}
2492
2493func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
mrziwange6c85812024-05-22 14:36:09 -07002494 outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag)
mrziwangabdb2932024-06-18 12:43:41 -07002495 if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet {
mrziwange6c85812024-05-22 14:36:09 -07002496 return outputFilesFromProvider, err
2497 }
mrziwang1ea01e32024-07-12 12:26:34 -07002498 if sourceFileProducer, ok := module.(SourceFileProducer); ok {
Colin Cross74b1e2b2020-11-22 20:23:02 -08002499 if tag != "" {
mrziwang1ea01e32024-07-12 12:26:34 -07002500 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 -08002501 }
2502 paths := sourceFileProducer.Srcs()
Colin Cross74b1e2b2020-11-22 20:23:02 -08002503 return paths, nil
Colin Cross5e708052019-08-06 13:59:50 -07002504 } else {
mrziwang68b25942024-07-11 09:58:30 -07002505 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 -07002506 }
2507}
2508
mrziwange6c85812024-05-22 14:36:09 -07002509// This method uses OutputFilesProvider for output files
2510// *inter-module-communication*.
2511// If mctx module is the same as the param module the output files are obtained
2512// from outputFiles property of module base, to avoid both setting and
mrziwang42953592024-06-20 09:53:33 -07002513// reading OutputFilesProvider before GenerateBuildActions is finished.
mrziwange6c85812024-05-22 14:36:09 -07002514// If a module doesn't have the OutputFilesProvider, nil is returned.
2515func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
mrziwangabdb2932024-06-18 12:43:41 -07002516 var outputFiles OutputFilesInfo
2517 fromProperty := false
mrziwang0cbd3b02024-06-20 16:39:25 -07002518
mrziwang1ea01e32024-07-12 12:26:34 -07002519 type OutputFilesProviderModuleContext interface {
2520 OtherModuleProviderContext
2521 Module() Module
Yu Liu876b7ce2024-08-21 18:20:13 +00002522 GetOutputFiles() OutputFilesInfo
mrziwang1ea01e32024-07-12 12:26:34 -07002523 }
2524
2525 if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx {
mrziwang0cbd3b02024-06-20 16:39:25 -07002526 if mctx.Module() != module {
mrziwangabdb2932024-06-18 12:43:41 -07002527 outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider)
mrziwang0cbd3b02024-06-20 16:39:25 -07002528 } else {
Yu Liu876b7ce2024-08-21 18:20:13 +00002529 outputFiles = mctx.GetOutputFiles()
mrziwangabdb2932024-06-18 12:43:41 -07002530 fromProperty = true
mrziwange6c85812024-05-22 14:36:09 -07002531 }
mrziwang0cbd3b02024-06-20 16:39:25 -07002532 } else if cta, isCta := ctx.(*singletonContextAdaptor); isCta {
Yu Liu663e4502024-08-12 18:23:59 +00002533 providerData, _ := cta.otherModuleProvider(module, OutputFilesProvider)
mrziwangabdb2932024-06-18 12:43:41 -07002534 outputFiles, _ = providerData.(OutputFilesInfo)
mrziwang7a47bd32024-07-17 11:11:05 -07002535 } else {
2536 return nil, fmt.Errorf("unsupported context %q in method outputFilesForModuleFromProvider", reflect.TypeOf(ctx))
mrziwang0cbd3b02024-06-20 16:39:25 -07002537 }
mrziwang0cbd3b02024-06-20 16:39:25 -07002538
mrziwangabdb2932024-06-18 12:43:41 -07002539 if outputFiles.isEmpty() {
mrziwangabdb2932024-06-18 12:43:41 -07002540 return nil, OutputFilesProviderNotSet
2541 }
2542
2543 if tag == "" {
2544 return outputFiles.DefaultOutputFiles, nil
2545 } else if taggedOutputFiles, hasTag := outputFiles.TaggedOutputFiles[tag]; hasTag {
2546 return taggedOutputFiles, nil
2547 } else {
2548 if fromProperty {
2549 return nil, fmt.Errorf("unsupported tag %q for module getting its own output files", tag)
mrziwange6c85812024-05-22 14:36:09 -07002550 } else {
mrziwang0cbd3b02024-06-20 16:39:25 -07002551 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
mrziwange6c85812024-05-22 14:36:09 -07002552 }
2553 }
mrziwange6c85812024-05-22 14:36:09 -07002554}
2555
mrziwang0cbd3b02024-06-20 16:39:25 -07002556func (o OutputFilesInfo) isEmpty() bool {
2557 return o.DefaultOutputFiles == nil && o.TaggedOutputFiles == nil
2558}
2559
mrziwange6c85812024-05-22 14:36:09 -07002560type OutputFilesInfo struct {
2561 // default output files when tag is an empty string ""
2562 DefaultOutputFiles Paths
2563
2564 // the corresponding output files for given tags
2565 TaggedOutputFiles map[string]Paths
2566}
2567
2568var OutputFilesProvider = blueprint.NewProvider[OutputFilesInfo]()
2569
mrziwangabdb2932024-06-18 12:43:41 -07002570// This is used to mark the case where OutputFilesProvider is not set on some modules.
2571var OutputFilesProviderNotSet = fmt.Errorf("No output files from provider")
2572
Colin Cross41589502020-12-01 14:00:21 -08002573// Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to
2574// specify that they can be used as a tool by a genrule module.
Colin Crossfe17f6f2019-03-28 19:30:56 -07002575type HostToolProvider interface {
Colin Crossba9e4032020-11-24 16:32:22 -08002576 Module
Colin Cross41589502020-12-01 14:00:21 -08002577 // HostToolPath returns the path to the host tool for the module if it is one, or an invalid
2578 // OptionalPath.
Colin Crossfe17f6f2019-03-28 19:30:56 -07002579 HostToolPath() OptionalPath
2580}
2581
Colin Cross463a90e2015-06-17 14:20:06 -07002582func init() {
LaMont Jones0c10e4d2023-05-16 00:58:37 +00002583 RegisterParallelSingletonType("buildtarget", BuildTargetSingleton)
Colin Cross463a90e2015-06-17 14:20:06 -07002584}
2585
Colin Cross0875c522017-11-28 17:34:01 -08002586func BuildTargetSingleton() Singleton {
Colin Cross1f8c52b2015-06-16 16:38:17 -07002587 return &buildTargetSingleton{}
2588}
2589
Colin Cross87d8b562017-04-25 10:01:55 -07002590func parentDir(dir string) string {
2591 dir, _ = filepath.Split(dir)
2592 return filepath.Clean(dir)
2593}
2594
Colin Cross1f8c52b2015-06-16 16:38:17 -07002595type buildTargetSingleton struct{}
2596
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002597func AddAncestors(ctx SingletonContext, dirMap map[string]Paths, mmName func(string) string) ([]string, []string) {
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002598 // Ensure ancestor directories are in dirMap
2599 // Make directories build their direct subdirectories
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002600 // Returns a slice of all directories and a slice of top-level directories.
Cole Faust18994c72023-02-28 16:02:16 -08002601 dirs := SortedKeys(dirMap)
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002602 for _, dir := range dirs {
2603 dir := parentDir(dir)
2604 for dir != "." && dir != "/" {
2605 if _, exists := dirMap[dir]; exists {
2606 break
2607 }
2608 dirMap[dir] = nil
2609 dir = parentDir(dir)
2610 }
2611 }
Cole Faust18994c72023-02-28 16:02:16 -08002612 dirs = SortedKeys(dirMap)
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002613 var topDirs []string
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002614 for _, dir := range dirs {
2615 p := parentDir(dir)
2616 if p != "." && p != "/" {
2617 dirMap[p] = append(dirMap[p], PathForPhony(ctx, mmName(dir)))
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002618 } else if dir != "." && dir != "/" && dir != "" {
2619 topDirs = append(topDirs, dir)
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002620 }
2621 }
Cole Faust18994c72023-02-28 16:02:16 -08002622 return SortedKeys(dirMap), topDirs
Chih-Hung Hsiehd0f82fe2021-09-05 20:15:38 -07002623}
2624
Colin Cross0875c522017-11-28 17:34:01 -08002625func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
2626 var checkbuildDeps Paths
Colin Cross1f8c52b2015-06-16 16:38:17 -07002627
Colin Crossc3d87d32020-06-04 13:25:17 -07002628 mmTarget := func(dir string) string {
2629 return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
Colin Cross87d8b562017-04-25 10:01:55 -07002630 }
2631
Colin Cross0875c522017-11-28 17:34:01 -08002632 modulesInDir := make(map[string]Paths)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002633
Colin Cross0875c522017-11-28 17:34:01 -08002634 ctx.VisitAllModules(func(module Module) {
Yu Liuddc2e1a2024-08-20 21:31:22 +00002635 info := OtherModuleProviderOrDefault(ctx, module, FinalModuleBuildTargetsProvider)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002636
Yu Liuddc2e1a2024-08-20 21:31:22 +00002637 if info.CheckbuildTarget != nil {
2638 checkbuildDeps = append(checkbuildDeps, info.CheckbuildTarget)
2639 modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.CheckbuildTarget)
Colin Cross0875c522017-11-28 17:34:01 -08002640 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07002641
Yu Liuddc2e1a2024-08-20 21:31:22 +00002642 if info.InstallTarget != nil {
2643 modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.InstallTarget)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002644 }
2645 })
2646
Dan Willemsen5ba07e82015-12-11 13:51:06 -08002647 suffix := ""
Jingwen Chencda22c92020-11-23 00:22:30 -05002648 if ctx.Config().KatiEnabled() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -08002649 suffix = "-soong"
2650 }
2651
Colin Cross1f8c52b2015-06-16 16:38:17 -07002652 // Create a top-level checkbuild target that depends on all modules
Colin Crossc3d87d32020-06-04 13:25:17 -07002653 ctx.Phony("checkbuild"+suffix, checkbuildDeps...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002654
Dan Willemsend2e95fb2017-09-20 14:30:50 -07002655 // Make will generate the MODULES-IN-* targets
Jingwen Chencda22c92020-11-23 00:22:30 -05002656 if ctx.Config().KatiEnabled() {
Dan Willemsend2e95fb2017-09-20 14:30:50 -07002657 return
2658 }
2659
Chih-Hung Hsieh80783772021-10-11 16:46:56 -07002660 dirs, _ := AddAncestors(ctx, modulesInDir, mmTarget)
Colin Cross87d8b562017-04-25 10:01:55 -07002661
Dan Willemsend2e95fb2017-09-20 14:30:50 -07002662 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and
2663 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
2664 // files.
Colin Cross1f8c52b2015-06-16 16:38:17 -07002665 for _, dir := range dirs {
Colin Crossc3d87d32020-06-04 13:25:17 -07002666 ctx.Phony(mmTarget(dir), modulesInDir[dir]...)
Colin Cross1f8c52b2015-06-16 16:38:17 -07002667 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07002668
2669 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
Jiyong Park1613e552020-09-14 19:43:17 +09002670 type osAndCross struct {
2671 os OsType
2672 hostCross bool
2673 }
2674 osDeps := map[osAndCross]Paths{}
Colin Cross0875c522017-11-28 17:34:01 -08002675 ctx.VisitAllModules(func(module Module) {
Cole Fausta963b942024-04-11 17:43:00 -07002676 if module.Enabled(ctx) {
Jiyong Park1613e552020-09-14 19:43:17 +09002677 key := osAndCross{os: module.Target().Os, hostCross: module.Target().HostCross}
Yu Liud46e5ae2024-08-15 18:46:17 +00002678 osDeps[key] = append(osDeps[key], OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).CheckbuildFiles...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07002679 }
2680 })
2681
Colin Cross0875c522017-11-28 17:34:01 -08002682 osClass := make(map[string]Paths)
Jiyong Park1613e552020-09-14 19:43:17 +09002683 for key, deps := range osDeps {
Dan Willemsen61d88b82017-09-20 17:29:08 -07002684 var className string
2685
Jiyong Park1613e552020-09-14 19:43:17 +09002686 switch key.os.Class {
Dan Willemsen61d88b82017-09-20 17:29:08 -07002687 case Host:
Jiyong Park1613e552020-09-14 19:43:17 +09002688 if key.hostCross {
2689 className = "host-cross"
2690 } else {
2691 className = "host"
2692 }
Dan Willemsen61d88b82017-09-20 17:29:08 -07002693 case Device:
2694 className = "target"
2695 default:
2696 continue
2697 }
2698
Jiyong Park1613e552020-09-14 19:43:17 +09002699 name := className + "-" + key.os.Name
Colin Crossc3d87d32020-06-04 13:25:17 -07002700 osClass[className] = append(osClass[className], PathForPhony(ctx, name))
Dan Willemsen61d88b82017-09-20 17:29:08 -07002701
Colin Crossc3d87d32020-06-04 13:25:17 -07002702 ctx.Phony(name, deps...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07002703 }
2704
2705 // Wrap those into host|host-cross|target phony rules
Cole Faust18994c72023-02-28 16:02:16 -08002706 for _, class := range SortedKeys(osClass) {
Colin Crossc3d87d32020-06-04 13:25:17 -07002707 ctx.Phony(class, osClass[class]...)
Dan Willemsen61d88b82017-09-20 17:29:08 -07002708 }
Colin Cross1f8c52b2015-06-16 16:38:17 -07002709}
Colin Crossd779da42015-12-17 18:00:23 -08002710
Brandon Lee5d45c6f2018-08-15 15:35:38 -07002711// Collect information for opening IDE project files in java/jdeps.go.
2712type IDEInfo interface {
2713 IDEInfo(ideInfo *IdeInfo)
2714 BaseModuleName() string
2715}
2716
2717// Extract the base module name from the Import name.
2718// Often the Import name has a prefix "prebuilt_".
2719// Remove the prefix explicitly if needed
2720// until we find a better solution to get the Import name.
2721type IDECustomizedModuleName interface {
2722 IDECustomizedModuleName() string
2723}
2724
2725type IdeInfo struct {
2726 Deps []string `json:"dependencies,omitempty"`
2727 Srcs []string `json:"srcs,omitempty"`
2728 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
2729 Jarjar_rules []string `json:"jarjar_rules,omitempty"`
2730 Jars []string `json:"jars,omitempty"`
2731 Classes []string `json:"class,omitempty"`
2732 Installed_paths []string `json:"installed,omitempty"`
patricktu18c82ff2019-05-10 15:48:50 +08002733 SrcJars []string `json:"srcjars,omitempty"`
bralee1fbf4402020-05-21 10:11:59 +08002734 Paths []string `json:"path,omitempty"`
Yikef6282022022-04-13 20:41:01 +08002735 Static_libs []string `json:"static_libs,omitempty"`
2736 Libs []string `json:"libs,omitempty"`
Brandon Lee5d45c6f2018-08-15 15:35:38 -07002737}
Paul Duffinf88d8e02020-05-07 20:21:34 +01002738
2739func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error {
2740 bpctx := ctx.blueprintBaseModuleContext()
2741 return blueprint.CheckBlueprintSyntax(bpctx.ModuleFactories(), filename, contents)
2742}