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 cc 16 17// This file contains the module types for compiling C/C++ for Android, and converts the properties 18// into the flags and filenames necessary to pass to the compiler. The final creation of the rules 19// is handled in builder.go 20 21import ( 22 "strconv" 23 "strings" 24 25 "github.com/google/blueprint" 26 "github.com/google/blueprint/proptools" 27 28 "android/soong/android" 29 "android/soong/cc/config" 30 "android/soong/genrule" 31) 32 33func init() { 34 android.RegisterModuleType("cc_defaults", defaultsFactory) 35 36 android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { 37 ctx.BottomUp("link", linkageMutator).Parallel() 38 ctx.BottomUp("image", vendorMutator).Parallel() 39 ctx.BottomUp("ndk_api", ndkApiMutator).Parallel() 40 ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel() 41 ctx.BottomUp("begin", beginMutator).Parallel() 42 }) 43 44 android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { 45 ctx.TopDown("asan_deps", sanitizerDepsMutator(asan)) 46 ctx.BottomUp("asan", sanitizerMutator(asan)).Parallel() 47 48 ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan)) 49 ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel() 50 51 ctx.BottomUp("coverage", coverageLinkingMutator).Parallel() 52 ctx.TopDown("vndk_deps", sabiDepsMutator) 53 }) 54 55 pctx.Import("android/soong/cc/config") 56} 57 58type Deps struct { 59 SharedLibs, LateSharedLibs []string 60 StaticLibs, LateStaticLibs, WholeStaticLibs []string 61 HeaderLibs []string 62 63 ReexportSharedLibHeaders, ReexportStaticLibHeaders, ReexportHeaderLibHeaders []string 64 65 ObjFiles []string 66 67 GeneratedSources []string 68 GeneratedHeaders []string 69 70 ReexportGeneratedHeaders []string 71 72 CrtBegin, CrtEnd string 73} 74 75type PathDeps struct { 76 // Paths to .so files 77 SharedLibs, LateSharedLibs android.Paths 78 // Paths to the dependencies to use for .so files (.so.toc files) 79 SharedLibsDeps, LateSharedLibsDeps android.Paths 80 // Paths to .a files 81 StaticLibs, LateStaticLibs, WholeStaticLibs android.Paths 82 83 // Paths to .o files 84 Objs Objects 85 StaticLibObjs Objects 86 WholeStaticLibObjs Objects 87 88 // Paths to generated source files 89 GeneratedSources android.Paths 90 GeneratedHeaders android.Paths 91 92 Flags, ReexportedFlags []string 93 ReexportedFlagsDeps android.Paths 94 95 // Paths to crt*.o files 96 CrtBegin, CrtEnd android.OptionalPath 97} 98 99type Flags struct { 100 GlobalFlags []string // Flags that apply to C, C++, and assembly source files 101 ArFlags []string // Flags that apply to ar 102 AsFlags []string // Flags that apply to assembly source files 103 CFlags []string // Flags that apply to C and C++ source files 104 ConlyFlags []string // Flags that apply to C source files 105 CppFlags []string // Flags that apply to C++ source files 106 YaccFlags []string // Flags that apply to Yacc source files 107 protoFlags []string // Flags that apply to proto source files 108 aidlFlags []string // Flags that apply to aidl source files 109 LdFlags []string // Flags that apply to linker command lines 110 libFlags []string // Flags to add libraries early to the link order 111 TidyFlags []string // Flags that apply to clang-tidy 112 SAbiFlags []string // Flags that apply to header-abi-dumper 113 YasmFlags []string // Flags that apply to yasm assembly source files 114 115 // Global include flags that apply to C, C++, and assembly source files 116 // These must be after any module include flags, which will be in GlobalFlags. 117 SystemIncludeFlags []string 118 119 Toolchain config.Toolchain 120 Clang bool 121 Tidy bool 122 Coverage bool 123 SAbiDump bool 124 125 RequiredInstructionSet string 126 DynamicLinker string 127 128 CFlagsDeps android.Paths // Files depended on by compiler flags 129 130 GroupStaticLibs bool 131} 132 133type ObjectLinkerProperties struct { 134 // names of other cc_object modules to link into this module using partial linking 135 Objs []string `android:"arch_variant"` 136} 137 138// Properties used to compile all C or C++ modules 139type BaseProperties struct { 140 // compile module with clang instead of gcc 141 Clang *bool `android:"arch_variant"` 142 143 // Minimum sdk version supported when compiling against the ndk 144 Sdk_version string 145 146 // don't insert default compiler flags into asflags, cflags, 147 // cppflags, conlyflags, ldflags, or include_dirs 148 No_default_compiler_flags *bool 149 150 // whether this module should be allowed to install onto /vendor as 151 // well as /system. The two variants will be built separately, one 152 // like normal, and the other limited to the set of libraries and 153 // headers that are exposed to /vendor modules. 154 // 155 // The vendor variant may be used with a different (newer) /system, 156 // so it shouldn't have any unversioned runtime dependencies, or 157 // make assumptions about the system that may not be true in the 158 // future. 159 // 160 // Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk 161 Vendor_available *bool 162 163 AndroidMkSharedLibs []string `blueprint:"mutated"` 164 HideFromMake bool `blueprint:"mutated"` 165 PreventInstall bool `blueprint:"mutated"` 166 167 UseVndk bool `blueprint:"mutated"` 168} 169 170type UnusedProperties struct { 171 Tags []string 172} 173 174type ModuleContextIntf interface { 175 static() bool 176 staticBinary() bool 177 clang() bool 178 toolchain() config.Toolchain 179 noDefaultCompilerFlags() bool 180 sdk() bool 181 sdkVersion() string 182 vndk() bool 183 createVndkSourceAbiDump() bool 184 selectedStl() string 185 baseModuleName() string 186} 187 188type ModuleContext interface { 189 android.ModuleContext 190 ModuleContextIntf 191} 192 193type BaseModuleContext interface { 194 android.BaseContext 195 ModuleContextIntf 196} 197 198type DepsContext interface { 199 android.BottomUpMutatorContext 200 ModuleContextIntf 201} 202 203type feature interface { 204 begin(ctx BaseModuleContext) 205 deps(ctx DepsContext, deps Deps) Deps 206 flags(ctx ModuleContext, flags Flags) Flags 207 props() []interface{} 208} 209 210type compiler interface { 211 compilerInit(ctx BaseModuleContext) 212 compilerDeps(ctx DepsContext, deps Deps) Deps 213 compilerFlags(ctx ModuleContext, flags Flags) Flags 214 compilerProps() []interface{} 215 216 appendCflags([]string) 217 appendAsflags([]string) 218 compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects 219} 220 221type linker interface { 222 linkerInit(ctx BaseModuleContext) 223 linkerDeps(ctx DepsContext, deps Deps) Deps 224 linkerFlags(ctx ModuleContext, flags Flags) Flags 225 linkerProps() []interface{} 226 227 link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path 228 appendLdflags([]string) 229} 230 231type installer interface { 232 installerProps() []interface{} 233 install(ctx ModuleContext, path android.Path) 234 inData() bool 235 inSanitizerDir() bool 236 hostToolPath() android.OptionalPath 237} 238 239type dependencyTag struct { 240 blueprint.BaseDependencyTag 241 name string 242 library bool 243 244 reexportFlags bool 245} 246 247var ( 248 sharedDepTag = dependencyTag{name: "shared", library: true} 249 sharedExportDepTag = dependencyTag{name: "shared", library: true, reexportFlags: true} 250 lateSharedDepTag = dependencyTag{name: "late shared", library: true} 251 staticDepTag = dependencyTag{name: "static", library: true} 252 staticExportDepTag = dependencyTag{name: "static", library: true, reexportFlags: true} 253 lateStaticDepTag = dependencyTag{name: "late static", library: true} 254 wholeStaticDepTag = dependencyTag{name: "whole static", library: true, reexportFlags: true} 255 headerDepTag = dependencyTag{name: "header", library: true} 256 headerExportDepTag = dependencyTag{name: "header", library: true, reexportFlags: true} 257 genSourceDepTag = dependencyTag{name: "gen source"} 258 genHeaderDepTag = dependencyTag{name: "gen header"} 259 genHeaderExportDepTag = dependencyTag{name: "gen header", reexportFlags: true} 260 objDepTag = dependencyTag{name: "obj"} 261 crtBeginDepTag = dependencyTag{name: "crtbegin"} 262 crtEndDepTag = dependencyTag{name: "crtend"} 263 reuseObjTag = dependencyTag{name: "reuse objects"} 264 ndkStubDepTag = dependencyTag{name: "ndk stub", library: true} 265 ndkLateStubDepTag = dependencyTag{name: "ndk late stub", library: true} 266) 267 268// Module contains the properties and members used by all C/C++ module types, and implements 269// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces 270// to construct the output file. Behavior can be customized with a Customizer interface 271type Module struct { 272 android.ModuleBase 273 android.DefaultableModule 274 275 Properties BaseProperties 276 unused UnusedProperties 277 278 // initialize before calling Init 279 hod android.HostOrDeviceSupported 280 multilib android.Multilib 281 282 // delegates, initialize before calling Init 283 features []feature 284 compiler compiler 285 linker linker 286 installer installer 287 stl *stl 288 sanitize *sanitize 289 coverage *coverage 290 sabi *sabi 291 292 androidMkSharedLibDeps []string 293 294 outputFile android.OptionalPath 295 296 cachedToolchain config.Toolchain 297 298 subAndroidMkOnce map[subAndroidMkProvider]bool 299 300 // Flags used to compile this module 301 flags Flags 302} 303 304func (c *Module) Init() (blueprint.Module, []interface{}) { 305 props := []interface{}{&c.Properties, &c.unused} 306 if c.compiler != nil { 307 props = append(props, c.compiler.compilerProps()...) 308 } 309 if c.linker != nil { 310 props = append(props, c.linker.linkerProps()...) 311 } 312 if c.installer != nil { 313 props = append(props, c.installer.installerProps()...) 314 } 315 if c.stl != nil { 316 props = append(props, c.stl.props()...) 317 } 318 if c.sanitize != nil { 319 props = append(props, c.sanitize.props()...) 320 } 321 if c.coverage != nil { 322 props = append(props, c.coverage.props()...) 323 } 324 if c.sabi != nil { 325 props = append(props, c.sabi.props()...) 326 } 327 for _, feature := range c.features { 328 props = append(props, feature.props()...) 329 } 330 331 _, props = android.InitAndroidArchModule(c, c.hod, c.multilib, props...) 332 333 return android.InitDefaultableModule(c, c, props...) 334} 335 336// Returns true for dependency roots (binaries) 337// TODO(ccross): also handle dlopenable libraries 338func (c *Module) isDependencyRoot() bool { 339 if root, ok := c.linker.(interface { 340 isDependencyRoot() bool 341 }); ok { 342 return root.isDependencyRoot() 343 } 344 return false 345} 346 347func (c *Module) vndk() bool { 348 return c.Properties.UseVndk 349} 350 351type baseModuleContext struct { 352 android.BaseContext 353 moduleContextImpl 354} 355 356type depsContext struct { 357 android.BottomUpMutatorContext 358 moduleContextImpl 359} 360 361type moduleContext struct { 362 android.ModuleContext 363 moduleContextImpl 364} 365 366// Vendor returns true for vendor modules so that they get installed onto the 367// correct partition 368func (ctx *moduleContext) Vendor() bool { 369 return ctx.ModuleContext.Vendor() || ctx.moduleContextImpl.mod.Properties.UseVndk 370} 371 372type moduleContextImpl struct { 373 mod *Module 374 ctx BaseModuleContext 375} 376 377func (ctx *moduleContextImpl) clang() bool { 378 return ctx.mod.clang(ctx.ctx) 379} 380 381func (ctx *moduleContextImpl) toolchain() config.Toolchain { 382 return ctx.mod.toolchain(ctx.ctx) 383} 384 385func (ctx *moduleContextImpl) static() bool { 386 if static, ok := ctx.mod.linker.(interface { 387 static() bool 388 }); ok { 389 return static.static() 390 } 391 return false 392} 393 394func (ctx *moduleContextImpl) staticBinary() bool { 395 if static, ok := ctx.mod.linker.(interface { 396 staticBinary() bool 397 }); ok { 398 return static.staticBinary() 399 } 400 return false 401} 402 403func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool { 404 return Bool(ctx.mod.Properties.No_default_compiler_flags) 405} 406 407func (ctx *moduleContextImpl) sdk() bool { 408 if ctx.ctx.Device() && !ctx.vndk() { 409 return ctx.mod.Properties.Sdk_version != "" 410 } 411 return false 412} 413 414func (ctx *moduleContextImpl) sdkVersion() string { 415 if ctx.ctx.Device() { 416 if ctx.vndk() { 417 return "current" 418 } else { 419 return ctx.mod.Properties.Sdk_version 420 } 421 } 422 return "" 423} 424 425func (ctx *moduleContextImpl) vndk() bool { 426 return ctx.mod.vndk() 427} 428 429// Create source abi dumps if the module belongs to the list of VndkLibraries. 430func (ctx *moduleContextImpl) createVndkSourceAbiDump() bool { 431 return ctx.ctx.Device() && ((Bool(ctx.mod.Properties.Vendor_available)) || (inList(ctx.baseModuleName(), config.LLndkLibraries()))) 432} 433 434func (ctx *moduleContextImpl) selectedStl() string { 435 if stl := ctx.mod.stl; stl != nil { 436 return stl.Properties.SelectedStl 437 } 438 return "" 439} 440 441func (ctx *moduleContextImpl) baseModuleName() string { 442 return ctx.mod.ModuleBase.BaseModuleName() 443} 444 445func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { 446 return &Module{ 447 hod: hod, 448 multilib: multilib, 449 } 450} 451 452func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { 453 module := newBaseModule(hod, multilib) 454 module.features = []feature{ 455 &tidyFeature{}, 456 } 457 module.stl = &stl{} 458 module.sanitize = &sanitize{} 459 module.coverage = &coverage{} 460 module.sabi = &sabi{} 461 return module 462} 463 464func (c *Module) Prebuilt() *android.Prebuilt { 465 if p, ok := c.linker.(prebuiltLinkerInterface); ok { 466 return p.prebuilt() 467 } 468 return nil 469} 470 471func (c *Module) Name() string { 472 name := c.ModuleBase.Name() 473 if p, ok := c.linker.(interface { 474 Name(string) string 475 }); ok { 476 name = p.Name(name) 477 } 478 return name 479} 480 481func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { 482 ctx := &moduleContext{ 483 ModuleContext: actx, 484 moduleContextImpl: moduleContextImpl{ 485 mod: c, 486 }, 487 } 488 ctx.ctx = ctx 489 490 flags := Flags{ 491 Toolchain: c.toolchain(ctx), 492 Clang: c.clang(ctx), 493 } 494 if c.compiler != nil { 495 flags = c.compiler.compilerFlags(ctx, flags) 496 } 497 if c.linker != nil { 498 flags = c.linker.linkerFlags(ctx, flags) 499 } 500 if c.stl != nil { 501 flags = c.stl.flags(ctx, flags) 502 } 503 if c.sanitize != nil { 504 flags = c.sanitize.flags(ctx, flags) 505 } 506 if c.coverage != nil { 507 flags = c.coverage.flags(ctx, flags) 508 } 509 if c.sabi != nil { 510 flags = c.sabi.flags(ctx, flags) 511 } 512 for _, feature := range c.features { 513 flags = feature.flags(ctx, flags) 514 } 515 if ctx.Failed() { 516 return 517 } 518 519 flags.CFlags, _ = filterList(flags.CFlags, config.IllegalFlags) 520 flags.CppFlags, _ = filterList(flags.CppFlags, config.IllegalFlags) 521 flags.ConlyFlags, _ = filterList(flags.ConlyFlags, config.IllegalFlags) 522 523 deps := c.depsToPaths(ctx) 524 if ctx.Failed() { 525 return 526 } 527 flags.GlobalFlags = append(flags.GlobalFlags, deps.Flags...) 528 c.flags = flags 529 530 // Optimization to reduce size of build.ninja 531 // Replace the long list of flags for each file with a module-local variable 532 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " ")) 533 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " ")) 534 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " ")) 535 flags.CFlags = []string{"$cflags"} 536 flags.CppFlags = []string{"$cppflags"} 537 flags.AsFlags = []string{"$asflags"} 538 539 var objs Objects 540 if c.compiler != nil { 541 objs = c.compiler.compile(ctx, flags, deps) 542 if ctx.Failed() { 543 return 544 } 545 } 546 547 if c.linker != nil { 548 outputFile := c.linker.link(ctx, flags, deps, objs) 549 if ctx.Failed() { 550 return 551 } 552 c.outputFile = android.OptionalPathForPath(outputFile) 553 } 554 555 if c.installer != nil && !c.Properties.PreventInstall && c.outputFile.Valid() { 556 c.installer.install(ctx, c.outputFile.Path()) 557 if ctx.Failed() { 558 return 559 } 560 } 561} 562 563func (c *Module) toolchain(ctx BaseModuleContext) config.Toolchain { 564 if c.cachedToolchain == nil { 565 c.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch()) 566 } 567 return c.cachedToolchain 568} 569 570func (c *Module) begin(ctx BaseModuleContext) { 571 if c.compiler != nil { 572 c.compiler.compilerInit(ctx) 573 } 574 if c.linker != nil { 575 c.linker.linkerInit(ctx) 576 } 577 if c.stl != nil { 578 c.stl.begin(ctx) 579 } 580 if c.sanitize != nil { 581 c.sanitize.begin(ctx) 582 } 583 if c.coverage != nil { 584 c.coverage.begin(ctx) 585 } 586 if c.sabi != nil { 587 c.sabi.begin(ctx) 588 } 589 for _, feature := range c.features { 590 feature.begin(ctx) 591 } 592 if ctx.sdk() { 593 version, err := normalizeNdkApiLevel(ctx.sdkVersion(), ctx.Arch()) 594 if err != nil { 595 ctx.PropertyErrorf("sdk_version", err.Error()) 596 } 597 c.Properties.Sdk_version = version 598 } 599} 600 601func (c *Module) deps(ctx DepsContext) Deps { 602 deps := Deps{} 603 604 if c.compiler != nil { 605 deps = c.compiler.compilerDeps(ctx, deps) 606 } 607 if c.linker != nil { 608 deps = c.linker.linkerDeps(ctx, deps) 609 } 610 if c.stl != nil { 611 deps = c.stl.deps(ctx, deps) 612 } 613 if c.sanitize != nil { 614 deps = c.sanitize.deps(ctx, deps) 615 } 616 if c.coverage != nil { 617 deps = c.coverage.deps(ctx, deps) 618 } 619 if c.sabi != nil { 620 deps = c.sabi.deps(ctx, deps) 621 } 622 for _, feature := range c.features { 623 deps = feature.deps(ctx, deps) 624 } 625 626 deps.WholeStaticLibs = lastUniqueElements(deps.WholeStaticLibs) 627 deps.StaticLibs = lastUniqueElements(deps.StaticLibs) 628 deps.LateStaticLibs = lastUniqueElements(deps.LateStaticLibs) 629 deps.SharedLibs = lastUniqueElements(deps.SharedLibs) 630 deps.LateSharedLibs = lastUniqueElements(deps.LateSharedLibs) 631 deps.HeaderLibs = lastUniqueElements(deps.HeaderLibs) 632 633 for _, lib := range deps.ReexportSharedLibHeaders { 634 if !inList(lib, deps.SharedLibs) { 635 ctx.PropertyErrorf("export_shared_lib_headers", "Shared library not in shared_libs: '%s'", lib) 636 } 637 } 638 639 for _, lib := range deps.ReexportStaticLibHeaders { 640 if !inList(lib, deps.StaticLibs) { 641 ctx.PropertyErrorf("export_static_lib_headers", "Static library not in static_libs: '%s'", lib) 642 } 643 } 644 645 for _, lib := range deps.ReexportHeaderLibHeaders { 646 if !inList(lib, deps.HeaderLibs) { 647 ctx.PropertyErrorf("export_header_lib_headers", "Header library not in header_libs: '%s'", lib) 648 } 649 } 650 651 for _, gen := range deps.ReexportGeneratedHeaders { 652 if !inList(gen, deps.GeneratedHeaders) { 653 ctx.PropertyErrorf("export_generated_headers", "Generated header module not in generated_headers: '%s'", gen) 654 } 655 } 656 657 return deps 658} 659 660func (c *Module) beginMutator(actx android.BottomUpMutatorContext) { 661 ctx := &baseModuleContext{ 662 BaseContext: actx, 663 moduleContextImpl: moduleContextImpl{ 664 mod: c, 665 }, 666 } 667 ctx.ctx = ctx 668 669 c.begin(ctx) 670} 671 672func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { 673 if !c.Enabled() { 674 return 675 } 676 677 ctx := &depsContext{ 678 BottomUpMutatorContext: actx, 679 moduleContextImpl: moduleContextImpl{ 680 mod: c, 681 }, 682 } 683 ctx.ctx = ctx 684 685 deps := c.deps(ctx) 686 687 c.Properties.AndroidMkSharedLibs = append(c.Properties.AndroidMkSharedLibs, deps.SharedLibs...) 688 c.Properties.AndroidMkSharedLibs = append(c.Properties.AndroidMkSharedLibs, deps.LateSharedLibs...) 689 690 variantNdkLibs := []string{} 691 variantLateNdkLibs := []string{} 692 if ctx.Os() == android.Android { 693 version := ctx.sdkVersion() 694 695 // Rewrites the names of shared libraries into the names of the NDK 696 // libraries where appropriate. This returns two slices. 697 // 698 // The first is a list of non-variant shared libraries (either rewritten 699 // NDK libraries to the modules in prebuilts/ndk, or not rewritten 700 // because they are not NDK libraries). 701 // 702 // The second is a list of ndk_library modules. These need to be 703 // separated because they are a variation dependency and must be added 704 // in a different manner. 705 rewriteNdkLibs := func(list []string) ([]string, []string) { 706 variantLibs := []string{} 707 nonvariantLibs := []string{} 708 for _, entry := range list { 709 if ctx.sdk() && inList(entry, ndkPrebuiltSharedLibraries) { 710 if !inList(entry, ndkMigratedLibs) { 711 nonvariantLibs = append(nonvariantLibs, entry+".ndk."+version) 712 } else { 713 variantLibs = append(variantLibs, entry+ndkLibrarySuffix) 714 } 715 } else if ctx.vndk() && inList(entry, config.LLndkLibraries()) { 716 nonvariantLibs = append(nonvariantLibs, entry+llndkLibrarySuffix) 717 } else { 718 nonvariantLibs = append(nonvariantLibs, entry) 719 } 720 } 721 return nonvariantLibs, variantLibs 722 } 723 724 deps.SharedLibs, variantNdkLibs = rewriteNdkLibs(deps.SharedLibs) 725 deps.LateSharedLibs, variantLateNdkLibs = rewriteNdkLibs(deps.LateSharedLibs) 726 } 727 728 for _, lib := range deps.HeaderLibs { 729 depTag := headerDepTag 730 if inList(lib, deps.ReexportHeaderLibHeaders) { 731 depTag = headerExportDepTag 732 } 733 actx.AddVariationDependencies(nil, depTag, lib) 734 } 735 736 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, wholeStaticDepTag, 737 deps.WholeStaticLibs...) 738 739 for _, lib := range deps.StaticLibs { 740 depTag := staticDepTag 741 if inList(lib, deps.ReexportStaticLibHeaders) { 742 depTag = staticExportDepTag 743 } 744 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, depTag, lib) 745 } 746 747 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, lateStaticDepTag, 748 deps.LateStaticLibs...) 749 750 for _, lib := range deps.SharedLibs { 751 depTag := sharedDepTag 752 if inList(lib, deps.ReexportSharedLibHeaders) { 753 depTag = sharedExportDepTag 754 } 755 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, depTag, lib) 756 } 757 758 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag, 759 deps.LateSharedLibs...) 760 761 actx.AddDependency(c, genSourceDepTag, deps.GeneratedSources...) 762 763 for _, gen := range deps.GeneratedHeaders { 764 depTag := genHeaderDepTag 765 if inList(gen, deps.ReexportGeneratedHeaders) { 766 depTag = genHeaderExportDepTag 767 } 768 actx.AddDependency(c, depTag, gen) 769 } 770 771 actx.AddDependency(c, objDepTag, deps.ObjFiles...) 772 773 if deps.CrtBegin != "" { 774 actx.AddDependency(c, crtBeginDepTag, deps.CrtBegin) 775 } 776 if deps.CrtEnd != "" { 777 actx.AddDependency(c, crtEndDepTag, deps.CrtEnd) 778 } 779 780 version := ctx.sdkVersion() 781 actx.AddVariationDependencies([]blueprint.Variation{ 782 {"ndk_api", version}, {"link", "shared"}}, ndkStubDepTag, variantNdkLibs...) 783 actx.AddVariationDependencies([]blueprint.Variation{ 784 {"ndk_api", version}, {"link", "shared"}}, ndkLateStubDepTag, variantLateNdkLibs...) 785} 786 787func beginMutator(ctx android.BottomUpMutatorContext) { 788 if c, ok := ctx.Module().(*Module); ok && c.Enabled() { 789 c.beginMutator(ctx) 790 } 791} 792 793func (c *Module) clang(ctx BaseModuleContext) bool { 794 clang := Bool(c.Properties.Clang) 795 796 if c.Properties.Clang == nil { 797 if ctx.Host() { 798 clang = true 799 } 800 801 if ctx.Device() && ctx.AConfig().DeviceUsesClang() { 802 clang = true 803 } 804 } 805 806 if !c.toolchain(ctx).ClangSupported() { 807 clang = false 808 } 809 810 return clang 811} 812 813// Convert dependencies to paths. Returns a PathDeps containing paths 814func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { 815 var depPaths PathDeps 816 817 // Whether a module can link to another module, taking into 818 // account NDK linking. 819 checkLinkType := func(from, to *Module) { 820 if from.Target().Os != android.Android { 821 // Host code is not restricted 822 return 823 } 824 if from.Properties.UseVndk { 825 // Vendor code is already limited by the vendor mutator 826 return 827 } 828 if from.Properties.Sdk_version == "" { 829 // Platform code can link to anything 830 return 831 } 832 if _, ok := to.linker.(*toolchainLibraryDecorator); ok { 833 // These are always allowed 834 return 835 } 836 if _, ok := to.linker.(*ndkPrebuiltLibraryLinker); ok { 837 // These are allowed, but don't set sdk_version 838 return 839 } 840 if _, ok := to.linker.(*ndkPrebuiltStlLinker); ok { 841 // These are allowed, but don't set sdk_version 842 return 843 } 844 if _, ok := to.linker.(*stubDecorator); ok { 845 // These aren't real libraries, but are the stub shared libraries that are included in 846 // the NDK. 847 return 848 } 849 if to.Properties.Sdk_version == "" { 850 // NDK code linking to platform code is never okay. 851 ctx.ModuleErrorf("depends on non-NDK-built library %q", 852 ctx.OtherModuleName(to)) 853 } 854 855 // All this point we know we have two NDK libraries, but we need to 856 // check that we're not linking against anything built against a higher 857 // API level, as it is only valid to link against older or equivalent 858 // APIs. 859 860 if from.Properties.Sdk_version == "current" { 861 // Current can link against anything. 862 return 863 } else if to.Properties.Sdk_version == "current" { 864 // Current can't be linked against by anything else. 865 ctx.ModuleErrorf("links %q built against newer API version %q", 866 ctx.OtherModuleName(to), "current") 867 } 868 869 fromApi, err := strconv.Atoi(from.Properties.Sdk_version) 870 if err != nil { 871 ctx.PropertyErrorf("sdk_version", 872 "Invalid sdk_version value (must be int): %q", 873 from.Properties.Sdk_version) 874 } 875 toApi, err := strconv.Atoi(to.Properties.Sdk_version) 876 if err != nil { 877 ctx.PropertyErrorf("sdk_version", 878 "Invalid sdk_version value (must be int): %q", 879 to.Properties.Sdk_version) 880 } 881 882 if toApi > fromApi { 883 ctx.ModuleErrorf("links %q built against newer API version %q", 884 ctx.OtherModuleName(to), to.Properties.Sdk_version) 885 } 886 } 887 888 ctx.VisitDirectDeps(func(m blueprint.Module) { 889 name := ctx.OtherModuleName(m) 890 tag := ctx.OtherModuleDependencyTag(m) 891 892 a, _ := m.(android.Module) 893 if a == nil { 894 ctx.ModuleErrorf("module %q not an android module", name) 895 return 896 } 897 898 cc, _ := m.(*Module) 899 if cc == nil { 900 switch tag { 901 case android.DefaultsDepTag, android.SourceDepTag: 902 case genSourceDepTag: 903 if genRule, ok := m.(genrule.SourceFileGenerator); ok { 904 depPaths.GeneratedSources = append(depPaths.GeneratedSources, 905 genRule.GeneratedSourceFiles()...) 906 } else { 907 ctx.ModuleErrorf("module %q is not a gensrcs or genrule", name) 908 } 909 case genHeaderDepTag, genHeaderExportDepTag: 910 if genRule, ok := m.(genrule.SourceFileGenerator); ok { 911 depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders, 912 genRule.GeneratedSourceFiles()...) 913 flags := includeDirsToFlags(genRule.GeneratedHeaderDirs()) 914 depPaths.Flags = append(depPaths.Flags, flags) 915 if tag == genHeaderExportDepTag { 916 depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags) 917 depPaths.ReexportedFlagsDeps = append(depPaths.ReexportedFlagsDeps, 918 genRule.GeneratedSourceFiles()...) 919 // Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library. 920 c.sabi.Properties.ReexportedIncludeFlags = append(c.sabi.Properties.ReexportedIncludeFlags, flags) 921 922 } 923 } else { 924 ctx.ModuleErrorf("module %q is not a genrule", name) 925 } 926 default: 927 ctx.ModuleErrorf("depends on non-cc module %q", name) 928 } 929 return 930 } 931 932 if !a.Enabled() { 933 if ctx.AConfig().AllowMissingDependencies() { 934 ctx.AddMissingDependencies([]string{name}) 935 } else { 936 ctx.ModuleErrorf("depends on disabled module %q", name) 937 } 938 return 939 } 940 941 if a.Target().Os != ctx.Os() { 942 ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), name) 943 return 944 } 945 946 if a.Target().Arch.ArchType != ctx.Arch().ArchType { 947 ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), name) 948 return 949 } 950 951 if tag == reuseObjTag { 952 if l, ok := cc.compiler.(libraryInterface); ok { 953 depPaths.Objs = depPaths.Objs.Append(l.reuseObjs()) 954 return 955 } 956 } 957 958 if t, ok := tag.(dependencyTag); ok && t.library { 959 if i, ok := cc.linker.(exportedFlagsProducer); ok { 960 flags := i.exportedFlags() 961 deps := i.exportedFlagsDeps() 962 depPaths.Flags = append(depPaths.Flags, flags...) 963 depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders, deps...) 964 965 if t.reexportFlags { 966 depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags...) 967 depPaths.ReexportedFlagsDeps = append(depPaths.ReexportedFlagsDeps, deps...) 968 // Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library. 969 // Re-exported flags from shared library dependencies are not included as those shared libraries 970 // will be included in the vndk set. 971 if tag == staticExportDepTag || tag == headerExportDepTag { 972 c.sabi.Properties.ReexportedIncludeFlags = append(c.sabi.Properties.ReexportedIncludeFlags, flags...) 973 } 974 } 975 } 976 977 checkLinkType(c, cc) 978 } 979 980 var ptr *android.Paths 981 var depPtr *android.Paths 982 983 linkFile := cc.outputFile 984 depFile := android.OptionalPath{} 985 986 switch tag { 987 case ndkStubDepTag, sharedDepTag, sharedExportDepTag: 988 ptr = &depPaths.SharedLibs 989 depPtr = &depPaths.SharedLibsDeps 990 depFile = cc.linker.(libraryInterface).toc() 991 case lateSharedDepTag, ndkLateStubDepTag: 992 ptr = &depPaths.LateSharedLibs 993 depPtr = &depPaths.LateSharedLibsDeps 994 depFile = cc.linker.(libraryInterface).toc() 995 case staticDepTag, staticExportDepTag: 996 ptr = &depPaths.StaticLibs 997 case lateStaticDepTag: 998 ptr = &depPaths.LateStaticLibs 999 case wholeStaticDepTag: 1000 ptr = &depPaths.WholeStaticLibs 1001 staticLib, ok := cc.linker.(libraryInterface) 1002 if !ok || !staticLib.static() { 1003 ctx.ModuleErrorf("module %q not a static library", name) 1004 return 1005 } 1006 1007 if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil { 1008 postfix := " (required by " + ctx.OtherModuleName(m) + ")" 1009 for i := range missingDeps { 1010 missingDeps[i] += postfix 1011 } 1012 ctx.AddMissingDependencies(missingDeps) 1013 } 1014 depPaths.WholeStaticLibObjs = depPaths.WholeStaticLibObjs.Append(staticLib.objs()) 1015 case headerDepTag: 1016 // Nothing 1017 case objDepTag: 1018 depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path()) 1019 case crtBeginDepTag: 1020 depPaths.CrtBegin = linkFile 1021 case crtEndDepTag: 1022 depPaths.CrtEnd = linkFile 1023 } 1024 1025 switch tag { 1026 case staticDepTag, staticExportDepTag, lateStaticDepTag: 1027 staticLib, ok := cc.linker.(libraryInterface) 1028 if !ok || !staticLib.static() { 1029 ctx.ModuleErrorf("module %q not a static library", name) 1030 return 1031 } 1032 1033 // When combining coverage files for shared libraries and executables, coverage files 1034 // in static libraries act as if they were whole static libraries. The same goes for 1035 // source based Abi dump files. 1036 depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles, 1037 staticLib.objs().coverageFiles...) 1038 depPaths.StaticLibObjs.sAbiDumpFiles = append(depPaths.StaticLibObjs.sAbiDumpFiles, 1039 staticLib.objs().sAbiDumpFiles...) 1040 } 1041 1042 if ptr != nil { 1043 if !linkFile.Valid() { 1044 ctx.ModuleErrorf("module %q missing output file", name) 1045 return 1046 } 1047 *ptr = append(*ptr, linkFile.Path()) 1048 } 1049 1050 if depPtr != nil { 1051 dep := depFile 1052 if !dep.Valid() { 1053 dep = linkFile 1054 } 1055 *depPtr = append(*depPtr, dep.Path()) 1056 } 1057 }) 1058 1059 return depPaths 1060} 1061 1062func (c *Module) InstallInData() bool { 1063 if c.installer == nil { 1064 return false 1065 } 1066 return c.installer.inData() 1067} 1068 1069func (c *Module) InstallInSanitizerDir() bool { 1070 if c.installer == nil { 1071 return false 1072 } 1073 if c.sanitize != nil && c.sanitize.inSanitizerDir() { 1074 return true 1075 } 1076 return c.installer.inSanitizerDir() 1077} 1078 1079func (c *Module) HostToolPath() android.OptionalPath { 1080 if c.installer == nil { 1081 return android.OptionalPath{} 1082 } 1083 return c.installer.hostToolPath() 1084} 1085 1086// 1087// Defaults 1088// 1089type Defaults struct { 1090 android.ModuleBase 1091 android.DefaultsModule 1092} 1093 1094func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1095} 1096 1097func (d *Defaults) DepsMutator(ctx android.BottomUpMutatorContext) { 1098} 1099 1100func defaultsFactory() (blueprint.Module, []interface{}) { 1101 return DefaultsFactory() 1102} 1103 1104func DefaultsFactory(props ...interface{}) (blueprint.Module, []interface{}) { 1105 module := &Defaults{} 1106 1107 props = append(props, 1108 &BaseProperties{}, 1109 &BaseCompilerProperties{}, 1110 &BaseLinkerProperties{}, 1111 &LibraryProperties{}, 1112 &FlagExporterProperties{}, 1113 &BinaryLinkerProperties{}, 1114 &TestProperties{}, 1115 &TestBinaryProperties{}, 1116 &UnusedProperties{}, 1117 &StlProperties{}, 1118 &SanitizeProperties{}, 1119 &StripProperties{}, 1120 &InstallerProperties{}, 1121 &TidyProperties{}, 1122 &CoverageProperties{}, 1123 &SAbiProperties{}, 1124 ) 1125 1126 return android.InitDefaultsModule(module, module, props...) 1127} 1128 1129const ( 1130 // coreMode is the variant used for framework-private libraries, or 1131 // SDK libraries. (which framework-private libraries can use) 1132 coreMode = "core" 1133 1134 // vendorMode is the variant used for /vendor code that compiles 1135 // against the VNDK. 1136 vendorMode = "vendor" 1137) 1138 1139func vendorMutator(mctx android.BottomUpMutatorContext) { 1140 if mctx.Os() != android.Android { 1141 return 1142 } 1143 1144 m, ok := mctx.Module().(*Module) 1145 if !ok { 1146 return 1147 } 1148 1149 // Sanity check 1150 if Bool(m.Properties.Vendor_available) && mctx.Vendor() { 1151 mctx.PropertyErrorf("vendor_available", 1152 "doesn't make sense at the same time as `vendor: true` or `proprietary: true`") 1153 return 1154 } 1155 1156 if !mctx.DeviceConfig().CompileVndk() { 1157 // If the device isn't compiling against the VNDK, we always 1158 // use the core mode. 1159 mctx.CreateVariations(coreMode) 1160 } else if _, ok := m.linker.(*llndkStubDecorator); ok { 1161 // LL-NDK stubs only exist in the vendor variant, since the 1162 // real libraries will be used in the core variant. 1163 mctx.CreateVariations(vendorMode) 1164 } else if Bool(m.Properties.Vendor_available) { 1165 // This will be available in both /system and /vendor 1166 mod := mctx.CreateVariations(coreMode, vendorMode) 1167 mod[1].(*Module).Properties.UseVndk = true 1168 } else if mctx.Vendor() && m.Properties.Sdk_version == "" { 1169 // This will be available in /vendor only 1170 mod := mctx.CreateVariations(vendorMode) 1171 mod[0].(*Module).Properties.UseVndk = true 1172 } else { 1173 // This is either in /system (or similar: /data), or is a 1174 // modules built with the NDK. Modules built with the NDK 1175 // will be restricted using the existing link type checks. 1176 mctx.CreateVariations(coreMode) 1177 } 1178} 1179 1180// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each 1181// modifies the slice contents in place, and returns a subslice of the original slice 1182func lastUniqueElements(list []string) []string { 1183 totalSkip := 0 1184 for i := len(list) - 1; i >= totalSkip; i-- { 1185 skip := 0 1186 for j := i - 1; j >= totalSkip; j-- { 1187 if list[i] == list[j] { 1188 skip++ 1189 } else { 1190 list[j+skip] = list[j] 1191 } 1192 } 1193 totalSkip += skip 1194 } 1195 return list[totalSkip:] 1196} 1197 1198var Bool = proptools.Bool 1199