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