1// Copyright 2016 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 17import ( 18 "fmt" 19 "io" 20 "path/filepath" 21 "regexp" 22 "sort" 23 "strconv" 24 "strings" 25 "sync" 26 27 "github.com/google/blueprint/pathtools" 28 29 "android/soong/android" 30 "android/soong/cc/config" 31 "android/soong/genrule" 32) 33 34type LibraryProperties struct { 35 // local file name to pass to the linker as -unexported_symbols_list 36 Unexported_symbols_list *string `android:"path,arch_variant"` 37 // local file name to pass to the linker as -force_symbols_not_weak_list 38 Force_symbols_not_weak_list *string `android:"path,arch_variant"` 39 // local file name to pass to the linker as -force_symbols_weak_list 40 Force_symbols_weak_list *string `android:"path,arch_variant"` 41 42 // rename host libraries to prevent overlap with system installed libraries 43 Unique_host_soname *bool 44 45 Aidl struct { 46 // export headers generated from .aidl sources 47 Export_aidl_headers *bool 48 } 49 50 Proto struct { 51 // export headers generated from .proto sources 52 Export_proto_headers *bool 53 } 54 55 Sysprop struct { 56 // Whether platform owns this sysprop library. 57 Platform *bool 58 } `blueprint:"mutated"` 59 60 Static_ndk_lib *bool 61 62 Stubs struct { 63 // Relative path to the symbol map. The symbol map provides the list of 64 // symbols that are exported for stubs variant of this library. 65 Symbol_file *string `android:"path"` 66 67 // List versions to generate stubs libs for. 68 Versions []string 69 } 70 71 // set the name of the output 72 Stem *string `android:"arch_variant"` 73 74 // set suffix of the name of the output 75 Suffix *string `android:"arch_variant"` 76 77 Target struct { 78 Vendor struct { 79 // set suffix of the name of the output 80 Suffix *string `android:"arch_variant"` 81 } 82 } 83 84 // Names of modules to be overridden. Listed modules can only be other shared libraries 85 // (in Make or Soong). 86 // This does not completely prevent installation of the overridden libraries, but if both 87 // binaries would be installed by default (in PRODUCT_PACKAGES) the other library will be removed 88 // from PRODUCT_PACKAGES. 89 Overrides []string 90 91 // Properties for ABI compatibility checker 92 Header_abi_checker struct { 93 // Enable ABI checks (even if this is not an LLNDK/VNDK lib) 94 Enabled *bool 95 96 // Path to a symbol file that specifies the symbols to be included in the generated 97 // ABI dump file 98 Symbol_file *string `android:"path"` 99 100 // Symbol versions that should be ignored from the symbol file 101 Exclude_symbol_versions []string 102 103 // Symbol tags that should be ignored from the symbol file 104 Exclude_symbol_tags []string 105 } 106 107 // Order symbols in .bss section by their sizes. Only useful for shared libraries. 108 Sort_bss_symbols_by_size *bool 109 110 // Inject boringssl hash into the shared library. This is only intended for use by external/boringssl. 111 Inject_bssl_hash *bool `android:"arch_variant"` 112} 113 114type StaticProperties struct { 115 Static StaticOrSharedProperties `android:"arch_variant"` 116} 117 118type SharedProperties struct { 119 Shared StaticOrSharedProperties `android:"arch_variant"` 120} 121 122type StaticOrSharedProperties struct { 123 Srcs []string `android:"path,arch_variant"` 124 Cflags []string `android:"arch_variant"` 125 126 Enabled *bool `android:"arch_variant"` 127 Whole_static_libs []string `android:"arch_variant"` 128 Static_libs []string `android:"arch_variant"` 129 Shared_libs []string `android:"arch_variant"` 130 System_shared_libs []string `android:"arch_variant"` 131 132 Export_shared_lib_headers []string `android:"arch_variant"` 133 Export_static_lib_headers []string `android:"arch_variant"` 134 135 Apex_available []string `android:"arch_variant"` 136} 137 138type LibraryMutatedProperties struct { 139 // Build a static variant 140 BuildStatic bool `blueprint:"mutated"` 141 // Build a shared variant 142 BuildShared bool `blueprint:"mutated"` 143 // This variant is shared 144 VariantIsShared bool `blueprint:"mutated"` 145 // This variant is static 146 VariantIsStatic bool `blueprint:"mutated"` 147 148 // This variant is a stubs lib 149 BuildStubs bool `blueprint:"mutated"` 150 // Version of the stubs lib 151 StubsVersion string `blueprint:"mutated"` 152} 153 154type FlagExporterProperties struct { 155 // list of directories relative to the Blueprints file that will 156 // be added to the include path (using -I) for this module and any module that links 157 // against this module. Directories listed in export_include_dirs do not need to be 158 // listed in local_include_dirs. 159 Export_include_dirs []string `android:"arch_variant"` 160 161 // list of directories that will be added to the system include path 162 // using -isystem for this module and any module that links against this module. 163 Export_system_include_dirs []string `android:"arch_variant"` 164 165 Target struct { 166 Vendor struct { 167 // list of exported include directories, like 168 // export_include_dirs, that will be applied to the 169 // vendor variant of this library. This will overwrite 170 // any other declarations. 171 Override_export_include_dirs []string 172 } 173 } 174} 175 176func init() { 177 RegisterLibraryBuildComponents(android.InitRegistrationContext) 178} 179 180func RegisterLibraryBuildComponents(ctx android.RegistrationContext) { 181 ctx.RegisterModuleType("cc_library_static", LibraryStaticFactory) 182 ctx.RegisterModuleType("cc_library_shared", LibrarySharedFactory) 183 ctx.RegisterModuleType("cc_library", LibraryFactory) 184 ctx.RegisterModuleType("cc_library_host_static", LibraryHostStaticFactory) 185 ctx.RegisterModuleType("cc_library_host_shared", LibraryHostSharedFactory) 186} 187 188// cc_library creates both static and/or shared libraries for a device and/or 189// host. By default, a cc_library has a single variant that targets the device. 190// Specifying `host_supported: true` also creates a library that targets the 191// host. 192func LibraryFactory() android.Module { 193 module, _ := NewLibrary(android.HostAndDeviceSupported) 194 // Can be used as both a static and a shared library. 195 module.sdkMemberTypes = []android.SdkMemberType{ 196 sharedLibrarySdkMemberType, 197 staticLibrarySdkMemberType, 198 staticAndSharedLibrarySdkMemberType, 199 } 200 return module.Init() 201} 202 203// cc_library_static creates a static library for a device and/or host binary. 204func LibraryStaticFactory() android.Module { 205 module, library := NewLibrary(android.HostAndDeviceSupported) 206 library.BuildOnlyStatic() 207 module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType} 208 return module.Init() 209} 210 211// cc_library_shared creates a shared library for a device and/or host. 212func LibrarySharedFactory() android.Module { 213 module, library := NewLibrary(android.HostAndDeviceSupported) 214 library.BuildOnlyShared() 215 module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType} 216 return module.Init() 217} 218 219// cc_library_host_static creates a static library that is linkable to a host 220// binary. 221func LibraryHostStaticFactory() android.Module { 222 module, library := NewLibrary(android.HostSupported) 223 library.BuildOnlyStatic() 224 module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType} 225 return module.Init() 226} 227 228// cc_library_host_shared creates a shared library that is usable on a host. 229func LibraryHostSharedFactory() android.Module { 230 module, library := NewLibrary(android.HostSupported) 231 library.BuildOnlyShared() 232 module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType} 233 return module.Init() 234} 235 236type flagExporter struct { 237 Properties FlagExporterProperties 238 239 dirs android.Paths 240 systemDirs android.Paths 241 flags []string 242 deps android.Paths 243 headers android.Paths 244} 245 246func (f *flagExporter) exportedIncludes(ctx ModuleContext) android.Paths { 247 if ctx.useVndk() && f.Properties.Target.Vendor.Override_export_include_dirs != nil { 248 return android.PathsForModuleSrc(ctx, f.Properties.Target.Vendor.Override_export_include_dirs) 249 } else { 250 return android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs) 251 } 252} 253 254func (f *flagExporter) exportIncludes(ctx ModuleContext) { 255 f.dirs = append(f.dirs, f.exportedIncludes(ctx)...) 256 f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...) 257} 258 259func (f *flagExporter) exportIncludesAsSystem(ctx ModuleContext) { 260 // all dirs are force exported as system 261 f.systemDirs = append(f.systemDirs, f.exportedIncludes(ctx)...) 262 f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...) 263} 264 265func (f *flagExporter) reexportDirs(dirs ...android.Path) { 266 f.dirs = append(f.dirs, dirs...) 267} 268 269func (f *flagExporter) reexportSystemDirs(dirs ...android.Path) { 270 f.systemDirs = append(f.systemDirs, dirs...) 271} 272 273func (f *flagExporter) reexportFlags(flags ...string) { 274 if android.PrefixInList(flags, "-I") || android.PrefixInList(flags, "-isystem") { 275 panic(fmt.Errorf("Exporting invalid flag %q: "+ 276 "use reexportDirs or reexportSystemDirs to export directories", flag)) 277 } 278 f.flags = append(f.flags, flags...) 279} 280 281func (f *flagExporter) reexportDeps(deps ...android.Path) { 282 f.deps = append(f.deps, deps...) 283} 284 285// addExportedGeneratedHeaders does nothing but collects generated header files. 286// This can be differ to exportedDeps which may contain phony files to minimize ninja. 287func (f *flagExporter) addExportedGeneratedHeaders(headers ...android.Path) { 288 f.headers = append(f.headers, headers...) 289} 290 291func (f *flagExporter) exportedDirs() android.Paths { 292 return f.dirs 293} 294 295func (f *flagExporter) exportedSystemDirs() android.Paths { 296 return f.systemDirs 297} 298 299func (f *flagExporter) exportedFlags() []string { 300 return f.flags 301} 302 303func (f *flagExporter) exportedDeps() android.Paths { 304 return f.deps 305} 306 307func (f *flagExporter) exportedGeneratedHeaders() android.Paths { 308 return f.headers 309} 310 311type exportedFlagsProducer interface { 312 exportedDirs() android.Paths 313 exportedSystemDirs() android.Paths 314 exportedFlags() []string 315 exportedDeps() android.Paths 316 exportedGeneratedHeaders() android.Paths 317} 318 319var _ exportedFlagsProducer = (*flagExporter)(nil) 320 321// libraryDecorator wraps baseCompiler, baseLinker and baseInstaller to provide library-specific 322// functionality: static vs. shared linkage, reusing object files for shared libraries 323type libraryDecorator struct { 324 Properties LibraryProperties 325 StaticProperties StaticProperties 326 SharedProperties SharedProperties 327 MutatedProperties LibraryMutatedProperties 328 329 // For reusing static library objects for shared library 330 reuseObjects Objects 331 332 // table-of-contents file to optimize out relinking when possible 333 tocFile android.OptionalPath 334 335 flagExporter 336 stripper 337 338 // If we're used as a whole_static_lib, our missing dependencies need 339 // to be given 340 wholeStaticMissingDeps []string 341 342 // For whole_static_libs 343 objects Objects 344 345 // Uses the module's name if empty, but can be overridden. Does not include 346 // shlib suffix. 347 libName string 348 349 sabi *sabi 350 351 // Output archive of gcno coverage information files 352 coverageOutputFile android.OptionalPath 353 354 // linked Source Abi Dump 355 sAbiOutputFile android.OptionalPath 356 357 // Source Abi Diff 358 sAbiDiff android.OptionalPath 359 360 // Location of the static library in the sysroot. Empty if the library is 361 // not included in the NDK. 362 ndkSysrootPath android.Path 363 364 // Location of the linked, unstripped library for shared libraries 365 unstrippedOutputFile android.Path 366 367 // Location of the file that should be copied to dist dir when requested 368 distFile android.OptionalPath 369 370 versionScriptPath android.ModuleGenPath 371 372 post_install_cmds []string 373 374 // If useCoreVariant is true, the vendor variant of a VNDK library is 375 // not installed. 376 useCoreVariant bool 377 checkSameCoreVariant bool 378 379 // Decorated interfaces 380 *baseCompiler 381 *baseLinker 382 *baseInstaller 383 384 collectedSnapshotHeaders android.Paths 385} 386 387// collectHeadersForSnapshot collects all exported headers from library. 388// It globs header files in the source tree for exported include directories, 389// and tracks generated header files separately. 390// 391// This is to be called from GenerateAndroidBuildActions, and then collected 392// header files can be retrieved by snapshotHeaders(). 393func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext) { 394 ret := android.Paths{} 395 396 // Headers in the source tree should be globbed. On the contrast, generated headers 397 // can't be globbed, and they should be manually collected. 398 // So, we first filter out intermediate directories (which contains generated headers) 399 // from exported directories, and then glob headers under remaining directories. 400 for _, path := range append(l.exportedDirs(), l.exportedSystemDirs()...) { 401 dir := path.String() 402 // Skip if dir is for generated headers 403 if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) { 404 continue 405 } 406 // libeigen wrongly exports the root directory "external/eigen". But only two 407 // subdirectories "Eigen" and "unsupported" contain exported header files. Even worse 408 // some of them have no extension. So we need special treatment for libeigen in order 409 // to glob correctly. 410 if dir == "external/eigen" { 411 // Only these two directories contains exported headers. 412 for _, subdir := range []string{"Eigen", "unsupported/Eigen"} { 413 glob, err := ctx.GlobWithDeps("external/eigen/"+subdir+"/**/*", nil) 414 if err != nil { 415 ctx.ModuleErrorf("glob failed: %#v", err) 416 return 417 } 418 for _, header := range glob { 419 if strings.HasSuffix(header, "/") { 420 continue 421 } 422 ext := filepath.Ext(header) 423 if ext != "" && ext != ".h" { 424 continue 425 } 426 ret = append(ret, android.PathForSource(ctx, header)) 427 } 428 } 429 continue 430 } 431 exts := headerExts 432 // Glob all files under this special directory, because of C++ headers. 433 if strings.HasPrefix(dir, "external/libcxx/include") { 434 exts = []string{""} 435 } 436 for _, ext := range exts { 437 glob, err := ctx.GlobWithDeps(dir+"/**/*"+ext, nil) 438 if err != nil { 439 ctx.ModuleErrorf("glob failed: %#v", err) 440 return 441 } 442 for _, header := range glob { 443 if strings.HasSuffix(header, "/") { 444 continue 445 } 446 ret = append(ret, android.PathForSource(ctx, header)) 447 } 448 } 449 } 450 451 // Collect generated headers 452 for _, header := range append(l.exportedGeneratedHeaders(), l.exportedDeps()...) { 453 // TODO(b/148123511): remove exportedDeps after cleaning up genrule 454 if strings.HasSuffix(header.Base(), "-phony") { 455 continue 456 } 457 ret = append(ret, header) 458 } 459 460 l.collectedSnapshotHeaders = ret 461} 462 463// This returns all exported header files, both generated ones and headers from source tree. 464// collectHeadersForSnapshot() must be called before calling this. 465func (l *libraryDecorator) snapshotHeaders() android.Paths { 466 if l.collectedSnapshotHeaders == nil { 467 panic("snapshotHeaders() must be called after collectHeadersForSnapshot()") 468 } 469 return l.collectedSnapshotHeaders 470} 471 472func (library *libraryDecorator) linkerProps() []interface{} { 473 var props []interface{} 474 props = append(props, library.baseLinker.linkerProps()...) 475 props = append(props, 476 &library.Properties, 477 &library.MutatedProperties, 478 &library.flagExporter.Properties, 479 &library.stripper.StripProperties) 480 481 if library.MutatedProperties.BuildShared { 482 props = append(props, &library.SharedProperties) 483 } 484 if library.MutatedProperties.BuildStatic { 485 props = append(props, &library.StaticProperties) 486 } 487 488 return props 489} 490 491func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { 492 flags = library.baseLinker.linkerFlags(ctx, flags) 493 494 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because 495 // all code is position independent, and then those warnings get promoted to 496 // errors. 497 if !ctx.Windows() { 498 flags.Global.CFlags = append(flags.Global.CFlags, "-fPIC") 499 } 500 501 if library.static() { 502 flags.Local.CFlags = append(flags.Local.CFlags, library.StaticProperties.Static.Cflags...) 503 } else if library.shared() { 504 flags.Local.CFlags = append(flags.Local.CFlags, library.SharedProperties.Shared.Cflags...) 505 } 506 507 if library.shared() { 508 libName := library.getLibName(ctx) 509 var f []string 510 if ctx.toolchain().Bionic() { 511 f = append(f, 512 "-nostdlib", 513 "-Wl,--gc-sections", 514 ) 515 } 516 517 if ctx.Darwin() { 518 f = append(f, 519 "-dynamiclib", 520 "-single_module", 521 "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(), 522 ) 523 if ctx.Arch().ArchType == android.X86 { 524 f = append(f, 525 "-read_only_relocs suppress", 526 ) 527 } 528 } else { 529 f = append(f, "-shared") 530 if !ctx.Windows() { 531 f = append(f, "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix()) 532 } 533 } 534 535 flags.Global.LdFlags = append(flags.Global.LdFlags, f...) 536 } 537 538 return flags 539} 540 541func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags { 542 exportIncludeDirs := library.flagExporter.exportedIncludes(ctx) 543 if len(exportIncludeDirs) > 0 { 544 f := includeDirsToFlags(exportIncludeDirs) 545 flags.Local.CommonFlags = append(flags.Local.CommonFlags, f) 546 flags.Local.YasmFlags = append(flags.Local.YasmFlags, f) 547 } 548 549 flags = library.baseCompiler.compilerFlags(ctx, flags, deps) 550 if library.buildStubs() { 551 // Remove -include <file> when compiling stubs. Otherwise, the force included 552 // headers might cause conflicting types error with the symbols in the 553 // generated stubs source code. e.g. 554 // double acos(double); // in header 555 // void acos() {} // in the generated source code 556 removeInclude := func(flags []string) []string { 557 ret := flags[:0] 558 for _, f := range flags { 559 if strings.HasPrefix(f, "-include ") { 560 continue 561 } 562 ret = append(ret, f) 563 } 564 return ret 565 } 566 flags.Local.CommonFlags = removeInclude(flags.Local.CommonFlags) 567 flags.Local.CFlags = removeInclude(flags.Local.CFlags) 568 569 flags = addStubLibraryCompilerFlags(flags) 570 } 571 return flags 572} 573 574// Returns a string that represents the class of the ABI dump. 575// Returns an empty string if ABI check is disabled for this library. 576func (library *libraryDecorator) classifySourceAbiDump(ctx ModuleContext) string { 577 enabled := library.Properties.Header_abi_checker.Enabled 578 if enabled != nil && !Bool(enabled) { 579 return "" 580 } 581 // Return NDK if the library is both NDK and LLNDK. 582 if ctx.isNdk() { 583 return "NDK" 584 } 585 if ctx.isLlndkPublic(ctx.Config()) { 586 return "LLNDK" 587 } 588 if ctx.useVndk() && ctx.isVndk() && !ctx.isVndkPrivate(ctx.Config()) { 589 if ctx.isVndkSp() { 590 if ctx.isVndkExt() { 591 return "VNDK-SP-ext" 592 } else { 593 return "VNDK-SP" 594 } 595 } else { 596 if ctx.isVndkExt() { 597 return "VNDK-ext" 598 } else { 599 return "VNDK-core" 600 } 601 } 602 } 603 if Bool(enabled) || ctx.hasStubsVariants() { 604 return "PLATFORM" 605 } 606 return "" 607} 608 609func (library *libraryDecorator) shouldCreateSourceAbiDump(ctx ModuleContext) bool { 610 if !ctx.shouldCreateSourceAbiDump() { 611 return false 612 } 613 if !ctx.isForPlatform() { 614 if !ctx.hasStubsVariants() { 615 // Skip ABI checks if this library is for APEX but isn't exported. 616 return false 617 } 618 if !Bool(library.Properties.Header_abi_checker.Enabled) { 619 // Skip ABI checks if this library is for APEX and did not explicitly enable 620 // ABI checks. 621 // TODO(b/145608479): ABI checks should be enabled by default. Remove this 622 // after evaluating the extra build time. 623 return false 624 } 625 } 626 return library.classifySourceAbiDump(ctx) != "" 627} 628 629func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { 630 if library.buildStubs() { 631 objs, versionScript := compileStubLibrary(ctx, flags, String(library.Properties.Stubs.Symbol_file), library.MutatedProperties.StubsVersion, "--apex") 632 library.versionScriptPath = versionScript 633 return objs 634 } 635 636 if !library.buildShared() && !library.buildStatic() { 637 if len(library.baseCompiler.Properties.Srcs) > 0 { 638 ctx.PropertyErrorf("srcs", "cc_library_headers must not have any srcs") 639 } 640 if len(library.StaticProperties.Static.Srcs) > 0 { 641 ctx.PropertyErrorf("static.srcs", "cc_library_headers must not have any srcs") 642 } 643 if len(library.SharedProperties.Shared.Srcs) > 0 { 644 ctx.PropertyErrorf("shared.srcs", "cc_library_headers must not have any srcs") 645 } 646 return Objects{} 647 } 648 if library.shouldCreateSourceAbiDump(ctx) || library.sabi.Properties.CreateSAbiDumps { 649 exportIncludeDirs := library.flagExporter.exportedIncludes(ctx) 650 var SourceAbiFlags []string 651 for _, dir := range exportIncludeDirs.Strings() { 652 SourceAbiFlags = append(SourceAbiFlags, "-I"+dir) 653 } 654 for _, reexportedInclude := range library.sabi.Properties.ReexportedIncludes { 655 SourceAbiFlags = append(SourceAbiFlags, "-I"+reexportedInclude) 656 } 657 flags.SAbiFlags = SourceAbiFlags 658 total_length := len(library.baseCompiler.Properties.Srcs) + len(deps.GeneratedSources) + 659 len(library.SharedProperties.Shared.Srcs) + len(library.StaticProperties.Static.Srcs) 660 if total_length > 0 { 661 flags.SAbiDump = true 662 } 663 } 664 objs := library.baseCompiler.compile(ctx, flags, deps) 665 library.reuseObjects = objs 666 buildFlags := flagsToBuilderFlags(flags) 667 668 if library.static() { 669 srcs := android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Srcs) 670 objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceStaticLibrary, 671 srcs, library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps)) 672 } else if library.shared() { 673 srcs := android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Srcs) 674 objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceSharedLibrary, 675 srcs, library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps)) 676 } 677 678 return objs 679} 680 681type libraryInterface interface { 682 getWholeStaticMissingDeps() []string 683 static() bool 684 shared() bool 685 objs() Objects 686 reuseObjs() (Objects, exportedFlagsProducer) 687 toc() android.OptionalPath 688 689 // Returns true if the build options for the module have selected a static or shared build 690 buildStatic() bool 691 buildShared() bool 692 693 // Sets whether a specific variant is static or shared 694 setStatic() 695 setShared() 696 697 // Write LOCAL_ADDITIONAL_DEPENDENCIES for ABI diff 698 androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) 699 700 availableFor(string) bool 701} 702 703func (library *libraryDecorator) getLibNameHelper(baseModuleName string, useVndk bool) string { 704 name := library.libName 705 if name == "" { 706 name = String(library.Properties.Stem) 707 if name == "" { 708 name = baseModuleName 709 } 710 } 711 712 suffix := "" 713 if useVndk { 714 suffix = String(library.Properties.Target.Vendor.Suffix) 715 } 716 if suffix == "" { 717 suffix = String(library.Properties.Suffix) 718 } 719 720 return name + suffix 721} 722 723func (library *libraryDecorator) getLibName(ctx BaseModuleContext) string { 724 name := library.getLibNameHelper(ctx.baseModuleName(), ctx.useVndk()) 725 726 if ctx.isVndkExt() { 727 // vndk-ext lib should have the same name with original lib 728 ctx.VisitDirectDepsWithTag(vndkExtDepTag, func(module android.Module) { 729 originalName := module.(*Module).outputFile.Path() 730 name = strings.TrimSuffix(originalName.Base(), originalName.Ext()) 731 }) 732 } 733 734 if ctx.Host() && Bool(library.Properties.Unique_host_soname) { 735 if !strings.HasSuffix(name, "-host") { 736 name = name + "-host" 737 } 738 } 739 740 return name 741} 742 743var versioningMacroNamesListMutex sync.Mutex 744 745func (library *libraryDecorator) linkerInit(ctx BaseModuleContext) { 746 location := InstallInSystem 747 if library.baseLinker.sanitize.inSanitizerDir() { 748 location = InstallInSanitizerDir 749 } 750 library.baseInstaller.location = location 751 library.baseLinker.linkerInit(ctx) 752 // Let baseLinker know whether this variant is for stubs or not, so that 753 // it can omit things that are not required for linking stubs. 754 library.baseLinker.dynamicProperties.BuildStubs = library.buildStubs() 755 756 if library.buildStubs() { 757 macroNames := versioningMacroNamesList(ctx.Config()) 758 myName := versioningMacroName(ctx.ModuleName()) 759 versioningMacroNamesListMutex.Lock() 760 defer versioningMacroNamesListMutex.Unlock() 761 if (*macroNames)[myName] == "" { 762 (*macroNames)[myName] = ctx.ModuleName() 763 } else if (*macroNames)[myName] != ctx.ModuleName() { 764 ctx.ModuleErrorf("Macro name %q for versioning conflicts with macro name from module %q ", myName, (*macroNames)[myName]) 765 } 766 } 767} 768 769func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { 770 deps = library.baseCompiler.compilerDeps(ctx, deps) 771 772 return deps 773} 774 775func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { 776 if library.static() { 777 // Compare with nil because an empty list needs to be propagated. 778 if library.StaticProperties.Static.System_shared_libs != nil { 779 library.baseLinker.Properties.System_shared_libs = library.StaticProperties.Static.System_shared_libs 780 } 781 } else if library.shared() { 782 // Compare with nil because an empty list needs to be propagated. 783 if library.SharedProperties.Shared.System_shared_libs != nil { 784 library.baseLinker.Properties.System_shared_libs = library.SharedProperties.Shared.System_shared_libs 785 } 786 } 787 788 deps = library.baseLinker.linkerDeps(ctx, deps) 789 790 if library.static() { 791 deps.WholeStaticLibs = append(deps.WholeStaticLibs, 792 library.StaticProperties.Static.Whole_static_libs...) 793 deps.StaticLibs = append(deps.StaticLibs, library.StaticProperties.Static.Static_libs...) 794 deps.SharedLibs = append(deps.SharedLibs, library.StaticProperties.Static.Shared_libs...) 795 796 deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.StaticProperties.Static.Export_shared_lib_headers...) 797 deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.StaticProperties.Static.Export_static_lib_headers...) 798 } else if library.shared() { 799 if ctx.toolchain().Bionic() && !Bool(library.baseLinker.Properties.Nocrt) { 800 if !ctx.useSdk() { 801 deps.CrtBegin = "crtbegin_so" 802 deps.CrtEnd = "crtend_so" 803 } else { 804 // TODO(danalbert): Add generation of crt objects. 805 // For `sdk_version: "current"`, we don't actually have a 806 // freshly generated set of CRT objects. Use the last stable 807 // version. 808 version := ctx.sdkVersion() 809 if version == "current" { 810 version = getCurrentNdkPrebuiltVersion(ctx) 811 } 812 deps.CrtBegin = "ndk_crtbegin_so." + version 813 deps.CrtEnd = "ndk_crtend_so." + version 814 } 815 } 816 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.SharedProperties.Shared.Whole_static_libs...) 817 deps.StaticLibs = append(deps.StaticLibs, library.SharedProperties.Shared.Static_libs...) 818 deps.SharedLibs = append(deps.SharedLibs, library.SharedProperties.Shared.Shared_libs...) 819 820 deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.SharedProperties.Shared.Export_shared_lib_headers...) 821 deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.SharedProperties.Shared.Export_static_lib_headers...) 822 } 823 if ctx.useVndk() { 824 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs) 825 deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs) 826 deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs) 827 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs) 828 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs) 829 } 830 if ctx.inRecovery() { 831 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs) 832 deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Recovery.Exclude_shared_libs) 833 deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs) 834 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Recovery.Exclude_shared_libs) 835 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs) 836 } 837 if ctx.inRamdisk() { 838 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs) 839 deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_shared_libs) 840 deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs) 841 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Ramdisk.Exclude_shared_libs) 842 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs) 843 } 844 845 return deps 846} 847 848func (library *libraryDecorator) linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps { 849 specifiedDeps = library.baseLinker.linkerSpecifiedDeps(specifiedDeps) 850 var properties StaticOrSharedProperties 851 if library.static() { 852 properties = library.StaticProperties.Static 853 } else if library.shared() { 854 properties = library.SharedProperties.Shared 855 } 856 857 specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, properties.Shared_libs...) 858 859 // Must distinguish nil and [] in system_shared_libs - ensure that [] in 860 // either input list doesn't come out as nil. 861 if specifiedDeps.systemSharedLibs == nil { 862 specifiedDeps.systemSharedLibs = properties.System_shared_libs 863 } else { 864 specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, properties.System_shared_libs...) 865 } 866 867 specifiedDeps.sharedLibs = android.FirstUniqueStrings(specifiedDeps.sharedLibs) 868 if len(specifiedDeps.systemSharedLibs) > 0 { 869 // Skip this if systemSharedLibs is either nil or [], to ensure they are 870 // retained. 871 specifiedDeps.systemSharedLibs = android.FirstUniqueStrings(specifiedDeps.systemSharedLibs) 872 } 873 return specifiedDeps 874} 875 876func (library *libraryDecorator) linkStatic(ctx ModuleContext, 877 flags Flags, deps PathDeps, objs Objects) android.Path { 878 879 library.objects = deps.WholeStaticLibObjs.Copy() 880 library.objects = library.objects.Append(objs) 881 882 fileName := ctx.ModuleName() + staticLibraryExtension 883 outputFile := android.PathForModuleOut(ctx, fileName) 884 builderFlags := flagsToBuilderFlags(flags) 885 886 if Bool(library.baseLinker.Properties.Use_version_lib) { 887 if ctx.Host() { 888 versionedOutputFile := outputFile 889 outputFile = android.PathForModuleOut(ctx, "unversioned", fileName) 890 library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) 891 } else { 892 versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName) 893 library.distFile = android.OptionalPathForPath(versionedOutputFile) 894 library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) 895 } 896 } 897 898 TransformObjToStaticLib(ctx, library.objects.objFiles, builderFlags, outputFile, objs.tidyFiles) 899 900 library.coverageOutputFile = TransformCoverageFilesToZip(ctx, library.objects, ctx.ModuleName()) 901 902 library.wholeStaticMissingDeps = ctx.GetMissingDependencies() 903 904 ctx.CheckbuildFile(outputFile) 905 906 return outputFile 907} 908 909func (library *libraryDecorator) linkShared(ctx ModuleContext, 910 flags Flags, deps PathDeps, objs Objects) android.Path { 911 912 var linkerDeps android.Paths 913 linkerDeps = append(linkerDeps, flags.LdFlagsDeps...) 914 915 unexportedSymbols := ctx.ExpandOptionalSource(library.Properties.Unexported_symbols_list, "unexported_symbols_list") 916 forceNotWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_not_weak_list, "force_symbols_not_weak_list") 917 forceWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_weak_list, "force_symbols_weak_list") 918 if !ctx.Darwin() { 919 if unexportedSymbols.Valid() { 920 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin") 921 } 922 if forceNotWeakSymbols.Valid() { 923 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin") 924 } 925 if forceWeakSymbols.Valid() { 926 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin") 927 } 928 } else { 929 if unexportedSymbols.Valid() { 930 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String()) 931 linkerDeps = append(linkerDeps, unexportedSymbols.Path()) 932 } 933 if forceNotWeakSymbols.Valid() { 934 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String()) 935 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path()) 936 } 937 if forceWeakSymbols.Valid() { 938 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String()) 939 linkerDeps = append(linkerDeps, forceWeakSymbols.Path()) 940 } 941 } 942 if library.buildStubs() { 943 linkerScriptFlags := "-Wl,--version-script," + library.versionScriptPath.String() 944 flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlags) 945 linkerDeps = append(linkerDeps, library.versionScriptPath) 946 } 947 948 fileName := library.getLibName(ctx) + flags.Toolchain.ShlibSuffix() 949 outputFile := android.PathForModuleOut(ctx, fileName) 950 ret := outputFile 951 952 var implicitOutputs android.WritablePaths 953 if ctx.Windows() { 954 importLibraryPath := android.PathForModuleOut(ctx, pathtools.ReplaceExtension(fileName, "lib")) 955 956 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--out-implib="+importLibraryPath.String()) 957 implicitOutputs = append(implicitOutputs, importLibraryPath) 958 } 959 960 builderFlags := flagsToBuilderFlags(flags) 961 962 // Optimize out relinking against shared libraries whose interface hasn't changed by 963 // depending on a table of contents file instead of the library itself. 964 tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.ShlibSuffix()[1:]+".toc") 965 library.tocFile = android.OptionalPathForPath(tocFile) 966 TransformSharedObjectToToc(ctx, outputFile, tocFile, builderFlags) 967 968 if library.stripper.needsStrip(ctx) { 969 if ctx.Darwin() { 970 builderFlags.stripUseGnuStrip = true 971 } 972 strippedOutputFile := outputFile 973 outputFile = android.PathForModuleOut(ctx, "unstripped", fileName) 974 library.stripper.stripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, builderFlags) 975 } 976 library.unstrippedOutputFile = outputFile 977 978 outputFile = maybeInjectBoringSSLHash(ctx, outputFile, library.Properties.Inject_bssl_hash, fileName) 979 980 if Bool(library.baseLinker.Properties.Use_version_lib) { 981 if ctx.Host() { 982 versionedOutputFile := outputFile 983 outputFile = android.PathForModuleOut(ctx, "unversioned", fileName) 984 library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) 985 } else { 986 versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName) 987 library.distFile = android.OptionalPathForPath(versionedOutputFile) 988 989 if library.stripper.needsStrip(ctx) { 990 out := android.PathForModuleOut(ctx, "versioned-stripped", fileName) 991 library.distFile = android.OptionalPathForPath(out) 992 library.stripper.stripExecutableOrSharedLib(ctx, versionedOutputFile, out, builderFlags) 993 } 994 995 library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) 996 } 997 } 998 999 sharedLibs := deps.EarlySharedLibs 1000 sharedLibs = append(sharedLibs, deps.SharedLibs...) 1001 sharedLibs = append(sharedLibs, deps.LateSharedLibs...) 1002 1003 linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...) 1004 linkerDeps = append(linkerDeps, deps.SharedLibsDeps...) 1005 linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...) 1006 linkerDeps = append(linkerDeps, objs.tidyFiles...) 1007 1008 if Bool(library.Properties.Sort_bss_symbols_by_size) { 1009 unsortedOutputFile := android.PathForModuleOut(ctx, "unsorted", fileName) 1010 TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, 1011 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, 1012 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, unsortedOutputFile, implicitOutputs) 1013 1014 symbolOrderingFile := android.PathForModuleOut(ctx, "unsorted", fileName+".symbol_order") 1015 symbolOrderingFlag := library.baseLinker.sortBssSymbolsBySize(ctx, unsortedOutputFile, symbolOrderingFile, builderFlags) 1016 builderFlags.localLdFlags += " " + symbolOrderingFlag 1017 linkerDeps = append(linkerDeps, symbolOrderingFile) 1018 } 1019 1020 TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, 1021 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, 1022 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs) 1023 1024 objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...) 1025 objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...) 1026 1027 objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.StaticLibObjs.sAbiDumpFiles...) 1028 objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.WholeStaticLibObjs.sAbiDumpFiles...) 1029 1030 library.coverageOutputFile = TransformCoverageFilesToZip(ctx, objs, library.getLibName(ctx)) 1031 library.linkSAbiDumpFiles(ctx, objs, fileName, ret) 1032 1033 return ret 1034} 1035 1036func (library *libraryDecorator) unstrippedOutputFilePath() android.Path { 1037 return library.unstrippedOutputFile 1038} 1039 1040func (library *libraryDecorator) nativeCoverage() bool { 1041 if library.header() || library.buildStubs() { 1042 return false 1043 } 1044 return true 1045} 1046 1047func (library *libraryDecorator) coverageOutputFilePath() android.OptionalPath { 1048 return library.coverageOutputFile 1049} 1050 1051func getRefAbiDumpFile(ctx ModuleContext, vndkVersion, fileName string) android.Path { 1052 // The logic must be consistent with classifySourceAbiDump. 1053 isNdk := ctx.isNdk() 1054 isLlndkOrVndk := ctx.isLlndkPublic(ctx.Config()) || (ctx.useVndk() && ctx.isVndk()) 1055 1056 refAbiDumpTextFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, false) 1057 refAbiDumpGzipFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, true) 1058 1059 if refAbiDumpTextFile.Valid() { 1060 if refAbiDumpGzipFile.Valid() { 1061 ctx.ModuleErrorf( 1062 "Two reference ABI dump files are found: %q and %q. Please delete the stale one.", 1063 refAbiDumpTextFile, refAbiDumpGzipFile) 1064 return nil 1065 } 1066 return refAbiDumpTextFile.Path() 1067 } 1068 if refAbiDumpGzipFile.Valid() { 1069 return UnzipRefDump(ctx, refAbiDumpGzipFile.Path(), fileName) 1070 } 1071 return nil 1072} 1073 1074func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) { 1075 if library.shouldCreateSourceAbiDump(ctx) { 1076 vndkVersion := ctx.DeviceConfig().PlatformVndkVersion() 1077 if ver := ctx.DeviceConfig().VndkVersion(); ver != "" && ver != "current" { 1078 vndkVersion = ver 1079 } 1080 1081 exportIncludeDirs := library.flagExporter.exportedIncludes(ctx) 1082 var SourceAbiFlags []string 1083 for _, dir := range exportIncludeDirs.Strings() { 1084 SourceAbiFlags = append(SourceAbiFlags, "-I"+dir) 1085 } 1086 for _, reexportedInclude := range library.sabi.Properties.ReexportedIncludes { 1087 SourceAbiFlags = append(SourceAbiFlags, "-I"+reexportedInclude) 1088 } 1089 exportedHeaderFlags := strings.Join(SourceAbiFlags, " ") 1090 library.sAbiOutputFile = TransformDumpToLinkedDump(ctx, objs.sAbiDumpFiles, soFile, fileName, exportedHeaderFlags, 1091 android.OptionalPathForModuleSrc(ctx, library.symbolFileForAbiCheck(ctx)), 1092 library.Properties.Header_abi_checker.Exclude_symbol_versions, 1093 library.Properties.Header_abi_checker.Exclude_symbol_tags) 1094 1095 addLsdumpPath(library.classifySourceAbiDump(ctx) + ":" + library.sAbiOutputFile.String()) 1096 1097 refAbiDumpFile := getRefAbiDumpFile(ctx, vndkVersion, fileName) 1098 if refAbiDumpFile != nil { 1099 library.sAbiDiff = SourceAbiDiff(ctx, library.sAbiOutputFile.Path(), 1100 refAbiDumpFile, fileName, exportedHeaderFlags, ctx.isLlndk(ctx.Config()), ctx.isNdk(), ctx.isVndkExt()) 1101 } 1102 } 1103} 1104 1105func (library *libraryDecorator) link(ctx ModuleContext, 1106 flags Flags, deps PathDeps, objs Objects) android.Path { 1107 1108 objs = deps.Objs.Copy().Append(objs) 1109 var out android.Path 1110 if library.static() || library.header() { 1111 out = library.linkStatic(ctx, flags, deps, objs) 1112 } else { 1113 out = library.linkShared(ctx, flags, deps, objs) 1114 } 1115 1116 library.exportIncludes(ctx) 1117 library.reexportDirs(deps.ReexportedDirs...) 1118 library.reexportSystemDirs(deps.ReexportedSystemDirs...) 1119 library.reexportFlags(deps.ReexportedFlags...) 1120 library.reexportDeps(deps.ReexportedDeps...) 1121 library.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...) 1122 1123 if Bool(library.Properties.Aidl.Export_aidl_headers) { 1124 if library.baseCompiler.hasSrcExt(".aidl") { 1125 dir := android.PathForModuleGen(ctx, "aidl") 1126 library.reexportDirs(dir) 1127 1128 // TODO: restrict to aidl deps 1129 library.reexportDeps(library.baseCompiler.pathDeps...) 1130 library.addExportedGeneratedHeaders(library.baseCompiler.pathDeps...) 1131 } 1132 } 1133 1134 if Bool(library.Properties.Proto.Export_proto_headers) { 1135 if library.baseCompiler.hasSrcExt(".proto") { 1136 var includes android.Paths 1137 if flags.proto.CanonicalPathFromRoot { 1138 includes = append(includes, flags.proto.SubDir) 1139 } 1140 includes = append(includes, flags.proto.Dir) 1141 library.reexportDirs(includes...) 1142 1143 // TODO: restrict to proto deps 1144 library.reexportDeps(library.baseCompiler.pathDeps...) 1145 library.addExportedGeneratedHeaders(library.baseCompiler.pathDeps...) 1146 } 1147 } 1148 1149 if library.baseCompiler.hasSrcExt(".sysprop") { 1150 dir := android.PathForModuleGen(ctx, "sysprop", "include") 1151 if library.Properties.Sysprop.Platform != nil { 1152 isProduct := ctx.ProductSpecific() && !ctx.useVndk() 1153 isVendor := ctx.useVndk() 1154 isOwnerPlatform := Bool(library.Properties.Sysprop.Platform) 1155 1156 if !ctx.inRamdisk() && !ctx.inRecovery() && (isProduct || (isOwnerPlatform == isVendor)) { 1157 dir = android.PathForModuleGen(ctx, "sysprop/public", "include") 1158 } 1159 } 1160 1161 library.reexportDirs(dir) 1162 library.reexportDeps(library.baseCompiler.pathDeps...) 1163 library.addExportedGeneratedHeaders(library.baseCompiler.pathDeps...) 1164 } 1165 1166 if library.buildStubs() { 1167 library.reexportFlags("-D" + versioningMacroName(ctx.ModuleName()) + "=" + library.stubsVersion()) 1168 } 1169 1170 return out 1171} 1172 1173func (library *libraryDecorator) buildStatic() bool { 1174 return library.MutatedProperties.BuildStatic && 1175 BoolDefault(library.StaticProperties.Static.Enabled, true) 1176} 1177 1178func (library *libraryDecorator) buildShared() bool { 1179 return library.MutatedProperties.BuildShared && 1180 BoolDefault(library.SharedProperties.Shared.Enabled, true) 1181} 1182 1183func (library *libraryDecorator) getWholeStaticMissingDeps() []string { 1184 return append([]string(nil), library.wholeStaticMissingDeps...) 1185} 1186 1187func (library *libraryDecorator) objs() Objects { 1188 return library.objects 1189} 1190 1191func (library *libraryDecorator) reuseObjs() (Objects, exportedFlagsProducer) { 1192 return library.reuseObjects, &library.flagExporter 1193} 1194 1195func (library *libraryDecorator) toc() android.OptionalPath { 1196 return library.tocFile 1197} 1198 1199func (library *libraryDecorator) installSymlinkToRuntimeApex(ctx ModuleContext, file android.Path) { 1200 dir := library.baseInstaller.installDir(ctx) 1201 dirOnDevice := android.InstallPathToOnDevicePath(ctx, dir) 1202 target := "/" + filepath.Join("apex", "com.android.runtime", dir.Base(), "bionic", file.Base()) 1203 ctx.InstallAbsoluteSymlink(dir, file.Base(), target) 1204 library.post_install_cmds = append(library.post_install_cmds, makeSymlinkCmd(dirOnDevice, file.Base(), target)) 1205} 1206 1207func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) { 1208 if library.shared() { 1209 if ctx.Device() && ctx.useVndk() { 1210 if ctx.isVndkSp() { 1211 library.baseInstaller.subDir = "vndk-sp" 1212 } else if ctx.isVndk() { 1213 mayUseCoreVariant := true 1214 1215 if ctx.mustUseVendorVariant() { 1216 mayUseCoreVariant = false 1217 } 1218 1219 if ctx.isVndkExt() { 1220 mayUseCoreVariant = false 1221 } 1222 1223 if ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) && ctx.Arch().ArchType == android.Arm64 { 1224 mayUseCoreVariant = false 1225 } 1226 1227 if mayUseCoreVariant { 1228 library.checkSameCoreVariant = true 1229 if ctx.DeviceConfig().VndkUseCoreVariant() { 1230 library.useCoreVariant = true 1231 } 1232 } 1233 library.baseInstaller.subDir = "vndk" 1234 } 1235 1236 // Append a version to vndk or vndk-sp directories on the system partition. 1237 if ctx.isVndk() && !ctx.isVndkExt() { 1238 vndkVersion := ctx.DeviceConfig().PlatformVndkVersion() 1239 if vndkVersion != "current" && vndkVersion != "" { 1240 library.baseInstaller.subDir += "-" + vndkVersion 1241 } 1242 } 1243 } else if len(library.Properties.Stubs.Versions) > 0 && android.DirectlyInAnyApex(ctx, ctx.ModuleName()) { 1244 // Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory. 1245 // The original path becomes a symlink to the corresponding file in the 1246 // runtime APEX. 1247 translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled 1248 if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() && !translatedArch && !ctx.inRamdisk() && !ctx.inRecovery() { 1249 if ctx.Device() { 1250 library.installSymlinkToRuntimeApex(ctx, file) 1251 } 1252 library.baseInstaller.subDir = "bootstrap" 1253 } 1254 } else if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && ctx.isLlndk(ctx.Config()) && !isBionic(ctx.baseModuleName()) { 1255 // Skip installing LLNDK (non-bionic) libraries moved to APEX. 1256 ctx.Module().SkipInstall() 1257 } 1258 1259 library.baseInstaller.install(ctx, file) 1260 } 1261 1262 if Bool(library.Properties.Static_ndk_lib) && library.static() && 1263 !ctx.useVndk() && !ctx.inRamdisk() && !ctx.inRecovery() && ctx.Device() && 1264 library.baseLinker.sanitize.isUnsanitizedVariant() && 1265 !library.buildStubs() && ctx.sdkVersion() == "" { 1266 installPath := getNdkSysrootBase(ctx).Join( 1267 ctx, "usr/lib", config.NDKTriple(ctx.toolchain()), file.Base()) 1268 1269 ctx.ModuleBuild(pctx, android.ModuleBuildParams{ 1270 Rule: android.Cp, 1271 Description: "install " + installPath.Base(), 1272 Output: installPath, 1273 Input: file, 1274 }) 1275 1276 library.ndkSysrootPath = installPath 1277 } 1278} 1279 1280func (library *libraryDecorator) everInstallable() bool { 1281 // Only shared and static libraries are installed. Header libraries (which are 1282 // neither static or shared) are not installed. 1283 return library.shared() || library.static() 1284} 1285 1286func (library *libraryDecorator) static() bool { 1287 return library.MutatedProperties.VariantIsStatic 1288} 1289 1290func (library *libraryDecorator) shared() bool { 1291 return library.MutatedProperties.VariantIsShared 1292} 1293 1294func (library *libraryDecorator) header() bool { 1295 return !library.static() && !library.shared() 1296} 1297 1298func (library *libraryDecorator) setStatic() { 1299 library.MutatedProperties.VariantIsStatic = true 1300 library.MutatedProperties.VariantIsShared = false 1301} 1302 1303func (library *libraryDecorator) setShared() { 1304 library.MutatedProperties.VariantIsStatic = false 1305 library.MutatedProperties.VariantIsShared = true 1306} 1307 1308func (library *libraryDecorator) BuildOnlyStatic() { 1309 library.MutatedProperties.BuildShared = false 1310} 1311 1312func (library *libraryDecorator) BuildOnlyShared() { 1313 library.MutatedProperties.BuildStatic = false 1314} 1315 1316func (library *libraryDecorator) HeaderOnly() { 1317 library.MutatedProperties.BuildShared = false 1318 library.MutatedProperties.BuildStatic = false 1319} 1320 1321func (library *libraryDecorator) buildStubs() bool { 1322 return library.MutatedProperties.BuildStubs 1323} 1324 1325func (library *libraryDecorator) symbolFileForAbiCheck(ctx ModuleContext) *string { 1326 if library.Properties.Header_abi_checker.Symbol_file != nil { 1327 return library.Properties.Header_abi_checker.Symbol_file 1328 } 1329 if ctx.hasStubsVariants() && library.Properties.Stubs.Symbol_file != nil { 1330 return library.Properties.Stubs.Symbol_file 1331 } 1332 return nil 1333} 1334 1335func (library *libraryDecorator) stubsVersion() string { 1336 return library.MutatedProperties.StubsVersion 1337} 1338 1339func (library *libraryDecorator) isLatestStubVersion() bool { 1340 versions := library.Properties.Stubs.Versions 1341 return versions[len(versions)-1] == library.stubsVersion() 1342} 1343 1344func (library *libraryDecorator) availableFor(what string) bool { 1345 var list []string 1346 if library.static() { 1347 list = library.StaticProperties.Static.Apex_available 1348 } else if library.shared() { 1349 list = library.SharedProperties.Shared.Apex_available 1350 } 1351 if len(list) == 0 { 1352 return false 1353 } 1354 return android.CheckAvailableForApex(what, list) 1355} 1356 1357func (library *libraryDecorator) skipInstall(mod *Module) { 1358 if library.static() && library.buildStatic() && !library.buildStubs() { 1359 // If we're asked to skip installation of a static library (in particular 1360 // when it's not //apex_available:platform) we still want an AndroidMk entry 1361 // for it to ensure we get the relevant NOTICE file targets (cf. 1362 // notice_files.mk) that other libraries might depend on. AndroidMkEntries 1363 // always sets LOCAL_UNINSTALLABLE_MODULE for these entries. 1364 return 1365 } 1366 mod.ModuleBase.SkipInstall() 1367} 1368 1369var versioningMacroNamesListKey = android.NewOnceKey("versioningMacroNamesList") 1370 1371func versioningMacroNamesList(config android.Config) *map[string]string { 1372 return config.Once(versioningMacroNamesListKey, func() interface{} { 1373 m := make(map[string]string) 1374 return &m 1375 }).(*map[string]string) 1376} 1377 1378// alphanumeric and _ characters are preserved. 1379// other characters are all converted to _ 1380var charsNotForMacro = regexp.MustCompile("[^a-zA-Z0-9_]+") 1381 1382func versioningMacroName(moduleName string) string { 1383 macroName := charsNotForMacro.ReplaceAllString(moduleName, "_") 1384 macroName = strings.ToUpper(macroName) 1385 return "__" + macroName + "_API__" 1386} 1387 1388func NewLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { 1389 module := newModule(hod, android.MultilibBoth) 1390 1391 library := &libraryDecorator{ 1392 MutatedProperties: LibraryMutatedProperties{ 1393 BuildShared: true, 1394 BuildStatic: true, 1395 }, 1396 baseCompiler: NewBaseCompiler(), 1397 baseLinker: NewBaseLinker(module.sanitize), 1398 baseInstaller: NewBaseInstaller("lib", "lib64", InstallInSystem), 1399 sabi: module.sabi, 1400 } 1401 1402 module.compiler = library 1403 module.linker = library 1404 module.installer = library 1405 1406 return module, library 1407} 1408 1409// connects a shared library to a static library in order to reuse its .o files to avoid 1410// compiling source files twice. 1411func reuseStaticLibrary(mctx android.BottomUpMutatorContext, static, shared *Module) { 1412 if staticCompiler, ok := static.compiler.(*libraryDecorator); ok { 1413 sharedCompiler := shared.compiler.(*libraryDecorator) 1414 1415 // Check libraries in addition to cflags, since libraries may be exporting different 1416 // include directories. 1417 if len(staticCompiler.StaticProperties.Static.Cflags) == 0 && 1418 len(sharedCompiler.SharedProperties.Shared.Cflags) == 0 && 1419 len(staticCompiler.StaticProperties.Static.Whole_static_libs) == 0 && 1420 len(sharedCompiler.SharedProperties.Shared.Whole_static_libs) == 0 && 1421 len(staticCompiler.StaticProperties.Static.Static_libs) == 0 && 1422 len(sharedCompiler.SharedProperties.Shared.Static_libs) == 0 && 1423 len(staticCompiler.StaticProperties.Static.Shared_libs) == 0 && 1424 len(sharedCompiler.SharedProperties.Shared.Shared_libs) == 0 && 1425 // Compare System_shared_libs properties with nil because empty lists are 1426 // semantically significant for them. 1427 staticCompiler.StaticProperties.Static.System_shared_libs == nil && 1428 sharedCompiler.SharedProperties.Shared.System_shared_libs == nil { 1429 1430 mctx.AddInterVariantDependency(reuseObjTag, shared, static) 1431 sharedCompiler.baseCompiler.Properties.OriginalSrcs = 1432 sharedCompiler.baseCompiler.Properties.Srcs 1433 sharedCompiler.baseCompiler.Properties.Srcs = nil 1434 sharedCompiler.baseCompiler.Properties.Generated_sources = nil 1435 } else { 1436 // This dep is just to reference static variant from shared variant 1437 mctx.AddInterVariantDependency(staticVariantTag, shared, static) 1438 } 1439 } 1440} 1441 1442func LinkageMutator(mctx android.BottomUpMutatorContext) { 1443 cc_prebuilt := false 1444 if m, ok := mctx.Module().(*Module); ok && m.linker != nil { 1445 _, cc_prebuilt = m.linker.(prebuiltLibraryInterface) 1446 } 1447 if cc_prebuilt { 1448 library := mctx.Module().(*Module).linker.(prebuiltLibraryInterface) 1449 1450 // Differentiate between header only and building an actual static/shared library 1451 if library.buildStatic() || library.buildShared() { 1452 // Always create both the static and shared variants for prebuilt libraries, and then disable the one 1453 // that is not being used. This allows them to share the name of a cc_library module, which requires that 1454 // all the variants of the cc_library also exist on the prebuilt. 1455 modules := mctx.CreateLocalVariations("static", "shared") 1456 static := modules[0].(*Module) 1457 shared := modules[1].(*Module) 1458 1459 static.linker.(prebuiltLibraryInterface).setStatic() 1460 shared.linker.(prebuiltLibraryInterface).setShared() 1461 1462 if !library.buildStatic() { 1463 static.linker.(prebuiltLibraryInterface).disablePrebuilt() 1464 } 1465 if !library.buildShared() { 1466 shared.linker.(prebuiltLibraryInterface).disablePrebuilt() 1467 } 1468 } else { 1469 // Header only 1470 } 1471 1472 } else if library, ok := mctx.Module().(LinkableInterface); ok && library.CcLibraryInterface() { 1473 1474 // Non-cc.Modules may need an empty variant for their mutators. 1475 variations := []string{} 1476 if library.NonCcVariants() { 1477 variations = append(variations, "") 1478 } 1479 1480 if library.BuildStaticVariant() && library.BuildSharedVariant() { 1481 variations := append([]string{"static", "shared"}, variations...) 1482 1483 modules := mctx.CreateLocalVariations(variations...) 1484 static := modules[0].(LinkableInterface) 1485 shared := modules[1].(LinkableInterface) 1486 1487 static.SetStatic() 1488 shared.SetShared() 1489 1490 if _, ok := library.(*Module); ok { 1491 reuseStaticLibrary(mctx, static.(*Module), shared.(*Module)) 1492 } 1493 } else if library.BuildStaticVariant() { 1494 variations := append([]string{"static"}, variations...) 1495 1496 modules := mctx.CreateLocalVariations(variations...) 1497 modules[0].(LinkableInterface).SetStatic() 1498 } else if library.BuildSharedVariant() { 1499 variations := append([]string{"shared"}, variations...) 1500 1501 modules := mctx.CreateLocalVariations(variations...) 1502 modules[0].(LinkableInterface).SetShared() 1503 } else if len(variations) > 0 { 1504 mctx.CreateLocalVariations(variations...) 1505 } 1506 } 1507} 1508 1509var stubVersionsKey = android.NewOnceKey("stubVersions") 1510 1511// maps a module name to the list of stubs versions available for the module 1512func stubsVersionsFor(config android.Config) map[string][]string { 1513 return config.Once(stubVersionsKey, func() interface{} { 1514 return make(map[string][]string) 1515 }).(map[string][]string) 1516} 1517 1518var stubsVersionsLock sync.Mutex 1519 1520func LatestStubsVersionFor(config android.Config, name string) string { 1521 versions, ok := stubsVersionsFor(config)[name] 1522 if ok && len(versions) > 0 { 1523 // the versions are alreay sorted in ascending order 1524 return versions[len(versions)-1] 1525 } 1526 return "" 1527} 1528 1529func normalizeVersions(ctx android.BaseModuleContext, versions []string) { 1530 numVersions := make([]int, len(versions)) 1531 for i, v := range versions { 1532 numVer, err := android.ApiStrToNum(ctx, v) 1533 if err != nil { 1534 ctx.PropertyErrorf("versions", "%s", err.Error()) 1535 return 1536 } 1537 numVersions[i] = numVer 1538 } 1539 if !sort.IsSorted(sort.IntSlice(numVersions)) { 1540 ctx.PropertyErrorf("versions", "not sorted: %v", versions) 1541 } 1542 for i, v := range numVersions { 1543 versions[i] = strconv.Itoa(v) 1544 } 1545} 1546 1547func createVersionVariations(mctx android.BottomUpMutatorContext, versions []string) { 1548 // "" is for the non-stubs variant 1549 versions = append([]string{""}, versions...) 1550 1551 modules := mctx.CreateVariations(versions...) 1552 for i, m := range modules { 1553 if versions[i] != "" { 1554 m.(LinkableInterface).SetBuildStubs() 1555 m.(LinkableInterface).SetStubsVersions(versions[i]) 1556 } 1557 } 1558} 1559 1560func VersionVariantAvailable(module interface { 1561 Host() bool 1562 InRamdisk() bool 1563 InRecovery() bool 1564}) bool { 1565 return !module.Host() && !module.InRamdisk() && !module.InRecovery() 1566} 1567 1568// VersionMutator splits a module into the mandatory non-stubs variant 1569// (which is unnamed) and zero or more stubs variants. 1570func VersionMutator(mctx android.BottomUpMutatorContext) { 1571 if library, ok := mctx.Module().(LinkableInterface); ok && VersionVariantAvailable(library) { 1572 if library.CcLibrary() && library.BuildSharedVariant() && len(library.StubsVersions()) > 0 { 1573 versions := library.StubsVersions() 1574 normalizeVersions(mctx, versions) 1575 if mctx.Failed() { 1576 return 1577 } 1578 1579 stubsVersionsLock.Lock() 1580 defer stubsVersionsLock.Unlock() 1581 // save the list of versions for later use 1582 stubsVersionsFor(mctx.Config())[mctx.ModuleName()] = versions 1583 1584 createVersionVariations(mctx, versions) 1585 return 1586 } 1587 1588 if c, ok := library.(*Module); ok && c.IsStubs() { 1589 stubsVersionsLock.Lock() 1590 defer stubsVersionsLock.Unlock() 1591 // For LLNDK llndk_library, we borrow vstubs.ersions from its implementation library. 1592 // Since llndk_library has dependency to its implementation library, 1593 // we can safely access stubsVersionsFor() with its baseModuleName. 1594 versions := stubsVersionsFor(mctx.Config())[c.BaseModuleName()] 1595 // save the list of versions for later use 1596 stubsVersionsFor(mctx.Config())[mctx.ModuleName()] = versions 1597 1598 createVersionVariations(mctx, versions) 1599 return 1600 } 1601 1602 mctx.CreateVariations("") 1603 return 1604 } 1605 if genrule, ok := mctx.Module().(*genrule.Module); ok { 1606 if _, ok := genrule.Extra.(*GenruleExtraProperties); ok { 1607 if VersionVariantAvailable(genrule) { 1608 mctx.CreateVariations("") 1609 return 1610 } 1611 } 1612 } 1613} 1614 1615// maybeInjectBoringSSLHash adds a rule to run bssl_inject_hash on the output file if the module has the 1616// inject_bssl_hash or if any static library dependencies have inject_bssl_hash set. It returns the output path 1617// that the linked output file should be written to. 1618// TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries. 1619func maybeInjectBoringSSLHash(ctx android.ModuleContext, outputFile android.ModuleOutPath, 1620 inject *bool, fileName string) android.ModuleOutPath { 1621 // TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries. 1622 injectBoringSSLHash := Bool(inject) 1623 ctx.VisitDirectDeps(func(dep android.Module) { 1624 tag := ctx.OtherModuleDependencyTag(dep) 1625 if tag == StaticDepTag || tag == staticExportDepTag || tag == wholeStaticDepTag || tag == lateStaticDepTag { 1626 if cc, ok := dep.(*Module); ok { 1627 if library, ok := cc.linker.(*libraryDecorator); ok { 1628 if Bool(library.Properties.Inject_bssl_hash) { 1629 injectBoringSSLHash = true 1630 } 1631 } 1632 } 1633 } 1634 }) 1635 if injectBoringSSLHash { 1636 hashedOutputfile := outputFile 1637 outputFile = android.PathForModuleOut(ctx, "unhashed", fileName) 1638 1639 rule := android.NewRuleBuilder() 1640 rule.Command(). 1641 BuiltTool(ctx, "bssl_inject_hash"). 1642 Flag("-sha256"). 1643 FlagWithInput("-in-object ", outputFile). 1644 FlagWithOutput("-o ", hashedOutputfile) 1645 rule.Build(pctx, ctx, "injectCryptoHash", "inject crypto hash") 1646 } 1647 1648 return outputFile 1649} 1650