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