1// Copyright 2015 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package android 16 17import ( 18 "fmt" 19 "os" 20 "path" 21 "path/filepath" 22 "regexp" 23 "strings" 24 "text/scanner" 25 26 "github.com/google/blueprint" 27 "github.com/google/blueprint/proptools" 28) 29 30var ( 31 DeviceSharedLibrary = "shared_library" 32 DeviceStaticLibrary = "static_library" 33 DeviceExecutable = "executable" 34 HostSharedLibrary = "host_shared_library" 35 HostStaticLibrary = "host_static_library" 36 HostExecutable = "host_executable" 37) 38 39type BuildParams struct { 40 Rule blueprint.Rule 41 Deps blueprint.Deps 42 Depfile WritablePath 43 Description string 44 Output WritablePath 45 Outputs WritablePaths 46 ImplicitOutput WritablePath 47 ImplicitOutputs WritablePaths 48 Input Path 49 Inputs Paths 50 Implicit Path 51 Implicits Paths 52 OrderOnly Paths 53 Validation Path 54 Validations Paths 55 Default bool 56 Args map[string]string 57} 58 59type ModuleBuildParams BuildParams 60 61// EarlyModuleContext provides methods that can be called early, as soon as the properties have 62// been parsed into the module and before any mutators have run. 63type EarlyModuleContext interface { 64 Module() Module 65 ModuleName() string 66 ModuleDir() string 67 ModuleType() string 68 BlueprintsFile() string 69 70 ContainsProperty(name string) bool 71 Errorf(pos scanner.Position, fmt string, args ...interface{}) 72 ModuleErrorf(fmt string, args ...interface{}) 73 PropertyErrorf(property, fmt string, args ...interface{}) 74 Failed() bool 75 76 AddNinjaFileDeps(deps ...string) 77 78 DeviceSpecific() bool 79 SocSpecific() bool 80 ProductSpecific() bool 81 SystemExtSpecific() bool 82 Platform() bool 83 84 Config() Config 85 DeviceConfig() DeviceConfig 86 87 // Deprecated: use Config() 88 AConfig() Config 89 90 // GlobWithDeps returns a list of files that match the specified pattern but do not match any 91 // of the patterns in excludes. It also adds efficient dependencies to rerun the primary 92 // builder whenever a file matching the pattern as added or removed, without rerunning if a 93 // file that does not match the pattern is added to a searched directory. 94 GlobWithDeps(pattern string, excludes []string) ([]string, error) 95 96 Glob(globPattern string, excludes []string) Paths 97 GlobFiles(globPattern string, excludes []string) Paths 98 IsSymlink(path Path) bool 99 Readlink(path Path) string 100} 101 102// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns 103// a Config instead of an interface{}, and some methods have been wrapped to use an android.Module 104// instead of a blueprint.Module, plus some extra methods that return Android-specific information 105// about the current module. 106type BaseModuleContext interface { 107 EarlyModuleContext 108 109 blueprintBaseModuleContext() blueprint.BaseModuleContext 110 111 OtherModuleName(m blueprint.Module) string 112 OtherModuleDir(m blueprint.Module) string 113 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) 114 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag 115 OtherModuleExists(name string) bool 116 OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool 117 OtherModuleReverseDependencyVariantExists(name string) bool 118 OtherModuleType(m blueprint.Module) string 119 120 GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module 121 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module 122 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) 123 124 VisitDirectDepsBlueprint(visit func(blueprint.Module)) 125 VisitDirectDeps(visit func(Module)) 126 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) 127 VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) 128 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module 129 VisitDepsDepthFirst(visit func(Module)) 130 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module 131 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) 132 WalkDeps(visit func(Module, Module) bool) 133 WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) 134 // GetWalkPath is supposed to be called in visit function passed in WalkDeps() 135 // and returns a top-down dependency path from a start module to current child module. 136 GetWalkPath() []Module 137 138 // GetTagPath is supposed to be called in visit function passed in WalkDeps() 139 // and returns a top-down dependency tags path from a start module to current child module. 140 // It has one less entry than GetWalkPath() as it contains the dependency tags that 141 // exist between each adjacent pair of modules in the GetWalkPath(). 142 // GetTagPath()[i] is the tag between GetWalkPath()[i] and GetWalkPath()[i+1] 143 GetTagPath() []blueprint.DependencyTag 144 145 // GetPathString is supposed to be called in visit function passed in WalkDeps() 146 // and returns a multi-line string showing the modules and dependency tags 147 // among them along the top-down dependency path from a start module to current child module. 148 // skipFirst when set to true, the output doesn't include the start module, 149 // which is already printed when this function is used along with ModuleErrorf(). 150 GetPathString(skipFirst bool) string 151 152 AddMissingDependencies(missingDeps []string) 153 154 Target() Target 155 TargetPrimary() bool 156 157 // The additional arch specific targets (e.g. 32/64 bit) that this module variant is 158 // responsible for creating. 159 MultiTargets() []Target 160 Arch() Arch 161 Os() OsType 162 Host() bool 163 Device() bool 164 Darwin() bool 165 Fuchsia() bool 166 Windows() bool 167 Debug() bool 168 PrimaryArch() bool 169} 170 171// Deprecated: use EarlyModuleContext instead 172type BaseContext interface { 173 EarlyModuleContext 174} 175 176type ModuleContext interface { 177 BaseModuleContext 178 179 // Deprecated: use ModuleContext.Build instead. 180 ModuleBuild(pctx PackageContext, params ModuleBuildParams) 181 182 ExpandSources(srcFiles, excludes []string) Paths 183 ExpandSource(srcFile, prop string) Path 184 ExpandOptionalSource(srcFile *string, prop string) OptionalPath 185 186 InstallExecutable(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath 187 InstallFile(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath 188 InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath 189 InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath 190 CheckbuildFile(srcPath Path) 191 192 InstallInData() bool 193 InstallInTestcases() bool 194 InstallInSanitizerDir() bool 195 InstallInRamdisk() bool 196 InstallInRecovery() bool 197 InstallInRoot() bool 198 InstallBypassMake() bool 199 InstallForceOS() *OsType 200 201 RequiredModuleNames() []string 202 HostRequiredModuleNames() []string 203 TargetRequiredModuleNames() []string 204 205 ModuleSubDir() string 206 207 Variable(pctx PackageContext, name, value string) 208 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule 209 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string, 210 // and performs more verification. 211 Build(pctx PackageContext, params BuildParams) 212 // Phony creates a Make-style phony rule, a rule with no commands that can depend on other 213 // phony rules or real files. Phony can be called on the same name multiple times to add 214 // additional dependencies. 215 Phony(phony string, deps ...Path) 216 217 PrimaryModule() Module 218 FinalModule() Module 219 VisitAllModuleVariants(visit func(Module)) 220 221 GetMissingDependencies() []string 222 Namespace() blueprint.Namespace 223} 224 225type Module interface { 226 blueprint.Module 227 228 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions, 229 // but GenerateAndroidBuildActions also has access to Android-specific information. 230 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go 231 GenerateAndroidBuildActions(ModuleContext) 232 233 // Add dependencies to the components of a module, i.e. modules that are created 234 // by the module and which are considered to be part of the creating module. 235 // 236 // This is called before prebuilts are renamed so as to allow a dependency to be 237 // added directly to a prebuilt child module instead of depending on a source module 238 // and relying on prebuilt processing to switch to the prebuilt module if preferred. 239 // 240 // A dependency on a prebuilt must include the "prebuilt_" prefix. 241 ComponentDepsMutator(ctx BottomUpMutatorContext) 242 243 DepsMutator(BottomUpMutatorContext) 244 245 base() *ModuleBase 246 Disable() 247 Enabled() bool 248 Target() Target 249 InstallInData() bool 250 InstallInTestcases() bool 251 InstallInSanitizerDir() bool 252 InstallInRamdisk() bool 253 InstallInRecovery() bool 254 InstallInRoot() bool 255 InstallBypassMake() bool 256 InstallForceOS() *OsType 257 SkipInstall() 258 IsSkipInstall() bool 259 ExportedToMake() bool 260 InitRc() Paths 261 VintfFragments() Paths 262 NoticeFiles() Paths 263 264 AddProperties(props ...interface{}) 265 GetProperties() []interface{} 266 267 BuildParamsForTests() []BuildParams 268 RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams 269 VariablesForTests() map[string]string 270 271 // String returns a string that includes the module name and variants for printing during debugging. 272 String() string 273 274 // Get the qualified module id for this module. 275 qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName 276 277 // Get information about the properties that can contain visibility rules. 278 visibilityProperties() []visibilityProperty 279 280 RequiredModuleNames() []string 281 HostRequiredModuleNames() []string 282 TargetRequiredModuleNames() []string 283 284 filesToInstall() InstallPaths 285} 286 287// Qualified id for a module 288type qualifiedModuleName struct { 289 // The package (i.e. directory) in which the module is defined, without trailing / 290 pkg string 291 292 // The name of the module, empty string if package. 293 name string 294} 295 296func (q qualifiedModuleName) String() string { 297 if q.name == "" { 298 return "//" + q.pkg 299 } 300 return "//" + q.pkg + ":" + q.name 301} 302 303func (q qualifiedModuleName) isRootPackage() bool { 304 return q.pkg == "" && q.name == "" 305} 306 307// Get the id for the package containing this module. 308func (q qualifiedModuleName) getContainingPackageId() qualifiedModuleName { 309 pkg := q.pkg 310 if q.name == "" { 311 if pkg == "" { 312 panic(fmt.Errorf("Cannot get containing package id of root package")) 313 } 314 315 index := strings.LastIndex(pkg, "/") 316 if index == -1 { 317 pkg = "" 318 } else { 319 pkg = pkg[:index] 320 } 321 } 322 return newPackageId(pkg) 323} 324 325func newPackageId(pkg string) qualifiedModuleName { 326 // A qualified id for a package module has no name. 327 return qualifiedModuleName{pkg: pkg, name: ""} 328} 329 330type Dist struct { 331 // Copy the output of this module to the $DIST_DIR when `dist` is specified on the 332 // command line and any of these targets are also on the command line, or otherwise 333 // built 334 Targets []string `android:"arch_variant"` 335 336 // The name of the output artifact. This defaults to the basename of the output of 337 // the module. 338 Dest *string `android:"arch_variant"` 339 340 // The directory within the dist directory to store the artifact. Defaults to the 341 // top level directory (""). 342 Dir *string `android:"arch_variant"` 343 344 // A suffix to add to the artifact file name (before any extension). 345 Suffix *string `android:"arch_variant"` 346 347 // A string tag to select the OutputFiles associated with the tag. Defaults to the 348 // the empty "" string. 349 Tag *string `android:"arch_variant"` 350} 351 352type nameProperties struct { 353 // The name of the module. Must be unique across all modules. 354 Name *string 355} 356 357type commonProperties struct { 358 // emit build rules for this module 359 // 360 // Disabling a module should only be done for those modules that cannot be built 361 // in the current environment. Modules that can build in the current environment 362 // but are not usually required (e.g. superceded by a prebuilt) should not be 363 // disabled as that will prevent them from being built by the checkbuild target 364 // and so prevent early detection of changes that have broken those modules. 365 Enabled *bool `android:"arch_variant"` 366 367 // Controls the visibility of this module to other modules. Allowable values are one or more of 368 // these formats: 369 // 370 // ["//visibility:public"]: Anyone can use this module. 371 // ["//visibility:private"]: Only rules in the module's package (not its subpackages) can use 372 // this module. 373 // ["//visibility:override"]: Discards any rules inherited from defaults or a creating module. 374 // Can only be used at the beginning of a list of visibility rules. 375 // ["//some/package:__pkg__", "//other/package:__pkg__"]: Only modules in some/package and 376 // other/package (defined in some/package/*.bp and other/package/*.bp) have access to 377 // this module. Note that sub-packages do not have access to the rule; for example, 378 // //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__ 379 // is a special module and must be used verbatim. It represents all of the modules in the 380 // package. 381 // ["//project:__subpackages__", "//other:__subpackages__"]: Only modules in packages project 382 // or other or in one of their sub-packages have access to this module. For example, 383 // //project:rule, //project/library:lib or //other/testing/internal:munge are allowed 384 // to depend on this rule (but not //independent:evil) 385 // ["//project"]: This is shorthand for ["//project:__pkg__"] 386 // [":__subpackages__"]: This is shorthand for ["//project:__subpackages__"] where 387 // //project is the module's package. e.g. using [":__subpackages__"] in 388 // packages/apps/Settings/Android.bp is equivalent to 389 // //packages/apps/Settings:__subpackages__. 390 // ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public 391 // for now. It is an error if it is used in a module. 392 // 393 // If a module does not specify the `visibility` property then it uses the 394 // `default_visibility` property of the `package` module in the module's package. 395 // 396 // If the `default_visibility` property is not set for the module's package then 397 // it will use the `default_visibility` of its closest ancestor package for which 398 // a `default_visibility` property is specified. 399 // 400 // If no `default_visibility` property can be found then the module uses the 401 // global default of `//visibility:legacy_public`. 402 // 403 // The `visibility` property has no effect on a defaults module although it does 404 // apply to any non-defaults module that uses it. To set the visibility of a 405 // defaults module, use the `defaults_visibility` property on the defaults module; 406 // not to be confused with the `default_visibility` property on the package module. 407 // 408 // See https://android.googlesource.com/platform/build/soong/+/master/README.md#visibility for 409 // more details. 410 Visibility []string 411 412 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values 413 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both 414 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit 415 // platform 416 Compile_multilib *string `android:"arch_variant"` 417 418 Target struct { 419 Host struct { 420 Compile_multilib *string 421 } 422 Android struct { 423 Compile_multilib *string 424 } 425 } 426 427 // If set to true then the archMutator will create variants for each arch specific target 428 // (e.g. 32/64) that the module is required to produce. If set to false then it will only 429 // create a variant for the architecture and will list the additional arch specific targets 430 // that the variant needs to produce in the CompileMultiTargets property. 431 UseTargetVariants bool `blueprint:"mutated"` 432 Default_multilib string `blueprint:"mutated"` 433 434 // whether this is a proprietary vendor module, and should be installed into /vendor 435 Proprietary *bool 436 437 // vendor who owns this module 438 Owner *string 439 440 // whether this module is specific to an SoC (System-On-a-Chip). When set to true, 441 // it is installed into /vendor (or /system/vendor if vendor partition does not exist). 442 // Use `soc_specific` instead for better meaning. 443 Vendor *bool 444 445 // whether this module is specific to an SoC (System-On-a-Chip). When set to true, 446 // it is installed into /vendor (or /system/vendor if vendor partition does not exist). 447 Soc_specific *bool 448 449 // whether this module is specific to a device, not only for SoC, but also for off-chip 450 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition 451 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist). 452 // This implies `soc_specific:true`. 453 Device_specific *bool 454 455 // whether this module is specific to a software configuration of a product (e.g. country, 456 // network operator, etc). When set to true, it is installed into /product (or 457 // /system/product if product partition does not exist). 458 Product_specific *bool 459 460 // whether this module extends system. When set to true, it is installed into /system_ext 461 // (or /system/system_ext if system_ext partition does not exist). 462 System_ext_specific *bool 463 464 // Whether this module is installed to recovery partition 465 Recovery *bool 466 467 // Whether this module is installed to ramdisk 468 Ramdisk *bool 469 470 // Whether this module is built for non-native architecures (also known as native bridge binary) 471 Native_bridge_supported *bool `android:"arch_variant"` 472 473 // init.rc files to be installed if this module is installed 474 Init_rc []string `android:"path"` 475 476 // VINTF manifest fragments to be installed if this module is installed 477 Vintf_fragments []string `android:"path"` 478 479 // names of other modules to install if this module is installed 480 Required []string `android:"arch_variant"` 481 482 // names of other modules to install on host if this module is installed 483 Host_required []string `android:"arch_variant"` 484 485 // names of other modules to install on target if this module is installed 486 Target_required []string `android:"arch_variant"` 487 488 // relative path to a file to include in the list of notices for the device 489 Notice *string `android:"path"` 490 491 // configuration to distribute output files from this module to the distribution 492 // directory (default: $OUT/dist, configurable with $DIST_DIR) 493 Dist Dist `android:"arch_variant"` 494 495 // a list of configurations to distribute output files from this module to the 496 // distribution directory (default: $OUT/dist, configurable with $DIST_DIR) 497 Dists []Dist `android:"arch_variant"` 498 499 // The OsType of artifacts that this module variant is responsible for creating. 500 // 501 // Set by osMutator 502 CompileOS OsType `blueprint:"mutated"` 503 504 // The Target of artifacts that this module variant is responsible for creating. 505 // 506 // Set by archMutator 507 CompileTarget Target `blueprint:"mutated"` 508 509 // The additional arch specific targets (e.g. 32/64 bit) that this module variant is 510 // responsible for creating. 511 // 512 // By default this is nil as, where necessary, separate variants are created for the 513 // different multilib types supported and that information is encapsulated in the 514 // CompileTarget so the module variant simply needs to create artifacts for that. 515 // 516 // However, if UseTargetVariants is set to false (e.g. by 517 // InitAndroidMultiTargetsArchModule) then no separate variants are created for the 518 // multilib targets. Instead a single variant is created for the architecture and 519 // this contains the multilib specific targets that this variant should create. 520 // 521 // Set by archMutator 522 CompileMultiTargets []Target `blueprint:"mutated"` 523 524 // True if the module variant's CompileTarget is the primary target 525 // 526 // Set by archMutator 527 CompilePrimary bool `blueprint:"mutated"` 528 529 // Set by InitAndroidModule 530 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"` 531 ArchSpecific bool `blueprint:"mutated"` 532 533 // If set to true then a CommonOS variant will be created which will have dependencies 534 // on all its OsType specific variants. Used by sdk/module_exports to create a snapshot 535 // that covers all os and architecture variants. 536 // 537 // The OsType specific variants can be retrieved by calling 538 // GetOsSpecificVariantsOfCommonOSVariant 539 // 540 // Set at module initialization time by calling InitCommonOSAndroidMultiTargetsArchModule 541 CreateCommonOSVariant bool `blueprint:"mutated"` 542 543 // If set to true then this variant is the CommonOS variant that has dependencies on its 544 // OsType specific variants. 545 // 546 // Set by osMutator. 547 CommonOSVariant bool `blueprint:"mutated"` 548 549 SkipInstall bool `blueprint:"mutated"` 550 551 // Disabled by mutators. If set to true, it overrides Enabled property. 552 ForcedDisabled bool `blueprint:"mutated"` 553 554 NamespaceExportedToMake bool `blueprint:"mutated"` 555 556 MissingDeps []string `blueprint:"mutated"` 557 558 // Name and variant strings stored by mutators to enable Module.String() 559 DebugName string `blueprint:"mutated"` 560 DebugMutators []string `blueprint:"mutated"` 561 DebugVariations []string `blueprint:"mutated"` 562 563 // set by ImageMutator 564 ImageVariation string `blueprint:"mutated"` 565} 566 567// A map of OutputFile tag keys to Paths, for disting purposes. 568type TaggedDistFiles map[string]Paths 569 570func MakeDefaultDistFiles(paths ...Path) TaggedDistFiles { 571 // The default OutputFile tag is the empty "" string. 572 return TaggedDistFiles{"": paths} 573} 574 575type hostAndDeviceProperties struct { 576 // If set to true, build a variant of the module for the host. Defaults to false. 577 Host_supported *bool 578 579 // If set to true, build a variant of the module for the device. Defaults to true. 580 Device_supported *bool 581} 582 583type Multilib string 584 585const ( 586 MultilibBoth Multilib = "both" 587 MultilibFirst Multilib = "first" 588 MultilibCommon Multilib = "common" 589 MultilibCommonFirst Multilib = "common_first" 590 MultilibDefault Multilib = "" 591) 592 593type HostOrDeviceSupported int 594 595const ( 596 _ HostOrDeviceSupported = iota 597 598 // Host and HostCross are built by default. Device is not supported. 599 HostSupported 600 601 // Host is built by default. HostCross and Device are not supported. 602 HostSupportedNoCross 603 604 // Device is built by default. Host and HostCross are not supported. 605 DeviceSupported 606 607 // Device is built by default. Host and HostCross are supported. 608 HostAndDeviceSupported 609 610 // Host, HostCross, and Device are built by default. 611 HostAndDeviceDefault 612 613 // Nothing is supported. This is not exposed to the user, but used to mark a 614 // host only module as unsupported when the module type is not supported on 615 // the host OS. E.g. benchmarks are supported on Linux but not Darwin. 616 NeitherHostNorDeviceSupported 617) 618 619type moduleKind int 620 621const ( 622 platformModule moduleKind = iota 623 deviceSpecificModule 624 socSpecificModule 625 productSpecificModule 626 systemExtSpecificModule 627) 628 629func (k moduleKind) String() string { 630 switch k { 631 case platformModule: 632 return "platform" 633 case deviceSpecificModule: 634 return "device-specific" 635 case socSpecificModule: 636 return "soc-specific" 637 case productSpecificModule: 638 return "product-specific" 639 case systemExtSpecificModule: 640 return "systemext-specific" 641 default: 642 panic(fmt.Errorf("unknown module kind %d", k)) 643 } 644} 645 646func initAndroidModuleBase(m Module) { 647 m.base().module = m 648} 649 650func InitAndroidModule(m Module) { 651 initAndroidModuleBase(m) 652 base := m.base() 653 654 m.AddProperties( 655 &base.nameProperties, 656 &base.commonProperties) 657 658 initProductVariableModule(m) 659 660 base.generalProperties = m.GetProperties() 661 base.customizableProperties = m.GetProperties() 662 663 // The default_visibility property needs to be checked and parsed by the visibility module during 664 // its checking and parsing phases so make it the primary visibility property. 665 setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility) 666} 667 668func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) { 669 InitAndroidModule(m) 670 671 base := m.base() 672 base.commonProperties.HostOrDeviceSupported = hod 673 base.commonProperties.Default_multilib = string(defaultMultilib) 674 base.commonProperties.ArchSpecific = true 675 base.commonProperties.UseTargetVariants = true 676 677 switch hod { 678 case HostAndDeviceSupported, HostAndDeviceDefault: 679 m.AddProperties(&base.hostAndDeviceProperties) 680 } 681 682 InitArchModule(m) 683} 684 685func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) { 686 InitAndroidArchModule(m, hod, defaultMultilib) 687 m.base().commonProperties.UseTargetVariants = false 688} 689 690// As InitAndroidMultiTargetsArchModule except it creates an additional CommonOS variant that 691// has dependencies on all the OsType specific variants. 692func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) { 693 InitAndroidArchModule(m, hod, defaultMultilib) 694 m.base().commonProperties.UseTargetVariants = false 695 m.base().commonProperties.CreateCommonOSVariant = true 696} 697 698// A ModuleBase object contains the properties that are common to all Android 699// modules. It should be included as an anonymous field in every module 700// struct definition. InitAndroidModule should then be called from the module's 701// factory function, and the return values from InitAndroidModule should be 702// returned from the factory function. 703// 704// The ModuleBase type is responsible for implementing the GenerateBuildActions 705// method to support the blueprint.Module interface. This method will then call 706// the module's GenerateAndroidBuildActions method once for each build variant 707// that is to be built. GenerateAndroidBuildActions is passed a ModuleContext 708// rather than the usual blueprint.ModuleContext. 709// ModuleContext exposes extra functionality specific to the Android build 710// system including details about the particular build variant that is to be 711// generated. 712// 713// For example: 714// 715// import ( 716// "android/soong/android" 717// ) 718// 719// type myModule struct { 720// android.ModuleBase 721// properties struct { 722// MyProperty string 723// } 724// } 725// 726// func NewMyModule() android.Module) { 727// m := &myModule{} 728// m.AddProperties(&m.properties) 729// android.InitAndroidModule(m) 730// return m 731// } 732// 733// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { 734// // Get the CPU architecture for the current build variant. 735// variantArch := ctx.Arch() 736// 737// // ... 738// } 739type ModuleBase struct { 740 // Putting the curiously recurring thing pointing to the thing that contains 741 // the thing pattern to good use. 742 // TODO: remove this 743 module Module 744 745 nameProperties nameProperties 746 commonProperties commonProperties 747 variableProperties interface{} 748 hostAndDeviceProperties hostAndDeviceProperties 749 generalProperties []interface{} 750 archProperties [][]interface{} 751 customizableProperties []interface{} 752 753 // Information about all the properties on the module that contains visibility rules that need 754 // checking. 755 visibilityPropertyInfo []visibilityProperty 756 757 // The primary visibility property, may be nil, that controls access to the module. 758 primaryVisibilityProperty visibilityProperty 759 760 noAddressSanitizer bool 761 installFiles InstallPaths 762 checkbuildFiles Paths 763 noticeFiles Paths 764 phonies map[string]Paths 765 766 // Used by buildTargetSingleton to create checkbuild and per-directory build targets 767 // Only set on the final variant of each module 768 installTarget WritablePath 769 checkbuildTarget WritablePath 770 blueprintDir string 771 772 hooks hooks 773 774 registerProps []interface{} 775 776 // For tests 777 buildParams []BuildParams 778 ruleParams map[blueprint.Rule]blueprint.RuleParams 779 variables map[string]string 780 781 initRcPaths Paths 782 vintfFragmentsPaths Paths 783 784 prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool 785} 786 787func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {} 788 789func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {} 790 791func (m *ModuleBase) AddProperties(props ...interface{}) { 792 m.registerProps = append(m.registerProps, props...) 793} 794 795func (m *ModuleBase) GetProperties() []interface{} { 796 return m.registerProps 797} 798 799func (m *ModuleBase) BuildParamsForTests() []BuildParams { 800 return m.buildParams 801} 802 803func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams { 804 return m.ruleParams 805} 806 807func (m *ModuleBase) VariablesForTests() map[string]string { 808 return m.variables 809} 810 811func (m *ModuleBase) Prefer32(prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool) { 812 m.prefer32 = prefer32 813} 814 815// Name returns the name of the module. It may be overridden by individual module types, for 816// example prebuilts will prepend prebuilt_ to the name. 817func (m *ModuleBase) Name() string { 818 return String(m.nameProperties.Name) 819} 820 821// String returns a string that includes the module name and variants for printing during debugging. 822func (m *ModuleBase) String() string { 823 sb := strings.Builder{} 824 sb.WriteString(m.commonProperties.DebugName) 825 sb.WriteString("{") 826 for i := range m.commonProperties.DebugMutators { 827 if i != 0 { 828 sb.WriteString(",") 829 } 830 sb.WriteString(m.commonProperties.DebugMutators[i]) 831 sb.WriteString(":") 832 sb.WriteString(m.commonProperties.DebugVariations[i]) 833 } 834 sb.WriteString("}") 835 return sb.String() 836} 837 838// BaseModuleName returns the name of the module as specified in the blueprints file. 839func (m *ModuleBase) BaseModuleName() string { 840 return String(m.nameProperties.Name) 841} 842 843func (m *ModuleBase) base() *ModuleBase { 844 return m 845} 846 847func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName { 848 return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()} 849} 850 851func (m *ModuleBase) visibilityProperties() []visibilityProperty { 852 return m.visibilityPropertyInfo 853} 854 855func (m *ModuleBase) Dists() []Dist { 856 if len(m.commonProperties.Dist.Targets) > 0 { 857 // Make a copy of the underlying Dists slice to protect against 858 // backing array modifications with repeated calls to this method. 859 distsCopy := append([]Dist(nil), m.commonProperties.Dists...) 860 return append(distsCopy, m.commonProperties.Dist) 861 } else { 862 return m.commonProperties.Dists 863 } 864} 865 866func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFiles { 867 distFiles := make(TaggedDistFiles) 868 for _, dist := range m.Dists() { 869 var tag string 870 var distFilesForTag Paths 871 if dist.Tag == nil { 872 tag = "" 873 } else { 874 tag = *dist.Tag 875 } 876 distFilesForTag, err := m.base().module.(OutputFileProducer).OutputFiles(tag) 877 if err != nil { 878 ctx.PropertyErrorf("dist.tag", "%s", err.Error()) 879 } 880 for _, distFile := range distFilesForTag { 881 if distFile != nil && !distFiles[tag].containsPath(distFile) { 882 distFiles[tag] = append(distFiles[tag], distFile) 883 } 884 } 885 } 886 887 return distFiles 888} 889 890func (m *ModuleBase) Target() Target { 891 return m.commonProperties.CompileTarget 892} 893 894func (m *ModuleBase) TargetPrimary() bool { 895 return m.commonProperties.CompilePrimary 896} 897 898func (m *ModuleBase) MultiTargets() []Target { 899 return m.commonProperties.CompileMultiTargets 900} 901 902func (m *ModuleBase) Os() OsType { 903 return m.Target().Os 904} 905 906func (m *ModuleBase) Host() bool { 907 return m.Os().Class == Host || m.Os().Class == HostCross 908} 909 910func (m *ModuleBase) Device() bool { 911 return m.Os().Class == Device 912} 913 914func (m *ModuleBase) Arch() Arch { 915 return m.Target().Arch 916} 917 918func (m *ModuleBase) ArchSpecific() bool { 919 return m.commonProperties.ArchSpecific 920} 921 922// True if the current variant is a CommonOS variant, false otherwise. 923func (m *ModuleBase) IsCommonOSVariant() bool { 924 return m.commonProperties.CommonOSVariant 925} 926 927func (m *ModuleBase) OsClassSupported() []OsClass { 928 switch m.commonProperties.HostOrDeviceSupported { 929 case HostSupported: 930 return []OsClass{Host, HostCross} 931 case HostSupportedNoCross: 932 return []OsClass{Host} 933 case DeviceSupported: 934 return []OsClass{Device} 935 case HostAndDeviceSupported, HostAndDeviceDefault: 936 var supported []OsClass 937 if Bool(m.hostAndDeviceProperties.Host_supported) || 938 (m.commonProperties.HostOrDeviceSupported == HostAndDeviceDefault && 939 m.hostAndDeviceProperties.Host_supported == nil) { 940 supported = append(supported, Host, HostCross) 941 } 942 if m.hostAndDeviceProperties.Device_supported == nil || 943 *m.hostAndDeviceProperties.Device_supported { 944 supported = append(supported, Device) 945 } 946 return supported 947 default: 948 return nil 949 } 950} 951 952func (m *ModuleBase) DeviceSupported() bool { 953 return m.commonProperties.HostOrDeviceSupported == DeviceSupported || 954 m.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported && 955 (m.hostAndDeviceProperties.Device_supported == nil || 956 *m.hostAndDeviceProperties.Device_supported) 957} 958 959func (m *ModuleBase) HostSupported() bool { 960 return m.commonProperties.HostOrDeviceSupported == HostSupported || 961 m.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported && 962 (m.hostAndDeviceProperties.Host_supported != nil && 963 *m.hostAndDeviceProperties.Host_supported) 964} 965 966func (m *ModuleBase) Platform() bool { 967 return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.SystemExtSpecific() 968} 969 970func (m *ModuleBase) DeviceSpecific() bool { 971 return Bool(m.commonProperties.Device_specific) 972} 973 974func (m *ModuleBase) SocSpecific() bool { 975 return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific) 976} 977 978func (m *ModuleBase) ProductSpecific() bool { 979 return Bool(m.commonProperties.Product_specific) 980} 981 982func (m *ModuleBase) SystemExtSpecific() bool { 983 return Bool(m.commonProperties.System_ext_specific) 984} 985 986// RequiresStableAPIs returns true if the module will be installed to a partition that may 987// be updated separately from the system image. 988func (m *ModuleBase) RequiresStableAPIs(ctx BaseModuleContext) bool { 989 return m.SocSpecific() || m.DeviceSpecific() || 990 (m.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) 991} 992 993func (m *ModuleBase) PartitionTag(config DeviceConfig) string { 994 partition := "system" 995 if m.SocSpecific() { 996 // A SoC-specific module could be on the vendor partition at 997 // "vendor" or the system partition at "system/vendor". 998 if config.VendorPath() == "vendor" { 999 partition = "vendor" 1000 } 1001 } else if m.DeviceSpecific() { 1002 // A device-specific module could be on the odm partition at 1003 // "odm", the vendor partition at "vendor/odm", or the system 1004 // partition at "system/vendor/odm". 1005 if config.OdmPath() == "odm" { 1006 partition = "odm" 1007 } else if strings.HasPrefix(config.OdmPath(), "vendor/") { 1008 partition = "vendor" 1009 } 1010 } else if m.ProductSpecific() { 1011 // A product-specific module could be on the product partition 1012 // at "product" or the system partition at "system/product". 1013 if config.ProductPath() == "product" { 1014 partition = "product" 1015 } 1016 } else if m.SystemExtSpecific() { 1017 // A system_ext-specific module could be on the system_ext 1018 // partition at "system_ext" or the system partition at 1019 // "system/system_ext". 1020 if config.SystemExtPath() == "system_ext" { 1021 partition = "system_ext" 1022 } 1023 } 1024 return partition 1025} 1026 1027func (m *ModuleBase) Enabled() bool { 1028 if m.commonProperties.ForcedDisabled { 1029 return false 1030 } 1031 if m.commonProperties.Enabled == nil { 1032 return !m.Os().DefaultDisabled 1033 } 1034 return *m.commonProperties.Enabled 1035} 1036 1037func (m *ModuleBase) Disable() { 1038 m.commonProperties.ForcedDisabled = true 1039} 1040 1041func (m *ModuleBase) SkipInstall() { 1042 m.commonProperties.SkipInstall = true 1043} 1044 1045func (m *ModuleBase) IsSkipInstall() bool { 1046 return m.commonProperties.SkipInstall == true 1047} 1048 1049func (m *ModuleBase) ExportedToMake() bool { 1050 return m.commonProperties.NamespaceExportedToMake 1051} 1052 1053func (m *ModuleBase) computeInstallDeps(ctx blueprint.ModuleContext) InstallPaths { 1054 1055 var result InstallPaths 1056 // TODO(ccross): we need to use WalkDeps and have some way to know which dependencies require installation 1057 ctx.VisitDepsDepthFirst(func(m blueprint.Module) { 1058 if a, ok := m.(Module); ok { 1059 result = append(result, a.filesToInstall()...) 1060 } 1061 }) 1062 1063 return result 1064} 1065 1066func (m *ModuleBase) filesToInstall() InstallPaths { 1067 return m.installFiles 1068} 1069 1070func (m *ModuleBase) NoAddressSanitizer() bool { 1071 return m.noAddressSanitizer 1072} 1073 1074func (m *ModuleBase) InstallInData() bool { 1075 return false 1076} 1077 1078func (m *ModuleBase) InstallInTestcases() bool { 1079 return false 1080} 1081 1082func (m *ModuleBase) InstallInSanitizerDir() bool { 1083 return false 1084} 1085 1086func (m *ModuleBase) InstallInRamdisk() bool { 1087 return Bool(m.commonProperties.Ramdisk) 1088} 1089 1090func (m *ModuleBase) InstallInRecovery() bool { 1091 return Bool(m.commonProperties.Recovery) 1092} 1093 1094func (m *ModuleBase) InstallInRoot() bool { 1095 return false 1096} 1097 1098func (m *ModuleBase) InstallBypassMake() bool { 1099 return false 1100} 1101 1102func (m *ModuleBase) InstallForceOS() *OsType { 1103 return nil 1104} 1105 1106func (m *ModuleBase) Owner() string { 1107 return String(m.commonProperties.Owner) 1108} 1109 1110func (m *ModuleBase) NoticeFiles() Paths { 1111 return m.noticeFiles 1112} 1113 1114func (m *ModuleBase) setImageVariation(variant string) { 1115 m.commonProperties.ImageVariation = variant 1116} 1117 1118func (m *ModuleBase) ImageVariation() blueprint.Variation { 1119 return blueprint.Variation{ 1120 Mutator: "image", 1121 Variation: m.base().commonProperties.ImageVariation, 1122 } 1123} 1124 1125func (m *ModuleBase) getVariationByMutatorName(mutator string) string { 1126 for i, v := range m.commonProperties.DebugMutators { 1127 if v == mutator { 1128 return m.commonProperties.DebugVariations[i] 1129 } 1130 } 1131 1132 return "" 1133} 1134 1135func (m *ModuleBase) InRamdisk() bool { 1136 return m.base().commonProperties.ImageVariation == RamdiskVariation 1137} 1138 1139func (m *ModuleBase) InRecovery() bool { 1140 return m.base().commonProperties.ImageVariation == RecoveryVariation 1141} 1142 1143func (m *ModuleBase) RequiredModuleNames() []string { 1144 return m.base().commonProperties.Required 1145} 1146 1147func (m *ModuleBase) HostRequiredModuleNames() []string { 1148 return m.base().commonProperties.Host_required 1149} 1150 1151func (m *ModuleBase) TargetRequiredModuleNames() []string { 1152 return m.base().commonProperties.Target_required 1153} 1154 1155func (m *ModuleBase) InitRc() Paths { 1156 return append(Paths{}, m.initRcPaths...) 1157} 1158 1159func (m *ModuleBase) VintfFragments() Paths { 1160 return append(Paths{}, m.vintfFragmentsPaths...) 1161} 1162 1163func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) { 1164 var allInstalledFiles InstallPaths 1165 var allCheckbuildFiles Paths 1166 ctx.VisitAllModuleVariants(func(module Module) { 1167 a := module.base() 1168 allInstalledFiles = append(allInstalledFiles, a.installFiles...) 1169 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...) 1170 }) 1171 1172 var deps Paths 1173 1174 namespacePrefix := ctx.Namespace().(*Namespace).id 1175 if namespacePrefix != "" { 1176 namespacePrefix = namespacePrefix + "-" 1177 } 1178 1179 if len(allInstalledFiles) > 0 { 1180 name := namespacePrefix + ctx.ModuleName() + "-install" 1181 ctx.Phony(name, allInstalledFiles.Paths()...) 1182 m.installTarget = PathForPhony(ctx, name) 1183 deps = append(deps, m.installTarget) 1184 } 1185 1186 if len(allCheckbuildFiles) > 0 { 1187 name := namespacePrefix + ctx.ModuleName() + "-checkbuild" 1188 ctx.Phony(name, allCheckbuildFiles...) 1189 m.checkbuildTarget = PathForPhony(ctx, name) 1190 deps = append(deps, m.checkbuildTarget) 1191 } 1192 1193 if len(deps) > 0 { 1194 suffix := "" 1195 if ctx.Config().EmbeddedInMake() { 1196 suffix = "-soong" 1197 } 1198 1199 ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...) 1200 1201 m.blueprintDir = ctx.ModuleDir() 1202 } 1203} 1204 1205func determineModuleKind(m *ModuleBase, ctx blueprint.EarlyModuleContext) moduleKind { 1206 var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific) 1207 var deviceSpecific = Bool(m.commonProperties.Device_specific) 1208 var productSpecific = Bool(m.commonProperties.Product_specific) 1209 var systemExtSpecific = Bool(m.commonProperties.System_ext_specific) 1210 1211 msg := "conflicting value set here" 1212 if socSpecific && deviceSpecific { 1213 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.") 1214 if Bool(m.commonProperties.Vendor) { 1215 ctx.PropertyErrorf("vendor", msg) 1216 } 1217 if Bool(m.commonProperties.Proprietary) { 1218 ctx.PropertyErrorf("proprietary", msg) 1219 } 1220 if Bool(m.commonProperties.Soc_specific) { 1221 ctx.PropertyErrorf("soc_specific", msg) 1222 } 1223 } 1224 1225 if productSpecific && systemExtSpecific { 1226 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and system_ext at the same time.") 1227 ctx.PropertyErrorf("system_ext_specific", msg) 1228 } 1229 1230 if (socSpecific || deviceSpecific) && (productSpecific || systemExtSpecific) { 1231 if productSpecific { 1232 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.") 1233 } else { 1234 ctx.PropertyErrorf("system_ext_specific", "a module cannot be specific to SoC or device and system_ext at the same time.") 1235 } 1236 if deviceSpecific { 1237 ctx.PropertyErrorf("device_specific", msg) 1238 } else { 1239 if Bool(m.commonProperties.Vendor) { 1240 ctx.PropertyErrorf("vendor", msg) 1241 } 1242 if Bool(m.commonProperties.Proprietary) { 1243 ctx.PropertyErrorf("proprietary", msg) 1244 } 1245 if Bool(m.commonProperties.Soc_specific) { 1246 ctx.PropertyErrorf("soc_specific", msg) 1247 } 1248 } 1249 } 1250 1251 if productSpecific { 1252 return productSpecificModule 1253 } else if systemExtSpecific { 1254 return systemExtSpecificModule 1255 } else if deviceSpecific { 1256 return deviceSpecificModule 1257 } else if socSpecific { 1258 return socSpecificModule 1259 } else { 1260 return platformModule 1261 } 1262} 1263 1264func (m *ModuleBase) earlyModuleContextFactory(ctx blueprint.EarlyModuleContext) earlyModuleContext { 1265 return earlyModuleContext{ 1266 EarlyModuleContext: ctx, 1267 kind: determineModuleKind(m, ctx), 1268 config: ctx.Config().(Config), 1269 } 1270} 1271 1272func (m *ModuleBase) baseModuleContextFactory(ctx blueprint.BaseModuleContext) baseModuleContext { 1273 return baseModuleContext{ 1274 bp: ctx, 1275 earlyModuleContext: m.earlyModuleContextFactory(ctx), 1276 os: m.commonProperties.CompileOS, 1277 target: m.commonProperties.CompileTarget, 1278 targetPrimary: m.commonProperties.CompilePrimary, 1279 multiTargets: m.commonProperties.CompileMultiTargets, 1280 } 1281} 1282 1283func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) { 1284 ctx := &moduleContext{ 1285 module: m.module, 1286 bp: blueprintCtx, 1287 baseModuleContext: m.baseModuleContextFactory(blueprintCtx), 1288 installDeps: m.computeInstallDeps(blueprintCtx), 1289 installFiles: m.installFiles, 1290 variables: make(map[string]string), 1291 } 1292 1293 // Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never 1294 // reporting missing dependency errors in Blueprint when AllowMissingDependencies == true. 1295 // TODO: This will be removed once defaults modules handle missing dependency errors 1296 blueprintCtx.GetMissingDependencies() 1297 1298 // For the final GenerateAndroidBuildActions pass, require that all visited dependencies Soong modules and 1299 // are enabled. Unless the module is a CommonOS variant which may have dependencies on disabled variants 1300 // (because the dependencies are added before the modules are disabled). The 1301 // GetOsSpecificVariantsOfCommonOSVariant(...) method will ensure that the disabled variants are 1302 // ignored. 1303 ctx.baseModuleContext.strictVisitDeps = !m.IsCommonOSVariant() 1304 1305 if ctx.config.captureBuild { 1306 ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams) 1307 } 1308 1309 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " " 1310 var suffix []string 1311 if ctx.Os().Class != Device && ctx.Os().Class != Generic { 1312 suffix = append(suffix, ctx.Os().String()) 1313 } 1314 if !ctx.PrimaryArch() { 1315 suffix = append(suffix, ctx.Arch().ArchType.String()) 1316 } 1317 if apex, ok := m.module.(ApexModule); ok && !apex.IsForPlatform() { 1318 suffix = append(suffix, apex.ApexName()) 1319 } 1320 1321 ctx.Variable(pctx, "moduleDesc", desc) 1322 1323 s := "" 1324 if len(suffix) > 0 { 1325 s = " [" + strings.Join(suffix, " ") + "]" 1326 } 1327 ctx.Variable(pctx, "moduleDescSuffix", s) 1328 1329 // Some common property checks for properties that will be used later in androidmk.go 1330 if m.commonProperties.Dist.Dest != nil { 1331 _, err := validateSafePath(*m.commonProperties.Dist.Dest) 1332 if err != nil { 1333 ctx.PropertyErrorf("dist.dest", "%s", err.Error()) 1334 } 1335 } 1336 if m.commonProperties.Dist.Dir != nil { 1337 _, err := validateSafePath(*m.commonProperties.Dist.Dir) 1338 if err != nil { 1339 ctx.PropertyErrorf("dist.dir", "%s", err.Error()) 1340 } 1341 } 1342 if m.commonProperties.Dist.Suffix != nil { 1343 if strings.Contains(*m.commonProperties.Dist.Suffix, "/") { 1344 ctx.PropertyErrorf("dist.suffix", "Suffix may not contain a '/' character.") 1345 } 1346 } 1347 1348 if m.Enabled() { 1349 // ensure all direct android.Module deps are enabled 1350 ctx.VisitDirectDepsBlueprint(func(bm blueprint.Module) { 1351 if _, ok := bm.(Module); ok { 1352 ctx.validateAndroidModule(bm, ctx.baseModuleContext.strictVisitDeps) 1353 } 1354 }) 1355 1356 m.noticeFiles = make([]Path, 0) 1357 optPath := OptionalPath{} 1358 notice := proptools.StringDefault(m.commonProperties.Notice, "") 1359 if module := SrcIsModule(notice); module != "" { 1360 optPath = ctx.ExpandOptionalSource(¬ice, "notice") 1361 } else if notice != "" { 1362 noticePath := filepath.Join(ctx.ModuleDir(), notice) 1363 optPath = ExistentPathForSource(ctx, noticePath) 1364 } 1365 if optPath.Valid() { 1366 m.noticeFiles = append(m.noticeFiles, optPath.Path()) 1367 } else { 1368 for _, notice = range []string{"LICENSE", "LICENCE", "NOTICE"} { 1369 noticePath := filepath.Join(ctx.ModuleDir(), notice) 1370 optPath = ExistentPathForSource(ctx, noticePath) 1371 if optPath.Valid() { 1372 m.noticeFiles = append(m.noticeFiles, optPath.Path()) 1373 } 1374 } 1375 } 1376 1377 m.module.GenerateAndroidBuildActions(ctx) 1378 if ctx.Failed() { 1379 return 1380 } 1381 1382 m.installFiles = append(m.installFiles, ctx.installFiles...) 1383 m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...) 1384 m.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc) 1385 m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments) 1386 for k, v := range ctx.phonies { 1387 m.phonies[k] = append(m.phonies[k], v...) 1388 } 1389 } else if ctx.Config().AllowMissingDependencies() { 1390 // If the module is not enabled it will not create any build rules, nothing will call 1391 // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled 1392 // and report them as an error even when AllowMissingDependencies = true. Call 1393 // ctx.GetMissingDependencies() here to tell blueprint not to handle them. 1394 ctx.GetMissingDependencies() 1395 } 1396 1397 if m == ctx.FinalModule().(Module).base() { 1398 m.generateModuleTarget(ctx) 1399 if ctx.Failed() { 1400 return 1401 } 1402 } 1403 1404 m.buildParams = ctx.buildParams 1405 m.ruleParams = ctx.ruleParams 1406 m.variables = ctx.variables 1407} 1408 1409type earlyModuleContext struct { 1410 blueprint.EarlyModuleContext 1411 1412 kind moduleKind 1413 config Config 1414} 1415 1416func (e *earlyModuleContext) Glob(globPattern string, excludes []string) Paths { 1417 ret, err := e.GlobWithDeps(globPattern, excludes) 1418 if err != nil { 1419 e.ModuleErrorf("glob: %s", err.Error()) 1420 } 1421 return pathsForModuleSrcFromFullPath(e, ret, true) 1422} 1423 1424func (e *earlyModuleContext) GlobFiles(globPattern string, excludes []string) Paths { 1425 ret, err := e.GlobWithDeps(globPattern, excludes) 1426 if err != nil { 1427 e.ModuleErrorf("glob: %s", err.Error()) 1428 } 1429 return pathsForModuleSrcFromFullPath(e, ret, false) 1430} 1431 1432func (b *earlyModuleContext) IsSymlink(path Path) bool { 1433 fileInfo, err := b.config.fs.Lstat(path.String()) 1434 if err != nil { 1435 b.ModuleErrorf("os.Lstat(%q) failed: %s", path.String(), err) 1436 } 1437 return fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink 1438} 1439 1440func (b *earlyModuleContext) Readlink(path Path) string { 1441 dest, err := b.config.fs.Readlink(path.String()) 1442 if err != nil { 1443 b.ModuleErrorf("os.Readlink(%q) failed: %s", path.String(), err) 1444 } 1445 return dest 1446} 1447 1448func (e *earlyModuleContext) Module() Module { 1449 module, _ := e.EarlyModuleContext.Module().(Module) 1450 return module 1451} 1452 1453func (e *earlyModuleContext) Config() Config { 1454 return e.EarlyModuleContext.Config().(Config) 1455} 1456 1457func (e *earlyModuleContext) AConfig() Config { 1458 return e.config 1459} 1460 1461func (e *earlyModuleContext) DeviceConfig() DeviceConfig { 1462 return DeviceConfig{e.config.deviceConfig} 1463} 1464 1465func (e *earlyModuleContext) Platform() bool { 1466 return e.kind == platformModule 1467} 1468 1469func (e *earlyModuleContext) DeviceSpecific() bool { 1470 return e.kind == deviceSpecificModule 1471} 1472 1473func (e *earlyModuleContext) SocSpecific() bool { 1474 return e.kind == socSpecificModule 1475} 1476 1477func (e *earlyModuleContext) ProductSpecific() bool { 1478 return e.kind == productSpecificModule 1479} 1480 1481func (e *earlyModuleContext) SystemExtSpecific() bool { 1482 return e.kind == systemExtSpecificModule 1483} 1484 1485type baseModuleContext struct { 1486 bp blueprint.BaseModuleContext 1487 earlyModuleContext 1488 os OsType 1489 target Target 1490 multiTargets []Target 1491 targetPrimary bool 1492 debug bool 1493 1494 walkPath []Module 1495 tagPath []blueprint.DependencyTag 1496 1497 strictVisitDeps bool // If true, enforce that all dependencies are enabled 1498} 1499 1500func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string { 1501 return b.bp.OtherModuleName(m) 1502} 1503func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { return b.bp.OtherModuleDir(m) } 1504func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) { 1505 b.bp.OtherModuleErrorf(m, fmt, args...) 1506} 1507func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag { 1508 return b.bp.OtherModuleDependencyTag(m) 1509} 1510func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) } 1511func (b *baseModuleContext) OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool { 1512 return b.bp.OtherModuleDependencyVariantExists(variations, name) 1513} 1514func (b *baseModuleContext) OtherModuleReverseDependencyVariantExists(name string) bool { 1515 return b.bp.OtherModuleReverseDependencyVariantExists(name) 1516} 1517func (b *baseModuleContext) OtherModuleType(m blueprint.Module) string { 1518 return b.bp.OtherModuleType(m) 1519} 1520 1521func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module { 1522 return b.bp.GetDirectDepWithTag(name, tag) 1523} 1524 1525func (b *baseModuleContext) blueprintBaseModuleContext() blueprint.BaseModuleContext { 1526 return b.bp 1527} 1528 1529type moduleContext struct { 1530 bp blueprint.ModuleContext 1531 baseModuleContext 1532 installDeps InstallPaths 1533 installFiles InstallPaths 1534 checkbuildFiles Paths 1535 module Module 1536 phonies map[string]Paths 1537 1538 // For tests 1539 buildParams []BuildParams 1540 ruleParams map[blueprint.Rule]blueprint.RuleParams 1541 variables map[string]string 1542} 1543 1544func (m *moduleContext) ninjaError(params BuildParams, err error) (PackageContext, BuildParams) { 1545 return pctx, BuildParams{ 1546 Rule: ErrorRule, 1547 Description: params.Description, 1548 Output: params.Output, 1549 Outputs: params.Outputs, 1550 ImplicitOutput: params.ImplicitOutput, 1551 ImplicitOutputs: params.ImplicitOutputs, 1552 Args: map[string]string{ 1553 "error": err.Error(), 1554 }, 1555 } 1556} 1557 1558func (m *moduleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) { 1559 m.Build(pctx, BuildParams(params)) 1560} 1561 1562func convertBuildParams(params BuildParams) blueprint.BuildParams { 1563 bparams := blueprint.BuildParams{ 1564 Rule: params.Rule, 1565 Description: params.Description, 1566 Deps: params.Deps, 1567 Outputs: params.Outputs.Strings(), 1568 ImplicitOutputs: params.ImplicitOutputs.Strings(), 1569 Inputs: params.Inputs.Strings(), 1570 Implicits: params.Implicits.Strings(), 1571 OrderOnly: params.OrderOnly.Strings(), 1572 Validations: params.Validations.Strings(), 1573 Args: params.Args, 1574 Optional: !params.Default, 1575 } 1576 1577 if params.Depfile != nil { 1578 bparams.Depfile = params.Depfile.String() 1579 } 1580 if params.Output != nil { 1581 bparams.Outputs = append(bparams.Outputs, params.Output.String()) 1582 } 1583 if params.ImplicitOutput != nil { 1584 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String()) 1585 } 1586 if params.Input != nil { 1587 bparams.Inputs = append(bparams.Inputs, params.Input.String()) 1588 } 1589 if params.Implicit != nil { 1590 bparams.Implicits = append(bparams.Implicits, params.Implicit.String()) 1591 } 1592 if params.Validation != nil { 1593 bparams.Validations = append(bparams.Validations, params.Validation.String()) 1594 } 1595 1596 bparams.Outputs = proptools.NinjaEscapeList(bparams.Outputs) 1597 bparams.ImplicitOutputs = proptools.NinjaEscapeList(bparams.ImplicitOutputs) 1598 bparams.Inputs = proptools.NinjaEscapeList(bparams.Inputs) 1599 bparams.Implicits = proptools.NinjaEscapeList(bparams.Implicits) 1600 bparams.OrderOnly = proptools.NinjaEscapeList(bparams.OrderOnly) 1601 bparams.Validations = proptools.NinjaEscapeList(bparams.Validations) 1602 bparams.Depfile = proptools.NinjaEscape(bparams.Depfile) 1603 1604 return bparams 1605} 1606 1607func (m *moduleContext) Variable(pctx PackageContext, name, value string) { 1608 if m.config.captureBuild { 1609 m.variables[name] = value 1610 } 1611 1612 m.bp.Variable(pctx.PackageContext, name, value) 1613} 1614 1615func (m *moduleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams, 1616 argNames ...string) blueprint.Rule { 1617 1618 if m.config.UseRemoteBuild() { 1619 if params.Pool == nil { 1620 // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict 1621 // jobs to the local parallelism value 1622 params.Pool = localPool 1623 } else if params.Pool == remotePool { 1624 // remotePool is a fake pool used to identify rule that are supported for remoting. If the rule's 1625 // pool is the remotePool, replace with nil so that ninja runs it at NINJA_REMOTE_NUM_JOBS 1626 // parallelism. 1627 params.Pool = nil 1628 } 1629 } 1630 1631 rule := m.bp.Rule(pctx.PackageContext, name, params, argNames...) 1632 1633 if m.config.captureBuild { 1634 m.ruleParams[rule] = params 1635 } 1636 1637 return rule 1638} 1639 1640func (m *moduleContext) Build(pctx PackageContext, params BuildParams) { 1641 if params.Description != "" { 1642 params.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}" 1643 } 1644 1645 if missingDeps := m.GetMissingDependencies(); len(missingDeps) > 0 { 1646 pctx, params = m.ninjaError(params, fmt.Errorf("module %s missing dependencies: %s\n", 1647 m.ModuleName(), strings.Join(missingDeps, ", "))) 1648 } 1649 1650 if m.config.captureBuild { 1651 m.buildParams = append(m.buildParams, params) 1652 } 1653 1654 m.bp.Build(pctx.PackageContext, convertBuildParams(params)) 1655} 1656 1657func (m *moduleContext) Phony(name string, deps ...Path) { 1658 addPhony(m.config, name, deps...) 1659} 1660 1661func (m *moduleContext) GetMissingDependencies() []string { 1662 var missingDeps []string 1663 missingDeps = append(missingDeps, m.Module().base().commonProperties.MissingDeps...) 1664 missingDeps = append(missingDeps, m.bp.GetMissingDependencies()...) 1665 missingDeps = FirstUniqueStrings(missingDeps) 1666 return missingDeps 1667} 1668 1669func (b *baseModuleContext) AddMissingDependencies(deps []string) { 1670 if deps != nil { 1671 missingDeps := &b.Module().base().commonProperties.MissingDeps 1672 *missingDeps = append(*missingDeps, deps...) 1673 *missingDeps = FirstUniqueStrings(*missingDeps) 1674 } 1675} 1676 1677func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, strict bool) Module { 1678 aModule, _ := module.(Module) 1679 1680 if !strict { 1681 return aModule 1682 } 1683 1684 if aModule == nil { 1685 b.ModuleErrorf("module %q not an android module", b.OtherModuleName(module)) 1686 return nil 1687 } 1688 1689 if !aModule.Enabled() { 1690 if b.Config().AllowMissingDependencies() { 1691 b.AddMissingDependencies([]string{b.OtherModuleName(aModule)}) 1692 } else { 1693 b.ModuleErrorf("depends on disabled module %q", b.OtherModuleName(aModule)) 1694 } 1695 return nil 1696 } 1697 return aModule 1698} 1699 1700func (b *baseModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) { 1701 type dep struct { 1702 mod blueprint.Module 1703 tag blueprint.DependencyTag 1704 } 1705 var deps []dep 1706 b.VisitDirectDepsBlueprint(func(module blueprint.Module) { 1707 if aModule, _ := module.(Module); aModule != nil && aModule.base().BaseModuleName() == name { 1708 returnedTag := b.bp.OtherModuleDependencyTag(aModule) 1709 if tag == nil || returnedTag == tag { 1710 deps = append(deps, dep{aModule, returnedTag}) 1711 } 1712 } 1713 }) 1714 if len(deps) == 1 { 1715 return deps[0].mod, deps[0].tag 1716 } else if len(deps) >= 2 { 1717 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q", 1718 name, b.ModuleName())) 1719 } else { 1720 return nil, nil 1721 } 1722} 1723 1724func (b *baseModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module { 1725 var deps []Module 1726 b.VisitDirectDepsBlueprint(func(module blueprint.Module) { 1727 if aModule, _ := module.(Module); aModule != nil { 1728 if b.bp.OtherModuleDependencyTag(aModule) == tag { 1729 deps = append(deps, aModule) 1730 } 1731 } 1732 }) 1733 return deps 1734} 1735 1736func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module { 1737 module, _ := m.getDirectDepInternal(name, tag) 1738 return module 1739} 1740 1741func (b *baseModuleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) { 1742 return b.getDirectDepInternal(name, nil) 1743} 1744 1745func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) { 1746 b.bp.VisitDirectDeps(visit) 1747} 1748 1749func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) { 1750 b.bp.VisitDirectDeps(func(module blueprint.Module) { 1751 if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil { 1752 visit(aModule) 1753 } 1754 }) 1755} 1756 1757func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) { 1758 b.bp.VisitDirectDeps(func(module blueprint.Module) { 1759 if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil { 1760 if b.bp.OtherModuleDependencyTag(aModule) == tag { 1761 visit(aModule) 1762 } 1763 } 1764 }) 1765} 1766 1767func (b *baseModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) { 1768 b.bp.VisitDirectDepsIf( 1769 // pred 1770 func(module blueprint.Module) bool { 1771 if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil { 1772 return pred(aModule) 1773 } else { 1774 return false 1775 } 1776 }, 1777 // visit 1778 func(module blueprint.Module) { 1779 visit(module.(Module)) 1780 }) 1781} 1782 1783func (b *baseModuleContext) VisitDepsDepthFirst(visit func(Module)) { 1784 b.bp.VisitDepsDepthFirst(func(module blueprint.Module) { 1785 if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil { 1786 visit(aModule) 1787 } 1788 }) 1789} 1790 1791func (b *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) { 1792 b.bp.VisitDepsDepthFirstIf( 1793 // pred 1794 func(module blueprint.Module) bool { 1795 if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil { 1796 return pred(aModule) 1797 } else { 1798 return false 1799 } 1800 }, 1801 // visit 1802 func(module blueprint.Module) { 1803 visit(module.(Module)) 1804 }) 1805} 1806 1807func (b *baseModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) { 1808 b.bp.WalkDeps(visit) 1809} 1810 1811func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) { 1812 b.walkPath = []Module{b.Module()} 1813 b.tagPath = []blueprint.DependencyTag{} 1814 b.bp.WalkDeps(func(child, parent blueprint.Module) bool { 1815 childAndroidModule, _ := child.(Module) 1816 parentAndroidModule, _ := parent.(Module) 1817 if childAndroidModule != nil && parentAndroidModule != nil { 1818 // record walkPath before visit 1819 for b.walkPath[len(b.walkPath)-1] != parentAndroidModule { 1820 b.walkPath = b.walkPath[0 : len(b.walkPath)-1] 1821 b.tagPath = b.tagPath[0 : len(b.tagPath)-1] 1822 } 1823 b.walkPath = append(b.walkPath, childAndroidModule) 1824 b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule)) 1825 return visit(childAndroidModule, parentAndroidModule) 1826 } else { 1827 return false 1828 } 1829 }) 1830} 1831 1832func (b *baseModuleContext) GetWalkPath() []Module { 1833 return b.walkPath 1834} 1835 1836func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag { 1837 return b.tagPath 1838} 1839 1840// A regexp for removing boilerplate from BaseDependencyTag from the string representation of 1841// a dependency tag. 1842var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:blueprint.BaseDependencyTag{}\E(, )?`) 1843 1844// PrettyPrintTag returns string representation of the tag, but prefers 1845// custom String() method if available. 1846func PrettyPrintTag(tag blueprint.DependencyTag) string { 1847 // Use tag's custom String() method if available. 1848 if stringer, ok := tag.(fmt.Stringer); ok { 1849 return stringer.String() 1850 } 1851 1852 // Otherwise, get a default string representation of the tag's struct. 1853 tagString := fmt.Sprintf("%#v", tag) 1854 1855 // Remove the boilerplate from BaseDependencyTag as it adds no value. 1856 tagString = tagCleaner.ReplaceAllString(tagString, "") 1857 return tagString 1858} 1859 1860func (b *baseModuleContext) GetPathString(skipFirst bool) string { 1861 sb := strings.Builder{} 1862 tagPath := b.GetTagPath() 1863 walkPath := b.GetWalkPath() 1864 if !skipFirst { 1865 sb.WriteString(walkPath[0].String()) 1866 } 1867 for i, m := range walkPath[1:] { 1868 sb.WriteString("\n") 1869 sb.WriteString(fmt.Sprintf(" via tag %s\n", PrettyPrintTag(tagPath[i]))) 1870 sb.WriteString(fmt.Sprintf(" -> %s", m.String())) 1871 } 1872 return sb.String() 1873} 1874 1875func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) { 1876 m.bp.VisitAllModuleVariants(func(module blueprint.Module) { 1877 visit(module.(Module)) 1878 }) 1879} 1880 1881func (m *moduleContext) PrimaryModule() Module { 1882 return m.bp.PrimaryModule().(Module) 1883} 1884 1885func (m *moduleContext) FinalModule() Module { 1886 return m.bp.FinalModule().(Module) 1887} 1888 1889func (m *moduleContext) ModuleSubDir() string { 1890 return m.bp.ModuleSubDir() 1891} 1892 1893func (b *baseModuleContext) Target() Target { 1894 return b.target 1895} 1896 1897func (b *baseModuleContext) TargetPrimary() bool { 1898 return b.targetPrimary 1899} 1900 1901func (b *baseModuleContext) MultiTargets() []Target { 1902 return b.multiTargets 1903} 1904 1905func (b *baseModuleContext) Arch() Arch { 1906 return b.target.Arch 1907} 1908 1909func (b *baseModuleContext) Os() OsType { 1910 return b.os 1911} 1912 1913func (b *baseModuleContext) Host() bool { 1914 return b.os.Class == Host || b.os.Class == HostCross 1915} 1916 1917func (b *baseModuleContext) Device() bool { 1918 return b.os.Class == Device 1919} 1920 1921func (b *baseModuleContext) Darwin() bool { 1922 return b.os == Darwin 1923} 1924 1925func (b *baseModuleContext) Fuchsia() bool { 1926 return b.os == Fuchsia 1927} 1928 1929func (b *baseModuleContext) Windows() bool { 1930 return b.os == Windows 1931} 1932 1933func (b *baseModuleContext) Debug() bool { 1934 return b.debug 1935} 1936 1937func (b *baseModuleContext) PrimaryArch() bool { 1938 if len(b.config.Targets[b.target.Os]) <= 1 { 1939 return true 1940 } 1941 return b.target.Arch.ArchType == b.config.Targets[b.target.Os][0].Arch.ArchType 1942} 1943 1944// Makes this module a platform module, i.e. not specific to soc, device, 1945// product, or system_ext. 1946func (m *ModuleBase) MakeAsPlatform() { 1947 m.commonProperties.Vendor = boolPtr(false) 1948 m.commonProperties.Proprietary = boolPtr(false) 1949 m.commonProperties.Soc_specific = boolPtr(false) 1950 m.commonProperties.Product_specific = boolPtr(false) 1951 m.commonProperties.System_ext_specific = boolPtr(false) 1952} 1953 1954func (m *ModuleBase) EnableNativeBridgeSupportByDefault() { 1955 m.commonProperties.Native_bridge_supported = boolPtr(true) 1956} 1957 1958func (m *ModuleBase) MakeAsSystemExt() { 1959 m.commonProperties.Vendor = boolPtr(false) 1960 m.commonProperties.Proprietary = boolPtr(false) 1961 m.commonProperties.Soc_specific = boolPtr(false) 1962 m.commonProperties.Product_specific = boolPtr(false) 1963 m.commonProperties.System_ext_specific = boolPtr(true) 1964} 1965 1966// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true" 1967func (m *ModuleBase) IsNativeBridgeSupported() bool { 1968 return proptools.Bool(m.commonProperties.Native_bridge_supported) 1969} 1970 1971func (m *moduleContext) InstallInData() bool { 1972 return m.module.InstallInData() 1973} 1974 1975func (m *moduleContext) InstallInTestcases() bool { 1976 return m.module.InstallInTestcases() 1977} 1978 1979func (m *moduleContext) InstallInSanitizerDir() bool { 1980 return m.module.InstallInSanitizerDir() 1981} 1982 1983func (m *moduleContext) InstallInRamdisk() bool { 1984 return m.module.InstallInRamdisk() 1985} 1986 1987func (m *moduleContext) InstallInRecovery() bool { 1988 return m.module.InstallInRecovery() 1989} 1990 1991func (m *moduleContext) InstallInRoot() bool { 1992 return m.module.InstallInRoot() 1993} 1994 1995func (m *moduleContext) InstallBypassMake() bool { 1996 return m.module.InstallBypassMake() 1997} 1998 1999func (m *moduleContext) InstallForceOS() *OsType { 2000 return m.module.InstallForceOS() 2001} 2002 2003func (m *moduleContext) skipInstall(fullInstallPath InstallPath) bool { 2004 if m.module.base().commonProperties.SkipInstall { 2005 return true 2006 } 2007 2008 // We'll need a solution for choosing which of modules with the same name in different 2009 // namespaces to install. For now, reuse the list of namespaces exported to Make as the 2010 // list of namespaces to install in a Soong-only build. 2011 if !m.module.base().commonProperties.NamespaceExportedToMake { 2012 return true 2013 } 2014 2015 if m.Device() { 2016 if m.Config().EmbeddedInMake() && !m.InstallBypassMake() { 2017 return true 2018 } 2019 2020 if m.Config().SkipMegaDeviceInstall(fullInstallPath.String()) { 2021 return true 2022 } 2023 } 2024 2025 return false 2026} 2027 2028func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path, 2029 deps ...Path) InstallPath { 2030 return m.installFile(installPath, name, srcPath, Cp, deps) 2031} 2032 2033func (m *moduleContext) InstallExecutable(installPath InstallPath, name string, srcPath Path, 2034 deps ...Path) InstallPath { 2035 return m.installFile(installPath, name, srcPath, CpExecutable, deps) 2036} 2037 2038func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path, 2039 rule blueprint.Rule, deps []Path) InstallPath { 2040 2041 fullInstallPath := installPath.Join(m, name) 2042 m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, false) 2043 2044 if !m.skipInstall(fullInstallPath) { 2045 2046 deps = append(deps, m.installDeps.Paths()...) 2047 2048 var implicitDeps, orderOnlyDeps Paths 2049 2050 if m.Host() { 2051 // Installed host modules might be used during the build, depend directly on their 2052 // dependencies so their timestamp is updated whenever their dependency is updated 2053 implicitDeps = deps 2054 } else { 2055 orderOnlyDeps = deps 2056 } 2057 2058 m.Build(pctx, BuildParams{ 2059 Rule: rule, 2060 Description: "install " + fullInstallPath.Base(), 2061 Output: fullInstallPath, 2062 Input: srcPath, 2063 Implicits: implicitDeps, 2064 OrderOnly: orderOnlyDeps, 2065 Default: !m.Config().EmbeddedInMake(), 2066 }) 2067 2068 m.installFiles = append(m.installFiles, fullInstallPath) 2069 } 2070 m.checkbuildFiles = append(m.checkbuildFiles, srcPath) 2071 return fullInstallPath 2072} 2073 2074func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath { 2075 fullInstallPath := installPath.Join(m, name) 2076 m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, true) 2077 2078 if !m.skipInstall(fullInstallPath) { 2079 2080 relPath, err := filepath.Rel(path.Dir(fullInstallPath.String()), srcPath.String()) 2081 if err != nil { 2082 panic(fmt.Sprintf("Unable to generate symlink between %q and %q: %s", fullInstallPath.Base(), srcPath.Base(), err)) 2083 } 2084 m.Build(pctx, BuildParams{ 2085 Rule: Symlink, 2086 Description: "install symlink " + fullInstallPath.Base(), 2087 Output: fullInstallPath, 2088 Input: srcPath, 2089 Default: !m.Config().EmbeddedInMake(), 2090 Args: map[string]string{ 2091 "fromPath": relPath, 2092 }, 2093 }) 2094 2095 m.installFiles = append(m.installFiles, fullInstallPath) 2096 m.checkbuildFiles = append(m.checkbuildFiles, srcPath) 2097 } 2098 return fullInstallPath 2099} 2100 2101// installPath/name -> absPath where absPath might be a path that is available only at runtime 2102// (e.g. /apex/...) 2103func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath { 2104 fullInstallPath := installPath.Join(m, name) 2105 m.module.base().hooks.runInstallHooks(m, nil, fullInstallPath, true) 2106 2107 if !m.skipInstall(fullInstallPath) { 2108 m.Build(pctx, BuildParams{ 2109 Rule: Symlink, 2110 Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath, 2111 Output: fullInstallPath, 2112 Default: !m.Config().EmbeddedInMake(), 2113 Args: map[string]string{ 2114 "fromPath": absPath, 2115 }, 2116 }) 2117 2118 m.installFiles = append(m.installFiles, fullInstallPath) 2119 } 2120 return fullInstallPath 2121} 2122 2123func (m *moduleContext) CheckbuildFile(srcPath Path) { 2124 m.checkbuildFiles = append(m.checkbuildFiles, srcPath) 2125} 2126 2127// SrcIsModule decodes module references in the format ":name" into the module name, or empty string if the input 2128// was not a module reference. 2129func SrcIsModule(s string) (module string) { 2130 if len(s) > 1 && s[0] == ':' { 2131 return s[1:] 2132 } 2133 return "" 2134} 2135 2136// SrcIsModule decodes module references in the format ":name{.tag}" into the module name and tag, ":name" into the 2137// module name and an empty string for the tag, or empty strings if the input was not a module reference. 2138func SrcIsModuleWithTag(s string) (module, tag string) { 2139 if len(s) > 1 && s[0] == ':' { 2140 module = s[1:] 2141 if tagStart := strings.IndexByte(module, '{'); tagStart > 0 { 2142 if module[len(module)-1] == '}' { 2143 tag = module[tagStart+1 : len(module)-1] 2144 module = module[:tagStart] 2145 return module, tag 2146 } 2147 } 2148 return module, "" 2149 } 2150 return "", "" 2151} 2152 2153type sourceOrOutputDependencyTag struct { 2154 blueprint.BaseDependencyTag 2155 tag string 2156} 2157 2158func sourceOrOutputDepTag(tag string) blueprint.DependencyTag { 2159 return sourceOrOutputDependencyTag{tag: tag} 2160} 2161 2162var SourceDepTag = sourceOrOutputDepTag("") 2163 2164// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles 2165// using ":module" syntax, if any. 2166// 2167// Deprecated: tag the property with `android:"path"` instead. 2168func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) { 2169 set := make(map[string]bool) 2170 2171 for _, s := range srcFiles { 2172 if m, t := SrcIsModuleWithTag(s); m != "" { 2173 if _, found := set[s]; found { 2174 ctx.ModuleErrorf("found source dependency duplicate: %q!", s) 2175 } else { 2176 set[s] = true 2177 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m) 2178 } 2179 } 2180 } 2181} 2182 2183// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s 2184// using ":module" syntax, if any. 2185// 2186// Deprecated: tag the property with `android:"path"` instead. 2187func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) { 2188 if s != nil { 2189 if m, t := SrcIsModuleWithTag(*s); m != "" { 2190 ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m) 2191 } 2192 } 2193} 2194 2195// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"` 2196// using the ":module" syntax and provides a list of paths to be used as if they were listed in the property. 2197type SourceFileProducer interface { 2198 Srcs() Paths 2199} 2200 2201// A module that implements OutputFileProducer can be referenced from any property that is tagged with `android:"path"` 2202// using the ":module" syntax or ":module{.tag}" syntax and provides a list of output files to be used as if they were 2203// listed in the property. 2204type OutputFileProducer interface { 2205 OutputFiles(tag string) (Paths, error) 2206} 2207 2208// OutputFilesForModule returns the paths from an OutputFileProducer with the given tag. On error, including if the 2209// module produced zero paths, it reports errors to the ctx and returns nil. 2210func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) Paths { 2211 paths, err := outputFilesForModule(ctx, module, tag) 2212 if err != nil { 2213 reportPathError(ctx, err) 2214 return nil 2215 } 2216 return paths 2217} 2218 2219// OutputFileForModule returns the path from an OutputFileProducer with the given tag. On error, including if the 2220// module produced zero or multiple paths, it reports errors to the ctx and returns nil. 2221func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) Path { 2222 paths, err := outputFilesForModule(ctx, module, tag) 2223 if err != nil { 2224 reportPathError(ctx, err) 2225 return nil 2226 } 2227 if len(paths) > 1 { 2228 reportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one", 2229 pathContextName(ctx, module)) 2230 return nil 2231 } 2232 return paths[0] 2233} 2234 2235func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) { 2236 if outputFileProducer, ok := module.(OutputFileProducer); ok { 2237 paths, err := outputFileProducer.OutputFiles(tag) 2238 if err != nil { 2239 return nil, fmt.Errorf("failed to get output file from module %q: %s", 2240 pathContextName(ctx, module), err.Error()) 2241 } 2242 if len(paths) == 0 { 2243 return nil, fmt.Errorf("failed to get output files from module %q", pathContextName(ctx, module)) 2244 } 2245 return paths, nil 2246 } else { 2247 return nil, fmt.Errorf("module %q is not an OutputFileProducer", pathContextName(ctx, module)) 2248 } 2249} 2250 2251type HostToolProvider interface { 2252 HostToolPath() OptionalPath 2253} 2254 2255// Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must 2256// be tagged with `android:"path" to support automatic source module dependency resolution. 2257// 2258// Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead. 2259func (m *moduleContext) ExpandSources(srcFiles, excludes []string) Paths { 2260 return PathsForModuleSrcExcludes(m, srcFiles, excludes) 2261} 2262 2263// Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must 2264// be tagged with `android:"path" to support automatic source module dependency resolution. 2265// 2266// Deprecated: use PathForModuleSrc instead. 2267func (m *moduleContext) ExpandSource(srcFile, prop string) Path { 2268 return PathForModuleSrc(m, srcFile) 2269} 2270 2271// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if 2272// the srcFile is non-nil. The property must be tagged with `android:"path" to support automatic source module 2273// dependency resolution. 2274func (m *moduleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath { 2275 if srcFile != nil { 2276 return OptionalPathForPath(PathForModuleSrc(m, *srcFile)) 2277 } 2278 return OptionalPath{} 2279} 2280 2281func (m *moduleContext) RequiredModuleNames() []string { 2282 return m.module.RequiredModuleNames() 2283} 2284 2285func (m *moduleContext) HostRequiredModuleNames() []string { 2286 return m.module.HostRequiredModuleNames() 2287} 2288 2289func (m *moduleContext) TargetRequiredModuleNames() []string { 2290 return m.module.TargetRequiredModuleNames() 2291} 2292 2293func init() { 2294 RegisterSingletonType("buildtarget", BuildTargetSingleton) 2295} 2296 2297func BuildTargetSingleton() Singleton { 2298 return &buildTargetSingleton{} 2299} 2300 2301func parentDir(dir string) string { 2302 dir, _ = filepath.Split(dir) 2303 return filepath.Clean(dir) 2304} 2305 2306type buildTargetSingleton struct{} 2307 2308func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) { 2309 var checkbuildDeps Paths 2310 2311 mmTarget := func(dir string) string { 2312 return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1) 2313 } 2314 2315 modulesInDir := make(map[string]Paths) 2316 2317 ctx.VisitAllModules(func(module Module) { 2318 blueprintDir := module.base().blueprintDir 2319 installTarget := module.base().installTarget 2320 checkbuildTarget := module.base().checkbuildTarget 2321 2322 if checkbuildTarget != nil { 2323 checkbuildDeps = append(checkbuildDeps, checkbuildTarget) 2324 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget) 2325 } 2326 2327 if installTarget != nil { 2328 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget) 2329 } 2330 }) 2331 2332 suffix := "" 2333 if ctx.Config().EmbeddedInMake() { 2334 suffix = "-soong" 2335 } 2336 2337 // Create a top-level checkbuild target that depends on all modules 2338 ctx.Phony("checkbuild"+suffix, checkbuildDeps...) 2339 2340 // Make will generate the MODULES-IN-* targets 2341 if ctx.Config().EmbeddedInMake() { 2342 return 2343 } 2344 2345 // Ensure ancestor directories are in modulesInDir 2346 dirs := SortedStringKeys(modulesInDir) 2347 for _, dir := range dirs { 2348 dir := parentDir(dir) 2349 for dir != "." && dir != "/" { 2350 if _, exists := modulesInDir[dir]; exists { 2351 break 2352 } 2353 modulesInDir[dir] = nil 2354 dir = parentDir(dir) 2355 } 2356 } 2357 2358 // Make directories build their direct subdirectories 2359 for _, dir := range dirs { 2360 p := parentDir(dir) 2361 if p != "." && p != "/" { 2362 modulesInDir[p] = append(modulesInDir[p], PathForPhony(ctx, mmTarget(dir))) 2363 } 2364 } 2365 2366 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and 2367 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp 2368 // files. 2369 for _, dir := range dirs { 2370 ctx.Phony(mmTarget(dir), modulesInDir[dir]...) 2371 } 2372 2373 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild. 2374 osDeps := map[OsType]Paths{} 2375 ctx.VisitAllModules(func(module Module) { 2376 if module.Enabled() { 2377 os := module.Target().Os 2378 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...) 2379 } 2380 }) 2381 2382 osClass := make(map[string]Paths) 2383 for os, deps := range osDeps { 2384 var className string 2385 2386 switch os.Class { 2387 case Host: 2388 className = "host" 2389 case HostCross: 2390 className = "host-cross" 2391 case Device: 2392 className = "target" 2393 default: 2394 continue 2395 } 2396 2397 name := className + "-" + os.Name 2398 osClass[className] = append(osClass[className], PathForPhony(ctx, name)) 2399 2400 ctx.Phony(name, deps...) 2401 } 2402 2403 // Wrap those into host|host-cross|target phony rules 2404 for _, class := range SortedStringKeys(osClass) { 2405 ctx.Phony(class, osClass[class]...) 2406 } 2407} 2408 2409// Collect information for opening IDE project files in java/jdeps.go. 2410type IDEInfo interface { 2411 IDEInfo(ideInfo *IdeInfo) 2412 BaseModuleName() string 2413} 2414 2415// Extract the base module name from the Import name. 2416// Often the Import name has a prefix "prebuilt_". 2417// Remove the prefix explicitly if needed 2418// until we find a better solution to get the Import name. 2419type IDECustomizedModuleName interface { 2420 IDECustomizedModuleName() string 2421} 2422 2423type IdeInfo struct { 2424 Deps []string `json:"dependencies,omitempty"` 2425 Srcs []string `json:"srcs,omitempty"` 2426 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"` 2427 Jarjar_rules []string `json:"jarjar_rules,omitempty"` 2428 Jars []string `json:"jars,omitempty"` 2429 Classes []string `json:"class,omitempty"` 2430 Installed_paths []string `json:"installed,omitempty"` 2431 SrcJars []string `json:"srcjars,omitempty"` 2432 Paths []string `json:"path,omitempty"` 2433} 2434 2435func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error { 2436 bpctx := ctx.blueprintBaseModuleContext() 2437 return blueprint.CheckBlueprintSyntax(bpctx.ModuleFactories(), filename, contents) 2438} 2439