Home | History | Annotate | Download | only in cc
      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