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