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 	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 }
    882