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 "path" 20 "path/filepath" 21 "sort" 22 "strings" 23 "text/scanner" 24 25 "github.com/google/blueprint" 26 "github.com/google/blueprint/pathtools" 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 Default bool 54 Args map[string]string 55} 56 57type ModuleBuildParams BuildParams 58 59type androidBaseContext interface { 60 Target() Target 61 TargetPrimary() bool 62 MultiTargets() []Target 63 Arch() Arch 64 Os() OsType 65 Host() bool 66 Device() bool 67 Darwin() bool 68 Fuchsia() bool 69 Windows() bool 70 Debug() bool 71 PrimaryArch() bool 72 Platform() bool 73 DeviceSpecific() bool 74 SocSpecific() bool 75 ProductSpecific() bool 76 ProductServicesSpecific() bool 77 AConfig() Config 78 DeviceConfig() DeviceConfig 79} 80 81type BaseContext interface { 82 BaseModuleContext 83 androidBaseContext 84} 85 86// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns 87// a Config instead of an interface{}. 88type BaseModuleContext interface { 89 ModuleName() string 90 ModuleDir() string 91 ModuleType() string 92 Config() Config 93 94 ContainsProperty(name string) bool 95 Errorf(pos scanner.Position, fmt string, args ...interface{}) 96 ModuleErrorf(fmt string, args ...interface{}) 97 PropertyErrorf(property, fmt string, args ...interface{}) 98 Failed() bool 99 100 // GlobWithDeps returns a list of files that match the specified pattern but do not match any 101 // of the patterns in excludes. It also adds efficient dependencies to rerun the primary 102 // builder whenever a file matching the pattern as added or removed, without rerunning if a 103 // file that does not match the pattern is added to a searched directory. 104 GlobWithDeps(pattern string, excludes []string) ([]string, error) 105 106 Fs() pathtools.FileSystem 107 AddNinjaFileDeps(deps ...string) 108} 109 110type ModuleContext interface { 111 androidBaseContext 112 BaseModuleContext 113 114 // Deprecated: use ModuleContext.Build instead. 115 ModuleBuild(pctx PackageContext, params ModuleBuildParams) 116 117 ExpandSources(srcFiles, excludes []string) Paths 118 ExpandSource(srcFile, prop string) Path 119 ExpandOptionalSource(srcFile *string, prop string) OptionalPath 120 Glob(globPattern string, excludes []string) Paths 121 GlobFiles(globPattern string, excludes []string) Paths 122 123 InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath 124 InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath 125 InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath 126 InstallAbsoluteSymlink(installPath OutputPath, name string, absPath string) OutputPath 127 CheckbuildFile(srcPath Path) 128 129 AddMissingDependencies(deps []string) 130 131 InstallInData() bool 132 InstallInSanitizerDir() bool 133 InstallInRecovery() bool 134 135 RequiredModuleNames() []string 136 137 // android.ModuleContext methods 138 // These are duplicated instead of embedded so that can eventually be wrapped to take an 139 // android.Module instead of a blueprint.Module 140 OtherModuleName(m blueprint.Module) string 141 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) 142 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag 143 144 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module 145 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) 146 147 ModuleSubDir() string 148 149 VisitDirectDepsBlueprint(visit func(blueprint.Module)) 150 VisitDirectDeps(visit func(Module)) 151 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) 152 VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) 153 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module 154 VisitDepsDepthFirst(visit func(Module)) 155 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module 156 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) 157 WalkDeps(visit func(Module, Module) bool) 158 WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) 159 160 Variable(pctx PackageContext, name, value string) 161 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule 162 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string, 163 // and performs more verification. 164 Build(pctx PackageContext, params BuildParams) 165 166 PrimaryModule() Module 167 FinalModule() Module 168 VisitAllModuleVariants(visit func(Module)) 169 170 GetMissingDependencies() []string 171 Namespace() blueprint.Namespace 172} 173 174type Module interface { 175 blueprint.Module 176 177 // GenerateAndroidBuildActions is analogous to Blueprints' GenerateBuildActions, 178 // but GenerateAndroidBuildActions also has access to Android-specific information. 179 // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go 180 GenerateAndroidBuildActions(ModuleContext) 181 182 DepsMutator(BottomUpMutatorContext) 183 184 base() *ModuleBase 185 Enabled() bool 186 Target() Target 187 InstallInData() bool 188 InstallInSanitizerDir() bool 189 InstallInRecovery() bool 190 SkipInstall() 191 ExportedToMake() bool 192 NoticeFile() OptionalPath 193 194 AddProperties(props ...interface{}) 195 GetProperties() []interface{} 196 197 BuildParamsForTests() []BuildParams 198 RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams 199 VariablesForTests() map[string]string 200} 201 202type nameProperties struct { 203 // The name of the module. Must be unique across all modules. 204 Name *string 205} 206 207type commonProperties struct { 208 // emit build rules for this module 209 Enabled *bool `android:"arch_variant"` 210 211 // control whether this module compiles for 32-bit, 64-bit, or both. Possible values 212 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both 213 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit 214 // platform 215 Compile_multilib *string `android:"arch_variant"` 216 217 Target struct { 218 Host struct { 219 Compile_multilib *string 220 } 221 Android struct { 222 Compile_multilib *string 223 } 224 } 225 226 UseTargetVariants bool `blueprint:"mutated"` 227 Default_multilib string `blueprint:"mutated"` 228 229 // whether this is a proprietary vendor module, and should be installed into /vendor 230 Proprietary *bool 231 232 // vendor who owns this module 233 Owner *string 234 235 // whether this module is specific to an SoC (System-On-a-Chip). When set to true, 236 // it is installed into /vendor (or /system/vendor if vendor partition does not exist). 237 // Use `soc_specific` instead for better meaning. 238 Vendor *bool 239 240 // whether this module is specific to an SoC (System-On-a-Chip). When set to true, 241 // it is installed into /vendor (or /system/vendor if vendor partition does not exist). 242 Soc_specific *bool 243 244 // whether this module is specific to a device, not only for SoC, but also for off-chip 245 // peripherals. When set to true, it is installed into /odm (or /vendor/odm if odm partition 246 // does not exist, or /system/vendor/odm if both odm and vendor partitions do not exist). 247 // This implies `soc_specific:true`. 248 Device_specific *bool 249 250 // whether this module is specific to a software configuration of a product (e.g. country, 251 // network operator, etc). When set to true, it is installed into /product (or 252 // /system/product if product partition does not exist). 253 Product_specific *bool 254 255 // whether this module provides services owned by the OS provider to the core platform. When set 256 // to true, it is installed into /product_services (or /system/product_services if 257 // product_services partition does not exist). 258 Product_services_specific *bool 259 260 // Whether this module is installed to recovery partition 261 Recovery *bool 262 263 // init.rc files to be installed if this module is installed 264 Init_rc []string `android:"path"` 265 266 // VINTF manifest fragments to be installed if this module is installed 267 Vintf_fragments []string `android:"path"` 268 269 // names of other modules to install if this module is installed 270 Required []string `android:"arch_variant"` 271 272 // relative path to a file to include in the list of notices for the device 273 Notice *string `android:"path"` 274 275 Dist struct { 276 // copy the output of this module to the $DIST_DIR when `dist` is specified on the 277 // command line and any of these targets are also on the command line, or otherwise 278 // built 279 Targets []string `android:"arch_variant"` 280 281 // The name of the output artifact. This defaults to the basename of the output of 282 // the module. 283 Dest *string `android:"arch_variant"` 284 285 // The directory within the dist directory to store the artifact. Defaults to the 286 // top level directory (""). 287 Dir *string `android:"arch_variant"` 288 289 // A suffix to add to the artifact file name (before any extension). 290 Suffix *string `android:"arch_variant"` 291 } `android:"arch_variant"` 292 293 // Set by TargetMutator 294 CompileTarget Target `blueprint:"mutated"` 295 CompileMultiTargets []Target `blueprint:"mutated"` 296 CompilePrimary bool `blueprint:"mutated"` 297 298 // Set by InitAndroidModule 299 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"` 300 ArchSpecific bool `blueprint:"mutated"` 301 302 SkipInstall bool `blueprint:"mutated"` 303 304 NamespaceExportedToMake bool `blueprint:"mutated"` 305} 306 307type hostAndDeviceProperties struct { 308 // If set to true, build a variant of the module for the host. Defaults to false. 309 Host_supported *bool 310 311 // If set to true, build a variant of the module for the device. Defaults to true. 312 Device_supported *bool 313} 314 315type Multilib string 316 317const ( 318 MultilibBoth Multilib = "both" 319 MultilibFirst Multilib = "first" 320 MultilibCommon Multilib = "common" 321 MultilibCommonFirst Multilib = "common_first" 322 MultilibDefault Multilib = "" 323) 324 325type HostOrDeviceSupported int 326 327const ( 328 _ HostOrDeviceSupported = iota 329 330 // Host and HostCross are built by default. Device is not supported. 331 HostSupported 332 333 // Host is built by default. HostCross and Device are not supported. 334 HostSupportedNoCross 335 336 // Device is built by default. Host and HostCross are not supported. 337 DeviceSupported 338 339 // Device is built by default. Host and HostCross are supported. 340 HostAndDeviceSupported 341 342 // Host, HostCross, and Device are built by default. 343 HostAndDeviceDefault 344 345 // Nothing is supported. This is not exposed to the user, but used to mark a 346 // host only module as unsupported when the module type is not supported on 347 // the host OS. E.g. benchmarks are supported on Linux but not Darwin. 348 NeitherHostNorDeviceSupported 349) 350 351type moduleKind int 352 353const ( 354 platformModule moduleKind = iota 355 deviceSpecificModule 356 socSpecificModule 357 productSpecificModule 358 productServicesSpecificModule 359) 360 361func (k moduleKind) String() string { 362 switch k { 363 case platformModule: 364 return "platform" 365 case deviceSpecificModule: 366 return "device-specific" 367 case socSpecificModule: 368 return "soc-specific" 369 case productSpecificModule: 370 return "product-specific" 371 case productServicesSpecificModule: 372 return "productservices-specific" 373 default: 374 panic(fmt.Errorf("unknown module kind %d", k)) 375 } 376} 377 378func InitAndroidModule(m Module) { 379 base := m.base() 380 base.module = m 381 382 m.AddProperties( 383 &base.nameProperties, 384 &base.commonProperties, 385 &base.variableProperties) 386 base.generalProperties = m.GetProperties() 387 base.customizableProperties = m.GetProperties() 388} 389 390func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) { 391 InitAndroidModule(m) 392 393 base := m.base() 394 base.commonProperties.HostOrDeviceSupported = hod 395 base.commonProperties.Default_multilib = string(defaultMultilib) 396 base.commonProperties.ArchSpecific = true 397 base.commonProperties.UseTargetVariants = true 398 399 switch hod { 400 case HostAndDeviceSupported, HostAndDeviceDefault: 401 m.AddProperties(&base.hostAndDeviceProperties) 402 } 403 404 InitArchModule(m) 405} 406 407func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) { 408 InitAndroidArchModule(m, hod, defaultMultilib) 409 m.base().commonProperties.UseTargetVariants = false 410} 411 412// A ModuleBase object contains the properties that are common to all Android 413// modules. It should be included as an anonymous field in every module 414// struct definition. InitAndroidModule should then be called from the module's 415// factory function, and the return values from InitAndroidModule should be 416// returned from the factory function. 417// 418// The ModuleBase type is responsible for implementing the GenerateBuildActions 419// method to support the blueprint.Module interface. This method will then call 420// the module's GenerateAndroidBuildActions method once for each build variant 421// that is to be built. GenerateAndroidBuildActions is passed a 422// AndroidModuleContext rather than the usual blueprint.ModuleContext. 423// AndroidModuleContext exposes extra functionality specific to the Android build 424// system including details about the particular build variant that is to be 425// generated. 426// 427// For example: 428// 429// import ( 430// "android/soong/android" 431// ) 432// 433// type myModule struct { 434// android.ModuleBase 435// properties struct { 436// MyProperty string 437// } 438// } 439// 440// func NewMyModule() android.Module) { 441// m := &myModule{} 442// m.AddProperties(&m.properties) 443// android.InitAndroidModule(m) 444// return m 445// } 446// 447// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { 448// // Get the CPU architecture for the current build variant. 449// variantArch := ctx.Arch() 450// 451// // ... 452// } 453type ModuleBase struct { 454 // Putting the curiously recurring thing pointing to the thing that contains 455 // the thing pattern to good use. 456 // TODO: remove this 457 module Module 458 459 nameProperties nameProperties 460 commonProperties commonProperties 461 variableProperties variableProperties 462 hostAndDeviceProperties hostAndDeviceProperties 463 generalProperties []interface{} 464 archProperties [][]interface{} 465 customizableProperties []interface{} 466 467 noAddressSanitizer bool 468 installFiles Paths 469 checkbuildFiles Paths 470 noticeFile OptionalPath 471 472 // Used by buildTargetSingleton to create checkbuild and per-directory build targets 473 // Only set on the final variant of each module 474 installTarget WritablePath 475 checkbuildTarget WritablePath 476 blueprintDir string 477 478 hooks hooks 479 480 registerProps []interface{} 481 482 // For tests 483 buildParams []BuildParams 484 ruleParams map[blueprint.Rule]blueprint.RuleParams 485 variables map[string]string 486 487 prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool 488} 489 490func (a *ModuleBase) DepsMutator(BottomUpMutatorContext) {} 491 492func (a *ModuleBase) AddProperties(props ...interface{}) { 493 a.registerProps = append(a.registerProps, props...) 494} 495 496func (a *ModuleBase) GetProperties() []interface{} { 497 return a.registerProps 498} 499 500func (a *ModuleBase) BuildParamsForTests() []BuildParams { 501 return a.buildParams 502} 503 504func (a *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams { 505 return a.ruleParams 506} 507 508func (a *ModuleBase) VariablesForTests() map[string]string { 509 return a.variables 510} 511 512func (a *ModuleBase) Prefer32(prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool) { 513 a.prefer32 = prefer32 514} 515 516// Name returns the name of the module. It may be overridden by individual module types, for 517// example prebuilts will prepend prebuilt_ to the name. 518func (a *ModuleBase) Name() string { 519 return String(a.nameProperties.Name) 520} 521 522// BaseModuleName returns the name of the module as specified in the blueprints file. 523func (a *ModuleBase) BaseModuleName() string { 524 return String(a.nameProperties.Name) 525} 526 527func (a *ModuleBase) base() *ModuleBase { 528 return a 529} 530 531func (a *ModuleBase) SetTarget(target Target, multiTargets []Target, primary bool) { 532 a.commonProperties.CompileTarget = target 533 a.commonProperties.CompileMultiTargets = multiTargets 534 a.commonProperties.CompilePrimary = primary 535} 536 537func (a *ModuleBase) Target() Target { 538 return a.commonProperties.CompileTarget 539} 540 541func (a *ModuleBase) TargetPrimary() bool { 542 return a.commonProperties.CompilePrimary 543} 544 545func (a *ModuleBase) MultiTargets() []Target { 546 return a.commonProperties.CompileMultiTargets 547} 548 549func (a *ModuleBase) Os() OsType { 550 return a.Target().Os 551} 552 553func (a *ModuleBase) Host() bool { 554 return a.Os().Class == Host || a.Os().Class == HostCross 555} 556 557func (a *ModuleBase) Arch() Arch { 558 return a.Target().Arch 559} 560 561func (a *ModuleBase) ArchSpecific() bool { 562 return a.commonProperties.ArchSpecific 563} 564 565func (a *ModuleBase) OsClassSupported() []OsClass { 566 switch a.commonProperties.HostOrDeviceSupported { 567 case HostSupported: 568 return []OsClass{Host, HostCross} 569 case HostSupportedNoCross: 570 return []OsClass{Host} 571 case DeviceSupported: 572 return []OsClass{Device} 573 case HostAndDeviceSupported, HostAndDeviceDefault: 574 var supported []OsClass 575 if Bool(a.hostAndDeviceProperties.Host_supported) || 576 (a.commonProperties.HostOrDeviceSupported == HostAndDeviceDefault && 577 a.hostAndDeviceProperties.Host_supported == nil) { 578 supported = append(supported, Host, HostCross) 579 } 580 if a.hostAndDeviceProperties.Device_supported == nil || 581 *a.hostAndDeviceProperties.Device_supported { 582 supported = append(supported, Device) 583 } 584 return supported 585 default: 586 return nil 587 } 588} 589 590func (a *ModuleBase) DeviceSupported() bool { 591 return a.commonProperties.HostOrDeviceSupported == DeviceSupported || 592 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported && 593 (a.hostAndDeviceProperties.Device_supported == nil || 594 *a.hostAndDeviceProperties.Device_supported) 595} 596 597func (a *ModuleBase) Platform() bool { 598 return !a.DeviceSpecific() && !a.SocSpecific() && !a.ProductSpecific() && !a.ProductServicesSpecific() 599} 600 601func (a *ModuleBase) DeviceSpecific() bool { 602 return Bool(a.commonProperties.Device_specific) 603} 604 605func (a *ModuleBase) SocSpecific() bool { 606 return Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific) 607} 608 609func (a *ModuleBase) ProductSpecific() bool { 610 return Bool(a.commonProperties.Product_specific) 611} 612 613func (a *ModuleBase) ProductServicesSpecific() bool { 614 return Bool(a.commonProperties.Product_services_specific) 615} 616 617func (a *ModuleBase) Enabled() bool { 618 if a.commonProperties.Enabled == nil { 619 return !a.Os().DefaultDisabled 620 } 621 return *a.commonProperties.Enabled 622} 623 624func (a *ModuleBase) SkipInstall() { 625 a.commonProperties.SkipInstall = true 626} 627 628func (a *ModuleBase) ExportedToMake() bool { 629 return a.commonProperties.NamespaceExportedToMake 630} 631 632func (a *ModuleBase) computeInstallDeps( 633 ctx blueprint.ModuleContext) Paths { 634 635 result := Paths{} 636 // TODO(ccross): we need to use WalkDeps and have some way to know which dependencies require installation 637 ctx.VisitDepsDepthFirstIf(isFileInstaller, 638 func(m blueprint.Module) { 639 fileInstaller := m.(fileInstaller) 640 files := fileInstaller.filesToInstall() 641 result = append(result, files...) 642 }) 643 644 return result 645} 646 647func (a *ModuleBase) filesToInstall() Paths { 648 return a.installFiles 649} 650 651func (p *ModuleBase) NoAddressSanitizer() bool { 652 return p.noAddressSanitizer 653} 654 655func (p *ModuleBase) InstallInData() bool { 656 return false 657} 658 659func (p *ModuleBase) InstallInSanitizerDir() bool { 660 return false 661} 662 663func (p *ModuleBase) InstallInRecovery() bool { 664 return Bool(p.commonProperties.Recovery) 665} 666 667func (a *ModuleBase) Owner() string { 668 return String(a.commonProperties.Owner) 669} 670 671func (a *ModuleBase) NoticeFile() OptionalPath { 672 return a.noticeFile 673} 674 675func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) { 676 allInstalledFiles := Paths{} 677 allCheckbuildFiles := Paths{} 678 ctx.VisitAllModuleVariants(func(module Module) { 679 a := module.base() 680 allInstalledFiles = append(allInstalledFiles, a.installFiles...) 681 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...) 682 }) 683 684 var deps Paths 685 686 namespacePrefix := ctx.Namespace().(*Namespace).id 687 if namespacePrefix != "" { 688 namespacePrefix = namespacePrefix + "-" 689 } 690 691 if len(allInstalledFiles) > 0 { 692 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install") 693 ctx.Build(pctx, BuildParams{ 694 Rule: blueprint.Phony, 695 Output: name, 696 Implicits: allInstalledFiles, 697 Default: !ctx.Config().EmbeddedInMake(), 698 }) 699 deps = append(deps, name) 700 a.installTarget = name 701 } 702 703 if len(allCheckbuildFiles) > 0 { 704 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild") 705 ctx.Build(pctx, BuildParams{ 706 Rule: blueprint.Phony, 707 Output: name, 708 Implicits: allCheckbuildFiles, 709 }) 710 deps = append(deps, name) 711 a.checkbuildTarget = name 712 } 713 714 if len(deps) > 0 { 715 suffix := "" 716 if ctx.Config().EmbeddedInMake() { 717 suffix = "-soong" 718 } 719 720 name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix) 721 ctx.Build(pctx, BuildParams{ 722 Rule: blueprint.Phony, 723 Outputs: []WritablePath{name}, 724 Implicits: deps, 725 }) 726 727 a.blueprintDir = ctx.ModuleDir() 728 } 729} 730 731func determineModuleKind(a *ModuleBase, ctx blueprint.BaseModuleContext) moduleKind { 732 var socSpecific = Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific) 733 var deviceSpecific = Bool(a.commonProperties.Device_specific) 734 var productSpecific = Bool(a.commonProperties.Product_specific) 735 var productServicesSpecific = Bool(a.commonProperties.Product_services_specific) 736 737 msg := "conflicting value set here" 738 if socSpecific && deviceSpecific { 739 ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.") 740 if Bool(a.commonProperties.Vendor) { 741 ctx.PropertyErrorf("vendor", msg) 742 } 743 if Bool(a.commonProperties.Proprietary) { 744 ctx.PropertyErrorf("proprietary", msg) 745 } 746 if Bool(a.commonProperties.Soc_specific) { 747 ctx.PropertyErrorf("soc_specific", msg) 748 } 749 } 750 751 if productSpecific && productServicesSpecific { 752 ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and product_services at the same time.") 753 ctx.PropertyErrorf("product_services_specific", msg) 754 } 755 756 if (socSpecific || deviceSpecific) && (productSpecific || productServicesSpecific) { 757 if productSpecific { 758 ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.") 759 } else { 760 ctx.PropertyErrorf("product_services_specific", "a module cannot be specific to SoC or device and product_services at the same time.") 761 } 762 if deviceSpecific { 763 ctx.PropertyErrorf("device_specific", msg) 764 } else { 765 if Bool(a.commonProperties.Vendor) { 766 ctx.PropertyErrorf("vendor", msg) 767 } 768 if Bool(a.commonProperties.Proprietary) { 769 ctx.PropertyErrorf("proprietary", msg) 770 } 771 if Bool(a.commonProperties.Soc_specific) { 772 ctx.PropertyErrorf("soc_specific", msg) 773 } 774 } 775 } 776 777 if productSpecific { 778 return productSpecificModule 779 } else if productServicesSpecific { 780 return productServicesSpecificModule 781 } else if deviceSpecific { 782 return deviceSpecificModule 783 } else if socSpecific { 784 return socSpecificModule 785 } else { 786 return platformModule 787 } 788} 789 790func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl { 791 return androidBaseContextImpl{ 792 target: a.commonProperties.CompileTarget, 793 targetPrimary: a.commonProperties.CompilePrimary, 794 multiTargets: a.commonProperties.CompileMultiTargets, 795 kind: determineModuleKind(a, ctx), 796 config: ctx.Config().(Config), 797 } 798} 799 800func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) { 801 ctx := &androidModuleContext{ 802 module: a.module, 803 ModuleContext: blueprintCtx, 804 androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx), 805 installDeps: a.computeInstallDeps(blueprintCtx), 806 installFiles: a.installFiles, 807 missingDeps: blueprintCtx.GetMissingDependencies(), 808 variables: make(map[string]string), 809 } 810 811 if ctx.config.captureBuild { 812 ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams) 813 } 814 815 desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " " 816 var suffix []string 817 if ctx.Os().Class != Device && ctx.Os().Class != Generic { 818 suffix = append(suffix, ctx.Os().String()) 819 } 820 if !ctx.PrimaryArch() { 821 suffix = append(suffix, ctx.Arch().ArchType.String()) 822 } 823 824 ctx.Variable(pctx, "moduleDesc", desc) 825 826 s := "" 827 if len(suffix) > 0 { 828 s = " [" + strings.Join(suffix, " ") + "]" 829 } 830 ctx.Variable(pctx, "moduleDescSuffix", s) 831 832 // Some common property checks for properties that will be used later in androidmk.go 833 if a.commonProperties.Dist.Dest != nil { 834 _, err := validateSafePath(*a.commonProperties.Dist.Dest) 835 if err != nil { 836 ctx.PropertyErrorf("dist.dest", "%s", err.Error()) 837 } 838 } 839 if a.commonProperties.Dist.Dir != nil { 840 _, err := validateSafePath(*a.commonProperties.Dist.Dir) 841 if err != nil { 842 ctx.PropertyErrorf("dist.dir", "%s", err.Error()) 843 } 844 } 845 if a.commonProperties.Dist.Suffix != nil { 846 if strings.Contains(*a.commonProperties.Dist.Suffix, "/") { 847 ctx.PropertyErrorf("dist.suffix", "Suffix may not contain a '/' character.") 848 } 849 } 850 851 if a.Enabled() { 852 notice := proptools.StringDefault(a.commonProperties.Notice, "NOTICE") 853 if m := SrcIsModule(notice); m != "" { 854 a.noticeFile = ctx.ExpandOptionalSource(¬ice, "notice") 855 } else { 856 noticePath := filepath.Join(ctx.ModuleDir(), notice) 857 a.noticeFile = ExistentPathForSource(ctx, noticePath) 858 } 859 860 a.module.GenerateAndroidBuildActions(ctx) 861 if ctx.Failed() { 862 return 863 } 864 865 a.installFiles = append(a.installFiles, ctx.installFiles...) 866 a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...) 867 } 868 869 if a == ctx.FinalModule().(Module).base() { 870 a.generateModuleTarget(ctx) 871 if ctx.Failed() { 872 return 873 } 874 } 875 876 a.buildParams = ctx.buildParams 877 a.ruleParams = ctx.ruleParams 878 a.variables = ctx.variables 879} 880 881type androidBaseContextImpl struct { 882 target Target 883 multiTargets []Target 884 targetPrimary bool 885 debug bool 886 kind moduleKind 887 config Config 888} 889 890type androidModuleContext struct { 891 blueprint.ModuleContext 892 androidBaseContextImpl 893 installDeps Paths 894 installFiles Paths 895 checkbuildFiles Paths 896 missingDeps []string 897 module Module 898 899 // For tests 900 buildParams []BuildParams 901 ruleParams map[blueprint.Rule]blueprint.RuleParams 902 variables map[string]string 903} 904 905func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) { 906 a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{ 907 Rule: ErrorRule, 908 Description: desc, 909 Outputs: outputs, 910 Optional: true, 911 Args: map[string]string{ 912 "error": err.Error(), 913 }, 914 }) 915 return 916} 917 918func (a *androidModuleContext) Config() Config { 919 return a.ModuleContext.Config().(Config) 920} 921 922func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) { 923 a.Build(pctx, BuildParams(params)) 924} 925 926func convertBuildParams(params BuildParams) blueprint.BuildParams { 927 bparams := blueprint.BuildParams{ 928 Rule: params.Rule, 929 Description: params.Description, 930 Deps: params.Deps, 931 Outputs: params.Outputs.Strings(), 932 ImplicitOutputs: params.ImplicitOutputs.Strings(), 933 Inputs: params.Inputs.Strings(), 934 Implicits: params.Implicits.Strings(), 935 OrderOnly: params.OrderOnly.Strings(), 936 Args: params.Args, 937 Optional: !params.Default, 938 } 939 940 if params.Depfile != nil { 941 bparams.Depfile = params.Depfile.String() 942 } 943 if params.Output != nil { 944 bparams.Outputs = append(bparams.Outputs, params.Output.String()) 945 } 946 if params.ImplicitOutput != nil { 947 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String()) 948 } 949 if params.Input != nil { 950 bparams.Inputs = append(bparams.Inputs, params.Input.String()) 951 } 952 if params.Implicit != nil { 953 bparams.Implicits = append(bparams.Implicits, params.Implicit.String()) 954 } 955 956 bparams.Outputs = proptools.NinjaEscapeList(bparams.Outputs) 957 bparams.ImplicitOutputs = proptools.NinjaEscapeList(bparams.ImplicitOutputs) 958 bparams.Inputs = proptools.NinjaEscapeList(bparams.Inputs) 959 bparams.Implicits = proptools.NinjaEscapeList(bparams.Implicits) 960 bparams.OrderOnly = proptools.NinjaEscapeList(bparams.OrderOnly) 961 bparams.Depfile = proptools.NinjaEscapeList([]string{bparams.Depfile})[0] 962 963 return bparams 964} 965 966func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) { 967 if a.config.captureBuild { 968 a.variables[name] = value 969 } 970 971 a.ModuleContext.Variable(pctx.PackageContext, name, value) 972} 973 974func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams, 975 argNames ...string) blueprint.Rule { 976 977 rule := a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...) 978 979 if a.config.captureBuild { 980 a.ruleParams[rule] = params 981 } 982 983 return rule 984} 985 986func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) { 987 if a.config.captureBuild { 988 a.buildParams = append(a.buildParams, params) 989 } 990 991 bparams := convertBuildParams(params) 992 993 if bparams.Description != "" { 994 bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}" 995 } 996 997 if a.missingDeps != nil { 998 a.ninjaError(bparams.Description, bparams.Outputs, 999 fmt.Errorf("module %s missing dependencies: %s\n", 1000 a.ModuleName(), strings.Join(a.missingDeps, ", "))) 1001 return 1002 } 1003 1004 a.ModuleContext.Build(pctx.PackageContext, bparams) 1005} 1006 1007func (a *androidModuleContext) GetMissingDependencies() []string { 1008 return a.missingDeps 1009} 1010 1011func (a *androidModuleContext) AddMissingDependencies(deps []string) { 1012 if deps != nil { 1013 a.missingDeps = append(a.missingDeps, deps...) 1014 a.missingDeps = FirstUniqueStrings(a.missingDeps) 1015 } 1016} 1017 1018func (a *androidModuleContext) validateAndroidModule(module blueprint.Module) Module { 1019 aModule, _ := module.(Module) 1020 if aModule == nil { 1021 a.ModuleErrorf("module %q not an android module", a.OtherModuleName(aModule)) 1022 return nil 1023 } 1024 1025 if !aModule.Enabled() { 1026 if a.Config().AllowMissingDependencies() { 1027 a.AddMissingDependencies([]string{a.OtherModuleName(aModule)}) 1028 } else { 1029 a.ModuleErrorf("depends on disabled module %q", a.OtherModuleName(aModule)) 1030 } 1031 return nil 1032 } 1033 1034 return aModule 1035} 1036 1037func (a *androidModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) { 1038 type dep struct { 1039 mod blueprint.Module 1040 tag blueprint.DependencyTag 1041 } 1042 var deps []dep 1043 a.VisitDirectDepsBlueprint(func(m blueprint.Module) { 1044 if aModule, _ := m.(Module); aModule != nil && aModule.base().BaseModuleName() == name { 1045 returnedTag := a.ModuleContext.OtherModuleDependencyTag(aModule) 1046 if tag == nil || returnedTag == tag { 1047 deps = append(deps, dep{aModule, returnedTag}) 1048 } 1049 } 1050 }) 1051 if len(deps) == 1 { 1052 return deps[0].mod, deps[0].tag 1053 } else if len(deps) >= 2 { 1054 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q", 1055 name, a.ModuleName())) 1056 } else { 1057 return nil, nil 1058 } 1059} 1060 1061func (a *androidModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module { 1062 m, _ := a.getDirectDepInternal(name, tag) 1063 return m 1064} 1065 1066func (a *androidModuleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) { 1067 return a.getDirectDepInternal(name, nil) 1068} 1069 1070func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) { 1071 a.ModuleContext.VisitDirectDeps(visit) 1072} 1073 1074func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) { 1075 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) { 1076 if aModule := a.validateAndroidModule(module); aModule != nil { 1077 visit(aModule) 1078 } 1079 }) 1080} 1081 1082func (a *androidModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) { 1083 a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) { 1084 if aModule := a.validateAndroidModule(module); aModule != nil { 1085 if a.ModuleContext.OtherModuleDependencyTag(aModule) == tag { 1086 visit(aModule) 1087 } 1088 } 1089 }) 1090} 1091 1092func (a *androidModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) { 1093 a.ModuleContext.VisitDirectDepsIf( 1094 // pred 1095 func(module blueprint.Module) bool { 1096 if aModule := a.validateAndroidModule(module); aModule != nil { 1097 return pred(aModule) 1098 } else { 1099 return false 1100 } 1101 }, 1102 // visit 1103 func(module blueprint.Module) { 1104 visit(module.(Module)) 1105 }) 1106} 1107 1108func (a *androidModuleContext) VisitDepsDepthFirst(visit func(Module)) { 1109 a.ModuleContext.VisitDepsDepthFirst(func(module blueprint.Module) { 1110 if aModule := a.validateAndroidModule(module); aModule != nil { 1111 visit(aModule) 1112 } 1113 }) 1114} 1115 1116func (a *androidModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) { 1117 a.ModuleContext.VisitDepsDepthFirstIf( 1118 // pred 1119 func(module blueprint.Module) bool { 1120 if aModule := a.validateAndroidModule(module); aModule != nil { 1121 return pred(aModule) 1122 } else { 1123 return false 1124 } 1125 }, 1126 // visit 1127 func(module blueprint.Module) { 1128 visit(module.(Module)) 1129 }) 1130} 1131 1132func (a *androidModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) { 1133 a.ModuleContext.WalkDeps(visit) 1134} 1135 1136func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) { 1137 a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool { 1138 childAndroidModule := a.validateAndroidModule(child) 1139 parentAndroidModule := a.validateAndroidModule(parent) 1140 if childAndroidModule != nil && parentAndroidModule != nil { 1141 return visit(childAndroidModule, parentAndroidModule) 1142 } else { 1143 return false 1144 } 1145 }) 1146} 1147 1148func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) { 1149 a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) { 1150 visit(module.(Module)) 1151 }) 1152} 1153 1154func (a *androidModuleContext) PrimaryModule() Module { 1155 return a.ModuleContext.PrimaryModule().(Module) 1156} 1157 1158func (a *androidModuleContext) FinalModule() Module { 1159 return a.ModuleContext.FinalModule().(Module) 1160} 1161 1162func (a *androidBaseContextImpl) Target() Target { 1163 return a.target 1164} 1165 1166func (a *androidBaseContextImpl) TargetPrimary() bool { 1167 return a.targetPrimary 1168} 1169 1170func (a *androidBaseContextImpl) MultiTargets() []Target { 1171 return a.multiTargets 1172} 1173 1174func (a *androidBaseContextImpl) Arch() Arch { 1175 return a.target.Arch 1176} 1177 1178func (a *androidBaseContextImpl) Os() OsType { 1179 return a.target.Os 1180} 1181 1182func (a *androidBaseContextImpl) Host() bool { 1183 return a.target.Os.Class == Host || a.target.Os.Class == HostCross 1184} 1185 1186func (a *androidBaseContextImpl) Device() bool { 1187 return a.target.Os.Class == Device 1188} 1189 1190func (a *androidBaseContextImpl) Darwin() bool { 1191 return a.target.Os == Darwin 1192} 1193 1194func (a *androidBaseContextImpl) Fuchsia() bool { 1195 return a.target.Os == Fuchsia 1196} 1197 1198func (a *androidBaseContextImpl) Windows() bool { 1199 return a.target.Os == Windows 1200} 1201 1202func (a *androidBaseContextImpl) Debug() bool { 1203 return a.debug 1204} 1205 1206func (a *androidBaseContextImpl) PrimaryArch() bool { 1207 if len(a.config.Targets[a.target.Os]) <= 1 { 1208 return true 1209 } 1210 return a.target.Arch.ArchType == a.config.Targets[a.target.Os][0].Arch.ArchType 1211} 1212 1213func (a *androidBaseContextImpl) AConfig() Config { 1214 return a.config 1215} 1216 1217func (a *androidBaseContextImpl) DeviceConfig() DeviceConfig { 1218 return DeviceConfig{a.config.deviceConfig} 1219} 1220 1221func (a *androidBaseContextImpl) Platform() bool { 1222 return a.kind == platformModule 1223} 1224 1225func (a *androidBaseContextImpl) DeviceSpecific() bool { 1226 return a.kind == deviceSpecificModule 1227} 1228 1229func (a *androidBaseContextImpl) SocSpecific() bool { 1230 return a.kind == socSpecificModule 1231} 1232 1233func (a *androidBaseContextImpl) ProductSpecific() bool { 1234 return a.kind == productSpecificModule 1235} 1236 1237func (a *androidBaseContextImpl) ProductServicesSpecific() bool { 1238 return a.kind == productServicesSpecificModule 1239} 1240 1241// Makes this module a platform module, i.e. not specific to soc, device, 1242// product, or product_services. 1243func (a *ModuleBase) MakeAsPlatform() { 1244 a.commonProperties.Vendor = boolPtr(false) 1245 a.commonProperties.Proprietary = boolPtr(false) 1246 a.commonProperties.Soc_specific = boolPtr(false) 1247 a.commonProperties.Product_specific = boolPtr(false) 1248 a.commonProperties.Product_services_specific = boolPtr(false) 1249} 1250 1251func (a *androidModuleContext) InstallInData() bool { 1252 return a.module.InstallInData() 1253} 1254 1255func (a *androidModuleContext) InstallInSanitizerDir() bool { 1256 return a.module.InstallInSanitizerDir() 1257} 1258 1259func (a *androidModuleContext) InstallInRecovery() bool { 1260 return a.module.InstallInRecovery() 1261} 1262 1263func (a *androidModuleContext) skipInstall(fullInstallPath OutputPath) bool { 1264 if a.module.base().commonProperties.SkipInstall { 1265 return true 1266 } 1267 1268 // We'll need a solution for choosing which of modules with the same name in different 1269 // namespaces to install. For now, reuse the list of namespaces exported to Make as the 1270 // list of namespaces to install in a Soong-only build. 1271 if !a.module.base().commonProperties.NamespaceExportedToMake { 1272 return true 1273 } 1274 1275 if a.Device() { 1276 if a.Config().SkipDeviceInstall() { 1277 return true 1278 } 1279 1280 if a.Config().SkipMegaDeviceInstall(fullInstallPath.String()) { 1281 return true 1282 } 1283 } 1284 1285 return false 1286} 1287 1288func (a *androidModuleContext) InstallFile(installPath OutputPath, name string, srcPath Path, 1289 deps ...Path) OutputPath { 1290 return a.installFile(installPath, name, srcPath, Cp, deps) 1291} 1292 1293func (a *androidModuleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path, 1294 deps ...Path) OutputPath { 1295 return a.installFile(installPath, name, srcPath, CpExecutable, deps) 1296} 1297 1298func (a *androidModuleContext) installFile(installPath OutputPath, name string, srcPath Path, 1299 rule blueprint.Rule, deps []Path) OutputPath { 1300 1301 fullInstallPath := installPath.Join(a, name) 1302 a.module.base().hooks.runInstallHooks(a, fullInstallPath, false) 1303 1304 if !a.skipInstall(fullInstallPath) { 1305 1306 deps = append(deps, a.installDeps...) 1307 1308 var implicitDeps, orderOnlyDeps Paths 1309 1310 if a.Host() { 1311 // Installed host modules might be used during the build, depend directly on their 1312 // dependencies so their timestamp is updated whenever their dependency is updated 1313 implicitDeps = deps 1314 } else { 1315 orderOnlyDeps = deps 1316 } 1317 1318 a.Build(pctx, BuildParams{ 1319 Rule: rule, 1320 Description: "install " + fullInstallPath.Base(), 1321 Output: fullInstallPath, 1322 Input: srcPath, 1323 Implicits: implicitDeps, 1324 OrderOnly: orderOnlyDeps, 1325 Default: !a.Config().EmbeddedInMake(), 1326 }) 1327 1328 a.installFiles = append(a.installFiles, fullInstallPath) 1329 } 1330 a.checkbuildFiles = append(a.checkbuildFiles, srcPath) 1331 return fullInstallPath 1332} 1333 1334func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath { 1335 fullInstallPath := installPath.Join(a, name) 1336 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true) 1337 1338 if !a.skipInstall(fullInstallPath) { 1339 1340 relPath, err := filepath.Rel(path.Dir(fullInstallPath.String()), srcPath.String()) 1341 if err != nil { 1342 panic(fmt.Sprintf("Unable to generate symlink between %q and %q: %s", fullInstallPath.Base(), srcPath.Base(), err)) 1343 } 1344 a.Build(pctx, BuildParams{ 1345 Rule: Symlink, 1346 Description: "install symlink " + fullInstallPath.Base(), 1347 Output: fullInstallPath, 1348 OrderOnly: Paths{srcPath}, 1349 Default: !a.Config().EmbeddedInMake(), 1350 Args: map[string]string{ 1351 "fromPath": relPath, 1352 }, 1353 }) 1354 1355 a.installFiles = append(a.installFiles, fullInstallPath) 1356 a.checkbuildFiles = append(a.checkbuildFiles, srcPath) 1357 } 1358 return fullInstallPath 1359} 1360 1361// installPath/name -> absPath where absPath might be a path that is available only at runtime 1362// (e.g. /apex/...) 1363func (a *androidModuleContext) InstallAbsoluteSymlink(installPath OutputPath, name string, absPath string) OutputPath { 1364 fullInstallPath := installPath.Join(a, name) 1365 a.module.base().hooks.runInstallHooks(a, fullInstallPath, true) 1366 1367 if !a.skipInstall(fullInstallPath) { 1368 a.Build(pctx, BuildParams{ 1369 Rule: Symlink, 1370 Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath, 1371 Output: fullInstallPath, 1372 Default: !a.Config().EmbeddedInMake(), 1373 Args: map[string]string{ 1374 "fromPath": absPath, 1375 }, 1376 }) 1377 1378 a.installFiles = append(a.installFiles, fullInstallPath) 1379 } 1380 return fullInstallPath 1381} 1382 1383func (a *androidModuleContext) CheckbuildFile(srcPath Path) { 1384 a.checkbuildFiles = append(a.checkbuildFiles, srcPath) 1385} 1386 1387type fileInstaller interface { 1388 filesToInstall() Paths 1389} 1390 1391func isFileInstaller(m blueprint.Module) bool { 1392 _, ok := m.(fileInstaller) 1393 return ok 1394} 1395 1396func isAndroidModule(m blueprint.Module) bool { 1397 _, ok := m.(Module) 1398 return ok 1399} 1400 1401func findStringInSlice(str string, slice []string) int { 1402 for i, s := range slice { 1403 if s == str { 1404 return i 1405 } 1406 } 1407 return -1 1408} 1409 1410func SrcIsModule(s string) string { 1411 if len(s) > 1 && s[0] == ':' { 1412 return s[1:] 1413 } 1414 return "" 1415} 1416 1417type sourceDependencyTag struct { 1418 blueprint.BaseDependencyTag 1419} 1420 1421var SourceDepTag sourceDependencyTag 1422 1423// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles 1424// using ":module" syntax, if any. 1425// 1426// Deprecated: tag the property with `android:"path"` instead. 1427func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) { 1428 var deps []string 1429 set := make(map[string]bool) 1430 1431 for _, s := range srcFiles { 1432 if m := SrcIsModule(s); m != "" { 1433 if _, found := set[m]; found { 1434 ctx.ModuleErrorf("found source dependency duplicate: %q!", m) 1435 } else { 1436 set[m] = true 1437 deps = append(deps, m) 1438 } 1439 } 1440 } 1441 1442 ctx.AddDependency(ctx.Module(), SourceDepTag, deps...) 1443} 1444 1445// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s 1446// using ":module" syntax, if any. 1447// 1448// Deprecated: tag the property with `android:"path"` instead. 1449func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) { 1450 if s != nil { 1451 if m := SrcIsModule(*s); m != "" { 1452 ctx.AddDependency(ctx.Module(), SourceDepTag, m) 1453 } 1454 } 1455} 1456 1457type SourceFileProducer interface { 1458 Srcs() Paths 1459} 1460 1461type HostToolProvider interface { 1462 HostToolPath() OptionalPath 1463} 1464 1465// Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must 1466// be tagged with `android:"path" to support automatic source module dependency resolution. 1467// 1468// Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead. 1469func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths { 1470 return PathsForModuleSrcExcludes(ctx, srcFiles, excludes) 1471} 1472 1473// Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must 1474// be tagged with `android:"path" to support automatic source module dependency resolution. 1475// 1476// Deprecated: use PathForModuleSrc instead. 1477func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path { 1478 return PathForModuleSrc(ctx, srcFile) 1479} 1480 1481// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if 1482// the srcFile is non-nil. The property must be tagged with `android:"path" to support automatic source module 1483// dependency resolution. 1484func (ctx *androidModuleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath { 1485 if srcFile != nil { 1486 return OptionalPathForPath(PathForModuleSrc(ctx, *srcFile)) 1487 } 1488 return OptionalPath{} 1489} 1490 1491func (ctx *androidModuleContext) RequiredModuleNames() []string { 1492 return ctx.module.base().commonProperties.Required 1493} 1494 1495func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths { 1496 ret, err := ctx.GlobWithDeps(globPattern, excludes) 1497 if err != nil { 1498 ctx.ModuleErrorf("glob: %s", err.Error()) 1499 } 1500 return pathsForModuleSrcFromFullPath(ctx, ret, true) 1501} 1502 1503func (ctx *androidModuleContext) GlobFiles(globPattern string, excludes []string) Paths { 1504 ret, err := ctx.GlobWithDeps(globPattern, excludes) 1505 if err != nil { 1506 ctx.ModuleErrorf("glob: %s", err.Error()) 1507 } 1508 return pathsForModuleSrcFromFullPath(ctx, ret, false) 1509} 1510 1511func init() { 1512 RegisterSingletonType("buildtarget", BuildTargetSingleton) 1513} 1514 1515func BuildTargetSingleton() Singleton { 1516 return &buildTargetSingleton{} 1517} 1518 1519func parentDir(dir string) string { 1520 dir, _ = filepath.Split(dir) 1521 return filepath.Clean(dir) 1522} 1523 1524type buildTargetSingleton struct{} 1525 1526func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) { 1527 var checkbuildDeps Paths 1528 1529 mmTarget := func(dir string) WritablePath { 1530 return PathForPhony(ctx, 1531 "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1)) 1532 } 1533 1534 modulesInDir := make(map[string]Paths) 1535 1536 ctx.VisitAllModules(func(module Module) { 1537 blueprintDir := module.base().blueprintDir 1538 installTarget := module.base().installTarget 1539 checkbuildTarget := module.base().checkbuildTarget 1540 1541 if checkbuildTarget != nil { 1542 checkbuildDeps = append(checkbuildDeps, checkbuildTarget) 1543 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget) 1544 } 1545 1546 if installTarget != nil { 1547 modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget) 1548 } 1549 }) 1550 1551 suffix := "" 1552 if ctx.Config().EmbeddedInMake() { 1553 suffix = "-soong" 1554 } 1555 1556 // Create a top-level checkbuild target that depends on all modules 1557 ctx.Build(pctx, BuildParams{ 1558 Rule: blueprint.Phony, 1559 Output: PathForPhony(ctx, "checkbuild"+suffix), 1560 Implicits: checkbuildDeps, 1561 }) 1562 1563 // Make will generate the MODULES-IN-* targets 1564 if ctx.Config().EmbeddedInMake() { 1565 return 1566 } 1567 1568 sortedKeys := func(m map[string]Paths) []string { 1569 s := make([]string, 0, len(m)) 1570 for k := range m { 1571 s = append(s, k) 1572 } 1573 sort.Strings(s) 1574 return s 1575 } 1576 1577 // Ensure ancestor directories are in modulesInDir 1578 dirs := sortedKeys(modulesInDir) 1579 for _, dir := range dirs { 1580 dir := parentDir(dir) 1581 for dir != "." && dir != "/" { 1582 if _, exists := modulesInDir[dir]; exists { 1583 break 1584 } 1585 modulesInDir[dir] = nil 1586 dir = parentDir(dir) 1587 } 1588 } 1589 1590 // Make directories build their direct subdirectories 1591 dirs = sortedKeys(modulesInDir) 1592 for _, dir := range dirs { 1593 p := parentDir(dir) 1594 if p != "." && p != "/" { 1595 modulesInDir[p] = append(modulesInDir[p], mmTarget(dir)) 1596 } 1597 } 1598 1599 // Create a MODULES-IN-<directory> target that depends on all modules in a directory, and 1600 // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp 1601 // files. 1602 for _, dir := range dirs { 1603 ctx.Build(pctx, BuildParams{ 1604 Rule: blueprint.Phony, 1605 Output: mmTarget(dir), 1606 Implicits: modulesInDir[dir], 1607 // HACK: checkbuild should be an optional build, but force it 1608 // enabled for now in standalone builds 1609 Default: !ctx.Config().EmbeddedInMake(), 1610 }) 1611 } 1612 1613 // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild. 1614 osDeps := map[OsType]Paths{} 1615 ctx.VisitAllModules(func(module Module) { 1616 if module.Enabled() { 1617 os := module.Target().Os 1618 osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...) 1619 } 1620 }) 1621 1622 osClass := make(map[string]Paths) 1623 for os, deps := range osDeps { 1624 var className string 1625 1626 switch os.Class { 1627 case Host: 1628 className = "host" 1629 case HostCross: 1630 className = "host-cross" 1631 case Device: 1632 className = "target" 1633 default: 1634 continue 1635 } 1636 1637 name := PathForPhony(ctx, className+"-"+os.Name) 1638 osClass[className] = append(osClass[className], name) 1639 1640 ctx.Build(pctx, BuildParams{ 1641 Rule: blueprint.Phony, 1642 Output: name, 1643 Implicits: deps, 1644 }) 1645 } 1646 1647 // Wrap those into host|host-cross|target phony rules 1648 osClasses := sortedKeys(osClass) 1649 for _, class := range osClasses { 1650 ctx.Build(pctx, BuildParams{ 1651 Rule: blueprint.Phony, 1652 Output: PathForPhony(ctx, class), 1653 Implicits: osClass[class], 1654 }) 1655 } 1656} 1657 1658// Collect information for opening IDE project files in java/jdeps.go. 1659type IDEInfo interface { 1660 IDEInfo(ideInfo *IdeInfo) 1661 BaseModuleName() string 1662} 1663 1664// Extract the base module name from the Import name. 1665// Often the Import name has a prefix "prebuilt_". 1666// Remove the prefix explicitly if needed 1667// until we find a better solution to get the Import name. 1668type IDECustomizedModuleName interface { 1669 IDECustomizedModuleName() string 1670} 1671 1672type IdeInfo struct { 1673 Deps []string `json:"dependencies,omitempty"` 1674 Srcs []string `json:"srcs,omitempty"` 1675 Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"` 1676 Jarjar_rules []string `json:"jarjar_rules,omitempty"` 1677 Jars []string `json:"jars,omitempty"` 1678 Classes []string `json:"class,omitempty"` 1679 Installed_paths []string `json:"installed,omitempty"` 1680} 1681