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