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 "os" 21 "path" 22 "path/filepath" 23 "reflect" 24 "regexp" 25 "sort" 26 "strings" 27 "text/scanner" 28 29 "android/soong/bazel" 30 31 "github.com/google/blueprint" 32 "github.com/google/blueprint/proptools" 33) 34 35var ( 36 DeviceSharedLibrary = "shared_library" 37 DeviceStaticLibrary = "static_library" 38) 39 40// BuildParameters describes the set of potential parameters to build a Ninja rule. 41// In general, these correspond to a Ninja concept. 42type BuildParams struct { 43 // A Ninja Rule that will be written to the Ninja file. This allows factoring out common code 44 // among multiple modules to reduce repetition in the Ninja file of action requirements. A rule 45 // can contain variables that should be provided in Args. 46 Rule blueprint.Rule 47 // Deps represents the depfile format. When using RuleBuilder, this defaults to GCC when depfiles 48 // are used. 49 Deps blueprint.Deps 50 // Depfile is a writeable path that allows correct incremental builds when the inputs have not 51 // been fully specified by the Ninja rule. Ninja supports a subset of the Makefile depfile syntax. 52 Depfile WritablePath 53 // A description of the build action. 54 Description string 55 // Output is an output file of the action. When using this field, references to $out in the Ninja 56 // command will refer to this file. 57 Output WritablePath 58 // Outputs is a slice of output file of the action. When using this field, references to $out in 59 // the Ninja command will refer to these files. 60 Outputs WritablePaths 61 // SymlinkOutput is an output file specifically that is a symlink. 62 SymlinkOutput WritablePath 63 // SymlinkOutputs is a slice of output files specifically that is a symlink. 64 SymlinkOutputs WritablePaths 65 // ImplicitOutput is an output file generated by the action. Note: references to `$out` in the 66 // Ninja command will NOT include references to this file. 67 ImplicitOutput WritablePath 68 // ImplicitOutputs is a slice of output files generated by the action. Note: references to `$out` 69 // in the Ninja command will NOT include references to these files. 70 ImplicitOutputs WritablePaths 71 // Input is an input file to the Ninja action. When using this field, references to $in in the 72 // Ninja command will refer to this file. 73 Input Path 74 // Inputs is a slice of input files to the Ninja action. When using this field, references to $in 75 // in the Ninja command will refer to these files. 76 Inputs Paths 77 // Implicit is an input file to the Ninja action. Note: references to `$in` in the Ninja command 78 // will NOT include references to this file. 79 Implicit Path 80 // Implicits is a slice of input files to the Ninja action. Note: references to `$in` in the Ninja 81 // command will NOT include references to these files. 82 Implicits Paths 83 // OrderOnly are Ninja order-only inputs to the action. When these are out of date, the output is 84 // not rebuilt until they are built, but changes in order-only dependencies alone do not cause the 85 // output to be rebuilt. 86 OrderOnly Paths 87 // Validation is an output path for a validation action. Validation outputs imply lower 88 // non-blocking priority to building non-validation outputs. 89 Validation Path 90 // Validations is a slice of output path for a validation action. Validation outputs imply lower 91 // non-blocking priority to building non-validation outputs. 92 Validations Paths 93 // Whether to skip outputting a default target statement which will be built by Ninja when no 94 // targets are specified on Ninja's command line. 95 Default bool 96 // Args is a key value mapping for replacements of variables within the Rule 97 Args map[string]string 98} 99 100type ModuleBuildParams BuildParams 101 102// EarlyModuleContext provides methods that can be called early, as soon as the properties have 103// been parsed into the module and before any mutators have run. 104type EarlyModuleContext interface { 105 // Module returns the current module as a Module. It should rarely be necessary, as the module already has a 106 // reference to itself. 107 Module() Module 108 109 // ModuleName returns the name of the module. This is generally the value that was returned by Module.Name() when 110 // the module was created, but may have been modified by calls to BaseMutatorContext.Rename. 111 ModuleName() string 112 113 // ModuleDir returns the path to the directory that contains the definition of the module. 114 ModuleDir() string 115 116 // ModuleType returns the name of the module type that was used to create the module, as specified in 117 // RegisterModuleType. 118 ModuleType() string 119 120 // BlueprintFile returns the name of the blueprint file that contains the definition of this 121 // module. 122 BlueprintsFile() string 123 124 // ContainsProperty returns true if the specified property name was set in the module definition. 125 ContainsProperty(name string) bool 126 127 // Errorf reports an error at the specified position of the module definition file. 128 Errorf(pos scanner.Position, fmt string, args ...interface{}) 129 130 // ModuleErrorf reports an error at the line number of the module type in the module definition. 131 ModuleErrorf(fmt string, args ...interface{}) 132 133 // PropertyErrorf reports an error at the line number of a property in the module definition. 134 PropertyErrorf(property, fmt string, args ...interface{}) 135 136 // Failed returns true if any errors have been reported. In most cases the module can continue with generating 137 // build rules after an error, allowing it to report additional errors in a single run, but in cases where the error 138 // has prevented the module from creating necessary data it can return early when Failed returns true. 139 Failed() bool 140 141 // AddNinjaFileDeps adds dependencies on the specified files to the rule that creates the ninja manifest. The 142 // primary builder will be rerun whenever the specified files are modified. 143 AddNinjaFileDeps(deps ...string) 144 145 DeviceSpecific() bool 146 SocSpecific() bool 147 ProductSpecific() bool 148 SystemExtSpecific() bool 149 Platform() bool 150 151 Config() Config 152 DeviceConfig() DeviceConfig 153 154 // Deprecated: use Config() 155 AConfig() Config 156 157 // GlobWithDeps returns a list of files that match the specified pattern but do not match any 158 // of the patterns in excludes. It also adds efficient dependencies to rerun the primary 159 // builder whenever a file matching the pattern as added or removed, without rerunning if a 160 // file that does not match the pattern is added to a searched directory. 161 GlobWithDeps(pattern string, excludes []string) ([]string, error) 162 163 Glob(globPattern string, excludes []string) Paths 164 GlobFiles(globPattern string, excludes []string) Paths 165 IsSymlink(path Path) bool 166 Readlink(path Path) string 167 168 // Namespace returns the Namespace object provided by the NameInterface set by Context.SetNameInterface, or the 169 // default SimpleNameInterface if Context.SetNameInterface was not called. 170 Namespace() *Namespace 171} 172 173// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns 174// a Config instead of an interface{}, and some methods have been wrapped to use an android.Module 175// instead of a blueprint.Module, plus some extra methods that return Android-specific information 176// about the current module. 177type BaseModuleContext interface { 178 EarlyModuleContext 179 180 blueprintBaseModuleContext() blueprint.BaseModuleContext 181 182 // OtherModuleName returns the name of another Module. See BaseModuleContext.ModuleName for more information. 183 // It is intended for use inside the visit functions of Visit* and WalkDeps. 184 OtherModuleName(m blueprint.Module) string 185 186 // OtherModuleDir returns the directory of another Module. See BaseModuleContext.ModuleDir for more information. 187 // It is intended for use inside the visit functions of Visit* and WalkDeps. 188 OtherModuleDir(m blueprint.Module) string 189 190 // OtherModuleErrorf reports an error on another Module. See BaseModuleContext.ModuleErrorf for more information. 191 // It is intended for use inside the visit functions of Visit* and WalkDeps. 192 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) 193 194 // OtherModuleDependencyTag returns the dependency tag used to depend on a module, or nil if there is no dependency 195 // on the module. When called inside a Visit* method with current module being visited, and there are multiple 196 // dependencies on the module being visited, it returns the dependency tag used for the current dependency. 197 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag 198 199 // OtherModuleExists returns true if a module with the specified name exists, as determined by the NameInterface 200 // passed to Context.SetNameInterface, or SimpleNameInterface if it was not called. 201 OtherModuleExists(name string) bool 202 203 // OtherModuleDependencyVariantExists returns true if a module with the 204 // specified name and variant exists. The variant must match the given 205 // variations. It must also match all the non-local variations of the current 206 // module. In other words, it checks for the module that AddVariationDependencies 207 // would add a dependency on with the same arguments. 208 OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool 209 210 // OtherModuleFarDependencyVariantExists returns true if a module with the 211 // specified name and variant exists. The variant must match the given 212 // variations, but not the non-local variations of the current module. In 213 // other words, it checks for the module that AddFarVariationDependencies 214 // would add a dependency on with the same arguments. 215 OtherModuleFarDependencyVariantExists(variations []blueprint.Variation, name string) bool 216 217 // OtherModuleReverseDependencyVariantExists returns true if a module with the 218 // specified name exists with the same variations as the current module. In 219 // other words, it checks for the module that AddReverseDependency would add a 220 // dependency on with the same argument. 221 OtherModuleReverseDependencyVariantExists(name string) bool 222 223 // OtherModuleType returns the type of another Module. See BaseModuleContext.ModuleType for more information. 224 // It is intended for use inside the visit functions of Visit* and WalkDeps. 225 OtherModuleType(m blueprint.Module) string 226 227 // OtherModuleProvider returns the value for a provider for the given module. If the value is 228 // not set it returns the zero value of the type of the provider, so the return value can always 229 // be type asserted to the type of the provider. The value returned may be a deep copy of the 230 // value originally passed to SetProvider. 231 OtherModuleProvider(m blueprint.Module, provider blueprint.ProviderKey) interface{} 232 233 // OtherModuleHasProvider returns true if the provider for the given module has been set. 234 OtherModuleHasProvider(m blueprint.Module, provider blueprint.ProviderKey) bool 235 236 // Provider returns the value for a provider for the current module. If the value is 237 // not set it returns the zero value of the type of the provider, so the return value can always 238 // be type asserted to the type of the provider. It panics if called before the appropriate 239 // mutator or GenerateBuildActions pass for the provider. The value returned may be a deep 240 // copy of the value originally passed to SetProvider. 241 Provider(provider blueprint.ProviderKey) interface{} 242 243 // HasProvider returns true if the provider for the current module has been set. 244 HasProvider(provider blueprint.ProviderKey) bool 245 246 // SetProvider sets the value for a provider for the current module. It panics if not called 247 // during the appropriate mutator or GenerateBuildActions pass for the provider, if the value 248 // is not of the appropriate type, or if the value has already been set. The value should not 249 // be modified after being passed to SetProvider. 250 SetProvider(provider blueprint.ProviderKey, value interface{}) 251 252 GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module 253 254 // GetDirectDepWithTag returns the Module the direct dependency with the specified name, or nil if 255 // none exists. It panics if the dependency does not have the specified tag. It skips any 256 // dependencies that are not an android.Module. 257 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module 258 259 // GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified 260 // name, or nil if none exists. If there are multiple dependencies on the same module it returns 261 // the first DependencyTag. 262 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) 263 264 ModuleFromName(name string) (blueprint.Module, bool) 265 266 // VisitDirectDepsBlueprint calls visit for each direct dependency. If there are multiple 267 // direct dependencies on the same module visit will be called multiple times on that module 268 // and OtherModuleDependencyTag will return a different tag for each. 269 // 270 // The Module passed to the visit function should not be retained outside of the visit 271 // function, it may be invalidated by future mutators. 272 VisitDirectDepsBlueprint(visit func(blueprint.Module)) 273 274 // VisitDirectDeps calls visit for each direct dependency. If there are multiple 275 // direct dependencies on the same module visit will be called multiple times on that module 276 // and OtherModuleDependencyTag will return a different tag for each. It raises an error if any of the 277 // dependencies are not an android.Module. 278 // 279 // The Module passed to the visit function should not be retained outside of the visit 280 // function, it may be invalidated by future mutators. 281 VisitDirectDeps(visit func(Module)) 282 283 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) 284 285 // VisitDirectDepsIf calls pred for each direct dependency, and if pred returns true calls visit. If there are 286 // multiple direct dependencies on the same module pred and visit will be called multiple times on that module and 287 // OtherModuleDependencyTag will return a different tag for each. It skips any 288 // dependencies that are not an android.Module. 289 // 290 // The Module passed to the visit function should not be retained outside of the visit function, it may be 291 // invalidated by future mutators. 292 VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) 293 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module 294 VisitDepsDepthFirst(visit func(Module)) 295 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module 296 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) 297 298 // WalkDeps calls visit for each transitive dependency, traversing the dependency tree in top down order. visit may 299 // be called multiple times for the same (child, parent) pair if there are multiple direct dependencies between the 300 // child and parent with different tags. OtherModuleDependencyTag will return the tag for the currently visited 301 // (child, parent) pair. If visit returns false WalkDeps will not continue recursing down to child. It skips 302 // any dependencies that are not an android.Module. 303 // 304 // The Modules passed to the visit function should not be retained outside of the visit function, they may be 305 // invalidated by future mutators. 306 WalkDeps(visit func(child, parent Module) bool) 307 308 // WalkDepsBlueprint calls visit for each transitive dependency, traversing the dependency 309 // tree in top down order. visit may be called multiple times for the same (child, parent) 310 // pair if there are multiple direct dependencies between the child and parent with different 311 // tags. OtherModuleDependencyTag will return the tag for the currently visited 312 // (child, parent) pair. If visit returns false WalkDeps will not continue recursing down 313 // to child. 314 // 315 // The Modules passed to the visit function should not be retained outside of the visit function, they may be 316 // invalidated by future mutators. 317 WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) 318 319 // GetWalkPath is supposed to be called in visit function passed in WalkDeps() 320 // and returns a top-down dependency path from a start module to current child module. 321 GetWalkPath() []Module 322 323 // PrimaryModule returns the first variant of the current module. Variants of a module are always visited in 324 // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from the 325 // Module returned by PrimaryModule without data races. This can be used to perform singleton actions that are 326 // only done once for all variants of a module. 327 PrimaryModule() Module 328 329 // FinalModule returns the last variant of the current module. Variants of a module are always visited in 330 // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all 331 // variants using VisitAllModuleVariants if the current module == FinalModule(). This can be used to perform 332 // singleton actions that are only done once for all variants of a module. 333 FinalModule() Module 334 335 // VisitAllModuleVariants calls visit for each variant of the current module. Variants of a module are always 336 // visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read 337 // from all variants if the current module == FinalModule(). Otherwise, care must be taken to not access any 338 // data modified by the current mutator. 339 VisitAllModuleVariants(visit func(Module)) 340 341 // GetTagPath is supposed to be called in visit function passed in WalkDeps() 342 // and returns a top-down dependency tags path from a start module to current child module. 343 // It has one less entry than GetWalkPath() as it contains the dependency tags that 344 // exist between each adjacent pair of modules in the GetWalkPath(). 345 // GetTagPath()[i] is the tag between GetWalkPath()[i] and GetWalkPath()[i+1] 346 GetTagPath() []blueprint.DependencyTag 347 348 // GetPathString is supposed to be called in visit function passed in WalkDeps() 349 // and returns a multi-line string showing the modules and dependency tags 350 // among them along the top-down dependency path from a start module to current child module. 351 // skipFirst when set to true, the output doesn't include the start module, 352 // which is already printed when this function is used along with ModuleErrorf(). 353 GetPathString(skipFirst bool) string 354 355 AddMissingDependencies(missingDeps []string) 356 357 // AddUnconvertedBp2buildDep stores module name of a direct dependency that was not converted via bp2build 358 AddUnconvertedBp2buildDep(dep string) 359 360 // AddMissingBp2buildDep stores the module name of a direct dependency that was not found. 361 AddMissingBp2buildDep(dep string) 362 363 Target() Target 364 TargetPrimary() bool 365 366 // The additional arch specific targets (e.g. 32/64 bit) that this module variant is 367 // responsible for creating. 368 MultiTargets() []Target 369 Arch() Arch 370 Os() OsType 371 Host() bool 372 Device() bool 373 Darwin() bool 374 Windows() bool 375 Debug() bool 376 PrimaryArch() bool 377} 378 379// Deprecated: use EarlyModuleContext instead 380type BaseContext interface { 381 EarlyModuleContext 382} 383 384type ModuleContext interface { 385 BaseModuleContext 386 387 blueprintModuleContext() blueprint.ModuleContext 388 389 // Deprecated: use ModuleContext.Build instead. 390 ModuleBuild(pctx PackageContext, params ModuleBuildParams) 391 392 // Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must 393 // be tagged with `android:"path" to support automatic source module dependency resolution. 394 // 395 // Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead. 396 ExpandSources(srcFiles, excludes []string) Paths 397 398 // Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must 399 // be tagged with `android:"path" to support automatic source module dependency resolution. 400 // 401 // Deprecated: use PathForModuleSrc instead. 402 ExpandSource(srcFile, prop string) Path 403 404 ExpandOptionalSource(srcFile *string, prop string) OptionalPath 405 406 // InstallExecutable creates a rule to copy srcPath to name in the installPath directory, 407 // with the given additional dependencies. The file is marked executable after copying. 408 // 409 // The installed file will be returned by FilesToInstall(), and the PackagingSpec for the 410 // installed file will be returned by PackagingSpecs() on this module or by 411 // TransitivePackagingSpecs() on modules that depend on this module through dependency tags 412 // for which IsInstallDepNeeded returns true. 413 InstallExecutable(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath 414 415 // InstallFile creates a rule to copy srcPath to name in the installPath directory, 416 // with the given additional dependencies. 417 // 418 // The installed file will be returned by FilesToInstall(), and the PackagingSpec for the 419 // installed file will be returned by PackagingSpecs() on this module or by 420 // TransitivePackagingSpecs() on modules that depend on this module through dependency tags 421 // for which IsInstallDepNeeded returns true. 422 InstallFile(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath 423 424 // InstallFileWithExtraFilesZip creates a rule to copy srcPath to name in the installPath 425 // directory, and also unzip a zip file containing extra files to install into the same 426 // directory. 427 // 428 // The installed file will be returned by FilesToInstall(), and the PackagingSpec for the 429 // installed file will be returned by PackagingSpecs() on this module or by 430 // TransitivePackagingSpecs() on modules that depend on this module through dependency tags 431 // for which IsInstallDepNeeded returns true. 432 InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path, extraZip Path, deps ...Path) InstallPath 433 434 // InstallSymlink creates a rule to create a symlink from src srcPath to name in the installPath 435 // directory. 436 // 437 // The installed symlink will be returned by FilesToInstall(), and the PackagingSpec for the 438 // installed file will be returned by PackagingSpecs() on this module or by 439 // TransitivePackagingSpecs() on modules that depend on this module through dependency tags 440 // for which IsInstallDepNeeded returns true. 441 InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath 442 443 // InstallAbsoluteSymlink creates a rule to create an absolute symlink from src srcPath to name 444 // in the installPath directory. 445 // 446 // The installed symlink will be returned by FilesToInstall(), and the PackagingSpec for the 447 // installed file will be returned by PackagingSpecs() on this module or by 448 // TransitivePackagingSpecs() on modules that depend on this module through dependency tags 449 // for which IsInstallDepNeeded returns true. 450 InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath 451 452 // PackageFile creates a PackagingSpec as if InstallFile was called, but without creating 453 // the rule to copy the file. This is useful to define how a module would be packaged 454 // without installing it into the global installation directories. 455 // 456 // The created PackagingSpec for the will be returned by PackagingSpecs() on this module or by 457 // TransitivePackagingSpecs() on modules that depend on this module through dependency tags 458 // for which IsInstallDepNeeded returns true. 459 PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec 460 461 CheckbuildFile(srcPath Path) 462 463 InstallInData() bool 464 InstallInTestcases() bool 465 InstallInSanitizerDir() bool 466 InstallInRamdisk() bool 467 InstallInVendorRamdisk() bool 468 InstallInDebugRamdisk() bool 469 InstallInRecovery() bool 470 InstallInRoot() bool 471 InstallInVendor() bool 472 InstallForceOS() (*OsType, *ArchType) 473 474 RequiredModuleNames() []string 475 HostRequiredModuleNames() []string 476 TargetRequiredModuleNames() []string 477 478 ModuleSubDir() string 479 480 Variable(pctx PackageContext, name, value string) 481 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule 482 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string, 483 // and performs more verification. 484 Build(pctx PackageContext, params BuildParams) 485 // Phony creates a Make-style phony rule, a rule with no commands that can depend on other 486 // phony rules or real files. Phony can be called on the same name multiple times to add 487 // additional dependencies. 488 Phony(phony string, deps ...Path) 489 490 // GetMissingDependencies returns the list of dependencies that were passed to AddDependencies or related methods, 491 // but do not exist. 492 GetMissingDependencies() []string 493 494 // LicenseMetadataFile returns the path where the license metadata for this module will be 495 // generated. 496 LicenseMetadataFile() Path 497} 498 499type Module interface { 500 blueprint.Module 501 502 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions, 503 // but GenerateAndroidBuildActions also has access to Android-specific information. 504 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go 505 GenerateAndroidBuildActions(ModuleContext) 506 507 // Add dependencies to the components of a module, i.e. modules that are created 508 // by the module and which are considered to be part of the creating module. 509 // 510 // This is called before prebuilts are renamed so as to allow a dependency to be 511 // added directly to a prebuilt child module instead of depending on a source module 512 // and relying on prebuilt processing to switch to the prebuilt module if preferred. 513 // 514 // A dependency on a prebuilt must include the "prebuilt_" prefix. 515 ComponentDepsMutator(ctx BottomUpMutatorContext) 516 517 DepsMutator(BottomUpMutatorContext) 518 519 base() *ModuleBase 520 Disable() 521 Enabled() bool 522 Target() Target 523 MultiTargets() []Target 524 525 // ImageVariation returns the image variation of this module. 526 // 527 // The returned structure has its Mutator field set to "image" and its Variation field set to the 528 // image variation, e.g. recovery, ramdisk, etc.. The Variation field is "" for host modules and 529 // device modules that have no image variation. 530 ImageVariation() blueprint.Variation 531 532 Owner() string 533 InstallInData() bool 534 InstallInTestcases() bool 535 InstallInSanitizerDir() bool 536 InstallInRamdisk() bool 537 InstallInVendorRamdisk() bool 538 InstallInDebugRamdisk() bool 539 InstallInRecovery() bool 540 InstallInRoot() bool 541 InstallInVendor() bool 542 InstallForceOS() (*OsType, *ArchType) 543 PartitionTag(DeviceConfig) string 544 HideFromMake() 545 IsHideFromMake() bool 546 IsSkipInstall() bool 547 MakeUninstallable() 548 ReplacedByPrebuilt() 549 IsReplacedByPrebuilt() bool 550 ExportedToMake() bool 551 InitRc() Paths 552 VintfFragments() Paths 553 EffectiveLicenseKinds() []string 554 EffectiveLicenseFiles() Paths 555 556 AddProperties(props ...interface{}) 557 GetProperties() []interface{} 558 559 // IsConvertedByBp2build returns whether this module was converted via bp2build 560 IsConvertedByBp2build() bool 561 // Bp2buildTargets returns the target(s) generated for Bazel via bp2build for this module 562 Bp2buildTargets() []bp2buildInfo 563 GetUnconvertedBp2buildDeps() []string 564 GetMissingBp2buildDeps() []string 565 566 BuildParamsForTests() []BuildParams 567 RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams 568 VariablesForTests() map[string]string 569 570 // String returns a string that includes the module name and variants for printing during debugging. 571 String() string 572 573 // Get the qualified module id for this module. 574 qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName 575 576 // Get information about the properties that can contain visibility rules. 577 visibilityProperties() []visibilityProperty 578 579 RequiredModuleNames() []string 580 HostRequiredModuleNames() []string 581 TargetRequiredModuleNames() []string 582 583 FilesToInstall() InstallPaths 584 PackagingSpecs() []PackagingSpec 585 586 // TransitivePackagingSpecs returns the PackagingSpecs for this module and any transitive 587 // dependencies with dependency tags for which IsInstallDepNeeded() returns true. 588 TransitivePackagingSpecs() []PackagingSpec 589} 590 591// Qualified id for a module 592type qualifiedModuleName struct { 593 // The package (i.e. directory) in which the module is defined, without trailing / 594 pkg string 595 596 // The name of the module, empty string if package. 597 name string 598} 599 600func (q qualifiedModuleName) String() string { 601 if q.name == "" { 602 return "//" + q.pkg 603 } 604 return "//" + q.pkg + ":" + q.name 605} 606 607func (q qualifiedModuleName) isRootPackage() bool { 608 return q.pkg == "" && q.name == "" 609} 610 611// Get the id for the package containing this module. 612func (q qualifiedModuleName) getContainingPackageId() qualifiedModuleName { 613 pkg := q.pkg 614 if q.name == "" { 615 if pkg == "" { 616 panic(fmt.Errorf("Cannot get containing package id of root package")) 617 } 618 619 index := strings.LastIndex(pkg, "/") 620 if index == -1 { 621 pkg = "" 622 } else { 623 pkg = pkg[:index] 624 } 625 } 626 return newPackageId(pkg) 627} 628 629func newPackageId(pkg string) qualifiedModuleName { 630 // A qualified id for a package module has no name. 631 return qualifiedModuleName{pkg: pkg, name: ""} 632} 633 634type Dist struct { 635 // Copy the output of this module to the $DIST_DIR when `dist` is specified on the 636 // command line and any of these targets are also on the command line, or otherwise 637 // built 638 Targets []string `android:"arch_variant"` 639 640 // The name of the output artifact. This defaults to the basename of the output of 641 // the module. 642 Dest *string `android:"arch_variant"` 643 644 // The directory within the dist directory to store the artifact. Defaults to the 645 // top level directory (""). 646 Dir *string `android:"arch_variant"` 647 648 // A suffix to add to the artifact file name (before any extension). 649 Suffix *string `android:"arch_variant"` 650 651 // If true, then the artifact file will be appended with _<product name>. For 652 // example, if the product is coral and the module is an android_app module 653 // of name foo, then the artifact would be foo_coral.apk. If false, there is 654 // no change to the artifact file name. 655 Append_artifact_with_product *bool `android:"arch_variant"` 656 657 // A string tag to select the OutputFiles associated with the tag. 658 // 659 // If no tag is specified then it will select the default dist paths provided 660 // by the module type. If a tag of "" is specified then it will return the 661 // default output files provided by the modules, i.e. the result of calling 662 // OutputFiles(""). 663 Tag *string `android:"arch_variant"` 664} 665 666// NamedPath associates a path with a name. e.g. a license text path with a package name 667type NamedPath struct { 668 Path Path 669 Name string 670} 671 672// String returns an escaped string representing the `NamedPath`. 673func (p NamedPath) String() string { 674 if len(p.Name) > 0 { 675 return p.Path.String() + ":" + url.QueryEscape(p.Name) 676 } 677 return p.Path.String() 678} 679 680// NamedPaths describes a list of paths each associated with a name. 681type NamedPaths []NamedPath 682 683// Strings returns a list of escaped strings representing each `NamedPath` in the list. 684func (l NamedPaths) Strings() []string { 685 result := make([]string, 0, len(l)) 686 for _, p := range l { 687 result = append(result, p.String()) 688 } 689 return result 690} 691 692// SortedUniqueNamedPaths modifies `l` in place to return the sorted unique subset. 693func SortedUniqueNamedPaths(l NamedPaths) NamedPaths { 694 if len(l) == 0 { 695 return l 696 } 697 sort.Slice(l, func(i, j int) bool { 698 return l[i].String() < l[j].String() 699 }) 700 k := 0 701 for i := 1; i < len(l); i++ { 702 if l[i].String() == l[k].String() { 703 continue 704 } 705 k++ 706 if k < i { 707 l[k] = l[i] 708 } 709 } 710 return l[:k+1] 711} 712 713type nameProperties struct { 714 // The name of the module. Must be unique across all modules. 715 Name *string 716} 717 718type commonProperties struct { 719 // emit build rules for this module 720 // 721 // Disabling a module should only be done for those modules that cannot be built 722 // in the current environment. Modules that can build in the current environment 723 // but are not usually required (e.g. superceded by a prebuilt) should not be 724 // disabled as that will prevent them from being built by the checkbuild target 725 // and so prevent early detection of changes that have broken those modules. 726 Enabled *bool `android:"arch_variant"` 727 728 // Controls the visibility of this module to other modules. Allowable values are one or more of 729 // these formats: 730 // 731 // ["//visibility:public"]: Anyone can use this module. 732 // ["//visibility:private"]: Only rules in the module's package (not its subpackages) can use 733 // this module. 734 // ["//visibility:override"]: Discards any rules inherited from defaults or a creating module. 735 // Can only be used at the beginning of a list of visibility rules. 736 // ["//some/package:__pkg__", "//other/package:__pkg__"]: Only modules in some/package and 737 // other/package (defined in some/package/*.bp and other/package/*.bp) have access to 738 // this module. Note that sub-packages do not have access to the rule; for example, 739 // //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__ 740 // is a special module and must be used verbatim. It represents all of the modules in the 741 // package. 742 // ["//project:__subpackages__", "//other:__subpackages__"]: Only modules in packages project 743 // or other or in one of their sub-packages have access to this module. For example, 744 // //project:rule, //project/library:lib or //other/testing/internal:munge are allowed 745 // to depend on this rule (but not //independent:evil) 746 // ["//project"]: This is shorthand for ["//project:__pkg__"] 747 // [":__subpackages__"]: This is shorthand for ["//project:__subpackages__"] where 748 // //project is the module's package. e.g. using [":__subpackages__"] in 749 // packages/apps/Settings/Android.bp is equivalent to 750 // //packages/apps/Settings:__subpackages__. 751 // ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public 752 // for now. It is an error if it is used in a module. 753 // 754 // If a module does not specify the `visibility` property then it uses the 755 // `default_visibility` property of the `package` module in the module's package. 756 // 757 // If the `default_visibility` property is not set for the module's package then 758 // it will use the `default_visibility` of its closest ancestor package for which 759 // a `default_visibility` property is specified. 760 // 761 // If no `default_visibility` property can be found then the module uses the 762 // global default of `//visibility:legacy_public`. 763 // 764 // The `visibility` property has no effect on a defaults module although it does 765 // apply to any non-defaults module that uses it. To set the visibility of a 766 // defaults module, use the `defaults_visibility` property on the defaults module; 767 // not to be confused with the `default_visibility` property on the package module. 768 // 769 // See https://android.googlesource.com/platform/build/soong/+/master/README.md#visibility for 770 // more details. 771 Visibility []string 772 773 // Describes the licenses applicable to this module. Must reference license modules. 774 Licenses []string 775 776 // Flattened from direct license dependencies. Equal to Licenses unless particular module adds more. 777 Effective_licenses []string `blueprint:"mutated"` 778 // Override of module name when reporting licenses 779 Effective_package_name *string `blueprint:"mutated"` 780 // Notice files 781 Effective_license_text NamedPaths `blueprint:"mutated"` 782 // License names 783 Effective_license_kinds []string `blueprint:"mutated"` 784 // License conditions 785 Effective_license_conditions []string `blueprint:"mutated"` 786 787 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values 788 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both 789 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit 790 // platform). 791 Compile_multilib *string `android:"arch_variant"` 792 793 Target struct { 794 Host struct { 795 Compile_multilib *string 796 } 797 Android struct { 798 Compile_multilib *string 799 } 800 } 801 802 // If set to true then the archMutator will create variants for each arch specific target 803 // (e.g. 32/64) that the module is required to produce. If set to false then it will only 804 // create a variant for the architecture and will list the additional arch specific targets 805 // that the variant needs to produce in the CompileMultiTargets property. 806 UseTargetVariants bool `blueprint:"mutated"` 807 Default_multilib string `blueprint:"mutated"` 808 809 // whether this is a proprietary vendor module, and should be installed into /vendor 810 Proprietary *bool 811 812 // vendor who owns this module 813 Owner *string 814 815 // whether this module is specific to an SoC (System-On-a-Chip). When set to true, 816 // it is installed into /vendor (or /system/vendor if vendor partition does not exist). 817 // Use `soc_specific` instead for better meaning. 818 Vendor *bool 819 820 // whether this module is specific to an SoC (System-On-a-Chip). When set to true, 821 // it is installed into /vendor (or /system/vendor if vendor partition does not exist). 822 Soc_specific *bool 823 824 // whether this module is specific to a device, not only for SoC, but also for off-chip 825 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition 826 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist). 827 // This implies `soc_specific:true`. 828 Device_specific *bool 829 830 // whether this module is specific to a software configuration of a product (e.g. country, 831 // network operator, etc). When set to true, it is installed into /product (or 832 // /system/product if product partition does not exist). 833 Product_specific *bool 834 835 // whether this module extends system. When set to true, it is installed into /system_ext 836 // (or /system/system_ext if system_ext partition does not exist). 837 System_ext_specific *bool 838 839 // Whether this module is installed to recovery partition 840 Recovery *bool 841 842 // Whether this module is installed to ramdisk 843 Ramdisk *bool 844 845 // Whether this module is installed to vendor ramdisk 846 Vendor_ramdisk *bool 847 848 // Whether this module is installed to debug ramdisk 849 Debug_ramdisk *bool 850 851 // Whether this module is built for non-native architectures (also known as native bridge binary) 852 Native_bridge_supported *bool `android:"arch_variant"` 853 854 // init.rc files to be installed if this module is installed 855 Init_rc []string `android:"arch_variant,path"` 856 857 // VINTF manifest fragments to be installed if this module is installed 858 Vintf_fragments []string `android:"path"` 859 860 // names of other modules to install if this module is installed 861 Required []string `android:"arch_variant"` 862 863 // names of other modules to install on host if this module is installed 864 Host_required []string `android:"arch_variant"` 865 866 // names of other modules to install on target if this module is installed 867 Target_required []string `android:"arch_variant"` 868 869 // The OsType of artifacts that this module variant is responsible for creating. 870 // 871 // Set by osMutator 872 CompileOS OsType `blueprint:"mutated"` 873 874 // The Target of artifacts that this module variant is responsible for creating. 875 // 876 // Set by archMutator 877 CompileTarget Target `blueprint:"mutated"` 878 879 // The additional arch specific targets (e.g. 32/64 bit) that this module variant is 880 // responsible for creating. 881 // 882 // By default this is nil as, where necessary, separate variants are created for the 883 // different multilib types supported and that information is encapsulated in the 884 // CompileTarget so the module variant simply needs to create artifacts for that. 885 // 886 // However, if UseTargetVariants is set to false (e.g. by 887 // InitAndroidMultiTargetsArchModule) then no separate variants are created for the 888 // multilib targets. Instead a single variant is created for the architecture and 889 // this contains the multilib specific targets that this variant should create. 890 // 891 // Set by archMutator 892 CompileMultiTargets []Target `blueprint:"mutated"` 893 894 // True if the module variant's CompileTarget is the primary target 895 // 896 // Set by archMutator 897 CompilePrimary bool `blueprint:"mutated"` 898 899 // Set by InitAndroidModule 900 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"` 901 ArchSpecific bool `blueprint:"mutated"` 902 903 // If set to true then a CommonOS variant will be created which will have dependencies 904 // on all its OsType specific variants. Used by sdk/module_exports to create a snapshot 905 // that covers all os and architecture variants. 906 // 907 // The OsType specific variants can be retrieved by calling 908 // GetOsSpecificVariantsOfCommonOSVariant 909 // 910 // Set at module initialization time by calling InitCommonOSAndroidMultiTargetsArchModule 911 CreateCommonOSVariant bool `blueprint:"mutated"` 912 913 // If set to true then this variant is the CommonOS variant that has dependencies on its 914 // OsType specific variants. 915 // 916 // Set by osMutator. 917 CommonOSVariant bool `blueprint:"mutated"` 918 919 // When HideFromMake is set to true, no entry for this variant will be emitted in the 920 // generated Android.mk file. 921 HideFromMake bool `blueprint:"mutated"` 922 923 // When SkipInstall is set to true, calls to ctx.InstallFile, ctx.InstallExecutable, 924 // ctx.InstallSymlink and ctx.InstallAbsoluteSymlink act like calls to ctx.PackageFile 925 // and don't create a rule to install the file. 926 SkipInstall bool `blueprint:"mutated"` 927 928 // UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex 929 // mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant 930 // is used to avoid adding install or packaging dependencies into libraries provided 931 // by apexes. 932 UninstallableApexPlatformVariant bool `blueprint:"mutated"` 933 934 // Whether the module has been replaced by a prebuilt 935 ReplacedByPrebuilt bool `blueprint:"mutated"` 936 937 // Disabled by mutators. If set to true, it overrides Enabled property. 938 ForcedDisabled bool `blueprint:"mutated"` 939 940 NamespaceExportedToMake bool `blueprint:"mutated"` 941 942 MissingDeps []string `blueprint:"mutated"` 943 944 // Name and variant strings stored by mutators to enable Module.String() 945 DebugName string `blueprint:"mutated"` 946 DebugMutators []string `blueprint:"mutated"` 947 DebugVariations []string `blueprint:"mutated"` 948 949 // ImageVariation is set by ImageMutator to specify which image this variation is for, 950 // for example "" for core or "recovery" for recovery. It will often be set to one of the 951 // constants in image.go, but can also be set to a custom value by individual module types. 952 ImageVariation string `blueprint:"mutated"` 953 954 // Bazel conversion status 955 BazelConversionStatus BazelConversionStatus `blueprint:"mutated"` 956} 957 958// CommonAttributes represents the common Bazel attributes from which properties 959// in `commonProperties` are translated/mapped; such properties are annotated in 960// a list their corresponding attribute. It is embedded within `bp2buildInfo`. 961type CommonAttributes struct { 962 // Soong nameProperties -> Bazel name 963 Name string 964 965 // Data mapped from: Required 966 Data bazel.LabelListAttribute 967 968 // SkipData is neither a Soong nor Bazel target attribute 969 // If true, this will not fill the data attribute automatically 970 // This is useful for Soong modules that have 1:many Bazel targets 971 // Some of the generated Bazel targets might not have a data attribute 972 SkipData *bool 973 974 Tags bazel.StringListAttribute 975 976 Applicable_licenses bazel.LabelListAttribute 977 978 Testonly *bool 979} 980 981// constraintAttributes represents Bazel attributes pertaining to build constraints, 982// which make restrict building a Bazel target for some set of platforms. 983type constraintAttributes struct { 984 // Constraint values this target can be built for. 985 Target_compatible_with bazel.LabelListAttribute 986} 987 988type distProperties struct { 989 // configuration to distribute output files from this module to the distribution 990 // directory (default: $OUT/dist, configurable with $DIST_DIR) 991 Dist Dist `android:"arch_variant"` 992 993 // a list of configurations to distribute output files from this module to the 994 // distribution directory (default: $OUT/dist, configurable with $DIST_DIR) 995 Dists []Dist `android:"arch_variant"` 996} 997 998// CommonTestOptions represents the common `test_options` properties in 999// Android.bp. 1000type CommonTestOptions struct { 1001 // If the test is a hostside (no device required) unittest that shall be run 1002 // during presubmit check. 1003 Unit_test *bool 1004 1005 // Tags provide additional metadata to customize test execution by downstream 1006 // test runners. The tags have no special meaning to Soong. 1007 Tags []string 1008} 1009 1010// SetAndroidMkEntries sets AndroidMkEntries according to the value of base 1011// `test_options`. 1012func (t *CommonTestOptions) SetAndroidMkEntries(entries *AndroidMkEntries) { 1013 entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test)) 1014 if len(t.Tags) > 0 { 1015 entries.AddStrings("LOCAL_TEST_OPTIONS_TAGS", t.Tags...) 1016 } 1017} 1018 1019// The key to use in TaggedDistFiles when a Dist structure does not specify a 1020// tag property. This intentionally does not use "" as the default because that 1021// would mean that an empty tag would have a different meaning when used in a dist 1022// structure that when used to reference a specific set of output paths using the 1023// :module{tag} syntax, which passes tag to the OutputFiles(tag) method. 1024const DefaultDistTag = "<default-dist-tag>" 1025 1026// A map of OutputFile tag keys to Paths, for disting purposes. 1027type TaggedDistFiles map[string]Paths 1028 1029// addPathsForTag adds a mapping from the tag to the paths. If the map is nil 1030// then it will create a map, update it and then return it. If a mapping already 1031// exists for the tag then the paths are appended to the end of the current list 1032// of paths, ignoring any duplicates. 1033func (t TaggedDistFiles) addPathsForTag(tag string, paths ...Path) TaggedDistFiles { 1034 if t == nil { 1035 t = make(TaggedDistFiles) 1036 } 1037 1038 for _, distFile := range paths { 1039 if distFile != nil && !t[tag].containsPath(distFile) { 1040 t[tag] = append(t[tag], distFile) 1041 } 1042 } 1043 1044 return t 1045} 1046 1047// merge merges the entries from the other TaggedDistFiles object into this one. 1048// If the TaggedDistFiles is nil then it will create a new instance, merge the 1049// other into it, and then return it. 1050func (t TaggedDistFiles) merge(other TaggedDistFiles) TaggedDistFiles { 1051 for tag, paths := range other { 1052 t = t.addPathsForTag(tag, paths...) 1053 } 1054 1055 return t 1056} 1057 1058func MakeDefaultDistFiles(paths ...Path) TaggedDistFiles { 1059 for _, p := range paths { 1060 if p == nil { 1061 panic("The path to a dist file cannot be nil.") 1062 } 1063 } 1064 1065 // The default OutputFile tag is the empty "" string. 1066 return TaggedDistFiles{DefaultDistTag: paths} 1067} 1068 1069type hostAndDeviceProperties struct { 1070 // If set to true, build a variant of the module for the host. Defaults to false. 1071 Host_supported *bool 1072 1073 // If set to true, build a variant of the module for the device. Defaults to true. 1074 Device_supported *bool 1075} 1076 1077type Multilib string 1078 1079const ( 1080 MultilibBoth Multilib = "both" 1081 MultilibFirst Multilib = "first" 1082 MultilibCommon Multilib = "common" 1083 MultilibCommonFirst Multilib = "common_first" 1084) 1085 1086type HostOrDeviceSupported int 1087 1088const ( 1089 hostSupported = 1 << iota 1090 hostCrossSupported 1091 deviceSupported 1092 hostDefault 1093 deviceDefault 1094 1095 // Host and HostCross are built by default. Device is not supported. 1096 HostSupported = hostSupported | hostCrossSupported | hostDefault 1097 1098 // Host is built by default. HostCross and Device are not supported. 1099 HostSupportedNoCross = hostSupported | hostDefault 1100 1101 // Device is built by default. Host and HostCross are not supported. 1102 DeviceSupported = deviceSupported | deviceDefault 1103 1104 // By default, _only_ device variant is built. Device variant can be disabled with `device_supported: false` 1105 // Host and HostCross are disabled by default and can be enabled with `host_supported: true` 1106 HostAndDeviceSupported = hostSupported | hostCrossSupported | deviceSupported | deviceDefault 1107 1108 // Host, HostCross, and Device are built by default. 1109 // Building Device can be disabled with `device_supported: false` 1110 // Building Host and HostCross can be disabled with `host_supported: false` 1111 HostAndDeviceDefault = hostSupported | hostCrossSupported | hostDefault | 1112 deviceSupported | deviceDefault 1113 1114 // Nothing is supported. This is not exposed to the user, but used to mark a 1115 // host only module as unsupported when the module type is not supported on 1116 // the host OS. E.g. benchmarks are supported on Linux but not Darwin. 1117 NeitherHostNorDeviceSupported = 0 1118) 1119 1120type moduleKind int 1121 1122const ( 1123 platformModule moduleKind = iota 1124 deviceSpecificModule 1125 socSpecificModule 1126 productSpecificModule 1127 systemExtSpecificModule 1128) 1129 1130func (k moduleKind) String() string { 1131 switch k { 1132 case platformModule: 1133 return "platform" 1134 case deviceSpecificModule: 1135 return "device-specific" 1136 case socSpecificModule: 1137 return "soc-specific" 1138 case productSpecificModule: 1139 return "product-specific" 1140 case systemExtSpecificModule: 1141 return "systemext-specific" 1142 default: 1143 panic(fmt.Errorf("unknown module kind %d", k)) 1144 } 1145} 1146 1147func initAndroidModuleBase(m Module) { 1148 m.base().module = m 1149} 1150 1151// InitAndroidModule initializes the Module as an Android module that is not architecture-specific. 1152// It adds the common properties, for example "name" and "enabled". 1153func InitAndroidModule(m Module) { 1154 initAndroidModuleBase(m) 1155 base := m.base() 1156 1157 m.AddProperties( 1158 &base.nameProperties, 1159 &base.commonProperties, 1160 &base.distProperties) 1161 1162 initProductVariableModule(m) 1163 1164 // The default_visibility property needs to be checked and parsed by the visibility module during 1165 // its checking and parsing phases so make it the primary visibility property. 1166 setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility) 1167 1168 // The default_applicable_licenses property needs to be checked and parsed by the licenses module during 1169 // its checking and parsing phases so make it the primary licenses property. 1170 setPrimaryLicensesProperty(m, "licenses", &base.commonProperties.Licenses) 1171} 1172 1173// InitAndroidArchModule initializes the Module as an Android module that is architecture-specific. 1174// It adds the common properties, for example "name" and "enabled", as well as runtime generated 1175// property structs for architecture-specific versions of generic properties tagged with 1176// `android:"arch_variant"`. 1177// 1178// InitAndroidModule should not be called if InitAndroidArchModule was called. 1179func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) { 1180 InitAndroidModule(m) 1181 1182 base := m.base() 1183 base.commonProperties.HostOrDeviceSupported = hod 1184 base.commonProperties.Default_multilib = string(defaultMultilib) 1185 base.commonProperties.ArchSpecific = true 1186 base.commonProperties.UseTargetVariants = true 1187 1188 if hod&hostSupported != 0 && hod&deviceSupported != 0 { 1189 m.AddProperties(&base.hostAndDeviceProperties) 1190 } 1191 1192 initArchModule(m) 1193} 1194 1195// InitAndroidMultiTargetsArchModule initializes the Module as an Android module that is 1196// architecture-specific, but will only have a single variant per OS that handles all the 1197// architectures simultaneously. The list of Targets that it must handle will be available from 1198// ModuleContext.MultiTargets. It adds the common properties, for example "name" and "enabled", as 1199// well as runtime generated property structs for architecture-specific versions of generic 1200// properties tagged with `android:"arch_variant"`. 1201// 1202// InitAndroidModule or InitAndroidArchModule should not be called if 1203// InitAndroidMultiTargetsArchModule was called. 1204func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) { 1205 InitAndroidArchModule(m, hod, defaultMultilib) 1206 m.base().commonProperties.UseTargetVariants = false 1207} 1208 1209// InitCommonOSAndroidMultiTargetsArchModule initializes the Module as an Android module that is 1210// architecture-specific, but will only have a single variant per OS that handles all the 1211// architectures simultaneously, and will also have an additional CommonOS variant that has 1212// dependencies on all the OS-specific variants. The list of Targets that it must handle will be 1213// available from ModuleContext.MultiTargets. It adds the common properties, for example "name" and 1214// "enabled", as well as runtime generated property structs for architecture-specific versions of 1215// generic properties tagged with `android:"arch_variant"`. 1216// 1217// InitAndroidModule, InitAndroidArchModule or InitAndroidMultiTargetsArchModule should not be 1218// called if InitCommonOSAndroidMultiTargetsArchModule was called. 1219func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) { 1220 InitAndroidArchModule(m, hod, defaultMultilib) 1221 m.base().commonProperties.UseTargetVariants = false 1222 m.base().commonProperties.CreateCommonOSVariant = true 1223} 1224 1225func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutatorContext, 1226 enabledPropertyOverrides bazel.BoolAttribute) constraintAttributes { 1227 1228 mod := ctx.Module().base() 1229 // Assert passed-in attributes include Name 1230 if len(attrs.Name) == 0 { 1231 if ctx.ModuleType() != "package" { 1232 ctx.ModuleErrorf("CommonAttributes in fillCommonBp2BuildModuleAttrs expects a `.Name`!") 1233 } 1234 } 1235 1236 depsToLabelList := func(deps []string) bazel.LabelListAttribute { 1237 return bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, deps)) 1238 } 1239 1240 var enabledProperty bazel.BoolAttribute 1241 1242 onlyAndroid := false 1243 neitherHostNorDevice := false 1244 1245 osSupport := map[string]bool{} 1246 1247 // if the target is enabled and supports arch variance, determine the defaults based on the module 1248 // type's host or device property and host_supported/device_supported properties 1249 if mod.commonProperties.ArchSpecific { 1250 moduleSupportsDevice := mod.DeviceSupported() 1251 moduleSupportsHost := mod.HostSupported() 1252 if moduleSupportsHost && !moduleSupportsDevice { 1253 // for host only, we specify as unsupported on android rather than listing all host osSupport 1254 // TODO(b/220874839): consider replacing this with a constraint that covers all host osSupport 1255 // instead 1256 enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, Android.Name, proptools.BoolPtr(false)) 1257 } else if moduleSupportsDevice && !moduleSupportsHost { 1258 enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, Android.Name, proptools.BoolPtr(true)) 1259 // specify as a positive to ensure any target-specific enabled can be resolved 1260 // also save that a target is only android, as if there is only the positive restriction on 1261 // android, it'll be dropped, so we may need to add it back later 1262 onlyAndroid = true 1263 } else if !moduleSupportsHost && !moduleSupportsDevice { 1264 neitherHostNorDevice = true 1265 } 1266 1267 for _, osType := range OsTypeList() { 1268 if osType.Class == Host { 1269 osSupport[osType.Name] = moduleSupportsHost 1270 } else if osType.Class == Device { 1271 osSupport[osType.Name] = moduleSupportsDevice 1272 } 1273 } 1274 } 1275 1276 if neitherHostNorDevice { 1277 // we can't build this, disable 1278 enabledProperty.Value = proptools.BoolPtr(false) 1279 } else if mod.commonProperties.Enabled != nil { 1280 enabledProperty.SetValue(mod.commonProperties.Enabled) 1281 if !*mod.commonProperties.Enabled { 1282 for oss, enabled := range osSupport { 1283 if val := enabledProperty.SelectValue(bazel.OsConfigurationAxis, oss); enabled && val != nil && *val { 1284 // if this should be disabled by default, clear out any enabling we've done 1285 enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, oss, nil) 1286 } 1287 } 1288 } 1289 } 1290 1291 attrs.Applicable_licenses = bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, mod.commonProperties.Licenses)) 1292 1293 // The required property can contain the module itself. This causes a cycle 1294 // when generated as the 'data' label list attribute in Bazel. Remove it if 1295 // it exists. See b/247985196. 1296 _, requiredWithoutCycles := RemoveFromList(ctx.ModuleName(), mod.commonProperties.Required) 1297 requiredWithoutCycles = FirstUniqueStrings(requiredWithoutCycles) 1298 required := depsToLabelList(requiredWithoutCycles) 1299 archVariantProps := mod.GetArchVariantProperties(ctx, &commonProperties{}) 1300 for axis, configToProps := range archVariantProps { 1301 for config, _props := range configToProps { 1302 if archProps, ok := _props.(*commonProperties); ok { 1303 _, requiredWithoutCycles := RemoveFromList(ctx.ModuleName(), archProps.Required) 1304 requiredWithoutCycles = FirstUniqueStrings(requiredWithoutCycles) 1305 required.SetSelectValue(axis, config, depsToLabelList(requiredWithoutCycles).Value) 1306 if !neitherHostNorDevice { 1307 if archProps.Enabled != nil { 1308 if axis != bazel.OsConfigurationAxis || osSupport[config] { 1309 enabledProperty.SetSelectValue(axis, config, archProps.Enabled) 1310 } 1311 } 1312 } 1313 } 1314 } 1315 } 1316 1317 if !neitherHostNorDevice { 1318 if enabledPropertyOverrides.Value != nil { 1319 enabledProperty.Value = enabledPropertyOverrides.Value 1320 } 1321 for _, axis := range enabledPropertyOverrides.SortedConfigurationAxes() { 1322 configToBools := enabledPropertyOverrides.ConfigurableValues[axis] 1323 for cfg, val := range configToBools { 1324 if axis != bazel.OsConfigurationAxis || osSupport[cfg] { 1325 enabledProperty.SetSelectValue(axis, cfg, &val) 1326 } 1327 } 1328 } 1329 } 1330 1331 productConfigEnabledLabels := []bazel.Label{} 1332 // TODO(b/234497586): Soong config variables and product variables have different overriding behavior, we 1333 // should handle it correctly 1334 if !proptools.BoolDefault(enabledProperty.Value, true) && !neitherHostNorDevice { 1335 // If the module is not enabled by default, then we can check if a 1336 // product variable enables it 1337 productConfigEnabledLabels = productVariableConfigEnableLabels(ctx) 1338 1339 if len(productConfigEnabledLabels) > 0 { 1340 // In this case, an existing product variable configuration overrides any 1341 // module-level `enable: false` definition 1342 newValue := true 1343 enabledProperty.Value = &newValue 1344 } 1345 } 1346 1347 productConfigEnabledAttribute := bazel.MakeLabelListAttribute(bazel.LabelList{ 1348 productConfigEnabledLabels, nil, 1349 }) 1350 1351 platformEnabledAttribute, err := enabledProperty.ToLabelListAttribute( 1352 bazel.LabelList{[]bazel.Label{{Label: "@platforms//:incompatible"}}, nil}, 1353 bazel.LabelList{[]bazel.Label{}, nil}) 1354 if err != nil { 1355 ctx.ModuleErrorf("Error processing platform enabled attribute: %s", err) 1356 } 1357 1358 // if android is the only arch/os enabled, then add a restriction to only be compatible with android 1359 if platformEnabledAttribute.IsNil() && onlyAndroid { 1360 l := bazel.LabelAttribute{} 1361 l.SetValue(bazel.Label{Label: bazel.OsConfigurationAxis.SelectKey(Android.Name)}) 1362 platformEnabledAttribute.Add(&l) 1363 } 1364 1365 if !proptools.Bool(attrs.SkipData) { 1366 attrs.Data.Append(required) 1367 } 1368 // SkipData is not an attribute of any Bazel target 1369 // Set this to nil so that it does not appear in the generated build file 1370 attrs.SkipData = nil 1371 1372 moduleEnableConstraints := bazel.LabelListAttribute{} 1373 moduleEnableConstraints.Append(platformEnabledAttribute) 1374 moduleEnableConstraints.Append(productConfigEnabledAttribute) 1375 1376 return constraintAttributes{Target_compatible_with: moduleEnableConstraints} 1377} 1378 1379// Check product variables for `enabled: true` flag override. 1380// Returns a list of the constraint_value targets who enable this override. 1381func productVariableConfigEnableLabels(ctx *topDownMutatorContext) []bazel.Label { 1382 productVariableProps := ProductVariableProperties(ctx, ctx.Module()) 1383 productConfigEnablingTargets := []bazel.Label{} 1384 const propName = "Enabled" 1385 if productConfigProps, exists := productVariableProps[propName]; exists { 1386 for productConfigProp, prop := range productConfigProps { 1387 flag, ok := prop.(*bool) 1388 if !ok { 1389 ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName)) 1390 } 1391 1392 if *flag { 1393 axis := productConfigProp.ConfigurationAxis() 1394 targetLabel := axis.SelectKey(productConfigProp.SelectKey()) 1395 productConfigEnablingTargets = append(productConfigEnablingTargets, bazel.Label{ 1396 Label: targetLabel, 1397 }) 1398 } else { 1399 // TODO(b/210546943): handle negative case where `enabled: false` 1400 ctx.ModuleErrorf("`enabled: false` is not currently supported for configuration variables. See b/210546943", proptools.PropertyNameForField(propName)) 1401 } 1402 } 1403 } 1404 1405 return productConfigEnablingTargets 1406} 1407 1408// A ModuleBase object contains the properties that are common to all Android 1409// modules. It should be included as an anonymous field in every module 1410// struct definition. InitAndroidModule should then be called from the module's 1411// factory function, and the return values from InitAndroidModule should be 1412// returned from the factory function. 1413// 1414// The ModuleBase type is responsible for implementing the GenerateBuildActions 1415// method to support the blueprint.Module interface. This method will then call 1416// the module's GenerateAndroidBuildActions method once for each build variant 1417// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext 1418// rather than the usual blueprint.ModuleContext. 1419// ModuleContext exposes extra functionality specific to the Android build 1420// system including details about the particular build variant that is to be 1421// generated. 1422// 1423// For example: 1424// 1425// import ( 1426// "android/soong/android" 1427// ) 1428// 1429// type myModule struct { 1430// android.ModuleBase 1431// properties struct { 1432// MyProperty string 1433// } 1434// } 1435// 1436// func NewMyModule() android.Module { 1437// m := &myModule{} 1438// m.AddProperties(&m.properties) 1439// android.InitAndroidModule(m) 1440// return m 1441// } 1442// 1443// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1444// // Get the CPU architecture for the current build variant. 1445// variantArch := ctx.Arch() 1446// 1447// // ... 1448// } 1449type ModuleBase struct { 1450 // Putting the curiously recurring thing pointing to the thing that contains 1451 // the thing pattern to good use. 1452 // TODO: remove this 1453 module Module 1454 1455 nameProperties nameProperties 1456 commonProperties commonProperties 1457 distProperties distProperties 1458 variableProperties interface{} 1459 hostAndDeviceProperties hostAndDeviceProperties 1460 1461 // Arch specific versions of structs in GetProperties() prior to 1462 // initialization in InitAndroidArchModule, lets call it `generalProperties`. 1463 // The outer index has the same order as generalProperties and the inner index 1464 // chooses the props specific to the architecture. The interface{} value is an 1465 // archPropRoot that is filled with arch specific values by the arch mutator. 1466 archProperties [][]interface{} 1467 1468 // Properties specific to the Blueprint to BUILD migration. 1469 bazelTargetModuleProperties bazel.BazelTargetModuleProperties 1470 1471 // Information about all the properties on the module that contains visibility rules that need 1472 // checking. 1473 visibilityPropertyInfo []visibilityProperty 1474 1475 // The primary visibility property, may be nil, that controls access to the module. 1476 primaryVisibilityProperty visibilityProperty 1477 1478 // The primary licenses property, may be nil, records license metadata for the module. 1479 primaryLicensesProperty applicableLicensesProperty 1480 1481 noAddressSanitizer bool 1482 installFiles InstallPaths 1483 installFilesDepSet *installPathsDepSet 1484 checkbuildFiles Paths 1485 packagingSpecs []PackagingSpec 1486 packagingSpecsDepSet *packagingSpecsDepSet 1487 // katiInstalls tracks the install rules that were created by Soong but are being exported 1488 // to Make to convert to ninja rules so that Make can add additional dependencies. 1489 katiInstalls katiInstalls 1490 katiSymlinks katiInstalls 1491 1492 // The files to copy to the dist as explicitly specified in the .bp file. 1493 distFiles TaggedDistFiles 1494 1495 // Used by buildTargetSingleton to create checkbuild and per-directory build targets 1496 // Only set on the final variant of each module 1497 installTarget WritablePath 1498 checkbuildTarget WritablePath 1499 blueprintDir string 1500 1501 hooks hooks 1502 1503 registerProps []interface{} 1504 1505 // For tests 1506 buildParams []BuildParams 1507 ruleParams map[blueprint.Rule]blueprint.RuleParams 1508 variables map[string]string 1509 1510 initRcPaths Paths 1511 vintfFragmentsPaths Paths 1512 1513 // set of dependency module:location mappings used to populate the license metadata for 1514 // apex containers. 1515 licenseInstallMap []string 1516 1517 // The path to the generated license metadata file for the module. 1518 licenseMetadataFile WritablePath 1519} 1520 1521// A struct containing all relevant information about a Bazel target converted via bp2build. 1522type bp2buildInfo struct { 1523 Dir string 1524 BazelProps bazel.BazelTargetModuleProperties 1525 CommonAttrs CommonAttributes 1526 ConstraintAttrs constraintAttributes 1527 Attrs interface{} 1528} 1529 1530// TargetName returns the Bazel target name of a bp2build converted target. 1531func (b bp2buildInfo) TargetName() string { 1532 return b.CommonAttrs.Name 1533} 1534 1535// TargetPackage returns the Bazel package of a bp2build converted target. 1536func (b bp2buildInfo) TargetPackage() string { 1537 return b.Dir 1538} 1539 1540// BazelRuleClass returns the Bazel rule class of a bp2build converted target. 1541func (b bp2buildInfo) BazelRuleClass() string { 1542 return b.BazelProps.Rule_class 1543} 1544 1545// BazelRuleLoadLocation returns the location of the Bazel rule of a bp2build converted target. 1546// This may be empty as native Bazel rules do not need to be loaded. 1547func (b bp2buildInfo) BazelRuleLoadLocation() string { 1548 return b.BazelProps.Bzl_load_location 1549} 1550 1551// BazelAttributes returns the Bazel attributes of a bp2build converted target. 1552func (b bp2buildInfo) BazelAttributes() []interface{} { 1553 return []interface{}{&b.CommonAttrs, &b.ConstraintAttrs, b.Attrs} 1554} 1555 1556func (m *ModuleBase) addBp2buildInfo(info bp2buildInfo) { 1557 m.commonProperties.BazelConversionStatus.Bp2buildInfo = append(m.commonProperties.BazelConversionStatus.Bp2buildInfo, info) 1558} 1559 1560// IsConvertedByBp2build returns whether this module was converted via bp2build. 1561func (m *ModuleBase) IsConvertedByBp2build() bool { 1562 return len(m.commonProperties.BazelConversionStatus.Bp2buildInfo) > 0 1563} 1564 1565// Bp2buildTargets returns the Bazel targets bp2build generated for this module. 1566func (m *ModuleBase) Bp2buildTargets() []bp2buildInfo { 1567 return m.commonProperties.BazelConversionStatus.Bp2buildInfo 1568} 1569 1570// AddUnconvertedBp2buildDep stores module name of a dependency that was not converted to Bazel. 1571func (b *baseModuleContext) AddUnconvertedBp2buildDep(dep string) { 1572 unconvertedDeps := &b.Module().base().commonProperties.BazelConversionStatus.UnconvertedDeps 1573 *unconvertedDeps = append(*unconvertedDeps, dep) 1574} 1575 1576// AddMissingBp2buildDep stores module name of a dependency that was not found in a Android.bp file. 1577func (b *baseModuleContext) AddMissingBp2buildDep(dep string) { 1578 missingDeps := &b.Module().base().commonProperties.BazelConversionStatus.MissingDeps 1579 *missingDeps = append(*missingDeps, dep) 1580} 1581 1582// GetUnconvertedBp2buildDeps returns the list of module names of this module's direct dependencies that 1583// were not converted to Bazel. 1584func (m *ModuleBase) GetUnconvertedBp2buildDeps() []string { 1585 return FirstUniqueStrings(m.commonProperties.BazelConversionStatus.UnconvertedDeps) 1586} 1587 1588// GetMissingBp2buildDeps returns the list of module names that were not found in Android.bp files. 1589func (m *ModuleBase) GetMissingBp2buildDeps() []string { 1590 return FirstUniqueStrings(m.commonProperties.BazelConversionStatus.MissingDeps) 1591} 1592 1593func (m *ModuleBase) AddJSONData(d *map[string]interface{}) { 1594 (*d)["Android"] = map[string]interface{}{ 1595 // Properties set in Blueprint or in blueprint of a defaults modules 1596 "SetProperties": m.propertiesWithValues(), 1597 } 1598} 1599 1600type propInfo struct { 1601 Name string 1602 Type string 1603 Value string 1604 Values []string 1605} 1606 1607func (m *ModuleBase) propertiesWithValues() []propInfo { 1608 var info []propInfo 1609 props := m.GetProperties() 1610 1611 var propsWithValues func(name string, v reflect.Value) 1612 propsWithValues = func(name string, v reflect.Value) { 1613 kind := v.Kind() 1614 switch kind { 1615 case reflect.Ptr, reflect.Interface: 1616 if v.IsNil() { 1617 return 1618 } 1619 propsWithValues(name, v.Elem()) 1620 case reflect.Struct: 1621 if v.IsZero() { 1622 return 1623 } 1624 for i := 0; i < v.NumField(); i++ { 1625 namePrefix := name 1626 sTyp := v.Type().Field(i) 1627 if proptools.ShouldSkipProperty(sTyp) { 1628 continue 1629 } 1630 if name != "" && !strings.HasSuffix(namePrefix, ".") { 1631 namePrefix += "." 1632 } 1633 if !proptools.IsEmbedded(sTyp) { 1634 namePrefix += sTyp.Name 1635 } 1636 sVal := v.Field(i) 1637 propsWithValues(namePrefix, sVal) 1638 } 1639 case reflect.Array, reflect.Slice: 1640 if v.IsNil() { 1641 return 1642 } 1643 elKind := v.Type().Elem().Kind() 1644 info = append(info, propInfo{Name: name, Type: elKind.String() + " " + kind.String(), Values: sliceReflectionValue(v)}) 1645 default: 1646 info = append(info, propInfo{Name: name, Type: kind.String(), Value: reflectionValue(v)}) 1647 } 1648 } 1649 1650 for _, p := range props { 1651 propsWithValues("", reflect.ValueOf(p).Elem()) 1652 } 1653 sort.Slice(info, func(i, j int) bool { 1654 return info[i].Name < info[j].Name 1655 }) 1656 return info 1657} 1658 1659func reflectionValue(value reflect.Value) string { 1660 switch value.Kind() { 1661 case reflect.Bool: 1662 return fmt.Sprintf("%t", value.Bool()) 1663 case reflect.Int64: 1664 return fmt.Sprintf("%d", value.Int()) 1665 case reflect.String: 1666 return fmt.Sprintf("%s", value.String()) 1667 case reflect.Struct: 1668 if value.IsZero() { 1669 return "{}" 1670 } 1671 length := value.NumField() 1672 vals := make([]string, length, length) 1673 for i := 0; i < length; i++ { 1674 sTyp := value.Type().Field(i) 1675 if proptools.ShouldSkipProperty(sTyp) { 1676 continue 1677 } 1678 name := sTyp.Name 1679 vals[i] = fmt.Sprintf("%s: %s", name, reflectionValue(value.Field(i))) 1680 } 1681 return fmt.Sprintf("%s{%s}", value.Type(), strings.Join(vals, ", ")) 1682 case reflect.Array, reflect.Slice: 1683 vals := sliceReflectionValue(value) 1684 return fmt.Sprintf("[%s]", strings.Join(vals, ", ")) 1685 } 1686 return "" 1687} 1688 1689func sliceReflectionValue(value reflect.Value) []string { 1690 length := value.Len() 1691 vals := make([]string, length, length) 1692 for i := 0; i < length; i++ { 1693 vals[i] = reflectionValue(value.Index(i)) 1694 } 1695 return vals 1696} 1697 1698func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {} 1699 1700func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {} 1701 1702// AddProperties "registers" the provided props 1703// each value in props MUST be a pointer to a struct 1704func (m *ModuleBase) AddProperties(props ...interface{}) { 1705 m.registerProps = append(m.registerProps, props...) 1706} 1707 1708func (m *ModuleBase) GetProperties() []interface{} { 1709 return m.registerProps 1710} 1711 1712func (m *ModuleBase) BuildParamsForTests() []BuildParams { 1713 // Expand the references to module variables like $flags[0-9]*, 1714 // so we do not need to change many existing unit tests. 1715 // This looks like undoing the shareFlags optimization in cc's 1716 // transformSourceToObj, and should only affects unit tests. 1717 vars := m.VariablesForTests() 1718 buildParams := append([]BuildParams(nil), m.buildParams...) 1719 for i := range buildParams { 1720 newArgs := make(map[string]string) 1721 for k, v := range buildParams[i].Args { 1722 newArgs[k] = v 1723 // Replaces both ${flags1} and $flags1 syntax. 1724 if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") { 1725 if value, found := vars[v[2:len(v)-1]]; found { 1726 newArgs[k] = value 1727 } 1728 } else if strings.HasPrefix(v, "$") { 1729 if value, found := vars[v[1:]]; found { 1730 newArgs[k] = value 1731 } 1732 } 1733 } 1734 buildParams[i].Args = newArgs 1735 } 1736 return buildParams 1737} 1738 1739func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams { 1740 return m.ruleParams 1741} 1742 1743func (m *ModuleBase) VariablesForTests() map[string]string { 1744 return m.variables 1745} 1746 1747// Name returns the name of the module. It may be overridden by individual module types, for 1748// example prebuilts will prepend prebuilt_ to the name. 1749func (m *ModuleBase) Name() string { 1750 return String(m.nameProperties.Name) 1751} 1752 1753// String returns a string that includes the module name and variants for printing during debugging. 1754func (m *ModuleBase) String() string { 1755 sb := strings.Builder{} 1756 sb.WriteString(m.commonProperties.DebugName) 1757 sb.WriteString("{") 1758 for i := range m.commonProperties.DebugMutators { 1759 if i != 0 { 1760 sb.WriteString(",") 1761 } 1762 sb.WriteString(m.commonProperties.DebugMutators[i]) 1763 sb.WriteString(":") 1764 sb.WriteString(m.commonProperties.DebugVariations[i]) 1765 } 1766 sb.WriteString("}") 1767 return sb.String() 1768} 1769 1770// BaseModuleName returns the name of the module as specified in the blueprints file. 1771func (m *ModuleBase) BaseModuleName() string { 1772 return String(m.nameProperties.Name) 1773} 1774 1775func (m *ModuleBase) base() *ModuleBase { 1776 return m 1777} 1778 1779func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName { 1780 return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()} 1781} 1782 1783func (m *ModuleBase) visibilityProperties() []visibilityProperty { 1784 return m.visibilityPropertyInfo 1785} 1786 1787func (m *ModuleBase) Dists() []Dist { 1788 if len(m.distProperties.Dist.Targets) > 0 { 1789 // Make a copy of the underlying Dists slice to protect against 1790 // backing array modifications with repeated calls to this method. 1791 distsCopy := append([]Dist(nil), m.distProperties.Dists...) 1792 return append(distsCopy, m.distProperties.Dist) 1793 } else { 1794 return m.distProperties.Dists 1795 } 1796} 1797 1798func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFiles { 1799 var distFiles TaggedDistFiles 1800 for _, dist := range m.Dists() { 1801 // If no tag is specified then it means to use the default dist paths so use 1802 // the special tag name which represents that. 1803 tag := proptools.StringDefault(dist.Tag, DefaultDistTag) 1804 1805 if outputFileProducer, ok := m.module.(OutputFileProducer); ok { 1806 // Call the OutputFiles(tag) method to get the paths associated with the tag. 1807 distFilesForTag, err := outputFileProducer.OutputFiles(tag) 1808 1809 // If the tag was not supported and is not DefaultDistTag then it is an error. 1810 // Failing to find paths for DefaultDistTag is not an error. It just means 1811 // that the module type requires the legacy behavior. 1812 if err != nil && tag != DefaultDistTag { 1813 ctx.PropertyErrorf("dist.tag", "%s", err.Error()) 1814 } 1815 1816 distFiles = distFiles.addPathsForTag(tag, distFilesForTag...) 1817 } else if tag != DefaultDistTag { 1818 // If the tag was specified then it is an error if the module does not 1819 // implement OutputFileProducer because there is no other way of accessing 1820 // the paths for the specified tag. 1821 ctx.PropertyErrorf("dist.tag", 1822 "tag %s not supported because the module does not implement OutputFileProducer", tag) 1823 } 1824 } 1825 1826 return distFiles 1827} 1828 1829func (m *ModuleBase) Target() Target { 1830 return m.commonProperties.CompileTarget 1831} 1832 1833func (m *ModuleBase) TargetPrimary() bool { 1834 return m.commonProperties.CompilePrimary 1835} 1836 1837func (m *ModuleBase) MultiTargets() []Target { 1838 return m.commonProperties.CompileMultiTargets 1839} 1840 1841func (m *ModuleBase) Os() OsType { 1842 return m.Target().Os 1843} 1844 1845func (m *ModuleBase) Host() bool { 1846 return m.Os().Class == Host 1847} 1848 1849func (m *ModuleBase) Device() bool { 1850 return m.Os().Class == Device 1851} 1852 1853func (m *ModuleBase) Arch() Arch { 1854 return m.Target().Arch 1855} 1856 1857func (m *ModuleBase) ArchSpecific() bool { 1858 return m.commonProperties.ArchSpecific 1859} 1860 1861// True if the current variant is a CommonOS variant, false otherwise. 1862func (m *ModuleBase) IsCommonOSVariant() bool { 1863 return m.commonProperties.CommonOSVariant 1864} 1865 1866// supportsTarget returns true if the given Target is supported by the current module. 1867func (m *ModuleBase) supportsTarget(target Target) bool { 1868 switch target.Os.Class { 1869 case Host: 1870 if target.HostCross { 1871 return m.HostCrossSupported() 1872 } else { 1873 return m.HostSupported() 1874 } 1875 case Device: 1876 return m.DeviceSupported() 1877 default: 1878 return false 1879 } 1880} 1881 1882// DeviceSupported returns true if the current module is supported and enabled for device targets, 1883// i.e. the factory method set the HostOrDeviceSupported value to include device support and 1884// the device support is enabled by default or enabled by the device_supported property. 1885func (m *ModuleBase) DeviceSupported() bool { 1886 hod := m.commonProperties.HostOrDeviceSupported 1887 // deviceEnabled is true if the device_supported property is true or the HostOrDeviceSupported 1888 // value has the deviceDefault bit set. 1889 deviceEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Device_supported, hod&deviceDefault != 0) 1890 return hod&deviceSupported != 0 && deviceEnabled 1891} 1892 1893// HostSupported returns true if the current module is supported and enabled for host targets, 1894// i.e. the factory method set the HostOrDeviceSupported value to include host support and 1895// the host support is enabled by default or enabled by the host_supported property. 1896func (m *ModuleBase) HostSupported() bool { 1897 hod := m.commonProperties.HostOrDeviceSupported 1898 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported 1899 // value has the hostDefault bit set. 1900 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0) 1901 return hod&hostSupported != 0 && hostEnabled 1902} 1903 1904// HostCrossSupported returns true if the current module is supported and enabled for host cross 1905// targets, i.e. the factory method set the HostOrDeviceSupported value to include host cross 1906// support and the host cross support is enabled by default or enabled by the 1907// host_supported property. 1908func (m *ModuleBase) HostCrossSupported() bool { 1909 hod := m.commonProperties.HostOrDeviceSupported 1910 // hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported 1911 // value has the hostDefault bit set. 1912 hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0) 1913 return hod&hostCrossSupported != 0 && hostEnabled 1914} 1915 1916func (m *ModuleBase) Platform() bool { 1917 return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.SystemExtSpecific() 1918} 1919 1920func (m *ModuleBase) DeviceSpecific() bool { 1921 return Bool(m.commonProperties.Device_specific) 1922} 1923 1924func (m *ModuleBase) SocSpecific() bool { 1925 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific) 1926} 1927 1928func (m *ModuleBase) ProductSpecific() bool { 1929 return Bool(m.commonProperties.Product_specific) 1930} 1931 1932func (m *ModuleBase) SystemExtSpecific() bool { 1933 return Bool(m.commonProperties.System_ext_specific) 1934} 1935 1936// RequiresStableAPIs returns true if the module will be installed to a partition that may 1937// be updated separately from the system image. 1938func (m *ModuleBase) RequiresStableAPIs(ctx BaseModuleContext) bool { 1939 return m.SocSpecific() || m.DeviceSpecific() || 1940 (m.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) 1941} 1942 1943func (m *ModuleBase) PartitionTag(config DeviceConfig) string { 1944 partition := "system" 1945 if m.SocSpecific() { 1946 // A SoC-specific module could be on the vendor partition at 1947 // "vendor" or the system partition at "system/vendor". 1948 if config.VendorPath() == "vendor" { 1949 partition = "vendor" 1950 } 1951 } else if m.DeviceSpecific() { 1952 // A device-specific module could be on the odm partition at 1953 // "odm", the vendor partition at "vendor/odm", or the system 1954 // partition at "system/vendor/odm". 1955 if config.OdmPath() == "odm" { 1956 partition = "odm" 1957 } else if strings.HasPrefix(config.OdmPath(), "vendor/") { 1958 partition = "vendor" 1959 } 1960 } else if m.ProductSpecific() { 1961 // A product-specific module could be on the product partition 1962 // at "product" or the system partition at "system/product". 1963 if config.ProductPath() == "product" { 1964 partition = "product" 1965 } 1966 } else if m.SystemExtSpecific() { 1967 // A system_ext-specific module could be on the system_ext 1968 // partition at "system_ext" or the system partition at 1969 // "system/system_ext". 1970 if config.SystemExtPath() == "system_ext" { 1971 partition = "system_ext" 1972 } 1973 } 1974 return partition 1975} 1976 1977func (m *ModuleBase) Enabled() bool { 1978 if m.commonProperties.ForcedDisabled { 1979 return false 1980 } 1981 if m.commonProperties.Enabled == nil { 1982 return !m.Os().DefaultDisabled 1983 } 1984 return *m.commonProperties.Enabled 1985} 1986 1987func (m *ModuleBase) Disable() { 1988 m.commonProperties.ForcedDisabled = true 1989} 1990 1991// HideFromMake marks this variant so that it is not emitted in the generated Android.mk file. 1992func (m *ModuleBase) HideFromMake() { 1993 m.commonProperties.HideFromMake = true 1994} 1995 1996// IsHideFromMake returns true if HideFromMake was previously called. 1997func (m *ModuleBase) IsHideFromMake() bool { 1998 return m.commonProperties.HideFromMake == true 1999} 2000 2001// SkipInstall marks this variant to not create install rules when ctx.Install* are called. 2002func (m *ModuleBase) SkipInstall() { 2003 m.commonProperties.SkipInstall = true 2004} 2005 2006// IsSkipInstall returns true if this variant is marked to not create install 2007// rules when ctx.Install* are called. 2008func (m *ModuleBase) IsSkipInstall() bool { 2009 return m.commonProperties.SkipInstall 2010} 2011 2012// Similar to HideFromMake, but if the AndroidMk entry would set 2013// LOCAL_UNINSTALLABLE_MODULE then this variant may still output that entry 2014// rather than leaving it out altogether. That happens in cases where it would 2015// have other side effects, in particular when it adds a NOTICE file target, 2016// which other install targets might depend on. 2017func (m *ModuleBase) MakeUninstallable() { 2018 m.commonProperties.UninstallableApexPlatformVariant = true 2019 m.HideFromMake() 2020} 2021 2022func (m *ModuleBase) ReplacedByPrebuilt() { 2023 m.commonProperties.ReplacedByPrebuilt = true 2024 m.HideFromMake() 2025} 2026 2027func (m *ModuleBase) IsReplacedByPrebuilt() bool { 2028 return m.commonProperties.ReplacedByPrebuilt 2029} 2030 2031func (m *ModuleBase) ExportedToMake() bool { 2032 return m.commonProperties.NamespaceExportedToMake 2033} 2034 2035func (m *ModuleBase) EffectiveLicenseKinds() []string { 2036 return m.commonProperties.Effective_license_kinds 2037} 2038 2039func (m *ModuleBase) EffectiveLicenseFiles() Paths { 2040 result := make(Paths, 0, len(m.commonProperties.Effective_license_text)) 2041 for _, p := range m.commonProperties.Effective_license_text { 2042 result = append(result, p.Path) 2043 } 2044 return result 2045} 2046 2047// computeInstallDeps finds the installed paths of all dependencies that have a dependency 2048// tag that is annotated as needing installation via the isInstallDepNeeded method. 2049func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]*installPathsDepSet, []*packagingSpecsDepSet) { 2050 var installDeps []*installPathsDepSet 2051 var packagingSpecs []*packagingSpecsDepSet 2052 ctx.VisitDirectDeps(func(dep Module) { 2053 if isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) { 2054 // Installation is still handled by Make, so anything hidden from Make is not 2055 // installable. 2056 if !dep.IsHideFromMake() && !dep.IsSkipInstall() { 2057 installDeps = append(installDeps, dep.base().installFilesDepSet) 2058 } 2059 // Add packaging deps even when the dependency is not installed so that uninstallable 2060 // modules can still be packaged. Often the package will be installed instead. 2061 packagingSpecs = append(packagingSpecs, dep.base().packagingSpecsDepSet) 2062 } 2063 }) 2064 2065 return installDeps, packagingSpecs 2066} 2067 2068// isInstallDepNeeded returns true if installing the output files of the current module 2069// should also install the output files of the given dependency and dependency tag. 2070func isInstallDepNeeded(dep Module, tag blueprint.DependencyTag) bool { 2071 // Don't add a dependency from the platform to a library provided by an apex. 2072 if dep.base().commonProperties.UninstallableApexPlatformVariant { 2073 return false 2074 } 2075 // Only install modules if the dependency tag is an InstallDepNeeded tag. 2076 return IsInstallDepNeededTag(tag) 2077} 2078 2079func (m *ModuleBase) FilesToInstall() InstallPaths { 2080 return m.installFiles 2081} 2082 2083func (m *ModuleBase) PackagingSpecs() []PackagingSpec { 2084 return m.packagingSpecs 2085} 2086 2087func (m *ModuleBase) TransitivePackagingSpecs() []PackagingSpec { 2088 return m.packagingSpecsDepSet.ToList() 2089} 2090 2091func (m *ModuleBase) NoAddressSanitizer() bool { 2092 return m.noAddressSanitizer 2093} 2094 2095func (m *ModuleBase) InstallInData() bool { 2096 return false 2097} 2098 2099func (m *ModuleBase) InstallInTestcases() bool { 2100 return false 2101} 2102 2103func (m *ModuleBase) InstallInSanitizerDir() bool { 2104 return false 2105} 2106 2107func (m *ModuleBase) InstallInRamdisk() bool { 2108 return Bool(m.commonProperties.Ramdisk) 2109} 2110 2111func (m *ModuleBase) InstallInVendorRamdisk() bool { 2112 return Bool(m.commonProperties.Vendor_ramdisk) 2113} 2114 2115func (m *ModuleBase) InstallInDebugRamdisk() bool { 2116 return Bool(m.commonProperties.Debug_ramdisk) 2117} 2118 2119func (m *ModuleBase) InstallInRecovery() bool { 2120 return Bool(m.commonProperties.Recovery) 2121} 2122 2123func (m *ModuleBase) InstallInVendor() bool { 2124 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Soc_specific) || Bool(m.commonProperties.Proprietary) 2125} 2126 2127func (m *ModuleBase) InstallInRoot() bool { 2128 return false 2129} 2130 2131func (m *ModuleBase) InstallForceOS() (*OsType, *ArchType) { 2132 return nil, nil 2133} 2134 2135func (m *ModuleBase) Owner() string { 2136 return String(m.commonProperties.Owner) 2137} 2138 2139func (m *ModuleBase) setImageVariation(variant string) { 2140 m.commonProperties.ImageVariation = variant 2141} 2142 2143func (m *ModuleBase) ImageVariation() blueprint.Variation { 2144 return blueprint.Variation{ 2145 Mutator: "image", 2146 Variation: m.base().commonProperties.ImageVariation, 2147 } 2148} 2149 2150func (m *ModuleBase) getVariationByMutatorName(mutator string) string { 2151 for i, v := range m.commonProperties.DebugMutators { 2152 if v == mutator { 2153 return m.commonProperties.DebugVariations[i] 2154 } 2155 } 2156 2157 return "" 2158} 2159 2160func (m *ModuleBase) InRamdisk() bool { 2161 return m.base().commonProperties.ImageVariation == RamdiskVariation 2162} 2163 2164func (m *ModuleBase) InVendorRamdisk() bool { 2165 return m.base().commonProperties.ImageVariation == VendorRamdiskVariation 2166} 2167 2168func (m *ModuleBase) InDebugRamdisk() bool { 2169 return m.base().commonProperties.ImageVariation == DebugRamdiskVariation 2170} 2171 2172func (m *ModuleBase) InRecovery() bool { 2173 return m.base().commonProperties.ImageVariation == RecoveryVariation 2174} 2175 2176func (m *ModuleBase) RequiredModuleNames() []string { 2177 return m.base().commonProperties.Required 2178} 2179 2180func (m *ModuleBase) HostRequiredModuleNames() []string { 2181 return m.base().commonProperties.Host_required 2182} 2183 2184func (m *ModuleBase) TargetRequiredModuleNames() []string { 2185 return m.base().commonProperties.Target_required 2186} 2187 2188func (m *ModuleBase) InitRc() Paths { 2189 return append(Paths{}, m.initRcPaths...) 2190} 2191 2192func (m *ModuleBase) VintfFragments() Paths { 2193 return append(Paths{}, m.vintfFragmentsPaths...) 2194} 2195 2196func (m *ModuleBase) CompileMultilib() *string { 2197 return m.base().commonProperties.Compile_multilib 2198} 2199 2200// SetLicenseInstallMap stores the set of dependency module:location mappings for files in an 2201// apex container for use when generation the license metadata file. 2202func (m *ModuleBase) SetLicenseInstallMap(installMap []string) { 2203 m.licenseInstallMap = append(m.licenseInstallMap, installMap...) 2204} 2205 2206func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) { 2207 var allInstalledFiles InstallPaths 2208 var allCheckbuildFiles Paths 2209 ctx.VisitAllModuleVariants(func(module Module) { 2210 a := module.base() 2211 allInstalledFiles = append(allInstalledFiles, a.installFiles...) 2212 // A module's -checkbuild phony targets should 2213 // not be created if the module is not exported to make. 2214 // Those could depend on the build target and fail to compile 2215 // for the current build target. 2216 if !ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(a) { 2217 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...) 2218 } 2219 }) 2220 2221 var deps Paths 2222 2223 namespacePrefix := ctx.Namespace().id 2224 if namespacePrefix != "" { 2225 namespacePrefix = namespacePrefix + "-" 2226 } 2227 2228 if len(allInstalledFiles) > 0 { 2229 name := namespacePrefix + ctx.ModuleName() + "-install" 2230 ctx.Phony(name, allInstalledFiles.Paths()...) 2231 m.installTarget = PathForPhony(ctx, name) 2232 deps = append(deps, m.installTarget) 2233 } 2234 2235 if len(allCheckbuildFiles) > 0 { 2236 name := namespacePrefix + ctx.ModuleName() + "-checkbuild" 2237 ctx.Phony(name, allCheckbuildFiles...) 2238 m.checkbuildTarget = PathForPhony(ctx, name) 2239 deps = append(deps, m.checkbuildTarget) 2240 } 2241 2242 if len(deps) > 0 { 2243 suffix := "" 2244 if ctx.Config().KatiEnabled() { 2245 suffix = "-soong" 2246 } 2247 2248 ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...) 2249 2250 m.blueprintDir = ctx.ModuleDir() 2251 } 2252} 2253 2254func determineModuleKind(m *ModuleBase, ctx blueprint.EarlyModuleContext) moduleKind { 2255 var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific) 2256 var deviceSpecific = Bool(m.commonProperties.Device_specific) 2257 var productSpecific = Bool(m.commonProperties.Product_specific) 2258 var systemExtSpecific = Bool(m.commonProperties.System_ext_specific) 2259 2260 msg := "conflicting value set here" 2261 if socSpecific && deviceSpecific { 2262 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.") 2263 if Bool(m.commonProperties.Vendor) { 2264 ctx.PropertyErrorf("vendor", msg) 2265 } 2266 if Bool(m.commonProperties.Proprietary) { 2267 ctx.PropertyErrorf("proprietary", msg) 2268 } 2269 if Bool(m.commonProperties.Soc_specific) { 2270 ctx.PropertyErrorf("soc_specific", msg) 2271 } 2272 } 2273 2274 if productSpecific && systemExtSpecific { 2275 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and system_ext at the same time.") 2276 ctx.PropertyErrorf("system_ext_specific", msg) 2277 } 2278 2279 if (socSpecific || deviceSpecific) && (productSpecific || systemExtSpecific) { 2280 if productSpecific { 2281 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.") 2282 } else { 2283 ctx.PropertyErrorf("system_ext_specific", "a module cannot be specific to SoC or device and system_ext at the same time.") 2284 } 2285 if deviceSpecific { 2286 ctx.PropertyErrorf("device_specific", msg) 2287 } else { 2288 if Bool(m.commonProperties.Vendor) { 2289 ctx.PropertyErrorf("vendor", msg) 2290 } 2291 if Bool(m.commonProperties.Proprietary) { 2292 ctx.PropertyErrorf("proprietary", msg) 2293 } 2294 if Bool(m.commonProperties.Soc_specific) { 2295 ctx.PropertyErrorf("soc_specific", msg) 2296 } 2297 } 2298 } 2299 2300 if productSpecific { 2301 return productSpecificModule 2302 } else if systemExtSpecific { 2303 return systemExtSpecificModule 2304 } else if deviceSpecific { 2305 return deviceSpecificModule 2306 } else if socSpecific { 2307 return socSpecificModule 2308 } else { 2309 return platformModule 2310 } 2311} 2312 2313func (m *ModuleBase) earlyModuleContextFactory(ctx blueprint.EarlyModuleContext) earlyModuleContext { 2314 return earlyModuleContext{ 2315 EarlyModuleContext: ctx, 2316 kind: determineModuleKind(m, ctx), 2317 config: ctx.Config().(Config), 2318 } 2319} 2320 2321func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext { 2322 return baseModuleContext{ 2323 bp: ctx, 2324 earlyModuleContext: m.earlyModuleContextFactory(ctx), 2325 os: m.commonProperties.CompileOS, 2326 target: m.commonProperties.CompileTarget, 2327 targetPrimary: m.commonProperties.CompilePrimary, 2328 multiTargets: m.commonProperties.CompileMultiTargets, 2329 } 2330} 2331 2332func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) { 2333 ctx := &moduleContext{ 2334 module: m.module, 2335 bp: blueprintCtx, 2336 baseModuleContext: m.baseModuleContextFactory(blueprintCtx), 2337 variables: make(map[string]string), 2338 } 2339 2340 m.licenseMetadataFile = PathForModuleOut(ctx, "meta_lic") 2341 2342 dependencyInstallFiles, dependencyPackagingSpecs := m.computeInstallDeps(ctx) 2343 // set m.installFilesDepSet to only the transitive dependencies to be used as the dependencies 2344 // of installed files of this module. It will be replaced by a depset including the installed 2345 // files of this module at the end for use by modules that depend on this one. 2346 m.installFilesDepSet = newInstallPathsDepSet(nil, dependencyInstallFiles) 2347 2348 // Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never 2349 // reporting missing dependency errors in Blueprint when AllowMissingDependencies == true. 2350 // TODO: This will be removed once defaults modules handle missing dependency errors 2351 blueprintCtx.GetMissingDependencies() 2352 2353 // For the final GenerateAndroidBuildActions pass, require that all visited dependencies Soong modules and 2354 // are enabled. Unless the module is a CommonOS variant which may have dependencies on disabled variants 2355 // (because the dependencies are added before the modules are disabled). The 2356 // GetOsSpecificVariantsOfCommonOSVariant(...) method will ensure that the disabled variants are 2357 // ignored. 2358 ctx.baseModuleContext.strictVisitDeps = !m.IsCommonOSVariant() 2359 2360 if ctx.config.captureBuild { 2361 ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams) 2362 } 2363 2364 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " " 2365 var suffix []string 2366 if ctx.Os().Class != Device && ctx.Os().Class != Generic { 2367 suffix = append(suffix, ctx.Os().String()) 2368 } 2369 if !ctx.PrimaryArch() { 2370 suffix = append(suffix, ctx.Arch().ArchType.String()) 2371 } 2372 if apexInfo := ctx.Provider(ApexInfoProvider).(ApexInfo); !apexInfo.IsForPlatform() { 2373 suffix = append(suffix, apexInfo.ApexVariationName) 2374 } 2375 2376 ctx.Variable(pctx, "moduleDesc", desc) 2377 2378 s := "" 2379 if len(suffix) > 0 { 2380 s = " [" + strings.Join(suffix, " ") + "]" 2381 } 2382 ctx.Variable(pctx, "moduleDescSuffix", s) 2383 2384 // Some common property checks for properties that will be used later in androidmk.go 2385 checkDistProperties(ctx, "dist", &m.distProperties.Dist) 2386 for i := range m.distProperties.Dists { 2387 checkDistProperties(ctx, fmt.Sprintf("dists[%d]", i), &m.distProperties.Dists[i]) 2388 } 2389 2390 if m.Enabled() { 2391 // ensure all direct android.Module deps are enabled 2392 ctx.VisitDirectDepsBlueprint(func(bm blueprint.Module) { 2393 if m, ok := bm.(Module); ok { 2394 ctx.validateAndroidModule(bm, ctx.OtherModuleDependencyTag(m), ctx.baseModuleContext.strictVisitDeps) 2395 } 2396 }) 2397 2398 licensesPropertyFlattener(ctx) 2399 if ctx.Failed() { 2400 return 2401 } 2402 2403 if mixedBuildMod, handled := m.isHandledByBazel(ctx); handled { 2404 mixedBuildMod.ProcessBazelQueryResponse(ctx) 2405 } else { 2406 m.module.GenerateAndroidBuildActions(ctx) 2407 } 2408 if ctx.Failed() { 2409 return 2410 } 2411 2412 m.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc) 2413 rcDir := PathForModuleInstall(ctx, "etc", "init") 2414 for _, src := range m.initRcPaths { 2415 ctx.PackageFile(rcDir, filepath.Base(src.String()), src) 2416 } 2417 2418 m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments) 2419 vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest") 2420 for _, src := range m.vintfFragmentsPaths { 2421 ctx.PackageFile(vintfDir, filepath.Base(src.String()), src) 2422 } 2423 2424 // Create the set of tagged dist files after calling GenerateAndroidBuildActions 2425 // as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the 2426 // output paths being set which must be done before or during 2427 // GenerateAndroidBuildActions. 2428 m.distFiles = m.GenerateTaggedDistFiles(ctx) 2429 if ctx.Failed() { 2430 return 2431 } 2432 2433 m.installFiles = append(m.installFiles, ctx.installFiles...) 2434 m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...) 2435 m.packagingSpecs = append(m.packagingSpecs, ctx.packagingSpecs...) 2436 m.katiInstalls = append(m.katiInstalls, ctx.katiInstalls...) 2437 m.katiSymlinks = append(m.katiSymlinks, ctx.katiSymlinks...) 2438 } else if ctx.Config().AllowMissingDependencies() { 2439 // If the module is not enabled it will not create any build rules, nothing will call 2440 // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled 2441 // and report them as an error even when AllowMissingDependencies = true. Call 2442 // ctx.GetMissingDependencies() here to tell blueprint not to handle them. 2443 ctx.GetMissingDependencies() 2444 } 2445 2446 if m == ctx.FinalModule().(Module).base() { 2447 m.generateModuleTarget(ctx) 2448 if ctx.Failed() { 2449 return 2450 } 2451 } 2452 2453 m.installFilesDepSet = newInstallPathsDepSet(m.installFiles, dependencyInstallFiles) 2454 m.packagingSpecsDepSet = newPackagingSpecsDepSet(m.packagingSpecs, dependencyPackagingSpecs) 2455 2456 buildLicenseMetadata(ctx, m.licenseMetadataFile) 2457 2458 m.buildParams = ctx.buildParams 2459 m.ruleParams = ctx.ruleParams 2460 m.variables = ctx.variables 2461} 2462 2463func (m *ModuleBase) isHandledByBazel(ctx ModuleContext) (MixedBuildBuildable, bool) { 2464 if mixedBuildMod, ok := m.module.(MixedBuildBuildable); ok { 2465 if mixedBuildMod.IsMixedBuildSupported(ctx) && MixedBuildsEnabled(ctx) { 2466 return mixedBuildMod, true 2467 } 2468 } 2469 return nil, false 2470} 2471 2472// Check the supplied dist structure to make sure that it is valid. 2473// 2474// property - the base property, e.g. dist or dists[1], which is combined with the 2475// name of the nested property to produce the full property, e.g. dist.dest or 2476// dists[1].dir. 2477func checkDistProperties(ctx *moduleContext, property string, dist *Dist) { 2478 if dist.Dest != nil { 2479 _, err := validateSafePath(*dist.Dest) 2480 if err != nil { 2481 ctx.PropertyErrorf(property+".dest", "%s", err.Error()) 2482 } 2483 } 2484 if dist.Dir != nil { 2485 _, err := validateSafePath(*dist.Dir) 2486 if err != nil { 2487 ctx.PropertyErrorf(property+".dir", "%s", err.Error()) 2488 } 2489 } 2490 if dist.Suffix != nil { 2491 if strings.Contains(*dist.Suffix, "/") { 2492 ctx.PropertyErrorf(property+".suffix", "Suffix may not contain a '/' character.") 2493 } 2494 } 2495 2496} 2497 2498type earlyModuleContext struct { 2499 blueprint.EarlyModuleContext 2500 2501 kind moduleKind 2502 config Config 2503} 2504 2505func (e *earlyModuleContext) Glob(globPattern string, excludes []string) Paths { 2506 return Glob(e, globPattern, excludes) 2507} 2508 2509func (e *earlyModuleContext) GlobFiles(globPattern string, excludes []string) Paths { 2510 return GlobFiles(e, globPattern, excludes) 2511} 2512 2513func (e *earlyModuleContext) IsSymlink(path Path) bool { 2514 fileInfo, err := e.config.fs.Lstat(path.String()) 2515 if err != nil { 2516 e.ModuleErrorf("os.Lstat(%q) failed: %s", path.String(), err) 2517 } 2518 return fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink 2519} 2520 2521func (e *earlyModuleContext) Readlink(path Path) string { 2522 dest, err := e.config.fs.Readlink(path.String()) 2523 if err != nil { 2524 e.ModuleErrorf("os.Readlink(%q) failed: %s", path.String(), err) 2525 } 2526 return dest 2527} 2528 2529func (e *earlyModuleContext) Module() Module { 2530 module, _ := e.EarlyModuleContext.Module().(Module) 2531 return module 2532} 2533 2534func (e *earlyModuleContext) Config() Config { 2535 return e.EarlyModuleContext.Config().(Config) 2536} 2537 2538func (e *earlyModuleContext) AConfig() Config { 2539 return e.config 2540} 2541 2542func (e *earlyModuleContext) DeviceConfig() DeviceConfig { 2543 return DeviceConfig{e.config.deviceConfig} 2544} 2545 2546func (e *earlyModuleContext) Platform() bool { 2547 return e.kind == platformModule 2548} 2549 2550func (e *earlyModuleContext) DeviceSpecific() bool { 2551 return e.kind == deviceSpecificModule 2552} 2553 2554func (e *earlyModuleContext) SocSpecific() bool { 2555 return e.kind == socSpecificModule 2556} 2557 2558func (e *earlyModuleContext) ProductSpecific() bool { 2559 return e.kind == productSpecificModule 2560} 2561 2562func (e *earlyModuleContext) SystemExtSpecific() bool { 2563 return e.kind == systemExtSpecificModule 2564} 2565 2566func (e *earlyModuleContext) Namespace() *Namespace { 2567 return e.EarlyModuleContext.Namespace().(*Namespace) 2568} 2569 2570type baseModuleContext struct { 2571 bp blueprint.BaseModuleContext 2572 earlyModuleContext 2573 os OsType 2574 target Target 2575 multiTargets []Target 2576 targetPrimary bool 2577 debug bool 2578 2579 walkPath []Module 2580 tagPath []blueprint.DependencyTag 2581 2582 strictVisitDeps bool // If true, enforce that all dependencies are enabled 2583 2584 bazelConversionMode bool 2585} 2586 2587func (b *baseModuleContext) isBazelConversionMode() bool { 2588 return b.bazelConversionMode 2589} 2590func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string { 2591 return b.bp.OtherModuleName(m) 2592} 2593func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { return b.bp.OtherModuleDir(m) } 2594func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) { 2595 b.bp.OtherModuleErrorf(m, fmt, args...) 2596} 2597func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag { 2598 return b.bp.OtherModuleDependencyTag(m) 2599} 2600func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) } 2601func (b *baseModuleContext) OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool { 2602 return b.bp.OtherModuleDependencyVariantExists(variations, name) 2603} 2604func (b *baseModuleContext) OtherModuleFarDependencyVariantExists(variations []blueprint.Variation, name string) bool { 2605 return b.bp.OtherModuleFarDependencyVariantExists(variations, name) 2606} 2607func (b *baseModuleContext) OtherModuleReverseDependencyVariantExists(name string) bool { 2608 return b.bp.OtherModuleReverseDependencyVariantExists(name) 2609} 2610func (b *baseModuleContext) OtherModuleType(m blueprint.Module) string { 2611 return b.bp.OtherModuleType(m) 2612} 2613func (b *baseModuleContext) OtherModuleProvider(m blueprint.Module, provider blueprint.ProviderKey) interface{} { 2614 return b.bp.OtherModuleProvider(m, provider) 2615} 2616func (b *baseModuleContext) OtherModuleHasProvider(m blueprint.Module, provider blueprint.ProviderKey) bool { 2617 return b.bp.OtherModuleHasProvider(m, provider) 2618} 2619func (b *baseModuleContext) Provider(provider blueprint.ProviderKey) interface{} { 2620 return b.bp.Provider(provider) 2621} 2622func (b *baseModuleContext) HasProvider(provider blueprint.ProviderKey) bool { 2623 return b.bp.HasProvider(provider) 2624} 2625func (b *baseModuleContext) SetProvider(provider blueprint.ProviderKey, value interface{}) { 2626 b.bp.SetProvider(provider, value) 2627} 2628 2629func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module { 2630 return b.bp.GetDirectDepWithTag(name, tag) 2631} 2632 2633func (b *baseModuleContext) blueprintBaseModuleContext() blueprint.BaseModuleContext { 2634 return b.bp 2635} 2636 2637type moduleContext struct { 2638 bp blueprint.ModuleContext 2639 baseModuleContext 2640 packagingSpecs []PackagingSpec 2641 installFiles InstallPaths 2642 checkbuildFiles Paths 2643 module Module 2644 phonies map[string]Paths 2645 2646 katiInstalls []katiInstall 2647 katiSymlinks []katiInstall 2648 2649 // For tests 2650 buildParams []BuildParams 2651 ruleParams map[blueprint.Rule]blueprint.RuleParams 2652 variables map[string]string 2653} 2654 2655// katiInstall stores a request from Soong to Make to create an install rule. 2656type katiInstall struct { 2657 from Path 2658 to InstallPath 2659 implicitDeps Paths 2660 orderOnlyDeps Paths 2661 executable bool 2662 extraFiles *extraFilesZip 2663 2664 absFrom string 2665} 2666 2667type extraFilesZip struct { 2668 zip Path 2669 dir InstallPath 2670} 2671 2672type katiInstalls []katiInstall 2673 2674// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a 2675// space separated list of from:to tuples. 2676func (installs katiInstalls) BuiltInstalled() string { 2677 sb := strings.Builder{} 2678 for i, install := range installs { 2679 if i != 0 { 2680 sb.WriteRune(' ') 2681 } 2682 sb.WriteString(install.from.String()) 2683 sb.WriteRune(':') 2684 sb.WriteString(install.to.String()) 2685 } 2686 return sb.String() 2687} 2688 2689// InstallPaths returns the install path of each entry. 2690func (installs katiInstalls) InstallPaths() InstallPaths { 2691 paths := make(InstallPaths, 0, len(installs)) 2692 for _, install := range installs { 2693 paths = append(paths, install.to) 2694 } 2695 return paths 2696} 2697 2698func (m *moduleContext) ninjaError(params BuildParams, err error) (PackageContext, BuildParams) { 2699 return pctx, BuildParams{ 2700 Rule: ErrorRule, 2701 Description: params.Description, 2702 Output: params.Output, 2703 Outputs: params.Outputs, 2704 ImplicitOutput: params.ImplicitOutput, 2705 ImplicitOutputs: params.ImplicitOutputs, 2706 Args: map[string]string{ 2707 "error": err.Error(), 2708 }, 2709 } 2710} 2711 2712func (m *moduleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) { 2713 m.Build(pctx, BuildParams(params)) 2714} 2715 2716func validateBuildParams(params blueprint.BuildParams) error { 2717 // Validate that the symlink outputs are declared outputs or implicit outputs 2718 allOutputs := map[string]bool{} 2719 for _, output := range params.Outputs { 2720 allOutputs[output] = true 2721 } 2722 for _, output := range params.ImplicitOutputs { 2723 allOutputs[output] = true 2724 } 2725 for _, symlinkOutput := range params.SymlinkOutputs { 2726 if !allOutputs[symlinkOutput] { 2727 return fmt.Errorf( 2728 "Symlink output %s is not a declared output or implicit output", 2729 symlinkOutput) 2730 } 2731 } 2732 return nil 2733} 2734 2735// Convert build parameters from their concrete Android types into their string representations, 2736// and combine the singular and plural fields of the same type (e.g. Output and Outputs). 2737func convertBuildParams(params BuildParams) blueprint.BuildParams { 2738 bparams := blueprint.BuildParams{ 2739 Rule: params.Rule, 2740 Description: params.Description, 2741 Deps: params.Deps, 2742 Outputs: params.Outputs.Strings(), 2743 ImplicitOutputs: params.ImplicitOutputs.Strings(), 2744 SymlinkOutputs: params.SymlinkOutputs.Strings(), 2745 Inputs: params.Inputs.Strings(), 2746 Implicits: params.Implicits.Strings(), 2747 OrderOnly: params.OrderOnly.Strings(), 2748 Validations: params.Validations.Strings(), 2749 Args: params.Args, 2750 Optional: !params.Default, 2751 } 2752 2753 if params.Depfile != nil { 2754 bparams.Depfile = params.Depfile.String() 2755 } 2756 if params.Output != nil { 2757 bparams.Outputs = append(bparams.Outputs, params.Output.String()) 2758 } 2759 if params.SymlinkOutput != nil { 2760 bparams.SymlinkOutputs = append(bparams.SymlinkOutputs, params.SymlinkOutput.String()) 2761 } 2762 if params.ImplicitOutput != nil { 2763 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String()) 2764 } 2765 if params.Input != nil { 2766 bparams.Inputs = append(bparams.Inputs, params.Input.String()) 2767 } 2768 if params.Implicit != nil { 2769 bparams.Implicits = append(bparams.Implicits, params.Implicit.String()) 2770 } 2771 if params.Validation != nil { 2772 bparams.Validations = append(bparams.Validations, params.Validation.String()) 2773 } 2774 2775 bparams.Outputs = proptools.NinjaEscapeList(bparams.Outputs) 2776 bparams.ImplicitOutputs = proptools.NinjaEscapeList(bparams.ImplicitOutputs) 2777 bparams.SymlinkOutputs = proptools.NinjaEscapeList(bparams.SymlinkOutputs) 2778 bparams.Inputs = proptools.NinjaEscapeList(bparams.Inputs) 2779 bparams.Implicits = proptools.NinjaEscapeList(bparams.Implicits) 2780 bparams.OrderOnly = proptools.NinjaEscapeList(bparams.OrderOnly) 2781 bparams.Validations = proptools.NinjaEscapeList(bparams.Validations) 2782 bparams.Depfile = proptools.NinjaEscape(bparams.Depfile) 2783 2784 return bparams 2785} 2786 2787func (m *moduleContext) Variable(pctx PackageContext, name, value string) { 2788 if m.config.captureBuild { 2789 m.variables[name] = value 2790 } 2791 2792 m.bp.Variable(pctx.PackageContext, name, value) 2793} 2794 2795func (m *moduleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams, 2796 argNames ...string) blueprint.Rule { 2797 2798 if m.config.UseRemoteBuild() { 2799 if params.Pool == nil { 2800 // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict 2801 // jobs to the local parallelism value 2802 params.Pool = localPool 2803 } else if params.Pool == remotePool { 2804 // remotePool is a fake pool used to identify rule that are supported for remoting. If the rule's 2805 // pool is the remotePool, replace with nil so that ninja runs it at NINJA_REMOTE_NUM_JOBS 2806 // parallelism. 2807 params.Pool = nil 2808 } 2809 } 2810 2811 rule := m.bp.Rule(pctx.PackageContext, name, params, argNames...) 2812 2813 if m.config.captureBuild { 2814 m.ruleParams[rule] = params 2815 } 2816 2817 return rule 2818} 2819 2820func (m *moduleContext) Build(pctx PackageContext, params BuildParams) { 2821 if params.Description != "" { 2822 params.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}" 2823 } 2824 2825 if missingDeps := m.GetMissingDependencies(); len(missingDeps) > 0 { 2826 pctx, params = m.ninjaError(params, fmt.Errorf("module %s missing dependencies: %s\n", 2827 m.ModuleName(), strings.Join(missingDeps, ", "))) 2828 } 2829 2830 if m.config.captureBuild { 2831 m.buildParams = append(m.buildParams, params) 2832 } 2833 2834 bparams := convertBuildParams(params) 2835 err := validateBuildParams(bparams) 2836 if err != nil { 2837 m.ModuleErrorf( 2838 "%s: build parameter validation failed: %s", 2839 m.ModuleName(), 2840 err.Error()) 2841 } 2842 m.bp.Build(pctx.PackageContext, bparams) 2843} 2844 2845func (m *moduleContext) Phony(name string, deps ...Path) { 2846 addPhony(m.config, name, deps...) 2847} 2848 2849func (m *moduleContext) GetMissingDependencies() []string { 2850 var missingDeps []string 2851 missingDeps = append(missingDeps, m.Module().base().commonProperties.MissingDeps...) 2852 missingDeps = append(missingDeps, m.bp.GetMissingDependencies()...) 2853 missingDeps = FirstUniqueStrings(missingDeps) 2854 return missingDeps 2855} 2856 2857func (b *baseModuleContext) AddMissingDependencies(deps []string) { 2858 if deps != nil { 2859 missingDeps := &b.Module().base().commonProperties.MissingDeps 2860 *missingDeps = append(*missingDeps, deps...) 2861 *missingDeps = FirstUniqueStrings(*missingDeps) 2862 } 2863} 2864 2865type AllowDisabledModuleDependency interface { 2866 blueprint.DependencyTag 2867 AllowDisabledModuleDependency(target Module) bool 2868} 2869 2870func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag blueprint.DependencyTag, strict bool) Module { 2871 aModule, _ := module.(Module) 2872 2873 if !strict { 2874 return aModule 2875 } 2876 2877 if aModule == nil { 2878 b.ModuleErrorf("module %q (%#v) not an android module", b.OtherModuleName(module), tag) 2879 return nil 2880 } 2881 2882 if !aModule.Enabled() { 2883 if t, ok := tag.(AllowDisabledModuleDependency); !ok || !t.AllowDisabledModuleDependency(aModule) { 2884 if b.Config().AllowMissingDependencies() { 2885 b.AddMissingDependencies([]string{b.OtherModuleName(aModule)}) 2886 } else { 2887 b.ModuleErrorf("depends on disabled module %q", b.OtherModuleName(aModule)) 2888 } 2889 } 2890 return nil 2891 } 2892 return aModule 2893} 2894 2895type dep struct { 2896 mod blueprint.Module 2897 tag blueprint.DependencyTag 2898} 2899 2900func (b *baseModuleContext) getDirectDepsInternal(name string, tag blueprint.DependencyTag) []dep { 2901 var deps []dep 2902 b.VisitDirectDepsBlueprint(func(module blueprint.Module) { 2903 if aModule, _ := module.(Module); aModule != nil { 2904 if aModule.base().BaseModuleName() == name { 2905 returnedTag := b.bp.OtherModuleDependencyTag(aModule) 2906 if tag == nil || returnedTag == tag { 2907 deps = append(deps, dep{aModule, returnedTag}) 2908 } 2909 } 2910 } else if b.bp.OtherModuleName(module) == name { 2911 returnedTag := b.bp.OtherModuleDependencyTag(module) 2912 if tag == nil || returnedTag == tag { 2913 deps = append(deps, dep{module, returnedTag}) 2914 } 2915 } 2916 }) 2917 return deps 2918} 2919 2920func (b *baseModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) { 2921 deps := b.getDirectDepsInternal(name, tag) 2922 if len(deps) == 1 { 2923 return deps[0].mod, deps[0].tag 2924 } else if len(deps) >= 2 { 2925 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q", 2926 name, b.ModuleName())) 2927 } else { 2928 return nil, nil 2929 } 2930} 2931 2932func (b *baseModuleContext) getDirectDepFirstTag(name string) (blueprint.Module, blueprint.DependencyTag) { 2933 foundDeps := b.getDirectDepsInternal(name, nil) 2934 deps := map[blueprint.Module]bool{} 2935 for _, dep := range foundDeps { 2936 deps[dep.mod] = true 2937 } 2938 if len(deps) == 1 { 2939 return foundDeps[0].mod, foundDeps[0].tag 2940 } else if len(deps) >= 2 { 2941 // this could happen if two dependencies have the same name in different namespaces 2942 // TODO(b/186554727): this should not occur if namespaces are handled within 2943 // getDirectDepsInternal. 2944 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q", 2945 name, b.ModuleName())) 2946 } else { 2947 return nil, nil 2948 } 2949} 2950 2951func (b *baseModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module { 2952 var deps []Module 2953 b.VisitDirectDepsBlueprint(func(module blueprint.Module) { 2954 if aModule, _ := module.(Module); aModule != nil { 2955 if b.bp.OtherModuleDependencyTag(aModule) == tag { 2956 deps = append(deps, aModule) 2957 } 2958 } 2959 }) 2960 return deps 2961} 2962 2963func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module { 2964 module, _ := m.getDirectDepInternal(name, tag) 2965 return module 2966} 2967 2968// GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified 2969// name, or nil if none exists. If there are multiple dependencies on the same module it returns the 2970// first DependencyTag. 2971func (b *baseModuleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) { 2972 return b.getDirectDepFirstTag(name) 2973} 2974 2975func (b *baseModuleContext) ModuleFromName(name string) (blueprint.Module, bool) { 2976 if !b.isBazelConversionMode() { 2977 panic("cannot call ModuleFromName if not in bazel conversion mode") 2978 } 2979 if moduleName, _ := SrcIsModuleWithTag(name); moduleName != "" { 2980 return b.bp.ModuleFromName(moduleName) 2981 } else { 2982 return b.bp.ModuleFromName(name) 2983 } 2984} 2985 2986func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) { 2987 b.bp.VisitDirectDeps(visit) 2988} 2989 2990func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) { 2991 b.bp.VisitDirectDeps(func(module blueprint.Module) { 2992 if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { 2993 visit(aModule) 2994 } 2995 }) 2996} 2997 2998func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) { 2999 b.bp.VisitDirectDeps(func(module blueprint.Module) { 3000 if b.bp.OtherModuleDependencyTag(module) == tag { 3001 if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { 3002 visit(aModule) 3003 } 3004 } 3005 }) 3006} 3007 3008func (b *baseModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) { 3009 b.bp.VisitDirectDepsIf( 3010 // pred 3011 func(module blueprint.Module) bool { 3012 if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { 3013 return pred(aModule) 3014 } else { 3015 return false 3016 } 3017 }, 3018 // visit 3019 func(module blueprint.Module) { 3020 visit(module.(Module)) 3021 }) 3022} 3023 3024func (b *baseModuleContext) VisitDepsDepthFirst(visit func(Module)) { 3025 b.bp.VisitDepsDepthFirst(func(module blueprint.Module) { 3026 if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { 3027 visit(aModule) 3028 } 3029 }) 3030} 3031 3032func (b *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) { 3033 b.bp.VisitDepsDepthFirstIf( 3034 // pred 3035 func(module blueprint.Module) bool { 3036 if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { 3037 return pred(aModule) 3038 } else { 3039 return false 3040 } 3041 }, 3042 // visit 3043 func(module blueprint.Module) { 3044 visit(module.(Module)) 3045 }) 3046} 3047 3048func (b *baseModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) { 3049 b.bp.WalkDeps(visit) 3050} 3051 3052func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) { 3053 b.walkPath = []Module{b.Module()} 3054 b.tagPath = []blueprint.DependencyTag{} 3055 b.bp.WalkDeps(func(child, parent blueprint.Module) bool { 3056 childAndroidModule, _ := child.(Module) 3057 parentAndroidModule, _ := parent.(Module) 3058 if childAndroidModule != nil && parentAndroidModule != nil { 3059 // record walkPath before visit 3060 for b.walkPath[len(b.walkPath)-1] != parentAndroidModule { 3061 b.walkPath = b.walkPath[0 : len(b.walkPath)-1] 3062 b.tagPath = b.tagPath[0 : len(b.tagPath)-1] 3063 } 3064 b.walkPath = append(b.walkPath, childAndroidModule) 3065 b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule)) 3066 return visit(childAndroidModule, parentAndroidModule) 3067 } else { 3068 return false 3069 } 3070 }) 3071} 3072 3073func (b *baseModuleContext) GetWalkPath() []Module { 3074 return b.walkPath 3075} 3076 3077func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag { 3078 return b.tagPath 3079} 3080 3081func (b *baseModuleContext) VisitAllModuleVariants(visit func(Module)) { 3082 b.bp.VisitAllModuleVariants(func(module blueprint.Module) { 3083 visit(module.(Module)) 3084 }) 3085} 3086 3087func (b *baseModuleContext) PrimaryModule() Module { 3088 return b.bp.PrimaryModule().(Module) 3089} 3090 3091func (b *baseModuleContext) FinalModule() Module { 3092 return b.bp.FinalModule().(Module) 3093} 3094 3095// IsMetaDependencyTag returns true for cross-cutting metadata dependencies. 3096func IsMetaDependencyTag(tag blueprint.DependencyTag) bool { 3097 if tag == licenseKindTag { 3098 return true 3099 } else if tag == licensesTag { 3100 return true 3101 } 3102 return false 3103} 3104 3105// A regexp for removing boilerplate from BaseDependencyTag from the string representation of 3106// a dependency tag. 3107var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:{}\E(, )?`) 3108 3109// PrettyPrintTag returns string representation of the tag, but prefers 3110// custom String() method if available. 3111func PrettyPrintTag(tag blueprint.DependencyTag) string { 3112 // Use tag's custom String() method if available. 3113 if stringer, ok := tag.(fmt.Stringer); ok { 3114 return stringer.String() 3115 } 3116 3117 // Otherwise, get a default string representation of the tag's struct. 3118 tagString := fmt.Sprintf("%T: %+v", tag, tag) 3119 3120 // Remove the boilerplate from BaseDependencyTag as it adds no value. 3121 tagString = tagCleaner.ReplaceAllString(tagString, "") 3122 return tagString 3123} 3124 3125func (b *baseModuleContext) GetPathString(skipFirst bool) string { 3126 sb := strings.Builder{} 3127 tagPath := b.GetTagPath() 3128 walkPath := b.GetWalkPath() 3129 if !skipFirst { 3130 sb.WriteString(walkPath[0].String()) 3131 } 3132 for i, m := range walkPath[1:] { 3133 sb.WriteString("\n") 3134 sb.WriteString(fmt.Sprintf(" via tag %s\n", PrettyPrintTag(tagPath[i]))) 3135 sb.WriteString(fmt.Sprintf(" -> %s", m.String())) 3136 } 3137 return sb.String() 3138} 3139 3140func (m *moduleContext) ModuleSubDir() string { 3141 return m.bp.ModuleSubDir() 3142} 3143 3144func (b *baseModuleContext) Target() Target { 3145 return b.target 3146} 3147 3148func (b *baseModuleContext) TargetPrimary() bool { 3149 return b.targetPrimary 3150} 3151 3152func (b *baseModuleContext) MultiTargets() []Target { 3153 return b.multiTargets 3154} 3155 3156func (b *baseModuleContext) Arch() Arch { 3157 return b.target.Arch 3158} 3159 3160func (b *baseModuleContext) Os() OsType { 3161 return b.os 3162} 3163 3164func (b *baseModuleContext) Host() bool { 3165 return b.os.Class == Host 3166} 3167 3168func (b *baseModuleContext) Device() bool { 3169 return b.os.Class == Device 3170} 3171 3172func (b *baseModuleContext) Darwin() bool { 3173 return b.os == Darwin 3174} 3175 3176func (b *baseModuleContext) Windows() bool { 3177 return b.os == Windows 3178} 3179 3180func (b *baseModuleContext) Debug() bool { 3181 return b.debug 3182} 3183 3184func (b *baseModuleContext) PrimaryArch() bool { 3185 if len(b.config.Targets[b.target.Os]) <= 1 { 3186 return true 3187 } 3188 return b.target.Arch.ArchType == b.config.Targets[b.target.Os][0].Arch.ArchType 3189} 3190 3191// Makes this module a platform module, i.e. not specific to soc, device, 3192// product, or system_ext. 3193func (m *ModuleBase) MakeAsPlatform() { 3194 m.commonProperties.Vendor = boolPtr(false) 3195 m.commonProperties.Proprietary = boolPtr(false) 3196 m.commonProperties.Soc_specific = boolPtr(false) 3197 m.commonProperties.Product_specific = boolPtr(false) 3198 m.commonProperties.System_ext_specific = boolPtr(false) 3199} 3200 3201func (m *ModuleBase) MakeAsSystemExt() { 3202 m.commonProperties.Vendor = boolPtr(false) 3203 m.commonProperties.Proprietary = boolPtr(false) 3204 m.commonProperties.Soc_specific = boolPtr(false) 3205 m.commonProperties.Product_specific = boolPtr(false) 3206 m.commonProperties.System_ext_specific = boolPtr(true) 3207} 3208 3209// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true" 3210func (m *ModuleBase) IsNativeBridgeSupported() bool { 3211 return proptools.Bool(m.commonProperties.Native_bridge_supported) 3212} 3213 3214func (m *moduleContext) InstallInData() bool { 3215 return m.module.InstallInData() 3216} 3217 3218func (m *moduleContext) InstallInTestcases() bool { 3219 return m.module.InstallInTestcases() 3220} 3221 3222func (m *moduleContext) InstallInSanitizerDir() bool { 3223 return m.module.InstallInSanitizerDir() 3224} 3225 3226func (m *moduleContext) InstallInRamdisk() bool { 3227 return m.module.InstallInRamdisk() 3228} 3229 3230func (m *moduleContext) InstallInVendorRamdisk() bool { 3231 return m.module.InstallInVendorRamdisk() 3232} 3233 3234func (m *moduleContext) InstallInDebugRamdisk() bool { 3235 return m.module.InstallInDebugRamdisk() 3236} 3237 3238func (m *moduleContext) InstallInRecovery() bool { 3239 return m.module.InstallInRecovery() 3240} 3241 3242func (m *moduleContext) InstallInRoot() bool { 3243 return m.module.InstallInRoot() 3244} 3245 3246func (m *moduleContext) InstallForceOS() (*OsType, *ArchType) { 3247 return m.module.InstallForceOS() 3248} 3249 3250func (m *moduleContext) InstallInVendor() bool { 3251 return m.module.InstallInVendor() 3252} 3253 3254func (m *moduleContext) skipInstall() bool { 3255 if m.module.base().commonProperties.SkipInstall { 3256 return true 3257 } 3258 3259 if m.module.base().commonProperties.HideFromMake { 3260 return true 3261 } 3262 3263 // We'll need a solution for choosing which of modules with the same name in different 3264 // namespaces to install. For now, reuse the list of namespaces exported to Make as the 3265 // list of namespaces to install in a Soong-only build. 3266 if !m.module.base().commonProperties.NamespaceExportedToMake { 3267 return true 3268 } 3269 3270 return false 3271} 3272 3273func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path, 3274 deps ...Path) InstallPath { 3275 return m.installFile(installPath, name, srcPath, deps, false, nil) 3276} 3277 3278func (m *moduleContext) InstallExecutable(installPath InstallPath, name string, srcPath Path, 3279 deps ...Path) InstallPath { 3280 return m.installFile(installPath, name, srcPath, deps, true, nil) 3281} 3282 3283func (m *moduleContext) InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path, 3284 extraZip Path, deps ...Path) InstallPath { 3285 return m.installFile(installPath, name, srcPath, deps, false, &extraFilesZip{ 3286 zip: extraZip, 3287 dir: installPath, 3288 }) 3289} 3290 3291func (m *moduleContext) PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec { 3292 fullInstallPath := installPath.Join(m, name) 3293 return m.packageFile(fullInstallPath, srcPath, false) 3294} 3295 3296func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, executable bool) PackagingSpec { 3297 licenseFiles := m.Module().EffectiveLicenseFiles() 3298 spec := PackagingSpec{ 3299 relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()), 3300 srcPath: srcPath, 3301 symlinkTarget: "", 3302 executable: executable, 3303 effectiveLicenseFiles: &licenseFiles, 3304 partition: fullInstallPath.partition, 3305 } 3306 m.packagingSpecs = append(m.packagingSpecs, spec) 3307 return spec 3308} 3309 3310func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path, deps []Path, 3311 executable bool, extraZip *extraFilesZip) InstallPath { 3312 3313 fullInstallPath := installPath.Join(m, name) 3314 m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, false) 3315 3316 if !m.skipInstall() { 3317 deps = append(deps, m.module.base().installFilesDepSet.ToList().Paths()...) 3318 3319 var implicitDeps, orderOnlyDeps Paths 3320 3321 if m.Host() { 3322 // Installed host modules might be used during the build, depend directly on their 3323 // dependencies so their timestamp is updated whenever their dependency is updated 3324 implicitDeps = deps 3325 } else { 3326 orderOnlyDeps = deps 3327 } 3328 3329 if m.Config().KatiEnabled() { 3330 // When creating the install rule in Soong but embedding in Make, write the rule to a 3331 // makefile instead of directly to the ninja file so that main.mk can add the 3332 // dependencies from the `required` property that are hard to resolve in Soong. 3333 m.katiInstalls = append(m.katiInstalls, katiInstall{ 3334 from: srcPath, 3335 to: fullInstallPath, 3336 implicitDeps: implicitDeps, 3337 orderOnlyDeps: orderOnlyDeps, 3338 executable: executable, 3339 extraFiles: extraZip, 3340 }) 3341 } else { 3342 rule := Cp 3343 if executable { 3344 rule = CpExecutable 3345 } 3346 3347 extraCmds := "" 3348 if extraZip != nil { 3349 extraCmds += fmt.Sprintf(" && ( unzip -qDD -d '%s' '%s' 2>&1 | grep -v \"zipfile is empty\"; exit $${PIPESTATUS[0]} )", 3350 extraZip.dir.String(), extraZip.zip.String()) 3351 extraCmds += " || ( code=$$?; if [ $$code -ne 0 -a $$code -ne 1 ]; then exit $$code; fi )" 3352 implicitDeps = append(implicitDeps, extraZip.zip) 3353 } 3354 3355 m.Build(pctx, BuildParams{ 3356 Rule: rule, 3357 Description: "install " + fullInstallPath.Base(), 3358 Output: fullInstallPath, 3359 Input: srcPath, 3360 Implicits: implicitDeps, 3361 OrderOnly: orderOnlyDeps, 3362 Default: !m.Config().KatiEnabled(), 3363 Args: map[string]string{ 3364 "extraCmds": extraCmds, 3365 }, 3366 }) 3367 } 3368 3369 m.installFiles = append(m.installFiles, fullInstallPath) 3370 } 3371 3372 m.packageFile(fullInstallPath, srcPath, executable) 3373 3374 m.checkbuildFiles = append(m.checkbuildFiles, srcPath) 3375 3376 return fullInstallPath 3377} 3378 3379func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath { 3380 fullInstallPath := installPath.Join(m, name) 3381 m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, true) 3382 3383 relPath, err := filepath.Rel(path.Dir(fullInstallPath.String()), srcPath.String()) 3384 if err != nil { 3385 panic(fmt.Sprintf("Unable to generate symlink between %q and %q: %s", fullInstallPath.Base(), srcPath.Base(), err)) 3386 } 3387 if !m.skipInstall() { 3388 3389 if m.Config().KatiEnabled() { 3390 // When creating the symlink rule in Soong but embedding in Make, write the rule to a 3391 // makefile instead of directly to the ninja file so that main.mk can add the 3392 // dependencies from the `required` property that are hard to resolve in Soong. 3393 m.katiSymlinks = append(m.katiSymlinks, katiInstall{ 3394 from: srcPath, 3395 to: fullInstallPath, 3396 }) 3397 } else { 3398 // The symlink doesn't need updating when the target is modified, but we sometimes 3399 // have a dependency on a symlink to a binary instead of to the binary directly, and 3400 // the mtime of the symlink must be updated when the binary is modified, so use a 3401 // normal dependency here instead of an order-only dependency. 3402 m.Build(pctx, BuildParams{ 3403 Rule: Symlink, 3404 Description: "install symlink " + fullInstallPath.Base(), 3405 Output: fullInstallPath, 3406 Input: srcPath, 3407 Default: !m.Config().KatiEnabled(), 3408 Args: map[string]string{ 3409 "fromPath": relPath, 3410 }, 3411 }) 3412 } 3413 3414 m.installFiles = append(m.installFiles, fullInstallPath) 3415 m.checkbuildFiles = append(m.checkbuildFiles, srcPath) 3416 } 3417 3418 m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{ 3419 relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()), 3420 srcPath: nil, 3421 symlinkTarget: relPath, 3422 executable: false, 3423 partition: fullInstallPath.partition, 3424 }) 3425 3426 return fullInstallPath 3427} 3428 3429// installPath/name -> absPath where absPath might be a path that is available only at runtime 3430// (e.g. /apex/...) 3431func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath { 3432 fullInstallPath := installPath.Join(m, name) 3433 m.module.base().hooks.runInstallHooks(m, nil, fullInstallPath, true) 3434 3435 if !m.skipInstall() { 3436 if m.Config().KatiEnabled() { 3437 // When creating the symlink rule in Soong but embedding in Make, write the rule to a 3438 // makefile instead of directly to the ninja file so that main.mk can add the 3439 // dependencies from the `required` property that are hard to resolve in Soong. 3440 m.katiSymlinks = append(m.katiSymlinks, katiInstall{ 3441 absFrom: absPath, 3442 to: fullInstallPath, 3443 }) 3444 } else { 3445 m.Build(pctx, BuildParams{ 3446 Rule: Symlink, 3447 Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath, 3448 Output: fullInstallPath, 3449 Default: !m.Config().KatiEnabled(), 3450 Args: map[string]string{ 3451 "fromPath": absPath, 3452 }, 3453 }) 3454 } 3455 3456 m.installFiles = append(m.installFiles, fullInstallPath) 3457 } 3458 3459 m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{ 3460 relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()), 3461 srcPath: nil, 3462 symlinkTarget: absPath, 3463 executable: false, 3464 partition: fullInstallPath.partition, 3465 }) 3466 3467 return fullInstallPath 3468} 3469 3470func (m *moduleContext) CheckbuildFile(srcPath Path) { 3471 m.checkbuildFiles = append(m.checkbuildFiles, srcPath) 3472} 3473 3474func (m *moduleContext) blueprintModuleContext() blueprint.ModuleContext { 3475 return m.bp 3476} 3477 3478func (m *moduleContext) LicenseMetadataFile() Path { 3479 return m.module.base().licenseMetadataFile 3480} 3481 3482// SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name" 3483// into the module name, or empty string if the input was not a module reference. 3484func SrcIsModule(s string) (module string) { 3485 if len(s) > 1 { 3486 if s[0] == ':' { 3487 module = s[1:] 3488 if !isUnqualifiedModuleName(module) { 3489 // The module name should be unqualified but is not so do not treat it as a module. 3490 module = "" 3491 } 3492 } else if s[0] == '/' && s[1] == '/' { 3493 module = s 3494 } 3495 } 3496 return module 3497} 3498 3499// SrcIsModuleWithTag decodes module references in the format ":unqualified-name{.tag}" or 3500// "//namespace:name{.tag}" into the module name and tag, ":unqualified-name" or "//namespace:name" 3501// into the module name and an empty string for the tag, or empty strings if the input was not a 3502// module reference. 3503func SrcIsModuleWithTag(s string) (module, tag string) { 3504 if len(s) > 1 { 3505 if s[0] == ':' { 3506 module = s[1:] 3507 } else if s[0] == '/' && s[1] == '/' { 3508 module = s 3509 } 3510 3511 if module != "" { 3512 if tagStart := strings.IndexByte(module, '{'); tagStart > 0 { 3513 if module[len(module)-1] == '}' { 3514 tag = module[tagStart+1 : len(module)-1] 3515 module = module[:tagStart] 3516 } 3517 } 3518 3519 if s[0] == ':' && !isUnqualifiedModuleName(module) { 3520 // The module name should be unqualified but is not so do not treat it as a module. 3521 module = "" 3522 tag = "" 3523 } 3524 } 3525 } 3526 3527 return module, tag 3528} 3529 3530// isUnqualifiedModuleName makes sure that the supplied module is an unqualified module name, i.e. 3531// does not contain any /. 3532func isUnqualifiedModuleName(module string) bool { 3533 return strings.IndexByte(module, '/') == -1 3534} 3535 3536// sourceOrOutputDependencyTag is the dependency tag added automatically by pathDepsMutator for any 3537// module reference in a property annotated with `android:"path"` or passed to ExtractSourceDeps 3538// or ExtractSourcesDeps. 3539// 3540// If uniquely identifies the dependency that was added as it contains both the module name used to 3541// add the dependency as well as the tag. That makes it very simple to find the matching dependency 3542// in GetModuleFromPathDep as all it needs to do is find the dependency whose tag matches the tag 3543// used to add it. It does not need to check that the module name as returned by one of 3544// Module.Name(), BaseModuleContext.OtherModuleName() or ModuleBase.BaseModuleName() matches the 3545// name supplied in the tag. That means it does not need to handle differences in module names 3546// caused by prebuilt_ prefix, or fully qualified module names. 3547type sourceOrOutputDependencyTag struct { 3548 blueprint.BaseDependencyTag 3549 3550 // The name of the module. 3551 moduleName string 3552 3553 // The tag that will be passed to the module's OutputFileProducer.OutputFiles(tag) method. 3554 tag string 3555} 3556 3557func sourceOrOutputDepTag(moduleName, tag string) blueprint.DependencyTag { 3558 return sourceOrOutputDependencyTag{moduleName: moduleName, tag: tag} 3559} 3560 3561// IsSourceDepTagWithOutputTag returns true if the supplied blueprint.DependencyTag is one that was 3562// used to add dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for 3563// properties tagged with `android:"path"` AND it was added using a module reference of 3564// :moduleName{outputTag}. 3565func IsSourceDepTagWithOutputTag(depTag blueprint.DependencyTag, outputTag string) bool { 3566 t, ok := depTag.(sourceOrOutputDependencyTag) 3567 return ok && t.tag == outputTag 3568} 3569 3570// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles 3571// using ":module" syntax, if any. 3572// 3573// Deprecated: tag the property with `android:"path"` instead. 3574func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) { 3575 set := make(map[string]bool) 3576 3577 for _, s := range srcFiles { 3578 if m, t := SrcIsModuleWithTag(s); m != "" { 3579 if _, found := set[s]; found { 3580 ctx.ModuleErrorf("found source dependency duplicate: %q!", s) 3581 } else { 3582 set[s] = true 3583 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m) 3584 } 3585 } 3586 } 3587} 3588 3589// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s 3590// using ":module" syntax, if any. 3591// 3592// Deprecated: tag the property with `android:"path"` instead. 3593func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) { 3594 if s != nil { 3595 if m, t := SrcIsModuleWithTag(*s); m != "" { 3596 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m) 3597 } 3598 } 3599} 3600 3601// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"` 3602// using the ":module" syntax and provides a list of paths to be used as if they were listed in the property. 3603type SourceFileProducer interface { 3604 Srcs() Paths 3605} 3606 3607// A module that implements OutputFileProducer can be referenced from any property that is tagged with `android:"path"` 3608// using the ":module" syntax or ":module{.tag}" syntax and provides a list of output files to be used as if they were 3609// listed in the property. 3610type OutputFileProducer interface { 3611 OutputFiles(tag string) (Paths, error) 3612} 3613 3614// OutputFilesForModule returns the paths from an OutputFileProducer with the given tag. On error, including if the 3615// module produced zero paths, it reports errors to the ctx and returns nil. 3616func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) Paths { 3617 paths, err := outputFilesForModule(ctx, module, tag) 3618 if err != nil { 3619 reportPathError(ctx, err) 3620 return nil 3621 } 3622 return paths 3623} 3624 3625// OutputFileForModule returns the path from an OutputFileProducer with the given tag. On error, including if the 3626// module produced zero or multiple paths, it reports errors to the ctx and returns nil. 3627func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) Path { 3628 paths, err := outputFilesForModule(ctx, module, tag) 3629 if err != nil { 3630 reportPathError(ctx, err) 3631 return nil 3632 } 3633 if len(paths) == 0 { 3634 type addMissingDependenciesIntf interface { 3635 AddMissingDependencies([]string) 3636 OtherModuleName(blueprint.Module) string 3637 } 3638 if mctx, ok := ctx.(addMissingDependenciesIntf); ok && ctx.Config().AllowMissingDependencies() { 3639 mctx.AddMissingDependencies([]string{mctx.OtherModuleName(module)}) 3640 } else { 3641 ReportPathErrorf(ctx, "failed to get output files from module %q", pathContextName(ctx, module)) 3642 } 3643 // Return a fake output file to avoid nil dereferences of Path objects later. 3644 // This should never get used for an actual build as the error or missing 3645 // dependency has already been reported. 3646 p, err := pathForSource(ctx, filepath.Join("missing_output_file", pathContextName(ctx, module))) 3647 if err != nil { 3648 reportPathError(ctx, err) 3649 return nil 3650 } 3651 return p 3652 } 3653 if len(paths) > 1 { 3654 ReportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one", 3655 pathContextName(ctx, module)) 3656 } 3657 return paths[0] 3658} 3659 3660func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) { 3661 if outputFileProducer, ok := module.(OutputFileProducer); ok { 3662 paths, err := outputFileProducer.OutputFiles(tag) 3663 if err != nil { 3664 return nil, fmt.Errorf("failed to get output file from module %q: %s", 3665 pathContextName(ctx, module), err.Error()) 3666 } 3667 return paths, nil 3668 } else if sourceFileProducer, ok := module.(SourceFileProducer); ok { 3669 if tag != "" { 3670 return nil, fmt.Errorf("module %q is a SourceFileProducer, not an OutputFileProducer, and so does not support tag %q", pathContextName(ctx, module), tag) 3671 } 3672 paths := sourceFileProducer.Srcs() 3673 return paths, nil 3674 } else { 3675 return nil, fmt.Errorf("module %q is not an OutputFileProducer", pathContextName(ctx, module)) 3676 } 3677} 3678 3679// Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to 3680// specify that they can be used as a tool by a genrule module. 3681type HostToolProvider interface { 3682 Module 3683 // HostToolPath returns the path to the host tool for the module if it is one, or an invalid 3684 // OptionalPath. 3685 HostToolPath() OptionalPath 3686} 3687 3688// Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must 3689// be tagged with `android:"path" to support automatic source module dependency resolution. 3690// 3691// Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead. 3692func (m *moduleContext) ExpandSources(srcFiles, excludes []string) Paths { 3693 return PathsForModuleSrcExcludes(m, srcFiles, excludes) 3694} 3695 3696// Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must 3697// be tagged with `android:"path" to support automatic source module dependency resolution. 3698// 3699// Deprecated: use PathForModuleSrc instead. 3700func (m *moduleContext) ExpandSource(srcFile, _ string) Path { 3701 return PathForModuleSrc(m, srcFile) 3702} 3703 3704// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if 3705// the srcFile is non-nil. The property must be tagged with `android:"path" to support automatic source module 3706// dependency resolution. 3707func (m *moduleContext) ExpandOptionalSource(srcFile *string, _ string) OptionalPath { 3708 if srcFile != nil { 3709 return OptionalPathForPath(PathForModuleSrc(m, *srcFile)) 3710 } 3711 return OptionalPath{} 3712} 3713 3714func (m *moduleContext) RequiredModuleNames() []string { 3715 return m.module.RequiredModuleNames() 3716} 3717 3718func (m *moduleContext) HostRequiredModuleNames() []string { 3719 return m.module.HostRequiredModuleNames() 3720} 3721 3722func (m *moduleContext) TargetRequiredModuleNames() []string { 3723 return m.module.TargetRequiredModuleNames() 3724} 3725 3726func init() { 3727 RegisterSingletonType("buildtarget", BuildTargetSingleton) 3728} 3729 3730func BuildTargetSingleton() Singleton { 3731 return &buildTargetSingleton{} 3732} 3733 3734func parentDir(dir string) string { 3735 dir, _ = filepath.Split(dir) 3736 return filepath.Clean(dir) 3737} 3738 3739type buildTargetSingleton struct{} 3740 3741func AddAncestors(ctx SingletonContext, dirMap map[string]Paths, mmName func(string) string) ([]string, []string) { 3742 // Ensure ancestor directories are in dirMap 3743 // Make directories build their direct subdirectories 3744 // Returns a slice of all directories and a slice of top-level directories. 3745 dirs := SortedKeys(dirMap) 3746 for _, dir := range dirs { 3747 dir := parentDir(dir) 3748 for dir != "." && dir != "/" { 3749 if _, exists := dirMap[dir]; exists { 3750 break 3751 } 3752 dirMap[dir] = nil 3753 dir = parentDir(dir) 3754 } 3755 } 3756 dirs = SortedKeys(dirMap) 3757 var topDirs []string 3758 for _, dir := range dirs { 3759 p := parentDir(dir) 3760 if p != "." && p != "/" { 3761 dirMap[p] = append(dirMap[p], PathForPhony(ctx, mmName(dir))) 3762 } else if dir != "." && dir != "/" && dir != "" { 3763 topDirs = append(topDirs, dir) 3764 } 3765 } 3766 return SortedKeys(dirMap), topDirs 3767} 3768 3769func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) { 3770 var checkbuildDeps Paths 3771 3772 mmTarget := func(dir string) string { 3773 return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1) 3774 } 3775 3776 modulesInDir := make(map[string]Paths) 3777 3778 ctx.VisitAllModules(func(module Module) { 3779 blueprintDir := module.base().blueprintDir 3780 installTarget := module.base().installTarget 3781 checkbuildTarget := module.base().checkbuildTarget 3782 3783 if checkbuildTarget != nil { 3784 checkbuildDeps = append(checkbuildDeps, checkbuildTarget) 3785 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget) 3786 } 3787 3788 if installTarget != nil { 3789 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget) 3790 } 3791 }) 3792 3793 suffix := "" 3794 if ctx.Config().KatiEnabled() { 3795 suffix = "-soong" 3796 } 3797 3798 // Create a top-level checkbuild target that depends on all modules 3799 ctx.Phony("checkbuild"+suffix, checkbuildDeps...) 3800 3801 // Make will generate the MODULES-IN-* targets 3802 if ctx.Config().KatiEnabled() { 3803 return 3804 } 3805 3806 dirs, _ := AddAncestors(ctx, modulesInDir, mmTarget) 3807 3808 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and 3809 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp 3810 // files. 3811 for _, dir := range dirs { 3812 ctx.Phony(mmTarget(dir), modulesInDir[dir]...) 3813 } 3814 3815 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild. 3816 type osAndCross struct { 3817 os OsType 3818 hostCross bool 3819 } 3820 osDeps := map[osAndCross]Paths{} 3821 ctx.VisitAllModules(func(module Module) { 3822 if module.Enabled() { 3823 key := osAndCross{os: module.Target().Os, hostCross: module.Target().HostCross} 3824 osDeps[key] = append(osDeps[key], module.base().checkbuildFiles...) 3825 } 3826 }) 3827 3828 osClass := make(map[string]Paths) 3829 for key, deps := range osDeps { 3830 var className string 3831 3832 switch key.os.Class { 3833 case Host: 3834 if key.hostCross { 3835 className = "host-cross" 3836 } else { 3837 className = "host" 3838 } 3839 case Device: 3840 className = "target" 3841 default: 3842 continue 3843 } 3844 3845 name := className + "-" + key.os.Name 3846 osClass[className] = append(osClass[className], PathForPhony(ctx, name)) 3847 3848 ctx.Phony(name, deps...) 3849 } 3850 3851 // Wrap those into host|host-cross|target phony rules 3852 for _, class := range SortedKeys(osClass) { 3853 ctx.Phony(class, osClass[class]...) 3854 } 3855} 3856 3857// Collect information for opening IDE project files in java/jdeps.go. 3858type IDEInfo interface { 3859 IDEInfo(ideInfo *IdeInfo) 3860 BaseModuleName() string 3861} 3862 3863// Extract the base module name from the Import name. 3864// Often the Import name has a prefix "prebuilt_". 3865// Remove the prefix explicitly if needed 3866// until we find a better solution to get the Import name. 3867type IDECustomizedModuleName interface { 3868 IDECustomizedModuleName() string 3869} 3870 3871type IdeInfo struct { 3872 Deps []string `json:"dependencies,omitempty"` 3873 Srcs []string `json:"srcs,omitempty"` 3874 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"` 3875 Jarjar_rules []string `json:"jarjar_rules,omitempty"` 3876 Jars []string `json:"jars,omitempty"` 3877 Classes []string `json:"class,omitempty"` 3878 Installed_paths []string `json:"installed,omitempty"` 3879 SrcJars []string `json:"srcjars,omitempty"` 3880 Paths []string `json:"path,omitempty"` 3881 Static_libs []string `json:"static_libs,omitempty"` 3882 Libs []string `json:"libs,omitempty"` 3883} 3884 3885func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error { 3886 bpctx := ctx.blueprintBaseModuleContext() 3887 return blueprint.CheckBlueprintSyntax(bpctx.ModuleFactories(), filename, contents) 3888} 3889 3890// installPathsDepSet is a thin type-safe wrapper around the generic depSet. It always uses 3891// topological order. 3892type installPathsDepSet struct { 3893 depSet 3894} 3895 3896// newInstallPathsDepSet returns an immutable packagingSpecsDepSet with the given direct and 3897// transitive contents. 3898func newInstallPathsDepSet(direct InstallPaths, transitive []*installPathsDepSet) *installPathsDepSet { 3899 return &installPathsDepSet{*newDepSet(TOPOLOGICAL, direct, transitive)} 3900} 3901 3902// ToList returns the installPathsDepSet flattened to a list in topological order. 3903func (d *installPathsDepSet) ToList() InstallPaths { 3904 if d == nil { 3905 return nil 3906 } 3907 return d.depSet.ToList().(InstallPaths) 3908} 3909