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 "strconv" 23 "strings" 24 "sync" 25 26 "android/soong/android" 27 "android/soong/bazel" 28 "android/soong/bazel/cquery" 29 "android/soong/cc/config" 30 31 "github.com/google/blueprint" 32 "github.com/google/blueprint/pathtools" 33) 34 35// LibraryProperties is a collection of properties shared by cc library rules/cc. 36type LibraryProperties struct { 37 // local file name to pass to the linker as -unexported_symbols_list 38 Unexported_symbols_list *string `android:"path,arch_variant"` 39 // local file name to pass to the linker as -force_symbols_not_weak_list 40 Force_symbols_not_weak_list *string `android:"path,arch_variant"` 41 // local file name to pass to the linker as -force_symbols_weak_list 42 Force_symbols_weak_list *string `android:"path,arch_variant"` 43 44 // rename host libraries to prevent overlap with system installed libraries 45 Unique_host_soname *bool 46 47 Aidl struct { 48 // export headers generated from .aidl sources 49 Export_aidl_headers *bool 50 } 51 52 Proto struct { 53 // export headers generated from .proto sources 54 Export_proto_headers *bool 55 } 56 57 Sysprop struct { 58 // Whether platform owns this sysprop library. 59 Platform *bool 60 } `blueprint:"mutated"` 61 62 Static_ndk_lib *bool 63 64 // Generate stubs to make this library accessible to APEXes. 65 Stubs struct { 66 // Relative path to the symbol map. The symbol map provides the list of 67 // symbols that are exported for stubs variant of this library. 68 Symbol_file *string `android:"path"` 69 70 // List versions to generate stubs libs for. The version name "current" is always 71 // implicitly added. 72 Versions []string 73 } 74 75 // set the name of the output 76 Stem *string `android:"arch_variant"` 77 78 // set suffix of the name of the output 79 Suffix *string `android:"arch_variant"` 80 81 Target struct { 82 Vendor, Product struct { 83 // set suffix of the name of the output 84 Suffix *string `android:"arch_variant"` 85 } 86 } 87 88 // Names of modules to be overridden. Listed modules can only be other shared libraries 89 // (in Make or Soong). 90 // This does not completely prevent installation of the overridden libraries, but if both 91 // binaries would be installed by default (in PRODUCT_PACKAGES) the other library will be removed 92 // from PRODUCT_PACKAGES. 93 Overrides []string 94 95 // Properties for ABI compatibility checker 96 Header_abi_checker struct { 97 // Enable ABI checks (even if this is not an LLNDK/VNDK lib) 98 Enabled *bool 99 100 // Path to a symbol file that specifies the symbols to be included in the generated 101 // ABI dump file 102 Symbol_file *string `android:"path"` 103 104 // Symbol versions that should be ignored from the symbol file 105 Exclude_symbol_versions []string 106 107 // Symbol tags that should be ignored from the symbol file 108 Exclude_symbol_tags []string 109 110 // Run checks on all APIs (in addition to the ones referred by 111 // one of exported ELF symbols.) 112 Check_all_apis *bool 113 114 // Extra flags passed to header-abi-diff 115 Diff_flags []string 116 } 117 118 // Inject boringssl hash into the shared library. This is only intended for use by external/boringssl. 119 Inject_bssl_hash *bool `android:"arch_variant"` 120 121 // If this is an LLNDK library, properties to describe the LLNDK stubs. Will be copied from 122 // the module pointed to by llndk_stubs if it is set. 123 Llndk llndkLibraryProperties 124 125 // If this is a vendor public library, properties to describe the vendor public library stubs. 126 Vendor_public_library vendorPublicLibraryProperties 127} 128 129// StaticProperties is a properties stanza to affect only attributes of the "static" variants of a 130// library module. 131type StaticProperties struct { 132 Static StaticOrSharedProperties `android:"arch_variant"` 133} 134 135// SharedProperties is a properties stanza to affect only attributes of the "shared" variants of a 136// library module. 137type SharedProperties struct { 138 Shared StaticOrSharedProperties `android:"arch_variant"` 139} 140 141// StaticOrSharedProperties is an embedded struct representing properties to affect attributes of 142// either only the "static" variants or only the "shared" variants of a library module. These override 143// the base properties of the same name. 144// Use `StaticProperties` or `SharedProperties`, depending on which variant is needed. 145// `StaticOrSharedProperties` exists only to avoid duplication. 146type StaticOrSharedProperties struct { 147 Srcs []string `android:"path,arch_variant"` 148 149 Tidy_disabled_srcs []string `android:"path,arch_variant"` 150 151 Tidy_timeout_srcs []string `android:"path,arch_variant"` 152 153 Sanitized Sanitized `android:"arch_variant"` 154 155 Cflags []string `android:"arch_variant"` 156 157 Enabled *bool `android:"arch_variant"` 158 Whole_static_libs []string `android:"arch_variant"` 159 Static_libs []string `android:"arch_variant"` 160 Shared_libs []string `android:"arch_variant"` 161 System_shared_libs []string `android:"arch_variant"` 162 163 Export_shared_lib_headers []string `android:"arch_variant"` 164 Export_static_lib_headers []string `android:"arch_variant"` 165 166 Apex_available []string `android:"arch_variant"` 167 168 Installable *bool `android:"arch_variant"` 169} 170 171type LibraryMutatedProperties struct { 172 // Build a static variant 173 BuildStatic bool `blueprint:"mutated"` 174 // Build a shared variant 175 BuildShared bool `blueprint:"mutated"` 176 // This variant is shared 177 VariantIsShared bool `blueprint:"mutated"` 178 // This variant is static 179 VariantIsStatic bool `blueprint:"mutated"` 180 181 // This variant is a stubs lib 182 BuildStubs bool `blueprint:"mutated"` 183 // This variant is the latest version 184 IsLatestVersion bool `blueprint:"mutated"` 185 // Version of the stubs lib 186 StubsVersion string `blueprint:"mutated"` 187 // List of all stubs versions associated with an implementation lib 188 AllStubsVersions []string `blueprint:"mutated"` 189} 190 191type FlagExporterProperties struct { 192 // list of directories relative to the Blueprints file that will 193 // be added to the include path (using -I) for this module and any module that links 194 // against this module. Directories listed in export_include_dirs do not need to be 195 // listed in local_include_dirs. 196 Export_include_dirs []string `android:"arch_variant,variant_prepend"` 197 198 // list of directories that will be added to the system include path 199 // using -isystem for this module and any module that links against this module. 200 Export_system_include_dirs []string `android:"arch_variant,variant_prepend"` 201 202 Target struct { 203 Vendor, Product struct { 204 // list of exported include directories, like 205 // export_include_dirs, that will be applied to 206 // vendor or product variant of this library. 207 // This will overwrite any other declarations. 208 Override_export_include_dirs []string 209 } 210 } 211} 212 213func init() { 214 RegisterLibraryBuildComponents(android.InitRegistrationContext) 215} 216 217func RegisterLibraryBuildComponents(ctx android.RegistrationContext) { 218 ctx.RegisterModuleType("cc_library_static", LibraryStaticFactory) 219 ctx.RegisterModuleType("cc_library_shared", LibrarySharedFactory) 220 ctx.RegisterModuleType("cc_library", LibraryFactory) 221 ctx.RegisterModuleType("cc_library_host_static", LibraryHostStaticFactory) 222 ctx.RegisterModuleType("cc_library_host_shared", LibraryHostSharedFactory) 223} 224 225// TODO(b/199902614): Can this be factored to share with the other Attributes? 226// For bp2build conversion. 227type bazelCcLibraryAttributes struct { 228 // Attributes pertaining to both static and shared variants. 229 Srcs bazel.LabelListAttribute 230 Srcs_c bazel.LabelListAttribute 231 Srcs_as bazel.LabelListAttribute 232 233 Copts bazel.StringListAttribute 234 Cppflags bazel.StringListAttribute 235 Conlyflags bazel.StringListAttribute 236 Asflags bazel.StringListAttribute 237 238 Hdrs bazel.LabelListAttribute 239 240 Deps bazel.LabelListAttribute 241 Implementation_deps bazel.LabelListAttribute 242 Dynamic_deps bazel.LabelListAttribute 243 Implementation_dynamic_deps bazel.LabelListAttribute 244 Whole_archive_deps bazel.LabelListAttribute 245 Implementation_whole_archive_deps bazel.LabelListAttribute 246 System_dynamic_deps bazel.LabelListAttribute 247 248 Export_includes bazel.StringListAttribute 249 Export_system_includes bazel.StringListAttribute 250 Local_includes bazel.StringListAttribute 251 Absolute_includes bazel.StringListAttribute 252 Linkopts bazel.StringListAttribute 253 Use_libcrt bazel.BoolAttribute 254 Rtti bazel.BoolAttribute 255 256 Stl *string 257 Cpp_std *string 258 C_std *string 259 260 // This is shared only. 261 Link_crt bazel.BoolAttribute 262 Additional_linker_inputs bazel.LabelListAttribute 263 264 // Common properties shared between both shared and static variants. 265 Shared staticOrSharedAttributes 266 Static staticOrSharedAttributes 267 268 Strip stripAttributes 269 270 Features bazel.StringListAttribute 271} 272 273type stripAttributes struct { 274 Keep_symbols bazel.BoolAttribute 275 Keep_symbols_and_debug_frame bazel.BoolAttribute 276 Keep_symbols_list bazel.StringListAttribute 277 All bazel.BoolAttribute 278 None bazel.BoolAttribute 279} 280 281func libraryBp2Build(ctx android.TopDownMutatorContext, m *Module) { 282 // For some cc_library modules, their static variants are ready to be 283 // converted, but not their shared variants. For these modules, delegate to 284 // the cc_library_static bp2build converter temporarily instead. 285 if android.GenerateCcLibraryStaticOnly(ctx.Module().Name()) { 286 sharedOrStaticLibraryBp2Build(ctx, m, true) 287 return 288 } 289 290 sharedAttrs := bp2BuildParseSharedProps(ctx, m) 291 staticAttrs := bp2BuildParseStaticProps(ctx, m) 292 baseAttributes := bp2BuildParseBaseProps(ctx, m) 293 compilerAttrs := baseAttributes.compilerAttributes 294 linkerAttrs := baseAttributes.linkerAttributes 295 exportedIncludes := bp2BuildParseExportedIncludes(ctx, m, compilerAttrs.includes) 296 297 srcs := compilerAttrs.srcs 298 299 sharedAttrs.Dynamic_deps.Add(baseAttributes.protoDependency) 300 staticAttrs.Deps.Add(baseAttributes.protoDependency) 301 302 asFlags := compilerAttrs.asFlags 303 if compilerAttrs.asSrcs.IsEmpty() && sharedAttrs.Srcs_as.IsEmpty() && staticAttrs.Srcs_as.IsEmpty() { 304 // Skip asflags for BUILD file simplicity if there are no assembly sources. 305 asFlags = bazel.MakeStringListAttribute(nil) 306 } 307 308 staticCommonAttrs := staticOrSharedAttributes{ 309 Srcs: *srcs.Clone().Append(staticAttrs.Srcs), 310 Srcs_c: *compilerAttrs.cSrcs.Clone().Append(staticAttrs.Srcs_c), 311 Srcs_as: *compilerAttrs.asSrcs.Clone().Append(staticAttrs.Srcs_as), 312 Copts: *compilerAttrs.copts.Clone().Append(staticAttrs.Copts), 313 Hdrs: *compilerAttrs.hdrs.Clone().Append(staticAttrs.Hdrs), 314 315 Deps: *linkerAttrs.deps.Clone().Append(staticAttrs.Deps), 316 Implementation_deps: *linkerAttrs.implementationDeps.Clone().Append(staticAttrs.Implementation_deps), 317 Dynamic_deps: *linkerAttrs.dynamicDeps.Clone().Append(staticAttrs.Dynamic_deps), 318 Implementation_dynamic_deps: *linkerAttrs.implementationDynamicDeps.Clone().Append(staticAttrs.Implementation_dynamic_deps), 319 Implementation_whole_archive_deps: linkerAttrs.implementationWholeArchiveDeps, 320 Whole_archive_deps: *linkerAttrs.wholeArchiveDeps.Clone().Append(staticAttrs.Whole_archive_deps), 321 System_dynamic_deps: *linkerAttrs.systemDynamicDeps.Clone().Append(staticAttrs.System_dynamic_deps), 322 sdkAttributes: bp2BuildParseSdkAttributes(m), 323 } 324 325 sharedCommonAttrs := staticOrSharedAttributes{ 326 Srcs: *srcs.Clone().Append(sharedAttrs.Srcs), 327 Srcs_c: *compilerAttrs.cSrcs.Clone().Append(sharedAttrs.Srcs_c), 328 Srcs_as: *compilerAttrs.asSrcs.Clone().Append(sharedAttrs.Srcs_as), 329 Copts: *compilerAttrs.copts.Clone().Append(sharedAttrs.Copts), 330 Hdrs: *compilerAttrs.hdrs.Clone().Append(sharedAttrs.Hdrs), 331 332 Deps: *linkerAttrs.deps.Clone().Append(sharedAttrs.Deps), 333 Implementation_deps: *linkerAttrs.implementationDeps.Clone().Append(sharedAttrs.Implementation_deps), 334 Dynamic_deps: *linkerAttrs.dynamicDeps.Clone().Append(sharedAttrs.Dynamic_deps), 335 Implementation_dynamic_deps: *linkerAttrs.implementationDynamicDeps.Clone().Append(sharedAttrs.Implementation_dynamic_deps), 336 Whole_archive_deps: *linkerAttrs.wholeArchiveDeps.Clone().Append(sharedAttrs.Whole_archive_deps), 337 System_dynamic_deps: *linkerAttrs.systemDynamicDeps.Clone().Append(sharedAttrs.System_dynamic_deps), 338 sdkAttributes: bp2BuildParseSdkAttributes(m), 339 } 340 341 staticTargetAttrs := &bazelCcLibraryStaticAttributes{ 342 staticOrSharedAttributes: staticCommonAttrs, 343 344 Cppflags: compilerAttrs.cppFlags, 345 Conlyflags: compilerAttrs.conlyFlags, 346 Asflags: asFlags, 347 348 Export_includes: exportedIncludes.Includes, 349 Export_absolute_includes: exportedIncludes.AbsoluteIncludes, 350 Export_system_includes: exportedIncludes.SystemIncludes, 351 Local_includes: compilerAttrs.localIncludes, 352 Absolute_includes: compilerAttrs.absoluteIncludes, 353 Use_libcrt: linkerAttrs.useLibcrt, 354 Rtti: compilerAttrs.rtti, 355 Stl: compilerAttrs.stl, 356 Cpp_std: compilerAttrs.cppStd, 357 C_std: compilerAttrs.cStd, 358 Use_version_lib: linkerAttrs.useVersionLib, 359 360 Features: linkerAttrs.features, 361 } 362 363 sharedTargetAttrs := &bazelCcLibrarySharedAttributes{ 364 staticOrSharedAttributes: sharedCommonAttrs, 365 Cppflags: compilerAttrs.cppFlags, 366 Conlyflags: compilerAttrs.conlyFlags, 367 Asflags: asFlags, 368 369 Export_includes: exportedIncludes.Includes, 370 Export_absolute_includes: exportedIncludes.AbsoluteIncludes, 371 Export_system_includes: exportedIncludes.SystemIncludes, 372 Local_includes: compilerAttrs.localIncludes, 373 Absolute_includes: compilerAttrs.absoluteIncludes, 374 Linkopts: linkerAttrs.linkopts, 375 Link_crt: linkerAttrs.linkCrt, 376 Use_libcrt: linkerAttrs.useLibcrt, 377 Rtti: compilerAttrs.rtti, 378 Stl: compilerAttrs.stl, 379 Cpp_std: compilerAttrs.cppStd, 380 C_std: compilerAttrs.cStd, 381 Use_version_lib: linkerAttrs.useVersionLib, 382 383 Additional_linker_inputs: linkerAttrs.additionalLinkerInputs, 384 385 Strip: stripAttributes{ 386 Keep_symbols: linkerAttrs.stripKeepSymbols, 387 Keep_symbols_and_debug_frame: linkerAttrs.stripKeepSymbolsAndDebugFrame, 388 Keep_symbols_list: linkerAttrs.stripKeepSymbolsList, 389 All: linkerAttrs.stripAll, 390 None: linkerAttrs.stripNone, 391 }, 392 Features: linkerAttrs.features, 393 394 Stubs_symbol_file: compilerAttrs.stubsSymbolFile, 395 Stubs_versions: compilerAttrs.stubsVersions, 396 } 397 398 for axis, configToProps := range m.GetArchVariantProperties(ctx, &LibraryProperties{}) { 399 for config, props := range configToProps { 400 if props, ok := props.(*LibraryProperties); ok { 401 if props.Inject_bssl_hash != nil { 402 // This is an edge case applies only to libcrypto 403 if m.Name() == "libcrypto" { 404 sharedTargetAttrs.Inject_bssl_hash.SetSelectValue(axis, config, props.Inject_bssl_hash) 405 } else { 406 ctx.PropertyErrorf("inject_bssl_hash", "only applies to libcrypto") 407 } 408 } 409 } 410 } 411 } 412 413 staticProps := bazel.BazelTargetModuleProperties{ 414 Rule_class: "cc_library_static", 415 Bzl_load_location: "//build/bazel/rules/cc:cc_library_static.bzl", 416 } 417 sharedProps := bazel.BazelTargetModuleProperties{ 418 Rule_class: "cc_library_shared", 419 Bzl_load_location: "//build/bazel/rules/cc:cc_library_shared.bzl", 420 } 421 422 ctx.CreateBazelTargetModuleWithRestrictions(staticProps, 423 android.CommonAttributes{Name: m.Name() + "_bp2build_cc_library_static"}, 424 staticTargetAttrs, staticAttrs.Enabled) 425 ctx.CreateBazelTargetModuleWithRestrictions(sharedProps, 426 android.CommonAttributes{Name: m.Name()}, 427 sharedTargetAttrs, sharedAttrs.Enabled) 428} 429 430// cc_library creates both static and/or shared libraries for a device and/or 431// host. By default, a cc_library has a single variant that targets the device. 432// Specifying `host_supported: true` also creates a library that targets the 433// host. 434func LibraryFactory() android.Module { 435 module, _ := NewLibrary(android.HostAndDeviceSupported) 436 // Can be used as both a static and a shared library. 437 module.sdkMemberTypes = []android.SdkMemberType{ 438 sharedLibrarySdkMemberType, 439 staticLibrarySdkMemberType, 440 staticAndSharedLibrarySdkMemberType, 441 } 442 module.bazelable = true 443 module.bazelHandler = &ccLibraryBazelHandler{module: module} 444 return module.Init() 445} 446 447// cc_library_static creates a static library for a device and/or host binary. 448func LibraryStaticFactory() android.Module { 449 module, library := NewLibrary(android.HostAndDeviceSupported) 450 library.BuildOnlyStatic() 451 module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType} 452 module.bazelable = true 453 module.bazelHandler = &ccLibraryBazelHandler{module: module} 454 return module.Init() 455} 456 457// cc_library_shared creates a shared library for a device and/or host. 458func LibrarySharedFactory() android.Module { 459 module, library := NewLibrary(android.HostAndDeviceSupported) 460 library.BuildOnlyShared() 461 module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType} 462 module.bazelable = true 463 module.bazelHandler = &ccLibraryBazelHandler{module: module} 464 return module.Init() 465} 466 467// cc_library_host_static creates a static library that is linkable to a host 468// binary. 469func LibraryHostStaticFactory() android.Module { 470 module, library := NewLibrary(android.HostSupported) 471 library.BuildOnlyStatic() 472 module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType} 473 module.bazelable = true 474 module.bazelHandler = &ccLibraryBazelHandler{module: module} 475 return module.Init() 476} 477 478// cc_library_host_shared creates a shared library that is usable on a host. 479func LibraryHostSharedFactory() android.Module { 480 module, library := NewLibrary(android.HostSupported) 481 library.BuildOnlyShared() 482 module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType} 483 module.bazelable = true 484 module.bazelHandler = &ccLibraryBazelHandler{module: module} 485 return module.Init() 486} 487 488// flagExporter is a separated portion of libraryDecorator pertaining to exported 489// include paths and flags. Keeping this dependency-related information separate 490// from the rest of library information is helpful in keeping data more structured 491// and explicit. 492type flagExporter struct { 493 Properties FlagExporterProperties 494 495 dirs android.Paths // Include directories to be included with -I 496 systemDirs android.Paths // System include directories to be included with -isystem 497 flags []string // Exported raw flags. 498 deps android.Paths 499 headers android.Paths 500} 501 502// exportedIncludes returns the effective include paths for this module and 503// any module that links against this module. This is obtained from 504// the export_include_dirs property in the appropriate target stanza. 505func (f *flagExporter) exportedIncludes(ctx ModuleContext) android.Paths { 506 if ctx.inVendor() && f.Properties.Target.Vendor.Override_export_include_dirs != nil { 507 return android.PathsForModuleSrc(ctx, f.Properties.Target.Vendor.Override_export_include_dirs) 508 } 509 if ctx.inProduct() && f.Properties.Target.Product.Override_export_include_dirs != nil { 510 return android.PathsForModuleSrc(ctx, f.Properties.Target.Product.Override_export_include_dirs) 511 } 512 return android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs) 513} 514 515// exportIncludes registers the include directories and system include directories to be exported 516// transitively to modules depending on this module. 517func (f *flagExporter) exportIncludes(ctx ModuleContext) { 518 f.dirs = append(f.dirs, f.exportedIncludes(ctx)...) 519 f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...) 520} 521 522// exportIncludesAsSystem registers the include directories and system include directories to be 523// exported transitively both as system include directories to modules depending on this module. 524func (f *flagExporter) exportIncludesAsSystem(ctx ModuleContext) { 525 // all dirs are force exported as system 526 f.systemDirs = append(f.systemDirs, f.exportedIncludes(ctx)...) 527 f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...) 528} 529 530// reexportDirs registers the given directories as include directories to be exported transitively 531// to modules depending on this module. 532func (f *flagExporter) reexportDirs(dirs ...android.Path) { 533 f.dirs = append(f.dirs, dirs...) 534} 535 536// reexportSystemDirs registers the given directories as system include directories 537// to be exported transitively to modules depending on this module. 538func (f *flagExporter) reexportSystemDirs(dirs ...android.Path) { 539 f.systemDirs = append(f.systemDirs, dirs...) 540} 541 542// reexportFlags registers the flags to be exported transitively to modules depending on this 543// module. 544func (f *flagExporter) reexportFlags(flags ...string) { 545 if android.PrefixInList(flags, "-I") || android.PrefixInList(flags, "-isystem") { 546 panic(fmt.Errorf("Exporting invalid flag %q: "+ 547 "use reexportDirs or reexportSystemDirs to export directories", flag)) 548 } 549 f.flags = append(f.flags, flags...) 550} 551 552func (f *flagExporter) reexportDeps(deps ...android.Path) { 553 f.deps = append(f.deps, deps...) 554} 555 556// addExportedGeneratedHeaders does nothing but collects generated header files. 557// This can be differ to exportedDeps which may contain phony files to minimize ninja. 558func (f *flagExporter) addExportedGeneratedHeaders(headers ...android.Path) { 559 f.headers = append(f.headers, headers...) 560} 561 562func (f *flagExporter) setProvider(ctx android.ModuleContext) { 563 ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{ 564 // Comes from Export_include_dirs property, and those of exported transitive deps 565 IncludeDirs: android.FirstUniquePaths(f.dirs), 566 // Comes from Export_system_include_dirs property, and those of exported transitive deps 567 SystemIncludeDirs: android.FirstUniquePaths(f.systemDirs), 568 // Used in very few places as a one-off way of adding extra defines. 569 Flags: f.flags, 570 // Used sparingly, for extra files that need to be explicitly exported to dependers, 571 // or for phony files to minimize ninja. 572 Deps: f.deps, 573 // For exported generated headers, such as exported aidl headers, proto headers, or 574 // sysprop headers. 575 GeneratedHeaders: f.headers, 576 }) 577} 578 579// libraryDecorator wraps baseCompiler, baseLinker and baseInstaller to provide library-specific 580// functionality: static vs. shared linkage, reusing object files for shared libraries 581type libraryDecorator struct { 582 Properties LibraryProperties 583 StaticProperties StaticProperties 584 SharedProperties SharedProperties 585 MutatedProperties LibraryMutatedProperties 586 587 // For reusing static library objects for shared library 588 reuseObjects Objects 589 590 // table-of-contents file to optimize out relinking when possible 591 tocFile android.OptionalPath 592 593 flagExporter 594 flagExporterInfo *FlagExporterInfo 595 stripper Stripper 596 597 // For whole_static_libs 598 objects Objects 599 wholeStaticLibsFromPrebuilts android.Paths 600 601 // Uses the module's name if empty, but can be overridden. Does not include 602 // shlib suffix. 603 libName string 604 605 sabi *sabi 606 607 // Output archive of gcno coverage information files 608 coverageOutputFile android.OptionalPath 609 610 // linked Source Abi Dump 611 sAbiOutputFile android.OptionalPath 612 613 // Source Abi Diff 614 sAbiDiff android.OptionalPath 615 616 // Location of the static library in the sysroot. Empty if the library is 617 // not included in the NDK. 618 ndkSysrootPath android.Path 619 620 // Location of the linked, unstripped library for shared libraries 621 unstrippedOutputFile android.Path 622 623 // Location of the file that should be copied to dist dir when requested 624 distFile android.Path 625 626 versionScriptPath android.OptionalPath 627 628 postInstallCmds []string 629 630 // If useCoreVariant is true, the vendor variant of a VNDK library is 631 // not installed. 632 useCoreVariant bool 633 checkSameCoreVariant bool 634 635 skipAPIDefine bool 636 637 // Decorated interfaces 638 *baseCompiler 639 *baseLinker 640 *baseInstaller 641 642 collectedSnapshotHeaders android.Paths 643 644 apiListCoverageXmlPath android.ModuleOutPath 645} 646 647type ccLibraryBazelHandler struct { 648 android.BazelHandler 649 650 module *Module 651} 652 653// generateStaticBazelBuildActions constructs the StaticLibraryInfo Soong 654// provider from a Bazel shared library's CcInfo provider. 655func (handler *ccLibraryBazelHandler) generateStaticBazelBuildActions(ctx android.ModuleContext, label string, ccInfo cquery.CcInfo) bool { 656 rootStaticArchives := ccInfo.RootStaticArchives 657 if len(rootStaticArchives) != 1 { 658 ctx.ModuleErrorf("expected exactly one root archive file for '%s', but got %s", label, rootStaticArchives) 659 return false 660 } 661 outputFilePath := android.PathForBazelOut(ctx, rootStaticArchives[0]) 662 handler.module.outputFile = android.OptionalPathForPath(outputFilePath) 663 664 objPaths := ccInfo.CcObjectFiles 665 objFiles := make(android.Paths, len(objPaths)) 666 for i, objPath := range objPaths { 667 objFiles[i] = android.PathForBazelOut(ctx, objPath) 668 } 669 objects := Objects{ 670 objFiles: objFiles, 671 } 672 673 ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{ 674 StaticLibrary: outputFilePath, 675 ReuseObjects: objects, 676 Objects: objects, 677 678 // TODO(b/190524881): Include transitive static libraries in this provider to support 679 // static libraries with deps. 680 TransitiveStaticLibrariesForOrdering: android.NewDepSetBuilder(android.TOPOLOGICAL). 681 Direct(outputFilePath). 682 Build(), 683 }) 684 685 return true 686} 687 688// generateSharedBazelBuildActions constructs the SharedLibraryInfo Soong 689// provider from a Bazel shared library's CcInfo provider. 690func (handler *ccLibraryBazelHandler) generateSharedBazelBuildActions(ctx android.ModuleContext, label string, ccInfo cquery.CcInfo) bool { 691 rootDynamicLibraries := ccInfo.RootDynamicLibraries 692 693 if len(rootDynamicLibraries) != 1 { 694 ctx.ModuleErrorf("expected exactly one root dynamic library file for '%s', but got %s", label, rootDynamicLibraries) 695 return false 696 } 697 outputFilePath := android.PathForBazelOut(ctx, rootDynamicLibraries[0]) 698 handler.module.outputFile = android.OptionalPathForPath(outputFilePath) 699 700 handler.module.linker.(*libraryDecorator).unstrippedOutputFile = outputFilePath 701 702 var tocFile android.OptionalPath 703 if len(ccInfo.TocFile) > 0 { 704 tocFile = android.OptionalPathForPath(android.PathForBazelOut(ctx, ccInfo.TocFile)) 705 } 706 handler.module.linker.(*libraryDecorator).tocFile = tocFile 707 708 ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{ 709 TableOfContents: tocFile, 710 SharedLibrary: outputFilePath, 711 Target: ctx.Target(), 712 // TODO(b/190524881): Include transitive static libraries in this provider to support 713 // static libraries with deps. The provider key for this is TransitiveStaticLibrariesForOrdering. 714 }) 715 return true 716} 717 718func (handler *ccLibraryBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool { 719 bazelCtx := ctx.Config().BazelContext 720 ccInfo, ok, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx)) 721 if err != nil { 722 ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err) 723 return false 724 } 725 if !ok { 726 return ok 727 } 728 729 if handler.module.static() { 730 if ok := handler.generateStaticBazelBuildActions(ctx, label, ccInfo); !ok { 731 return false 732 } 733 } else if handler.module.Shared() { 734 if ok := handler.generateSharedBazelBuildActions(ctx, label, ccInfo); !ok { 735 return false 736 } 737 } else { 738 return false 739 } 740 741 handler.module.linker.(*libraryDecorator).setFlagExporterInfoFromCcInfo(ctx, ccInfo) 742 handler.module.maybeUnhideFromMake() 743 744 if i, ok := handler.module.linker.(snapshotLibraryInterface); ok { 745 // Dependencies on this library will expect collectedSnapshotHeaders to 746 // be set, otherwise validation will fail. For now, set this to an empty 747 // list. 748 // TODO(b/190533363): More closely mirror the collectHeadersForSnapshot 749 // implementation. 750 i.(*libraryDecorator).collectedSnapshotHeaders = android.Paths{} 751 } 752 return ok 753} 754 755func (library *libraryDecorator) setFlagExporterInfoFromCcInfo(ctx android.ModuleContext, ccInfo cquery.CcInfo) { 756 flagExporterInfo := flagExporterInfoFromCcInfo(ctx, ccInfo) 757 // flag exporters consolidates properties like includes, flags, dependencies that should be 758 // exported from this module to other modules 759 ctx.SetProvider(FlagExporterInfoProvider, flagExporterInfo) 760 // Store flag info to be passed along to androidmk 761 // TODO(b/184387147): Androidmk should be done in Bazel, not Soong. 762 library.flagExporterInfo = &flagExporterInfo 763} 764 765func GlobHeadersForSnapshot(ctx android.ModuleContext, paths android.Paths) android.Paths { 766 ret := android.Paths{} 767 768 // Headers in the source tree should be globbed. On the contrast, generated headers 769 // can't be globbed, and they should be manually collected. 770 // So, we first filter out intermediate directories (which contains generated headers) 771 // from exported directories, and then glob headers under remaining directories. 772 for _, path := range paths { 773 dir := path.String() 774 // Skip if dir is for generated headers 775 if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) { 776 continue 777 } 778 // libeigen wrongly exports the root directory "external/eigen". But only two 779 // subdirectories "Eigen" and "unsupported" contain exported header files. Even worse 780 // some of them have no extension. So we need special treatment for libeigen in order 781 // to glob correctly. 782 if dir == "external/eigen" { 783 // Only these two directories contains exported headers. 784 for _, subdir := range []string{"Eigen", "unsupported/Eigen"} { 785 globDir := "external/eigen/" + subdir + "/**/*" 786 glob, err := ctx.GlobWithDeps(globDir, nil) 787 if err != nil { 788 ctx.ModuleErrorf("glob of %q failed: %s", globDir, err) 789 return nil 790 } 791 for _, header := range glob { 792 if strings.HasSuffix(header, "/") { 793 continue 794 } 795 ext := filepath.Ext(header) 796 if ext != "" && ext != ".h" { 797 continue 798 } 799 ret = append(ret, android.PathForSource(ctx, header)) 800 } 801 } 802 continue 803 } 804 globDir := dir + "/**/*" 805 glob, err := ctx.GlobWithDeps(globDir, nil) 806 if err != nil { 807 ctx.ModuleErrorf("glob of %q failed: %s", globDir, err) 808 return nil 809 } 810 isLibcxx := strings.HasPrefix(dir, "external/libcxx/include") 811 for _, header := range glob { 812 if isLibcxx { 813 // Glob all files under this special directory, because of C++ headers with no 814 // extension. 815 if strings.HasSuffix(header, "/") { 816 continue 817 } 818 } else { 819 // Filter out only the files with extensions that are headers. 820 found := false 821 for _, ext := range HeaderExts { 822 if strings.HasSuffix(header, ext) { 823 found = true 824 break 825 } 826 } 827 if !found { 828 continue 829 } 830 } 831 ret = append(ret, android.PathForSource(ctx, header)) 832 } 833 } 834 return ret 835} 836 837func GlobGeneratedHeadersForSnapshot(ctx android.ModuleContext, paths android.Paths) android.Paths { 838 ret := android.Paths{} 839 for _, header := range paths { 840 // TODO(b/148123511): remove exportedDeps after cleaning up genrule 841 if strings.HasSuffix(header.Base(), "-phony") { 842 continue 843 } 844 ret = append(ret, header) 845 } 846 return ret 847} 848 849// collectHeadersForSnapshot collects all exported headers from library. 850// It globs header files in the source tree for exported include directories, 851// and tracks generated header files separately. 852// 853// This is to be called from GenerateAndroidBuildActions, and then collected 854// header files can be retrieved by snapshotHeaders(). 855func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext) { 856 ret := android.Paths{} 857 858 // Headers in the source tree should be globbed. On the contrast, generated headers 859 // can't be globbed, and they should be manually collected. 860 // So, we first filter out intermediate directories (which contains generated headers) 861 // from exported directories, and then glob headers under remaining directories. 862 ret = append(ret, GlobHeadersForSnapshot(ctx, append(android.CopyOfPaths(l.flagExporter.dirs), l.flagExporter.systemDirs...))...) 863 864 // Collect generated headers 865 ret = append(ret, GlobGeneratedHeadersForSnapshot(ctx, append(android.CopyOfPaths(l.flagExporter.headers), l.flagExporter.deps...))...) 866 867 l.collectedSnapshotHeaders = ret 868} 869 870// This returns all exported header files, both generated ones and headers from source tree. 871// collectHeadersForSnapshot() must be called before calling this. 872func (l *libraryDecorator) snapshotHeaders() android.Paths { 873 if l.collectedSnapshotHeaders == nil { 874 panic("snapshotHeaders() must be called after collectHeadersForSnapshot()") 875 } 876 return l.collectedSnapshotHeaders 877} 878 879// linkerProps returns the list of properties structs relevant for this library. (For example, if 880// the library is cc_shared_library, then static-library properties are omitted.) 881func (library *libraryDecorator) linkerProps() []interface{} { 882 var props []interface{} 883 props = append(props, library.baseLinker.linkerProps()...) 884 props = append(props, 885 &library.Properties, 886 &library.MutatedProperties, 887 &library.flagExporter.Properties, 888 &library.stripper.StripProperties) 889 890 if library.MutatedProperties.BuildShared { 891 props = append(props, &library.SharedProperties) 892 } 893 if library.MutatedProperties.BuildStatic { 894 props = append(props, &library.StaticProperties) 895 } 896 897 return props 898} 899 900// linkerFlags takes a Flags struct and augments it to contain linker flags that are defined by this 901// library, or that are implied by attributes of this library (such as whether this library is a 902// shared library). 903func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { 904 flags = library.baseLinker.linkerFlags(ctx, flags) 905 906 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because 907 // all code is position independent, and then those warnings get promoted to 908 // errors. 909 if !ctx.Windows() { 910 flags.Global.CFlags = append(flags.Global.CFlags, "-fPIC") 911 } 912 913 if library.static() { 914 flags.Local.CFlags = append(flags.Local.CFlags, library.StaticProperties.Static.Cflags...) 915 } else if library.shared() { 916 flags.Local.CFlags = append(flags.Local.CFlags, library.SharedProperties.Shared.Cflags...) 917 } 918 919 if library.shared() { 920 libName := library.getLibName(ctx) 921 var f []string 922 if ctx.toolchain().Bionic() { 923 f = append(f, 924 "-nostdlib", 925 "-Wl,--gc-sections", 926 ) 927 } 928 929 if ctx.Darwin() { 930 f = append(f, 931 "-dynamiclib", 932 "-single_module", 933 "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(), 934 ) 935 if ctx.Arch().ArchType == android.X86 { 936 f = append(f, 937 "-read_only_relocs suppress", 938 ) 939 } 940 } else { 941 f = append(f, "-shared") 942 if !ctx.Windows() { 943 f = append(f, "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix()) 944 } 945 } 946 947 flags.Global.LdFlags = append(flags.Global.LdFlags, f...) 948 } 949 950 return flags 951} 952 953// compilerFlags takes a Flags and augments it to contain compile flags from global values, 954// per-target values, module type values, per-module Blueprints properties, extra flags from 955// `flags`, and generated sources from `deps`. 956func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags { 957 exportIncludeDirs := library.flagExporter.exportedIncludes(ctx) 958 if len(exportIncludeDirs) > 0 { 959 f := includeDirsToFlags(exportIncludeDirs) 960 flags.Local.CommonFlags = append(flags.Local.CommonFlags, f) 961 flags.Local.YasmFlags = append(flags.Local.YasmFlags, f) 962 } 963 964 flags = library.baseCompiler.compilerFlags(ctx, flags, deps) 965 if ctx.IsLlndk() { 966 // LLNDK libraries ignore most of the properties on the cc_library and use the 967 // LLNDK-specific properties instead. 968 // Wipe all the module-local properties, leaving only the global properties. 969 flags.Local = LocalOrGlobalFlags{} 970 } 971 if library.buildStubs() { 972 // Remove -include <file> when compiling stubs. Otherwise, the force included 973 // headers might cause conflicting types error with the symbols in the 974 // generated stubs source code. e.g. 975 // double acos(double); // in header 976 // void acos() {} // in the generated source code 977 removeInclude := func(flags []string) []string { 978 ret := flags[:0] 979 for _, f := range flags { 980 if strings.HasPrefix(f, "-include ") { 981 continue 982 } 983 ret = append(ret, f) 984 } 985 return ret 986 } 987 flags.Local.CommonFlags = removeInclude(flags.Local.CommonFlags) 988 flags.Local.CFlags = removeInclude(flags.Local.CFlags) 989 990 flags = addStubLibraryCompilerFlags(flags) 991 } 992 return flags 993} 994 995func (library *libraryDecorator) headerAbiCheckerEnabled() bool { 996 return Bool(library.Properties.Header_abi_checker.Enabled) 997} 998 999func (library *libraryDecorator) headerAbiCheckerExplicitlyDisabled() bool { 1000 return !BoolDefault(library.Properties.Header_abi_checker.Enabled, true) 1001} 1002 1003func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { 1004 if ctx.IsLlndk() { 1005 // This is the vendor variant of an LLNDK library, build the LLNDK stubs. 1006 vndkVer := ctx.Module().(*Module).VndkVersion() 1007 if !inList(vndkVer, ctx.Config().PlatformVersionActiveCodenames()) || vndkVer == "" { 1008 // For non-enforcing devices, vndkVer is empty. Use "current" in that case, too. 1009 vndkVer = "current" 1010 } 1011 if library.stubsVersion() != "" { 1012 vndkVer = library.stubsVersion() 1013 } 1014 nativeAbiResult := parseNativeAbiDefinition(ctx, 1015 String(library.Properties.Llndk.Symbol_file), 1016 android.ApiLevelOrPanic(ctx, vndkVer), "--llndk") 1017 objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc) 1018 if !Bool(library.Properties.Llndk.Unversioned) { 1019 library.versionScriptPath = android.OptionalPathForPath( 1020 nativeAbiResult.versionScript) 1021 } 1022 return objs 1023 } 1024 if ctx.IsVendorPublicLibrary() { 1025 nativeAbiResult := parseNativeAbiDefinition(ctx, 1026 String(library.Properties.Vendor_public_library.Symbol_file), 1027 android.FutureApiLevel, "") 1028 objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc) 1029 if !Bool(library.Properties.Vendor_public_library.Unversioned) { 1030 library.versionScriptPath = android.OptionalPathForPath(nativeAbiResult.versionScript) 1031 } 1032 return objs 1033 } 1034 if library.buildStubs() { 1035 symbolFile := String(library.Properties.Stubs.Symbol_file) 1036 if symbolFile != "" && !strings.HasSuffix(symbolFile, ".map.txt") { 1037 ctx.PropertyErrorf("symbol_file", "%q doesn't have .map.txt suffix", symbolFile) 1038 return Objects{} 1039 } 1040 nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile, 1041 android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), 1042 "--apex") 1043 objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc) 1044 library.versionScriptPath = android.OptionalPathForPath( 1045 nativeAbiResult.versionScript) 1046 1047 // Parse symbol file to get API list for coverage 1048 if library.stubsVersion() == "current" && ctx.PrimaryArch() && !ctx.inRecovery() && !ctx.inProduct() && !ctx.inVendor() { 1049 library.apiListCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile) 1050 } 1051 1052 return objs 1053 } 1054 1055 if !library.buildShared() && !library.buildStatic() { 1056 if len(library.baseCompiler.Properties.Srcs) > 0 { 1057 ctx.PropertyErrorf("srcs", "cc_library_headers must not have any srcs") 1058 } 1059 if len(library.StaticProperties.Static.Srcs) > 0 { 1060 ctx.PropertyErrorf("static.srcs", "cc_library_headers must not have any srcs") 1061 } 1062 if len(library.SharedProperties.Shared.Srcs) > 0 { 1063 ctx.PropertyErrorf("shared.srcs", "cc_library_headers must not have any srcs") 1064 } 1065 return Objects{} 1066 } 1067 if library.sabi.shouldCreateSourceAbiDump() { 1068 exportIncludeDirs := library.flagExporter.exportedIncludes(ctx) 1069 var SourceAbiFlags []string 1070 for _, dir := range exportIncludeDirs.Strings() { 1071 SourceAbiFlags = append(SourceAbiFlags, "-I"+dir) 1072 } 1073 for _, reexportedInclude := range library.sabi.Properties.ReexportedIncludes { 1074 SourceAbiFlags = append(SourceAbiFlags, "-I"+reexportedInclude) 1075 } 1076 flags.SAbiFlags = SourceAbiFlags 1077 totalLength := len(library.baseCompiler.Properties.Srcs) + len(deps.GeneratedSources) + 1078 len(library.SharedProperties.Shared.Srcs) + len(library.StaticProperties.Static.Srcs) 1079 if totalLength > 0 { 1080 flags.SAbiDump = true 1081 } 1082 } 1083 objs := library.baseCompiler.compile(ctx, flags, deps) 1084 library.reuseObjects = objs 1085 buildFlags := flagsToBuilderFlags(flags) 1086 1087 if library.static() { 1088 srcs := android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Srcs) 1089 objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceStaticLibrary, srcs, 1090 android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Tidy_disabled_srcs), 1091 android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Tidy_timeout_srcs), 1092 library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps)) 1093 } else if library.shared() { 1094 srcs := android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Srcs) 1095 objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceSharedLibrary, srcs, 1096 android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Tidy_disabled_srcs), 1097 android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Tidy_timeout_srcs), 1098 library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps)) 1099 } 1100 1101 return objs 1102} 1103 1104type libraryInterface interface { 1105 versionedInterface 1106 1107 static() bool 1108 shared() bool 1109 objs() Objects 1110 reuseObjs() Objects 1111 toc() android.OptionalPath 1112 1113 // Returns true if the build options for the module have selected a static or shared build 1114 buildStatic() bool 1115 buildShared() bool 1116 1117 // Sets whether a specific variant is static or shared 1118 setStatic() 1119 setShared() 1120 1121 // Check whether header_abi_checker is enabled or explicitly disabled. 1122 headerAbiCheckerEnabled() bool 1123 headerAbiCheckerExplicitlyDisabled() bool 1124 1125 // Write LOCAL_ADDITIONAL_DEPENDENCIES for ABI diff 1126 androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) 1127 1128 availableFor(string) bool 1129 1130 getAPIListCoverageXMLPath() android.ModuleOutPath 1131 1132 installable() *bool 1133} 1134 1135type versionedInterface interface { 1136 buildStubs() bool 1137 setBuildStubs(isLatest bool) 1138 hasStubsVariants() bool 1139 setStubsVersion(string) 1140 stubsVersion() string 1141 1142 stubsVersions(ctx android.BaseMutatorContext) []string 1143 setAllStubsVersions([]string) 1144 allStubsVersions() []string 1145 1146 implementationModuleName(name string) string 1147 hasLLNDKStubs() bool 1148 hasLLNDKHeaders() bool 1149 hasVendorPublicLibrary() bool 1150} 1151 1152var _ libraryInterface = (*libraryDecorator)(nil) 1153var _ versionedInterface = (*libraryDecorator)(nil) 1154 1155func (library *libraryDecorator) getLibNameHelper(baseModuleName string, inVendor bool, inProduct bool) string { 1156 name := library.libName 1157 if name == "" { 1158 name = String(library.Properties.Stem) 1159 if name == "" { 1160 name = baseModuleName 1161 } 1162 } 1163 1164 suffix := "" 1165 if inVendor { 1166 suffix = String(library.Properties.Target.Vendor.Suffix) 1167 } else if inProduct { 1168 suffix = String(library.Properties.Target.Product.Suffix) 1169 } 1170 if suffix == "" { 1171 suffix = String(library.Properties.Suffix) 1172 } 1173 1174 return name + suffix 1175} 1176 1177// getLibName returns the actual canonical name of the library (the name which 1178// should be passed to the linker via linker flags). 1179func (library *libraryDecorator) getLibName(ctx BaseModuleContext) string { 1180 name := library.getLibNameHelper(ctx.baseModuleName(), ctx.inVendor(), ctx.inProduct()) 1181 1182 if ctx.IsVndkExt() { 1183 // vndk-ext lib should have the same name with original lib 1184 ctx.VisitDirectDepsWithTag(vndkExtDepTag, func(module android.Module) { 1185 originalName := module.(*Module).outputFile.Path() 1186 name = strings.TrimSuffix(originalName.Base(), originalName.Ext()) 1187 }) 1188 } 1189 1190 if ctx.Host() && Bool(library.Properties.Unique_host_soname) { 1191 if !strings.HasSuffix(name, "-host") { 1192 name = name + "-host" 1193 } 1194 } 1195 1196 return name 1197} 1198 1199var versioningMacroNamesListMutex sync.Mutex 1200 1201func (library *libraryDecorator) linkerInit(ctx BaseModuleContext) { 1202 location := InstallInSystem 1203 if library.baseLinker.sanitize.inSanitizerDir() { 1204 location = InstallInSanitizerDir 1205 } 1206 library.baseInstaller.location = location 1207 library.baseLinker.linkerInit(ctx) 1208 // Let baseLinker know whether this variant is for stubs or not, so that 1209 // it can omit things that are not required for linking stubs. 1210 library.baseLinker.dynamicProperties.BuildStubs = library.buildStubs() 1211 1212 if library.buildStubs() { 1213 macroNames := versioningMacroNamesList(ctx.Config()) 1214 myName := versioningMacroName(ctx.ModuleName()) 1215 versioningMacroNamesListMutex.Lock() 1216 defer versioningMacroNamesListMutex.Unlock() 1217 if (*macroNames)[myName] == "" { 1218 (*macroNames)[myName] = ctx.ModuleName() 1219 } else if (*macroNames)[myName] != ctx.ModuleName() { 1220 ctx.ModuleErrorf("Macro name %q for versioning conflicts with macro name from module %q ", myName, (*macroNames)[myName]) 1221 } 1222 } 1223} 1224 1225func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { 1226 if ctx.IsLlndk() { 1227 // LLNDK libraries ignore most of the properties on the cc_library and use the 1228 // LLNDK-specific properties instead. 1229 return deps 1230 } 1231 1232 deps = library.baseCompiler.compilerDeps(ctx, deps) 1233 1234 return deps 1235} 1236 1237func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { 1238 if ctx.IsLlndk() { 1239 // LLNDK libraries ignore most of the properties on the cc_library and use the 1240 // LLNDK-specific properties instead. 1241 deps.HeaderLibs = append([]string(nil), library.Properties.Llndk.Export_llndk_headers...) 1242 deps.ReexportHeaderLibHeaders = append([]string(nil), library.Properties.Llndk.Export_llndk_headers...) 1243 return deps 1244 } 1245 if ctx.IsVendorPublicLibrary() { 1246 headers := library.Properties.Vendor_public_library.Export_public_headers 1247 deps.HeaderLibs = append([]string(nil), headers...) 1248 deps.ReexportHeaderLibHeaders = append([]string(nil), headers...) 1249 return deps 1250 } 1251 1252 if library.static() { 1253 // Compare with nil because an empty list needs to be propagated. 1254 if library.StaticProperties.Static.System_shared_libs != nil { 1255 library.baseLinker.Properties.System_shared_libs = library.StaticProperties.Static.System_shared_libs 1256 } 1257 } else if library.shared() { 1258 // Compare with nil because an empty list needs to be propagated. 1259 if library.SharedProperties.Shared.System_shared_libs != nil { 1260 library.baseLinker.Properties.System_shared_libs = library.SharedProperties.Shared.System_shared_libs 1261 } 1262 } 1263 1264 deps = library.baseLinker.linkerDeps(ctx, deps) 1265 1266 if library.static() { 1267 deps.WholeStaticLibs = append(deps.WholeStaticLibs, 1268 library.StaticProperties.Static.Whole_static_libs...) 1269 deps.StaticLibs = append(deps.StaticLibs, library.StaticProperties.Static.Static_libs...) 1270 deps.SharedLibs = append(deps.SharedLibs, library.StaticProperties.Static.Shared_libs...) 1271 1272 deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.StaticProperties.Static.Export_shared_lib_headers...) 1273 deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.StaticProperties.Static.Export_static_lib_headers...) 1274 } else if library.shared() { 1275 if !Bool(library.baseLinker.Properties.Nocrt) { 1276 deps.CrtBegin = append(deps.CrtBegin, ctx.toolchain().CrtBeginSharedLibrary()...) 1277 deps.CrtEnd = append(deps.CrtEnd, ctx.toolchain().CrtEndSharedLibrary()...) 1278 } 1279 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.SharedProperties.Shared.Whole_static_libs...) 1280 deps.StaticLibs = append(deps.StaticLibs, library.SharedProperties.Shared.Static_libs...) 1281 deps.SharedLibs = append(deps.SharedLibs, library.SharedProperties.Shared.Shared_libs...) 1282 1283 deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.SharedProperties.Shared.Export_shared_lib_headers...) 1284 deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.SharedProperties.Shared.Export_static_lib_headers...) 1285 } 1286 if ctx.inVendor() { 1287 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs) 1288 deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs) 1289 deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs) 1290 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs) 1291 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs) 1292 } 1293 if ctx.inProduct() { 1294 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Product.Exclude_static_libs) 1295 deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Product.Exclude_shared_libs) 1296 deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Product.Exclude_static_libs) 1297 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Product.Exclude_shared_libs) 1298 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Product.Exclude_static_libs) 1299 } 1300 if ctx.inRecovery() { 1301 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs) 1302 deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Recovery.Exclude_shared_libs) 1303 deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs) 1304 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Recovery.Exclude_shared_libs) 1305 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs) 1306 } 1307 if ctx.inRamdisk() { 1308 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs) 1309 deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_shared_libs) 1310 deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs) 1311 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Ramdisk.Exclude_shared_libs) 1312 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs) 1313 } 1314 if ctx.inVendorRamdisk() { 1315 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs) 1316 deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_shared_libs) 1317 deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs) 1318 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_shared_libs) 1319 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs) 1320 } 1321 1322 return deps 1323} 1324 1325func (library *libraryDecorator) linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps { 1326 specifiedDeps = library.baseLinker.linkerSpecifiedDeps(specifiedDeps) 1327 var properties StaticOrSharedProperties 1328 if library.static() { 1329 properties = library.StaticProperties.Static 1330 } else if library.shared() { 1331 properties = library.SharedProperties.Shared 1332 } 1333 1334 specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, properties.Shared_libs...) 1335 1336 // Must distinguish nil and [] in system_shared_libs - ensure that [] in 1337 // either input list doesn't come out as nil. 1338 if specifiedDeps.systemSharedLibs == nil { 1339 specifiedDeps.systemSharedLibs = properties.System_shared_libs 1340 } else { 1341 specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, properties.System_shared_libs...) 1342 } 1343 1344 specifiedDeps.sharedLibs = android.FirstUniqueStrings(specifiedDeps.sharedLibs) 1345 if len(specifiedDeps.systemSharedLibs) > 0 { 1346 // Skip this if systemSharedLibs is either nil or [], to ensure they are 1347 // retained. 1348 specifiedDeps.systemSharedLibs = android.FirstUniqueStrings(specifiedDeps.systemSharedLibs) 1349 } 1350 return specifiedDeps 1351} 1352 1353func (library *libraryDecorator) linkStatic(ctx ModuleContext, 1354 flags Flags, deps PathDeps, objs Objects) android.Path { 1355 1356 library.objects = deps.WholeStaticLibObjs.Copy() 1357 library.objects = library.objects.Append(objs) 1358 library.wholeStaticLibsFromPrebuilts = android.CopyOfPaths(deps.WholeStaticLibsFromPrebuilts) 1359 1360 fileName := ctx.ModuleName() + staticLibraryExtension 1361 outputFile := android.PathForModuleOut(ctx, fileName) 1362 builderFlags := flagsToBuilderFlags(flags) 1363 1364 if Bool(library.baseLinker.Properties.Use_version_lib) { 1365 if ctx.Host() { 1366 versionedOutputFile := outputFile 1367 outputFile = android.PathForModuleOut(ctx, "unversioned", fileName) 1368 library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) 1369 } else { 1370 versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName) 1371 library.distFile = versionedOutputFile 1372 library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) 1373 } 1374 } 1375 1376 transformObjToStaticLib(ctx, library.objects.objFiles, deps.WholeStaticLibsFromPrebuilts, builderFlags, outputFile, nil, objs.tidyDepFiles) 1377 1378 library.coverageOutputFile = transformCoverageFilesToZip(ctx, library.objects, ctx.ModuleName()) 1379 1380 ctx.CheckbuildFile(outputFile) 1381 1382 if library.static() { 1383 ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{ 1384 StaticLibrary: outputFile, 1385 ReuseObjects: library.reuseObjects, 1386 Objects: library.objects, 1387 WholeStaticLibsFromPrebuilts: library.wholeStaticLibsFromPrebuilts, 1388 1389 TransitiveStaticLibrariesForOrdering: android.NewDepSetBuilder(android.TOPOLOGICAL). 1390 Direct(outputFile). 1391 Transitive(deps.TranstiveStaticLibrariesForOrdering). 1392 Build(), 1393 }) 1394 } 1395 1396 if library.header() { 1397 ctx.SetProvider(HeaderLibraryInfoProvider, HeaderLibraryInfo{}) 1398 } 1399 1400 return outputFile 1401} 1402 1403func ndkSharedLibDeps(ctx ModuleContext) android.Paths { 1404 if ctx.Module().(*Module).IsSdkVariant() { 1405 // The NDK sysroot timestamp file depends on all the NDK 1406 // sysroot header and shared library files. 1407 return android.Paths{getNdkBaseTimestampFile(ctx)} 1408 } 1409 return nil 1410} 1411 1412func (library *libraryDecorator) linkShared(ctx ModuleContext, 1413 flags Flags, deps PathDeps, objs Objects) android.Path { 1414 1415 var linkerDeps android.Paths 1416 linkerDeps = append(linkerDeps, flags.LdFlagsDeps...) 1417 linkerDeps = append(linkerDeps, ndkSharedLibDeps(ctx)...) 1418 1419 unexportedSymbols := ctx.ExpandOptionalSource(library.Properties.Unexported_symbols_list, "unexported_symbols_list") 1420 forceNotWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_not_weak_list, "force_symbols_not_weak_list") 1421 forceWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_weak_list, "force_symbols_weak_list") 1422 if !ctx.Darwin() { 1423 if unexportedSymbols.Valid() { 1424 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin") 1425 } 1426 if forceNotWeakSymbols.Valid() { 1427 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin") 1428 } 1429 if forceWeakSymbols.Valid() { 1430 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin") 1431 } 1432 } else { 1433 if unexportedSymbols.Valid() { 1434 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String()) 1435 linkerDeps = append(linkerDeps, unexportedSymbols.Path()) 1436 } 1437 if forceNotWeakSymbols.Valid() { 1438 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String()) 1439 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path()) 1440 } 1441 if forceWeakSymbols.Valid() { 1442 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String()) 1443 linkerDeps = append(linkerDeps, forceWeakSymbols.Path()) 1444 } 1445 } 1446 if library.versionScriptPath.Valid() { 1447 linkerScriptFlags := "-Wl,--version-script," + library.versionScriptPath.String() 1448 flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlags) 1449 linkerDeps = append(linkerDeps, library.versionScriptPath.Path()) 1450 } 1451 1452 fileName := library.getLibName(ctx) + flags.Toolchain.ShlibSuffix() 1453 outputFile := android.PathForModuleOut(ctx, fileName) 1454 unstrippedOutputFile := outputFile 1455 1456 var implicitOutputs android.WritablePaths 1457 if ctx.Windows() { 1458 importLibraryPath := android.PathForModuleOut(ctx, pathtools.ReplaceExtension(fileName, "lib")) 1459 1460 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--out-implib="+importLibraryPath.String()) 1461 implicitOutputs = append(implicitOutputs, importLibraryPath) 1462 } 1463 1464 builderFlags := flagsToBuilderFlags(flags) 1465 1466 if ctx.Darwin() && deps.DarwinSecondArchOutput.Valid() { 1467 fatOutputFile := outputFile 1468 outputFile = android.PathForModuleOut(ctx, "pre-fat", fileName) 1469 transformDarwinUniversalBinary(ctx, fatOutputFile, outputFile, deps.DarwinSecondArchOutput.Path()) 1470 } 1471 1472 // Optimize out relinking against shared libraries whose interface hasn't changed by 1473 // depending on a table of contents file instead of the library itself. 1474 tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.ShlibSuffix()[1:]+".toc") 1475 library.tocFile = android.OptionalPathForPath(tocFile) 1476 TransformSharedObjectToToc(ctx, outputFile, tocFile) 1477 1478 stripFlags := flagsToStripFlags(flags) 1479 needsStrip := library.stripper.NeedsStrip(ctx) 1480 if library.buildStubs() { 1481 // No need to strip stubs libraries 1482 needsStrip = false 1483 } 1484 if needsStrip { 1485 if ctx.Darwin() { 1486 stripFlags.StripUseGnuStrip = true 1487 } 1488 strippedOutputFile := outputFile 1489 outputFile = android.PathForModuleOut(ctx, "unstripped", fileName) 1490 library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, stripFlags) 1491 } 1492 library.unstrippedOutputFile = outputFile 1493 1494 outputFile = maybeInjectBoringSSLHash(ctx, outputFile, library.Properties.Inject_bssl_hash, fileName) 1495 1496 if Bool(library.baseLinker.Properties.Use_version_lib) { 1497 if ctx.Host() { 1498 versionedOutputFile := outputFile 1499 outputFile = android.PathForModuleOut(ctx, "unversioned", fileName) 1500 library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) 1501 } else { 1502 versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName) 1503 library.distFile = versionedOutputFile 1504 1505 if library.stripper.NeedsStrip(ctx) { 1506 out := android.PathForModuleOut(ctx, "versioned-stripped", fileName) 1507 library.distFile = out 1508 library.stripper.StripExecutableOrSharedLib(ctx, versionedOutputFile, out, stripFlags) 1509 } 1510 1511 library.injectVersionSymbol(ctx, outputFile, versionedOutputFile) 1512 } 1513 } 1514 1515 sharedLibs := deps.EarlySharedLibs 1516 sharedLibs = append(sharedLibs, deps.SharedLibs...) 1517 sharedLibs = append(sharedLibs, deps.LateSharedLibs...) 1518 1519 linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...) 1520 linkerDeps = append(linkerDeps, deps.SharedLibsDeps...) 1521 linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...) 1522 transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, 1523 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, 1524 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs, objs.tidyDepFiles) 1525 1526 objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...) 1527 objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...) 1528 1529 objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.StaticLibObjs.sAbiDumpFiles...) 1530 objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.WholeStaticLibObjs.sAbiDumpFiles...) 1531 1532 library.coverageOutputFile = transformCoverageFilesToZip(ctx, objs, library.getLibName(ctx)) 1533 library.linkSAbiDumpFiles(ctx, objs, fileName, unstrippedOutputFile) 1534 1535 var transitiveStaticLibrariesForOrdering *android.DepSet 1536 if static := ctx.GetDirectDepsWithTag(staticVariantTag); len(static) > 0 { 1537 s := ctx.OtherModuleProvider(static[0], StaticLibraryInfoProvider).(StaticLibraryInfo) 1538 transitiveStaticLibrariesForOrdering = s.TransitiveStaticLibrariesForOrdering 1539 } 1540 1541 ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{ 1542 TableOfContents: android.OptionalPathForPath(tocFile), 1543 SharedLibrary: unstrippedOutputFile, 1544 TransitiveStaticLibrariesForOrdering: transitiveStaticLibrariesForOrdering, 1545 Target: ctx.Target(), 1546 }) 1547 1548 stubs := ctx.GetDirectDepsWithTag(stubImplDepTag) 1549 if len(stubs) > 0 { 1550 var stubsInfo []SharedStubLibrary 1551 for _, stub := range stubs { 1552 stubInfo := ctx.OtherModuleProvider(stub, SharedLibraryInfoProvider).(SharedLibraryInfo) 1553 flagInfo := ctx.OtherModuleProvider(stub, FlagExporterInfoProvider).(FlagExporterInfo) 1554 stubsInfo = append(stubsInfo, SharedStubLibrary{ 1555 Version: moduleLibraryInterface(stub).stubsVersion(), 1556 SharedLibraryInfo: stubInfo, 1557 FlagExporterInfo: flagInfo, 1558 }) 1559 } 1560 ctx.SetProvider(SharedLibraryStubsProvider, SharedLibraryStubsInfo{ 1561 SharedStubLibraries: stubsInfo, 1562 1563 IsLLNDK: ctx.IsLlndk(), 1564 }) 1565 } 1566 1567 return unstrippedOutputFile 1568} 1569 1570func (library *libraryDecorator) unstrippedOutputFilePath() android.Path { 1571 return library.unstrippedOutputFile 1572} 1573 1574func (library *libraryDecorator) disableStripping() { 1575 library.stripper.StripProperties.Strip.None = BoolPtr(true) 1576} 1577 1578func (library *libraryDecorator) nativeCoverage() bool { 1579 if library.header() || library.buildStubs() { 1580 return false 1581 } 1582 return true 1583} 1584 1585func (library *libraryDecorator) coverageOutputFilePath() android.OptionalPath { 1586 return library.coverageOutputFile 1587} 1588 1589func getRefAbiDumpFile(ctx ModuleContext, vndkVersion, fileName string) android.Path { 1590 // The logic must be consistent with classifySourceAbiDump. 1591 isNdk := ctx.isNdk(ctx.Config()) 1592 isLlndkOrVndk := ctx.IsLlndkPublic() || (ctx.useVndk() && ctx.isVndk()) 1593 1594 refAbiDumpTextFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, false) 1595 refAbiDumpGzipFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, true) 1596 1597 if refAbiDumpTextFile.Valid() { 1598 if refAbiDumpGzipFile.Valid() { 1599 ctx.ModuleErrorf( 1600 "Two reference ABI dump files are found: %q and %q. Please delete the stale one.", 1601 refAbiDumpTextFile, refAbiDumpGzipFile) 1602 return nil 1603 } 1604 return refAbiDumpTextFile.Path() 1605 } 1606 if refAbiDumpGzipFile.Valid() { 1607 return unzipRefDump(ctx, refAbiDumpGzipFile.Path(), fileName) 1608 } 1609 return nil 1610} 1611 1612func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) { 1613 if library.sabi.shouldCreateSourceAbiDump() { 1614 var vndkVersion string 1615 1616 if ctx.useVndk() { 1617 // For modules linking against vndk, follow its vndk version 1618 vndkVersion = ctx.Module().(*Module).VndkVersion() 1619 } else { 1620 // Regard the other modules as PLATFORM_VNDK_VERSION 1621 vndkVersion = ctx.DeviceConfig().PlatformVndkVersion() 1622 } 1623 1624 exportIncludeDirs := library.flagExporter.exportedIncludes(ctx) 1625 var SourceAbiFlags []string 1626 for _, dir := range exportIncludeDirs.Strings() { 1627 SourceAbiFlags = append(SourceAbiFlags, "-I"+dir) 1628 } 1629 for _, reexportedInclude := range library.sabi.Properties.ReexportedIncludes { 1630 SourceAbiFlags = append(SourceAbiFlags, "-I"+reexportedInclude) 1631 } 1632 exportedHeaderFlags := strings.Join(SourceAbiFlags, " ") 1633 library.sAbiOutputFile = transformDumpToLinkedDump(ctx, objs.sAbiDumpFiles, soFile, fileName, exportedHeaderFlags, 1634 android.OptionalPathForModuleSrc(ctx, library.symbolFileForAbiCheck(ctx)), 1635 library.Properties.Header_abi_checker.Exclude_symbol_versions, 1636 library.Properties.Header_abi_checker.Exclude_symbol_tags) 1637 1638 addLsdumpPath(classifySourceAbiDump(ctx) + ":" + library.sAbiOutputFile.String()) 1639 1640 refAbiDumpFile := getRefAbiDumpFile(ctx, vndkVersion, fileName) 1641 if refAbiDumpFile != nil { 1642 library.sAbiDiff = sourceAbiDiff(ctx, library.sAbiOutputFile.Path(), 1643 refAbiDumpFile, fileName, exportedHeaderFlags, 1644 library.Properties.Header_abi_checker.Diff_flags, 1645 Bool(library.Properties.Header_abi_checker.Check_all_apis), 1646 ctx.IsLlndk(), ctx.isNdk(ctx.Config()), ctx.IsVndkExt()) 1647 } 1648 } 1649} 1650 1651func processLLNDKHeaders(ctx ModuleContext, srcHeaderDir string, outDir android.ModuleGenPath) (timestamp android.Path, installPaths android.WritablePaths) { 1652 srcDir := android.PathForModuleSrc(ctx, srcHeaderDir) 1653 srcFiles := ctx.GlobFiles(filepath.Join(srcDir.String(), "**/*.h"), nil) 1654 1655 for _, header := range srcFiles { 1656 headerDir := filepath.Dir(header.String()) 1657 relHeaderDir, err := filepath.Rel(srcDir.String(), headerDir) 1658 if err != nil { 1659 ctx.ModuleErrorf("filepath.Rel(%q, %q) failed: %s", 1660 srcDir.String(), headerDir, err) 1661 continue 1662 } 1663 1664 installPaths = append(installPaths, outDir.Join(ctx, relHeaderDir, header.Base())) 1665 } 1666 1667 return processHeadersWithVersioner(ctx, srcDir, outDir, srcFiles, installPaths), installPaths 1668} 1669 1670// link registers actions to link this library, and sets various fields 1671// on this library to reflect information that should be exported up the build 1672// tree (for example, exported flags and include paths). 1673func (library *libraryDecorator) link(ctx ModuleContext, 1674 flags Flags, deps PathDeps, objs Objects) android.Path { 1675 1676 if ctx.IsLlndk() { 1677 if len(library.Properties.Llndk.Export_preprocessed_headers) > 0 { 1678 // This is the vendor variant of an LLNDK library with preprocessed headers. 1679 genHeaderOutDir := android.PathForModuleGen(ctx, "include") 1680 1681 var timestampFiles android.Paths 1682 for _, dir := range library.Properties.Llndk.Export_preprocessed_headers { 1683 timestampFile, installPaths := processLLNDKHeaders(ctx, dir, genHeaderOutDir) 1684 timestampFiles = append(timestampFiles, timestampFile) 1685 library.addExportedGeneratedHeaders(installPaths.Paths()...) 1686 } 1687 1688 if Bool(library.Properties.Llndk.Export_headers_as_system) { 1689 library.reexportSystemDirs(genHeaderOutDir) 1690 } else { 1691 library.reexportDirs(genHeaderOutDir) 1692 } 1693 1694 library.reexportDeps(timestampFiles...) 1695 } 1696 1697 // override the module's export_include_dirs with llndk.override_export_include_dirs 1698 // if it is set. 1699 if override := library.Properties.Llndk.Override_export_include_dirs; override != nil { 1700 library.flagExporter.Properties.Export_include_dirs = override 1701 } 1702 1703 if Bool(library.Properties.Llndk.Export_headers_as_system) { 1704 library.flagExporter.Properties.Export_system_include_dirs = append( 1705 library.flagExporter.Properties.Export_system_include_dirs, 1706 library.flagExporter.Properties.Export_include_dirs...) 1707 library.flagExporter.Properties.Export_include_dirs = nil 1708 } 1709 } 1710 1711 if ctx.IsVendorPublicLibrary() { 1712 // override the module's export_include_dirs with vendor_public_library.override_export_include_dirs 1713 // if it is set. 1714 if override := library.Properties.Vendor_public_library.Override_export_include_dirs; override != nil { 1715 library.flagExporter.Properties.Export_include_dirs = override 1716 } 1717 } 1718 1719 // Linking this library consists of linking `deps.Objs` (.o files in dependencies 1720 // of this library), together with `objs` (.o files created by compiling this 1721 // library). 1722 objs = deps.Objs.Copy().Append(objs) 1723 var out android.Path 1724 if library.static() || library.header() { 1725 out = library.linkStatic(ctx, flags, deps, objs) 1726 } else { 1727 out = library.linkShared(ctx, flags, deps, objs) 1728 } 1729 1730 // Export include paths and flags to be propagated up the tree. 1731 library.exportIncludes(ctx) 1732 library.reexportDirs(deps.ReexportedDirs...) 1733 library.reexportSystemDirs(deps.ReexportedSystemDirs...) 1734 library.reexportFlags(deps.ReexportedFlags...) 1735 library.reexportDeps(deps.ReexportedDeps...) 1736 library.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...) 1737 1738 // Optionally export aidl headers. 1739 if Bool(library.Properties.Aidl.Export_aidl_headers) { 1740 if library.baseCompiler.hasSrcExt(".aidl") { 1741 dir := android.PathForModuleGen(ctx, "aidl") 1742 library.reexportDirs(dir) 1743 1744 library.reexportDeps(library.baseCompiler.aidlOrderOnlyDeps...) 1745 library.addExportedGeneratedHeaders(library.baseCompiler.aidlHeaders...) 1746 } 1747 } 1748 1749 // Optionally export proto headers. 1750 if Bool(library.Properties.Proto.Export_proto_headers) { 1751 if library.baseCompiler.hasSrcExt(".proto") { 1752 var includes android.Paths 1753 if flags.proto.CanonicalPathFromRoot { 1754 includes = append(includes, flags.proto.SubDir) 1755 } 1756 includes = append(includes, flags.proto.Dir) 1757 library.reexportDirs(includes...) 1758 1759 library.reexportDeps(library.baseCompiler.protoOrderOnlyDeps...) 1760 library.addExportedGeneratedHeaders(library.baseCompiler.protoHeaders...) 1761 } 1762 } 1763 1764 // If the library is sysprop_library, expose either public or internal header selectively. 1765 if library.baseCompiler.hasSrcExt(".sysprop") { 1766 dir := android.PathForModuleGen(ctx, "sysprop", "include") 1767 if library.Properties.Sysprop.Platform != nil { 1768 isOwnerPlatform := Bool(library.Properties.Sysprop.Platform) 1769 1770 // If the owner is different from the user, expose public header. That is, 1771 // 1) if the user is product (as owner can only be platform / vendor) 1772 // 2) if the owner is platform and the client is vendor 1773 // We don't care Platform -> Vendor dependency as it's already forbidden. 1774 if ctx.Device() && (ctx.ProductSpecific() || (isOwnerPlatform && ctx.inVendor())) { 1775 dir = android.PathForModuleGen(ctx, "sysprop/public", "include") 1776 } 1777 } 1778 1779 // Make sure to only export headers which are within the include directory. 1780 _, headers := android.FilterPathListPredicate(library.baseCompiler.syspropHeaders, func(path android.Path) bool { 1781 _, isRel := android.MaybeRel(ctx, dir.String(), path.String()) 1782 return isRel 1783 }) 1784 1785 // Add sysprop-related directories to the exported directories of this library. 1786 library.reexportDirs(dir) 1787 library.reexportDeps(library.baseCompiler.syspropOrderOnlyDeps...) 1788 library.addExportedGeneratedHeaders(headers...) 1789 } 1790 1791 // Add stub-related flags if this library is a stub library. 1792 library.exportVersioningMacroIfNeeded(ctx) 1793 1794 // Propagate a Provider containing information about exported flags, deps, and include paths. 1795 library.flagExporter.setProvider(ctx) 1796 1797 return out 1798} 1799 1800func (library *libraryDecorator) exportVersioningMacroIfNeeded(ctx android.BaseModuleContext) { 1801 if library.buildStubs() && library.stubsVersion() != "" && !library.skipAPIDefine { 1802 name := versioningMacroName(ctx.Module().(*Module).ImplementationModuleName(ctx)) 1803 apiLevel, err := android.ApiLevelFromUser(ctx, library.stubsVersion()) 1804 if err != nil { 1805 ctx.ModuleErrorf("Can't export version macro: %s", err.Error()) 1806 } 1807 library.reexportFlags("-D" + name + "=" + strconv.Itoa(apiLevel.FinalOrPreviewInt())) 1808 } 1809} 1810 1811// buildStatic returns true if this library should be built as a static library. 1812func (library *libraryDecorator) buildStatic() bool { 1813 return library.MutatedProperties.BuildStatic && 1814 BoolDefault(library.StaticProperties.Static.Enabled, true) 1815} 1816 1817// buildShared returns true if this library should be built as a shared library. 1818func (library *libraryDecorator) buildShared() bool { 1819 return library.MutatedProperties.BuildShared && 1820 BoolDefault(library.SharedProperties.Shared.Enabled, true) 1821} 1822 1823func (library *libraryDecorator) objs() Objects { 1824 return library.objects 1825} 1826 1827func (library *libraryDecorator) reuseObjs() Objects { 1828 return library.reuseObjects 1829} 1830 1831func (library *libraryDecorator) toc() android.OptionalPath { 1832 return library.tocFile 1833} 1834 1835func (library *libraryDecorator) installSymlinkToRuntimeApex(ctx ModuleContext, file android.Path) { 1836 dir := library.baseInstaller.installDir(ctx) 1837 dirOnDevice := android.InstallPathToOnDevicePath(ctx, dir) 1838 target := "/" + filepath.Join("apex", "com.android.runtime", dir.Base(), "bionic", file.Base()) 1839 ctx.InstallAbsoluteSymlink(dir, file.Base(), target) 1840 library.postInstallCmds = append(library.postInstallCmds, makeSymlinkCmd(dirOnDevice, file.Base(), target)) 1841} 1842 1843func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) { 1844 if library.shared() { 1845 if ctx.Device() && ctx.useVndk() { 1846 // set subDir for VNDK extensions 1847 if ctx.IsVndkExt() { 1848 if ctx.isVndkSp() { 1849 library.baseInstaller.subDir = "vndk-sp" 1850 } else { 1851 library.baseInstaller.subDir = "vndk" 1852 } 1853 } 1854 1855 // In some cases we want to use core variant for VNDK-Core libs. 1856 // Skip product variant since VNDKs use only the vendor variant. 1857 if ctx.isVndk() && !ctx.isVndkSp() && !ctx.IsVndkExt() && !ctx.inProduct() { 1858 mayUseCoreVariant := true 1859 1860 if ctx.mustUseVendorVariant() { 1861 mayUseCoreVariant = false 1862 } 1863 1864 if ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) { 1865 mayUseCoreVariant = false 1866 } 1867 1868 if mayUseCoreVariant { 1869 library.checkSameCoreVariant = true 1870 if ctx.DeviceConfig().VndkUseCoreVariant() { 1871 library.useCoreVariant = true 1872 } 1873 } 1874 } 1875 1876 // do not install vndk libs 1877 // vndk libs are packaged into VNDK APEX 1878 if ctx.isVndk() && !ctx.IsVndkExt() { 1879 return 1880 } 1881 } else if library.hasStubsVariants() && !ctx.Host() && ctx.directlyInAnyApex() { 1882 // Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory. 1883 // The original path becomes a symlink to the corresponding file in the 1884 // runtime APEX. 1885 translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled 1886 if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() && 1887 !translatedArch && !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() { 1888 if ctx.Device() { 1889 library.installSymlinkToRuntimeApex(ctx, file) 1890 } 1891 library.baseInstaller.subDir = "bootstrap" 1892 } 1893 } else if ctx.directlyInAnyApex() && ctx.IsLlndk() && !isBionic(ctx.baseModuleName()) { 1894 // Skip installing LLNDK (non-bionic) libraries moved to APEX. 1895 ctx.Module().HideFromMake() 1896 } 1897 1898 library.baseInstaller.install(ctx, file) 1899 } 1900 1901 if Bool(library.Properties.Static_ndk_lib) && library.static() && 1902 !ctx.useVndk() && !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() && ctx.Device() && 1903 library.baseLinker.sanitize.isUnsanitizedVariant() && 1904 ctx.isForPlatform() && !ctx.isPreventInstall() { 1905 installPath := getNdkSysrootBase(ctx).Join( 1906 ctx, "usr/lib", config.NDKTriple(ctx.toolchain()), file.Base()) 1907 1908 ctx.ModuleBuild(pctx, android.ModuleBuildParams{ 1909 Rule: android.Cp, 1910 Description: "install " + installPath.Base(), 1911 Output: installPath, 1912 Input: file, 1913 }) 1914 1915 library.ndkSysrootPath = installPath 1916 } 1917} 1918 1919func (library *libraryDecorator) everInstallable() bool { 1920 // Only shared and static libraries are installed. Header libraries (which are 1921 // neither static or shared) are not installed. 1922 return library.shared() || library.static() 1923} 1924 1925// static returns true if this library is for a "static' variant. 1926func (library *libraryDecorator) static() bool { 1927 return library.MutatedProperties.VariantIsStatic 1928} 1929 1930// shared returns true if this library is for a "shared' variant. 1931func (library *libraryDecorator) shared() bool { 1932 return library.MutatedProperties.VariantIsShared 1933} 1934 1935// header returns true if this library is for a header-only variant. 1936func (library *libraryDecorator) header() bool { 1937 // Neither "static" nor "shared" implies this library is header-only. 1938 return !library.static() && !library.shared() 1939} 1940 1941// setStatic marks the library variant as "static". 1942func (library *libraryDecorator) setStatic() { 1943 library.MutatedProperties.VariantIsStatic = true 1944 library.MutatedProperties.VariantIsShared = false 1945} 1946 1947// setShared marks the library variant as "shared". 1948func (library *libraryDecorator) setShared() { 1949 library.MutatedProperties.VariantIsStatic = false 1950 library.MutatedProperties.VariantIsShared = true 1951} 1952 1953// BuildOnlyStatic disables building this library as a shared library. 1954func (library *libraryDecorator) BuildOnlyStatic() { 1955 library.MutatedProperties.BuildShared = false 1956} 1957 1958// BuildOnlyShared disables building this library as a static library. 1959func (library *libraryDecorator) BuildOnlyShared() { 1960 library.MutatedProperties.BuildStatic = false 1961} 1962 1963// HeaderOnly disables building this library as a shared or static library; 1964// the library only exists to propagate header file dependencies up the build graph. 1965func (library *libraryDecorator) HeaderOnly() { 1966 library.MutatedProperties.BuildShared = false 1967 library.MutatedProperties.BuildStatic = false 1968} 1969 1970// hasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs. 1971func (library *libraryDecorator) hasLLNDKStubs() bool { 1972 return String(library.Properties.Llndk.Symbol_file) != "" 1973} 1974 1975// hasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs. 1976func (library *libraryDecorator) hasLLNDKHeaders() bool { 1977 return Bool(library.Properties.Llndk.Llndk_headers) 1978} 1979 1980// hasVendorPublicLibrary returns true if this cc_library module has a variant that will build 1981// vendor public library stubs. 1982func (library *libraryDecorator) hasVendorPublicLibrary() bool { 1983 return String(library.Properties.Vendor_public_library.Symbol_file) != "" 1984} 1985 1986func (library *libraryDecorator) implementationModuleName(name string) string { 1987 return name 1988} 1989 1990func (library *libraryDecorator) buildStubs() bool { 1991 return library.MutatedProperties.BuildStubs 1992} 1993 1994func (library *libraryDecorator) symbolFileForAbiCheck(ctx ModuleContext) *string { 1995 if library.Properties.Header_abi_checker.Symbol_file != nil { 1996 return library.Properties.Header_abi_checker.Symbol_file 1997 } 1998 if ctx.Module().(*Module).IsLlndk() { 1999 return library.Properties.Llndk.Symbol_file 2000 } 2001 if library.hasStubsVariants() && library.Properties.Stubs.Symbol_file != nil { 2002 return library.Properties.Stubs.Symbol_file 2003 } 2004 return nil 2005} 2006 2007func (library *libraryDecorator) hasStubsVariants() bool { 2008 // Just having stubs.symbol_file is enough to create a stub variant. In that case 2009 // the stub for the future API level is created. 2010 return library.Properties.Stubs.Symbol_file != nil || 2011 len(library.Properties.Stubs.Versions) > 0 2012} 2013 2014func (library *libraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []string { 2015 if !library.hasStubsVariants() { 2016 return nil 2017 } 2018 2019 if library.hasLLNDKStubs() && ctx.Module().(*Module).UseVndk() { 2020 // LLNDK libraries only need a single stubs variant. 2021 return []string{android.FutureApiLevel.String()} 2022 } 2023 2024 // Future API level is implicitly added if there isn't 2025 vers := library.Properties.Stubs.Versions 2026 if inList(android.FutureApiLevel.String(), vers) { 2027 return vers 2028 } 2029 // In some cases, people use the raw value "10000" in the versions property. 2030 // We shouldn't add the future API level in that case, otherwise there will 2031 // be two identical versions. 2032 if inList(strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt()), vers) { 2033 return vers 2034 } 2035 return append(vers, android.FutureApiLevel.String()) 2036} 2037 2038func (library *libraryDecorator) setStubsVersion(version string) { 2039 library.MutatedProperties.StubsVersion = version 2040} 2041 2042func (library *libraryDecorator) stubsVersion() string { 2043 return library.MutatedProperties.StubsVersion 2044} 2045 2046func (library *libraryDecorator) setBuildStubs(isLatest bool) { 2047 library.MutatedProperties.BuildStubs = true 2048 library.MutatedProperties.IsLatestVersion = isLatest 2049} 2050 2051func (library *libraryDecorator) setAllStubsVersions(versions []string) { 2052 library.MutatedProperties.AllStubsVersions = versions 2053} 2054 2055func (library *libraryDecorator) allStubsVersions() []string { 2056 return library.MutatedProperties.AllStubsVersions 2057} 2058 2059func (library *libraryDecorator) isLatestStubVersion() bool { 2060 return library.MutatedProperties.IsLatestVersion 2061} 2062 2063func (library *libraryDecorator) availableFor(what string) bool { 2064 var list []string 2065 if library.static() { 2066 list = library.StaticProperties.Static.Apex_available 2067 } else if library.shared() { 2068 list = library.SharedProperties.Shared.Apex_available 2069 } 2070 if len(list) == 0 { 2071 return false 2072 } 2073 return android.CheckAvailableForApex(what, list) 2074} 2075 2076func (library *libraryDecorator) installable() *bool { 2077 if library.static() { 2078 return library.StaticProperties.Static.Installable 2079 } else if library.shared() { 2080 return library.SharedProperties.Shared.Installable 2081 } 2082 return nil 2083} 2084 2085func (library *libraryDecorator) makeUninstallable(mod *Module) { 2086 if library.static() && library.buildStatic() && !library.buildStubs() { 2087 // If we're asked to make a static library uninstallable we don't do 2088 // anything since AndroidMkEntries always sets LOCAL_UNINSTALLABLE_MODULE 2089 // for these entries. This is done to still get the make targets for NOTICE 2090 // files from notice_files.mk, which other libraries might depend on. 2091 return 2092 } 2093 mod.ModuleBase.MakeUninstallable() 2094} 2095 2096func (library *libraryDecorator) getAPIListCoverageXMLPath() android.ModuleOutPath { 2097 return library.apiListCoverageXmlPath 2098} 2099 2100var versioningMacroNamesListKey = android.NewOnceKey("versioningMacroNamesList") 2101 2102// versioningMacroNamesList returns a singleton map, where keys are "version macro names", 2103// and values are the module name responsible for registering the version macro name. 2104// 2105// Version macros are used when building against stubs, to provide version information about 2106// the stub. Only stub libraries should have an entry in this list. 2107// 2108// For example, when building against libFoo#ver, __LIBFOO_API__ macro is set to ver so 2109// that headers from libFoo can be conditionally compiled (this may hide APIs 2110// that are not available for the version). 2111// 2112// This map is used to ensure that there aren't conflicts between these version macro names. 2113func versioningMacroNamesList(config android.Config) *map[string]string { 2114 return config.Once(versioningMacroNamesListKey, func() interface{} { 2115 m := make(map[string]string) 2116 return &m 2117 }).(*map[string]string) 2118} 2119 2120// alphanumeric and _ characters are preserved. 2121// other characters are all converted to _ 2122var charsNotForMacro = regexp.MustCompile("[^a-zA-Z0-9_]+") 2123 2124// versioningMacroName returns the canonical version macro name for the given module. 2125func versioningMacroName(moduleName string) string { 2126 macroName := charsNotForMacro.ReplaceAllString(moduleName, "_") 2127 macroName = strings.ToUpper(macroName) 2128 return "__" + macroName + "_API__" 2129} 2130 2131// NewLibrary builds and returns a new Module corresponding to a C++ library. 2132// Individual module implementations which comprise a C++ library (or something like 2133// a C++ library) should call this function, set some fields on the result, and 2134// then call the Init function. 2135func NewLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { 2136 module := newModule(hod, android.MultilibBoth) 2137 2138 library := &libraryDecorator{ 2139 MutatedProperties: LibraryMutatedProperties{ 2140 BuildShared: true, 2141 BuildStatic: true, 2142 }, 2143 baseCompiler: NewBaseCompiler(), 2144 baseLinker: NewBaseLinker(module.sanitize), 2145 baseInstaller: NewBaseInstaller("lib", "lib64", InstallInSystem), 2146 sabi: module.sabi, 2147 } 2148 2149 module.compiler = library 2150 module.linker = library 2151 module.installer = library 2152 module.library = library 2153 2154 return module, library 2155} 2156 2157// connects a shared library to a static library in order to reuse its .o files to avoid 2158// compiling source files twice. 2159func reuseStaticLibrary(mctx android.BottomUpMutatorContext, static, shared *Module) { 2160 if staticCompiler, ok := static.compiler.(*libraryDecorator); ok { 2161 sharedCompiler := shared.compiler.(*libraryDecorator) 2162 2163 // Check libraries in addition to cflags, since libraries may be exporting different 2164 // include directories. 2165 if len(staticCompiler.StaticProperties.Static.Cflags) == 0 && 2166 len(sharedCompiler.SharedProperties.Shared.Cflags) == 0 && 2167 len(staticCompiler.StaticProperties.Static.Whole_static_libs) == 0 && 2168 len(sharedCompiler.SharedProperties.Shared.Whole_static_libs) == 0 && 2169 len(staticCompiler.StaticProperties.Static.Static_libs) == 0 && 2170 len(sharedCompiler.SharedProperties.Shared.Static_libs) == 0 && 2171 len(staticCompiler.StaticProperties.Static.Shared_libs) == 0 && 2172 len(sharedCompiler.SharedProperties.Shared.Shared_libs) == 0 && 2173 // Compare System_shared_libs properties with nil because empty lists are 2174 // semantically significant for them. 2175 staticCompiler.StaticProperties.Static.System_shared_libs == nil && 2176 sharedCompiler.SharedProperties.Shared.System_shared_libs == nil { 2177 2178 mctx.AddInterVariantDependency(reuseObjTag, shared, static) 2179 sharedCompiler.baseCompiler.Properties.OriginalSrcs = 2180 sharedCompiler.baseCompiler.Properties.Srcs 2181 sharedCompiler.baseCompiler.Properties.Srcs = nil 2182 sharedCompiler.baseCompiler.Properties.Generated_sources = nil 2183 } 2184 2185 // This dep is just to reference static variant from shared variant 2186 mctx.AddInterVariantDependency(staticVariantTag, shared, static) 2187 } 2188} 2189 2190// LinkageMutator adds "static" or "shared" variants for modules depending 2191// on whether the module can be built as a static library or a shared library. 2192func LinkageMutator(mctx android.BottomUpMutatorContext) { 2193 ccPrebuilt := false 2194 if m, ok := mctx.Module().(*Module); ok && m.linker != nil { 2195 _, ccPrebuilt = m.linker.(prebuiltLibraryInterface) 2196 } 2197 if ccPrebuilt { 2198 library := mctx.Module().(*Module).linker.(prebuiltLibraryInterface) 2199 2200 // Differentiate between header only and building an actual static/shared library 2201 buildStatic := library.buildStatic() 2202 buildShared := library.buildShared() 2203 if buildStatic || buildShared { 2204 // Always create both the static and shared variants for prebuilt libraries, and then disable the one 2205 // that is not being used. This allows them to share the name of a cc_library module, which requires that 2206 // all the variants of the cc_library also exist on the prebuilt. 2207 modules := mctx.CreateLocalVariations("static", "shared") 2208 static := modules[0].(*Module) 2209 shared := modules[1].(*Module) 2210 2211 static.linker.(prebuiltLibraryInterface).setStatic() 2212 shared.linker.(prebuiltLibraryInterface).setShared() 2213 2214 if buildShared { 2215 mctx.AliasVariation("shared") 2216 } else if buildStatic { 2217 mctx.AliasVariation("static") 2218 } 2219 2220 if !buildStatic { 2221 static.linker.(prebuiltLibraryInterface).disablePrebuilt() 2222 } 2223 if !buildShared { 2224 shared.linker.(prebuiltLibraryInterface).disablePrebuilt() 2225 } 2226 } else { 2227 // Header only 2228 } 2229 2230 } else if library, ok := mctx.Module().(LinkableInterface); ok && library.CcLibraryInterface() { 2231 2232 // Non-cc.Modules may need an empty variant for their mutators. 2233 variations := []string{} 2234 if library.NonCcVariants() { 2235 variations = append(variations, "") 2236 } 2237 2238 isLLNDK := false 2239 if m, ok := mctx.Module().(*Module); ok { 2240 isLLNDK = m.IsLlndk() 2241 } 2242 buildStatic := library.BuildStaticVariant() && !isLLNDK 2243 buildShared := library.BuildSharedVariant() 2244 if buildStatic && buildShared { 2245 variations := append([]string{"static", "shared"}, variations...) 2246 2247 modules := mctx.CreateLocalVariations(variations...) 2248 static := modules[0].(LinkableInterface) 2249 shared := modules[1].(LinkableInterface) 2250 2251 static.SetStatic() 2252 shared.SetShared() 2253 2254 if _, ok := library.(*Module); ok { 2255 reuseStaticLibrary(mctx, static.(*Module), shared.(*Module)) 2256 } 2257 mctx.AliasVariation("shared") 2258 } else if buildStatic { 2259 variations := append([]string{"static"}, variations...) 2260 2261 modules := mctx.CreateLocalVariations(variations...) 2262 modules[0].(LinkableInterface).SetStatic() 2263 mctx.AliasVariation("static") 2264 } else if buildShared { 2265 variations := append([]string{"shared"}, variations...) 2266 2267 modules := mctx.CreateLocalVariations(variations...) 2268 modules[0].(LinkableInterface).SetShared() 2269 mctx.AliasVariation("shared") 2270 } else if len(variations) > 0 { 2271 mctx.CreateLocalVariations(variations...) 2272 mctx.AliasVariation(variations[0]) 2273 } 2274 } 2275} 2276 2277// normalizeVersions modifies `versions` in place, so that each raw version 2278// string becomes its normalized canonical form. 2279// Validates that the versions in `versions` are specified in least to greatest order. 2280func normalizeVersions(ctx android.BaseModuleContext, versions []string) { 2281 var previous android.ApiLevel 2282 for i, v := range versions { 2283 ver, err := android.ApiLevelFromUser(ctx, v) 2284 if err != nil { 2285 ctx.PropertyErrorf("versions", "%s", err.Error()) 2286 return 2287 } 2288 if i > 0 && ver.LessThanOrEqualTo(previous) { 2289 ctx.PropertyErrorf("versions", "not sorted: %v", versions) 2290 } 2291 versions[i] = ver.String() 2292 previous = ver 2293 } 2294} 2295 2296func createVersionVariations(mctx android.BottomUpMutatorContext, versions []string) { 2297 // "" is for the non-stubs (implementation) variant for system modules, or the LLNDK variant 2298 // for LLNDK modules. 2299 variants := append(android.CopyOf(versions), "") 2300 2301 m := mctx.Module().(*Module) 2302 isLLNDK := m.IsLlndk() 2303 isVendorPublicLibrary := m.IsVendorPublicLibrary() 2304 2305 modules := mctx.CreateLocalVariations(variants...) 2306 for i, m := range modules { 2307 2308 if variants[i] != "" || isLLNDK || isVendorPublicLibrary { 2309 // A stubs or LLNDK stubs variant. 2310 c := m.(*Module) 2311 c.sanitize = nil 2312 c.stl = nil 2313 c.Properties.PreventInstall = true 2314 lib := moduleLibraryInterface(m) 2315 isLatest := i == (len(versions) - 1) 2316 lib.setBuildStubs(isLatest) 2317 2318 if variants[i] != "" { 2319 // A non-LLNDK stubs module is hidden from make and has a dependency from the 2320 // implementation module to the stubs module. 2321 c.Properties.HideFromMake = true 2322 lib.setStubsVersion(variants[i]) 2323 mctx.AddInterVariantDependency(stubImplDepTag, modules[len(modules)-1], modules[i]) 2324 } 2325 } 2326 } 2327 mctx.AliasVariation("") 2328 latestVersion := "" 2329 if len(versions) > 0 { 2330 latestVersion = versions[len(versions)-1] 2331 } 2332 mctx.CreateAliasVariation("latest", latestVersion) 2333} 2334 2335func createPerApiVersionVariations(mctx android.BottomUpMutatorContext, minSdkVersion string) { 2336 from, err := nativeApiLevelFromUser(mctx, minSdkVersion) 2337 if err != nil { 2338 mctx.PropertyErrorf("min_sdk_version", err.Error()) 2339 return 2340 } 2341 2342 versionStrs := ndkLibraryVersions(mctx, from) 2343 modules := mctx.CreateLocalVariations(versionStrs...) 2344 2345 for i, module := range modules { 2346 module.(*Module).Properties.Sdk_version = StringPtr(versionStrs[i]) 2347 module.(*Module).Properties.Min_sdk_version = StringPtr(versionStrs[i]) 2348 } 2349} 2350 2351func CanBeOrLinkAgainstVersionVariants(module interface { 2352 Host() bool 2353 InRamdisk() bool 2354 InVendorRamdisk() bool 2355}) bool { 2356 return !module.Host() && !module.InRamdisk() && !module.InVendorRamdisk() 2357} 2358 2359func CanBeVersionVariant(module interface { 2360 Host() bool 2361 InRamdisk() bool 2362 InVendorRamdisk() bool 2363 InRecovery() bool 2364 CcLibraryInterface() bool 2365 Shared() bool 2366}) bool { 2367 return CanBeOrLinkAgainstVersionVariants(module) && 2368 module.CcLibraryInterface() && module.Shared() 2369} 2370 2371func moduleLibraryInterface(module blueprint.Module) libraryInterface { 2372 if m, ok := module.(*Module); ok { 2373 return m.library 2374 } 2375 return nil 2376} 2377 2378// versionSelector normalizes the versions in the Stubs.Versions property into MutatedProperties.AllStubsVersions. 2379func versionSelectorMutator(mctx android.BottomUpMutatorContext) { 2380 if library := moduleLibraryInterface(mctx.Module()); library != nil && CanBeVersionVariant(mctx.Module().(*Module)) { 2381 if library.buildShared() { 2382 versions := library.stubsVersions(mctx) 2383 if len(versions) > 0 { 2384 normalizeVersions(mctx, versions) 2385 if mctx.Failed() { 2386 return 2387 } 2388 // Set the versions on the pre-mutated module so they can be read by any llndk modules that 2389 // depend on the implementation library and haven't been mutated yet. 2390 library.setAllStubsVersions(versions) 2391 } 2392 } 2393 } 2394} 2395 2396// versionMutator splits a module into the mandatory non-stubs variant 2397// (which is unnamed) and zero or more stubs variants. 2398func versionMutator(mctx android.BottomUpMutatorContext) { 2399 if library := moduleLibraryInterface(mctx.Module()); library != nil && CanBeVersionVariant(mctx.Module().(*Module)) { 2400 createVersionVariations(mctx, library.allStubsVersions()) 2401 return 2402 } 2403 2404 if m, ok := mctx.Module().(*Module); ok { 2405 if m.SplitPerApiLevel() && m.IsSdkVariant() { 2406 if mctx.Os() != android.Android { 2407 return 2408 } 2409 createPerApiVersionVariations(mctx, m.MinSdkVersion()) 2410 } 2411 } 2412} 2413 2414// maybeInjectBoringSSLHash adds a rule to run bssl_inject_hash on the output file if the module has the 2415// inject_bssl_hash or if any static library dependencies have inject_bssl_hash set. It returns the output path 2416// that the linked output file should be written to. 2417// TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries. 2418func maybeInjectBoringSSLHash(ctx android.ModuleContext, outputFile android.ModuleOutPath, 2419 inject *bool, fileName string) android.ModuleOutPath { 2420 // TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries. 2421 injectBoringSSLHash := Bool(inject) 2422 ctx.VisitDirectDeps(func(dep android.Module) { 2423 if tag, ok := ctx.OtherModuleDependencyTag(dep).(libraryDependencyTag); ok && tag.static() { 2424 if cc, ok := dep.(*Module); ok { 2425 if library, ok := cc.linker.(*libraryDecorator); ok { 2426 if Bool(library.Properties.Inject_bssl_hash) { 2427 injectBoringSSLHash = true 2428 } 2429 } 2430 } 2431 } 2432 }) 2433 if injectBoringSSLHash { 2434 hashedOutputfile := outputFile 2435 outputFile = android.PathForModuleOut(ctx, "unhashed", fileName) 2436 2437 rule := android.NewRuleBuilder(pctx, ctx) 2438 rule.Command(). 2439 BuiltTool("bssl_inject_hash"). 2440 FlagWithInput("-in-object ", outputFile). 2441 FlagWithOutput("-o ", hashedOutputfile) 2442 rule.Build("injectCryptoHash", "inject crypto hash") 2443 } 2444 2445 return outputFile 2446} 2447 2448func sharedOrStaticLibraryBp2Build(ctx android.TopDownMutatorContext, module *Module, isStatic bool) { 2449 baseAttributes := bp2BuildParseBaseProps(ctx, module) 2450 compilerAttrs := baseAttributes.compilerAttributes 2451 linkerAttrs := baseAttributes.linkerAttributes 2452 2453 exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, compilerAttrs.includes) 2454 2455 // Append shared/static{} stanza properties. These won't be specified on 2456 // cc_library_* itself, but may be specified in cc_defaults that this module 2457 // depends on. 2458 libSharedOrStaticAttrs := bp2BuildParseLibProps(ctx, module, isStatic) 2459 2460 compilerAttrs.srcs.Append(libSharedOrStaticAttrs.Srcs) 2461 compilerAttrs.cSrcs.Append(libSharedOrStaticAttrs.Srcs_c) 2462 compilerAttrs.asSrcs.Append(libSharedOrStaticAttrs.Srcs_as) 2463 compilerAttrs.copts.Append(libSharedOrStaticAttrs.Copts) 2464 2465 linkerAttrs.deps.Append(libSharedOrStaticAttrs.Deps) 2466 linkerAttrs.implementationDeps.Append(libSharedOrStaticAttrs.Implementation_deps) 2467 linkerAttrs.dynamicDeps.Append(libSharedOrStaticAttrs.Dynamic_deps) 2468 linkerAttrs.implementationDynamicDeps.Append(libSharedOrStaticAttrs.Implementation_dynamic_deps) 2469 linkerAttrs.systemDynamicDeps.Append(libSharedOrStaticAttrs.System_dynamic_deps) 2470 2471 asFlags := compilerAttrs.asFlags 2472 if compilerAttrs.asSrcs.IsEmpty() { 2473 // Skip asflags for BUILD file simplicity if there are no assembly sources. 2474 asFlags = bazel.MakeStringListAttribute(nil) 2475 } 2476 2477 commonAttrs := staticOrSharedAttributes{ 2478 Srcs: compilerAttrs.srcs, 2479 Srcs_c: compilerAttrs.cSrcs, 2480 Srcs_as: compilerAttrs.asSrcs, 2481 Copts: compilerAttrs.copts, 2482 Hdrs: compilerAttrs.hdrs, 2483 2484 Deps: linkerAttrs.deps, 2485 Implementation_deps: linkerAttrs.implementationDeps, 2486 Dynamic_deps: linkerAttrs.dynamicDeps, 2487 Implementation_dynamic_deps: linkerAttrs.implementationDynamicDeps, 2488 Whole_archive_deps: linkerAttrs.wholeArchiveDeps, 2489 Implementation_whole_archive_deps: linkerAttrs.implementationWholeArchiveDeps, 2490 System_dynamic_deps: linkerAttrs.systemDynamicDeps, 2491 sdkAttributes: bp2BuildParseSdkAttributes(module), 2492 } 2493 2494 var attrs interface{} 2495 if isStatic { 2496 commonAttrs.Deps.Add(baseAttributes.protoDependency) 2497 attrs = &bazelCcLibraryStaticAttributes{ 2498 staticOrSharedAttributes: commonAttrs, 2499 2500 Use_libcrt: linkerAttrs.useLibcrt, 2501 Use_version_lib: linkerAttrs.useVersionLib, 2502 2503 Rtti: compilerAttrs.rtti, 2504 Stl: compilerAttrs.stl, 2505 Cpp_std: compilerAttrs.cppStd, 2506 C_std: compilerAttrs.cStd, 2507 2508 Export_includes: exportedIncludes.Includes, 2509 Export_absolute_includes: exportedIncludes.AbsoluteIncludes, 2510 Export_system_includes: exportedIncludes.SystemIncludes, 2511 Local_includes: compilerAttrs.localIncludes, 2512 Absolute_includes: compilerAttrs.absoluteIncludes, 2513 2514 Cppflags: compilerAttrs.cppFlags, 2515 Conlyflags: compilerAttrs.conlyFlags, 2516 Asflags: asFlags, 2517 2518 Features: linkerAttrs.features, 2519 } 2520 } else { 2521 commonAttrs.Dynamic_deps.Add(baseAttributes.protoDependency) 2522 2523 attrs = &bazelCcLibrarySharedAttributes{ 2524 staticOrSharedAttributes: commonAttrs, 2525 2526 Cppflags: compilerAttrs.cppFlags, 2527 Conlyflags: compilerAttrs.conlyFlags, 2528 Asflags: asFlags, 2529 2530 Linkopts: linkerAttrs.linkopts, 2531 Link_crt: linkerAttrs.linkCrt, 2532 Use_libcrt: linkerAttrs.useLibcrt, 2533 Use_version_lib: linkerAttrs.useVersionLib, 2534 2535 Rtti: compilerAttrs.rtti, 2536 Stl: compilerAttrs.stl, 2537 Cpp_std: compilerAttrs.cppStd, 2538 C_std: compilerAttrs.cStd, 2539 2540 Export_includes: exportedIncludes.Includes, 2541 Export_absolute_includes: exportedIncludes.AbsoluteIncludes, 2542 Export_system_includes: exportedIncludes.SystemIncludes, 2543 Local_includes: compilerAttrs.localIncludes, 2544 Absolute_includes: compilerAttrs.absoluteIncludes, 2545 Additional_linker_inputs: linkerAttrs.additionalLinkerInputs, 2546 2547 Strip: stripAttributes{ 2548 Keep_symbols: linkerAttrs.stripKeepSymbols, 2549 Keep_symbols_and_debug_frame: linkerAttrs.stripKeepSymbolsAndDebugFrame, 2550 Keep_symbols_list: linkerAttrs.stripKeepSymbolsList, 2551 All: linkerAttrs.stripAll, 2552 None: linkerAttrs.stripNone, 2553 }, 2554 2555 Features: linkerAttrs.features, 2556 2557 Stubs_symbol_file: compilerAttrs.stubsSymbolFile, 2558 Stubs_versions: compilerAttrs.stubsVersions, 2559 } 2560 } 2561 2562 var modType string 2563 if isStatic { 2564 modType = "cc_library_static" 2565 } else { 2566 modType = "cc_library_shared" 2567 } 2568 props := bazel.BazelTargetModuleProperties{ 2569 Rule_class: modType, 2570 Bzl_load_location: fmt.Sprintf("//build/bazel/rules/cc:%s.bzl", modType), 2571 } 2572 2573 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs) 2574} 2575 2576// TODO(b/199902614): Can this be factored to share with the other Attributes? 2577type bazelCcLibraryStaticAttributes struct { 2578 staticOrSharedAttributes 2579 2580 Use_libcrt bazel.BoolAttribute 2581 Use_version_lib bazel.BoolAttribute 2582 2583 Rtti bazel.BoolAttribute 2584 Stl *string 2585 Cpp_std *string 2586 C_std *string 2587 2588 Export_includes bazel.StringListAttribute 2589 Export_absolute_includes bazel.StringListAttribute 2590 Export_system_includes bazel.StringListAttribute 2591 Local_includes bazel.StringListAttribute 2592 Absolute_includes bazel.StringListAttribute 2593 Hdrs bazel.LabelListAttribute 2594 2595 Cppflags bazel.StringListAttribute 2596 Conlyflags bazel.StringListAttribute 2597 Asflags bazel.StringListAttribute 2598 2599 Features bazel.StringListAttribute 2600} 2601 2602// TODO(b/199902614): Can this be factored to share with the other Attributes? 2603type bazelCcLibrarySharedAttributes struct { 2604 staticOrSharedAttributes 2605 2606 Linkopts bazel.StringListAttribute 2607 Link_crt bazel.BoolAttribute // Only for linking shared library (and cc_binary) 2608 2609 Use_libcrt bazel.BoolAttribute 2610 Use_version_lib bazel.BoolAttribute 2611 2612 Rtti bazel.BoolAttribute 2613 Stl *string 2614 Cpp_std *string 2615 C_std *string 2616 2617 Export_includes bazel.StringListAttribute 2618 Export_absolute_includes bazel.StringListAttribute 2619 Export_system_includes bazel.StringListAttribute 2620 Local_includes bazel.StringListAttribute 2621 Absolute_includes bazel.StringListAttribute 2622 Hdrs bazel.LabelListAttribute 2623 2624 Strip stripAttributes 2625 Additional_linker_inputs bazel.LabelListAttribute 2626 2627 Cppflags bazel.StringListAttribute 2628 Conlyflags bazel.StringListAttribute 2629 Asflags bazel.StringListAttribute 2630 2631 Features bazel.StringListAttribute 2632 2633 Stubs_symbol_file *string 2634 Stubs_versions bazel.StringListAttribute 2635 Inject_bssl_hash bazel.BoolAttribute 2636} 2637