1// 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 15package android 16 17import ( 18 "errors" 19 "fmt" 20 "net/url" 21 "path/filepath" 22 "reflect" 23 "slices" 24 "sort" 25 "strconv" 26 "strings" 27 28 "github.com/google/blueprint" 29 "github.com/google/blueprint/depset" 30 "github.com/google/blueprint/gobtools" 31 "github.com/google/blueprint/proptools" 32) 33 34var ( 35 DeviceSharedLibrary = "shared_library" 36 DeviceStaticLibrary = "static_library" 37 jarJarPrefixHandler func(ctx ModuleContext) 38) 39 40type Module interface { 41 blueprint.Module 42 43 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions, 44 // but GenerateAndroidBuildActions also has access to Android-specific information. 45 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go 46 GenerateAndroidBuildActions(ModuleContext) 47 48 // CleanupAfterBuildActions is called after ModuleBase.GenerateBuildActions is finished. 49 // If all interactions with this module are handled via providers instead of direct access 50 // to the module then it can free memory attached to the module. 51 // This is a temporary measure to reduce memory usage, eventually blueprint's reference 52 // to the Module should be dropped after GenerateAndroidBuildActions once all accesses 53 // can be done through providers. 54 CleanupAfterBuildActions() 55 56 // Add dependencies to the components of a module, i.e. modules that are created 57 // by the module and which are considered to be part of the creating module. 58 // 59 // This is called before prebuilts are renamed so as to allow a dependency to be 60 // added directly to a prebuilt child module instead of depending on a source module 61 // and relying on prebuilt processing to switch to the prebuilt module if preferred. 62 // 63 // A dependency on a prebuilt must include the "prebuilt_" prefix. 64 ComponentDepsMutator(ctx BottomUpMutatorContext) 65 66 DepsMutator(BottomUpMutatorContext) 67 68 base() *ModuleBase 69 Disable() 70 Enabled(ctx ConfigurableEvaluatorContext) bool 71 Target() Target 72 MultiTargets() []Target 73 74 // ImageVariation returns the image variation of this module. 75 // 76 // The returned structure has its Mutator field set to "image" and its Variation field set to the 77 // image variation, e.g. recovery, ramdisk, etc.. The Variation field is "" for host modules and 78 // device modules that have no image variation. 79 ImageVariation() blueprint.Variation 80 81 Owner() string 82 InstallInData() bool 83 InstallInTestcases() bool 84 InstallInSanitizerDir() bool 85 InstallInRamdisk() bool 86 InstallInVendorRamdisk() bool 87 InstallInDebugRamdisk() bool 88 InstallInRecovery() bool 89 InstallInRoot() bool 90 InstallInOdm() bool 91 InstallInProduct() bool 92 InstallInVendor() bool 93 InstallInSystemExt() bool 94 InstallInSystemDlkm() bool 95 InstallInVendorDlkm() bool 96 InstallInOdmDlkm() bool 97 InstallForceOS() (*OsType, *ArchType) 98 PartitionTag(DeviceConfig) string 99 HideFromMake() 100 IsHideFromMake() bool 101 SkipInstall() 102 IsSkipInstall() bool 103 MakeUninstallable() 104 ReplacedByPrebuilt() 105 IsReplacedByPrebuilt() bool 106 ExportedToMake() bool 107 EffectiveLicenseFiles() Paths 108 109 AddProperties(props ...interface{}) 110 GetProperties() []interface{} 111 112 BuildParamsForTests() []BuildParams 113 RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams 114 VariablesForTests() map[string]string 115 116 // String returns a string that includes the module name and variants for printing during debugging. 117 String() string 118 119 // Get the qualified module id for this module. 120 qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName 121 122 // Get information about the properties that can contain visibility rules. 123 visibilityProperties() []visibilityProperty 124 125 RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string 126 HostRequiredModuleNames() []string 127 TargetRequiredModuleNames() []string 128 VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string 129 VintfFragments(ctx ConfigurableEvaluatorContext) []string 130 131 ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator 132 133 // The usage of this method is experimental and should not be used outside of fsgen package. 134 // This will be removed once product packaging migration to Soong is complete. 135 DecodeMultilib(ctx ConfigContext) (string, string) 136 137 // WARNING: This should not be used outside build/soong/fsgen 138 // Overrides returns the list of modules which should not be installed if this module is installed. 139 Overrides() []string 140 141 // If this is true, the module must not read product-specific configurations. 142 UseGenericConfig() bool 143} 144 145// Qualified id for a module 146type qualifiedModuleName struct { 147 // The package (i.e. directory) in which the module is defined, without trailing / 148 pkg string 149 150 // The name of the module, empty string if package. 151 name string 152} 153 154func (q qualifiedModuleName) String() string { 155 if q.name == "" { 156 return "//" + q.pkg 157 } 158 return "//" + q.pkg + ":" + q.name 159} 160 161func (q qualifiedModuleName) isRootPackage() bool { 162 return q.pkg == "" && q.name == "" 163} 164 165// Get the id for the package containing this module. 166func (q qualifiedModuleName) getContainingPackageId() qualifiedModuleName { 167 pkg := q.pkg 168 if q.name == "" { 169 if pkg == "" { 170 panic(fmt.Errorf("Cannot get containing package id of root package")) 171 } 172 173 index := strings.LastIndex(pkg, "/") 174 if index == -1 { 175 pkg = "" 176 } else { 177 pkg = pkg[:index] 178 } 179 } 180 return newPackageId(pkg) 181} 182 183func newPackageId(pkg string) qualifiedModuleName { 184 // A qualified id for a package module has no name. 185 return qualifiedModuleName{pkg: pkg, name: ""} 186} 187 188type Dist struct { 189 // Copy the output of this module to the $DIST_DIR when `dist` is specified on the 190 // command line and any of these targets are also on the command line, or otherwise 191 // built 192 Targets []string `android:"arch_variant"` 193 194 // The name of the output artifact. This defaults to the basename of the output of 195 // the module. 196 Dest *string `android:"arch_variant"` 197 198 // The directory within the dist directory to store the artifact. Defaults to the 199 // top level directory (""). 200 Dir *string `android:"arch_variant"` 201 202 // A suffix to add to the artifact file name (before any extension). 203 Suffix *string `android:"arch_variant"` 204 205 // If true, then the artifact file will be appended with _<product name>. For 206 // example, if the product is coral and the module is an android_app module 207 // of name foo, then the artifact would be foo_coral.apk. If false, there is 208 // no change to the artifact file name. 209 Append_artifact_with_product *bool `android:"arch_variant"` 210 211 // If true, then the artifact file will be prepended with <product name>-. For 212 // example, if the product is coral and the module is an android_app module 213 // of name foo, then the artifact would be coral-foo.apk. If false, there is 214 // no change to the artifact file name. 215 Prepend_artifact_with_product *bool `android:"arch_variant"` 216 217 // A string tag to select the OutputFiles associated with the tag. 218 // 219 // If no tag is specified then it will select the default dist paths provided 220 // by the module type. If a tag of "" is specified then it will return the 221 // default output files provided by the modules, i.e. the result of calling 222 // OutputFiles(""). 223 Tag *string `android:"arch_variant"` 224} 225 226// NamedPath associates a path with a name. e.g. a license text path with a package name 227type NamedPath struct { 228 Path Path 229 Name string 230} 231 232// String returns an escaped string representing the `NamedPath`. 233func (p NamedPath) String() string { 234 if len(p.Name) > 0 { 235 return p.Path.String() + ":" + url.QueryEscape(p.Name) 236 } 237 return p.Path.String() 238} 239 240// NamedPaths describes a list of paths each associated with a name. 241type NamedPaths []NamedPath 242 243// Strings returns a list of escaped strings representing each `NamedPath` in the list. 244func (l NamedPaths) Strings() []string { 245 result := make([]string, 0, len(l)) 246 for _, p := range l { 247 result = append(result, p.String()) 248 } 249 return result 250} 251 252// SortedUniqueNamedPaths modifies `l` in place to return the sorted unique subset. 253func SortedUniqueNamedPaths(l NamedPaths) NamedPaths { 254 if len(l) == 0 { 255 return l 256 } 257 sort.Slice(l, func(i, j int) bool { 258 return l[i].String() < l[j].String() 259 }) 260 k := 0 261 for i := 1; i < len(l); i++ { 262 if l[i].String() == l[k].String() { 263 continue 264 } 265 k++ 266 if k < i { 267 l[k] = l[i] 268 } 269 } 270 return l[:k+1] 271} 272 273type nameProperties struct { 274 // The name of the module. Must be unique across all modules. 275 Name *string 276} 277 278// Properties common to all modules inheriting from ModuleBase. These properties are automatically 279// inherited by sub-modules created with ctx.CreateModule() 280type commonProperties struct { 281 // emit build rules for this module 282 // 283 // Disabling a module should only be done for those modules that cannot be built 284 // in the current environment. Modules that can build in the current environment 285 // but are not usually required (e.g. superceded by a prebuilt) should not be 286 // disabled as that will prevent them from being built by the checkbuild target 287 // and so prevent early detection of changes that have broken those modules. 288 Enabled proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"` 289 290 // Controls the visibility of this module to other modules. Allowable values are one or more of 291 // these formats: 292 // 293 // ["//visibility:public"]: Anyone can use this module. 294 // ["//visibility:private"]: Only rules in the module's package (not its subpackages) can use 295 // this module. 296 // ["//visibility:override"]: Discards any rules inherited from defaults or a creating module. 297 // Can only be used at the beginning of a list of visibility rules. 298 // ["//some/package:__pkg__", "//other/package:__pkg__"]: Only modules in some/package and 299 // other/package (defined in some/package/*.bp and other/package/*.bp) have access to 300 // this module. Note that sub-packages do not have access to the rule; for example, 301 // //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__ 302 // is a special module and must be used verbatim. It represents all of the modules in the 303 // package. 304 // ["//project:__subpackages__", "//other:__subpackages__"]: Only modules in packages project 305 // or other or in one of their sub-packages have access to this module. For example, 306 // //project:rule, //project/library:lib or //other/testing/internal:munge are allowed 307 // to depend on this rule (but not //independent:evil) 308 // ["//project"]: This is shorthand for ["//project:__pkg__"] 309 // [":__subpackages__"]: This is shorthand for ["//project:__subpackages__"] where 310 // //project is the module's package. e.g. using [":__subpackages__"] in 311 // packages/apps/Settings/Android.bp is equivalent to 312 // //packages/apps/Settings:__subpackages__. 313 // ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public 314 // for now. It is an error if it is used in a module. 315 // 316 // If a module does not specify the `visibility` property then it uses the 317 // `default_visibility` property of the `package` module in the module's package. 318 // 319 // If the `default_visibility` property is not set for the module's package then 320 // it will use the `default_visibility` of its closest ancestor package for which 321 // a `default_visibility` property is specified. 322 // 323 // If no `default_visibility` property can be found then the module uses the 324 // global default of `//visibility:legacy_public`. 325 // 326 // The `visibility` property has no effect on a defaults module although it does 327 // apply to any non-defaults module that uses it. To set the visibility of a 328 // defaults module, use the `defaults_visibility` property on the defaults module; 329 // not to be confused with the `default_visibility` property on the package module. 330 // 331 // See https://android.googlesource.com/platform/build/soong/+/main/README.md#visibility for 332 // more details. 333 Visibility []string 334 335 // Describes the licenses applicable to this module. Must reference license modules. 336 Licenses []string 337 338 // Override of module name when reporting licenses 339 Effective_package_name *string `blueprint:"mutated"` 340 // Notice files 341 Effective_license_text NamedPaths `blueprint:"mutated"` 342 // License names 343 Effective_license_kinds []string `blueprint:"mutated"` 344 // License conditions 345 Effective_license_conditions []string `blueprint:"mutated"` 346 347 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values 348 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both 349 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit 350 // platform). 351 Compile_multilib *string `android:"arch_variant"` 352 353 Target struct { 354 Host struct { 355 Compile_multilib *string 356 } 357 Android struct { 358 Compile_multilib *string 359 Enabled *bool 360 } 361 } 362 363 // If set to true then the archMutator will create variants for each arch specific target 364 // (e.g. 32/64) that the module is required to produce. If set to false then it will only 365 // create a variant for the architecture and will list the additional arch specific targets 366 // that the variant needs to produce in the CompileMultiTargets property. 367 UseTargetVariants bool `blueprint:"mutated"` 368 Default_multilib string `blueprint:"mutated"` 369 370 // whether this is a proprietary vendor module, and should be installed into /vendor 371 Proprietary *bool 372 373 // vendor who owns this module 374 Owner *string 375 376 // whether this module is specific to an SoC (System-On-a-Chip). When set to true, 377 // it is installed into /vendor (or /system/vendor if vendor partition does not exist). 378 // Use `soc_specific` instead for better meaning. 379 Vendor *bool 380 381 // whether this module is specific to an SoC (System-On-a-Chip). When set to true, 382 // it is installed into /vendor (or /system/vendor if vendor partition does not exist). 383 Soc_specific *bool 384 385 // whether this module is specific to a device, not only for SoC, but also for off-chip 386 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition 387 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist). 388 // This implies `soc_specific:true`. 389 Device_specific *bool 390 391 // whether this module is specific to a software configuration of a product (e.g. country, 392 // network operator, etc). When set to true, it is installed into /product (or 393 // /system/product if product partition does not exist). 394 Product_specific *bool 395 396 // whether this module extends system. When set to true, it is installed into /system_ext 397 // (or /system/system_ext if system_ext partition does not exist). 398 System_ext_specific *bool 399 400 // Whether this module is installed to recovery partition 401 Recovery *bool 402 403 // Whether this module is installed to ramdisk 404 Ramdisk *bool 405 406 // Whether this module is installed to vendor ramdisk 407 Vendor_ramdisk *bool 408 409 // Whether this module is installed to debug ramdisk 410 Debug_ramdisk *bool 411 412 // Install to partition system_dlkm when set to true. 413 System_dlkm_specific *bool 414 415 // Install to partition vendor_dlkm when set to true. 416 Vendor_dlkm_specific *bool 417 418 // Install to partition odm_dlkm when set to true. 419 Odm_dlkm_specific *bool 420 421 // Whether this module is built for non-native architectures (also known as native bridge binary) 422 Native_bridge_supported *bool `android:"arch_variant"` 423 424 // init.rc files to be installed if this module is installed 425 Init_rc proptools.Configurable[[]string] `android:"arch_variant,path"` 426 427 // VINTF manifest fragments to be installed if this module is installed 428 Vintf_fragments proptools.Configurable[[]string] `android:"path"` 429 430 // The OsType of artifacts that this module variant is responsible for creating. 431 // 432 // Set by osMutator 433 CompileOS OsType `blueprint:"mutated"` 434 435 // Set to true after the arch mutator has run on this module and set CompileTarget, 436 // CompileMultiTargets, and CompilePrimary 437 ArchReady bool `blueprint:"mutated"` 438 439 // The Target of artifacts that this module variant is responsible for creating. 440 // 441 // Set by archMutator 442 CompileTarget Target `blueprint:"mutated"` 443 444 // The additional arch specific targets (e.g. 32/64 bit) that this module variant is 445 // responsible for creating. 446 // 447 // By default this is nil as, where necessary, separate variants are created for the 448 // different multilib types supported and that information is encapsulated in the 449 // CompileTarget so the module variant simply needs to create artifacts for that. 450 // 451 // However, if UseTargetVariants is set to false (e.g. by 452 // InitAndroidMultiTargetsArchModule) then no separate variants are created for the 453 // multilib targets. Instead a single variant is created for the architecture and 454 // this contains the multilib specific targets that this variant should create. 455 // 456 // Set by archMutator 457 CompileMultiTargets []Target `blueprint:"mutated"` 458 459 // True if the module variant's CompileTarget is the primary target 460 // 461 // Set by archMutator 462 CompilePrimary bool `blueprint:"mutated"` 463 464 // Set by InitAndroidModule 465 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"` 466 ArchSpecific bool `blueprint:"mutated"` 467 468 // If set to true then a CommonOS variant will be created which will have dependencies 469 // on all its OsType specific variants. Used by sdk/module_exports to create a snapshot 470 // that covers all os and architecture variants. 471 // 472 // The OsType specific variants can be retrieved by calling 473 // GetOsSpecificVariantsOfCommonOSVariant 474 // 475 // Set at module initialization time by calling InitCommonOSAndroidMultiTargetsArchModule 476 CreateCommonOSVariant bool `blueprint:"mutated"` 477 478 // When set to true, this module is not installed to the full install path (ex: under 479 // out/target/product/<name>/<partition>). It can be installed only to the packaging 480 // modules like android_filesystem. 481 No_full_install *bool 482 483 // When HideFromMake is set to true, no entry for this variant will be emitted in the 484 // generated Android.mk file. 485 HideFromMake bool `blueprint:"mutated"` 486 487 // When SkipInstall is set to true, calls to ctx.InstallFile, ctx.InstallExecutable, 488 // ctx.InstallSymlink and ctx.InstallAbsoluteSymlink act like calls to ctx.PackageFile 489 // and don't create a rule to install the file. 490 SkipInstall bool `blueprint:"mutated"` 491 492 // UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex 493 // mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant 494 // is used to avoid adding install or packaging dependencies into libraries provided 495 // by apexes. 496 UninstallableApexPlatformVariant bool `blueprint:"mutated"` 497 498 // Whether the module has been replaced by a prebuilt 499 ReplacedByPrebuilt bool `blueprint:"mutated"` 500 501 // Disabled by mutators. If set to true, it overrides Enabled property. 502 ForcedDisabled bool `blueprint:"mutated"` 503 504 NamespaceExportedToMake bool `blueprint:"mutated"` 505 506 MissingDeps []string `blueprint:"mutated"` 507 CheckedMissingDeps bool `blueprint:"mutated"` 508 509 // Name and variant strings stored by mutators to enable Module.String() 510 DebugName string `blueprint:"mutated"` 511 DebugMutators []string `blueprint:"mutated"` 512 DebugVariations []string `blueprint:"mutated"` 513 514 // ImageVariation is set by ImageMutator to specify which image this variation is for, 515 // for example "" for core or "recovery" for recovery. It will often be set to one of the 516 // constants in image.go, but can also be set to a custom value by individual module types. 517 ImageVariation string `blueprint:"mutated"` 518 519 // The team (defined by the owner/vendor) who owns the property. 520 Team *string `android:"path"` 521 522 // vintf_fragment Modules required from this module. 523 Vintf_fragment_modules proptools.Configurable[[]string] `android:"path"` 524 525 // List of module names that are prevented from being installed when this module gets 526 // installed. 527 Overrides []string 528 529 // Set to true if this module must be generic and does not require product-specific information. 530 // To be included in the system image, this property must be set to true. 531 Use_generic_config *bool 532} 533 534// Properties common to all modules inheriting from ModuleBase. Unlike commonProperties, these 535// properties are NOT automatically inherited by sub-modules created with ctx.CreateModule() 536type baseProperties struct { 537 // names of other modules to install if this module is installed 538 Required proptools.Configurable[[]string] `android:"arch_variant"` 539 540 // names of other modules to install on host if this module is installed 541 Host_required []string `android:"arch_variant"` 542 543 // names of other modules to install on target if this module is installed 544 Target_required []string `android:"arch_variant"` 545 546 // If this is a soong config module, this property will be set to the name of the original 547 // module type. This is used by neverallow to ensure you can't bypass a ModuleType() matcher 548 // just by creating a soong config module type. 549 Soong_config_base_module_type *string `blueprint:"mutated"` 550} 551 552type distProperties struct { 553 // configuration to distribute output files from this module to the distribution 554 // directory (default: $OUT/dist, configurable with $DIST_DIR) 555 Dist Dist `android:"arch_variant"` 556 557 // a list of configurations to distribute output files from this module to the 558 // distribution directory (default: $OUT/dist, configurable with $DIST_DIR) 559 Dists []Dist `android:"arch_variant"` 560} 561 562type TeamDepTagType struct { 563 blueprint.BaseDependencyTag 564} 565 566var teamDepTag = TeamDepTagType{} 567 568// Dependency tag for required, host_required, and target_required modules. 569var RequiredDepTag = struct { 570 blueprint.BaseDependencyTag 571 InstallAlwaysNeededDependencyTag 572 // Requiring disabled module has been supported (as a side effect of this being implemented 573 // in Make). We may want to make it an error, but for now, let's keep the existing behavior. 574 AlwaysAllowDisabledModuleDependencyTag 575}{} 576 577// CommonTestOptions represents the common `test_options` properties in 578// Android.bp. 579type CommonTestOptions struct { 580 // If the test is a hostside (no device required) unittest that shall be run 581 // during presubmit check. 582 Unit_test *bool 583 584 // Tags provide additional metadata to customize test execution by downstream 585 // test runners. The tags have no special meaning to Soong. 586 Tags []string 587} 588 589// SetAndroidMkEntries sets AndroidMkEntries according to the value of base 590// `test_options`. 591func (t *CommonTestOptions) SetAndroidMkEntries(entries *AndroidMkEntries) { 592 entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test)) 593 if len(t.Tags) > 0 { 594 entries.AddStrings("LOCAL_TEST_OPTIONS_TAGS", t.Tags...) 595 } 596} 597 598func (t *CommonTestOptions) SetAndroidMkInfoEntries(entries *AndroidMkInfo) { 599 entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test)) 600 if len(t.Tags) > 0 { 601 entries.AddStrings("LOCAL_TEST_OPTIONS_TAGS", t.Tags...) 602 } 603} 604 605// The key to use in TaggedDistFiles when a Dist structure does not specify a 606// tag property. This intentionally does not use "" as the default because that 607// would mean that an empty tag would have a different meaning when used in a dist 608// structure that when used to reference a specific set of output paths using the 609// :module{tag} syntax, which passes tag to the OutputFiles(tag) method. 610const DefaultDistTag = "<default-dist-tag>" 611 612// A map of OutputFile tag keys to Paths, for disting purposes. 613type TaggedDistFiles map[string]Paths 614 615// addPathsForTag adds a mapping from the tag to the paths. If the map is nil 616// then it will create a map, update it and then return it. If a mapping already 617// exists for the tag then the paths are appended to the end of the current list 618// of paths, ignoring any duplicates. 619func (t TaggedDistFiles) addPathsForTag(tag string, paths ...Path) TaggedDistFiles { 620 if t == nil { 621 t = make(TaggedDistFiles) 622 } 623 624 for _, distFile := range paths { 625 if distFile != nil && !t[tag].containsPath(distFile) { 626 t[tag] = append(t[tag], distFile) 627 } 628 } 629 630 return t 631} 632 633// merge merges the entries from the other TaggedDistFiles object into this one. 634// If the TaggedDistFiles is nil then it will create a new instance, merge the 635// other into it, and then return it. 636func (t TaggedDistFiles) merge(other TaggedDistFiles) TaggedDistFiles { 637 for tag, paths := range other { 638 t = t.addPathsForTag(tag, paths...) 639 } 640 641 return t 642} 643 644type hostAndDeviceProperties struct { 645 // If set to true, build a variant of the module for the host. Defaults to false. 646 Host_supported *bool 647 648 // If set to true, build a variant of the module for the device. Defaults to true. 649 Device_supported *bool 650} 651 652type hostCrossProperties struct { 653 // If set to true, build a variant of the module for the host cross. Defaults to true. 654 Host_cross_supported *bool 655} 656 657type Multilib string 658 659const ( 660 MultilibBoth Multilib = "both" 661 MultilibFirst Multilib = "first" 662 MultilibCommon Multilib = "common" 663) 664 665type HostOrDeviceSupported int 666 667const ( 668 hostSupported = 1 << iota 669 hostCrossSupported 670 deviceSupported 671 hostDefault 672 deviceDefault 673 674 // Host and HostCross are built by default. Device is not supported. 675 HostSupported = hostSupported | hostCrossSupported | hostDefault 676 677 // Host is built by default. HostCross and Device are not supported. 678 HostSupportedNoCross = hostSupported | hostDefault 679 680 // Device is built by default. Host and HostCross are not supported. 681 DeviceSupported = deviceSupported | deviceDefault 682 683 // By default, _only_ device variant is built. Device variant can be disabled with `device_supported: false` 684 // Host and HostCross are disabled by default and can be enabled with `host_supported: true` 685 HostAndDeviceSupported = hostSupported | hostCrossSupported | deviceSupported | deviceDefault 686 687 // Host, HostCross, and Device are built by default. 688 // Building Device can be disabled with `device_supported: false` 689 // Building Host and HostCross can be disabled with `host_supported: false` 690 HostAndDeviceDefault = hostSupported | hostCrossSupported | hostDefault | 691 deviceSupported | deviceDefault 692 693 // Nothing is supported. This is not exposed to the user, but used to mark a 694 // host only module as unsupported when the module type is not supported on 695 // the host OS. E.g. benchmarks are supported on Linux but not Darwin. 696 NeitherHostNorDeviceSupported = 0 697) 698 699type moduleKind int 700 701const ( 702 platformModule moduleKind = iota 703 deviceSpecificModule 704 socSpecificModule 705 productSpecificModule 706 systemExtSpecificModule 707) 708 709func (k moduleKind) String() string { 710 switch k { 711 case platformModule: 712 return "platform" 713 case deviceSpecificModule: 714 return "device-specific" 715 case socSpecificModule: 716 return "soc-specific" 717 case productSpecificModule: 718 return "product-specific" 719 case systemExtSpecificModule: 720 return "systemext-specific" 721 default: 722 panic(fmt.Errorf("unknown module kind %d", k)) 723 } 724} 725 726func initAndroidModuleBase(m Module) { 727 m.base().module = m 728} 729 730// InitAndroidModule initializes the Module as an Android module that is not architecture-specific. 731// It adds the common properties, for example "name" and "enabled". 732func InitAndroidModule(m Module) { 733 initAndroidModuleBase(m) 734 base := m.base() 735 736 m.AddProperties( 737 &base.nameProperties, 738 &base.commonProperties, 739 &base.baseProperties, 740 &base.distProperties) 741 742 initProductVariableModule(m) 743 744 // The default_visibility property needs to be checked and parsed by the visibility module during 745 // its checking and parsing phases so make it the primary visibility property. 746 setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility) 747 748 // The default_applicable_licenses property needs to be checked and parsed by the licenses module during 749 // its checking and parsing phases so make it the primary licenses property. 750 setPrimaryLicensesProperty(m, "licenses", &base.commonProperties.Licenses) 751} 752 753// InitAndroidArchModule initializes the Module as an Android module that is architecture-specific. 754// It adds the common properties, for example "name" and "enabled", as well as runtime generated 755// property structs for architecture-specific versions of generic properties tagged with 756// `android:"arch_variant"`. 757// 758// InitAndroidModule should not be called if InitAndroidArchModule was called. 759func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) { 760 InitAndroidModule(m) 761 762 base := m.base() 763 base.commonProperties.HostOrDeviceSupported = hod 764 base.commonProperties.Default_multilib = string(defaultMultilib) 765 base.commonProperties.ArchSpecific = true 766 base.commonProperties.UseTargetVariants = true 767 768 if hod&hostSupported != 0 && hod&deviceSupported != 0 { 769 m.AddProperties(&base.hostAndDeviceProperties) 770 } 771 772 if hod&hostCrossSupported != 0 { 773 m.AddProperties(&base.hostCrossProperties) 774 } 775 776 initArchModule(m) 777} 778 779// InitAndroidMultiTargetsArchModule initializes the Module as an Android module that is 780// architecture-specific, but will only have a single variant per OS that handles all the 781// architectures simultaneously. The list of Targets that it must handle will be available from 782// ModuleContext.MultiTargets. It adds the common properties, for example "name" and "enabled", as 783// well as runtime generated property structs for architecture-specific versions of generic 784// properties tagged with `android:"arch_variant"`. 785// 786// InitAndroidModule or InitAndroidArchModule should not be called if 787// InitAndroidMultiTargetsArchModule was called. 788func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) { 789 InitAndroidArchModule(m, hod, defaultMultilib) 790 m.base().commonProperties.UseTargetVariants = false 791} 792 793// InitCommonOSAndroidMultiTargetsArchModule initializes the Module as an Android module that is 794// architecture-specific, but will only have a single variant per OS that handles all the 795// architectures simultaneously, and will also have an additional CommonOS variant that has 796// dependencies on all the OS-specific variants. The list of Targets that it must handle will be 797// available from ModuleContext.MultiTargets. It adds the common properties, for example "name" and 798// "enabled", as well as runtime generated property structs for architecture-specific versions of 799// generic properties tagged with `android:"arch_variant"`. 800// 801// InitAndroidModule, InitAndroidArchModule or InitAndroidMultiTargetsArchModule should not be 802// called if InitCommonOSAndroidMultiTargetsArchModule was called. 803func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) { 804 InitAndroidArchModule(m, hod, defaultMultilib) 805 m.base().commonProperties.UseTargetVariants = false 806 m.base().commonProperties.CreateCommonOSVariant = true 807} 808 809// A ModuleBase object contains the properties that are common to all Android 810// modules. It should be included as an anonymous field in every module 811// struct definition. InitAndroidModule should then be called from the module's 812// factory function, and the return values from InitAndroidModule should be 813// returned from the factory function. 814// 815// The ModuleBase type is responsible for implementing the GenerateBuildActions 816// method to support the blueprint.Module interface. This method will then call 817// the module's GenerateAndroidBuildActions method once for each build variant 818// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext 819// rather than the usual blueprint.ModuleContext. 820// ModuleContext exposes extra functionality specific to the Android build 821// system including details about the particular build variant that is to be 822// generated. 823// 824// For example: 825// 826// import ( 827// "android/soong/android" 828// ) 829// 830// type myModule struct { 831// android.ModuleBase 832// properties struct { 833// MyProperty string 834// } 835// } 836// 837// func NewMyModule() android.Module { 838// m := &myModule{} 839// m.AddProperties(&m.properties) 840// android.InitAndroidModule(m) 841// return m 842// } 843// 844// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { 845// // Get the CPU architecture for the current build variant. 846// variantArch := ctx.Arch() 847// 848// // ... 849// } 850type ModuleBase struct { 851 // Putting the curiously recurring thing pointing to the thing that contains 852 // the thing pattern to good use. 853 // TODO: remove this 854 module Module 855 856 nameProperties nameProperties 857 commonProperties commonProperties 858 baseProperties baseProperties 859 distProperties distProperties 860 variableProperties interface{} 861 hostAndDeviceProperties hostAndDeviceProperties 862 hostCrossProperties hostCrossProperties 863 864 // Arch specific versions of structs in GetProperties() prior to 865 // initialization in InitAndroidArchModule, lets call it `generalProperties`. 866 // The outer index has the same order as generalProperties and the inner index 867 // chooses the props specific to the architecture. The interface{} value is an 868 // archPropRoot that is filled with arch specific values by the arch mutator. 869 archProperties [][]interface{} 870 871 // Information about all the properties on the module that contains visibility rules that need 872 // checking. 873 visibilityPropertyInfo []visibilityProperty 874 875 // The primary visibility property, may be nil, that controls access to the module. 876 primaryVisibilityProperty visibilityProperty 877 878 // The primary licenses property, may be nil, records license metadata for the module. 879 primaryLicensesProperty applicableLicensesProperty 880 881 noAddressSanitizer bool 882 883 hooks hooks 884 885 registerProps []interface{} 886 887 // For tests 888 buildParams []BuildParams 889 ruleParams map[blueprint.Rule]blueprint.RuleParams 890 variables map[string]string 891} 892 893func (m *ModuleBase) AddJSONData(d *map[string]interface{}) { 894 (*d)["Android"] = map[string]interface{}{ 895 // Properties set in Blueprint or in blueprint of a defaults modules 896 "SetProperties": m.propertiesWithValues(), 897 } 898} 899 900type propInfo struct { 901 Name string 902 Type string 903 Value string 904 Values []string 905} 906 907func (m *ModuleBase) propertiesWithValues() []propInfo { 908 var info []propInfo 909 props := m.GetProperties() 910 911 var propsWithValues func(name string, v reflect.Value) 912 propsWithValues = func(name string, v reflect.Value) { 913 kind := v.Kind() 914 switch kind { 915 case reflect.Ptr, reflect.Interface: 916 if v.IsNil() { 917 return 918 } 919 propsWithValues(name, v.Elem()) 920 case reflect.Struct: 921 if v.IsZero() { 922 return 923 } 924 for i := 0; i < v.NumField(); i++ { 925 namePrefix := name 926 sTyp := v.Type().Field(i) 927 if proptools.ShouldSkipProperty(sTyp) { 928 continue 929 } 930 if name != "" && !strings.HasSuffix(namePrefix, ".") { 931 namePrefix += "." 932 } 933 if !proptools.IsEmbedded(sTyp) { 934 namePrefix += sTyp.Name 935 } 936 sVal := v.Field(i) 937 propsWithValues(namePrefix, sVal) 938 } 939 case reflect.Array, reflect.Slice: 940 if v.IsNil() { 941 return 942 } 943 elKind := v.Type().Elem().Kind() 944 info = append(info, propInfo{Name: name, Type: elKind.String() + " " + kind.String(), Values: sliceReflectionValue(v)}) 945 default: 946 info = append(info, propInfo{Name: name, Type: kind.String(), Value: reflectionValue(v)}) 947 } 948 } 949 950 for _, p := range props { 951 propsWithValues("", reflect.ValueOf(p).Elem()) 952 } 953 sort.Slice(info, func(i, j int) bool { 954 return info[i].Name < info[j].Name 955 }) 956 return info 957} 958 959func reflectionValue(value reflect.Value) string { 960 switch value.Kind() { 961 case reflect.Bool: 962 return fmt.Sprintf("%t", value.Bool()) 963 case reflect.Int64: 964 return fmt.Sprintf("%d", value.Int()) 965 case reflect.String: 966 return fmt.Sprintf("%s", value.String()) 967 case reflect.Struct: 968 if value.IsZero() { 969 return "{}" 970 } 971 length := value.NumField() 972 vals := make([]string, length, length) 973 for i := 0; i < length; i++ { 974 sTyp := value.Type().Field(i) 975 if proptools.ShouldSkipProperty(sTyp) { 976 continue 977 } 978 name := sTyp.Name 979 vals[i] = fmt.Sprintf("%s: %s", name, reflectionValue(value.Field(i))) 980 } 981 return fmt.Sprintf("%s{%s}", value.Type(), strings.Join(vals, ", ")) 982 case reflect.Array, reflect.Slice: 983 vals := sliceReflectionValue(value) 984 return fmt.Sprintf("[%s]", strings.Join(vals, ", ")) 985 } 986 return "" 987} 988 989func sliceReflectionValue(value reflect.Value) []string { 990 length := value.Len() 991 vals := make([]string, length, length) 992 for i := 0; i < length; i++ { 993 vals[i] = reflectionValue(value.Index(i)) 994 } 995 return vals 996} 997 998func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {} 999 1000func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {} 1001 1002func (m *ModuleBase) baseDepsMutator(ctx BottomUpMutatorContext) { 1003 if m.Team() != "" { 1004 ctx.AddDependency(ctx.Module(), teamDepTag, m.Team()) 1005 } 1006 1007 // TODO(jiyong): remove below case. This is to work around build errors happening 1008 // on branches with reduced manifest like aosp_kernel-build-tools. 1009 // In the branch, a build error occurs as follows. 1010 // 1. aosp_kernel-build-tools is a reduced manifest branch. It doesn't have some git 1011 // projects like external/bouncycastle 1012 // 2. `boot_signer` is `required` by modules like `build_image` which is explicitly list as 1013 // the top-level build goal (in the shell file that invokes Soong). 1014 // 3. `boot_signer` depends on `bouncycastle-unbundled` which is in the missing git project. 1015 // 4. aosp_kernel-build-tools invokes soong with `--soong-only`. Therefore, the absence of 1016 // ALLOW_MISSING_DEPENDENCIES didn't cause a problem, as previously only make processed required 1017 // dependencies. 1018 // 5. Now, since Soong understands `required` deps, it tries to build `boot_signer` and the 1019 // absence of external/bouncycastle fails the build. 1020 // 1021 // Unfortunately, there's no way for Soong to correctly determine if it's running in a 1022 // reduced manifest branch. Instead, here, we use the absence of DeviceArch or DeviceName as 1023 // a strong signal, because that's very common across reduced manifest branches. 1024 pv := ctx.Config().productVariables 1025 fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil 1026 if fullManifest { 1027 addVintfFragmentDeps(ctx) 1028 } 1029} 1030 1031// required property can be overridden too; handle it separately 1032func (m *ModuleBase) baseOverridablePropertiesDepsMutator(ctx BottomUpMutatorContext) { 1033 pv := ctx.Config().productVariables 1034 fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil 1035 if fullManifest { 1036 addRequiredDeps(ctx) 1037 } 1038} 1039 1040// addRequiredDeps adds required, target_required, and host_required as dependencies. 1041func addRequiredDeps(ctx BottomUpMutatorContext) { 1042 addDep := func(target Target, depName string) { 1043 if !ctx.OtherModuleExists(depName) { 1044 if ctx.Config().AllowMissingDependencies() { 1045 return 1046 } 1047 } 1048 1049 // If Android native module requires another Android native module, ensure that 1050 // they have the same bitness. This mimics the policy in select-bitness-of-required-modules 1051 // in build/make/core/main.mk. 1052 // TODO(jiyong): the Make-side does this only when the required module is a shared 1053 // library or a native test. 1054 bothInAndroid := ctx.Device() && target.Os.Class == Device 1055 nativeArch := InList(ctx.Arch().ArchType.Multilib, []string{"lib32", "lib64"}) && 1056 InList(target.Arch.ArchType.Multilib, []string{"lib32", "lib64"}) 1057 sameBitness := ctx.Arch().ArchType.Multilib == target.Arch.ArchType.Multilib 1058 if bothInAndroid && nativeArch && !sameBitness { 1059 return 1060 } 1061 1062 // ... also don't make a dependency between native bridge arch and non-native bridge 1063 // arches. b/342945184 1064 if ctx.Target().NativeBridge != target.NativeBridge { 1065 return 1066 } 1067 1068 variation := target.Variations() 1069 if ctx.OtherModuleFarDependencyVariantExists(variation, depName) { 1070 ctx.AddFarVariationDependencies(variation, RequiredDepTag, depName) 1071 } 1072 } 1073 1074 var deviceTargets []Target 1075 deviceTargets = append(deviceTargets, ctx.Config().Targets[Android]...) 1076 deviceTargets = append(deviceTargets, ctx.Config().AndroidCommonTarget) 1077 1078 var hostTargets []Target 1079 hostTargets = append(hostTargets, ctx.Config().Targets[ctx.Config().BuildOS]...) 1080 hostTargets = append(hostTargets, ctx.Config().BuildOSCommonTarget) 1081 1082 if ctx.Device() { 1083 for _, depName := range append(ctx.Module().RequiredModuleNames(ctx), ctx.Module().VintfFragmentModuleNames(ctx)...) { 1084 for _, target := range deviceTargets { 1085 addDep(target, depName) 1086 } 1087 } 1088 for _, depName := range ctx.Module().HostRequiredModuleNames() { 1089 for _, target := range hostTargets { 1090 addDep(target, depName) 1091 } 1092 } 1093 } 1094 1095 if ctx.Host() { 1096 for _, depName := range append(ctx.Module().RequiredModuleNames(ctx), ctx.Module().VintfFragmentModuleNames(ctx)...) { 1097 for _, target := range hostTargets { 1098 // When a host module requires another host module, don't make a 1099 // dependency if they have different OSes (i.e. hostcross). 1100 if ctx.Target().HostCross != target.HostCross { 1101 continue 1102 } 1103 addDep(target, depName) 1104 } 1105 } 1106 for _, depName := range ctx.Module().TargetRequiredModuleNames() { 1107 for _, target := range deviceTargets { 1108 addDep(target, depName) 1109 } 1110 } 1111 } 1112} 1113 1114var vintfDepTag = struct { 1115 blueprint.BaseDependencyTag 1116 InstallAlwaysNeededDependencyTag 1117}{} 1118 1119func IsVintfDepTag(depTag blueprint.DependencyTag) bool { 1120 return depTag == vintfDepTag 1121} 1122 1123func addVintfFragmentDeps(ctx BottomUpMutatorContext) { 1124 // Vintf manifests in the recovery partition will be ignored. 1125 if !ctx.Device() || ctx.Module().InstallInRecovery() { 1126 return 1127 } 1128 1129 deviceConfig := ctx.DeviceConfig() 1130 1131 mod := ctx.Module() 1132 vintfModules := ctx.AddDependency(mod, vintfDepTag, mod.VintfFragmentModuleNames(ctx)...) 1133 1134 modPartition := mod.PartitionTag(deviceConfig) 1135 for _, vintf := range vintfModules { 1136 if vintf == nil { 1137 // TODO(b/372091092): Remove this. Having it gives us missing dependency errors instead 1138 // of nil pointer dereference errors, but we should resolve the missing dependencies. 1139 continue 1140 } 1141 if vintfModule, ok := vintf.(*VintfFragmentModule); ok { 1142 vintfPartition := vintfModule.PartitionTag(deviceConfig) 1143 if modPartition != vintfPartition { 1144 ctx.ModuleErrorf("Module %q(%q) and Vintf_fragment %q(%q) are installed to different partitions.", 1145 mod.Name(), modPartition, 1146 vintfModule.Name(), vintfPartition) 1147 } 1148 } else { 1149 ctx.ModuleErrorf("Only vintf_fragment type module should be listed in vintf_fragment_modules : %q", vintf.Name()) 1150 } 1151 } 1152} 1153 1154// AddProperties "registers" the provided props 1155// each value in props MUST be a pointer to a struct 1156func (m *ModuleBase) AddProperties(props ...interface{}) { 1157 m.registerProps = append(m.registerProps, props...) 1158} 1159 1160func (m *ModuleBase) GetProperties() []interface{} { 1161 return m.registerProps 1162} 1163 1164func (m *ModuleBase) BuildParamsForTests() []BuildParams { 1165 // Expand the references to module variables like $flags[0-9]*, 1166 // so we do not need to change many existing unit tests. 1167 // This looks like undoing the shareFlags optimization in cc's 1168 // transformSourceToObj, and should only affects unit tests. 1169 vars := m.VariablesForTests() 1170 buildParams := append([]BuildParams(nil), m.buildParams...) 1171 for i := range buildParams { 1172 newArgs := make(map[string]string) 1173 for k, v := range buildParams[i].Args { 1174 newArgs[k] = v 1175 // Replaces both ${flags1} and $flags1 syntax. 1176 if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") { 1177 if value, found := vars[v[2:len(v)-1]]; found { 1178 newArgs[k] = value 1179 } 1180 } else if strings.HasPrefix(v, "$") { 1181 if value, found := vars[v[1:]]; found { 1182 newArgs[k] = value 1183 } 1184 } 1185 } 1186 buildParams[i].Args = newArgs 1187 } 1188 return buildParams 1189} 1190 1191func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams { 1192 return m.ruleParams 1193} 1194 1195func (m *ModuleBase) VariablesForTests() map[string]string { 1196 return m.variables 1197} 1198 1199// Name returns the name of the module. It may be overridden by individual module types, for 1200// example prebuilts will prepend prebuilt_ to the name. 1201func (m *ModuleBase) Name() string { 1202 return String(m.nameProperties.Name) 1203} 1204 1205// String returns a string that includes the module name and variants for printing during debugging. 1206func (m *ModuleBase) String() string { 1207 sb := strings.Builder{} 1208 sb.WriteString(m.commonProperties.DebugName) 1209 sb.WriteString("{") 1210 for i := range m.commonProperties.DebugMutators { 1211 if i != 0 { 1212 sb.WriteString(",") 1213 } 1214 sb.WriteString(m.commonProperties.DebugMutators[i]) 1215 sb.WriteString(":") 1216 sb.WriteString(m.commonProperties.DebugVariations[i]) 1217 } 1218 sb.WriteString("}") 1219 return sb.String() 1220} 1221 1222// BaseModuleName returns the name of the module as specified in the blueprints file. 1223func (m *ModuleBase) BaseModuleName() string { 1224 return String(m.nameProperties.Name) 1225} 1226 1227func (m *ModuleBase) base() *ModuleBase { 1228 return m 1229} 1230 1231func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName { 1232 return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()} 1233} 1234 1235func (m *ModuleBase) visibilityProperties() []visibilityProperty { 1236 return m.visibilityPropertyInfo 1237} 1238 1239func (m *ModuleBase) Dists() []Dist { 1240 if len(m.distProperties.Dist.Targets) > 0 { 1241 // Make a copy of the underlying Dists slice to protect against 1242 // backing array modifications with repeated calls to this method. 1243 distsCopy := append([]Dist(nil), m.distProperties.Dists...) 1244 return append(distsCopy, m.distProperties.Dist) 1245 } else { 1246 return m.distProperties.Dists 1247 } 1248} 1249 1250func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFiles { 1251 var distFiles TaggedDistFiles 1252 for _, dist := range m.Dists() { 1253 // If no tag is specified then it means to use the default dist paths so use 1254 // the special tag name which represents that. 1255 tag := proptools.StringDefault(dist.Tag, DefaultDistTag) 1256 1257 distFileForTagFromProvider, err := outputFilesForModuleFromProvider(ctx, m.module, tag) 1258 1259 // If the module doesn't define output files for the DefaultDistTag, try the files under 1260 // the "" tag. 1261 if tag == DefaultDistTag && errors.Is(err, ErrUnsupportedOutputTag) { 1262 distFileForTagFromProvider, err = outputFilesForModuleFromProvider(ctx, m.module, "") 1263 } 1264 1265 if err != OutputFilesProviderNotSet { 1266 if err != nil && tag != DefaultDistTag { 1267 ctx.PropertyErrorf("dist.tag", "%s", err.Error()) 1268 } else { 1269 distFiles = distFiles.addPathsForTag(tag, distFileForTagFromProvider...) 1270 continue 1271 } 1272 } 1273 } 1274 return distFiles 1275} 1276 1277func (m *ModuleBase) ArchReady() bool { 1278 return m.commonProperties.ArchReady 1279} 1280 1281func (m *ModuleBase) Target() Target { 1282 return m.commonProperties.CompileTarget 1283} 1284 1285func (m *ModuleBase) TargetPrimary() bool { 1286 return m.commonProperties.CompilePrimary 1287} 1288 1289func (m *ModuleBase) MultiTargets() []Target { 1290 return m.commonProperties.CompileMultiTargets 1291} 1292 1293func (m *ModuleBase) Os() OsType { 1294 return m.Target().Os 1295} 1296 1297func (m *ModuleBase) Host() bool { 1298 return m.Os().Class == Host 1299} 1300 1301func (m *ModuleBase) Device() bool { 1302 return m.Os().Class == Device 1303} 1304 1305func (m *ModuleBase) Arch() Arch { 1306 return m.Target().Arch 1307} 1308 1309func (m *ModuleBase) ArchSpecific() bool { 1310 return m.commonProperties.ArchSpecific 1311} 1312 1313// True if the current variant is a CommonOS variant, false otherwise. 1314func (m *ModuleBase) IsCommonOSVariant() bool { 1315 return m.commonProperties.CompileOS == CommonOS 1316} 1317 1318// supportsTarget returns true if the given Target is supported by the current module. 1319func (m *ModuleBase) supportsTarget(target Target) bool { 1320 switch target.Os.Class { 1321 case Host: 1322 if target.HostCross { 1323 return m.HostCrossSupported() 1324 } else { 1325 return m.HostSupported() 1326 } 1327 case Device: 1328 return m.DeviceSupported() 1329 default: 1330 return false 1331 } 1332} 1333 1334// DeviceSupported returns true if the current module is supported and enabled for device targets, 1335// i.e. the factory method set the HostOrDeviceSupported value to include device support and 1336// the device support is enabled by default or enabled by the device_supported property. 1337func (m *ModuleBase) DeviceSupported() bool { 1338 hod := m.commonProperties.HostOrDeviceSupported 1339 // deviceEnabled is true if the device_supported property is true or the HostOrDeviceSupported 1340 // value has the deviceDefault bit set. 1341 deviceEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Device_supported, hod&deviceDefault != 0) 1342 return hod&deviceSupported != 0 && deviceEnabled 1343} 1344 1345// HostSupported returns true if the current module is supported and enabled for host targets, 1346// i.e. the factory method set the HostOrDeviceSupported value to include host support and 1347// the host support is enabled by default or enabled by the host_supported property. 1348func (m *ModuleBase) HostSupported() bool { 1349 hod := m.commonProperties.HostOrDeviceSupported 1350 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported 1351 // value has the hostDefault bit set. 1352 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0) 1353 return hod&hostSupported != 0 && hostEnabled 1354} 1355 1356// HostCrossSupported returns true if the current module is supported and enabled for host cross 1357// targets, i.e. the factory method set the HostOrDeviceSupported value to include host cross 1358// support and the host cross support is enabled by default or enabled by the 1359// host_supported property. 1360func (m *ModuleBase) HostCrossSupported() bool { 1361 hod := m.commonProperties.HostOrDeviceSupported 1362 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported 1363 // value has the hostDefault bit set. 1364 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0) 1365 1366 // Default true for the Host_cross_supported property 1367 hostCrossEnabled := proptools.BoolDefault(m.hostCrossProperties.Host_cross_supported, true) 1368 1369 return hod&hostCrossSupported != 0 && hostEnabled && hostCrossEnabled 1370} 1371 1372func (m *ModuleBase) Platform() bool { 1373 return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.SystemExtSpecific() 1374} 1375 1376func (m *ModuleBase) DeviceSpecific() bool { 1377 return Bool(m.commonProperties.Device_specific) 1378} 1379 1380func (m *ModuleBase) SocSpecific() bool { 1381 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific) 1382} 1383 1384func (m *ModuleBase) ProductSpecific() bool { 1385 return Bool(m.commonProperties.Product_specific) 1386} 1387 1388func (m *ModuleBase) SystemExtSpecific() bool { 1389 return Bool(m.commonProperties.System_ext_specific) 1390} 1391 1392// RequiresStableAPIs returns true if the module will be installed to a partition that may 1393// be updated separately from the system image. 1394func (m *ModuleBase) RequiresStableAPIs(ctx BaseModuleContext) bool { 1395 return m.SocSpecific() || m.DeviceSpecific() || 1396 (m.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) 1397} 1398 1399func (m *ModuleBase) PartitionTag(config DeviceConfig) string { 1400 partition := "system" 1401 if m.SocSpecific() { 1402 // A SoC-specific module could be on the vendor partition at 1403 // "vendor" or the system partition at "system/vendor". 1404 if config.VendorPath() == "vendor" { 1405 partition = "vendor" 1406 } 1407 } else if m.DeviceSpecific() { 1408 // A device-specific module could be on the odm partition at 1409 // "odm", the vendor partition at "vendor/odm", or the system 1410 // partition at "system/vendor/odm". 1411 if config.OdmPath() == "odm" { 1412 partition = "odm" 1413 } else if strings.HasPrefix(config.OdmPath(), "vendor/") { 1414 partition = "vendor" 1415 } 1416 } else if m.ProductSpecific() { 1417 // A product-specific module could be on the product partition 1418 // at "product" or the system partition at "system/product". 1419 if config.ProductPath() == "product" { 1420 partition = "product" 1421 } 1422 } else if m.SystemExtSpecific() { 1423 // A system_ext-specific module could be on the system_ext 1424 // partition at "system_ext" or the system partition at 1425 // "system/system_ext". 1426 if config.SystemExtPath() == "system_ext" { 1427 partition = "system_ext" 1428 } 1429 } else if m.InstallInRamdisk() { 1430 partition = "ramdisk" 1431 } else if m.InstallInVendorRamdisk() { 1432 partition = "vendor_ramdisk" 1433 } else if m.InstallInRecovery() { 1434 partition = "recovery" 1435 } 1436 return partition 1437} 1438 1439func (m *ModuleBase) Enabled(ctx ConfigurableEvaluatorContext) bool { 1440 if m.commonProperties.ForcedDisabled { 1441 return false 1442 } 1443 return m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled) 1444} 1445 1446// Returns a copy of the enabled property, useful for passing it on to sub-modules 1447func (m *ModuleBase) EnabledProperty() proptools.Configurable[bool] { 1448 if m.commonProperties.ForcedDisabled { 1449 return proptools.NewSimpleConfigurable(false) 1450 } 1451 return m.commonProperties.Enabled.Clone() 1452} 1453 1454func (m *ModuleBase) Disable() { 1455 m.commonProperties.ForcedDisabled = true 1456} 1457 1458// HideFromMake marks this variant so that it is not emitted in the generated Android.mk file. 1459func (m *ModuleBase) HideFromMake() { 1460 m.commonProperties.HideFromMake = true 1461} 1462 1463// IsHideFromMake returns true if HideFromMake was previously called. 1464func (m *ModuleBase) IsHideFromMake() bool { 1465 return m.commonProperties.HideFromMake == true 1466} 1467 1468// SkipInstall marks this variant to not create install rules when ctx.Install* are called. 1469func (m *ModuleBase) SkipInstall() { 1470 m.commonProperties.SkipInstall = true 1471} 1472 1473// IsSkipInstall returns true if this variant is marked to not create install 1474// rules when ctx.Install* are called. 1475func (m *ModuleBase) IsSkipInstall() bool { 1476 return m.commonProperties.SkipInstall 1477} 1478 1479// Similar to HideFromMake, but if the AndroidMk entry would set 1480// LOCAL_UNINSTALLABLE_MODULE then this variant may still output that entry 1481// rather than leaving it out altogether. That happens in cases where it would 1482// have other side effects, in particular when it adds a NOTICE file target, 1483// which other install targets might depend on. 1484func (m *ModuleBase) MakeUninstallable() { 1485 m.commonProperties.UninstallableApexPlatformVariant = true 1486 m.HideFromMake() 1487 m.SkipInstall() 1488} 1489 1490func (m *ModuleBase) ReplacedByPrebuilt() { 1491 m.commonProperties.ReplacedByPrebuilt = true 1492 m.HideFromMake() 1493} 1494 1495func (m *ModuleBase) IsReplacedByPrebuilt() bool { 1496 return m.commonProperties.ReplacedByPrebuilt 1497} 1498 1499func (m *ModuleBase) ExportedToMake() bool { 1500 return m.commonProperties.NamespaceExportedToMake 1501} 1502 1503func (m *ModuleBase) EffectiveLicenseFiles() Paths { 1504 result := make(Paths, 0, len(m.commonProperties.Effective_license_text)) 1505 for _, p := range m.commonProperties.Effective_license_text { 1506 result = append(result, p.Path) 1507 } 1508 return result 1509} 1510 1511// computeInstallDeps finds the installed paths of all dependencies that have a dependency 1512// tag that is annotated as needing installation via the isInstallDepNeeded method. 1513func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]depset.DepSet[InstallPath], []depset.DepSet[PackagingSpec]) { 1514 var installDeps []depset.DepSet[InstallPath] 1515 var packagingSpecs []depset.DepSet[PackagingSpec] 1516 ctx.VisitDirectDepsProxy(func(dep ModuleProxy) { 1517 if isInstallDepNeeded(ctx, dep) { 1518 // Installation is still handled by Make, so anything hidden from Make is not 1519 // installable. 1520 info := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider) 1521 commonInfo := OtherModulePointerProviderOrDefault(ctx, dep, CommonModuleInfoProvider) 1522 if !commonInfo.HideFromMake && !commonInfo.SkipInstall { 1523 installDeps = append(installDeps, info.TransitiveInstallFiles) 1524 } 1525 // Add packaging deps even when the dependency is not installed so that uninstallable 1526 // modules can still be packaged. Often the package will be installed instead. 1527 packagingSpecs = append(packagingSpecs, info.TransitivePackagingSpecs) 1528 } 1529 }) 1530 1531 return installDeps, packagingSpecs 1532} 1533 1534// isInstallDepNeeded returns true if installing the output files of the current module 1535// should also install the output files of the given dependency and dependency tag. 1536func isInstallDepNeeded(ctx ModuleContext, dep ModuleProxy) bool { 1537 // Don't add a dependency from the platform to a library provided by an apex. 1538 if OtherModulePointerProviderOrDefault(ctx, dep, CommonModuleInfoProvider).UninstallableApexPlatformVariant { 1539 return false 1540 } 1541 // Only install modules if the dependency tag is an InstallDepNeeded tag. 1542 return IsInstallDepNeededTag(ctx.OtherModuleDependencyTag(dep)) 1543} 1544 1545func (m *ModuleBase) NoAddressSanitizer() bool { 1546 return m.noAddressSanitizer 1547} 1548 1549func (m *ModuleBase) InstallInData() bool { 1550 return false 1551} 1552 1553func (m *ModuleBase) InstallInTestcases() bool { 1554 return false 1555} 1556 1557func (m *ModuleBase) InstallInSanitizerDir() bool { 1558 return false 1559} 1560 1561func (m *ModuleBase) InstallInRamdisk() bool { 1562 return Bool(m.commonProperties.Ramdisk) 1563} 1564 1565func (m *ModuleBase) InstallInVendorRamdisk() bool { 1566 return Bool(m.commonProperties.Vendor_ramdisk) 1567} 1568 1569func (m *ModuleBase) InstallInDebugRamdisk() bool { 1570 return Bool(m.commonProperties.Debug_ramdisk) 1571} 1572 1573func (m *ModuleBase) InstallInRecovery() bool { 1574 return Bool(m.commonProperties.Recovery) 1575} 1576 1577func (m *ModuleBase) InstallInOdm() bool { 1578 return false 1579} 1580 1581func (m *ModuleBase) InstallInProduct() bool { 1582 return false 1583} 1584 1585func (m *ModuleBase) InstallInVendor() bool { 1586 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Soc_specific) || Bool(m.commonProperties.Proprietary) 1587} 1588 1589func (m *ModuleBase) InstallInSystemExt() bool { 1590 return Bool(m.commonProperties.System_ext_specific) 1591} 1592 1593func (m *ModuleBase) InstallInRoot() bool { 1594 return false 1595} 1596 1597func (m *ModuleBase) InstallInSystemDlkm() bool { 1598 return Bool(m.commonProperties.System_dlkm_specific) 1599} 1600 1601func (m *ModuleBase) InstallInVendorDlkm() bool { 1602 return Bool(m.commonProperties.Vendor_dlkm_specific) 1603} 1604 1605func (m *ModuleBase) InstallInOdmDlkm() bool { 1606 return Bool(m.commonProperties.Odm_dlkm_specific) 1607} 1608 1609func (m *ModuleBase) InstallForceOS() (*OsType, *ArchType) { 1610 return nil, nil 1611} 1612 1613func (m *ModuleBase) Owner() string { 1614 return String(m.commonProperties.Owner) 1615} 1616 1617func (m *ModuleBase) Team() string { 1618 return String(m.commonProperties.Team) 1619} 1620 1621func (m *ModuleBase) setImageVariation(variant string) { 1622 m.commonProperties.ImageVariation = variant 1623} 1624 1625func (m *ModuleBase) ImageVariation() blueprint.Variation { 1626 return blueprint.Variation{ 1627 Mutator: "image", 1628 Variation: m.base().commonProperties.ImageVariation, 1629 } 1630} 1631 1632func (m *ModuleBase) getVariationByMutatorName(mutator string) string { 1633 for i, v := range m.commonProperties.DebugMutators { 1634 if v == mutator { 1635 return m.commonProperties.DebugVariations[i] 1636 } 1637 } 1638 1639 return "" 1640} 1641 1642func (m *ModuleBase) InRamdisk() bool { 1643 return m.base().commonProperties.ImageVariation == RamdiskVariation 1644} 1645 1646func (m *ModuleBase) InVendorRamdisk() bool { 1647 return m.base().commonProperties.ImageVariation == VendorRamdiskVariation 1648} 1649 1650func (m *ModuleBase) InDebugRamdisk() bool { 1651 return m.base().commonProperties.ImageVariation == DebugRamdiskVariation 1652} 1653 1654func (m *ModuleBase) InRecovery() bool { 1655 return m.base().commonProperties.ImageVariation == RecoveryVariation 1656} 1657 1658func (m *ModuleBase) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string { 1659 return m.base().baseProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil) 1660} 1661 1662func (m *ModuleBase) HostRequiredModuleNames() []string { 1663 return m.base().baseProperties.Host_required 1664} 1665 1666func (m *ModuleBase) TargetRequiredModuleNames() []string { 1667 return m.base().baseProperties.Target_required 1668} 1669 1670func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string { 1671 return m.base().commonProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil) 1672} 1673 1674func (m *ModuleBase) VintfFragments(ctx ConfigurableEvaluatorContext) []string { 1675 return m.base().commonProperties.Vintf_fragments.GetOrDefault(m.ConfigurableEvaluator(ctx), nil) 1676} 1677 1678func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) { 1679 namespacePrefix := ctx.Namespace().id 1680 if namespacePrefix != "" { 1681 namespacePrefix = namespacePrefix + "-" 1682 } 1683 1684 if !ctx.uncheckedModule { 1685 name := namespacePrefix + ctx.ModuleName() + "-" + ctx.ModuleSubDir() + "-checkbuild" 1686 ctx.Phony(name, ctx.checkbuildFiles...) 1687 ctx.checkbuildTarget = PathForPhony(ctx, name) 1688 } 1689 1690} 1691 1692// generateModuleTarget generates phony targets so that you can do `m <module-name>`. 1693// It will be run on every variant of the module, so it relies on the fact that phony targets 1694// are deduped to merge all the deps from different variants together. 1695func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) { 1696 var namespacePrefix string 1697 nameSpace := ctx.Namespace().Path 1698 if nameSpace != "." { 1699 namespacePrefix = strings.ReplaceAll(nameSpace, "/", ".") + "-" 1700 } 1701 1702 var deps Paths 1703 var info ModuleBuildTargetsInfo 1704 1705 if len(ctx.installFiles) > 0 { 1706 name := namespacePrefix + ctx.ModuleName() + "-install" 1707 installFiles := ctx.installFiles.Paths() 1708 ctx.Phony(name, installFiles...) 1709 info.InstallTarget = PathForPhony(ctx, name) 1710 deps = append(deps, installFiles...) 1711 } 1712 1713 // A module's -checkbuild phony targets should 1714 // not be created if the module is not exported to make. 1715 // Those could depend on the build target and fail to compile 1716 // for the current build target. 1717 if (!ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, m)) && !ctx.uncheckedModule && ctx.checkbuildTarget != nil { 1718 name := namespacePrefix + ctx.ModuleName() + "-checkbuild" 1719 ctx.Phony(name, ctx.checkbuildTarget) 1720 deps = append(deps, ctx.checkbuildTarget) 1721 } 1722 1723 if outputFiles, err := outputFilesForModule(ctx, ctx.Module(), ""); err == nil && len(outputFiles) > 0 { 1724 name := namespacePrefix + ctx.ModuleName() + "-outputs" 1725 ctx.Phony(name, outputFiles...) 1726 deps = append(deps, outputFiles...) 1727 } 1728 1729 if len(deps) > 0 { 1730 suffix := "" 1731 if ctx.Config().KatiEnabled() { 1732 suffix = "-soong" 1733 } 1734 1735 ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...) 1736 if ctx.Device() { 1737 // Generate a target suffix for use in atest etc. 1738 ctx.Phony(namespacePrefix+ctx.ModuleName()+"-target"+suffix, deps...) 1739 } else { 1740 // Generate a host suffix for use in atest etc. 1741 ctx.Phony(namespacePrefix+ctx.ModuleName()+"-host"+suffix, deps...) 1742 if ctx.Target().HostCross { 1743 // Generate a host-cross suffix for use in atest etc. 1744 ctx.Phony(namespacePrefix+ctx.ModuleName()+"-host-cross"+suffix, deps...) 1745 } 1746 } 1747 1748 info.BlueprintDir = ctx.ModuleDir() 1749 SetProvider(ctx, ModuleBuildTargetsProvider, info) 1750 } 1751} 1752 1753func determineModuleKind(m *ModuleBase, ctx ModuleErrorContext) moduleKind { 1754 var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific) 1755 var deviceSpecific = Bool(m.commonProperties.Device_specific) 1756 var productSpecific = Bool(m.commonProperties.Product_specific) 1757 var systemExtSpecific = Bool(m.commonProperties.System_ext_specific) 1758 1759 msg := "conflicting value set here" 1760 if socSpecific && deviceSpecific { 1761 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.") 1762 if Bool(m.commonProperties.Vendor) { 1763 ctx.PropertyErrorf("vendor", msg) 1764 } 1765 if Bool(m.commonProperties.Proprietary) { 1766 ctx.PropertyErrorf("proprietary", msg) 1767 } 1768 if Bool(m.commonProperties.Soc_specific) { 1769 ctx.PropertyErrorf("soc_specific", msg) 1770 } 1771 } 1772 1773 if productSpecific && systemExtSpecific { 1774 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and system_ext at the same time.") 1775 ctx.PropertyErrorf("system_ext_specific", msg) 1776 } 1777 1778 if (socSpecific || deviceSpecific) && (productSpecific || systemExtSpecific) { 1779 if productSpecific { 1780 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.") 1781 } else { 1782 ctx.PropertyErrorf("system_ext_specific", "a module cannot be specific to SoC or device and system_ext at the same time.") 1783 } 1784 if deviceSpecific { 1785 ctx.PropertyErrorf("device_specific", msg) 1786 } else { 1787 if Bool(m.commonProperties.Vendor) { 1788 ctx.PropertyErrorf("vendor", msg) 1789 } 1790 if Bool(m.commonProperties.Proprietary) { 1791 ctx.PropertyErrorf("proprietary", msg) 1792 } 1793 if Bool(m.commonProperties.Soc_specific) { 1794 ctx.PropertyErrorf("soc_specific", msg) 1795 } 1796 } 1797 } 1798 1799 if productSpecific { 1800 return productSpecificModule 1801 } else if systemExtSpecific { 1802 return systemExtSpecificModule 1803 } else if deviceSpecific { 1804 return deviceSpecificModule 1805 } else if socSpecific { 1806 return socSpecificModule 1807 } else { 1808 return platformModule 1809 } 1810} 1811 1812func (m *ModuleBase) earlyModuleContextFactory(ctx blueprint.EarlyModuleContext) earlyModuleContext { 1813 return earlyModuleContext{ 1814 EarlyModuleContext: ctx, 1815 kind: determineModuleKind(m, ctx), 1816 config: ctx.Config().(Config), 1817 } 1818} 1819 1820func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext { 1821 return baseModuleContext{ 1822 bp: ctx, 1823 archModuleContext: m.archModuleContextFactory(ctx), 1824 earlyModuleContext: m.earlyModuleContextFactory(ctx), 1825 } 1826} 1827 1828type archModuleContextFactoryContext interface { 1829 Config() interface{} 1830} 1831 1832func (m *ModuleBase) archModuleContextFactory(ctx archModuleContextFactoryContext) archModuleContext { 1833 config := ctx.Config().(Config) 1834 target := m.Target() 1835 primaryArch := false 1836 if len(config.Targets[target.Os]) <= 1 { 1837 primaryArch = true 1838 } else { 1839 primaryArch = target.Arch.ArchType == config.Targets[target.Os][0].Arch.ArchType 1840 } 1841 1842 return archModuleContext{ 1843 ready: m.commonProperties.ArchReady, 1844 os: m.commonProperties.CompileOS, 1845 target: m.commonProperties.CompileTarget, 1846 targetPrimary: m.commonProperties.CompilePrimary, 1847 multiTargets: m.commonProperties.CompileMultiTargets, 1848 primaryArch: primaryArch, 1849 } 1850 1851} 1852 1853type InstallFilesInfo struct { 1854 InstallFiles InstallPaths 1855 CheckbuildFiles Paths 1856 CheckbuildTarget Path 1857 UncheckedModule bool 1858 PackagingSpecs []PackagingSpec 1859 // katiInstalls tracks the install rules that were created by Soong but are being exported 1860 // to Make to convert to ninja rules so that Make can add additional dependencies. 1861 KatiInstalls katiInstalls 1862 KatiSymlinks katiInstalls 1863 TestData []DataPath 1864 TransitivePackagingSpecs depset.DepSet[PackagingSpec] 1865 LicenseMetadataFile WritablePath 1866 1867 // The following fields are private before, make it private again once we have 1868 // better solution. 1869 TransitiveInstallFiles depset.DepSet[InstallPath] 1870 // katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are 1871 // allowed to have duplicates across modules and variants. 1872 KatiInitRcInstalls katiInstalls 1873 KatiVintfInstalls katiInstalls 1874 InitRcPaths Paths 1875 VintfFragmentsPaths Paths 1876 InstalledInitRcPaths InstallPaths 1877 InstalledVintfFragmentsPaths InstallPaths 1878 1879 // The files to copy to the dist as explicitly specified in the .bp file. 1880 DistFiles TaggedDistFiles 1881} 1882 1883var InstallFilesProvider = blueprint.NewProvider[InstallFilesInfo]() 1884 1885type SourceFilesInfo struct { 1886 Srcs Paths 1887} 1888 1889var SourceFilesInfoProvider = blueprint.NewProvider[SourceFilesInfo]() 1890 1891// ModuleBuildTargetsInfo is used by buildTargetSingleton to create checkbuild and 1892// per-directory build targets. 1893type ModuleBuildTargetsInfo struct { 1894 InstallTarget WritablePath 1895 CheckbuildTarget WritablePath 1896 BlueprintDir string 1897} 1898 1899var ModuleBuildTargetsProvider = blueprint.NewProvider[ModuleBuildTargetsInfo]() 1900 1901type CommonModuleInfo struct { 1902 Enabled bool 1903 // Whether the module has been replaced by a prebuilt 1904 ReplacedByPrebuilt bool 1905 // The Target of artifacts that this module variant is responsible for creating. 1906 Target Target 1907 SkipAndroidMkProcessing bool 1908 BaseModuleName string 1909 CanHaveApexVariants bool 1910 MinSdkVersion ApiLevelOrPlatform 1911 SdkVersion string 1912 NotAvailableForPlatform bool 1913 // There some subtle differences between this one and the one above. 1914 NotInPlatform bool 1915 // UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex 1916 // mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant 1917 // is used to avoid adding install or packaging dependencies into libraries provided 1918 // by apexes. 1919 UninstallableApexPlatformVariant bool 1920 MinSdkVersionSupported ApiLevel 1921 ModuleWithMinSdkVersionCheck bool 1922 // Tests if this module can be installed to APEX as a file. For example, this would return 1923 // true for shared libs while return false for static libs because static libs are not 1924 // installable module (but it can still be mutated for APEX) 1925 IsInstallableToApex bool 1926 HideFromMake bool 1927 SkipInstall bool 1928 IsStubsModule bool 1929 Host bool 1930 IsApexModule bool 1931 // The primary licenses property, may be nil, records license metadata for the module. 1932 PrimaryLicensesProperty applicableLicensesProperty 1933 Owner string 1934 Vendor bool 1935 Proprietary bool 1936 SocSpecific bool 1937 ProductSpecific bool 1938 SystemExtSpecific bool 1939 DeviceSpecific bool 1940 // When set to true, this module is not installed to the full install path (ex: under 1941 // out/target/product/<name>/<partition>). It can be installed only to the packaging 1942 // modules like android_filesystem. 1943 NoFullInstall bool 1944 InVendorRamdisk bool 1945 ExemptFromRequiredApplicableLicensesProperty bool 1946 RequiredModuleNames []string 1947 HostRequiredModuleNames []string 1948 TargetRequiredModuleNames []string 1949 VintfFragmentModuleNames []string 1950 Dists []Dist 1951 ExportedToMake bool 1952 Team string 1953 PartitionTag string 1954} 1955 1956type ApiLevelOrPlatform struct { 1957 ApiLevel *ApiLevel 1958 IsPlatform bool 1959} 1960 1961var CommonModuleInfoProvider = blueprint.NewProvider[*CommonModuleInfo]() 1962 1963type PrebuiltModuleInfo struct { 1964 SourceExists bool 1965 UsePrebuilt bool 1966} 1967 1968var PrebuiltModuleInfoProvider = blueprint.NewProvider[PrebuiltModuleInfo]() 1969 1970type HostToolProviderInfo struct { 1971 HostToolPath OptionalPath 1972} 1973 1974var HostToolProviderInfoProvider = blueprint.NewProvider[HostToolProviderInfo]() 1975 1976type DistInfo struct { 1977 Dists []dist 1978} 1979 1980var DistProvider = blueprint.NewProvider[DistInfo]() 1981 1982type SourceFileGenerator interface { 1983 GeneratedSourceFiles() Paths 1984 GeneratedHeaderDirs() Paths 1985 GeneratedDeps() Paths 1986} 1987 1988type GeneratedSourceInfo struct { 1989 GeneratedSourceFiles Paths 1990 GeneratedHeaderDirs Paths 1991 GeneratedDeps Paths 1992} 1993 1994var GeneratedSourceInfoProvider = blueprint.NewProvider[GeneratedSourceInfo]() 1995 1996func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) { 1997 ctx := &moduleContext{ 1998 module: m.module, 1999 bp: blueprintCtx, 2000 baseModuleContext: m.baseModuleContextFactory(blueprintCtx), 2001 variables: make(map[string]string), 2002 phonies: make(map[string]Paths), 2003 } 2004 2005 setContainerInfo(ctx) 2006 if ctx.Config().Getenv("DISABLE_CONTAINER_CHECK") != "true" { 2007 checkContainerViolations(ctx) 2008 } 2009 2010 ctx.licenseMetadataFile = PathForModuleOut(ctx, "meta_lic") 2011 2012 dependencyInstallFiles, dependencyPackagingSpecs := m.computeInstallDeps(ctx) 2013 // set the TransitiveInstallFiles to only the transitive dependencies to be used as the dependencies 2014 // of installed files of this module. It will be replaced by a depset including the installed 2015 // files of this module at the end for use by modules that depend on this one. 2016 ctx.TransitiveInstallFiles = depset.New[InstallPath](depset.TOPOLOGICAL, nil, dependencyInstallFiles) 2017 2018 // Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never 2019 // reporting missing dependency errors in Blueprint when AllowMissingDependencies == true. 2020 // TODO: This will be removed once defaults modules handle missing dependency errors 2021 blueprintCtx.GetMissingDependencies() 2022 2023 // For the final GenerateAndroidBuildActions pass, require that all visited dependencies Soong modules and 2024 // are enabled. Unless the module is a CommonOS variant which may have dependencies on disabled variants 2025 // (because the dependencies are added before the modules are disabled). The 2026 // GetOsSpecificVariantsOfCommonOSVariant(...) method will ensure that the disabled variants are 2027 // ignored. 2028 ctx.baseModuleContext.strictVisitDeps = !m.IsCommonOSVariant() 2029 2030 if ctx.config.captureBuild { 2031 ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams) 2032 } 2033 2034 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " " 2035 var suffix []string 2036 if ctx.Os().Class != Device && ctx.Os().Class != Generic { 2037 suffix = append(suffix, ctx.Os().String()) 2038 } 2039 if !ctx.PrimaryArch() { 2040 suffix = append(suffix, ctx.Arch().ArchType.String()) 2041 } 2042 if apexInfo, _ := ModuleProvider(ctx, ApexInfoProvider); !apexInfo.IsForPlatform() { 2043 suffix = append(suffix, apexInfo.ApexVariationName) 2044 } 2045 2046 ctx.Variable(pctx, "moduleDesc", desc) 2047 2048 s := "" 2049 if len(suffix) > 0 { 2050 s = " [" + strings.Join(suffix, " ") + "]" 2051 } 2052 ctx.Variable(pctx, "moduleDescSuffix", s) 2053 2054 // Some common property checks for properties that will be used later in androidmk.go 2055 checkDistProperties(ctx, "dist", &m.distProperties.Dist) 2056 for i := range m.distProperties.Dists { 2057 checkDistProperties(ctx, fmt.Sprintf("dists[%d]", i), &m.distProperties.Dists[i]) 2058 } 2059 2060 var installFiles InstallFilesInfo 2061 2062 if m.Enabled(ctx) { 2063 // ensure all direct android.Module deps are enabled 2064 ctx.VisitDirectDepsProxy(func(m ModuleProxy) {}) 2065 2066 if m.Device() { 2067 // Handle any init.rc and vintf fragment files requested by the module. All files installed by this 2068 // module will automatically have a dependency on the installed init.rc or vintf fragment file. 2069 // The same init.rc or vintf fragment file may be requested by multiple modules or variants, 2070 // so instead of installing them now just compute the install path and store it for later. 2071 // The full list of all init.rc and vintf fragment install rules will be deduplicated later 2072 // so only a single rule is created for each init.rc or vintf fragment file. 2073 2074 if !m.InVendorRamdisk() { 2075 ctx.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc.GetOrDefault(ctx, nil)) 2076 rcDir := PathForModuleInstall(ctx, "etc", "init") 2077 for _, src := range ctx.initRcPaths { 2078 installedInitRc := rcDir.Join(ctx, src.Base()) 2079 ctx.katiInitRcInstalls = append(ctx.katiInitRcInstalls, katiInstall{ 2080 from: src, 2081 to: installedInitRc, 2082 }) 2083 ctx.PackageFile(rcDir, src.Base(), src) 2084 ctx.installedInitRcPaths = append(ctx.installedInitRcPaths, installedInitRc) 2085 } 2086 installFiles.InitRcPaths = ctx.initRcPaths 2087 installFiles.KatiInitRcInstalls = ctx.katiInitRcInstalls 2088 installFiles.InstalledInitRcPaths = ctx.installedInitRcPaths 2089 } 2090 2091 ctx.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments.GetOrDefault(ctx, nil)) 2092 vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest") 2093 for _, src := range ctx.vintfFragmentsPaths { 2094 installedVintfFragment := vintfDir.Join(ctx, src.Base()) 2095 ctx.katiVintfInstalls = append(ctx.katiVintfInstalls, katiInstall{ 2096 from: src, 2097 to: installedVintfFragment, 2098 }) 2099 ctx.PackageFile(vintfDir, src.Base(), src) 2100 ctx.installedVintfFragmentsPaths = append(ctx.installedVintfFragmentsPaths, installedVintfFragment) 2101 } 2102 installFiles.VintfFragmentsPaths = ctx.vintfFragmentsPaths 2103 installFiles.KatiVintfInstalls = ctx.katiVintfInstalls 2104 installFiles.InstalledVintfFragmentsPaths = ctx.installedVintfFragmentsPaths 2105 } 2106 2107 licensesPropertyFlattener(ctx) 2108 if ctx.Failed() { 2109 return 2110 } 2111 2112 if jarJarPrefixHandler != nil { 2113 jarJarPrefixHandler(ctx) 2114 if ctx.Failed() { 2115 return 2116 } 2117 } 2118 2119 // Call aconfigUpdateAndroidBuildActions to collect merged aconfig files before being used 2120 // in m.module.GenerateAndroidBuildActions 2121 aconfigUpdateAndroidBuildActions(ctx) 2122 if ctx.Failed() { 2123 return 2124 } 2125 2126 m.module.GenerateAndroidBuildActions(ctx) 2127 if ctx.Failed() { 2128 return 2129 } 2130 2131 if x, ok := m.module.(IDEInfo); ok { 2132 var result IdeInfo 2133 x.IDEInfo(ctx, &result) 2134 result.BaseModuleName = x.BaseModuleName() 2135 SetProvider(ctx, IdeInfoProviderKey, result) 2136 } 2137 2138 // Create the set of tagged dist files after calling GenerateAndroidBuildActions 2139 // as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the 2140 // output paths being set which must be done before or during 2141 // GenerateAndroidBuildActions. 2142 installFiles.DistFiles = m.GenerateTaggedDistFiles(ctx) 2143 if ctx.Failed() { 2144 return 2145 } 2146 2147 m.generateVariantTarget(ctx) 2148 2149 installFiles.LicenseMetadataFile = ctx.licenseMetadataFile 2150 installFiles.InstallFiles = ctx.installFiles 2151 installFiles.CheckbuildFiles = ctx.checkbuildFiles 2152 installFiles.CheckbuildTarget = ctx.checkbuildTarget 2153 installFiles.UncheckedModule = ctx.uncheckedModule 2154 installFiles.PackagingSpecs = ctx.packagingSpecs 2155 installFiles.KatiInstalls = ctx.katiInstalls 2156 installFiles.KatiSymlinks = ctx.katiSymlinks 2157 installFiles.TestData = ctx.testData 2158 } else if ctx.Config().AllowMissingDependencies() { 2159 // If the module is not enabled it will not create any build rules, nothing will call 2160 // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled 2161 // and report them as an error even when AllowMissingDependencies = true. Call 2162 // ctx.GetMissingDependencies() here to tell blueprint not to handle them. 2163 ctx.GetMissingDependencies() 2164 } 2165 2166 if sourceFileProducer, ok := m.module.(SourceFileProducer); ok { 2167 srcs := sourceFileProducer.Srcs() 2168 for _, src := range srcs { 2169 if src == nil { 2170 ctx.ModuleErrorf("SourceFileProducer cannot return nil srcs") 2171 return 2172 } 2173 } 2174 SetProvider(ctx, SourceFilesInfoProvider, SourceFilesInfo{Srcs: sourceFileProducer.Srcs()}) 2175 } 2176 2177 m.generateModuleTarget(ctx) 2178 if ctx.Failed() { 2179 return 2180 } 2181 2182 ctx.TransitiveInstallFiles = depset.New[InstallPath](depset.TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles) 2183 installFiles.TransitiveInstallFiles = ctx.TransitiveInstallFiles 2184 installFiles.TransitivePackagingSpecs = depset.New[PackagingSpec](depset.TOPOLOGICAL, ctx.packagingSpecs, dependencyPackagingSpecs) 2185 2186 SetProvider(ctx, InstallFilesProvider, installFiles) 2187 buildLicenseMetadata(ctx, ctx.licenseMetadataFile) 2188 2189 if len(ctx.moduleInfoJSON) > 0 { 2190 for _, moduleInfoJSON := range ctx.moduleInfoJSON { 2191 if moduleInfoJSON.Disabled { 2192 continue 2193 } 2194 var installed InstallPaths 2195 installed = append(installed, ctx.katiInstalls.InstallPaths()...) 2196 installed = append(installed, ctx.katiSymlinks.InstallPaths()...) 2197 installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...) 2198 installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...) 2199 installedStrings := installed.Strings() 2200 2201 var targetRequired, hostRequired []string 2202 if ctx.Host() { 2203 targetRequired = m.baseProperties.Target_required 2204 } else { 2205 hostRequired = m.baseProperties.Host_required 2206 } 2207 hostRequired = append(hostRequired, moduleInfoJSON.ExtraHostRequired...) 2208 2209 var data []string 2210 for _, d := range ctx.testData { 2211 data = append(data, d.ToRelativeInstallPath()) 2212 } 2213 2214 if moduleInfoJSON.Uninstallable { 2215 installedStrings = nil 2216 if len(moduleInfoJSON.CompatibilitySuites) == 1 && moduleInfoJSON.CompatibilitySuites[0] == "null-suite" { 2217 moduleInfoJSON.CompatibilitySuites = nil 2218 moduleInfoJSON.TestConfig = nil 2219 moduleInfoJSON.AutoTestConfig = nil 2220 data = nil 2221 } 2222 } 2223 2224 // M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}. 2225 // To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite, 2226 // we add the full test suite to our list. This was inherited from 2227 // AndroidMkEntries.AddCompatibilityTestSuites. 2228 suites := moduleInfoJSON.CompatibilitySuites 2229 if PrefixInList(suites, "mts-") && !InList("mts", suites) { 2230 suites = append(suites, "mts") 2231 } 2232 if PrefixInList(suites, "mcts-") && !InList("mcts", suites) { 2233 suites = append(suites, "mcts") 2234 } 2235 moduleInfoJSON.CompatibilitySuites = suites 2236 2237 required := append(m.RequiredModuleNames(ctx), m.VintfFragmentModuleNames(ctx)...) 2238 required = append(required, moduleInfoJSON.ExtraRequired...) 2239 2240 registerName := moduleInfoJSON.RegisterNameOverride 2241 if len(registerName) == 0 { 2242 registerName = m.moduleInfoRegisterName(ctx, moduleInfoJSON.SubName) 2243 } 2244 2245 moduleName := moduleInfoJSON.ModuleNameOverride 2246 if len(moduleName) == 0 { 2247 moduleName = m.BaseModuleName() + moduleInfoJSON.SubName 2248 } 2249 2250 supportedVariants := moduleInfoJSON.SupportedVariantsOverride 2251 if moduleInfoJSON.SupportedVariantsOverride == nil { 2252 supportedVariants = []string{m.moduleInfoVariant(ctx)} 2253 } 2254 2255 moduleInfoJSON.core = CoreModuleInfoJSON{ 2256 RegisterName: registerName, 2257 Path: []string{ctx.ModuleDir()}, 2258 Installed: installedStrings, 2259 ModuleName: moduleName, 2260 SupportedVariants: supportedVariants, 2261 TargetDependencies: targetRequired, 2262 HostDependencies: hostRequired, 2263 Data: data, 2264 Required: required, 2265 } 2266 } 2267 2268 SetProvider(ctx, ModuleInfoJSONProvider, ctx.moduleInfoJSON) 2269 } 2270 2271 m.buildParams = ctx.buildParams 2272 m.ruleParams = ctx.ruleParams 2273 m.variables = ctx.variables 2274 2275 outputFiles := ctx.GetOutputFiles() 2276 if outputFiles.DefaultOutputFiles != nil || outputFiles.TaggedOutputFiles != nil { 2277 SetProvider(ctx, OutputFilesProvider, outputFiles) 2278 } 2279 2280 if len(ctx.phonies) > 0 { 2281 SetProvider(ctx, ModulePhonyProvider, ModulePhonyInfo{ 2282 Phonies: ctx.phonies, 2283 }) 2284 } 2285 2286 if len(ctx.dists) > 0 { 2287 SetProvider(ctx, DistProvider, DistInfo{ 2288 Dists: ctx.dists, 2289 }) 2290 } 2291 2292 buildComplianceMetadataProvider(ctx, m) 2293 2294 commonData := CommonModuleInfo{ 2295 Enabled: m.Enabled(ctx), 2296 ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt, 2297 Target: m.commonProperties.CompileTarget, 2298 SkipAndroidMkProcessing: shouldSkipAndroidMkProcessing(ctx, m), 2299 UninstallableApexPlatformVariant: m.commonProperties.UninstallableApexPlatformVariant, 2300 HideFromMake: m.commonProperties.HideFromMake, 2301 SkipInstall: m.commonProperties.SkipInstall, 2302 Host: m.Host(), 2303 PrimaryLicensesProperty: m.primaryLicensesProperty, 2304 Owner: m.module.Owner(), 2305 SocSpecific: Bool(m.commonProperties.Soc_specific), 2306 Vendor: Bool(m.commonProperties.Vendor), 2307 Proprietary: Bool(m.commonProperties.Proprietary), 2308 ProductSpecific: Bool(m.commonProperties.Product_specific), 2309 SystemExtSpecific: Bool(m.commonProperties.System_ext_specific), 2310 DeviceSpecific: Bool(m.commonProperties.Device_specific), 2311 NoFullInstall: proptools.Bool(m.commonProperties.No_full_install), 2312 InVendorRamdisk: m.InVendorRamdisk(), 2313 ExemptFromRequiredApplicableLicensesProperty: exemptFromRequiredApplicableLicensesProperty(m.module), 2314 RequiredModuleNames: m.module.RequiredModuleNames(ctx), 2315 HostRequiredModuleNames: m.module.HostRequiredModuleNames(), 2316 TargetRequiredModuleNames: m.module.TargetRequiredModuleNames(), 2317 VintfFragmentModuleNames: m.module.VintfFragmentModuleNames(ctx), 2318 Dists: m.Dists(), 2319 ExportedToMake: m.ExportedToMake(), 2320 Team: m.Team(), 2321 PartitionTag: m.PartitionTag(ctx.DeviceConfig()), 2322 } 2323 if mm, ok := m.module.(interface { 2324 MinSdkVersion(ctx EarlyModuleContext) ApiLevel 2325 }); ok { 2326 ver := mm.MinSdkVersion(ctx) 2327 commonData.MinSdkVersion.ApiLevel = &ver 2328 } else if mm, ok := m.module.(interface{ MinSdkVersion() string }); ok { 2329 ver := mm.MinSdkVersion() 2330 // Compile against the current platform 2331 if ver == "" { 2332 commonData.MinSdkVersion.IsPlatform = true 2333 } else { 2334 api := ApiLevelFrom(ctx, ver) 2335 commonData.MinSdkVersion.ApiLevel = &api 2336 } 2337 } 2338 2339 if mm, ok := m.module.(interface { 2340 SdkVersion(ctx EarlyModuleContext) ApiLevel 2341 }); ok { 2342 ver := mm.SdkVersion(ctx) 2343 if !ver.IsNone() { 2344 commonData.SdkVersion = ver.String() 2345 } 2346 } else if mm, ok := m.module.(interface{ SdkVersion() string }); ok { 2347 commonData.SdkVersion = mm.SdkVersion() 2348 } 2349 2350 if am, ok := m.module.(ApexModule); ok { 2351 commonData.CanHaveApexVariants = am.CanHaveApexVariants() 2352 commonData.NotAvailableForPlatform = am.NotAvailableForPlatform() 2353 commonData.NotInPlatform = am.NotInPlatform() 2354 commonData.MinSdkVersionSupported = am.MinSdkVersionSupported(ctx) 2355 commonData.IsInstallableToApex = am.IsInstallableToApex() 2356 commonData.IsApexModule = true 2357 } 2358 2359 if _, ok := m.module.(ModuleWithMinSdkVersionCheck); ok { 2360 commonData.ModuleWithMinSdkVersionCheck = true 2361 } 2362 2363 if st, ok := m.module.(StubsAvailableModule); ok { 2364 commonData.IsStubsModule = st.IsStubsModule() 2365 } 2366 if mm, ok := m.module.(interface{ BaseModuleName() string }); ok { 2367 commonData.BaseModuleName = mm.BaseModuleName() 2368 } 2369 SetProvider(ctx, CommonModuleInfoProvider, &commonData) 2370 if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil { 2371 SetProvider(ctx, PrebuiltModuleInfoProvider, PrebuiltModuleInfo{ 2372 SourceExists: p.Prebuilt().SourceExists(), 2373 UsePrebuilt: p.Prebuilt().UsePrebuilt(), 2374 }) 2375 } 2376 if h, ok := m.module.(HostToolProvider); ok { 2377 SetProvider(ctx, HostToolProviderInfoProvider, HostToolProviderInfo{ 2378 HostToolPath: h.HostToolPath()}) 2379 } 2380 2381 if p, ok := m.module.(AndroidMkProviderInfoProducer); ok && !commonData.SkipAndroidMkProcessing { 2382 SetProvider(ctx, AndroidMkInfoProvider, p.PrepareAndroidMKProviderInfo(ctx.Config())) 2383 } 2384 2385 if s, ok := m.module.(SourceFileGenerator); ok { 2386 SetProvider(ctx, GeneratedSourceInfoProvider, GeneratedSourceInfo{ 2387 GeneratedSourceFiles: s.GeneratedSourceFiles(), 2388 GeneratedHeaderDirs: s.GeneratedHeaderDirs(), 2389 GeneratedDeps: s.GeneratedDeps(), 2390 }) 2391 } 2392 2393 if m.Enabled(ctx) { 2394 if v, ok := m.module.(ModuleMakeVarsProvider); ok { 2395 SetProvider(ctx, ModuleMakeVarsInfoProvider, v.MakeVars(ctx)) 2396 } 2397 2398 if am, ok := m.module.(AndroidMkDataProvider); ok { 2399 SetProvider(ctx, AndroidMkDataInfoProvider, AndroidMkDataInfo{ 2400 Class: am.AndroidMk().Class, 2401 }) 2402 } 2403 } 2404 2405 m.module.CleanupAfterBuildActions() 2406} 2407 2408func (m *ModuleBase) CleanupAfterBuildActions() {} 2409 2410func SetJarJarPrefixHandler(handler func(ModuleContext)) { 2411 if jarJarPrefixHandler != nil { 2412 panic("jarJarPrefixHandler already set") 2413 } 2414 jarJarPrefixHandler = handler 2415} 2416 2417func (m *ModuleBase) moduleInfoRegisterName(ctx ModuleContext, subName string) string { 2418 name := m.BaseModuleName() 2419 2420 prefix := "" 2421 if ctx.Host() { 2422 if ctx.Os() != ctx.Config().BuildOS { 2423 prefix = "host_cross_" 2424 } 2425 } 2426 suffix := "" 2427 arches := slices.Clone(ctx.Config().Targets[ctx.Os()]) 2428 arches = slices.DeleteFunc(arches, func(target Target) bool { 2429 return target.NativeBridge != ctx.Target().NativeBridge 2430 }) 2431 if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType && ctx.Arch().ArchType != Common { 2432 if ctx.Arch().ArchType.Multilib == "lib32" { 2433 suffix = "_32" 2434 } else { 2435 suffix = "_64" 2436 } 2437 } 2438 return prefix + name + subName + suffix 2439} 2440 2441func (m *ModuleBase) moduleInfoVariant(ctx ModuleContext) string { 2442 variant := "DEVICE" 2443 if ctx.Host() { 2444 if ctx.Os() != ctx.Config().BuildOS { 2445 variant = "HOST_CROSS" 2446 } else { 2447 variant = "HOST" 2448 } 2449 } 2450 return variant 2451} 2452 2453// Check the supplied dist structure to make sure that it is valid. 2454// 2455// property - the base property, e.g. dist or dists[1], which is combined with the 2456// name of the nested property to produce the full property, e.g. dist.dest or 2457// dists[1].dir. 2458func checkDistProperties(ctx *moduleContext, property string, dist *Dist) { 2459 if dist.Dest != nil { 2460 _, err := validateSafePath(*dist.Dest) 2461 if err != nil { 2462 ctx.PropertyErrorf(property+".dest", "%s", err.Error()) 2463 } 2464 } 2465 if dist.Dir != nil { 2466 _, err := validateSafePath(*dist.Dir) 2467 if err != nil { 2468 ctx.PropertyErrorf(property+".dir", "%s", err.Error()) 2469 } 2470 } 2471 if dist.Suffix != nil { 2472 if strings.Contains(*dist.Suffix, "/") { 2473 ctx.PropertyErrorf(property+".suffix", "Suffix may not contain a '/' character.") 2474 } 2475 } 2476 2477} 2478 2479// katiInstall stores a request from Soong to Make to create an install rule. 2480type katiInstall struct { 2481 from Path 2482 to InstallPath 2483 implicitDeps Paths 2484 orderOnlyDeps Paths 2485 executable bool 2486 extraFiles *extraFilesZip 2487 absFrom string 2488} 2489 2490type katiInstallGob struct { 2491 From Path 2492 To InstallPath 2493 ImplicitDeps Paths 2494 OrderOnlyDeps Paths 2495 Executable bool 2496 ExtraFiles *extraFilesZip 2497 AbsFrom string 2498} 2499 2500func (k *katiInstall) ToGob() *katiInstallGob { 2501 return &katiInstallGob{ 2502 From: k.from, 2503 To: k.to, 2504 ImplicitDeps: k.implicitDeps, 2505 OrderOnlyDeps: k.orderOnlyDeps, 2506 Executable: k.executable, 2507 ExtraFiles: k.extraFiles, 2508 AbsFrom: k.absFrom, 2509 } 2510} 2511 2512func (k *katiInstall) FromGob(data *katiInstallGob) { 2513 k.from = data.From 2514 k.to = data.To 2515 k.implicitDeps = data.ImplicitDeps 2516 k.orderOnlyDeps = data.OrderOnlyDeps 2517 k.executable = data.Executable 2518 k.extraFiles = data.ExtraFiles 2519 k.absFrom = data.AbsFrom 2520} 2521 2522func (k *katiInstall) GobEncode() ([]byte, error) { 2523 return gobtools.CustomGobEncode[katiInstallGob](k) 2524} 2525 2526func (k *katiInstall) GobDecode(data []byte) error { 2527 return gobtools.CustomGobDecode[katiInstallGob](data, k) 2528} 2529 2530type extraFilesZip struct { 2531 zip Path 2532 dir InstallPath 2533} 2534 2535type extraFilesZipGob struct { 2536 Zip Path 2537 Dir InstallPath 2538} 2539 2540func (e *extraFilesZip) ToGob() *extraFilesZipGob { 2541 return &extraFilesZipGob{ 2542 Zip: e.zip, 2543 Dir: e.dir, 2544 } 2545} 2546 2547func (e *extraFilesZip) FromGob(data *extraFilesZipGob) { 2548 e.zip = data.Zip 2549 e.dir = data.Dir 2550} 2551 2552func (e *extraFilesZip) GobEncode() ([]byte, error) { 2553 return gobtools.CustomGobEncode[extraFilesZipGob](e) 2554} 2555 2556func (e *extraFilesZip) GobDecode(data []byte) error { 2557 return gobtools.CustomGobDecode[extraFilesZipGob](data, e) 2558} 2559 2560type katiInstalls []katiInstall 2561 2562// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a 2563// space separated list of from:to tuples. 2564func (installs katiInstalls) BuiltInstalled() string { 2565 sb := strings.Builder{} 2566 for i, install := range installs { 2567 if i != 0 { 2568 sb.WriteRune(' ') 2569 } 2570 sb.WriteString(install.from.String()) 2571 sb.WriteRune(':') 2572 sb.WriteString(install.to.String()) 2573 } 2574 return sb.String() 2575} 2576 2577// InstallPaths returns the install path of each entry. 2578func (installs katiInstalls) InstallPaths() InstallPaths { 2579 paths := make(InstallPaths, 0, len(installs)) 2580 for _, install := range installs { 2581 paths = append(paths, install.to) 2582 } 2583 return paths 2584} 2585 2586// Makes this module a platform module, i.e. not specific to soc, device, 2587// product, or system_ext. 2588func (m *ModuleBase) MakeAsPlatform() { 2589 m.commonProperties.Vendor = boolPtr(false) 2590 m.commonProperties.Proprietary = boolPtr(false) 2591 m.commonProperties.Soc_specific = boolPtr(false) 2592 m.commonProperties.Product_specific = boolPtr(false) 2593 m.commonProperties.System_ext_specific = boolPtr(false) 2594} 2595 2596func (m *ModuleBase) MakeAsSystemExt() { 2597 m.commonProperties.Vendor = boolPtr(false) 2598 m.commonProperties.Proprietary = boolPtr(false) 2599 m.commonProperties.Soc_specific = boolPtr(false) 2600 m.commonProperties.Product_specific = boolPtr(false) 2601 m.commonProperties.System_ext_specific = boolPtr(true) 2602} 2603 2604// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true" 2605func (m *ModuleBase) IsNativeBridgeSupported() bool { 2606 return proptools.Bool(m.commonProperties.Native_bridge_supported) 2607} 2608 2609func (m *ModuleBase) DecodeMultilib(ctx ConfigContext) (string, string) { 2610 return decodeMultilib(ctx, m) 2611} 2612 2613func (m *ModuleBase) Overrides() []string { 2614 return m.commonProperties.Overrides 2615} 2616 2617func (m *ModuleBase) UseGenericConfig() bool { 2618 return proptools.Bool(m.commonProperties.Use_generic_config) 2619} 2620 2621type ConfigContext interface { 2622 Config() Config 2623} 2624 2625type ConfigurableEvaluatorContext interface { 2626 OtherModuleProviderContext 2627 Config() Config 2628 OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{}) 2629 HasMutatorFinished(mutatorName string) bool 2630} 2631 2632type configurationEvalutor struct { 2633 ctx ConfigurableEvaluatorContext 2634 m Module 2635} 2636 2637func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator { 2638 return configurationEvalutor{ 2639 ctx: ctx, 2640 m: m.module, 2641 } 2642} 2643 2644func (e configurationEvalutor) PropertyErrorf(property string, fmt string, args ...interface{}) { 2645 e.ctx.OtherModulePropertyErrorf(e.m, property, fmt, args...) 2646} 2647 2648func (e configurationEvalutor) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue { 2649 ctx := e.ctx 2650 m := e.m 2651 2652 if !ctx.HasMutatorFinished("defaults") { 2653 ctx.OtherModulePropertyErrorf(m, property, "Cannot evaluate configurable property before the defaults mutator has run") 2654 return proptools.ConfigurableValueUndefined() 2655 } 2656 2657 switch condition.FunctionName() { 2658 case "release_flag": 2659 if condition.NumArgs() != 1 { 2660 ctx.OtherModulePropertyErrorf(m, property, "release_flag requires 1 argument, found %d", condition.NumArgs()) 2661 return proptools.ConfigurableValueUndefined() 2662 } 2663 if ty, ok := ctx.Config().productVariables.BuildFlagTypes[condition.Arg(0)]; ok { 2664 v := ctx.Config().productVariables.BuildFlags[condition.Arg(0)] 2665 switch ty { 2666 case "unspecified", "obsolete": 2667 return proptools.ConfigurableValueUndefined() 2668 case "string": 2669 return proptools.ConfigurableValueString(v) 2670 case "bool": 2671 return proptools.ConfigurableValueBool(v == "true") 2672 default: 2673 panic("unhandled release flag type: " + ty) 2674 } 2675 } 2676 return proptools.ConfigurableValueUndefined() 2677 case "product_variable": 2678 if condition.NumArgs() != 1 { 2679 ctx.OtherModulePropertyErrorf(m, property, "product_variable requires 1 argument, found %d", condition.NumArgs()) 2680 return proptools.ConfigurableValueUndefined() 2681 } 2682 variable := condition.Arg(0) 2683 switch variable { 2684 case "build_from_text_stub": 2685 return proptools.ConfigurableValueBool(ctx.Config().BuildFromTextStub()) 2686 case "debuggable": 2687 return proptools.ConfigurableValueBool(ctx.Config().Debuggable()) 2688 case "eng": 2689 return proptools.ConfigurableValueBool(ctx.Config().Eng()) 2690 case "use_debug_art": 2691 // TODO(b/234351700): Remove once ART does not have separated debug APEX 2692 return proptools.ConfigurableValueBool(ctx.Config().UseDebugArt()) 2693 case "selinux_ignore_neverallows": 2694 return proptools.ConfigurableValueBool(ctx.Config().SelinuxIgnoreNeverallows()) 2695 case "always_use_prebuilt_sdks": 2696 return proptools.ConfigurableValueBool(ctx.Config().AlwaysUsePrebuiltSdks()) 2697 default: 2698 // TODO(b/323382414): Might add these on a case-by-case basis 2699 ctx.OtherModulePropertyErrorf(m, property, fmt.Sprintf("TODO(b/323382414): Product variable %q is not yet supported in selects", variable)) 2700 return proptools.ConfigurableValueUndefined() 2701 } 2702 case "soong_config_variable": 2703 if condition.NumArgs() != 2 { 2704 ctx.OtherModulePropertyErrorf(m, property, "soong_config_variable requires 2 arguments, found %d", condition.NumArgs()) 2705 return proptools.ConfigurableValueUndefined() 2706 } 2707 namespace := condition.Arg(0) 2708 variable := condition.Arg(1) 2709 if n, ok := ctx.Config().productVariables.VendorVars[namespace]; ok { 2710 if v, ok := n[variable]; ok { 2711 ty := "" 2712 if namespaces, ok := ctx.Config().productVariables.VendorVarTypes[namespace]; ok { 2713 ty = namespaces[variable] 2714 } 2715 switch ty { 2716 case "": 2717 // strings are the default, we don't bother writing them to the soong variables json file 2718 return proptools.ConfigurableValueString(v) 2719 case "bool": 2720 return proptools.ConfigurableValueBool(v == "true") 2721 case "int": 2722 i, err := strconv.ParseInt(v, 10, 64) 2723 if err != nil { 2724 ctx.OtherModulePropertyErrorf(m, property, "integer soong_config_variable was not an int: %q", v) 2725 return proptools.ConfigurableValueUndefined() 2726 } 2727 return proptools.ConfigurableValueInt(i) 2728 case "string_list": 2729 return proptools.ConfigurableValueStringList(strings.Split(v, " ")) 2730 default: 2731 panic("unhandled soong config variable type: " + ty) 2732 } 2733 2734 } 2735 } 2736 return proptools.ConfigurableValueUndefined() 2737 case "arch": 2738 if condition.NumArgs() != 0 { 2739 ctx.OtherModulePropertyErrorf(m, property, "arch requires no arguments, found %d", condition.NumArgs()) 2740 return proptools.ConfigurableValueUndefined() 2741 } 2742 if !m.base().ArchReady() { 2743 ctx.OtherModulePropertyErrorf(m, property, "A select on arch was attempted before the arch mutator ran") 2744 return proptools.ConfigurableValueUndefined() 2745 } 2746 return proptools.ConfigurableValueString(m.base().Arch().ArchType.Name) 2747 case "os": 2748 if condition.NumArgs() != 0 { 2749 ctx.OtherModulePropertyErrorf(m, property, "os requires no arguments, found %d", condition.NumArgs()) 2750 return proptools.ConfigurableValueUndefined() 2751 } 2752 // the arch mutator runs after the os mutator, we can just use this to enforce that os is ready. 2753 if !m.base().ArchReady() { 2754 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)") 2755 return proptools.ConfigurableValueUndefined() 2756 } 2757 return proptools.ConfigurableValueString(m.base().Os().Name) 2758 case "boolean_var_for_testing": 2759 // We currently don't have any other boolean variables (we should add support for typing 2760 // the soong config variables), so add this fake one for testing the boolean select 2761 // functionality. 2762 if condition.NumArgs() != 0 { 2763 ctx.OtherModulePropertyErrorf(m, property, "boolean_var_for_testing requires 0 arguments, found %d", condition.NumArgs()) 2764 return proptools.ConfigurableValueUndefined() 2765 } 2766 2767 if n, ok := ctx.Config().productVariables.VendorVars["boolean_var"]; ok { 2768 if v, ok := n["for_testing"]; ok { 2769 switch v { 2770 case "true": 2771 return proptools.ConfigurableValueBool(true) 2772 case "false": 2773 return proptools.ConfigurableValueBool(false) 2774 default: 2775 ctx.OtherModulePropertyErrorf(m, property, "testing:my_boolean_var can only be true or false, found %q", v) 2776 } 2777 } 2778 } 2779 return proptools.ConfigurableValueUndefined() 2780 default: 2781 ctx.OtherModulePropertyErrorf(m, property, "Unknown select condition %s", condition.FunctionName) 2782 return proptools.ConfigurableValueUndefined() 2783 } 2784} 2785 2786// ModuleNameWithPossibleOverride returns the name of the OverrideModule that overrides the current 2787// variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule 2788// or if this variant is not overridden. 2789func ModuleNameWithPossibleOverride(ctx BaseModuleContext) string { 2790 if overridable, ok := ctx.Module().(OverridableModule); ok { 2791 if o := overridable.GetOverriddenBy(); o != "" { 2792 return o 2793 } 2794 } 2795 return ctx.ModuleName() 2796} 2797 2798// SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name" 2799// into the module name, or empty string if the input was not a module reference. 2800func SrcIsModule(s string) (module string) { 2801 if len(s) > 1 { 2802 if s[0] == ':' { 2803 module = s[1:] 2804 if !isUnqualifiedModuleName(module) { 2805 // The module name should be unqualified but is not so do not treat it as a module. 2806 module = "" 2807 } 2808 } else if s[0] == '/' && s[1] == '/' { 2809 module = s 2810 } 2811 } 2812 return module 2813} 2814 2815// SrcIsModuleWithTag decodes module references in the format ":unqualified-name{.tag}" or 2816// "//namespace:name{.tag}" into the module name and tag, ":unqualified-name" or "//namespace:name" 2817// into the module name and an empty string for the tag, or empty strings if the input was not a 2818// module reference. 2819func SrcIsModuleWithTag(s string) (module, tag string) { 2820 if len(s) > 1 { 2821 if s[0] == ':' { 2822 module = s[1:] 2823 } else if s[0] == '/' && s[1] == '/' { 2824 module = s 2825 } 2826 2827 if module != "" { 2828 if tagStart := strings.IndexByte(module, '{'); tagStart > 0 { 2829 if module[len(module)-1] == '}' { 2830 tag = module[tagStart+1 : len(module)-1] 2831 module = module[:tagStart] 2832 } 2833 } 2834 2835 if s[0] == ':' && !isUnqualifiedModuleName(module) { 2836 // The module name should be unqualified but is not so do not treat it as a module. 2837 module = "" 2838 tag = "" 2839 } 2840 } 2841 } 2842 2843 return module, tag 2844} 2845 2846// isUnqualifiedModuleName makes sure that the supplied module is an unqualified module name, i.e. 2847// does not contain any /. 2848func isUnqualifiedModuleName(module string) bool { 2849 return strings.IndexByte(module, '/') == -1 2850} 2851 2852// sourceOrOutputDependencyTag is the dependency tag added automatically by pathDepsMutator for any 2853// module reference in a property annotated with `android:"path"` or passed to ExtractSourceDeps 2854// or ExtractSourcesDeps. 2855// 2856// If uniquely identifies the dependency that was added as it contains both the module name used to 2857// add the dependency as well as the tag. That makes it very simple to find the matching dependency 2858// in GetModuleFromPathDep as all it needs to do is find the dependency whose tag matches the tag 2859// used to add it. It does not need to check that the module name as returned by one of 2860// Module.Name(), BaseModuleContext.OtherModuleName() or ModuleBase.BaseModuleName() matches the 2861// name supplied in the tag. That means it does not need to handle differences in module names 2862// caused by prebuilt_ prefix, or fully qualified module names. 2863type sourceOrOutputDependencyTag struct { 2864 blueprint.BaseDependencyTag 2865 AlwaysPropagateAconfigValidationDependencyTag 2866 2867 // The name of the module. 2868 moduleName string 2869 2870 // The tag that will be used to get the specific output file(s). 2871 tag string 2872} 2873 2874func sourceOrOutputDepTag(moduleName, tag string) blueprint.DependencyTag { 2875 return sourceOrOutputDependencyTag{moduleName: moduleName, tag: tag} 2876} 2877 2878// IsSourceDepTagWithOutputTag returns true if the supplied blueprint.DependencyTag is one that was 2879// used to add dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for 2880// properties tagged with `android:"path"` AND it was added using a module reference of 2881// :moduleName{outputTag}. 2882func IsSourceDepTagWithOutputTag(depTag blueprint.DependencyTag, outputTag string) bool { 2883 t, ok := depTag.(sourceOrOutputDependencyTag) 2884 return ok && t.tag == outputTag 2885} 2886 2887// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles 2888// using ":module" syntax, if any. 2889// 2890// Deprecated: tag the property with `android:"path"` instead. 2891func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) { 2892 set := make(map[string]bool) 2893 2894 for _, s := range srcFiles { 2895 if m, t := SrcIsModuleWithTag(s); m != "" { 2896 if _, found := set[s]; found { 2897 ctx.ModuleErrorf("found source dependency duplicate: %q!", s) 2898 } else { 2899 set[s] = true 2900 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m) 2901 } 2902 } 2903 } 2904} 2905 2906// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s 2907// using ":module" syntax, if any. 2908// 2909// Deprecated: tag the property with `android:"path"` instead. 2910func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) { 2911 if s != nil { 2912 if m, t := SrcIsModuleWithTag(*s); m != "" { 2913 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m) 2914 } 2915 } 2916} 2917 2918// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"` 2919// using the ":module" syntax and provides a list of paths to be used as if they were listed in the property. 2920type SourceFileProducer interface { 2921 Srcs() Paths 2922} 2923 2924// OutputFilesForModule returns the output file paths with the given tag. On error, including if the 2925// module produced zero paths, it reports errors to the ctx and returns nil. 2926func OutputFilesForModule(ctx PathContext, module Module, tag string) Paths { 2927 paths, err := outputFilesForModule(ctx, module, tag) 2928 if err != nil { 2929 reportPathError(ctx, err) 2930 return nil 2931 } 2932 return paths 2933} 2934 2935// OutputFileForModule returns the output file paths with the given tag. On error, including if the 2936// module produced zero or multiple paths, it reports errors to the ctx and returns nil. 2937// TODO(b/397766191): Change the signature to take ModuleProxy 2938// Please only access the module's internal data through providers. 2939func OutputFileForModule(ctx PathContext, module Module, tag string) Path { 2940 paths, err := outputFilesForModule(ctx, module, tag) 2941 if err != nil { 2942 reportPathError(ctx, err) 2943 return nil 2944 } 2945 if len(paths) == 0 { 2946 type addMissingDependenciesIntf interface { 2947 AddMissingDependencies([]string) 2948 OtherModuleName(blueprint.Module) string 2949 } 2950 if mctx, ok := ctx.(addMissingDependenciesIntf); ok && ctx.Config().AllowMissingDependencies() { 2951 mctx.AddMissingDependencies([]string{mctx.OtherModuleName(module)}) 2952 } else { 2953 ReportPathErrorf(ctx, "failed to get output files from module %q", pathContextName(ctx, module)) 2954 } 2955 // Return a fake output file to avoid nil dereferences of Path objects later. 2956 // This should never get used for an actual build as the error or missing 2957 // dependency has already been reported. 2958 p, err := pathForSource(ctx, filepath.Join("missing_output_file", pathContextName(ctx, module))) 2959 if err != nil { 2960 reportPathError(ctx, err) 2961 return nil 2962 } 2963 return p 2964 } 2965 if len(paths) > 1 { 2966 ReportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one", 2967 pathContextName(ctx, module)) 2968 } 2969 return paths[0] 2970} 2971 2972type OutputFilesProviderModuleContext interface { 2973 OtherModuleProviderContext 2974 Module() Module 2975 GetOutputFiles() OutputFilesInfo 2976} 2977 2978// TODO(b/397766191): Change the signature to take ModuleProxy 2979// Please only access the module's internal data through providers. 2980func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, error) { 2981 outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag) 2982 if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet { 2983 return outputFilesFromProvider, err 2984 } 2985 2986 if octx, ok := ctx.(OutputFilesProviderModuleContext); ok { 2987 if EqualModules(octx.Module(), module) { 2988 // It is the current module, we can access the srcs through interface 2989 if sourceFileProducer, ok := module.(SourceFileProducer); ok { 2990 return sourceFileProducer.Srcs(), nil 2991 } 2992 } else if sourceFiles, ok := OtherModuleProvider(octx, module, SourceFilesInfoProvider); ok { 2993 if tag != "" { 2994 return nil, fmt.Errorf("module %q is a SourceFileProducer, which does not support tag %q", pathContextName(ctx, module), tag) 2995 } 2996 paths := sourceFiles.Srcs 2997 return paths, nil 2998 } 2999 } 3000 3001 return nil, fmt.Errorf("module %q is not a SourceFileProducer or having valid output file for tag %q", pathContextName(ctx, module), tag) 3002} 3003 3004// This method uses OutputFilesProvider for output files 3005// *inter-module-communication*. 3006// If mctx module is the same as the param module the output files are obtained 3007// from outputFiles property of module base, to avoid both setting and 3008// reading OutputFilesProvider before GenerateBuildActions is finished. 3009// If a module doesn't have the OutputFilesProvider, nil is returned. 3010func outputFilesForModuleFromProvider(ctx PathContext, module Module, tag string) (Paths, error) { 3011 var outputFiles OutputFilesInfo 3012 3013 if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx { 3014 if !EqualModules(mctx.Module(), module) { 3015 outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider) 3016 } else { 3017 outputFiles = mctx.GetOutputFiles() 3018 } 3019 } else if cta, isCta := ctx.(*singletonContextAdaptor); isCta { 3020 outputFiles, _ = OtherModuleProvider(cta, module, OutputFilesProvider) 3021 } else { 3022 return nil, fmt.Errorf("unsupported context %q in method outputFilesForModuleFromProvider", reflect.TypeOf(ctx)) 3023 } 3024 3025 if outputFiles.isEmpty() { 3026 return nil, OutputFilesProviderNotSet 3027 } 3028 3029 if tag == "" { 3030 return outputFiles.DefaultOutputFiles, nil 3031 } else if taggedOutputFiles, hasTag := outputFiles.TaggedOutputFiles[tag]; hasTag { 3032 return taggedOutputFiles, nil 3033 } else { 3034 return nil, UnsupportedOutputTagError{ 3035 tag: tag, 3036 } 3037 } 3038} 3039 3040func (o OutputFilesInfo) isEmpty() bool { 3041 return o.DefaultOutputFiles == nil && o.TaggedOutputFiles == nil 3042} 3043 3044type OutputFilesInfo struct { 3045 // default output files when tag is an empty string "" 3046 DefaultOutputFiles Paths 3047 3048 // the corresponding output files for given tags 3049 TaggedOutputFiles map[string]Paths 3050} 3051 3052var OutputFilesProvider = blueprint.NewProvider[OutputFilesInfo]() 3053 3054type UnsupportedOutputTagError struct { 3055 tag string 3056} 3057 3058func (u UnsupportedOutputTagError) Error() string { 3059 return fmt.Sprintf("unsupported output tag %q", u.tag) 3060} 3061 3062func (u UnsupportedOutputTagError) Is(e error) bool { 3063 _, ok := e.(UnsupportedOutputTagError) 3064 return ok 3065} 3066 3067var _ error = UnsupportedOutputTagError{} 3068 3069// This is used to mark the case where OutputFilesProvider is not set on some modules. 3070var OutputFilesProviderNotSet = fmt.Errorf("No output files from provider") 3071var ErrUnsupportedOutputTag = UnsupportedOutputTagError{} 3072 3073// Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to 3074// specify that they can be used as a tool by a genrule module. 3075type HostToolProvider interface { 3076 Module 3077 // HostToolPath returns the path to the host tool for the module if it is one, or an invalid 3078 // OptionalPath. 3079 HostToolPath() OptionalPath 3080} 3081 3082func init() { 3083 RegisterParallelSingletonType("buildtarget", BuildTargetSingleton) 3084} 3085 3086func BuildTargetSingleton() Singleton { 3087 return &buildTargetSingleton{} 3088} 3089 3090func parentDir(dir string) string { 3091 dir, _ = filepath.Split(dir) 3092 return filepath.Clean(dir) 3093} 3094 3095type buildTargetSingleton struct{} 3096 3097func AddAncestors(ctx SingletonContext, dirMap map[string]Paths, mmName func(string) string) ([]string, []string) { 3098 // Ensure ancestor directories are in dirMap 3099 // Make directories build their direct subdirectories 3100 // Returns a slice of all directories and a slice of top-level directories. 3101 dirs := SortedKeys(dirMap) 3102 for _, dir := range dirs { 3103 dir := parentDir(dir) 3104 for dir != "." && dir != "/" { 3105 if _, exists := dirMap[dir]; exists { 3106 break 3107 } 3108 dirMap[dir] = nil 3109 dir = parentDir(dir) 3110 } 3111 } 3112 dirs = SortedKeys(dirMap) 3113 var topDirs []string 3114 for _, dir := range dirs { 3115 p := parentDir(dir) 3116 if p != "." && p != "/" { 3117 dirMap[p] = append(dirMap[p], PathForPhony(ctx, mmName(dir))) 3118 } else if dir != "." && dir != "/" && dir != "" { 3119 topDirs = append(topDirs, dir) 3120 } 3121 } 3122 return SortedKeys(dirMap), topDirs 3123} 3124 3125func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) { 3126 var checkbuildDeps Paths 3127 3128 // Create a top level partialcompileclean target for modules to add dependencies to. 3129 ctx.Phony("partialcompileclean") 3130 3131 mmTarget := func(dir string) string { 3132 return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1) 3133 } 3134 3135 modulesInDir := make(map[string]Paths) 3136 3137 ctx.VisitAllModuleProxies(func(module ModuleProxy) { 3138 info := OtherModuleProviderOrDefault(ctx, module, ModuleBuildTargetsProvider) 3139 3140 if info.CheckbuildTarget != nil { 3141 checkbuildDeps = append(checkbuildDeps, info.CheckbuildTarget) 3142 modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.CheckbuildTarget) 3143 } 3144 3145 if info.InstallTarget != nil { 3146 modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.InstallTarget) 3147 } 3148 }) 3149 3150 suffix := "" 3151 if ctx.Config().KatiEnabled() { 3152 suffix = "-soong" 3153 } 3154 3155 // Create a top-level checkbuild target that depends on all modules 3156 ctx.Phony("checkbuild"+suffix, checkbuildDeps...) 3157 3158 // Make will generate the MODULES-IN-* targets 3159 if ctx.Config().KatiEnabled() { 3160 return 3161 } 3162 3163 dirs, _ := AddAncestors(ctx, modulesInDir, mmTarget) 3164 3165 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and 3166 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp 3167 // files. 3168 for _, dir := range dirs { 3169 ctx.Phony(mmTarget(dir), modulesInDir[dir]...) 3170 } 3171 3172 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild. 3173 type osAndCross struct { 3174 os OsType 3175 hostCross bool 3176 } 3177 osDeps := map[osAndCross]Paths{} 3178 ctx.VisitAllModules(func(module Module) { 3179 if module.Enabled(ctx) { 3180 key := osAndCross{os: module.Target().Os, hostCross: module.Target().HostCross} 3181 osDeps[key] = append(osDeps[key], OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).CheckbuildFiles...) 3182 } 3183 }) 3184 3185 osClass := make(map[string]Paths) 3186 for key, deps := range osDeps { 3187 var className string 3188 3189 switch key.os.Class { 3190 case Host: 3191 if key.hostCross { 3192 className = "host-cross" 3193 } else { 3194 className = "host" 3195 } 3196 case Device: 3197 className = "target" 3198 default: 3199 continue 3200 } 3201 3202 name := className + "-" + key.os.Name 3203 osClass[className] = append(osClass[className], PathForPhony(ctx, name)) 3204 3205 ctx.Phony(name, deps...) 3206 } 3207 3208 // Wrap those into host|host-cross|target phony rules 3209 for _, class := range SortedKeys(osClass) { 3210 ctx.Phony(class, osClass[class]...) 3211 } 3212} 3213 3214// Collect information for opening IDE project files in java/jdeps.go. 3215type IDEInfo interface { 3216 IDEInfo(ctx BaseModuleContext, ideInfo *IdeInfo) 3217 BaseModuleName() string 3218} 3219 3220// Collect information for opening IDE project files in java/jdeps.go. 3221type IdeInfo struct { 3222 BaseModuleName string `json:"-"` 3223 Deps []string `json:"dependencies,omitempty"` 3224 Srcs []string `json:"srcs,omitempty"` 3225 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"` 3226 Jarjar_rules []string `json:"jarjar_rules,omitempty"` 3227 Jars []string `json:"jars,omitempty"` 3228 Classes []string `json:"class,omitempty"` 3229 Installed_paths []string `json:"installed,omitempty"` 3230 SrcJars []string `json:"srcjars,omitempty"` 3231 Paths []string `json:"path,omitempty"` 3232 Static_libs []string `json:"static_libs,omitempty"` 3233 Libs []string `json:"libs,omitempty"` 3234} 3235 3236// Merge merges two IdeInfos and produces a new one, leaving the origional unchanged 3237func (i IdeInfo) Merge(other IdeInfo) IdeInfo { 3238 return IdeInfo{ 3239 Deps: mergeStringLists(i.Deps, other.Deps), 3240 Srcs: mergeStringLists(i.Srcs, other.Srcs), 3241 Aidl_include_dirs: mergeStringLists(i.Aidl_include_dirs, other.Aidl_include_dirs), 3242 Jarjar_rules: mergeStringLists(i.Jarjar_rules, other.Jarjar_rules), 3243 Jars: mergeStringLists(i.Jars, other.Jars), 3244 Classes: mergeStringLists(i.Classes, other.Classes), 3245 Installed_paths: mergeStringLists(i.Installed_paths, other.Installed_paths), 3246 SrcJars: mergeStringLists(i.SrcJars, other.SrcJars), 3247 Paths: mergeStringLists(i.Paths, other.Paths), 3248 Static_libs: mergeStringLists(i.Static_libs, other.Static_libs), 3249 Libs: mergeStringLists(i.Libs, other.Libs), 3250 } 3251} 3252 3253// mergeStringLists appends the two string lists together and returns a new string list, 3254// leaving the originals unchanged. Duplicate strings will be deduplicated. 3255func mergeStringLists(a, b []string) []string { 3256 return FirstUniqueStrings(Concat(a, b)) 3257} 3258 3259var IdeInfoProviderKey = blueprint.NewProvider[IdeInfo]() 3260 3261func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error { 3262 bpctx := ctx.blueprintBaseModuleContext() 3263 return blueprint.CheckBlueprintSyntax(bpctx.ModuleFactories(), filename, contents) 3264} 3265