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