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