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