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 "slices" 23 "strconv" 24 "strings" 25 "sync" 26 27 "android/soong/android" 28 "android/soong/cc/config" 29 30 "github.com/google/blueprint" 31 "github.com/google/blueprint/depset" 32 "github.com/google/blueprint/pathtools" 33 "github.com/google/blueprint/proptools" 34) 35 36// LibraryProperties is a collection of properties shared by cc library rules/cc. 37type LibraryProperties struct { 38 // local file name to pass to the linker as -exported_symbols_list 39 Exported_symbols_list *string `android:"path,arch_variant"` 40 // local file name to pass to the linker as -unexported_symbols_list 41 Unexported_symbols_list *string `android:"path,arch_variant"` 42 // local file name to pass to the linker as -force_symbols_not_weak_list 43 Force_symbols_not_weak_list *string `android:"path,arch_variant"` 44 // local file name to pass to the linker as -force_symbols_weak_list 45 Force_symbols_weak_list *string `android:"path,arch_variant"` 46 47 // rename host libraries to prevent overlap with system installed libraries 48 Unique_host_soname *bool 49 50 Aidl struct { 51 // export headers generated from .aidl sources 52 Export_aidl_headers *bool 53 } 54 55 Proto struct { 56 // export headers generated from .proto sources 57 Export_proto_headers *bool 58 } 59 60 Sysprop struct { 61 // Whether platform owns this sysprop library. 62 Platform *bool 63 } `blueprint:"mutated"` 64 65 Static_ndk_lib *bool 66 67 // Generate stubs to make this library accessible to APEXes. 68 Stubs StubsProperties `android:"arch_variant"` 69 70 // set the name of the output 71 Stem *string `android:"arch_variant"` 72 73 // set suffix of the name of the output 74 Suffix *string `android:"arch_variant"` 75 76 // Properties for ABI compatibility checker. 77 Header_abi_checker headerAbiCheckerProperties 78 79 Target struct { 80 Vendor, Product struct { 81 // set suffix of the name of the output 82 Suffix *string `android:"arch_variant"` 83 84 Header_abi_checker headerAbiCheckerProperties 85 86 // Disable stubs for vendor/product variants 87 // This is a workaround to keep `stubs` only for "core" variant (not product/vendor). 88 // It would be nice if we could put `stubs` into a `target: { core: {} }` 89 // block but it's not supported in soong yet. This could be removed/simplified once we have 90 // a better syntax. 91 No_stubs bool 92 } 93 94 Platform struct { 95 Header_abi_checker headerAbiCheckerProperties 96 } 97 } 98 99 // Names of modules to be overridden. Listed modules can only be other shared libraries 100 // (in Make or Soong). 101 // This does not completely prevent installation of the overridden libraries, but if both 102 // binaries would be installed by default (in PRODUCT_PACKAGES) the other library will be removed 103 // from PRODUCT_PACKAGES. 104 Overrides []string 105 106 // Inject boringssl hash into the shared library. This is only intended for use by external/boringssl. 107 Inject_bssl_hash *bool `android:"arch_variant"` 108 109 // If this is an LLNDK library, properties to describe the LLNDK stubs. Will be copied from 110 // the module pointed to by llndk_stubs if it is set. 111 Llndk llndkLibraryProperties `android:"arch_variant"` 112 113 // If this is a vendor public library, properties to describe the vendor public library stubs. 114 Vendor_public_library vendorPublicLibraryProperties 115} 116 117type StubsProperties struct { 118 // Relative path to the symbol map. The symbol map provides the list of 119 // symbols that are exported for stubs variant of this library. 120 Symbol_file *string `android:"path,arch_variant"` 121 122 // List versions to generate stubs libs for. The version name "current" is always 123 // implicitly added. 124 Versions []string 125 126 // Whether to not require the implementation of the library to be installed if a 127 // client of the stubs is installed. Defaults to true; set to false if the 128 // implementation is made available by some other means, e.g. in a Microdroid 129 // virtual machine. 130 Implementation_installable *bool 131} 132 133// StaticProperties is a properties stanza to affect only attributes of the "static" variants of a 134// library module. 135type StaticProperties struct { 136 Static StaticOrSharedProperties `android:"arch_variant"` 137} 138 139// SharedProperties is a properties stanza to affect only attributes of the "shared" variants of a 140// library module. 141type SharedProperties struct { 142 Shared StaticOrSharedProperties `android:"arch_variant"` 143} 144 145// StaticOrSharedProperties is an embedded struct representing properties to affect attributes of 146// either only the "static" variants or only the "shared" variants of a library module. These override 147// the base properties of the same name. 148// Use `StaticProperties` or `SharedProperties`, depending on which variant is needed. 149// `StaticOrSharedProperties` exists only to avoid duplication. 150type StaticOrSharedProperties struct { 151 Srcs proptools.Configurable[[]string] `android:"path,arch_variant"` 152 153 Tidy_disabled_srcs []string `android:"path,arch_variant"` 154 155 Tidy_timeout_srcs []string `android:"path,arch_variant"` 156 157 Sanitized Sanitized `android:"arch_variant"` 158 159 Cflags proptools.Configurable[[]string] `android:"arch_variant"` 160 161 Enabled *bool `android:"arch_variant"` 162 Whole_static_libs proptools.Configurable[[]string] `android:"arch_variant"` 163 Static_libs proptools.Configurable[[]string] `android:"arch_variant"` 164 Shared_libs proptools.Configurable[[]string] `android:"arch_variant"` 165 System_shared_libs []string `android:"arch_variant"` 166 167 Export_shared_lib_headers []string `android:"arch_variant"` 168 Export_static_lib_headers []string `android:"arch_variant"` 169 170 Apex_available []string `android:"arch_variant"` 171 172 Installable *bool `android:"arch_variant"` 173} 174 175type LibraryMutatedProperties struct { 176 // Build a static variant 177 BuildStatic bool `blueprint:"mutated"` 178 // Build a shared variant 179 BuildShared bool `blueprint:"mutated"` 180 // This variant is shared 181 VariantIsShared bool `blueprint:"mutated"` 182 // This variant is static 183 VariantIsStatic bool `blueprint:"mutated"` 184 185 // This variant is a stubs lib 186 BuildStubs bool `blueprint:"mutated"` 187 // This variant is the latest version 188 IsLatestVersion bool `blueprint:"mutated"` 189 // Version of the stubs lib 190 StubsVersion string `blueprint:"mutated"` 191 // List of all stubs versions associated with an implementation lib 192 AllStubsVersions []string `blueprint:"mutated"` 193} 194 195type FlagExporterProperties struct { 196 // list of directories relative to the Blueprints file that will 197 // be added to the include path (using -I) for this module and any module that links 198 // against this module. Directories listed in export_include_dirs do not need to be 199 // listed in local_include_dirs. 200 Export_include_dirs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"` 201 202 // list of directories that will be added to the system include path 203 // using -isystem for this module and any module that links against this module. 204 Export_system_include_dirs []string `android:"arch_variant,variant_prepend"` 205 206 Target struct { 207 Vendor, Product struct { 208 // list of exported include directories, like 209 // export_include_dirs, that will be applied to 210 // vendor or product variant of this library. 211 // This will overwrite any other declarations. 212 Override_export_include_dirs []string 213 } 214 } 215} 216 217func init() { 218 RegisterLibraryBuildComponents(android.InitRegistrationContext) 219} 220 221func RegisterLibraryBuildComponents(ctx android.RegistrationContext) { 222 ctx.RegisterModuleType("cc_library_static", LibraryStaticFactory) 223 ctx.RegisterModuleType("cc_rustlibs_for_make", LibraryMakeRustlibsFactory) 224 ctx.RegisterModuleType("cc_library_shared", LibrarySharedFactory) 225 ctx.RegisterModuleType("cc_library", LibraryFactory) 226 ctx.RegisterModuleType("cc_library_host_static", LibraryHostStaticFactory) 227 ctx.RegisterModuleType("cc_library_host_shared", LibraryHostSharedFactory) 228} 229 230// cc_library creates both static and/or shared libraries for a device and/or 231// host. By default, a cc_library has a single variant that targets the device. 232// Specifying `host_supported: true` also creates a library that targets the 233// host. 234func LibraryFactory() android.Module { 235 module, _ := NewLibrary(android.HostAndDeviceSupported) 236 // Can be used as both a static and a shared library. 237 module.sdkMemberTypes = []android.SdkMemberType{ 238 sharedLibrarySdkMemberType, 239 staticLibrarySdkMemberType, 240 staticAndSharedLibrarySdkMemberType, 241 } 242 return module.Init() 243} 244 245// cc_library_static creates a static library for a device and/or host binary. 246func LibraryStaticFactory() android.Module { 247 module, library := NewLibrary(android.HostAndDeviceSupported) 248 library.BuildOnlyStatic() 249 module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType} 250 return module.Init() 251} 252 253// cc_rustlibs_for_make creates a static library which bundles together rust_ffi_static 254// deps for Make. This should not be depended on in Soong, and is probably not the 255// module you need unless you are sure of what you're doing. These should only 256// be declared as dependencies in Make. To ensure inclusion, rust_ffi_static modules 257// should be declared in the whole_static_libs property. 258func LibraryMakeRustlibsFactory() android.Module { 259 module, library := NewLibrary(android.HostAndDeviceSupported) 260 library.BuildOnlyStatic() 261 library.wideStaticlibForMake = true 262 module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType} 263 return module.Init() 264} 265 266// cc_library_shared creates a shared library for a device and/or host. 267func LibrarySharedFactory() android.Module { 268 module, library := NewLibrary(android.HostAndDeviceSupported) 269 library.BuildOnlyShared() 270 module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType} 271 return module.Init() 272} 273 274// cc_library_host_static creates a static library that is linkable to a host 275// binary. 276func LibraryHostStaticFactory() android.Module { 277 module, library := NewLibrary(android.HostSupported) 278 library.BuildOnlyStatic() 279 module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType} 280 return module.Init() 281} 282 283// cc_library_host_shared creates a shared library that is usable on a host. 284func LibraryHostSharedFactory() android.Module { 285 module, library := NewLibrary(android.HostSupported) 286 library.BuildOnlyShared() 287 module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType} 288 return module.Init() 289} 290 291// flagExporter is a separated portion of libraryDecorator pertaining to exported 292// include paths and flags. Keeping this dependency-related information separate 293// from the rest of library information is helpful in keeping data more structured 294// and explicit. 295type flagExporter struct { 296 Properties FlagExporterProperties 297 298 dirs android.Paths // Include directories to be included with -I 299 systemDirs android.Paths // System include directories to be included with -isystem 300 flags []string // Exported raw flags. 301 deps android.Paths 302 headers android.Paths 303 rustRlibDeps []RustRlibDep 304} 305 306// exportedIncludes returns the effective include paths for this module and 307// any module that links against this module. This is obtained from 308// the export_include_dirs property in the appropriate target stanza. 309func (f *flagExporter) exportedIncludes(ctx ModuleContext) android.Paths { 310 if ctx.inVendor() && f.Properties.Target.Vendor.Override_export_include_dirs != nil { 311 return android.PathsForModuleSrc(ctx, f.Properties.Target.Vendor.Override_export_include_dirs) 312 } 313 if ctx.inProduct() && f.Properties.Target.Product.Override_export_include_dirs != nil { 314 return android.PathsForModuleSrc(ctx, f.Properties.Target.Product.Override_export_include_dirs) 315 } 316 return android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs.GetOrDefault(ctx, nil)) 317} 318 319func (f *flagExporter) exportedSystemIncludes(ctx ModuleContext) android.Paths { 320 return android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs) 321} 322 323// exportIncludes registers the include directories and system include directories to be exported 324// transitively to modules depending on this module. 325func (f *flagExporter) exportIncludes(ctx ModuleContext) { 326 f.dirs = append(f.dirs, f.exportedIncludes(ctx)...) 327 f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...) 328} 329 330// exportIncludesAsSystem registers the include directories and system include directories to be 331// exported transitively both as system include directories to modules depending on this module. 332func (f *flagExporter) exportIncludesAsSystem(ctx ModuleContext) { 333 // all dirs are force exported as system 334 f.systemDirs = append(f.systemDirs, f.exportedIncludes(ctx)...) 335 f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...) 336} 337 338// reexportDirs registers the given directories as include directories to be exported transitively 339// to modules depending on this module. 340func (f *flagExporter) reexportDirs(dirs ...android.Path) { 341 f.dirs = append(f.dirs, dirs...) 342} 343 344// reexportSystemDirs registers the given directories as system include directories 345// to be exported transitively to modules depending on this module. 346func (f *flagExporter) reexportSystemDirs(dirs ...android.Path) { 347 f.systemDirs = append(f.systemDirs, dirs...) 348} 349 350// reexportFlags registers the flags to be exported transitively to modules depending on this 351// module. 352func (f *flagExporter) reexportFlags(flags ...string) { 353 if android.PrefixInList(flags, "-I") || android.PrefixInList(flags, "-isystem") { 354 panic(fmt.Errorf("Exporting invalid flag %q: "+ 355 "use reexportDirs or reexportSystemDirs to export directories", flag)) 356 } 357 f.flags = append(f.flags, flags...) 358} 359 360func (f *flagExporter) reexportDeps(deps ...android.Path) { 361 f.deps = append(f.deps, deps...) 362} 363 364func (f *flagExporter) reexportRustStaticDeps(deps ...RustRlibDep) { 365 f.rustRlibDeps = append(f.rustRlibDeps, deps...) 366} 367 368// addExportedGeneratedHeaders does nothing but collects generated header files. 369// This can be differ to exportedDeps which may contain phony files to minimize ninja. 370func (f *flagExporter) addExportedGeneratedHeaders(headers ...android.Path) { 371 f.headers = append(f.headers, headers...) 372} 373 374func (f *flagExporter) setProvider(ctx android.ModuleContext) { 375 android.SetProvider(ctx, FlagExporterInfoProvider, FlagExporterInfo{ 376 // Comes from Export_include_dirs property, and those of exported transitive deps 377 IncludeDirs: android.FirstUniquePaths(f.dirs), 378 // Comes from Export_system_include_dirs property, and those of exported transitive deps 379 SystemIncludeDirs: android.FirstUniquePaths(f.systemDirs), 380 // Used in very few places as a one-off way of adding extra defines. 381 Flags: f.flags, 382 // Used sparingly, for extra files that need to be explicitly exported to dependers, 383 // or for phony files to minimize ninja. 384 Deps: f.deps, 385 // Used for exporting rlib deps of static libraries to dependents. 386 RustRlibDeps: f.rustRlibDeps, 387 // For exported generated headers, such as exported aidl headers, proto headers, or 388 // sysprop headers. 389 GeneratedHeaders: f.headers, 390 }) 391} 392 393// libraryDecorator wraps baseCompiler, baseLinker and baseInstaller to provide library-specific 394// functionality: static vs. shared linkage, reusing object files for shared libraries 395type libraryDecorator struct { 396 Properties LibraryProperties 397 StaticProperties StaticProperties 398 SharedProperties SharedProperties 399 MutatedProperties LibraryMutatedProperties 400 401 // For reusing static library objects for shared library 402 reuseObjects Objects 403 404 // table-of-contents file to optimize out relinking when possible 405 tocFile android.OptionalPath 406 407 flagExporter 408 flagExporterInfo *FlagExporterInfo 409 stripper Stripper 410 411 // For whole_static_libs 412 objects Objects 413 wholeStaticLibsFromPrebuilts android.Paths 414 415 // Uses the module's name if empty, but can be overridden. Does not include 416 // shlib suffix. 417 libName string 418 419 sabi *sabi 420 421 // Output archive of gcno coverage information files 422 coverageOutputFile android.OptionalPath 423 424 // Source Abi Diff 425 sAbiDiff android.Paths 426 427 // Location of the static library in the sysroot. Empty if the library is 428 // not included in the NDK. 429 ndkSysrootPath android.Path 430 431 // Location of the linked, unstripped library for shared libraries 432 unstrippedOutputFile android.Path 433 // Location of the linked, stripped library for shared libraries, strip: "all" 434 strippedAllOutputFile android.Path 435 436 // Location of the file that should be copied to dist dir when no explicit tag is requested 437 defaultDistFile android.Path 438 439 versionScriptPath android.OptionalPath 440 441 postInstallCmds []string 442 443 skipAPIDefine bool 444 445 // Decorated interfaces 446 *baseCompiler 447 *baseLinker 448 *baseInstaller 449 450 apiListCoverageXmlPath android.ModuleOutPath 451 452 // Path to the file containing the APIs exported by this library 453 stubsSymbolFilePath android.Path 454 455 // Forces production of the generated Rust staticlib for cc_library_static. 456 // Intended to be used to provide these generated staticlibs for Make. 457 wideStaticlibForMake bool 458} 459 460// linkerProps returns the list of properties structs relevant for this library. (For example, if 461// the library is cc_shared_library, then static-library properties are omitted.) 462func (library *libraryDecorator) linkerProps() []interface{} { 463 var props []interface{} 464 props = append(props, library.baseLinker.linkerProps()...) 465 props = append(props, 466 &library.Properties, 467 &library.MutatedProperties, 468 &library.flagExporter.Properties, 469 &library.stripper.StripProperties) 470 471 if library.MutatedProperties.BuildShared { 472 props = append(props, &library.SharedProperties) 473 } 474 if library.MutatedProperties.BuildStatic { 475 props = append(props, &library.StaticProperties) 476 } 477 478 return props 479} 480 481func CommonLibraryLinkerFlags(ctx android.ModuleContext, flags Flags, 482 toolchain config.Toolchain, libName string) Flags { 483 484 mod, ok := ctx.Module().(LinkableInterface) 485 486 if !ok { 487 ctx.ModuleErrorf("trying to add linker flags to a non-LinkableInterface module.") 488 return flags 489 } 490 491 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because 492 // all code is position independent, and then those warnings get promoted to 493 // errors. 494 if !ctx.Windows() { 495 flags.Global.CFlags = append(flags.Global.CFlags, "-fPIC") 496 } 497 if mod.Shared() { 498 var f []string 499 if toolchain.Bionic() { 500 f = append(f, 501 "-nostdlib", 502 "-Wl,--gc-sections", 503 ) 504 } 505 if ctx.Darwin() { 506 f = append(f, 507 "-dynamiclib", 508 "-install_name @rpath/"+libName+toolchain.ShlibSuffix(), 509 ) 510 if ctx.Arch().ArchType == android.X86 { 511 f = append(f, 512 "-read_only_relocs suppress", 513 ) 514 } 515 } else { 516 f = append(f, "-shared") 517 if !ctx.Windows() { 518 f = append(f, "-Wl,-soname,"+libName+toolchain.ShlibSuffix()) 519 } 520 } 521 flags.Global.LdFlags = append(flags.Global.LdFlags, f...) 522 } 523 524 return flags 525} 526 527// linkerFlags takes a Flags struct and augments it to contain linker flags that are defined by this 528// library, or that are implied by attributes of this library (such as whether this library is a 529// shared library). 530func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { 531 flags = library.baseLinker.linkerFlags(ctx, flags) 532 flags = CommonLibraryLinkerFlags(ctx, flags, ctx.toolchain(), library.getLibName(ctx)) 533 if library.static() { 534 flags.Local.CFlags = append(flags.Local.CFlags, library.StaticProperties.Static.Cflags.GetOrDefault(ctx, nil)...) 535 } else if library.shared() { 536 flags.Local.CFlags = append(flags.Local.CFlags, library.SharedProperties.Shared.Cflags.GetOrDefault(ctx, nil)...) 537 } 538 539 return flags 540} 541 542// compilerFlags takes a Flags and augments it to contain compile flags from global values, 543// per-target values, module type values, per-module Blueprints properties, extra flags from 544// `flags`, and generated sources from `deps`. 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 ctx.IsLlndk() { 555 // LLNDK libraries ignore most of the properties on the cc_library and use the 556 // LLNDK-specific properties instead. 557 // Wipe all the module-local properties, leaving only the global properties. 558 flags.Local = LocalOrGlobalFlags{} 559 } 560 if library.BuildStubs() { 561 // Remove -include <file> when compiling stubs. Otherwise, the force included 562 // headers might cause conflicting types error with the symbols in the 563 // generated stubs source code. e.g. 564 // double acos(double); // in header 565 // void acos() {} // in the generated source code 566 removeInclude := func(flags []string) []string { 567 ret := flags[:0] 568 for _, f := range flags { 569 if strings.HasPrefix(f, "-include ") { 570 continue 571 } 572 ret = append(ret, f) 573 } 574 return ret 575 } 576 flags.Local.CommonFlags = removeInclude(flags.Local.CommonFlags) 577 flags.Local.CFlags = removeInclude(flags.Local.CFlags) 578 579 flags = AddStubLibraryCompilerFlags(flags) 580 } 581 return flags 582} 583 584func (library *libraryDecorator) getHeaderAbiCheckerProperties(m *Module) headerAbiCheckerProperties { 585 variantProps := &library.Properties.Target.Platform.Header_abi_checker 586 if m.InVendor() { 587 variantProps = &library.Properties.Target.Vendor.Header_abi_checker 588 } else if m.InProduct() { 589 variantProps = &library.Properties.Target.Product.Header_abi_checker 590 } 591 props := library.Properties.Header_abi_checker 592 err := proptools.AppendProperties(&props, variantProps, nil) 593 if err != nil { 594 panic(fmt.Errorf("Cannot merge headerAbiCheckerProperties: %s", err.Error())) 595 } 596 return props 597} 598 599func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { 600 sharedFlags := ctx.getSharedFlags() 601 602 if ctx.IsLlndk() { 603 // Get the matching SDK version for the vendor API level. 604 version, err := android.GetSdkVersionForVendorApiLevel(ctx.Config().VendorApiLevel()) 605 if err != nil { 606 panic(err) 607 } 608 609 llndkFlag := "--llndk" 610 if ctx.baseModuleName() == "libbinder_ndk" && ctx.inProduct() { 611 // This is a special case only for the libbinder_ndk. As the product partition is in the 612 // framework side along with system and system_ext partitions in Treble, libbinder_ndk 613 // provides different binder interfaces between product and vendor modules. 614 // In libbinder_ndk, 'llndk' annotation is for the vendor APIs; while 'systemapi' 615 // annotation is for the product APIs. 616 // Use '--systemapi' flag for building the llndk stub of product variant for the 617 // libbinder_ndk. 618 llndkFlag = "--systemapi" 619 } 620 621 // This is the vendor variant of an LLNDK library, build the LLNDK stubs. 622 nativeAbiResult := ParseNativeAbiDefinition(ctx, 623 String(library.Properties.Llndk.Symbol_file), 624 nativeClampedApiLevel(ctx, version), llndkFlag) 625 objs := CompileStubLibrary(ctx, flags, nativeAbiResult.StubSrc, sharedFlags) 626 if !Bool(library.Properties.Llndk.Unversioned) { 627 library.versionScriptPath = android.OptionalPathForPath( 628 nativeAbiResult.VersionScript) 629 } 630 return objs 631 } 632 if ctx.IsVendorPublicLibrary() { 633 nativeAbiResult := ParseNativeAbiDefinition(ctx, 634 String(library.Properties.Vendor_public_library.Symbol_file), 635 android.FutureApiLevel, "") 636 objs := CompileStubLibrary(ctx, flags, nativeAbiResult.StubSrc, sharedFlags) 637 if !Bool(library.Properties.Vendor_public_library.Unversioned) { 638 library.versionScriptPath = android.OptionalPathForPath(nativeAbiResult.VersionScript) 639 } 640 return objs 641 } 642 if library.BuildStubs() { 643 return library.compileModuleLibApiStubs(ctx, flags, deps) 644 } 645 646 srcs := library.baseCompiler.Properties.Srcs.GetOrDefault(ctx, nil) 647 staticSrcs := library.StaticProperties.Static.Srcs.GetOrDefault(ctx, nil) 648 sharedSrcs := library.SharedProperties.Shared.Srcs.GetOrDefault(ctx, nil) 649 if !library.buildShared() && !library.buildStatic() { 650 if len(srcs) > 0 { 651 ctx.PropertyErrorf("srcs", "cc_library_headers must not have any srcs") 652 } 653 if len(staticSrcs) > 0 { 654 ctx.PropertyErrorf("static.srcs", "cc_library_headers must not have any srcs") 655 } 656 if len(sharedSrcs) > 0 { 657 ctx.PropertyErrorf("shared.srcs", "cc_library_headers must not have any srcs") 658 } 659 return Objects{} 660 } 661 if library.sabi.shouldCreateSourceAbiDump() { 662 dirs := library.exportedIncludeDirsForAbiCheck(ctx) 663 flags.SAbiFlags = make([]string, 0, len(dirs)+1) 664 for _, dir := range dirs { 665 flags.SAbiFlags = append(flags.SAbiFlags, "-I"+dir) 666 } 667 // If this library does not export any include directory, do not append the flags 668 // so that the ABI tool dumps everything without filtering by the include directories. 669 // requiresGlobalIncludes returns whether this library can include CommonGlobalIncludes. 670 // If the library cannot include them, it cannot export them. 671 if len(dirs) > 0 && requiresGlobalIncludes(ctx) { 672 flags.SAbiFlags = append(flags.SAbiFlags, "${config.CommonGlobalIncludes}") 673 } 674 totalLength := len(srcs) + len(deps.GeneratedSources) + 675 len(sharedSrcs) + len(staticSrcs) 676 if totalLength > 0 { 677 flags.SAbiDump = true 678 } 679 } 680 objs := library.baseCompiler.compile(ctx, flags, deps) 681 library.reuseObjects = objs 682 buildFlags := flagsToBuilderFlags(flags) 683 684 if library.static() { 685 srcs := android.PathsForModuleSrc(ctx, staticSrcs) 686 objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceStaticLibrary, srcs, 687 android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Tidy_disabled_srcs), 688 android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Tidy_timeout_srcs), 689 library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps, sharedFlags)) 690 } else if library.shared() { 691 srcs := android.PathsForModuleSrc(ctx, sharedSrcs) 692 objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceSharedLibrary, srcs, 693 android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Tidy_disabled_srcs), 694 android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Tidy_timeout_srcs), 695 library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps, sharedFlags)) 696 } 697 698 return objs 699} 700 701type ApiStubsParams struct { 702 NotInPlatform bool 703 IsNdk bool 704 BaseModuleName string 705 ModuleName string 706} 707 708// GetApiStubsFlags calculates the genstubFlags string to pass to ParseNativeAbiDefinition 709func GetApiStubsFlags(api ApiStubsParams) string { 710 var flag string 711 712 // b/239274367 --apex and --systemapi filters symbols tagged with # apex and # 713 // systemapi, respectively. The former is for symbols defined in platform libraries 714 // and the latter is for symbols defined in APEXes. 715 // A single library can contain either # apex or # systemapi, but not both. 716 // The stub generator (ndkstubgen) is additive, so passing _both_ of these to it should be a no-op. 717 // However, having this distinction helps guard accidental 718 // promotion or demotion of API and also helps the API review process b/191371676 719 if api.NotInPlatform { 720 flag = "--apex" 721 } else { 722 flag = "--systemapi" 723 } 724 725 // b/184712170, unless the lib is an NDK library, exclude all public symbols from 726 // the stub so that it is mandated that all symbols are explicitly marked with 727 // either apex or systemapi. 728 if !api.IsNdk && 729 // the symbol files of libclang libs are autogenerated and do not contain systemapi tags 730 // TODO (spandandas): Update mapfile.py to include #systemapi tag on all symbols 731 !strings.Contains(api.ModuleName, "libclang_rt") { 732 flag = flag + " --no-ndk" 733 } 734 735 // TODO(b/361303067): Remove this special case if bionic/ projects are added to ART development branches. 736 if isBionic(api.BaseModuleName) { 737 // set the flags explicitly for bionic libs. 738 // this is necessary for development in minimal branches which does not contain bionic/*. 739 // In such minimal branches, e.g. on the prebuilt libc stubs 740 // 1. IsNdk will return false (since the ndk_library definition for libc does not exist) 741 // 2. NotInPlatform will return true (since the source com.android.runtime does not exist) 742 flag = "--apex" 743 } 744 745 return flag 746} 747 748// Compile stubs for the API surface between platform and apex 749// This method will be used by source and prebuilt cc module types. 750func (library *libraryDecorator) compileModuleLibApiStubs(ctx ModuleContext, flags Flags, deps PathDeps) Objects { 751 // TODO (b/275273834): Make this a hard error when the symbol files have been added to module sdk. 752 if library.Properties.Stubs.Symbol_file == nil { 753 return Objects{} 754 } 755 756 symbolFile := String(library.Properties.Stubs.Symbol_file) 757 library.stubsSymbolFilePath = android.PathForModuleSrc(ctx, symbolFile) 758 759 apiParams := ApiStubsParams{ 760 NotInPlatform: ctx.notInPlatform(), 761 IsNdk: ctx.Module().(*Module).IsNdk(ctx.Config()), 762 BaseModuleName: ctx.baseModuleName(), 763 ModuleName: ctx.ModuleName(), 764 } 765 flag := GetApiStubsFlags(apiParams) 766 767 nativeAbiResult := ParseNativeAbiDefinition(ctx, symbolFile, 768 android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag) 769 objs := CompileStubLibrary(ctx, flags, nativeAbiResult.StubSrc, ctx.getSharedFlags()) 770 771 library.versionScriptPath = android.OptionalPathForPath( 772 nativeAbiResult.VersionScript) 773 // Parse symbol file to get API list for coverage 774 if library.StubsVersion() == "current" && ctx.PrimaryArch() && !ctx.inRecovery() && !ctx.inProduct() && !ctx.inVendor() { 775 library.apiListCoverageXmlPath = ParseSymbolFileForAPICoverage(ctx, symbolFile) 776 } 777 778 return objs 779} 780 781type libraryInterface interface { 782 VersionedInterface 783 784 static() bool 785 shared() bool 786 objs() Objects 787 reuseObjs() Objects 788 toc() android.OptionalPath 789 790 // Returns true if the build options for the module have selected a static or shared build 791 buildStatic() bool 792 buildShared() bool 793 794 // Sets whether a specific variant is static or shared 795 setStatic() 796 setShared() 797 798 // Gets the ABI properties for vendor, product, or platform variant 799 getHeaderAbiCheckerProperties(m *Module) headerAbiCheckerProperties 800 801 // Write LOCAL_ADDITIONAL_DEPENDENCIES for ABI diff 802 androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) 803 804 apexAvailable() []string 805 806 setAPIListCoverageXMLPath(out android.ModuleOutPath) 807 symbolsFile() *string 808 setSymbolFilePath(path android.Path) 809 setVersionScriptPath(path android.OptionalPath) 810 811 installable() *bool 812} 813 814func (library *libraryDecorator) symbolsFile() *string { 815 return library.Properties.Stubs.Symbol_file 816} 817 818func (library *libraryDecorator) setSymbolFilePath(path android.Path) { 819 library.stubsSymbolFilePath = path 820} 821 822func (library *libraryDecorator) setVersionScriptPath(path android.OptionalPath) { 823 library.versionScriptPath = path 824} 825 826type VersionedInterface interface { 827 BuildStubs() bool 828 SetBuildStubs(isLatest bool) 829 HasStubsVariants() bool 830 IsStubsImplementationRequired() bool 831 SetStubsVersion(string) 832 StubsVersion() string 833 834 StubsVersions(ctx android.BaseModuleContext) []string 835 SetAllStubsVersions([]string) 836 AllStubsVersions() []string 837 838 ImplementationModuleName(name string) string 839 HasLLNDKStubs() bool 840 HasLLNDKHeaders() bool 841 HasVendorPublicLibrary() bool 842 IsLLNDKMovedToApex() bool 843 844 GetAPIListCoverageXMLPath() android.ModuleOutPath 845} 846 847var _ libraryInterface = (*libraryDecorator)(nil) 848var _ VersionedInterface = (*libraryDecorator)(nil) 849 850func (library *libraryDecorator) getLibNameHelper(baseModuleName string, inVendor bool, inProduct bool) string { 851 name := library.libName 852 if name == "" { 853 name = String(library.Properties.Stem) 854 if name == "" { 855 name = baseModuleName 856 } 857 } 858 859 suffix := "" 860 if inVendor { 861 suffix = String(library.Properties.Target.Vendor.Suffix) 862 } else if inProduct { 863 suffix = String(library.Properties.Target.Product.Suffix) 864 } 865 if suffix == "" { 866 suffix = String(library.Properties.Suffix) 867 } 868 869 return name + suffix 870} 871 872// getLibName returns the actual canonical name of the library (the name which 873// should be passed to the linker via linker flags). 874func (library *libraryDecorator) getLibName(ctx BaseModuleContext) string { 875 name := library.getLibNameHelper(ctx.baseModuleName(), ctx.inVendor(), ctx.inProduct()) 876 877 if ctx.Host() && Bool(library.Properties.Unique_host_soname) { 878 if !strings.HasSuffix(name, "-host") { 879 name = name + "-host" 880 } 881 } 882 883 return name 884} 885 886var versioningMacroNamesListMutex sync.Mutex 887 888func (library *libraryDecorator) linkerInit(ctx BaseModuleContext) { 889 location := InstallInSystem 890 if library.baseLinker.sanitize.inSanitizerDir() { 891 location = InstallInSanitizerDir 892 } 893 library.baseInstaller.location = location 894 library.baseLinker.linkerInit(ctx) 895 // Let baseLinker know whether this variant is for stubs or not, so that 896 // it can omit things that are not required for linking stubs. 897 library.baseLinker.dynamicProperties.BuildStubs = library.BuildStubs() 898 899 if library.BuildStubs() { 900 macroNames := versioningMacroNamesList(ctx.Config()) 901 myName := versioningMacroName(ctx.ModuleName()) 902 versioningMacroNamesListMutex.Lock() 903 defer versioningMacroNamesListMutex.Unlock() 904 if (*macroNames)[myName] == "" { 905 (*macroNames)[myName] = ctx.ModuleName() 906 } else if (*macroNames)[myName] != ctx.ModuleName() { 907 ctx.ModuleErrorf("Macro name %q for versioning conflicts with macro name from module %q ", myName, (*macroNames)[myName]) 908 } 909 } 910} 911 912func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { 913 if ctx.IsLlndk() { 914 // LLNDK libraries ignore most of the properties on the cc_library and use the 915 // LLNDK-specific properties instead. 916 return deps 917 } 918 919 deps = library.baseCompiler.compilerDeps(ctx, deps) 920 921 return deps 922} 923 924func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { 925 if ctx.IsLlndk() { 926 // LLNDK libraries ignore most of the properties on the cc_library and use the 927 // LLNDK-specific properties instead. 928 deps.HeaderLibs = append([]string(nil), library.Properties.Llndk.Export_llndk_headers...) 929 deps.ReexportHeaderLibHeaders = append([]string(nil), library.Properties.Llndk.Export_llndk_headers...) 930 return deps 931 } 932 if ctx.IsVendorPublicLibrary() { 933 headers := library.Properties.Vendor_public_library.Export_public_headers 934 deps.HeaderLibs = append([]string(nil), headers...) 935 deps.ReexportHeaderLibHeaders = append([]string(nil), headers...) 936 return deps 937 } 938 939 if library.static() { 940 // Compare with nil because an empty list needs to be propagated. 941 if library.StaticProperties.Static.System_shared_libs != nil { 942 library.baseLinker.Properties.System_shared_libs = library.StaticProperties.Static.System_shared_libs 943 } 944 } else if library.shared() { 945 // Compare with nil because an empty list needs to be propagated. 946 if library.SharedProperties.Shared.System_shared_libs != nil { 947 library.baseLinker.Properties.System_shared_libs = library.SharedProperties.Shared.System_shared_libs 948 } 949 } 950 951 deps = library.baseLinker.linkerDeps(ctx, deps) 952 953 if library.static() { 954 deps.WholeStaticLibs = append(deps.WholeStaticLibs, 955 library.StaticProperties.Static.Whole_static_libs.GetOrDefault(ctx, nil)...) 956 deps.StaticLibs = append(deps.StaticLibs, library.StaticProperties.Static.Static_libs.GetOrDefault(ctx, nil)...) 957 deps.SharedLibs = append(deps.SharedLibs, library.StaticProperties.Static.Shared_libs.GetOrDefault(ctx, nil)...) 958 959 deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.StaticProperties.Static.Export_shared_lib_headers...) 960 deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.StaticProperties.Static.Export_static_lib_headers...) 961 } else if library.shared() { 962 if library.baseLinker.Properties.crt() { 963 deps.CrtBegin = append(deps.CrtBegin, ctx.toolchain().CrtBeginSharedLibrary()...) 964 deps.CrtEnd = append(deps.CrtEnd, ctx.toolchain().CrtEndSharedLibrary()...) 965 966 } 967 if library.baseLinker.Properties.crtPadSegment() { 968 deps.CrtEnd = append(deps.CrtEnd, ctx.toolchain().CrtPadSegmentSharedLibrary()...) 969 } 970 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.SharedProperties.Shared.Whole_static_libs.GetOrDefault(ctx, nil)...) 971 deps.StaticLibs = append(deps.StaticLibs, library.SharedProperties.Shared.Static_libs.GetOrDefault(ctx, nil)...) 972 deps.SharedLibs = append(deps.SharedLibs, library.SharedProperties.Shared.Shared_libs.GetOrDefault(ctx, nil)...) 973 974 deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.SharedProperties.Shared.Export_shared_lib_headers...) 975 deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.SharedProperties.Shared.Export_static_lib_headers...) 976 977 deps.LlndkHeaderLibs = append(deps.LlndkHeaderLibs, library.Properties.Llndk.Export_llndk_headers...) 978 } 979 if ctx.inVendor() { 980 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs) 981 deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs) 982 deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs) 983 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs) 984 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs) 985 } 986 if ctx.inProduct() { 987 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Product.Exclude_static_libs) 988 deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Product.Exclude_shared_libs) 989 deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Product.Exclude_static_libs) 990 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Product.Exclude_shared_libs) 991 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Product.Exclude_static_libs) 992 } 993 if ctx.inRecovery() { 994 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs) 995 deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Recovery.Exclude_shared_libs) 996 deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs) 997 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Recovery.Exclude_shared_libs) 998 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs) 999 } 1000 if ctx.inRamdisk() { 1001 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs) 1002 deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_shared_libs) 1003 deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs) 1004 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Ramdisk.Exclude_shared_libs) 1005 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs) 1006 } 1007 if ctx.inVendorRamdisk() { 1008 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs) 1009 deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_shared_libs) 1010 deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs) 1011 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_shared_libs) 1012 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs) 1013 } 1014 1015 return deps 1016} 1017 1018func (library *libraryDecorator) linkerSpecifiedDeps(ctx android.ConfigurableEvaluatorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps { 1019 specifiedDeps = library.baseLinker.linkerSpecifiedDeps(ctx, module, specifiedDeps) 1020 var properties StaticOrSharedProperties 1021 if library.static() { 1022 properties = library.StaticProperties.Static 1023 } else if library.shared() { 1024 properties = library.SharedProperties.Shared 1025 } 1026 1027 eval := module.ConfigurableEvaluator(ctx) 1028 specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, properties.Shared_libs.GetOrDefault(eval, nil)...) 1029 1030 // Must distinguish nil and [] in system_shared_libs - ensure that [] in 1031 // either input list doesn't come out as nil. 1032 if specifiedDeps.systemSharedLibs == nil { 1033 specifiedDeps.systemSharedLibs = properties.System_shared_libs 1034 } else { 1035 specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, properties.System_shared_libs...) 1036 } 1037 1038 specifiedDeps.sharedLibs = android.FirstUniqueStrings(specifiedDeps.sharedLibs) 1039 if len(specifiedDeps.systemSharedLibs) > 0 { 1040 // Skip this if systemSharedLibs is either nil or [], to ensure they are 1041 // retained. 1042 specifiedDeps.systemSharedLibs = android.FirstUniqueStrings(specifiedDeps.systemSharedLibs) 1043 } 1044 return specifiedDeps 1045} 1046 1047func (library *libraryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { 1048 if library.static() { 1049 moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"} 1050 moduleInfoJSON.Uninstallable = true 1051 } else if library.shared() { 1052 moduleInfoJSON.Class = []string{"SHARED_LIBRARIES"} 1053 } else if library.header() { 1054 moduleInfoJSON.Class = []string{"HEADER_LIBRARIES"} 1055 moduleInfoJSON.Uninstallable = true 1056 } 1057 1058 if library.BuildStubs() && library.StubsVersion() != "" { 1059 moduleInfoJSON.SubName += "." + library.StubsVersion() 1060 } 1061 1062 // If a library providing a stub is included in an APEX, the private APIs of the library 1063 // is accessible only inside the APEX. From outside of the APEX, clients can only use the 1064 // public APIs via the stub. To enforce this, the (latest version of the) stub gets the 1065 // name of the library. The impl library instead gets the `.bootstrap` suffix to so that 1066 // they can be exceptionally used directly when APEXes are not available (e.g. during the 1067 // very early stage in the boot process). 1068 if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.notInPlatform() && 1069 !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() && !ctx.useVndk() && !ctx.static() { 1070 if library.BuildStubs() && library.isLatestStubVersion() { 1071 moduleInfoJSON.SubName = "" 1072 } 1073 if !library.BuildStubs() { 1074 moduleInfoJSON.SubName = ".bootstrap" 1075 } 1076 } 1077 1078 library.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) 1079} 1080 1081func (library *libraryDecorator) testSuiteInfo(ctx ModuleContext) { 1082 // not a test 1083} 1084 1085func (library *libraryDecorator) linkStatic(ctx ModuleContext, 1086 flags Flags, deps PathDeps, objs Objects) android.Path { 1087 1088 library.objects = deps.WholeStaticLibObjs.Copy() 1089 library.objects = library.objects.Append(objs) 1090 library.wholeStaticLibsFromPrebuilts = android.CopyOfPaths(deps.WholeStaticLibsFromPrebuilts) 1091 1092 if library.wideStaticlibForMake { 1093 if generatedLib := GenerateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil { 1094 // WholeStaticLibsFromPrebuilts are .a files that get included whole into the resulting staticlib 1095 // so reuse that here for our Rust staticlibs because we don't have individual object files for 1096 // these. 1097 deps.WholeStaticLibsFromPrebuilts = append(deps.WholeStaticLibsFromPrebuilts, generatedLib) 1098 } 1099 1100 } 1101 1102 fileName := ctx.ModuleName() + staticLibraryExtension 1103 outputFile := android.PathForModuleOut(ctx, fileName) 1104 builderFlags := flagsToBuilderFlags(flags) 1105 1106 if Bool(library.baseLinker.Properties.Use_version_lib) { 1107 if ctx.Host() { 1108 versionedOutputFile := outputFile 1109 outputFile = android.PathForModuleOut(ctx, "unversioned", fileName) 1110 library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) 1111 } else { 1112 versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName) 1113 library.defaultDistFile = versionedOutputFile 1114 library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) 1115 } 1116 } 1117 1118 transformObjToStaticLib(ctx, library.objects.objFiles, deps.WholeStaticLibsFromPrebuilts, builderFlags, outputFile, nil, objs.tidyDepFiles) 1119 1120 library.coverageOutputFile = transformCoverageFilesToZip(ctx, library.objects, ctx.ModuleName()) 1121 1122 ctx.CheckbuildFile(outputFile) 1123 1124 if library.static() { 1125 android.SetProvider(ctx, StaticLibraryInfoProvider, StaticLibraryInfo{ 1126 StaticLibrary: outputFile, 1127 ReuseObjects: library.reuseObjects, 1128 Objects: library.objects, 1129 WholeStaticLibsFromPrebuilts: library.wholeStaticLibsFromPrebuilts, 1130 1131 TransitiveStaticLibrariesForOrdering: depset.NewBuilder[android.Path](depset.TOPOLOGICAL). 1132 Direct(outputFile). 1133 Transitive(deps.TranstiveStaticLibrariesForOrdering). 1134 Build(), 1135 }) 1136 } 1137 1138 if library.header() { 1139 android.SetProvider(ctx, HeaderLibraryInfoProvider, HeaderLibraryInfo{}) 1140 } 1141 1142 return outputFile 1143} 1144 1145func ndkSharedLibDeps(ctx ModuleContext) android.Paths { 1146 if ctx.Module().(*Module).IsSdkVariant() { 1147 // The NDK sysroot timestamp file depends on all the NDK 1148 // sysroot header and shared library files. 1149 return android.Paths{getNdkBaseTimestampFile(ctx)} 1150 } 1151 return nil 1152} 1153 1154func (library *libraryDecorator) linkShared(ctx ModuleContext, 1155 flags Flags, deps PathDeps, objs Objects) android.Path { 1156 1157 var linkerDeps android.Paths 1158 linkerDeps = append(linkerDeps, flags.LdFlagsDeps...) 1159 linkerDeps = append(linkerDeps, ndkSharedLibDeps(ctx)...) 1160 1161 exportedSymbols := ctx.ExpandOptionalSource(library.Properties.Exported_symbols_list, "exported_symbols_list") 1162 unexportedSymbols := ctx.ExpandOptionalSource(library.Properties.Unexported_symbols_list, "unexported_symbols_list") 1163 forceNotWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_not_weak_list, "force_symbols_not_weak_list") 1164 forceWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_weak_list, "force_symbols_weak_list") 1165 if !ctx.Darwin() { 1166 if exportedSymbols.Valid() { 1167 ctx.PropertyErrorf("exported_symbols_list", "Only supported on Darwin") 1168 } 1169 if unexportedSymbols.Valid() { 1170 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin") 1171 } 1172 if forceNotWeakSymbols.Valid() { 1173 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin") 1174 } 1175 if forceWeakSymbols.Valid() { 1176 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin") 1177 } 1178 } else { 1179 if exportedSymbols.Valid() { 1180 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-exported_symbols_list,"+exportedSymbols.String()) 1181 linkerDeps = append(linkerDeps, exportedSymbols.Path()) 1182 } 1183 if unexportedSymbols.Valid() { 1184 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String()) 1185 linkerDeps = append(linkerDeps, unexportedSymbols.Path()) 1186 } 1187 if forceNotWeakSymbols.Valid() { 1188 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String()) 1189 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path()) 1190 } 1191 if forceWeakSymbols.Valid() { 1192 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String()) 1193 linkerDeps = append(linkerDeps, forceWeakSymbols.Path()) 1194 } 1195 } 1196 if library.versionScriptPath.Valid() { 1197 linkerScriptFlags := "-Wl,--version-script," + library.versionScriptPath.String() 1198 flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlags) 1199 linkerDeps = append(linkerDeps, library.versionScriptPath.Path()) 1200 } 1201 1202 fileName := library.getLibName(ctx) + flags.Toolchain.ShlibSuffix() 1203 outputFile := android.PathForModuleOut(ctx, fileName) 1204 unstrippedOutputFile := outputFile 1205 1206 var implicitOutputs android.WritablePaths 1207 if ctx.Windows() { 1208 importLibraryPath := android.PathForModuleOut(ctx, pathtools.ReplaceExtension(fileName, "lib")) 1209 1210 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--out-implib="+importLibraryPath.String()) 1211 implicitOutputs = append(implicitOutputs, importLibraryPath) 1212 } 1213 1214 builderFlags := flagsToBuilderFlags(flags) 1215 1216 if ctx.Darwin() && deps.DarwinSecondArchOutput.Valid() { 1217 fatOutputFile := outputFile 1218 outputFile = android.PathForModuleOut(ctx, "pre-fat", fileName) 1219 transformDarwinUniversalBinary(ctx, fatOutputFile, outputFile, deps.DarwinSecondArchOutput.Path()) 1220 } 1221 1222 // Optimize out relinking against shared libraries whose interface hasn't changed by 1223 // depending on a table of contents file instead of the library itself. 1224 tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.ShlibSuffix()[1:]+".toc") 1225 library.tocFile = android.OptionalPathForPath(tocFile) 1226 TransformSharedObjectToToc(ctx, outputFile, tocFile) 1227 1228 stripFlags := flagsToStripFlags(flags) 1229 needsStrip := library.stripper.NeedsStrip(ctx) 1230 if library.BuildStubs() { 1231 // No need to strip stubs libraries 1232 needsStrip = false 1233 } 1234 if needsStrip { 1235 if ctx.Darwin() { 1236 stripFlags.StripUseGnuStrip = true 1237 } 1238 strippedOutputFile := outputFile 1239 outputFile = android.PathForModuleOut(ctx, "unstripped", fileName) 1240 library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, stripFlags) 1241 } 1242 library.unstrippedOutputFile = outputFile 1243 1244 outputFile = maybeInjectBoringSSLHash(ctx, outputFile, library.Properties.Inject_bssl_hash, fileName) 1245 1246 if Bool(library.baseLinker.Properties.Use_version_lib) { 1247 if ctx.Host() { 1248 versionedOutputFile := outputFile 1249 outputFile = android.PathForModuleOut(ctx, "unversioned", fileName) 1250 library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) 1251 } else { 1252 versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName) 1253 library.defaultDistFile = versionedOutputFile 1254 1255 if library.stripper.NeedsStrip(ctx) { 1256 out := android.PathForModuleOut(ctx, "versioned-stripped", fileName) 1257 library.defaultDistFile = out 1258 library.stripper.StripExecutableOrSharedLib(ctx, versionedOutputFile, out, stripFlags) 1259 } 1260 1261 library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) 1262 } 1263 } 1264 1265 // Generate an output file for dist as if strip: "all" is set on the module. 1266 // Currently this is for layoutlib release process only. 1267 for _, dist := range ctx.Module().(*Module).Dists() { 1268 if dist.Tag != nil && *dist.Tag == "stripped_all" { 1269 strippedAllOutputFile := android.PathForModuleOut(ctx, "stripped_all", fileName) 1270 transformStrip(ctx, outputFile, strippedAllOutputFile, StripFlags{Toolchain: flags.Toolchain}) 1271 library.strippedAllOutputFile = strippedAllOutputFile 1272 break 1273 } 1274 } 1275 1276 sharedLibs := deps.EarlySharedLibs 1277 sharedLibs = append(sharedLibs, deps.SharedLibs...) 1278 sharedLibs = append(sharedLibs, deps.LateSharedLibs...) 1279 1280 linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...) 1281 linkerDeps = append(linkerDeps, deps.SharedLibsDeps...) 1282 linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...) 1283 1284 if generatedLib := GenerateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil && !library.BuildStubs() { 1285 if ctx.Module().(*Module).WholeRustStaticlib { 1286 deps.WholeStaticLibs = append(deps.WholeStaticLibs, generatedLib) 1287 } else { 1288 deps.StaticLibs = append(deps.StaticLibs, generatedLib) 1289 } 1290 } 1291 1292 transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, 1293 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, 1294 deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs, objs.tidyDepFiles) 1295 1296 objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...) 1297 objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...) 1298 objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.StaticLibObjs.sAbiDumpFiles...) 1299 objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.WholeStaticLibObjs.sAbiDumpFiles...) 1300 1301 library.coverageOutputFile = transformCoverageFilesToZip(ctx, objs, library.getLibName(ctx)) 1302 library.linkSAbiDumpFiles(ctx, deps, objs, fileName, unstrippedOutputFile) 1303 1304 var transitiveStaticLibrariesForOrdering depset.DepSet[android.Path] 1305 if static := ctx.GetDirectDepsProxyWithTag(staticVariantTag); len(static) > 0 { 1306 s, _ := android.OtherModuleProvider(ctx, static[0], StaticLibraryInfoProvider) 1307 transitiveStaticLibrariesForOrdering = s.TransitiveStaticLibrariesForOrdering 1308 } 1309 1310 android.SetProvider(ctx, SharedLibraryInfoProvider, SharedLibraryInfo{ 1311 TableOfContents: android.OptionalPathForPath(tocFile), 1312 SharedLibrary: unstrippedOutputFile, 1313 TransitiveStaticLibrariesForOrdering: transitiveStaticLibrariesForOrdering, 1314 Target: ctx.Target(), 1315 IsStubs: library.BuildStubs(), 1316 }) 1317 1318 AddStubDependencyProviders(ctx) 1319 1320 return unstrippedOutputFile 1321} 1322 1323// Visits the stub variants of the library and returns a struct containing the stub .so paths 1324func AddStubDependencyProviders(ctx android.BaseModuleContext) []SharedStubLibrary { 1325 stubsInfo := []SharedStubLibrary{} 1326 stubs := ctx.GetDirectDepsProxyWithTag(StubImplDepTag) 1327 if len(stubs) > 0 { 1328 for _, stub := range stubs { 1329 stubInfo, ok := android.OtherModuleProvider(ctx, stub, SharedLibraryInfoProvider) 1330 // TODO (b/275273834): Make this a hard error when the symbol files have been added to module sdk. 1331 if !ok { 1332 continue 1333 } 1334 flagInfo, _ := android.OtherModuleProvider(ctx, stub, FlagExporterInfoProvider) 1335 if _, ok = android.OtherModuleProvider(ctx, stub, CcInfoProvider); !ok { 1336 panic(fmt.Errorf("stub is not a cc module %s", stub)) 1337 } 1338 stubsInfo = append(stubsInfo, SharedStubLibrary{ 1339 Version: android.OtherModuleProviderOrDefault(ctx, stub, LinkableInfoProvider).StubsVersion, 1340 SharedLibraryInfo: stubInfo, 1341 FlagExporterInfo: flagInfo, 1342 }) 1343 } 1344 if len(stubsInfo) > 0 { 1345 android.SetProvider(ctx, SharedLibraryStubsProvider, SharedLibraryStubsInfo{ 1346 SharedStubLibraries: stubsInfo, 1347 IsLLNDK: ctx.Module().(LinkableInterface).IsLlndk(), 1348 }) 1349 } 1350 } 1351 1352 return stubsInfo 1353} 1354 1355func (library *libraryDecorator) unstrippedOutputFilePath() android.Path { 1356 return library.unstrippedOutputFile 1357} 1358 1359func (library *libraryDecorator) strippedAllOutputFilePath() android.Path { 1360 return library.strippedAllOutputFile 1361} 1362 1363func (library *libraryDecorator) disableStripping() { 1364 library.stripper.StripProperties.Strip.None = BoolPtr(true) 1365} 1366 1367func (library *libraryDecorator) nativeCoverage() bool { 1368 if library.header() || library.BuildStubs() { 1369 return false 1370 } 1371 return true 1372} 1373 1374func (library *libraryDecorator) coverageOutputFilePath() android.OptionalPath { 1375 return library.coverageOutputFile 1376} 1377 1378func (library *libraryDecorator) exportedIncludeDirsForAbiCheck(ctx ModuleContext) []string { 1379 exportIncludeDirs := library.flagExporter.exportedIncludes(ctx).Strings() 1380 exportIncludeDirs = append(exportIncludeDirs, library.sabi.Properties.ReexportedIncludes...) 1381 exportSystemIncludeDirs := library.flagExporter.exportedSystemIncludes(ctx).Strings() 1382 exportSystemIncludeDirs = append(exportSystemIncludeDirs, library.sabi.Properties.ReexportedSystemIncludes...) 1383 // The ABI checker does not distinguish normal and system headers. 1384 return append(exportIncludeDirs, exportSystemIncludeDirs...) 1385} 1386 1387func (library *libraryDecorator) llndkIncludeDirsForAbiCheck(ctx ModuleContext, deps PathDeps) []string { 1388 var includeDirs, systemIncludeDirs []string 1389 1390 if library.Properties.Llndk.Override_export_include_dirs != nil { 1391 includeDirs = append(includeDirs, android.PathsForModuleSrc( 1392 ctx, library.Properties.Llndk.Override_export_include_dirs).Strings()...) 1393 } else { 1394 includeDirs = append(includeDirs, library.flagExporter.exportedIncludes(ctx).Strings()...) 1395 // Ignore library.sabi.Properties.ReexportedIncludes because 1396 // LLNDK does not reexport the implementation's dependencies, such as export_header_libs. 1397 } 1398 1399 systemIncludeDirs = append(systemIncludeDirs, 1400 library.flagExporter.exportedSystemIncludes(ctx).Strings()...) 1401 if Bool(library.Properties.Llndk.Export_headers_as_system) { 1402 systemIncludeDirs = append(systemIncludeDirs, includeDirs...) 1403 includeDirs = nil 1404 } 1405 // Header libs. 1406 includeDirs = append(includeDirs, deps.LlndkIncludeDirs.Strings()...) 1407 systemIncludeDirs = append(systemIncludeDirs, deps.LlndkSystemIncludeDirs.Strings()...) 1408 // The ABI checker does not distinguish normal and system headers. 1409 return append(includeDirs, systemIncludeDirs...) 1410} 1411 1412func (library *libraryDecorator) linkLlndkSAbiDumpFiles(ctx ModuleContext, 1413 deps PathDeps, sAbiDumpFiles android.Paths, soFile android.Path, libFileName string, 1414 excludeSymbolVersions, excludeSymbolTags []string, 1415 sdkVersionForVendorApiLevel string) android.Path { 1416 // Though LLNDK is implemented in system, the callers in vendor cannot include CommonGlobalIncludes, 1417 // so commonGlobalIncludes is false. 1418 return transformDumpToLinkedDump(ctx, 1419 sAbiDumpFiles, soFile, libFileName+".llndk", 1420 library.llndkIncludeDirsForAbiCheck(ctx, deps), 1421 android.OptionalPathForModuleSrc(ctx, library.Properties.Llndk.Symbol_file), 1422 append([]string{"*_PLATFORM", "*_PRIVATE"}, excludeSymbolVersions...), 1423 append([]string{"platform-only"}, excludeSymbolTags...), 1424 []string{"llndk"}, sdkVersionForVendorApiLevel, false /* commonGlobalIncludes */) 1425} 1426 1427func (library *libraryDecorator) linkApexSAbiDumpFiles(ctx ModuleContext, 1428 deps PathDeps, sAbiDumpFiles android.Paths, soFile android.Path, libFileName string, 1429 excludeSymbolVersions, excludeSymbolTags []string, 1430 sdkVersion string) android.Path { 1431 return transformDumpToLinkedDump(ctx, 1432 sAbiDumpFiles, soFile, libFileName+".apex", 1433 library.exportedIncludeDirsForAbiCheck(ctx), 1434 android.OptionalPathForModuleSrc(ctx, library.Properties.Stubs.Symbol_file), 1435 append([]string{"*_PLATFORM", "*_PRIVATE"}, excludeSymbolVersions...), 1436 append([]string{"platform-only"}, excludeSymbolTags...), 1437 []string{"apex", "systemapi"}, sdkVersion, requiresGlobalIncludes(ctx)) 1438} 1439 1440func getRefAbiDumpFile(ctx android.ModuleInstallPathContext, 1441 versionedDumpDir, fileName string) android.OptionalPath { 1442 1443 currentArchType := ctx.Arch().ArchType 1444 primaryArchType := ctx.Config().DevicePrimaryArchType() 1445 archName := currentArchType.String() 1446 if currentArchType != primaryArchType { 1447 archName += "_" + primaryArchType.String() 1448 } 1449 1450 return android.ExistentPathForSource(ctx, versionedDumpDir, archName, "source-based", 1451 fileName+".lsdump") 1452} 1453 1454// Return the previous and current SDK versions for cross-version ABI diff. 1455func crossVersionAbiDiffSdkVersions(ctx ModuleContext, dumpDir string) (int, int) { 1456 sdkVersionInt := ctx.Config().PlatformSdkVersion().FinalInt() 1457 1458 if ctx.Config().PlatformSdkFinal() { 1459 return sdkVersionInt - 1, sdkVersionInt 1460 } else { 1461 // The platform SDK version can be upgraded before finalization while the corresponding abi dumps hasn't 1462 // been generated. Thus the Cross-Version Check chooses PLATFORM_SDK_VERION - 1 as previous version. 1463 // This situation could be identified by checking the existence of the PLATFORM_SDK_VERION dump directory. 1464 versionedDumpDir := android.ExistentPathForSource(ctx, 1465 dumpDir, ctx.Config().PlatformSdkVersion().String()) 1466 if versionedDumpDir.Valid() { 1467 return sdkVersionInt, sdkVersionInt + 1 1468 } else { 1469 return sdkVersionInt - 1, sdkVersionInt 1470 } 1471 } 1472} 1473 1474// Return the SDK version for same-version ABI diff. 1475func currRefAbiDumpSdkVersion(ctx ModuleContext) string { 1476 if ctx.Config().PlatformSdkFinal() { 1477 // After sdk finalization, the ABI of the latest API level must be consistent with the source code, 1478 // so choose PLATFORM_SDK_VERSION as the current version. 1479 return ctx.Config().PlatformSdkVersion().String() 1480 } else { 1481 return "current" 1482 } 1483} 1484 1485// sourceAbiDiff registers a build statement to compare linked sAbi dump files (.lsdump). 1486func (library *libraryDecorator) sourceAbiDiff(ctx android.ModuleContext, 1487 sourceDump, referenceDump android.Path, 1488 baseName, nameExt string, isLlndk, allowExtensions bool, 1489 sourceVersion, errorMessage string) { 1490 1491 extraFlags := []string{"-target-version", sourceVersion} 1492 headerAbiChecker := library.getHeaderAbiCheckerProperties(ctx.Module().(*Module)) 1493 if Bool(headerAbiChecker.Check_all_apis) { 1494 extraFlags = append(extraFlags, "-check-all-apis") 1495 } else { 1496 extraFlags = append(extraFlags, 1497 "-allow-unreferenced-changes", 1498 "-allow-unreferenced-elf-symbol-changes") 1499 // The functions in standard libraries are not always declared in the headers. 1500 // Allow them to be added or removed without changing the symbols. 1501 if isBionic(ctx.ModuleName()) { 1502 extraFlags = append(extraFlags, "-allow-adding-removing-referenced-apis") 1503 } 1504 } 1505 if isLlndk { 1506 extraFlags = append(extraFlags, "-consider-opaque-types-different") 1507 } 1508 if allowExtensions { 1509 extraFlags = append(extraFlags, "-allow-extensions") 1510 } 1511 extraFlags = append(extraFlags, headerAbiChecker.Diff_flags...) 1512 1513 library.sAbiDiff = append( 1514 library.sAbiDiff, 1515 transformAbiDumpToAbiDiff(ctx, sourceDump, referenceDump, 1516 baseName, nameExt, extraFlags, errorMessage)) 1517} 1518 1519func (library *libraryDecorator) crossVersionAbiDiff(ctx android.ModuleContext, 1520 sourceDump, referenceDump android.Path, 1521 baseName, nameExt string, isLlndk bool, sourceVersion, prevDumpDir string) { 1522 1523 errorMessage := "error: Please follow https://android.googlesource.com/platform/development/+/main/vndk/tools/header-checker/README.md#configure-cross_version-abi-check to resolve the difference between your source code and the ABI dumps in " + prevDumpDir 1524 1525 library.sourceAbiDiff(ctx, sourceDump, referenceDump, baseName, nameExt, 1526 isLlndk, true /* allowExtensions */, sourceVersion, errorMessage) 1527} 1528 1529func (library *libraryDecorator) sameVersionAbiDiff(ctx android.ModuleContext, 1530 sourceDump, referenceDump android.Path, 1531 baseName, nameExt string, isLlndk bool, lsdumpTagName string) { 1532 1533 libName := strings.TrimSuffix(baseName, filepath.Ext(baseName)) 1534 errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py --lib " + libName + " --lib-variant " + lsdumpTagName 1535 1536 targetRelease := ctx.Config().Getenv("TARGET_RELEASE") 1537 if targetRelease != "" { 1538 errorMessage += " --release " + targetRelease 1539 } 1540 1541 library.sourceAbiDiff(ctx, sourceDump, referenceDump, baseName, nameExt, 1542 isLlndk, false /* allowExtensions */, "current", errorMessage) 1543} 1544 1545func (library *libraryDecorator) optInAbiDiff(ctx android.ModuleContext, 1546 sourceDump, referenceDump android.Path, 1547 baseName, nameExt string, refDumpDir string, lsdumpTagName string) { 1548 1549 libName := strings.TrimSuffix(baseName, filepath.Ext(baseName)) 1550 errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py --lib " + libName + " --lib-variant " + lsdumpTagName + " --ref-dump-dir $$ANDROID_BUILD_TOP/" + refDumpDir 1551 1552 targetRelease := ctx.Config().Getenv("TARGET_RELEASE") 1553 if targetRelease != "" { 1554 errorMessage += " --release " + targetRelease 1555 } 1556 1557 // Most opt-in libraries do not have dumps for all default architectures. 1558 if ctx.Config().HasDeviceProduct() { 1559 errorMessage += " --product " + ctx.Config().DeviceProduct() 1560 } 1561 1562 library.sourceAbiDiff(ctx, sourceDump, referenceDump, baseName, nameExt, 1563 false /* isLlndk */, false /* allowExtensions */, "current", errorMessage) 1564} 1565 1566func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, deps PathDeps, objs Objects, fileName string, soFile android.Path) { 1567 if library.sabi.shouldCreateSourceAbiDump() { 1568 exportedIncludeDirs := library.exportedIncludeDirsForAbiCheck(ctx) 1569 headerAbiChecker := library.getHeaderAbiCheckerProperties(ctx.Module().(*Module)) 1570 currSdkVersion := currRefAbiDumpSdkVersion(ctx) 1571 currVendorVersion := ctx.Config().VendorApiLevel() 1572 1573 // Generate source dumps. 1574 implDump := transformDumpToLinkedDump(ctx, 1575 objs.sAbiDumpFiles, soFile, fileName, 1576 exportedIncludeDirs, 1577 android.OptionalPathForModuleSrc(ctx, library.symbolFileForAbiCheck(ctx)), 1578 headerAbiChecker.Exclude_symbol_versions, 1579 headerAbiChecker.Exclude_symbol_tags, 1580 []string{} /* includeSymbolTags */, currSdkVersion, requiresGlobalIncludes(ctx)) 1581 1582 var llndkDump, apexVariantDump android.Path 1583 tags := classifySourceAbiDump(ctx.Module().(*Module)) 1584 optInTags := []lsdumpTag{} 1585 for _, tag := range tags { 1586 if tag == llndkLsdumpTag && currVendorVersion != "" { 1587 if llndkDump == nil { 1588 sdkVersion, err := android.GetSdkVersionForVendorApiLevel(currVendorVersion) 1589 if err != nil { 1590 ctx.ModuleErrorf("Cannot create %s llndk dump: %s", fileName, err) 1591 return 1592 } 1593 // TODO(b/323447559): Evaluate if replacing sAbiDumpFiles with implDump is faster 1594 llndkDump = library.linkLlndkSAbiDumpFiles(ctx, 1595 deps, objs.sAbiDumpFiles, soFile, fileName, 1596 headerAbiChecker.Exclude_symbol_versions, 1597 headerAbiChecker.Exclude_symbol_tags, 1598 nativeClampedApiLevel(ctx, sdkVersion).String()) 1599 } 1600 addLsdumpPath(ctx.Config(), string(tag)+":"+llndkDump.String()) 1601 } else if tag == apexLsdumpTag { 1602 if apexVariantDump == nil { 1603 apexVariantDump = library.linkApexSAbiDumpFiles(ctx, 1604 deps, objs.sAbiDumpFiles, soFile, fileName, 1605 headerAbiChecker.Exclude_symbol_versions, 1606 headerAbiChecker.Exclude_symbol_tags, 1607 currSdkVersion) 1608 } 1609 addLsdumpPath(ctx.Config(), string(tag)+":"+apexVariantDump.String()) 1610 } else { 1611 if tag.dirName() == "" { 1612 optInTags = append(optInTags, tag) 1613 } 1614 addLsdumpPath(ctx.Config(), string(tag)+":"+implDump.String()) 1615 } 1616 } 1617 1618 // Diff source dumps and reference dumps. 1619 for _, tag := range tags { 1620 dumpDirName := tag.dirName() 1621 if dumpDirName == "" { 1622 continue 1623 } 1624 dumpDir := filepath.Join("prebuilts", "abi-dumps", dumpDirName) 1625 isLlndk := (tag == llndkLsdumpTag) 1626 isApex := (tag == apexLsdumpTag) 1627 binderBitness := ctx.DeviceConfig().BinderBitness() 1628 nameExt := "" 1629 if isLlndk { 1630 nameExt = "llndk" 1631 } else if isApex { 1632 nameExt = "apex" 1633 } 1634 // Check against the previous version. 1635 var prevVersion, currVersion string 1636 sourceDump := implDump 1637 // If this release config does not define VendorApiLevel, fall back to the old policy. 1638 if isLlndk && currVendorVersion != "" { 1639 prevVersion = ctx.Config().PrevVendorApiLevel() 1640 currVersion = currVendorVersion 1641 // LLNDK dumps are generated by different rules after trunk stable. 1642 if android.IsTrunkStableVendorApiLevel(prevVersion) { 1643 sourceDump = llndkDump 1644 } 1645 } else { 1646 prevVersionInt, currVersionInt := crossVersionAbiDiffSdkVersions(ctx, dumpDir) 1647 prevVersion = strconv.Itoa(prevVersionInt) 1648 currVersion = strconv.Itoa(currVersionInt) 1649 // APEX dumps are generated by different rules after trunk stable. 1650 if isApex && prevVersionInt > 34 { 1651 sourceDump = apexVariantDump 1652 } 1653 } 1654 prevDumpDir := filepath.Join(dumpDir, prevVersion, binderBitness) 1655 prevDumpFile := getRefAbiDumpFile(ctx, prevDumpDir, fileName) 1656 if prevDumpFile.Valid() { 1657 library.crossVersionAbiDiff(ctx, sourceDump, prevDumpFile.Path(), 1658 fileName, nameExt+prevVersion, isLlndk, currVersion, prevDumpDir) 1659 } 1660 // Check against the current version. 1661 sourceDump = implDump 1662 if isLlndk && currVendorVersion != "" { 1663 currVersion = currVendorVersion 1664 if android.IsTrunkStableVendorApiLevel(currVersion) { 1665 sourceDump = llndkDump 1666 } 1667 } else { 1668 currVersion = currSdkVersion 1669 if isApex && (!ctx.Config().PlatformSdkFinal() || 1670 ctx.Config().PlatformSdkVersion().FinalInt() > 34) { 1671 sourceDump = apexVariantDump 1672 } 1673 } 1674 currDumpDir := filepath.Join(dumpDir, currVersion, binderBitness) 1675 currDumpFile := getRefAbiDumpFile(ctx, currDumpDir, fileName) 1676 if currDumpFile.Valid() { 1677 library.sameVersionAbiDiff(ctx, sourceDump, currDumpFile.Path(), 1678 fileName, nameExt, isLlndk, string(tag)) 1679 } 1680 } 1681 1682 // Assert that a module is tagged with at most one of platformLsdumpTag, productLsdumpTag, or vendorLsdumpTag. 1683 if len(headerAbiChecker.Ref_dump_dirs) > 0 && len(optInTags) != 1 { 1684 ctx.ModuleErrorf("Expect exactly one opt-in lsdump tag when ref_dump_dirs are specified: %s", optInTags) 1685 return 1686 } 1687 // Ensure that a module tagged with only platformLsdumpTag has ref_dump_dirs. 1688 // Android.bp in vendor projects should be cleaned up before this is enforced for vendorLsdumpTag and productLsdumpTag. 1689 if len(headerAbiChecker.Ref_dump_dirs) == 0 && len(tags) == 1 && tags[0] == platformLsdumpTag { 1690 ctx.ModuleErrorf("header_abi_checker is explicitly enabled, but no ref_dump_dirs are specified.") 1691 } 1692 // Check against the opt-in reference dumps. 1693 for i, optInDumpDir := range headerAbiChecker.Ref_dump_dirs { 1694 optInDumpDirPath := android.PathForModuleSrc(ctx, optInDumpDir) 1695 // Ref_dump_dirs are not versioned. 1696 // They do not contain subdir for binder bitness because 64-bit binder has been mandatory. 1697 optInDumpFile := getRefAbiDumpFile(ctx, optInDumpDirPath.String(), fileName) 1698 if !optInDumpFile.Valid() { 1699 continue 1700 } 1701 library.optInAbiDiff(ctx, 1702 implDump, optInDumpFile.Path(), 1703 fileName, "opt"+strconv.Itoa(i), optInDumpDirPath.String(), string(optInTags[0])) 1704 } 1705 } 1706} 1707 1708// link registers actions to link this library, and sets various fields 1709// on this library to reflect information that should be exported up the build 1710// tree (for example, exported flags and include paths). 1711func (library *libraryDecorator) link(ctx ModuleContext, 1712 flags Flags, deps PathDeps, objs Objects) android.Path { 1713 1714 if ctx.IsLlndk() { 1715 // override the module's export_include_dirs with llndk.override_export_include_dirs 1716 // if it is set. 1717 if override := library.Properties.Llndk.Override_export_include_dirs; override != nil { 1718 library.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string]( 1719 nil, 1720 []proptools.ConfigurableCase[[]string]{ 1721 proptools.NewConfigurableCase[[]string](nil, &override), 1722 }, 1723 ) 1724 } 1725 1726 if Bool(library.Properties.Llndk.Export_headers_as_system) { 1727 library.flagExporter.Properties.Export_system_include_dirs = append( 1728 library.flagExporter.Properties.Export_system_include_dirs, 1729 library.flagExporter.Properties.Export_include_dirs.GetOrDefault(ctx, nil)...) 1730 library.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string](nil, nil) 1731 } 1732 } 1733 1734 if ctx.IsVendorPublicLibrary() { 1735 // override the module's export_include_dirs with vendor_public_library.override_export_include_dirs 1736 // if it is set. 1737 if override := library.Properties.Vendor_public_library.Override_export_include_dirs; override != nil { 1738 library.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string]( 1739 nil, 1740 []proptools.ConfigurableCase[[]string]{ 1741 proptools.NewConfigurableCase[[]string](nil, &override), 1742 }, 1743 ) 1744 } 1745 } 1746 1747 // Linking this library consists of linking `deps.Objs` (.o files in dependencies 1748 // of this library), together with `objs` (.o files created by compiling this 1749 // library). 1750 objs = deps.Objs.Copy().Append(objs) 1751 var out android.Path 1752 if library.static() || library.header() { 1753 out = library.linkStatic(ctx, flags, deps, objs) 1754 } else { 1755 out = library.linkShared(ctx, flags, deps, objs) 1756 } 1757 1758 // Export include paths and flags to be propagated up the tree. 1759 library.exportIncludes(ctx) 1760 library.reexportDirs(deps.ReexportedDirs...) 1761 library.reexportSystemDirs(deps.ReexportedSystemDirs...) 1762 library.reexportFlags(deps.ReexportedFlags...) 1763 library.reexportDeps(deps.ReexportedDeps...) 1764 library.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...) 1765 1766 if library.static() && len(deps.ReexportedRustRlibDeps) > 0 { 1767 library.reexportRustStaticDeps(deps.ReexportedRustRlibDeps...) 1768 } 1769 1770 // Optionally export aidl headers. 1771 if Bool(library.Properties.Aidl.Export_aidl_headers) { 1772 if library.baseCompiler.hasAidl(ctx, deps) { 1773 if library.baseCompiler.hasSrcExt(ctx, ".aidl") { 1774 dir := android.PathForModuleGen(ctx, "aidl") 1775 library.reexportDirs(dir) 1776 } 1777 if len(deps.AidlLibraryInfos) > 0 { 1778 dir := android.PathForModuleGen(ctx, "aidl_library") 1779 library.reexportDirs(dir) 1780 } 1781 1782 library.reexportDeps(library.baseCompiler.aidlOrderOnlyDeps...) 1783 library.addExportedGeneratedHeaders(library.baseCompiler.aidlHeaders...) 1784 } 1785 } 1786 1787 // Optionally export proto headers. 1788 if Bool(library.Properties.Proto.Export_proto_headers) { 1789 if library.baseCompiler.hasSrcExt(ctx, ".proto") { 1790 var includes android.Paths 1791 if flags.proto.CanonicalPathFromRoot { 1792 includes = append(includes, flags.proto.SubDir) 1793 } 1794 includes = append(includes, flags.proto.Dir) 1795 library.reexportDirs(includes...) 1796 1797 library.reexportDeps(library.baseCompiler.protoOrderOnlyDeps...) 1798 library.addExportedGeneratedHeaders(library.baseCompiler.protoHeaders...) 1799 } 1800 } 1801 1802 // If the library is sysprop_library, expose either public or internal header selectively. 1803 if library.baseCompiler.hasSrcExt(ctx, ".sysprop") { 1804 dir := android.PathForModuleGen(ctx, "sysprop", "include") 1805 if library.Properties.Sysprop.Platform != nil { 1806 isOwnerPlatform := Bool(library.Properties.Sysprop.Platform) 1807 1808 // If the owner is different from the user, expose public header. That is, 1809 // 1) if the user is product (as owner can only be platform / vendor) 1810 // 2) if the owner is platform and the client is vendor 1811 // We don't care Platform -> Vendor dependency as it's already forbidden. 1812 if ctx.Device() && (ctx.ProductSpecific() || (isOwnerPlatform && ctx.inVendor())) { 1813 dir = android.PathForModuleGen(ctx, "sysprop/public", "include") 1814 } 1815 } 1816 1817 // Make sure to only export headers which are within the include directory. 1818 _, headers := android.FilterPathListPredicate(library.baseCompiler.syspropHeaders, func(path android.Path) bool { 1819 _, isRel := android.MaybeRel(ctx, dir.String(), path.String()) 1820 return isRel 1821 }) 1822 1823 // Add sysprop-related directories to the exported directories of this library. 1824 library.reexportDirs(dir) 1825 library.reexportDeps(library.baseCompiler.syspropOrderOnlyDeps...) 1826 library.addExportedGeneratedHeaders(headers...) 1827 } 1828 1829 // Add stub-related flags if this library is a stub library. 1830 library.exportVersioningMacroIfNeeded(ctx) 1831 1832 // Propagate a Provider containing information about exported flags, deps, and include paths. 1833 library.flagExporter.setProvider(ctx) 1834 1835 return out 1836} 1837 1838func (library *libraryDecorator) exportVersioningMacroIfNeeded(ctx android.BaseModuleContext) { 1839 if library.BuildStubs() && library.StubsVersion() != "" && !library.skipAPIDefine { 1840 name := versioningMacroName(ctx.Module().(*Module).ImplementationModuleName(ctx)) 1841 apiLevel, err := android.ApiLevelFromUser(ctx, library.StubsVersion()) 1842 if err != nil { 1843 ctx.ModuleErrorf("Can't export version macro: %s", err.Error()) 1844 } 1845 library.reexportFlags("-D" + name + "=" + strconv.Itoa(apiLevel.FinalOrPreviewInt())) 1846 } 1847} 1848 1849// buildStatic returns true if this library should be built as a static library. 1850func (library *libraryDecorator) buildStatic() bool { 1851 return library.MutatedProperties.BuildStatic && 1852 BoolDefault(library.StaticProperties.Static.Enabled, true) 1853} 1854 1855// buildShared returns true if this library should be built as a shared library. 1856func (library *libraryDecorator) buildShared() bool { 1857 return library.MutatedProperties.BuildShared && 1858 BoolDefault(library.SharedProperties.Shared.Enabled, true) 1859} 1860 1861func (library *libraryDecorator) objs() Objects { 1862 return library.objects 1863} 1864 1865func (library *libraryDecorator) reuseObjs() Objects { 1866 return library.reuseObjects 1867} 1868 1869func (library *libraryDecorator) toc() android.OptionalPath { 1870 return library.tocFile 1871} 1872 1873func (library *libraryDecorator) installSymlinkToRuntimeApex(ctx ModuleContext, file android.Path) { 1874 dir := library.baseInstaller.installDir(ctx) 1875 dirOnDevice := android.InstallPathToOnDevicePath(ctx, dir) 1876 // libc_hwasan has relative_install_dir set, which would mess up the dir.Base() logic. 1877 // hardcode here because it's the only target, if we have other targets that use this 1878 // we can generalise this. 1879 var target string 1880 if ctx.baseModuleName() == "libc_hwasan" { 1881 target = "/" + filepath.Join("apex", "com.android.runtime", "lib64", "bionic", "hwasan", file.Base()) 1882 } else { 1883 base := dir.Base() 1884 target = "/" + filepath.Join("apex", "com.android.runtime", base, "bionic", file.Base()) 1885 } 1886 ctx.InstallAbsoluteSymlink(dir, file.Base(), target) 1887 library.postInstallCmds = append(library.postInstallCmds, makeSymlinkCmd(dirOnDevice, file.Base(), target)) 1888} 1889 1890func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) { 1891 if library.shared() { 1892 translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled 1893 if library.HasStubsVariants() && !ctx.Host() && !ctx.isSdkVariant() && 1894 InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.BuildStubs() && 1895 !translatedArch && !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() { 1896 // Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory. 1897 // The original path becomes a symlink to the corresponding file in the 1898 // runtime APEX. 1899 if ctx.Device() { 1900 library.installSymlinkToRuntimeApex(ctx, file) 1901 } 1902 library.baseInstaller.subDir = "bootstrap" 1903 } 1904 1905 library.baseInstaller.install(ctx, file) 1906 } 1907 1908 if Bool(library.Properties.Static_ndk_lib) && library.static() && 1909 !ctx.InVendorOrProduct() && !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() && ctx.Device() && 1910 library.baseLinker.sanitize.isUnsanitizedVariant() && 1911 CtxIsForPlatform(ctx) && !ctx.isPreventInstall() { 1912 installPath := getUnversionedLibraryInstallPath(ctx).Join(ctx, file.Base()) 1913 1914 ctx.ModuleBuild(pctx, android.ModuleBuildParams{ 1915 Rule: android.Cp, 1916 Description: "install " + installPath.Base(), 1917 Output: installPath, 1918 Input: file, 1919 }) 1920 1921 library.ndkSysrootPath = installPath 1922 } 1923} 1924 1925func (library *libraryDecorator) everInstallable() bool { 1926 // Only shared and static libraries are installed. Header libraries (which are 1927 // neither static or shared) are not installed. 1928 return library.shared() || library.static() 1929} 1930 1931// static returns true if this library is for a "static" variant. 1932func (library *libraryDecorator) static() bool { 1933 return library.MutatedProperties.VariantIsStatic 1934} 1935 1936// staticLibrary returns true if this library is for a "static"" variant. 1937func (library *libraryDecorator) staticLibrary() bool { 1938 return library.static() 1939} 1940 1941// shared returns true if this library is for a "shared" variant. 1942func (library *libraryDecorator) shared() bool { 1943 return library.MutatedProperties.VariantIsShared 1944} 1945 1946// header returns true if this library is for a header-only variant. 1947func (library *libraryDecorator) header() bool { 1948 // Neither "static" nor "shared" implies this library is header-only. 1949 return !library.static() && !library.shared() 1950} 1951 1952// setStatic marks the library variant as "static". 1953func (library *libraryDecorator) setStatic() { 1954 library.MutatedProperties.VariantIsStatic = true 1955 library.MutatedProperties.VariantIsShared = false 1956} 1957 1958// setShared marks the library variant as "shared". 1959func (library *libraryDecorator) setShared() { 1960 library.MutatedProperties.VariantIsStatic = false 1961 library.MutatedProperties.VariantIsShared = true 1962} 1963 1964// BuildOnlyStatic disables building this library as a shared library. 1965func (library *libraryDecorator) BuildOnlyStatic() { 1966 library.MutatedProperties.BuildShared = false 1967} 1968 1969// BuildOnlyShared disables building this library as a static library. 1970func (library *libraryDecorator) BuildOnlyShared() { 1971 library.MutatedProperties.BuildStatic = false 1972} 1973 1974// HeaderOnly disables building this library as a shared or static library; 1975// the library only exists to propagate header file dependencies up the build graph. 1976func (library *libraryDecorator) HeaderOnly() { 1977 library.MutatedProperties.BuildShared = false 1978 library.MutatedProperties.BuildStatic = false 1979} 1980 1981// HasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs. 1982func (library *libraryDecorator) HasLLNDKStubs() bool { 1983 return String(library.Properties.Llndk.Symbol_file) != "" 1984} 1985 1986// hasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs. 1987func (library *libraryDecorator) HasLLNDKHeaders() bool { 1988 return Bool(library.Properties.Llndk.Llndk_headers) 1989} 1990 1991// IsLLNDKMovedToApex returns true if this cc_library module sets the llndk.moved_to_apex property. 1992func (library *libraryDecorator) IsLLNDKMovedToApex() bool { 1993 return Bool(library.Properties.Llndk.Moved_to_apex) 1994} 1995 1996// HasVendorPublicLibrary returns true if this cc_library module has a variant that will build 1997// vendor public library stubs. 1998func (library *libraryDecorator) HasVendorPublicLibrary() bool { 1999 return String(library.Properties.Vendor_public_library.Symbol_file) != "" 2000} 2001 2002func (library *libraryDecorator) ImplementationModuleName(name string) string { 2003 return name 2004} 2005 2006func (library *libraryDecorator) BuildStubs() bool { 2007 return library.MutatedProperties.BuildStubs 2008} 2009 2010func (library *libraryDecorator) symbolFileForAbiCheck(ctx ModuleContext) *string { 2011 if props := library.getHeaderAbiCheckerProperties(ctx.Module().(*Module)); props.Symbol_file != nil { 2012 return props.Symbol_file 2013 } 2014 if library.HasStubsVariants() && library.Properties.Stubs.Symbol_file != nil { 2015 return library.Properties.Stubs.Symbol_file 2016 } 2017 // TODO(b/309880485): Distinguish platform, NDK, LLNDK, and APEX version scripts. 2018 if library.baseLinker.Properties.Version_script != nil { 2019 return library.baseLinker.Properties.Version_script 2020 } 2021 return nil 2022} 2023 2024func (library *libraryDecorator) HasStubsVariants() bool { 2025 // Just having stubs.symbol_file is enough to create a stub variant. In that case 2026 // the stub for the future API level is created. 2027 return library.Properties.Stubs.Symbol_file != nil || 2028 len(library.Properties.Stubs.Versions) > 0 2029} 2030 2031func (library *libraryDecorator) IsStubsImplementationRequired() bool { 2032 return BoolDefault(library.Properties.Stubs.Implementation_installable, true) 2033} 2034 2035func (library *libraryDecorator) StubsVersions(ctx android.BaseModuleContext) []string { 2036 if !library.HasStubsVariants() { 2037 return nil 2038 } 2039 2040 if library.HasLLNDKStubs() && ctx.Module().(*Module).InVendorOrProduct() { 2041 // LLNDK libraries only need a single stubs variant (""), which is 2042 // added automatically in createVersionVariations(). 2043 return nil 2044 } 2045 2046 // Future API level is implicitly added if there isn't 2047 versions := AddCurrentVersionIfNotPresent(library.Properties.Stubs.Versions) 2048 NormalizeVersions(ctx, versions) 2049 return versions 2050} 2051 2052func AddCurrentVersionIfNotPresent(vers []string) []string { 2053 if inList(android.FutureApiLevel.String(), vers) { 2054 return vers 2055 } 2056 // In some cases, people use the raw value "10000" in the versions property. 2057 // We shouldn't add the future API level in that case, otherwise there will 2058 // be two identical versions. 2059 if inList(strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt()), vers) { 2060 return vers 2061 } 2062 return append(vers, android.FutureApiLevel.String()) 2063} 2064 2065func (library *libraryDecorator) SetStubsVersion(version string) { 2066 library.MutatedProperties.StubsVersion = version 2067} 2068 2069func (library *libraryDecorator) StubsVersion() string { 2070 return library.MutatedProperties.StubsVersion 2071} 2072 2073func (library *libraryDecorator) SetBuildStubs(isLatest bool) { 2074 library.MutatedProperties.BuildStubs = true 2075 library.MutatedProperties.IsLatestVersion = isLatest 2076} 2077 2078func (library *libraryDecorator) SetAllStubsVersions(versions []string) { 2079 library.MutatedProperties.AllStubsVersions = versions 2080} 2081 2082func (library *libraryDecorator) AllStubsVersions() []string { 2083 return library.MutatedProperties.AllStubsVersions 2084} 2085 2086func (library *libraryDecorator) isLatestStubVersion() bool { 2087 return library.MutatedProperties.IsLatestVersion 2088} 2089 2090func (library *libraryDecorator) apexAvailable() []string { 2091 var list []string 2092 if library.static() { 2093 list = library.StaticProperties.Static.Apex_available 2094 } else if library.shared() { 2095 list = library.SharedProperties.Shared.Apex_available 2096 } 2097 2098 return list 2099} 2100 2101func (library *libraryDecorator) installable() *bool { 2102 if library.static() { 2103 return library.StaticProperties.Static.Installable 2104 } else if library.shared() { 2105 return library.SharedProperties.Shared.Installable 2106 } 2107 return nil 2108} 2109 2110func (library *libraryDecorator) makeUninstallable(mod *Module) { 2111 if library.static() && library.buildStatic() && !library.BuildStubs() { 2112 // If we're asked to make a static library uninstallable we don't do 2113 // anything since AndroidMkEntries always sets LOCAL_UNINSTALLABLE_MODULE 2114 // for these entries. This is done to still get the make targets for NOTICE 2115 // files from notice_files.mk, which other libraries might depend on. 2116 return 2117 } 2118 mod.ModuleBase.MakeUninstallable() 2119} 2120 2121func (library *libraryDecorator) getPartition() string { 2122 return library.path.Partition() 2123} 2124 2125func (library *libraryDecorator) GetAPIListCoverageXMLPath() android.ModuleOutPath { 2126 return library.apiListCoverageXmlPath 2127} 2128 2129func (library *libraryDecorator) setAPIListCoverageXMLPath(xml android.ModuleOutPath) { 2130 library.apiListCoverageXmlPath = xml 2131} 2132 2133func (library *libraryDecorator) overriddenModules() []string { 2134 return library.Properties.Overrides 2135} 2136 2137func (library *libraryDecorator) defaultDistFiles() []android.Path { 2138 if library.defaultDistFile == nil { 2139 return nil 2140 } 2141 return []android.Path{library.defaultDistFile} 2142} 2143 2144var _ overridable = (*libraryDecorator)(nil) 2145 2146var versioningMacroNamesListKey = android.NewOnceKey("versioningMacroNamesList") 2147 2148// versioningMacroNamesList returns a singleton map, where keys are "version macro names", 2149// and values are the module name responsible for registering the version macro name. 2150// 2151// Version macros are used when building against stubs, to provide version information about 2152// the stub. Only stub libraries should have an entry in this list. 2153// 2154// For example, when building against libFoo#ver, __LIBFOO_API__ macro is set to ver so 2155// that headers from libFoo can be conditionally compiled (this may hide APIs 2156// that are not available for the version). 2157// 2158// This map is used to ensure that there aren't conflicts between these version macro names. 2159func versioningMacroNamesList(config android.Config) *map[string]string { 2160 return config.Once(versioningMacroNamesListKey, func() interface{} { 2161 m := make(map[string]string) 2162 return &m 2163 }).(*map[string]string) 2164} 2165 2166// alphanumeric and _ characters are preserved. 2167// other characters are all converted to _ 2168var charsNotForMacro = regexp.MustCompile("[^a-zA-Z0-9_]+") 2169 2170// versioningMacroName returns the canonical version macro name for the given module. 2171func versioningMacroName(moduleName string) string { 2172 macroName := charsNotForMacro.ReplaceAllString(moduleName, "_") 2173 macroName = strings.ToUpper(macroName) 2174 return "__" + macroName + "_API__" 2175} 2176 2177// NewLibrary builds and returns a new Module corresponding to a C++ library. 2178// Individual module implementations which comprise a C++ library (or something like 2179// a C++ library) should call this function, set some fields on the result, and 2180// then call the Init function. 2181func NewLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { 2182 module := newModule(hod, android.MultilibBoth) 2183 2184 library := &libraryDecorator{ 2185 MutatedProperties: LibraryMutatedProperties{ 2186 BuildShared: true, 2187 BuildStatic: true, 2188 }, 2189 baseCompiler: NewBaseCompiler(), 2190 baseLinker: NewBaseLinker(module.sanitize), 2191 baseInstaller: NewBaseInstaller("lib", "lib64", InstallInSystem), 2192 sabi: module.sabi, 2193 } 2194 2195 module.compiler = library 2196 module.linker = library 2197 module.installer = library 2198 module.library = library 2199 2200 return module, library 2201} 2202 2203// connects a shared library to a static library in order to reuse its .o files to avoid 2204// compiling source files twice. 2205func reuseStaticLibrary(ctx android.BottomUpMutatorContext, shared *Module) { 2206 if sharedCompiler, ok := shared.compiler.(*libraryDecorator); ok { 2207 2208 // Check libraries in addition to cflags, since libraries may be exporting different 2209 // include directories. 2210 if len(sharedCompiler.StaticProperties.Static.Cflags.GetOrDefault(ctx, nil)) == 0 && 2211 len(sharedCompiler.SharedProperties.Shared.Cflags.GetOrDefault(ctx, nil)) == 0 && 2212 len(sharedCompiler.StaticProperties.Static.Whole_static_libs.GetOrDefault(ctx, nil)) == 0 && 2213 len(sharedCompiler.SharedProperties.Shared.Whole_static_libs.GetOrDefault(ctx, nil)) == 0 && 2214 len(sharedCompiler.StaticProperties.Static.Static_libs.GetOrDefault(ctx, nil)) == 0 && 2215 len(sharedCompiler.SharedProperties.Shared.Static_libs.GetOrDefault(ctx, nil)) == 0 && 2216 len(sharedCompiler.StaticProperties.Static.Shared_libs.GetOrDefault(ctx, nil)) == 0 && 2217 len(sharedCompiler.SharedProperties.Shared.Shared_libs.GetOrDefault(ctx, nil)) == 0 && 2218 // Compare System_shared_libs properties with nil because empty lists are 2219 // semantically significant for them. 2220 sharedCompiler.StaticProperties.Static.System_shared_libs == nil && 2221 sharedCompiler.SharedProperties.Shared.System_shared_libs == nil { 2222 2223 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, reuseObjTag, ctx.ModuleName()) 2224 } 2225 2226 // This dep is just to reference static variant from shared variant 2227 ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticVariantTag, ctx.ModuleName()) 2228 } 2229} 2230 2231// linkageTransitionMutator adds "static" or "shared" variants for modules depending 2232// on whether the module can be built as a static library or a shared library. 2233type linkageTransitionMutator struct{} 2234 2235func (linkageTransitionMutator) Split(ctx android.BaseModuleContext) []string { 2236 ccPrebuilt := false 2237 if m, ok := ctx.Module().(*Module); ok && m.linker != nil { 2238 _, ccPrebuilt = m.linker.(prebuiltLibraryInterface) 2239 } 2240 if ccPrebuilt { 2241 library := ctx.Module().(*Module).linker.(prebuiltLibraryInterface) 2242 2243 // Differentiate between header only and building an actual static/shared library 2244 buildStatic := library.buildStatic() 2245 buildShared := library.buildShared() 2246 if buildStatic || buildShared { 2247 // Always create both the static and shared variants for prebuilt libraries, and then disable the one 2248 // that is not being used. This allows them to share the name of a cc_library module, which requires that 2249 // all the variants of the cc_library also exist on the prebuilt. 2250 return []string{"static", "shared"} 2251 } else { 2252 // Header only 2253 } 2254 } else if library, ok := ctx.Module().(LinkableInterface); ok && (library.CcLibraryInterface()) { 2255 // Non-cc.Modules may need an empty variant for their mutators. 2256 variations := []string{} 2257 if library.NonCcVariants() { 2258 variations = append(variations, "") 2259 } 2260 isLLNDK := false 2261 if m, ok := ctx.Module().(*Module); ok { 2262 isLLNDK = m.IsLlndk() 2263 } 2264 buildStatic := library.BuildStaticVariant() && !isLLNDK 2265 buildShared := library.BuildSharedVariant() 2266 if buildStatic && buildShared { 2267 variations = append([]string{"static", "shared"}, variations...) 2268 return variations 2269 } else if buildStatic { 2270 variations = append([]string{"static"}, variations...) 2271 } else if buildShared { 2272 variations = append([]string{"shared"}, variations...) 2273 } 2274 2275 if len(variations) > 0 { 2276 return variations 2277 } 2278 } 2279 return []string{""} 2280} 2281 2282func (linkageTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string { 2283 if ctx.DepTag() == android.PrebuiltDepTag { 2284 return sourceVariation 2285 } 2286 return "" 2287} 2288 2289func (linkageTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string { 2290 ccPrebuilt := false 2291 if m, ok := ctx.Module().(*Module); ok && m.linker != nil { 2292 _, ccPrebuilt = m.linker.(prebuiltLibraryInterface) 2293 } 2294 if ccPrebuilt { 2295 if incomingVariation != "" { 2296 return incomingVariation 2297 } 2298 library := ctx.Module().(*Module).linker.(prebuiltLibraryInterface) 2299 if library.buildShared() { 2300 return "shared" 2301 } else if library.buildStatic() { 2302 return "static" 2303 } 2304 return "" 2305 } else if library, ok := ctx.Module().(LinkableInterface); ok && library.CcLibraryInterface() { 2306 isLLNDK := false 2307 if m, ok := ctx.Module().(*Module); ok { 2308 isLLNDK = m.IsLlndk() 2309 } 2310 buildStatic := library.BuildStaticVariant() && !isLLNDK 2311 buildShared := library.BuildSharedVariant() 2312 if library.BuildRlibVariant() && !buildStatic && (incomingVariation == "static" || incomingVariation == "") { 2313 // Rust modules do not build static libs, but rlibs are used as if they 2314 // were via `static_libs`. Thus we need to alias the BuildRlibVariant 2315 // to "static" for Rust FFI libraries. 2316 return "" 2317 } 2318 if incomingVariation != "" { 2319 return incomingVariation 2320 } 2321 if buildShared { 2322 return "shared" 2323 } else if buildStatic { 2324 return "static" 2325 } 2326 return "" 2327 } 2328 return "" 2329} 2330 2331func (linkageTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) { 2332 ccPrebuilt := false 2333 if m, ok := ctx.Module().(*Module); ok && m.linker != nil { 2334 _, ccPrebuilt = m.linker.(prebuiltLibraryInterface) 2335 } 2336 if ccPrebuilt { 2337 library := ctx.Module().(*Module).linker.(prebuiltLibraryInterface) 2338 if variation == "static" { 2339 library.setStatic() 2340 if !library.buildStatic() { 2341 library.disablePrebuilt() 2342 ctx.Module().(*Module).Prebuilt().SetUsePrebuilt(false) 2343 } 2344 } else if variation == "shared" { 2345 library.setShared() 2346 if !library.buildShared() { 2347 library.disablePrebuilt() 2348 ctx.Module().(*Module).Prebuilt().SetUsePrebuilt(false) 2349 } 2350 } 2351 } else if library, ok := ctx.Module().(LinkableInterface); ok && library.CcLibraryInterface() { 2352 if variation == "static" { 2353 library.SetStatic() 2354 } else if variation == "shared" { 2355 library.SetShared() 2356 var isLLNDK bool 2357 if m, ok := ctx.Module().(*Module); ok { 2358 isLLNDK = m.IsLlndk() 2359 } 2360 buildStatic := library.BuildStaticVariant() && !isLLNDK 2361 buildShared := library.BuildSharedVariant() 2362 if buildStatic && buildShared { 2363 if _, ok := library.(*Module); ok { 2364 reuseStaticLibrary(ctx, library.(*Module)) 2365 } 2366 } 2367 } 2368 } 2369} 2370 2371// NormalizeVersions modifies `versions` in place, so that each raw version 2372// string becomes its normalized canonical form. 2373// Validates that the versions in `versions` are specified in least to greatest order. 2374func NormalizeVersions(ctx android.BaseModuleContext, versions []string) { 2375 var previous android.ApiLevel 2376 for i, v := range versions { 2377 ver, err := android.ApiLevelFromUser(ctx, v) 2378 if err != nil { 2379 ctx.PropertyErrorf("versions", "%s", err.Error()) 2380 return 2381 } 2382 if i > 0 && ver.LessThanOrEqualTo(previous) { 2383 ctx.PropertyErrorf("versions", "not sorted: %v", versions) 2384 } 2385 versions[i] = ver.String() 2386 previous = ver 2387 } 2388} 2389 2390func perApiVersionVariations(mctx android.BaseModuleContext, minSdkVersion string) []string { 2391 from, err := NativeApiLevelFromUser(mctx, minSdkVersion) 2392 if err != nil { 2393 mctx.PropertyErrorf("min_sdk_version", err.Error()) 2394 return []string{""} 2395 } 2396 2397 return ndkLibraryVersions(mctx, from) 2398} 2399 2400func canBeOrLinkAgainstVersionVariants(module interface { 2401 Host() bool 2402 InRamdisk() bool 2403 InVendorRamdisk() bool 2404}) bool { 2405 return !module.Host() && !module.InRamdisk() && !module.InVendorRamdisk() 2406} 2407 2408func canBeVersionVariant(module interface { 2409 Host() bool 2410 InRamdisk() bool 2411 InVendorRamdisk() bool 2412 CcLibraryInterface() bool 2413 Shared() bool 2414}) bool { 2415 return canBeOrLinkAgainstVersionVariants(module) && 2416 module.CcLibraryInterface() && module.Shared() 2417} 2418 2419func moduleVersionedInterface(module blueprint.Module) VersionedInterface { 2420 if m, ok := module.(VersionedLinkableInterface); ok { 2421 return m.VersionedInterface() 2422 } 2423 return nil 2424} 2425 2426// setStubsVersions normalizes the versions in the Stubs.Versions property into MutatedProperties.AllStubsVersions. 2427func setStubsVersions(mctx android.BaseModuleContext, module VersionedLinkableInterface) { 2428 if !module.BuildSharedVariant() || !canBeVersionVariant(module) { 2429 return 2430 } 2431 versions := module.VersionedInterface().StubsVersions(mctx) 2432 if mctx.Failed() { 2433 return 2434 } 2435 // Set the versions on the pre-mutated module so they can be read by any llndk modules that 2436 // depend on the implementation library and haven't been mutated yet. 2437 module.VersionedInterface().SetAllStubsVersions(versions) 2438} 2439 2440// versionTransitionMutator splits a module into the mandatory non-stubs variant 2441// (which is unnamed) and zero or more stubs variants. 2442type versionTransitionMutator struct{} 2443 2444func (versionTransitionMutator) Split(ctx android.BaseModuleContext) []string { 2445 if ctx.Os() != android.Android { 2446 return []string{""} 2447 } 2448 if m, ok := ctx.Module().(VersionedLinkableInterface); ok { 2449 if m.CcLibraryInterface() && canBeVersionVariant(m) { 2450 setStubsVersions(ctx, m) 2451 return append(slices.Clone(m.VersionedInterface().AllStubsVersions()), "") 2452 } else if m.SplitPerApiLevel() && m.IsSdkVariant() { 2453 return perApiVersionVariations(ctx, m.MinSdkVersion()) 2454 } 2455 } 2456 2457 return []string{""} 2458} 2459 2460func (versionTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string { 2461 if ctx.DepTag() == android.PrebuiltDepTag { 2462 return sourceVariation 2463 } 2464 return "" 2465} 2466 2467func (versionTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string { 2468 if ctx.Os() != android.Android { 2469 return "" 2470 } 2471 m, ok := ctx.Module().(VersionedLinkableInterface) 2472 if library := moduleVersionedInterface(ctx.Module()); library != nil && canBeVersionVariant(m) { 2473 if incomingVariation == "latest" { 2474 latestVersion := "" 2475 versions := library.AllStubsVersions() 2476 if len(versions) > 0 { 2477 latestVersion = versions[len(versions)-1] 2478 } 2479 return latestVersion 2480 } 2481 return incomingVariation 2482 } else if ok && m.SplitPerApiLevel() && m.IsSdkVariant() { 2483 // If this module only has variants with versions and the incoming dependency doesn't specify which one 2484 // is needed then assume the latest version. 2485 if incomingVariation == "" { 2486 return android.FutureApiLevel.String() 2487 } 2488 return incomingVariation 2489 } 2490 2491 return "" 2492} 2493 2494func (versionTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) { 2495 // Optimization: return early if this module can't be affected. 2496 if ctx.Os() != android.Android { 2497 return 2498 } 2499 2500 m, ok := ctx.Module().(VersionedLinkableInterface) 2501 if library := moduleVersionedInterface(ctx.Module()); library != nil && canBeVersionVariant(m) { 2502 isLLNDK := m.IsLlndk() 2503 isVendorPublicLibrary := m.IsVendorPublicLibrary() 2504 2505 if variation != "" || isLLNDK || isVendorPublicLibrary { 2506 // A stubs or LLNDK stubs variant. 2507 if sm, ok := ctx.Module().(PlatformSanitizeable); ok && sm.SanitizePropDefined() { 2508 sm.ForceDisableSanitizers() 2509 } 2510 m.SetStl("none") 2511 m.SetPreventInstall() 2512 allStubsVersions := m.VersionedInterface().AllStubsVersions() 2513 isLatest := len(allStubsVersions) > 0 && variation == allStubsVersions[len(allStubsVersions)-1] 2514 m.VersionedInterface().SetBuildStubs(isLatest) 2515 } 2516 if variation != "" { 2517 // A non-LLNDK stubs module is hidden from make 2518 m.VersionedInterface().SetStubsVersion(variation) 2519 m.SetHideFromMake() 2520 } else { 2521 // A non-LLNDK implementation module has a dependency to all stubs versions 2522 for _, version := range m.VersionedInterface().AllStubsVersions() { 2523 ctx.AddVariationDependencies( 2524 []blueprint.Variation{ 2525 {Mutator: "version", Variation: version}, 2526 {Mutator: "link", Variation: "shared"}}, 2527 StubImplDepTag, ctx.ModuleName()) 2528 } 2529 } 2530 } else if ok && m.SplitPerApiLevel() && m.IsSdkVariant() { 2531 m.SetSdkVersion(variation) 2532 m.SetMinSdkVersion(variation) 2533 } 2534} 2535 2536// maybeInjectBoringSSLHash adds a rule to run bssl_inject_hash on the output file if the module has the 2537// inject_bssl_hash or if any static library dependencies have inject_bssl_hash set. It returns the output path 2538// that the linked output file should be written to. 2539// TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries. 2540func maybeInjectBoringSSLHash(ctx android.ModuleContext, outputFile android.ModuleOutPath, 2541 inject *bool, fileName string) android.ModuleOutPath { 2542 // TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries. 2543 injectBoringSSLHash := Bool(inject) 2544 ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) { 2545 if tag, ok := ctx.OtherModuleDependencyTag(dep).(libraryDependencyTag); ok && tag.static() { 2546 if ccInfo, ok := android.OtherModuleProvider(ctx, dep, CcInfoProvider); ok && 2547 ccInfo.LinkerInfo != nil && ccInfo.LinkerInfo.LibraryDecoratorInfo != nil { 2548 if ccInfo.LinkerInfo.LibraryDecoratorInfo.InjectBsslHash { 2549 injectBoringSSLHash = true 2550 } 2551 } 2552 } 2553 }) 2554 if injectBoringSSLHash { 2555 hashedOutputfile := outputFile 2556 outputFile = android.PathForModuleOut(ctx, "unhashed", fileName) 2557 2558 rule := android.NewRuleBuilder(pctx, ctx) 2559 rule.Command(). 2560 BuiltTool("bssl_inject_hash"). 2561 FlagWithInput("-in-object ", outputFile). 2562 FlagWithOutput("-o ", hashedOutputfile) 2563 rule.Build("injectCryptoHash", "inject crypto hash") 2564 } 2565 2566 return outputFile 2567} 2568