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 15 package cc 16 17 import ( 18 "strings" 19 20 "github.com/google/blueprint" 21 "github.com/google/blueprint/pathtools" 22 23 "android/soong/android" 24 ) 25 26 type LibraryProperties struct { 27 Static struct { 28 Srcs []string `android:"arch_variant"` 29 Cflags []string `android:"arch_variant"` 30 31 Enabled *bool `android:"arch_variant"` 32 Whole_static_libs []string `android:"arch_variant"` 33 Static_libs []string `android:"arch_variant"` 34 Shared_libs []string `android:"arch_variant"` 35 } `android:"arch_variant"` 36 Shared struct { 37 Srcs []string `android:"arch_variant"` 38 Cflags []string `android:"arch_variant"` 39 40 Enabled *bool `android:"arch_variant"` 41 Whole_static_libs []string `android:"arch_variant"` 42 Static_libs []string `android:"arch_variant"` 43 Shared_libs []string `android:"arch_variant"` 44 } `android:"arch_variant"` 45 46 // local file name to pass to the linker as --version_script 47 Version_script *string `android:"arch_variant"` 48 // local file name to pass to the linker as -unexported_symbols_list 49 Unexported_symbols_list *string `android:"arch_variant"` 50 // local file name to pass to the linker as -force_symbols_not_weak_list 51 Force_symbols_not_weak_list *string `android:"arch_variant"` 52 // local file name to pass to the linker as -force_symbols_weak_list 53 Force_symbols_weak_list *string `android:"arch_variant"` 54 55 // rename host libraries to prevent overlap with system installed libraries 56 Unique_host_soname *bool 57 58 Aidl struct { 59 // export headers generated from .aidl sources 60 Export_aidl_headers bool 61 } 62 63 Proto struct { 64 // export headers generated from .proto sources 65 Export_proto_headers bool 66 } 67 } 68 69 type LibraryMutatedProperties struct { 70 VariantName string `blueprint:"mutated"` 71 72 // Build a static variant 73 BuildStatic bool `blueprint:"mutated"` 74 // Build a shared variant 75 BuildShared bool `blueprint:"mutated"` 76 // This variant is shared 77 VariantIsShared bool `blueprint:"mutated"` 78 // This variant is static 79 VariantIsStatic bool `blueprint:"mutated"` 80 } 81 82 type FlagExporterProperties struct { 83 // list of directories relative to the Blueprints file that will 84 // be added to the include path (using -I) for this module and any module that links 85 // against this module 86 Export_include_dirs []string `android:"arch_variant"` 87 88 Target struct { 89 Vendor struct { 90 // list of exported include directories, like 91 // export_include_dirs, that will be applied to the 92 // vendor variant of this library. This will overwrite 93 // any other declarations. 94 Export_include_dirs []string 95 } 96 } 97 } 98 99 func init() { 100 android.RegisterModuleType("cc_library_static", libraryStaticFactory) 101 android.RegisterModuleType("cc_library_shared", librarySharedFactory) 102 android.RegisterModuleType("cc_library", libraryFactory) 103 android.RegisterModuleType("cc_library_host_static", libraryHostStaticFactory) 104 android.RegisterModuleType("cc_library_host_shared", libraryHostSharedFactory) 105 android.RegisterModuleType("cc_library_headers", libraryHeaderFactory) 106 } 107 108 // Module factory for combined static + shared libraries, device by default but with possible host 109 // support 110 func libraryFactory() android.Module { 111 module, _ := NewLibrary(android.HostAndDeviceSupported) 112 return module.Init() 113 } 114 115 // Module factory for static libraries 116 func libraryStaticFactory() android.Module { 117 module, library := NewLibrary(android.HostAndDeviceSupported) 118 library.BuildOnlyStatic() 119 return module.Init() 120 } 121 122 // Module factory for shared libraries 123 func librarySharedFactory() android.Module { 124 module, library := NewLibrary(android.HostAndDeviceSupported) 125 library.BuildOnlyShared() 126 return module.Init() 127 } 128 129 // Module factory for host static libraries 130 func libraryHostStaticFactory() android.Module { 131 module, library := NewLibrary(android.HostSupported) 132 library.BuildOnlyStatic() 133 return module.Init() 134 } 135 136 // Module factory for host shared libraries 137 func libraryHostSharedFactory() android.Module { 138 module, library := NewLibrary(android.HostSupported) 139 library.BuildOnlyShared() 140 return module.Init() 141 } 142 143 // Module factory for header-only libraries 144 func libraryHeaderFactory() android.Module { 145 module, library := NewLibrary(android.HostAndDeviceSupported) 146 library.HeaderOnly() 147 return module.Init() 148 } 149 150 type flagExporter struct { 151 Properties FlagExporterProperties 152 153 flags []string 154 flagsDeps android.Paths 155 } 156 157 func (f *flagExporter) exportedIncludes(ctx ModuleContext) android.Paths { 158 if ctx.vndk() && f.Properties.Target.Vendor.Export_include_dirs != nil { 159 return android.PathsForModuleSrc(ctx, f.Properties.Target.Vendor.Export_include_dirs) 160 } else { 161 return android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs) 162 } 163 } 164 165 func (f *flagExporter) exportIncludes(ctx ModuleContext, inc string) { 166 includeDirs := f.exportedIncludes(ctx) 167 for _, dir := range includeDirs.Strings() { 168 f.flags = append(f.flags, inc+dir) 169 } 170 } 171 172 func (f *flagExporter) reexportFlags(flags []string) { 173 f.flags = append(f.flags, flags...) 174 } 175 176 func (f *flagExporter) reexportDeps(deps android.Paths) { 177 f.flagsDeps = append(f.flagsDeps, deps...) 178 } 179 180 func (f *flagExporter) exportedFlags() []string { 181 return f.flags 182 } 183 184 func (f *flagExporter) exportedFlagsDeps() android.Paths { 185 return f.flagsDeps 186 } 187 188 type exportedFlagsProducer interface { 189 exportedFlags() []string 190 exportedFlagsDeps() android.Paths 191 } 192 193 var _ exportedFlagsProducer = (*flagExporter)(nil) 194 195 // libraryDecorator wraps baseCompiler, baseLinker and baseInstaller to provide library-specific 196 // functionality: static vs. shared linkage, reusing object files for shared libraries 197 type libraryDecorator struct { 198 Properties LibraryProperties 199 MutatedProperties LibraryMutatedProperties 200 201 // For reusing static library objects for shared library 202 reuseObjects Objects 203 reuseExportedFlags []string 204 reuseExportedDeps android.Paths 205 206 // table-of-contents file to optimize out relinking when possible 207 tocFile android.OptionalPath 208 209 flagExporter 210 stripper 211 relocationPacker 212 213 // If we're used as a whole_static_lib, our missing dependencies need 214 // to be given 215 wholeStaticMissingDeps []string 216 217 // For whole_static_libs 218 objects Objects 219 220 // Uses the module's name if empty, but can be overridden. Does not include 221 // shlib suffix. 222 libName string 223 224 sanitize *sanitize 225 226 sabi *sabi 227 228 // Output archive of gcno coverage information files 229 coverageOutputFile android.OptionalPath 230 231 // linked Source Abi Dump 232 sAbiOutputFile android.OptionalPath 233 234 // Source Abi Diff 235 sAbiDiff android.OptionalPath 236 237 // Decorated interafaces 238 *baseCompiler 239 *baseLinker 240 *baseInstaller 241 } 242 243 func (library *libraryDecorator) linkerProps() []interface{} { 244 var props []interface{} 245 props = append(props, library.baseLinker.linkerProps()...) 246 return append(props, 247 &library.Properties, 248 &library.MutatedProperties, 249 &library.flagExporter.Properties, 250 &library.stripper.StripProperties, 251 &library.relocationPacker.Properties) 252 } 253 254 func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { 255 flags = library.baseLinker.linkerFlags(ctx, flags) 256 257 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because 258 // all code is position independent, and then those warnings get promoted to 259 // errors. 260 if !ctx.Windows() { 261 flags.CFlags = append(flags.CFlags, "-fPIC") 262 } 263 264 if library.static() { 265 flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...) 266 } else if library.shared() { 267 flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...) 268 } 269 270 if library.shared() { 271 libName := library.getLibName(ctx) 272 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead 273 sharedFlag := "-Wl,-shared" 274 if flags.Clang || ctx.Host() { 275 sharedFlag = "-shared" 276 } 277 var f []string 278 if ctx.toolchain().Bionic() { 279 f = append(f, 280 "-nostdlib", 281 "-Wl,--gc-sections", 282 ) 283 } 284 285 if ctx.Darwin() { 286 f = append(f, 287 "-dynamiclib", 288 "-single_module", 289 "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(), 290 ) 291 if ctx.Arch().ArchType == android.X86 { 292 f = append(f, 293 "-read_only_relocs suppress", 294 ) 295 } 296 } else { 297 f = append(f, 298 sharedFlag, 299 "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix()) 300 } 301 302 flags.LdFlags = append(f, flags.LdFlags...) 303 } 304 305 return flags 306 } 307 308 func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags { 309 exportIncludeDirs := library.flagExporter.exportedIncludes(ctx) 310 if len(exportIncludeDirs) > 0 { 311 f := includeDirsToFlags(exportIncludeDirs) 312 flags.GlobalFlags = append(flags.GlobalFlags, f) 313 flags.YasmFlags = append(flags.YasmFlags, f) 314 } 315 316 return library.baseCompiler.compilerFlags(ctx, flags) 317 } 318 319 func extractExportIncludesFromFlags(flags []string) []string { 320 // This method is used in the generation of rules which produce 321 // abi-dumps for source files. Exported headers are needed to infer the 322 // abi exported by a library and filter out the rest of the abi dumped 323 // from a source. We extract the include flags exported by a library. 324 // This includes the flags exported which are re-exported from static 325 // library dependencies, exported header library dependencies and 326 // generated header dependencies. Re-exported shared library include 327 // flags are not in this set since shared library dependencies will 328 // themselves be included in the vndk. -isystem headers are not included 329 // since for bionic libraries, abi-filtering is taken care of by version 330 // scripts. 331 var exportedIncludes []string 332 for _, flag := range flags { 333 if strings.HasPrefix(flag, "-I") { 334 exportedIncludes = append(exportedIncludes, flag) 335 } 336 } 337 return exportedIncludes 338 } 339 340 func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { 341 if !library.buildShared() && !library.buildStatic() { 342 if len(library.baseCompiler.Properties.Srcs) > 0 { 343 ctx.PropertyErrorf("srcs", "cc_library_headers must not have any srcs") 344 } 345 if len(library.Properties.Static.Srcs) > 0 { 346 ctx.PropertyErrorf("static.srcs", "cc_library_headers must not have any srcs") 347 } 348 if len(library.Properties.Shared.Srcs) > 0 { 349 ctx.PropertyErrorf("shared.srcs", "cc_library_headers must not have any srcs") 350 } 351 return Objects{} 352 } 353 if ctx.createVndkSourceAbiDump() || library.sabi.Properties.CreateSAbiDumps { 354 exportIncludeDirs := android.PathsForModuleSrc(ctx, library.flagExporter.Properties.Export_include_dirs) 355 var SourceAbiFlags []string 356 for _, dir := range exportIncludeDirs.Strings() { 357 SourceAbiFlags = append(SourceAbiFlags, "-I"+dir) 358 } 359 for _, reexportedInclude := range extractExportIncludesFromFlags(library.sabi.Properties.ReexportedIncludeFlags) { 360 SourceAbiFlags = append(SourceAbiFlags, reexportedInclude) 361 } 362 flags.SAbiFlags = SourceAbiFlags 363 total_length := len(library.baseCompiler.Properties.Srcs) + len(deps.GeneratedSources) + len(library.Properties.Shared.Srcs) + 364 len(library.Properties.Static.Srcs) 365 if total_length > 0 { 366 flags.SAbiDump = true 367 } 368 } 369 objs := library.baseCompiler.compile(ctx, flags, deps) 370 library.reuseObjects = objs 371 buildFlags := flagsToBuilderFlags(flags) 372 373 if library.static() { 374 srcs := android.PathsForModuleSrc(ctx, library.Properties.Static.Srcs) 375 objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceStaticLibrary, 376 srcs, library.baseCompiler.deps)) 377 } else if library.shared() { 378 srcs := android.PathsForModuleSrc(ctx, library.Properties.Shared.Srcs) 379 objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceSharedLibrary, 380 srcs, library.baseCompiler.deps)) 381 } 382 383 return objs 384 } 385 386 type libraryInterface interface { 387 getWholeStaticMissingDeps() []string 388 static() bool 389 objs() Objects 390 reuseObjs() (Objects, []string, android.Paths) 391 toc() android.OptionalPath 392 393 // Returns true if the build options for the module have selected a static or shared build 394 buildStatic() bool 395 buildShared() bool 396 397 // Sets whether a specific variant is static or shared 398 setStatic() 399 setShared() 400 } 401 402 func (library *libraryDecorator) getLibName(ctx ModuleContext) string { 403 name := library.libName 404 if name == "" { 405 name = ctx.baseModuleName() 406 } 407 408 if ctx.Host() && Bool(library.Properties.Unique_host_soname) { 409 if !strings.HasSuffix(name, "-host") { 410 name = name + "-host" 411 } 412 } 413 414 return name + library.MutatedProperties.VariantName 415 } 416 417 func (library *libraryDecorator) linkerInit(ctx BaseModuleContext) { 418 location := InstallInSystem 419 if library.sanitize.inSanitizerDir() { 420 location = InstallInSanitizerDir 421 } 422 library.baseInstaller.location = location 423 424 library.baseLinker.linkerInit(ctx) 425 426 library.relocationPacker.packingInit(ctx) 427 } 428 429 func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { 430 deps = library.baseLinker.linkerDeps(ctx, deps) 431 432 if library.static() { 433 deps.WholeStaticLibs = append(deps.WholeStaticLibs, 434 library.Properties.Static.Whole_static_libs...) 435 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...) 436 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...) 437 } else if library.shared() { 438 if ctx.toolchain().Bionic() && !Bool(library.baseLinker.Properties.Nocrt) { 439 if !ctx.sdk() { 440 deps.CrtBegin = "crtbegin_so" 441 deps.CrtEnd = "crtend_so" 442 } else { 443 // TODO(danalbert): Add generation of crt objects. 444 // For `sdk_version: "current"`, we don't actually have a 445 // freshly generated set of CRT objects. Use the last stable 446 // version. 447 version := ctx.sdkVersion() 448 if version == "current" { 449 version = getCurrentNdkPrebuiltVersion(ctx) 450 } 451 deps.CrtBegin = "ndk_crtbegin_so." + version 452 deps.CrtEnd = "ndk_crtend_so." + version 453 } 454 } 455 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...) 456 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...) 457 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...) 458 } 459 460 return deps 461 } 462 463 func (library *libraryDecorator) linkStatic(ctx ModuleContext, 464 flags Flags, deps PathDeps, objs Objects) android.Path { 465 466 library.objects = deps.WholeStaticLibObjs.Copy() 467 library.objects = library.objects.Append(objs) 468 469 outputFile := android.PathForModuleOut(ctx, 470 ctx.ModuleName()+library.MutatedProperties.VariantName+staticLibraryExtension) 471 builderFlags := flagsToBuilderFlags(flags) 472 473 TransformObjToStaticLib(ctx, library.objects.objFiles, builderFlags, outputFile, objs.tidyFiles) 474 475 library.coverageOutputFile = TransformCoverageFilesToLib(ctx, library.objects, builderFlags, 476 ctx.ModuleName()+library.MutatedProperties.VariantName) 477 478 library.wholeStaticMissingDeps = ctx.GetMissingDependencies() 479 480 ctx.CheckbuildFile(outputFile) 481 482 return outputFile 483 } 484 485 func (library *libraryDecorator) linkShared(ctx ModuleContext, 486 flags Flags, deps PathDeps, objs Objects) android.Path { 487 488 var linkerDeps android.Paths 489 490 versionScript := android.OptionalPathForModuleSrc(ctx, library.Properties.Version_script) 491 unexportedSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list) 492 forceNotWeakSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list) 493 forceWeakSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list) 494 if !ctx.Darwin() { 495 if versionScript.Valid() { 496 flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String()) 497 linkerDeps = append(linkerDeps, versionScript.Path()) 498 } 499 if unexportedSymbols.Valid() { 500 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin") 501 } 502 if forceNotWeakSymbols.Valid() { 503 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin") 504 } 505 if forceWeakSymbols.Valid() { 506 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin") 507 } 508 } else { 509 if versionScript.Valid() { 510 ctx.PropertyErrorf("version_script", "Not supported on Darwin") 511 } 512 if unexportedSymbols.Valid() { 513 flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String()) 514 linkerDeps = append(linkerDeps, unexportedSymbols.Path()) 515 } 516 if forceNotWeakSymbols.Valid() { 517 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String()) 518 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path()) 519 } 520 if forceWeakSymbols.Valid() { 521 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String()) 522 linkerDeps = append(linkerDeps, forceWeakSymbols.Path()) 523 } 524 } 525 526 fileName := library.getLibName(ctx) + flags.Toolchain.ShlibSuffix() 527 outputFile := android.PathForModuleOut(ctx, fileName) 528 ret := outputFile 529 530 builderFlags := flagsToBuilderFlags(flags) 531 532 if !ctx.Darwin() && !ctx.Windows() { 533 // Optimize out relinking against shared libraries whose interface hasn't changed by 534 // depending on a table of contents file instead of the library itself. 535 tocPath := outputFile.RelPathString() 536 tocPath = pathtools.ReplaceExtension(tocPath, flags.Toolchain.ShlibSuffix()[1:]+".toc") 537 tocFile := android.PathForOutput(ctx, tocPath) 538 library.tocFile = android.OptionalPathForPath(tocFile) 539 TransformSharedObjectToToc(ctx, outputFile, tocFile, builderFlags) 540 } 541 542 if library.relocationPacker.needsPacking(ctx) { 543 packedOutputFile := outputFile 544 outputFile = android.PathForModuleOut(ctx, "unpacked", fileName) 545 library.relocationPacker.pack(ctx, outputFile, packedOutputFile, builderFlags) 546 } 547 548 if library.stripper.needsStrip(ctx) { 549 strippedOutputFile := outputFile 550 outputFile = android.PathForModuleOut(ctx, "unstripped", fileName) 551 library.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags) 552 } 553 554 sharedLibs := deps.SharedLibs 555 sharedLibs = append(sharedLibs, deps.LateSharedLibs...) 556 557 // TODO(danalbert): Clean this up when soong supports prebuilts. 558 if strings.HasPrefix(ctx.selectedStl(), "ndk_libc++") { 559 libDir := getNdkStlLibDir(ctx, flags.Toolchain, "libc++") 560 561 if strings.HasSuffix(ctx.selectedStl(), "_shared") { 562 deps.StaticLibs = append(deps.StaticLibs, 563 libDir.Join(ctx, "libandroid_support.a")) 564 } else { 565 deps.StaticLibs = append(deps.StaticLibs, 566 libDir.Join(ctx, "libc++abi.a"), 567 libDir.Join(ctx, "libandroid_support.a")) 568 } 569 570 if ctx.Arch().ArchType == android.Arm { 571 deps.StaticLibs = append(deps.StaticLibs, 572 libDir.Join(ctx, "libunwind.a")) 573 } 574 } 575 576 linkerDeps = append(linkerDeps, deps.SharedLibsDeps...) 577 linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...) 578 linkerDeps = append(linkerDeps, objs.tidyFiles...) 579 580 TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, 581 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, 582 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile) 583 584 objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...) 585 objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...) 586 587 objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.StaticLibObjs.sAbiDumpFiles...) 588 objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.WholeStaticLibObjs.sAbiDumpFiles...) 589 590 library.coverageOutputFile = TransformCoverageFilesToLib(ctx, objs, builderFlags, library.getLibName(ctx)) 591 library.linkSAbiDumpFiles(ctx, objs, fileName, ret) 592 593 return ret 594 } 595 596 func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) { 597 //Also take into account object re-use. 598 if len(objs.sAbiDumpFiles) > 0 && ctx.createVndkSourceAbiDump() { 599 refSourceDumpFile := android.PathForVndkRefAbiDump(ctx, "current", fileName, vndkVsNdk(ctx), true) 600 versionScript := android.OptionalPathForModuleSrc(ctx, library.Properties.Version_script) 601 var symbolFile android.OptionalPath 602 if versionScript.Valid() { 603 symbolFile = versionScript 604 } 605 exportIncludeDirs := android.PathsForModuleSrc(ctx, library.flagExporter.Properties.Export_include_dirs) 606 var SourceAbiFlags []string 607 for _, dir := range exportIncludeDirs.Strings() { 608 SourceAbiFlags = append(SourceAbiFlags, "-I"+dir) 609 } 610 for _, reexportedInclude := range extractExportIncludesFromFlags(library.sabi.Properties.ReexportedIncludeFlags) { 611 SourceAbiFlags = append(SourceAbiFlags, reexportedInclude) 612 } 613 exportedHeaderFlags := strings.Join(SourceAbiFlags, " ") 614 library.sAbiOutputFile = TransformDumpToLinkedDump(ctx, objs.sAbiDumpFiles, soFile, symbolFile, "current", fileName, exportedHeaderFlags) 615 if refSourceDumpFile.Valid() { 616 unzippedRefDump := UnzipRefDump(ctx, refSourceDumpFile.Path(), fileName) 617 library.sAbiDiff = SourceAbiDiff(ctx, library.sAbiOutputFile.Path(), unzippedRefDump, fileName) 618 } 619 } 620 } 621 622 func vndkVsNdk(ctx ModuleContext) bool { 623 if inList(ctx.baseModuleName(), llndkLibraries) { 624 return false 625 } 626 return true 627 } 628 629 func (library *libraryDecorator) link(ctx ModuleContext, 630 flags Flags, deps PathDeps, objs Objects) android.Path { 631 632 objs = objs.Append(deps.Objs) 633 634 var out android.Path 635 if library.static() || library.header() { 636 out = library.linkStatic(ctx, flags, deps, objs) 637 } else { 638 out = library.linkShared(ctx, flags, deps, objs) 639 } 640 641 library.exportIncludes(ctx, "-I") 642 library.reexportFlags(deps.ReexportedFlags) 643 library.reexportDeps(deps.ReexportedFlagsDeps) 644 645 if library.Properties.Aidl.Export_aidl_headers { 646 if library.baseCompiler.hasSrcExt(".aidl") { 647 flags := []string{ 648 "-I" + android.PathForModuleGen(ctx, "aidl").String(), 649 } 650 library.reexportFlags(flags) 651 library.reuseExportedFlags = append(library.reuseExportedFlags, flags...) 652 library.reexportDeps(library.baseCompiler.deps) // TODO: restrict to aidl deps 653 library.reuseExportedDeps = append(library.reuseExportedDeps, library.baseCompiler.deps...) 654 } 655 } 656 657 if library.Properties.Proto.Export_proto_headers { 658 if library.baseCompiler.hasSrcExt(".proto") { 659 flags := []string{ 660 "-I" + protoSubDir(ctx).String(), 661 "-I" + protoDir(ctx).String(), 662 } 663 library.reexportFlags(flags) 664 library.reuseExportedFlags = append(library.reuseExportedFlags, flags...) 665 library.reexportDeps(library.baseCompiler.deps) // TODO: restrict to proto deps 666 library.reuseExportedDeps = append(library.reuseExportedDeps, library.baseCompiler.deps...) 667 } 668 } 669 670 return out 671 } 672 673 func (library *libraryDecorator) buildStatic() bool { 674 return library.MutatedProperties.BuildStatic && 675 (library.Properties.Static.Enabled == nil || *library.Properties.Static.Enabled) 676 } 677 678 func (library *libraryDecorator) buildShared() bool { 679 return library.MutatedProperties.BuildShared && 680 (library.Properties.Shared.Enabled == nil || *library.Properties.Shared.Enabled) 681 } 682 683 func (library *libraryDecorator) getWholeStaticMissingDeps() []string { 684 return library.wholeStaticMissingDeps 685 } 686 687 func (library *libraryDecorator) objs() Objects { 688 return library.objects 689 } 690 691 func (library *libraryDecorator) reuseObjs() (Objects, []string, android.Paths) { 692 return library.reuseObjects, library.reuseExportedFlags, library.reuseExportedDeps 693 } 694 695 func (library *libraryDecorator) toc() android.OptionalPath { 696 return library.tocFile 697 } 698 699 func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) { 700 if library.shared() { 701 if ctx.Device() { 702 if ctx.vndk() { 703 if ctx.isVndkSp() { 704 library.baseInstaller.subDir = "vndk-sp" 705 } else if ctx.isVndk() { 706 library.baseInstaller.subDir = "vndk" 707 } 708 } 709 } 710 library.baseInstaller.install(ctx, file) 711 } 712 } 713 714 func (library *libraryDecorator) static() bool { 715 return library.MutatedProperties.VariantIsStatic 716 } 717 718 func (library *libraryDecorator) shared() bool { 719 return library.MutatedProperties.VariantIsShared 720 } 721 722 func (library *libraryDecorator) header() bool { 723 return !library.static() && !library.shared() 724 } 725 726 func (library *libraryDecorator) setStatic() { 727 library.MutatedProperties.VariantIsStatic = true 728 library.MutatedProperties.VariantIsShared = false 729 } 730 731 func (library *libraryDecorator) setShared() { 732 library.MutatedProperties.VariantIsStatic = false 733 library.MutatedProperties.VariantIsShared = true 734 } 735 736 func (library *libraryDecorator) BuildOnlyStatic() { 737 library.MutatedProperties.BuildShared = false 738 } 739 740 func (library *libraryDecorator) BuildOnlyShared() { 741 library.MutatedProperties.BuildStatic = false 742 } 743 744 func (library *libraryDecorator) HeaderOnly() { 745 library.MutatedProperties.BuildShared = false 746 library.MutatedProperties.BuildStatic = false 747 } 748 749 func NewLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { 750 module := newModule(hod, android.MultilibBoth) 751 752 library := &libraryDecorator{ 753 MutatedProperties: LibraryMutatedProperties{ 754 BuildShared: true, 755 BuildStatic: true, 756 }, 757 baseCompiler: NewBaseCompiler(), 758 baseLinker: NewBaseLinker(), 759 baseInstaller: NewBaseInstaller("lib", "lib64", InstallInSystem), 760 sanitize: module.sanitize, 761 sabi: module.sabi, 762 } 763 764 module.compiler = library 765 module.linker = library 766 module.installer = library 767 768 return module, library 769 } 770 771 // connects a shared library to a static library in order to reuse its .o files to avoid 772 // compiling source files twice. 773 func reuseStaticLibrary(mctx android.BottomUpMutatorContext, static, shared *Module) { 774 if staticCompiler, ok := static.compiler.(*libraryDecorator); ok { 775 sharedCompiler := shared.compiler.(*libraryDecorator) 776 if len(staticCompiler.Properties.Static.Cflags) == 0 && 777 len(sharedCompiler.Properties.Shared.Cflags) == 0 { 778 779 mctx.AddInterVariantDependency(reuseObjTag, shared, static) 780 sharedCompiler.baseCompiler.Properties.OriginalSrcs = 781 sharedCompiler.baseCompiler.Properties.Srcs 782 sharedCompiler.baseCompiler.Properties.Srcs = nil 783 sharedCompiler.baseCompiler.Properties.Generated_sources = nil 784 } 785 } 786 } 787 788 func linkageMutator(mctx android.BottomUpMutatorContext) { 789 if m, ok := mctx.Module().(*Module); ok && m.linker != nil { 790 if library, ok := m.linker.(libraryInterface); ok { 791 var modules []blueprint.Module 792 if library.buildStatic() && library.buildShared() { 793 modules = mctx.CreateLocalVariations("static", "shared") 794 static := modules[0].(*Module) 795 shared := modules[1].(*Module) 796 797 static.linker.(libraryInterface).setStatic() 798 shared.linker.(libraryInterface).setShared() 799 800 reuseStaticLibrary(mctx, static, shared) 801 802 } else if library.buildStatic() { 803 modules = mctx.CreateLocalVariations("static") 804 modules[0].(*Module).linker.(libraryInterface).setStatic() 805 } else if library.buildShared() { 806 modules = mctx.CreateLocalVariations("shared") 807 modules[0].(*Module).linker.(libraryInterface).setShared() 808 } 809 } 810 } 811 } 812