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