| // Copyright 2015 Google Inc. All rights reserved. | 
 | // | 
 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | // you may not use this file except in compliance with the License. | 
 | // You may obtain a copy of the License at | 
 | // | 
 | //     http://www.apache.org/licenses/LICENSE-2.0 | 
 | // | 
 | // Unless required by applicable law or agreed to in writing, software | 
 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | // See the License for the specific language governing permissions and | 
 | // limitations under the License. | 
 |  | 
 | package cc | 
 |  | 
 | // This file contains the module types for compiling C/C++ for Android, and converts the properties | 
 | // into the flags and filenames necessary to pass to the compiler.  The final creation of the rules | 
 | // is handled in builder.go | 
 |  | 
 | import ( | 
 | 	"fmt" | 
 | 	"io" | 
 | 	"strconv" | 
 | 	"strings" | 
 |  | 
 | 	"github.com/google/blueprint" | 
 | 	"github.com/google/blueprint/proptools" | 
 |  | 
 | 	"android/soong/android" | 
 | 	"android/soong/cc/config" | 
 | 	"android/soong/genrule" | 
 | ) | 
 |  | 
 | func init() { | 
 | 	RegisterCCBuildComponents(android.InitRegistrationContext) | 
 |  | 
 | 	pctx.Import("android/soong/cc/config") | 
 | } | 
 |  | 
 | func RegisterCCBuildComponents(ctx android.RegistrationContext) { | 
 | 	ctx.RegisterModuleType("cc_defaults", defaultsFactory) | 
 |  | 
 | 	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { | 
 | 		ctx.BottomUp("sdk", sdkMutator).Parallel() | 
 | 		ctx.BottomUp("vndk", VndkMutator).Parallel() | 
 | 		ctx.BottomUp("link", LinkageMutator).Parallel() | 
 | 		ctx.BottomUp("ndk_api", NdkApiMutator).Parallel() | 
 | 		ctx.BottomUp("test_per_src", TestPerSrcMutator).Parallel() | 
 | 		ctx.BottomUp("version", VersionMutator).Parallel() | 
 | 		ctx.BottomUp("begin", BeginMutator).Parallel() | 
 | 		ctx.BottomUp("sysprop_cc", SyspropMutator).Parallel() | 
 | 		ctx.BottomUp("vendor_snapshot", VendorSnapshotMutator).Parallel() | 
 | 		ctx.BottomUp("vendor_snapshot_source", VendorSnapshotSourceMutator).Parallel() | 
 | 	}) | 
 |  | 
 | 	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { | 
 | 		ctx.TopDown("asan_deps", sanitizerDepsMutator(asan)) | 
 | 		ctx.BottomUp("asan", sanitizerMutator(asan)).Parallel() | 
 |  | 
 | 		ctx.TopDown("hwasan_deps", sanitizerDepsMutator(hwasan)) | 
 | 		ctx.BottomUp("hwasan", sanitizerMutator(hwasan)).Parallel() | 
 |  | 
 | 		ctx.TopDown("fuzzer_deps", sanitizerDepsMutator(fuzzer)) | 
 | 		ctx.BottomUp("fuzzer", sanitizerMutator(fuzzer)).Parallel() | 
 |  | 
 | 		// cfi mutator shouldn't run before sanitizers that return true for | 
 | 		// incompatibleWithCfi() | 
 | 		ctx.TopDown("cfi_deps", sanitizerDepsMutator(cfi)) | 
 | 		ctx.BottomUp("cfi", sanitizerMutator(cfi)).Parallel() | 
 |  | 
 | 		ctx.TopDown("scs_deps", sanitizerDepsMutator(scs)) | 
 | 		ctx.BottomUp("scs", sanitizerMutator(scs)).Parallel() | 
 |  | 
 | 		ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan)) | 
 | 		ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel() | 
 |  | 
 | 		ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel() | 
 | 		ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel() | 
 |  | 
 | 		ctx.BottomUp("coverage", coverageMutator).Parallel() | 
 | 		ctx.TopDown("vndk_deps", sabiDepsMutator) | 
 |  | 
 | 		ctx.TopDown("lto_deps", ltoDepsMutator) | 
 | 		ctx.BottomUp("lto", ltoMutator).Parallel() | 
 |  | 
 | 		ctx.TopDown("double_loadable", checkDoubleLoadableLibraries).Parallel() | 
 | 	}) | 
 |  | 
 | 	android.RegisterSingletonType("kythe_extract_all", kytheExtractAllFactory) | 
 | } | 
 |  | 
 | type Deps struct { | 
 | 	SharedLibs, LateSharedLibs                  []string | 
 | 	StaticLibs, LateStaticLibs, WholeStaticLibs []string | 
 | 	HeaderLibs                                  []string | 
 | 	RuntimeLibs                                 []string | 
 |  | 
 | 	StaticUnwinderIfLegacy bool | 
 |  | 
 | 	ReexportSharedLibHeaders, ReexportStaticLibHeaders, ReexportHeaderLibHeaders []string | 
 |  | 
 | 	ObjFiles []string | 
 |  | 
 | 	GeneratedSources []string | 
 | 	GeneratedHeaders []string | 
 | 	GeneratedDeps    []string | 
 |  | 
 | 	ReexportGeneratedHeaders []string | 
 |  | 
 | 	CrtBegin, CrtEnd string | 
 |  | 
 | 	// Used for host bionic | 
 | 	LinkerFlagsFile string | 
 | 	DynamicLinker   string | 
 | } | 
 |  | 
 | type PathDeps struct { | 
 | 	// Paths to .so files | 
 | 	SharedLibs, EarlySharedLibs, LateSharedLibs android.Paths | 
 | 	// Paths to the dependencies to use for .so files (.so.toc files) | 
 | 	SharedLibsDeps, EarlySharedLibsDeps, LateSharedLibsDeps android.Paths | 
 | 	// Paths to .a files | 
 | 	StaticLibs, LateStaticLibs, WholeStaticLibs android.Paths | 
 |  | 
 | 	// Paths to .o files | 
 | 	Objs               Objects | 
 | 	StaticLibObjs      Objects | 
 | 	WholeStaticLibObjs Objects | 
 |  | 
 | 	// Paths to generated source files | 
 | 	GeneratedSources android.Paths | 
 | 	GeneratedHeaders android.Paths | 
 | 	GeneratedDeps    android.Paths | 
 |  | 
 | 	Flags                      []string | 
 | 	IncludeDirs                android.Paths | 
 | 	SystemIncludeDirs          android.Paths | 
 | 	ReexportedDirs             android.Paths | 
 | 	ReexportedSystemDirs       android.Paths | 
 | 	ReexportedFlags            []string | 
 | 	ReexportedGeneratedHeaders android.Paths | 
 | 	ReexportedDeps             android.Paths | 
 |  | 
 | 	// Paths to crt*.o files | 
 | 	CrtBegin, CrtEnd android.OptionalPath | 
 |  | 
 | 	// Path to the file container flags to use with the linker | 
 | 	LinkerFlagsFile android.OptionalPath | 
 |  | 
 | 	// Path to the dynamic linker binary | 
 | 	DynamicLinker android.OptionalPath | 
 | } | 
 |  | 
 | // LocalOrGlobalFlags contains flags that need to have values set globally by the build system or locally by the module | 
 | // tracked separately, in order to maintain the required ordering (most of the global flags need to go first on the | 
 | // command line so they can be overridden by the local module flags). | 
 | type LocalOrGlobalFlags struct { | 
 | 	CommonFlags     []string // Flags that apply to C, C++, and assembly source files | 
 | 	AsFlags         []string // Flags that apply to assembly source files | 
 | 	YasmFlags       []string // Flags that apply to yasm assembly source files | 
 | 	CFlags          []string // Flags that apply to C and C++ source files | 
 | 	ToolingCFlags   []string // Flags that apply to C and C++ source files parsed by clang LibTooling tools | 
 | 	ConlyFlags      []string // Flags that apply to C source files | 
 | 	CppFlags        []string // Flags that apply to C++ source files | 
 | 	ToolingCppFlags []string // Flags that apply to C++ source files parsed by clang LibTooling tools | 
 | 	LdFlags         []string // Flags that apply to linker command lines | 
 | } | 
 |  | 
 | type Flags struct { | 
 | 	Local  LocalOrGlobalFlags | 
 | 	Global LocalOrGlobalFlags | 
 |  | 
 | 	aidlFlags     []string // Flags that apply to aidl source files | 
 | 	rsFlags       []string // Flags that apply to renderscript source files | 
 | 	libFlags      []string // Flags to add libraries early to the link order | 
 | 	extraLibFlags []string // Flags to add libraries late in the link order after LdFlags | 
 | 	TidyFlags     []string // Flags that apply to clang-tidy | 
 | 	SAbiFlags     []string // Flags that apply to header-abi-dumper | 
 |  | 
 | 	// Global include flags that apply to C, C++, and assembly source files | 
 | 	// These must be after any module include flags, which will be in CommonFlags. | 
 | 	SystemIncludeFlags []string | 
 |  | 
 | 	Toolchain    config.Toolchain | 
 | 	Tidy         bool | 
 | 	GcovCoverage bool | 
 | 	SAbiDump     bool | 
 | 	EmitXrefs    bool // If true, generate Ninja rules to generate emitXrefs input files for Kythe | 
 |  | 
 | 	RequiredInstructionSet string | 
 | 	DynamicLinker          string | 
 |  | 
 | 	CFlagsDeps  android.Paths // Files depended on by compiler flags | 
 | 	LdFlagsDeps android.Paths // Files depended on by linker flags | 
 |  | 
 | 	AssemblerWithCpp bool | 
 | 	GroupStaticLibs  bool | 
 |  | 
 | 	proto            android.ProtoFlags | 
 | 	protoC           bool // Whether to use C instead of C++ | 
 | 	protoOptionsFile bool // Whether to look for a .options file next to the .proto | 
 |  | 
 | 	Yacc *YaccProperties | 
 | } | 
 |  | 
 | // Properties used to compile all C or C++ modules | 
 | type BaseProperties struct { | 
 | 	// Deprecated. true is the default, false is invalid. | 
 | 	Clang *bool `android:"arch_variant"` | 
 |  | 
 | 	// Minimum sdk version supported when compiling against the ndk. Setting this property causes | 
 | 	// two variants to be built, one for the platform and one for apps. | 
 | 	Sdk_version *string | 
 |  | 
 | 	// Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX). | 
 | 	Min_sdk_version *string | 
 |  | 
 | 	// If true, always create an sdk variant and don't create a platform variant. | 
 | 	Sdk_variant_only *bool | 
 |  | 
 | 	AndroidMkSharedLibs       []string `blueprint:"mutated"` | 
 | 	AndroidMkStaticLibs       []string `blueprint:"mutated"` | 
 | 	AndroidMkRuntimeLibs      []string `blueprint:"mutated"` | 
 | 	AndroidMkWholeStaticLibs  []string `blueprint:"mutated"` | 
 | 	AndroidMkHeaderLibs       []string `blueprint:"mutated"` | 
 | 	HideFromMake              bool     `blueprint:"mutated"` | 
 | 	PreventInstall            bool     `blueprint:"mutated"` | 
 | 	ApexesProvidingSharedLibs []string `blueprint:"mutated"` | 
 |  | 
 | 	ImageVariationPrefix string `blueprint:"mutated"` | 
 | 	VndkVersion          string `blueprint:"mutated"` | 
 | 	SubName              string `blueprint:"mutated"` | 
 |  | 
 | 	// *.logtags files, to combine together in order to generate the /system/etc/event-log-tags | 
 | 	// file | 
 | 	Logtags []string | 
 |  | 
 | 	// Make this module available when building for ramdisk | 
 | 	Ramdisk_available *bool | 
 |  | 
 | 	// Make this module available when building for recovery | 
 | 	Recovery_available *bool | 
 |  | 
 | 	// Set by imageMutator | 
 | 	CoreVariantNeeded     bool     `blueprint:"mutated"` | 
 | 	RamdiskVariantNeeded  bool     `blueprint:"mutated"` | 
 | 	RecoveryVariantNeeded bool     `blueprint:"mutated"` | 
 | 	ExtraVariants         []string `blueprint:"mutated"` | 
 |  | 
 | 	// Allows this module to use non-APEX version of libraries. Useful | 
 | 	// for building binaries that are started before APEXes are activated. | 
 | 	Bootstrap *bool | 
 |  | 
 | 	// Even if DeviceConfig().VndkUseCoreVariant() is set, this module must use vendor variant. | 
 | 	// see soong/cc/config/vndk.go | 
 | 	MustUseVendorVariant bool `blueprint:"mutated"` | 
 |  | 
 | 	// Used by vendor snapshot to record dependencies from snapshot modules. | 
 | 	SnapshotSharedLibs  []string `blueprint:"mutated"` | 
 | 	SnapshotRuntimeLibs []string `blueprint:"mutated"` | 
 |  | 
 | 	Installable *bool | 
 |  | 
 | 	// Set by factories of module types that can only be referenced from variants compiled against | 
 | 	// the SDK. | 
 | 	AlwaysSdk bool `blueprint:"mutated"` | 
 |  | 
 | 	// Variant is an SDK variant created by sdkMutator | 
 | 	IsSdkVariant bool `blueprint:"mutated"` | 
 | 	// Set when both SDK and platform variants are exported to Make to trigger renaming the SDK | 
 | 	// variant to have a ".sdk" suffix. | 
 | 	SdkAndPlatformVariantVisibleToMake bool `blueprint:"mutated"` | 
 | } | 
 |  | 
 | type VendorProperties struct { | 
 | 	// whether this module should be allowed to be directly depended by other | 
 | 	// modules with `vendor: true`, `proprietary: true`, or `vendor_available:true`. | 
 | 	// In addition, this module should be allowed to be directly depended by | 
 | 	// product modules with `product_specific: true`. | 
 | 	// If set to true, three variants will be built separately, one like | 
 | 	// normal, another limited to the set of libraries and headers | 
 | 	// that are exposed to /vendor modules, and the other to /product modules. | 
 | 	// | 
 | 	// The vendor and product variants may be used with a different (newer) /system, | 
 | 	// so it shouldn't have any unversioned runtime dependencies, or | 
 | 	// make assumptions about the system that may not be true in the | 
 | 	// future. | 
 | 	// | 
 | 	// If set to false, this module becomes inaccessible from /vendor or /product | 
 | 	// modules. | 
 | 	// | 
 | 	// Default value is true when vndk: {enabled: true} or vendor: true. | 
 | 	// | 
 | 	// Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk | 
 | 	// If PRODUCT_PRODUCT_VNDK_VERSION isn't set, product variant will not be used. | 
 | 	Vendor_available *bool | 
 |  | 
 | 	// whether this module is capable of being loaded with other instance | 
 | 	// (possibly an older version) of the same module in the same process. | 
 | 	// Currently, a shared library that is a member of VNDK (vndk: {enabled: true}) | 
 | 	// can be double loaded in a vendor process if the library is also a | 
 | 	// (direct and indirect) dependency of an LLNDK library. Such libraries must be | 
 | 	// explicitly marked as `double_loadable: true` by the owner, or the dependency | 
 | 	// from the LLNDK lib should be cut if the lib is not designed to be double loaded. | 
 | 	Double_loadable *bool | 
 | } | 
 |  | 
 | type ModuleContextIntf interface { | 
 | 	static() bool | 
 | 	staticBinary() bool | 
 | 	header() bool | 
 | 	toolchain() config.Toolchain | 
 | 	canUseSdk() bool | 
 | 	useSdk() bool | 
 | 	sdkVersion() string | 
 | 	useVndk() bool | 
 | 	isNdk() bool | 
 | 	isLlndk(config android.Config) bool | 
 | 	isLlndkPublic(config android.Config) bool | 
 | 	isVndkPrivate(config android.Config) bool | 
 | 	isVndk() bool | 
 | 	isVndkSp() bool | 
 | 	isVndkExt() bool | 
 | 	inProduct() bool | 
 | 	inVendor() bool | 
 | 	inRamdisk() bool | 
 | 	inRecovery() bool | 
 | 	shouldCreateSourceAbiDump() bool | 
 | 	selectedStl() string | 
 | 	baseModuleName() string | 
 | 	getVndkExtendsModuleName() string | 
 | 	isPgoCompile() bool | 
 | 	isNDKStubLibrary() bool | 
 | 	useClangLld(actx ModuleContext) bool | 
 | 	isForPlatform() bool | 
 | 	apexName() string | 
 | 	apexSdkVersion() int | 
 | 	hasStubsVariants() bool | 
 | 	isStubs() bool | 
 | 	bootstrap() bool | 
 | 	mustUseVendorVariant() bool | 
 | 	nativeCoverage() bool | 
 | } | 
 |  | 
 | type ModuleContext interface { | 
 | 	android.ModuleContext | 
 | 	ModuleContextIntf | 
 | } | 
 |  | 
 | type BaseModuleContext interface { | 
 | 	android.BaseModuleContext | 
 | 	ModuleContextIntf | 
 | } | 
 |  | 
 | type DepsContext interface { | 
 | 	android.BottomUpMutatorContext | 
 | 	ModuleContextIntf | 
 | } | 
 |  | 
 | type feature interface { | 
 | 	begin(ctx BaseModuleContext) | 
 | 	deps(ctx DepsContext, deps Deps) Deps | 
 | 	flags(ctx ModuleContext, flags Flags) Flags | 
 | 	props() []interface{} | 
 | } | 
 |  | 
 | type compiler interface { | 
 | 	compilerInit(ctx BaseModuleContext) | 
 | 	compilerDeps(ctx DepsContext, deps Deps) Deps | 
 | 	compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags | 
 | 	compilerProps() []interface{} | 
 |  | 
 | 	appendCflags([]string) | 
 | 	appendAsflags([]string) | 
 | 	compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects | 
 | } | 
 |  | 
 | type linker interface { | 
 | 	linkerInit(ctx BaseModuleContext) | 
 | 	linkerDeps(ctx DepsContext, deps Deps) Deps | 
 | 	linkerFlags(ctx ModuleContext, flags Flags) Flags | 
 | 	linkerProps() []interface{} | 
 | 	useClangLld(actx ModuleContext) bool | 
 |  | 
 | 	link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path | 
 | 	appendLdflags([]string) | 
 | 	unstrippedOutputFilePath() android.Path | 
 |  | 
 | 	nativeCoverage() bool | 
 | 	coverageOutputFilePath() android.OptionalPath | 
 |  | 
 | 	// Get the deps that have been explicitly specified in the properties. | 
 | 	// Only updates the | 
 | 	linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps | 
 | } | 
 |  | 
 | type specifiedDeps struct { | 
 | 	sharedLibs       []string | 
 | 	systemSharedLibs []string // Note nil and [] are semantically distinct. | 
 | } | 
 |  | 
 | type installer interface { | 
 | 	installerProps() []interface{} | 
 | 	install(ctx ModuleContext, path android.Path) | 
 | 	everInstallable() bool | 
 | 	inData() bool | 
 | 	inSanitizerDir() bool | 
 | 	hostToolPath() android.OptionalPath | 
 | 	relativeInstallPath() string | 
 | 	skipInstall(mod *Module) | 
 | } | 
 |  | 
 | type xref interface { | 
 | 	XrefCcFiles() android.Paths | 
 | } | 
 |  | 
 | var ( | 
 | 	sharedExportDepTag    = DependencyTag{Name: "shared", Library: true, Shared: true, ReexportFlags: true} | 
 | 	earlySharedDepTag     = DependencyTag{Name: "early_shared", Library: true, Shared: true} | 
 | 	lateSharedDepTag      = DependencyTag{Name: "late shared", Library: true, Shared: true} | 
 | 	staticExportDepTag    = DependencyTag{Name: "static", Library: true, ReexportFlags: true} | 
 | 	lateStaticDepTag      = DependencyTag{Name: "late static", Library: true} | 
 | 	staticUnwinderDepTag  = DependencyTag{Name: "static unwinder", Library: true} | 
 | 	wholeStaticDepTag     = DependencyTag{Name: "whole static", Library: true, ReexportFlags: true} | 
 | 	headerDepTag          = DependencyTag{Name: "header", Library: true} | 
 | 	headerExportDepTag    = DependencyTag{Name: "header", Library: true, ReexportFlags: true} | 
 | 	genSourceDepTag       = DependencyTag{Name: "gen source"} | 
 | 	genHeaderDepTag       = DependencyTag{Name: "gen header"} | 
 | 	genHeaderExportDepTag = DependencyTag{Name: "gen header", ReexportFlags: true} | 
 | 	objDepTag             = DependencyTag{Name: "obj"} | 
 | 	linkerFlagsDepTag     = DependencyTag{Name: "linker flags file"} | 
 | 	dynamicLinkerDepTag   = DependencyTag{Name: "dynamic linker"} | 
 | 	reuseObjTag           = DependencyTag{Name: "reuse objects"} | 
 | 	staticVariantTag      = DependencyTag{Name: "static variant"} | 
 | 	ndkStubDepTag         = DependencyTag{Name: "ndk stub", Library: true} | 
 | 	ndkLateStubDepTag     = DependencyTag{Name: "ndk late stub", Library: true} | 
 | 	vndkExtDepTag         = DependencyTag{Name: "vndk extends", Library: true} | 
 | 	runtimeDepTag         = DependencyTag{Name: "runtime lib"} | 
 | 	coverageDepTag        = DependencyTag{Name: "coverage"} | 
 | 	testPerSrcDepTag      = DependencyTag{Name: "test_per_src"} | 
 | ) | 
 |  | 
 | func IsSharedDepTag(depTag blueprint.DependencyTag) bool { | 
 | 	ccDepTag, ok := depTag.(DependencyTag) | 
 | 	return ok && ccDepTag.Shared | 
 | } | 
 |  | 
 | func IsRuntimeDepTag(depTag blueprint.DependencyTag) bool { | 
 | 	ccDepTag, ok := depTag.(DependencyTag) | 
 | 	return ok && ccDepTag == runtimeDepTag | 
 | } | 
 |  | 
 | func IsTestPerSrcDepTag(depTag blueprint.DependencyTag) bool { | 
 | 	ccDepTag, ok := depTag.(DependencyTag) | 
 | 	return ok && ccDepTag == testPerSrcDepTag | 
 | } | 
 |  | 
 | // Module contains the properties and members used by all C/C++ module types, and implements | 
 | // the blueprint.Module interface.  It delegates to compiler, linker, and installer interfaces | 
 | // to construct the output file.  Behavior can be customized with a Customizer interface | 
 | type Module struct { | 
 | 	android.ModuleBase | 
 | 	android.DefaultableModuleBase | 
 | 	android.ApexModuleBase | 
 | 	android.SdkBase | 
 |  | 
 | 	Properties       BaseProperties | 
 | 	VendorProperties VendorProperties | 
 |  | 
 | 	// initialize before calling Init | 
 | 	hod      android.HostOrDeviceSupported | 
 | 	multilib android.Multilib | 
 |  | 
 | 	// Allowable SdkMemberTypes of this module type. | 
 | 	sdkMemberTypes []android.SdkMemberType | 
 |  | 
 | 	// delegates, initialize before calling Init | 
 | 	features  []feature | 
 | 	compiler  compiler | 
 | 	linker    linker | 
 | 	installer installer | 
 | 	stl       *stl | 
 | 	sanitize  *sanitize | 
 | 	coverage  *coverage | 
 | 	sabi      *sabi | 
 | 	vndkdep   *vndkdep | 
 | 	lto       *lto | 
 | 	pgo       *pgo | 
 |  | 
 | 	outputFile android.OptionalPath | 
 |  | 
 | 	cachedToolchain config.Toolchain | 
 |  | 
 | 	subAndroidMkOnce map[subAndroidMkProvider]bool | 
 |  | 
 | 	// Flags used to compile this module | 
 | 	flags Flags | 
 |  | 
 | 	// When calling a linker, if module A depends on module B, then A must precede B in its command | 
 | 	// line invocation. depsInLinkOrder stores the proper ordering of all of the transitive | 
 | 	// deps of this module | 
 | 	depsInLinkOrder android.Paths | 
 |  | 
 | 	// only non-nil when this is a shared library that reuses the objects of a static library | 
 | 	staticVariant LinkableInterface | 
 |  | 
 | 	makeLinkType string | 
 | 	// Kythe (source file indexer) paths for this compilation module | 
 | 	kytheFiles android.Paths | 
 |  | 
 | 	// For apex variants, this is set as apex.min_sdk_version | 
 | 	apexSdkVersion int | 
 | } | 
 |  | 
 | func (c *Module) Toc() android.OptionalPath { | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(libraryInterface); ok { | 
 | 			return library.toc() | 
 | 		} | 
 | 	} | 
 | 	panic(fmt.Errorf("Toc() called on non-library module: %q", c.BaseModuleName())) | 
 | } | 
 |  | 
 | func (c *Module) ApiLevel() string { | 
 | 	if c.linker != nil { | 
 | 		if stub, ok := c.linker.(*stubDecorator); ok { | 
 | 			return stub.properties.ApiLevel | 
 | 		} | 
 | 	} | 
 | 	panic(fmt.Errorf("ApiLevel() called on non-stub library module: %q", c.BaseModuleName())) | 
 | } | 
 |  | 
 | func (c *Module) Static() bool { | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(libraryInterface); ok { | 
 | 			return library.static() | 
 | 		} | 
 | 	} | 
 | 	panic(fmt.Errorf("Static() called on non-library module: %q", c.BaseModuleName())) | 
 | } | 
 |  | 
 | func (c *Module) Shared() bool { | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(libraryInterface); ok { | 
 | 			return library.shared() | 
 | 		} | 
 | 	} | 
 | 	panic(fmt.Errorf("Shared() called on non-library module: %q", c.BaseModuleName())) | 
 | } | 
 |  | 
 | func (c *Module) SelectedStl() string { | 
 | 	if c.stl != nil { | 
 | 		return c.stl.Properties.SelectedStl | 
 | 	} | 
 | 	return "" | 
 | } | 
 |  | 
 | func (c *Module) ToolchainLibrary() bool { | 
 | 	if _, ok := c.linker.(*toolchainLibraryDecorator); ok { | 
 | 		return true | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) NdkPrebuiltStl() bool { | 
 | 	if _, ok := c.linker.(*ndkPrebuiltStlLinker); ok { | 
 | 		return true | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) StubDecorator() bool { | 
 | 	if _, ok := c.linker.(*stubDecorator); ok { | 
 | 		return true | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) SdkVersion() string { | 
 | 	return String(c.Properties.Sdk_version) | 
 | } | 
 |  | 
 | func (c *Module) MinSdkVersion() string { | 
 | 	return String(c.Properties.Min_sdk_version) | 
 | } | 
 |  | 
 | func (c *Module) AlwaysSdk() bool { | 
 | 	return c.Properties.AlwaysSdk || Bool(c.Properties.Sdk_variant_only) | 
 | } | 
 |  | 
 | func (c *Module) IncludeDirs() android.Paths { | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(exportedFlagsProducer); ok { | 
 | 			return library.exportedDirs() | 
 | 		} | 
 | 	} | 
 | 	panic(fmt.Errorf("IncludeDirs called on non-exportedFlagsProducer module: %q", c.BaseModuleName())) | 
 | } | 
 |  | 
 | func (c *Module) HasStaticVariant() bool { | 
 | 	if c.staticVariant != nil { | 
 | 		return true | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) GetStaticVariant() LinkableInterface { | 
 | 	return c.staticVariant | 
 | } | 
 |  | 
 | func (c *Module) SetDepsInLinkOrder(depsInLinkOrder []android.Path) { | 
 | 	c.depsInLinkOrder = depsInLinkOrder | 
 | } | 
 |  | 
 | func (c *Module) GetDepsInLinkOrder() []android.Path { | 
 | 	return c.depsInLinkOrder | 
 | } | 
 |  | 
 | func (c *Module) StubsVersions() []string { | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(*libraryDecorator); ok { | 
 | 			return library.Properties.Stubs.Versions | 
 | 		} | 
 | 	} | 
 | 	panic(fmt.Errorf("StubsVersions called on non-library module: %q", c.BaseModuleName())) | 
 | } | 
 |  | 
 | func (c *Module) CcLibrary() bool { | 
 | 	if c.linker != nil { | 
 | 		if _, ok := c.linker.(*libraryDecorator); ok { | 
 | 			return true | 
 | 		} | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) CcLibraryInterface() bool { | 
 | 	if _, ok := c.linker.(libraryInterface); ok { | 
 | 		return true | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) NonCcVariants() bool { | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) SetBuildStubs() { | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(*libraryDecorator); ok { | 
 | 			library.MutatedProperties.BuildStubs = true | 
 | 			c.Properties.HideFromMake = true | 
 | 			c.sanitize = nil | 
 | 			c.stl = nil | 
 | 			c.Properties.PreventInstall = true | 
 | 			return | 
 | 		} | 
 | 		if _, ok := c.linker.(*llndkStubDecorator); ok { | 
 | 			c.Properties.HideFromMake = true | 
 | 			return | 
 | 		} | 
 | 	} | 
 | 	panic(fmt.Errorf("SetBuildStubs called on non-library module: %q", c.BaseModuleName())) | 
 | } | 
 |  | 
 | func (c *Module) BuildStubs() bool { | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(*libraryDecorator); ok { | 
 | 			return library.buildStubs() | 
 | 		} | 
 | 	} | 
 | 	panic(fmt.Errorf("BuildStubs called on non-library module: %q", c.BaseModuleName())) | 
 | } | 
 |  | 
 | func (c *Module) SetStubsVersions(version string) { | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(*libraryDecorator); ok { | 
 | 			library.MutatedProperties.StubsVersion = version | 
 | 			return | 
 | 		} | 
 | 		if llndk, ok := c.linker.(*llndkStubDecorator); ok { | 
 | 			llndk.libraryDecorator.MutatedProperties.StubsVersion = version | 
 | 			return | 
 | 		} | 
 | 	} | 
 | 	panic(fmt.Errorf("SetStubsVersions called on non-library module: %q", c.BaseModuleName())) | 
 | } | 
 |  | 
 | func (c *Module) StubsVersion() string { | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(*libraryDecorator); ok { | 
 | 			return library.MutatedProperties.StubsVersion | 
 | 		} | 
 | 		if llndk, ok := c.linker.(*llndkStubDecorator); ok { | 
 | 			return llndk.libraryDecorator.MutatedProperties.StubsVersion | 
 | 		} | 
 | 	} | 
 | 	panic(fmt.Errorf("StubsVersion called on non-library module: %q", c.BaseModuleName())) | 
 | } | 
 |  | 
 | func (c *Module) SetStatic() { | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(libraryInterface); ok { | 
 | 			library.setStatic() | 
 | 			return | 
 | 		} | 
 | 	} | 
 | 	panic(fmt.Errorf("SetStatic called on non-library module: %q", c.BaseModuleName())) | 
 | } | 
 |  | 
 | func (c *Module) SetShared() { | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(libraryInterface); ok { | 
 | 			library.setShared() | 
 | 			return | 
 | 		} | 
 | 	} | 
 | 	panic(fmt.Errorf("SetShared called on non-library module: %q", c.BaseModuleName())) | 
 | } | 
 |  | 
 | func (c *Module) BuildStaticVariant() bool { | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(libraryInterface); ok { | 
 | 			return library.buildStatic() | 
 | 		} | 
 | 	} | 
 | 	panic(fmt.Errorf("BuildStaticVariant called on non-library module: %q", c.BaseModuleName())) | 
 | } | 
 |  | 
 | func (c *Module) BuildSharedVariant() bool { | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(libraryInterface); ok { | 
 | 			return library.buildShared() | 
 | 		} | 
 | 	} | 
 | 	panic(fmt.Errorf("BuildSharedVariant called on non-library module: %q", c.BaseModuleName())) | 
 | } | 
 |  | 
 | func (c *Module) Module() android.Module { | 
 | 	return c | 
 | } | 
 |  | 
 | func (c *Module) OutputFile() android.OptionalPath { | 
 | 	return c.outputFile | 
 | } | 
 |  | 
 | var _ LinkableInterface = (*Module)(nil) | 
 |  | 
 | func (c *Module) UnstrippedOutputFile() android.Path { | 
 | 	if c.linker != nil { | 
 | 		return c.linker.unstrippedOutputFilePath() | 
 | 	} | 
 | 	return nil | 
 | } | 
 |  | 
 | func (c *Module) CoverageOutputFile() android.OptionalPath { | 
 | 	if c.linker != nil { | 
 | 		return c.linker.coverageOutputFilePath() | 
 | 	} | 
 | 	return android.OptionalPath{} | 
 | } | 
 |  | 
 | func (c *Module) RelativeInstallPath() string { | 
 | 	if c.installer != nil { | 
 | 		return c.installer.relativeInstallPath() | 
 | 	} | 
 | 	return "" | 
 | } | 
 |  | 
 | func (c *Module) VndkVersion() string { | 
 | 	return c.Properties.VndkVersion | 
 | } | 
 |  | 
 | func (c *Module) Init() android.Module { | 
 | 	c.AddProperties(&c.Properties, &c.VendorProperties) | 
 | 	if c.compiler != nil { | 
 | 		c.AddProperties(c.compiler.compilerProps()...) | 
 | 	} | 
 | 	if c.linker != nil { | 
 | 		c.AddProperties(c.linker.linkerProps()...) | 
 | 	} | 
 | 	if c.installer != nil { | 
 | 		c.AddProperties(c.installer.installerProps()...) | 
 | 	} | 
 | 	if c.stl != nil { | 
 | 		c.AddProperties(c.stl.props()...) | 
 | 	} | 
 | 	if c.sanitize != nil { | 
 | 		c.AddProperties(c.sanitize.props()...) | 
 | 	} | 
 | 	if c.coverage != nil { | 
 | 		c.AddProperties(c.coverage.props()...) | 
 | 	} | 
 | 	if c.sabi != nil { | 
 | 		c.AddProperties(c.sabi.props()...) | 
 | 	} | 
 | 	if c.vndkdep != nil { | 
 | 		c.AddProperties(c.vndkdep.props()...) | 
 | 	} | 
 | 	if c.lto != nil { | 
 | 		c.AddProperties(c.lto.props()...) | 
 | 	} | 
 | 	if c.pgo != nil { | 
 | 		c.AddProperties(c.pgo.props()...) | 
 | 	} | 
 | 	for _, feature := range c.features { | 
 | 		c.AddProperties(feature.props()...) | 
 | 	} | 
 |  | 
 | 	c.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool { | 
 | 		switch class { | 
 | 		case android.Device: | 
 | 			return ctx.Config().DevicePrefer32BitExecutables() | 
 | 		case android.HostCross: | 
 | 			// Windows builds always prefer 32-bit | 
 | 			return true | 
 | 		default: | 
 | 			return false | 
 | 		} | 
 | 	}) | 
 | 	android.InitAndroidArchModule(c, c.hod, c.multilib) | 
 | 	android.InitApexModule(c) | 
 | 	android.InitSdkAwareModule(c) | 
 | 	android.InitDefaultableModule(c) | 
 |  | 
 | 	return c | 
 | } | 
 |  | 
 | // Returns true for dependency roots (binaries) | 
 | // TODO(ccross): also handle dlopenable libraries | 
 | func (c *Module) isDependencyRoot() bool { | 
 | 	if root, ok := c.linker.(interface { | 
 | 		isDependencyRoot() bool | 
 | 	}); ok { | 
 | 		return root.isDependencyRoot() | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | // Returns true if the module is using VNDK libraries instead of the libraries in /system/lib or /system/lib64. | 
 | // "product" and "vendor" variant modules return true for this function. | 
 | // When BOARD_VNDK_VERSION is set, vendor variants of "vendor_available: true", "vendor: true", | 
 | // "soc_specific: true" and more vendor installed modules are included here. | 
 | // When PRODUCT_PRODUCT_VNDK_VERSION is set, product variants of "vendor_available: true" or | 
 | // "product_specific: true" modules are included here. | 
 | func (c *Module) UseVndk() bool { | 
 | 	return c.Properties.VndkVersion != "" | 
 | } | 
 |  | 
 | func (c *Module) canUseSdk() bool { | 
 | 	return c.Os() == android.Android && !c.UseVndk() && !c.InRamdisk() && !c.InRecovery() | 
 | } | 
 |  | 
 | func (c *Module) UseSdk() bool { | 
 | 	if c.canUseSdk() { | 
 | 		return String(c.Properties.Sdk_version) != "" | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) isCoverageVariant() bool { | 
 | 	return c.coverage.Properties.IsCoverageVariant | 
 | } | 
 |  | 
 | func (c *Module) IsNdk() bool { | 
 | 	return inList(c.Name(), ndkMigratedLibs) | 
 | } | 
 |  | 
 | func (c *Module) isLlndk(config android.Config) bool { | 
 | 	// Returns true for both LLNDK (public) and LLNDK-private libs. | 
 | 	return isLlndkLibrary(c.BaseModuleName(), config) | 
 | } | 
 |  | 
 | func (c *Module) isLlndkPublic(config android.Config) bool { | 
 | 	// Returns true only for LLNDK (public) libs. | 
 | 	name := c.BaseModuleName() | 
 | 	return isLlndkLibrary(name, config) && !isVndkPrivateLibrary(name, config) | 
 | } | 
 |  | 
 | func (c *Module) isVndkPrivate(config android.Config) bool { | 
 | 	// Returns true for LLNDK-private, VNDK-SP-private, and VNDK-core-private. | 
 | 	return isVndkPrivateLibrary(c.BaseModuleName(), config) | 
 | } | 
 |  | 
 | func (c *Module) IsVndk() bool { | 
 | 	if vndkdep := c.vndkdep; vndkdep != nil { | 
 | 		return vndkdep.isVndk() | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) isPgoCompile() bool { | 
 | 	if pgo := c.pgo; pgo != nil { | 
 | 		return pgo.Properties.PgoCompile | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) isNDKStubLibrary() bool { | 
 | 	if _, ok := c.compiler.(*stubDecorator); ok { | 
 | 		return true | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) isVndkSp() bool { | 
 | 	if vndkdep := c.vndkdep; vndkdep != nil { | 
 | 		return vndkdep.isVndkSp() | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) isVndkExt() bool { | 
 | 	if vndkdep := c.vndkdep; vndkdep != nil { | 
 | 		return vndkdep.isVndkExt() | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) MustUseVendorVariant() bool { | 
 | 	return c.isVndkSp() || c.Properties.MustUseVendorVariant | 
 | } | 
 |  | 
 | func (c *Module) getVndkExtendsModuleName() string { | 
 | 	if vndkdep := c.vndkdep; vndkdep != nil { | 
 | 		return vndkdep.getVndkExtendsModuleName() | 
 | 	} | 
 | 	return "" | 
 | } | 
 |  | 
 | // Returns true only when this module is configured to have core, product and vendor | 
 | // variants. | 
 | func (c *Module) HasVendorVariant() bool { | 
 | 	return c.IsVndk() || Bool(c.VendorProperties.Vendor_available) | 
 | } | 
 |  | 
 | const ( | 
 | 	// VendorVariationPrefix is the variant prefix used for /vendor code that compiles | 
 | 	// against the VNDK. | 
 | 	VendorVariationPrefix = "vendor." | 
 |  | 
 | 	// ProductVariationPrefix is the variant prefix used for /product code that compiles | 
 | 	// against the VNDK. | 
 | 	ProductVariationPrefix = "product." | 
 | ) | 
 |  | 
 | // Returns true if the module is "product" variant. Usually these modules are installed in /product | 
 | func (c *Module) inProduct() bool { | 
 | 	return c.Properties.ImageVariationPrefix == ProductVariationPrefix | 
 | } | 
 |  | 
 | // Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor | 
 | func (c *Module) inVendor() bool { | 
 | 	return c.Properties.ImageVariationPrefix == VendorVariationPrefix | 
 | } | 
 |  | 
 | func (c *Module) InRamdisk() bool { | 
 | 	return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk() | 
 | } | 
 |  | 
 | func (c *Module) InRecovery() bool { | 
 | 	return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery() | 
 | } | 
 |  | 
 | func (c *Module) OnlyInRamdisk() bool { | 
 | 	return c.ModuleBase.InstallInRamdisk() | 
 | } | 
 |  | 
 | func (c *Module) OnlyInRecovery() bool { | 
 | 	return c.ModuleBase.InstallInRecovery() | 
 | } | 
 |  | 
 | func (c *Module) IsStubs() bool { | 
 | 	if library, ok := c.linker.(*libraryDecorator); ok { | 
 | 		return library.buildStubs() | 
 | 	} else if _, ok := c.linker.(*llndkStubDecorator); ok { | 
 | 		return true | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) HasStubsVariants() bool { | 
 | 	if library, ok := c.linker.(*libraryDecorator); ok { | 
 | 		return len(library.Properties.Stubs.Versions) > 0 | 
 | 	} | 
 | 	if library, ok := c.linker.(*prebuiltLibraryLinker); ok { | 
 | 		return len(library.Properties.Stubs.Versions) > 0 | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) bootstrap() bool { | 
 | 	return Bool(c.Properties.Bootstrap) | 
 | } | 
 |  | 
 | func (c *Module) nativeCoverage() bool { | 
 | 	// Bug: http://b/137883967 - native-bridge modules do not currently work with coverage | 
 | 	if c.Target().NativeBridge == android.NativeBridgeEnabled { | 
 | 		return false | 
 | 	} | 
 | 	return c.linker != nil && c.linker.nativeCoverage() | 
 | } | 
 |  | 
 | func (c *Module) isSnapshotPrebuilt() bool { | 
 | 	if _, ok := c.linker.(*vndkPrebuiltLibraryDecorator); ok { | 
 | 		return true | 
 | 	} | 
 | 	if _, ok := c.linker.(*vendorSnapshotLibraryDecorator); ok { | 
 | 		return true | 
 | 	} | 
 | 	if _, ok := c.linker.(*vendorSnapshotBinaryDecorator); ok { | 
 | 		return true | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) ExportedIncludeDirs() android.Paths { | 
 | 	if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok { | 
 | 		return flagsProducer.exportedDirs() | 
 | 	} | 
 | 	return nil | 
 | } | 
 |  | 
 | func (c *Module) ExportedSystemIncludeDirs() android.Paths { | 
 | 	if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok { | 
 | 		return flagsProducer.exportedSystemDirs() | 
 | 	} | 
 | 	return nil | 
 | } | 
 |  | 
 | func (c *Module) ExportedFlags() []string { | 
 | 	if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok { | 
 | 		return flagsProducer.exportedFlags() | 
 | 	} | 
 | 	return nil | 
 | } | 
 |  | 
 | func (c *Module) ExportedDeps() android.Paths { | 
 | 	if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok { | 
 | 		return flagsProducer.exportedDeps() | 
 | 	} | 
 | 	return nil | 
 | } | 
 |  | 
 | func (c *Module) ExportedGeneratedHeaders() android.Paths { | 
 | 	if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok { | 
 | 		return flagsProducer.exportedGeneratedHeaders() | 
 | 	} | 
 | 	return nil | 
 | } | 
 |  | 
 | func isBionic(name string) bool { | 
 | 	switch name { | 
 | 	case "libc", "libm", "libdl", "libdl_android", "linker": | 
 | 		return true | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func InstallToBootstrap(name string, config android.Config) bool { | 
 | 	if name == "libclang_rt.hwasan-aarch64-android" { | 
 | 		return inList("hwaddress", config.SanitizeDevice()) | 
 | 	} | 
 | 	return isBionic(name) | 
 | } | 
 |  | 
 | func (c *Module) XrefCcFiles() android.Paths { | 
 | 	return c.kytheFiles | 
 | } | 
 |  | 
 | type baseModuleContext struct { | 
 | 	android.BaseModuleContext | 
 | 	moduleContextImpl | 
 | } | 
 |  | 
 | type depsContext struct { | 
 | 	android.BottomUpMutatorContext | 
 | 	moduleContextImpl | 
 | } | 
 |  | 
 | type moduleContext struct { | 
 | 	android.ModuleContext | 
 | 	moduleContextImpl | 
 | } | 
 |  | 
 | func (ctx *moduleContext) ProductSpecific() bool { | 
 | 	return ctx.ModuleContext.ProductSpecific() || | 
 | 		(ctx.mod.HasVendorVariant() && ctx.mod.inProduct() && !ctx.mod.IsVndk()) | 
 | } | 
 |  | 
 | func (ctx *moduleContext) SocSpecific() bool { | 
 | 	return ctx.ModuleContext.SocSpecific() || | 
 | 		(ctx.mod.HasVendorVariant() && ctx.mod.inVendor() && !ctx.mod.IsVndk()) | 
 | } | 
 |  | 
 | type moduleContextImpl struct { | 
 | 	mod *Module | 
 | 	ctx BaseModuleContext | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) toolchain() config.Toolchain { | 
 | 	return ctx.mod.toolchain(ctx.ctx) | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) static() bool { | 
 | 	return ctx.mod.static() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) staticBinary() bool { | 
 | 	return ctx.mod.staticBinary() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) header() bool { | 
 | 	return ctx.mod.header() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) canUseSdk() bool { | 
 | 	return ctx.mod.canUseSdk() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) useSdk() bool { | 
 | 	return ctx.mod.UseSdk() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) sdkVersion() string { | 
 | 	if ctx.ctx.Device() { | 
 | 		if ctx.useVndk() { | 
 | 			vndkVer := ctx.mod.VndkVersion() | 
 | 			if inList(vndkVer, ctx.ctx.Config().PlatformVersionActiveCodenames()) { | 
 | 				return "current" | 
 | 			} | 
 | 			return vndkVer | 
 | 		} | 
 | 		return String(ctx.mod.Properties.Sdk_version) | 
 | 	} | 
 | 	return "" | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) useVndk() bool { | 
 | 	return ctx.mod.UseVndk() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) isNdk() bool { | 
 | 	return ctx.mod.IsNdk() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) isLlndk(config android.Config) bool { | 
 | 	return ctx.mod.isLlndk(config) | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) isLlndkPublic(config android.Config) bool { | 
 | 	return ctx.mod.isLlndkPublic(config) | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) isVndkPrivate(config android.Config) bool { | 
 | 	return ctx.mod.isVndkPrivate(config) | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) isVndk() bool { | 
 | 	return ctx.mod.IsVndk() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) isPgoCompile() bool { | 
 | 	return ctx.mod.isPgoCompile() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) isNDKStubLibrary() bool { | 
 | 	return ctx.mod.isNDKStubLibrary() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) isVndkSp() bool { | 
 | 	return ctx.mod.isVndkSp() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) isVndkExt() bool { | 
 | 	return ctx.mod.isVndkExt() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) mustUseVendorVariant() bool { | 
 | 	return ctx.mod.MustUseVendorVariant() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) inProduct() bool { | 
 | 	return ctx.mod.inProduct() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) inVendor() bool { | 
 | 	return ctx.mod.inVendor() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) inRamdisk() bool { | 
 | 	return ctx.mod.InRamdisk() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) inRecovery() bool { | 
 | 	return ctx.mod.InRecovery() | 
 | } | 
 |  | 
 | // Check whether ABI dumps should be created for this module. | 
 | func (ctx *moduleContextImpl) shouldCreateSourceAbiDump() bool { | 
 | 	if ctx.ctx.Config().IsEnvTrue("SKIP_ABI_CHECKS") { | 
 | 		return false | 
 | 	} | 
 |  | 
 | 	// Coverage builds have extra symbols. | 
 | 	if ctx.mod.isCoverageVariant() { | 
 | 		return false | 
 | 	} | 
 |  | 
 | 	if ctx.ctx.Fuchsia() { | 
 | 		return false | 
 | 	} | 
 |  | 
 | 	if sanitize := ctx.mod.sanitize; sanitize != nil { | 
 | 		if !sanitize.isVariantOnProductionDevice() { | 
 | 			return false | 
 | 		} | 
 | 	} | 
 | 	if !ctx.ctx.Device() { | 
 | 		// Host modules do not need ABI dumps. | 
 | 		return false | 
 | 	} | 
 | 	if ctx.isStubs() || ctx.isNDKStubLibrary() { | 
 | 		// Stubs do not need ABI dumps. | 
 | 		return false | 
 | 	} | 
 | 	return true | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) selectedStl() string { | 
 | 	if stl := ctx.mod.stl; stl != nil { | 
 | 		return stl.Properties.SelectedStl | 
 | 	} | 
 | 	return "" | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) useClangLld(actx ModuleContext) bool { | 
 | 	return ctx.mod.linker.useClangLld(actx) | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) baseModuleName() string { | 
 | 	return ctx.mod.ModuleBase.BaseModuleName() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) getVndkExtendsModuleName() string { | 
 | 	return ctx.mod.getVndkExtendsModuleName() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) isForPlatform() bool { | 
 | 	return ctx.mod.IsForPlatform() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) apexName() string { | 
 | 	return ctx.mod.ApexName() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) apexSdkVersion() int { | 
 | 	return ctx.mod.apexSdkVersion | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) hasStubsVariants() bool { | 
 | 	return ctx.mod.HasStubsVariants() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) isStubs() bool { | 
 | 	return ctx.mod.IsStubs() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) bootstrap() bool { | 
 | 	return ctx.mod.bootstrap() | 
 | } | 
 |  | 
 | func (ctx *moduleContextImpl) nativeCoverage() bool { | 
 | 	return ctx.mod.nativeCoverage() | 
 | } | 
 |  | 
 | func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { | 
 | 	return &Module{ | 
 | 		hod:      hod, | 
 | 		multilib: multilib, | 
 | 	} | 
 | } | 
 |  | 
 | func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { | 
 | 	module := newBaseModule(hod, multilib) | 
 | 	module.features = []feature{ | 
 | 		&tidyFeature{}, | 
 | 	} | 
 | 	module.stl = &stl{} | 
 | 	module.sanitize = &sanitize{} | 
 | 	module.coverage = &coverage{} | 
 | 	module.sabi = &sabi{} | 
 | 	module.vndkdep = &vndkdep{} | 
 | 	module.lto = <o{} | 
 | 	module.pgo = &pgo{} | 
 | 	return module | 
 | } | 
 |  | 
 | func (c *Module) Prebuilt() *android.Prebuilt { | 
 | 	if p, ok := c.linker.(prebuiltLinkerInterface); ok { | 
 | 		return p.prebuilt() | 
 | 	} | 
 | 	return nil | 
 | } | 
 |  | 
 | func (c *Module) Name() string { | 
 | 	name := c.ModuleBase.Name() | 
 | 	if p, ok := c.linker.(interface { | 
 | 		Name(string) string | 
 | 	}); ok { | 
 | 		name = p.Name(name) | 
 | 	} | 
 | 	return name | 
 | } | 
 |  | 
 | func (c *Module) Symlinks() []string { | 
 | 	if p, ok := c.installer.(interface { | 
 | 		symlinkList() []string | 
 | 	}); ok { | 
 | 		return p.symlinkList() | 
 | 	} | 
 | 	return nil | 
 | } | 
 |  | 
 | // orderDeps reorders dependencies into a list such that if module A depends on B, then | 
 | // A will precede B in the resultant list. | 
 | // This is convenient for passing into a linker. | 
 | // Note that directSharedDeps should be the analogous static library for each shared lib dep | 
 | func orderDeps(directStaticDeps []android.Path, directSharedDeps []android.Path, allTransitiveDeps map[android.Path][]android.Path) (orderedAllDeps []android.Path, orderedDeclaredDeps []android.Path) { | 
 | 	// If A depends on B, then | 
 | 	//   Every list containing A will also contain B later in the list | 
 | 	//   So, after concatenating all lists, the final instance of B will have come from the same | 
 | 	//     original list as the final instance of A | 
 | 	//   So, the final instance of B will be later in the concatenation than the final A | 
 | 	//   So, keeping only the final instance of A and of B ensures that A is earlier in the output | 
 | 	//     list than B | 
 | 	for _, dep := range directStaticDeps { | 
 | 		orderedAllDeps = append(orderedAllDeps, dep) | 
 | 		orderedAllDeps = append(orderedAllDeps, allTransitiveDeps[dep]...) | 
 | 	} | 
 | 	for _, dep := range directSharedDeps { | 
 | 		orderedAllDeps = append(orderedAllDeps, dep) | 
 | 		orderedAllDeps = append(orderedAllDeps, allTransitiveDeps[dep]...) | 
 | 	} | 
 |  | 
 | 	orderedAllDeps = android.LastUniquePaths(orderedAllDeps) | 
 |  | 
 | 	// We don't want to add any new dependencies into directStaticDeps (to allow the caller to | 
 | 	// intentionally exclude or replace any unwanted transitive dependencies), so we limit the | 
 | 	// resultant list to only what the caller has chosen to include in directStaticDeps | 
 | 	_, orderedDeclaredDeps = android.FilterPathList(orderedAllDeps, directStaticDeps) | 
 |  | 
 | 	return orderedAllDeps, orderedDeclaredDeps | 
 | } | 
 |  | 
 | func orderStaticModuleDeps(module LinkableInterface, staticDeps []LinkableInterface, sharedDeps []LinkableInterface) (results []android.Path) { | 
 | 	// convert Module to Path | 
 | 	var depsInLinkOrder []android.Path | 
 | 	allTransitiveDeps := make(map[android.Path][]android.Path, len(staticDeps)) | 
 | 	staticDepFiles := []android.Path{} | 
 | 	for _, dep := range staticDeps { | 
 | 		// The OutputFile may not be valid for a variant not present, and the AllowMissingDependencies flag is set. | 
 | 		if dep.OutputFile().Valid() { | 
 | 			allTransitiveDeps[dep.OutputFile().Path()] = dep.GetDepsInLinkOrder() | 
 | 			staticDepFiles = append(staticDepFiles, dep.OutputFile().Path()) | 
 | 		} | 
 | 	} | 
 | 	sharedDepFiles := []android.Path{} | 
 | 	for _, sharedDep := range sharedDeps { | 
 | 		if sharedDep.HasStaticVariant() { | 
 | 			staticAnalogue := sharedDep.GetStaticVariant() | 
 | 			allTransitiveDeps[staticAnalogue.OutputFile().Path()] = staticAnalogue.GetDepsInLinkOrder() | 
 | 			sharedDepFiles = append(sharedDepFiles, staticAnalogue.OutputFile().Path()) | 
 | 		} | 
 | 	} | 
 |  | 
 | 	// reorder the dependencies based on transitive dependencies | 
 | 	depsInLinkOrder, results = orderDeps(staticDepFiles, sharedDepFiles, allTransitiveDeps) | 
 | 	module.SetDepsInLinkOrder(depsInLinkOrder) | 
 |  | 
 | 	return results | 
 | } | 
 |  | 
 | func (c *Module) IsTestPerSrcAllTestsVariation() bool { | 
 | 	test, ok := c.linker.(testPerSrc) | 
 | 	return ok && test.isAllTestsVariation() | 
 | } | 
 |  | 
 | func (c *Module) getNameSuffixWithVndkVersion(ctx android.ModuleContext) string { | 
 | 	// Returns the name suffix for product and vendor variants. If the VNDK version is not | 
 | 	// "current", it will append the VNDK version to the name suffix. | 
 | 	var vndkVersion string | 
 | 	var nameSuffix string | 
 | 	if c.inProduct() { | 
 | 		vndkVersion = ctx.DeviceConfig().ProductVndkVersion() | 
 | 		nameSuffix = productSuffix | 
 | 	} else { | 
 | 		vndkVersion = ctx.DeviceConfig().VndkVersion() | 
 | 		nameSuffix = vendorSuffix | 
 | 	} | 
 | 	if vndkVersion == "current" { | 
 | 		vndkVersion = ctx.DeviceConfig().PlatformVndkVersion() | 
 | 	} | 
 | 	if c.Properties.VndkVersion != vndkVersion { | 
 | 		// add version suffix only if the module is using different vndk version than the | 
 | 		// version in product or vendor partition. | 
 | 		nameSuffix += "." + c.Properties.VndkVersion | 
 | 	} | 
 | 	return nameSuffix | 
 | } | 
 |  | 
 | func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { | 
 | 	// Handle the case of a test module split by `test_per_src` mutator. | 
 | 	// | 
 | 	// The `test_per_src` mutator adds an extra variation named "", depending on all the other | 
 | 	// `test_per_src` variations of the test module. Set `outputFile` to an empty path for this | 
 | 	// module and return early, as this module does not produce an output file per se. | 
 | 	if c.IsTestPerSrcAllTestsVariation() { | 
 | 		c.outputFile = android.OptionalPath{} | 
 | 		return | 
 | 	} | 
 |  | 
 | 	c.makeLinkType = c.getMakeLinkType(actx) | 
 |  | 
 | 	c.Properties.SubName = "" | 
 |  | 
 | 	if c.Target().NativeBridge == android.NativeBridgeEnabled { | 
 | 		c.Properties.SubName += nativeBridgeSuffix | 
 | 	} | 
 |  | 
 | 	_, llndk := c.linker.(*llndkStubDecorator) | 
 | 	_, llndkHeader := c.linker.(*llndkHeadersDecorator) | 
 | 	if llndk || llndkHeader || (c.UseVndk() && c.HasVendorVariant()) { | 
 | 		// .vendor.{version} suffix is added for vendor variant or .product.{version} suffix is | 
 | 		// added for product variant only when we have vendor and product variants with core | 
 | 		// variant. The suffix is not added for vendor-only or product-only module. | 
 | 		c.Properties.SubName += c.getNameSuffixWithVndkVersion(actx) | 
 | 	} else if _, ok := c.linker.(*vndkPrebuiltLibraryDecorator); ok { | 
 | 		// .vendor suffix is added for backward compatibility with VNDK snapshot whose names with | 
 | 		// such suffixes are already hard-coded in prebuilts/vndk/.../Android.bp. | 
 | 		c.Properties.SubName += vendorSuffix | 
 | 	} else if c.InRamdisk() && !c.OnlyInRamdisk() { | 
 | 		c.Properties.SubName += ramdiskSuffix | 
 | 	} else if c.InRecovery() && !c.OnlyInRecovery() { | 
 | 		c.Properties.SubName += recoverySuffix | 
 | 	} else if c.Properties.IsSdkVariant && c.Properties.SdkAndPlatformVariantVisibleToMake { | 
 | 		c.Properties.SubName += sdkSuffix | 
 | 	} | 
 |  | 
 | 	ctx := &moduleContext{ | 
 | 		ModuleContext: actx, | 
 | 		moduleContextImpl: moduleContextImpl{ | 
 | 			mod: c, | 
 | 		}, | 
 | 	} | 
 | 	ctx.ctx = ctx | 
 |  | 
 | 	deps := c.depsToPaths(ctx) | 
 | 	if ctx.Failed() { | 
 | 		return | 
 | 	} | 
 |  | 
 | 	if c.Properties.Clang != nil && *c.Properties.Clang == false { | 
 | 		ctx.PropertyErrorf("clang", "false (GCC) is no longer supported") | 
 | 	} | 
 |  | 
 | 	flags := Flags{ | 
 | 		Toolchain: c.toolchain(ctx), | 
 | 		EmitXrefs: ctx.Config().EmitXrefRules(), | 
 | 	} | 
 | 	if c.compiler != nil { | 
 | 		flags = c.compiler.compilerFlags(ctx, flags, deps) | 
 | 	} | 
 | 	if c.linker != nil { | 
 | 		flags = c.linker.linkerFlags(ctx, flags) | 
 | 	} | 
 | 	if c.stl != nil { | 
 | 		flags = c.stl.flags(ctx, flags) | 
 | 	} | 
 | 	if c.sanitize != nil { | 
 | 		flags = c.sanitize.flags(ctx, flags) | 
 | 	} | 
 | 	if c.coverage != nil { | 
 | 		flags, deps = c.coverage.flags(ctx, flags, deps) | 
 | 	} | 
 | 	if c.lto != nil { | 
 | 		flags = c.lto.flags(ctx, flags) | 
 | 	} | 
 | 	if c.pgo != nil { | 
 | 		flags = c.pgo.flags(ctx, flags) | 
 | 	} | 
 | 	for _, feature := range c.features { | 
 | 		flags = feature.flags(ctx, flags) | 
 | 	} | 
 | 	if ctx.Failed() { | 
 | 		return | 
 | 	} | 
 |  | 
 | 	flags.Local.CFlags, _ = filterList(flags.Local.CFlags, config.IllegalFlags) | 
 | 	flags.Local.CppFlags, _ = filterList(flags.Local.CppFlags, config.IllegalFlags) | 
 | 	flags.Local.ConlyFlags, _ = filterList(flags.Local.ConlyFlags, config.IllegalFlags) | 
 |  | 
 | 	flags.Local.CommonFlags = append(flags.Local.CommonFlags, deps.Flags...) | 
 |  | 
 | 	for _, dir := range deps.IncludeDirs { | 
 | 		flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+dir.String()) | 
 | 	} | 
 | 	for _, dir := range deps.SystemIncludeDirs { | 
 | 		flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-isystem "+dir.String()) | 
 | 	} | 
 |  | 
 | 	c.flags = flags | 
 | 	// We need access to all the flags seen by a source file. | 
 | 	if c.sabi != nil { | 
 | 		flags = c.sabi.flags(ctx, flags) | 
 | 	} | 
 |  | 
 | 	flags.AssemblerWithCpp = inList("-xassembler-with-cpp", flags.Local.AsFlags) | 
 |  | 
 | 	// Optimization to reduce size of build.ninja | 
 | 	// Replace the long list of flags for each file with a module-local variable | 
 | 	ctx.Variable(pctx, "cflags", strings.Join(flags.Local.CFlags, " ")) | 
 | 	ctx.Variable(pctx, "cppflags", strings.Join(flags.Local.CppFlags, " ")) | 
 | 	ctx.Variable(pctx, "asflags", strings.Join(flags.Local.AsFlags, " ")) | 
 | 	flags.Local.CFlags = []string{"$cflags"} | 
 | 	flags.Local.CppFlags = []string{"$cppflags"} | 
 | 	flags.Local.AsFlags = []string{"$asflags"} | 
 |  | 
 | 	var objs Objects | 
 | 	if c.compiler != nil { | 
 | 		objs = c.compiler.compile(ctx, flags, deps) | 
 | 		if ctx.Failed() { | 
 | 			return | 
 | 		} | 
 | 		c.kytheFiles = objs.kytheFiles | 
 | 	} | 
 |  | 
 | 	if c.linker != nil { | 
 | 		outputFile := c.linker.link(ctx, flags, deps, objs) | 
 | 		if ctx.Failed() { | 
 | 			return | 
 | 		} | 
 | 		c.outputFile = android.OptionalPathForPath(outputFile) | 
 |  | 
 | 		// If a lib is directly included in any of the APEXes, unhide the stubs | 
 | 		// variant having the latest version gets visible to make. In addition, | 
 | 		// the non-stubs variant is renamed to <libname>.bootstrap. This is to | 
 | 		// force anything in the make world to link against the stubs library. | 
 | 		// (unless it is explicitly referenced via .bootstrap suffix or the | 
 | 		// module is marked with 'bootstrap: true'). | 
 | 		if c.HasStubsVariants() && | 
 | 			android.DirectlyInAnyApex(ctx, ctx.baseModuleName()) && !c.InRamdisk() && | 
 | 			!c.InRecovery() && !c.UseVndk() && !c.static() && !c.isCoverageVariant() && | 
 | 			c.IsStubs() { | 
 | 			c.Properties.HideFromMake = false // unhide | 
 | 			// Note: this is still non-installable | 
 | 		} | 
 |  | 
 | 		// glob exported headers for snapshot, if BOARD_VNDK_VERSION is current. | 
 | 		if i, ok := c.linker.(snapshotLibraryInterface); ok && ctx.DeviceConfig().VndkVersion() == "current" { | 
 | 			if isSnapshotAware(ctx, c) { | 
 | 				i.collectHeadersForSnapshot(ctx) | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	if c.installable() { | 
 | 		c.installer.install(ctx, c.outputFile.Path()) | 
 | 		if ctx.Failed() { | 
 | 			return | 
 | 		} | 
 | 	} else if !proptools.BoolDefault(c.Properties.Installable, true) { | 
 | 		// If the module has been specifically configure to not be installed then | 
 | 		// skip the installation as otherwise it will break when running inside make | 
 | 		// as the output path to install will not be specified. Not all uninstallable | 
 | 		// modules can skip installation as some are needed for resolving make side | 
 | 		// dependencies. | 
 | 		c.SkipInstall() | 
 | 	} | 
 | } | 
 |  | 
 | func (c *Module) toolchain(ctx android.BaseModuleContext) config.Toolchain { | 
 | 	if c.cachedToolchain == nil { | 
 | 		c.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch()) | 
 | 	} | 
 | 	return c.cachedToolchain | 
 | } | 
 |  | 
 | func (c *Module) begin(ctx BaseModuleContext) { | 
 | 	if c.compiler != nil { | 
 | 		c.compiler.compilerInit(ctx) | 
 | 	} | 
 | 	if c.linker != nil { | 
 | 		c.linker.linkerInit(ctx) | 
 | 	} | 
 | 	if c.stl != nil { | 
 | 		c.stl.begin(ctx) | 
 | 	} | 
 | 	if c.sanitize != nil { | 
 | 		c.sanitize.begin(ctx) | 
 | 	} | 
 | 	if c.coverage != nil { | 
 | 		c.coverage.begin(ctx) | 
 | 	} | 
 | 	if c.sabi != nil { | 
 | 		c.sabi.begin(ctx) | 
 | 	} | 
 | 	if c.vndkdep != nil { | 
 | 		c.vndkdep.begin(ctx) | 
 | 	} | 
 | 	if c.lto != nil { | 
 | 		c.lto.begin(ctx) | 
 | 	} | 
 | 	if c.pgo != nil { | 
 | 		c.pgo.begin(ctx) | 
 | 	} | 
 | 	for _, feature := range c.features { | 
 | 		feature.begin(ctx) | 
 | 	} | 
 | 	if ctx.useSdk() { | 
 | 		version, err := normalizeNdkApiLevel(ctx, ctx.sdkVersion(), ctx.Arch()) | 
 | 		if err != nil { | 
 | 			ctx.PropertyErrorf("sdk_version", err.Error()) | 
 | 		} | 
 | 		c.Properties.Sdk_version = StringPtr(version) | 
 | 	} | 
 | } | 
 |  | 
 | func (c *Module) deps(ctx DepsContext) Deps { | 
 | 	deps := Deps{} | 
 |  | 
 | 	if c.compiler != nil { | 
 | 		deps = c.compiler.compilerDeps(ctx, deps) | 
 | 	} | 
 | 	// Add the PGO dependency (the clang_rt.profile runtime library), which | 
 | 	// sometimes depends on symbols from libgcc, before libgcc gets added | 
 | 	// in linkerDeps(). | 
 | 	if c.pgo != nil { | 
 | 		deps = c.pgo.deps(ctx, deps) | 
 | 	} | 
 | 	if c.linker != nil { | 
 | 		deps = c.linker.linkerDeps(ctx, deps) | 
 | 	} | 
 | 	if c.stl != nil { | 
 | 		deps = c.stl.deps(ctx, deps) | 
 | 	} | 
 | 	if c.sanitize != nil { | 
 | 		deps = c.sanitize.deps(ctx, deps) | 
 | 	} | 
 | 	if c.coverage != nil { | 
 | 		deps = c.coverage.deps(ctx, deps) | 
 | 	} | 
 | 	if c.sabi != nil { | 
 | 		deps = c.sabi.deps(ctx, deps) | 
 | 	} | 
 | 	if c.vndkdep != nil { | 
 | 		deps = c.vndkdep.deps(ctx, deps) | 
 | 	} | 
 | 	if c.lto != nil { | 
 | 		deps = c.lto.deps(ctx, deps) | 
 | 	} | 
 | 	for _, feature := range c.features { | 
 | 		deps = feature.deps(ctx, deps) | 
 | 	} | 
 |  | 
 | 	deps.WholeStaticLibs = android.LastUniqueStrings(deps.WholeStaticLibs) | 
 | 	deps.StaticLibs = android.LastUniqueStrings(deps.StaticLibs) | 
 | 	deps.LateStaticLibs = android.LastUniqueStrings(deps.LateStaticLibs) | 
 | 	deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs) | 
 | 	deps.LateSharedLibs = android.LastUniqueStrings(deps.LateSharedLibs) | 
 | 	deps.HeaderLibs = android.LastUniqueStrings(deps.HeaderLibs) | 
 | 	deps.RuntimeLibs = android.LastUniqueStrings(deps.RuntimeLibs) | 
 |  | 
 | 	for _, lib := range deps.ReexportSharedLibHeaders { | 
 | 		if !inList(lib, deps.SharedLibs) { | 
 | 			ctx.PropertyErrorf("export_shared_lib_headers", "Shared library not in shared_libs: '%s'", lib) | 
 | 		} | 
 | 	} | 
 |  | 
 | 	for _, lib := range deps.ReexportStaticLibHeaders { | 
 | 		if !inList(lib, deps.StaticLibs) { | 
 | 			ctx.PropertyErrorf("export_static_lib_headers", "Static library not in static_libs: '%s'", lib) | 
 | 		} | 
 | 	} | 
 |  | 
 | 	for _, lib := range deps.ReexportHeaderLibHeaders { | 
 | 		if !inList(lib, deps.HeaderLibs) { | 
 | 			ctx.PropertyErrorf("export_header_lib_headers", "Header library not in header_libs: '%s'", lib) | 
 | 		} | 
 | 	} | 
 |  | 
 | 	for _, gen := range deps.ReexportGeneratedHeaders { | 
 | 		if !inList(gen, deps.GeneratedHeaders) { | 
 | 			ctx.PropertyErrorf("export_generated_headers", "Generated header module not in generated_headers: '%s'", gen) | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return deps | 
 | } | 
 |  | 
 | func (c *Module) beginMutator(actx android.BottomUpMutatorContext) { | 
 | 	ctx := &baseModuleContext{ | 
 | 		BaseModuleContext: actx, | 
 | 		moduleContextImpl: moduleContextImpl{ | 
 | 			mod: c, | 
 | 		}, | 
 | 	} | 
 | 	ctx.ctx = ctx | 
 |  | 
 | 	c.begin(ctx) | 
 | } | 
 |  | 
 | // Split name#version into name and version | 
 | func StubsLibNameAndVersion(name string) (string, string) { | 
 | 	if sharp := strings.LastIndex(name, "#"); sharp != -1 && sharp != len(name)-1 { | 
 | 		version := name[sharp+1:] | 
 | 		libname := name[:sharp] | 
 | 		return libname, version | 
 | 	} | 
 | 	return name, "" | 
 | } | 
 |  | 
 | func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { | 
 | 	if !c.Enabled() { | 
 | 		return | 
 | 	} | 
 |  | 
 | 	ctx := &depsContext{ | 
 | 		BottomUpMutatorContext: actx, | 
 | 		moduleContextImpl: moduleContextImpl{ | 
 | 			mod: c, | 
 | 		}, | 
 | 	} | 
 | 	ctx.ctx = ctx | 
 |  | 
 | 	deps := c.deps(ctx) | 
 |  | 
 | 	variantNdkLibs := []string{} | 
 | 	variantLateNdkLibs := []string{} | 
 | 	if ctx.Os() == android.Android { | 
 | 		version := ctx.sdkVersion() | 
 |  | 
 | 		// rewriteLibs takes a list of names of shared libraries and scans it for three types | 
 | 		// of names: | 
 | 		// | 
 | 		// 1. Name of an NDK library that refers to a prebuilt module. | 
 | 		//    For each of these, it adds the name of the prebuilt module (which will be in | 
 | 		//    prebuilts/ndk) to the list of nonvariant libs. | 
 | 		// 2. Name of an NDK library that refers to an ndk_library module. | 
 | 		//    For each of these, it adds the name of the ndk_library module to the list of | 
 | 		//    variant libs. | 
 | 		// 3. Anything else (so anything that isn't an NDK library). | 
 | 		//    It adds these to the nonvariantLibs list. | 
 | 		// | 
 | 		// The caller can then know to add the variantLibs dependencies differently from the | 
 | 		// nonvariantLibs | 
 |  | 
 | 		vendorPublicLibraries := vendorPublicLibraries(actx.Config()) | 
 | 		vendorSnapshotSharedLibs := vendorSnapshotSharedLibs(actx.Config()) | 
 |  | 
 | 		rewriteVendorLibs := func(lib string) string { | 
 | 			if isLlndkLibrary(lib, ctx.Config()) { | 
 | 				return lib + llndkLibrarySuffix | 
 | 			} | 
 |  | 
 | 			// only modules with BOARD_VNDK_VERSION uses snapshot. | 
 | 			if c.VndkVersion() != actx.DeviceConfig().VndkVersion() { | 
 | 				return lib | 
 | 			} | 
 |  | 
 | 			if snapshot, ok := vendorSnapshotSharedLibs.get(lib, actx.Arch().ArchType); ok { | 
 | 				return snapshot | 
 | 			} | 
 |  | 
 | 			return lib | 
 | 		} | 
 |  | 
 | 		rewriteLibs := func(list []string) (nonvariantLibs []string, variantLibs []string) { | 
 | 			variantLibs = []string{} | 
 | 			nonvariantLibs = []string{} | 
 | 			for _, entry := range list { | 
 | 				// strip #version suffix out | 
 | 				name, _ := StubsLibNameAndVersion(entry) | 
 | 				if ctx.useSdk() && inList(name, ndkPrebuiltSharedLibraries) { | 
 | 					if !inList(name, ndkMigratedLibs) { | 
 | 						nonvariantLibs = append(nonvariantLibs, name+".ndk."+version) | 
 | 					} else { | 
 | 						variantLibs = append(variantLibs, name+ndkLibrarySuffix) | 
 | 					} | 
 | 				} else if ctx.useVndk() { | 
 | 					nonvariantLibs = append(nonvariantLibs, rewriteVendorLibs(entry)) | 
 | 				} else if (ctx.Platform() || ctx.ProductSpecific()) && inList(name, *vendorPublicLibraries) { | 
 | 					vendorPublicLib := name + vendorPublicLibrarySuffix | 
 | 					if actx.OtherModuleExists(vendorPublicLib) { | 
 | 						nonvariantLibs = append(nonvariantLibs, vendorPublicLib) | 
 | 					} else { | 
 | 						// This can happen if vendor_public_library module is defined in a | 
 | 						// namespace that isn't visible to the current module. In that case, | 
 | 						// link to the original library. | 
 | 						nonvariantLibs = append(nonvariantLibs, name) | 
 | 					} | 
 | 				} else { | 
 | 					// put name#version back | 
 | 					nonvariantLibs = append(nonvariantLibs, entry) | 
 | 				} | 
 | 			} | 
 | 			return nonvariantLibs, variantLibs | 
 | 		} | 
 |  | 
 | 		deps.SharedLibs, variantNdkLibs = rewriteLibs(deps.SharedLibs) | 
 | 		deps.LateSharedLibs, variantLateNdkLibs = rewriteLibs(deps.LateSharedLibs) | 
 | 		deps.ReexportSharedLibHeaders, _ = rewriteLibs(deps.ReexportSharedLibHeaders) | 
 | 		if ctx.useVndk() { | 
 | 			for idx, lib := range deps.RuntimeLibs { | 
 | 				deps.RuntimeLibs[idx] = rewriteVendorLibs(lib) | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	buildStubs := false | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(*libraryDecorator); ok { | 
 | 			if library.buildStubs() { | 
 | 				buildStubs = true | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	rewriteSnapshotLibs := func(lib string, snapshotMap *snapshotMap) string { | 
 | 		// only modules with BOARD_VNDK_VERSION uses snapshot. | 
 | 		if c.VndkVersion() != actx.DeviceConfig().VndkVersion() { | 
 | 			return lib | 
 | 		} | 
 |  | 
 | 		if snapshot, ok := snapshotMap.get(lib, actx.Arch().ArchType); ok { | 
 | 			return snapshot | 
 | 		} | 
 |  | 
 | 		return lib | 
 | 	} | 
 |  | 
 | 	vendorSnapshotHeaderLibs := vendorSnapshotHeaderLibs(actx.Config()) | 
 | 	for _, lib := range deps.HeaderLibs { | 
 | 		depTag := headerDepTag | 
 | 		if inList(lib, deps.ReexportHeaderLibHeaders) { | 
 | 			depTag = headerExportDepTag | 
 | 		} | 
 |  | 
 | 		lib = rewriteSnapshotLibs(lib, vendorSnapshotHeaderLibs) | 
 |  | 
 | 		if buildStubs { | 
 | 			actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()), | 
 | 				depTag, lib) | 
 | 		} else { | 
 | 			actx.AddVariationDependencies(nil, depTag, lib) | 
 | 		} | 
 | 	} | 
 |  | 
 | 	if buildStubs { | 
 | 		// Stubs lib does not have dependency to other static/shared libraries. | 
 | 		// Don't proceed. | 
 | 		return | 
 | 	} | 
 |  | 
 | 	syspropImplLibraries := syspropImplLibraries(actx.Config()) | 
 | 	vendorSnapshotStaticLibs := vendorSnapshotStaticLibs(actx.Config()) | 
 |  | 
 | 	for _, lib := range deps.WholeStaticLibs { | 
 | 		depTag := wholeStaticDepTag | 
 | 		if impl, ok := syspropImplLibraries[lib]; ok { | 
 | 			lib = impl | 
 | 		} | 
 |  | 
 | 		lib = rewriteSnapshotLibs(lib, vendorSnapshotStaticLibs) | 
 |  | 
 | 		actx.AddVariationDependencies([]blueprint.Variation{ | 
 | 			{Mutator: "link", Variation: "static"}, | 
 | 		}, depTag, lib) | 
 | 	} | 
 |  | 
 | 	for _, lib := range deps.StaticLibs { | 
 | 		depTag := StaticDepTag | 
 | 		if inList(lib, deps.ReexportStaticLibHeaders) { | 
 | 			depTag = staticExportDepTag | 
 | 		} | 
 |  | 
 | 		if impl, ok := syspropImplLibraries[lib]; ok { | 
 | 			lib = impl | 
 | 		} | 
 |  | 
 | 		lib = rewriteSnapshotLibs(lib, vendorSnapshotStaticLibs) | 
 |  | 
 | 		actx.AddVariationDependencies([]blueprint.Variation{ | 
 | 			{Mutator: "link", Variation: "static"}, | 
 | 		}, depTag, lib) | 
 | 	} | 
 |  | 
 | 	// staticUnwinderDep is treated as staticDep for Q apexes | 
 | 	// so that native libraries/binaries are linked with static unwinder | 
 | 	// because Q libc doesn't have unwinder APIs | 
 | 	if deps.StaticUnwinderIfLegacy { | 
 | 		actx.AddVariationDependencies([]blueprint.Variation{ | 
 | 			{Mutator: "link", Variation: "static"}, | 
 | 		}, staticUnwinderDepTag, staticUnwinder(actx)) | 
 | 	} | 
 |  | 
 | 	for _, lib := range deps.LateStaticLibs { | 
 | 		actx.AddVariationDependencies([]blueprint.Variation{ | 
 | 			{Mutator: "link", Variation: "static"}, | 
 | 		}, lateStaticDepTag, rewriteSnapshotLibs(lib, vendorSnapshotStaticLibs)) | 
 | 	} | 
 |  | 
 | 	addSharedLibDependencies := func(depTag DependencyTag, name string, version string) { | 
 | 		var variations []blueprint.Variation | 
 | 		variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"}) | 
 | 		if version != "" && VersionVariantAvailable(c) { | 
 | 			// Version is explicitly specified. i.e. libFoo#30 | 
 | 			variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version}) | 
 | 			depTag.ExplicitlyVersioned = true | 
 | 		} | 
 | 		actx.AddVariationDependencies(variations, depTag, name) | 
 |  | 
 | 		// If the version is not specified, add dependency to all stubs libraries. | 
 | 		// The stubs library will be used when the depending module is built for APEX and | 
 | 		// the dependent module is not in the same APEX. | 
 | 		if version == "" && VersionVariantAvailable(c) { | 
 | 			for _, ver := range stubsVersionsFor(actx.Config())[name] { | 
 | 				// Note that depTag.ExplicitlyVersioned is false in this case. | 
 | 				actx.AddVariationDependencies([]blueprint.Variation{ | 
 | 					{Mutator: "link", Variation: "shared"}, | 
 | 					{Mutator: "version", Variation: ver}, | 
 | 				}, depTag, name) | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	// shared lib names without the #version suffix | 
 | 	var sharedLibNames []string | 
 |  | 
 | 	for _, lib := range deps.SharedLibs { | 
 | 		depTag := SharedDepTag | 
 | 		if c.static() { | 
 | 			depTag = SharedFromStaticDepTag | 
 | 		} | 
 | 		if inList(lib, deps.ReexportSharedLibHeaders) { | 
 | 			depTag = sharedExportDepTag | 
 | 		} | 
 |  | 
 | 		if impl, ok := syspropImplLibraries[lib]; ok { | 
 | 			lib = impl | 
 | 		} | 
 |  | 
 | 		name, version := StubsLibNameAndVersion(lib) | 
 | 		sharedLibNames = append(sharedLibNames, name) | 
 |  | 
 | 		addSharedLibDependencies(depTag, name, version) | 
 | 	} | 
 |  | 
 | 	for _, lib := range deps.LateSharedLibs { | 
 | 		if inList(lib, sharedLibNames) { | 
 | 			// This is to handle the case that some of the late shared libs (libc, libdl, libm, ...) | 
 | 			// are added also to SharedLibs with version (e.g., libc#10). If not skipped, we will be | 
 | 			// linking against both the stubs lib and the non-stubs lib at the same time. | 
 | 			continue | 
 | 		} | 
 | 		addSharedLibDependencies(lateSharedDepTag, lib, "") | 
 | 	} | 
 |  | 
 | 	actx.AddVariationDependencies([]blueprint.Variation{ | 
 | 		{Mutator: "link", Variation: "shared"}, | 
 | 	}, runtimeDepTag, deps.RuntimeLibs...) | 
 |  | 
 | 	actx.AddDependency(c, genSourceDepTag, deps.GeneratedSources...) | 
 |  | 
 | 	for _, gen := range deps.GeneratedHeaders { | 
 | 		depTag := genHeaderDepTag | 
 | 		if inList(gen, deps.ReexportGeneratedHeaders) { | 
 | 			depTag = genHeaderExportDepTag | 
 | 		} | 
 | 		actx.AddDependency(c, depTag, gen) | 
 | 	} | 
 |  | 
 | 	actx.AddVariationDependencies(nil, objDepTag, deps.ObjFiles...) | 
 |  | 
 | 	if deps.CrtBegin != "" { | 
 | 		actx.AddVariationDependencies(nil, CrtBeginDepTag, deps.CrtBegin) | 
 | 	} | 
 | 	if deps.CrtEnd != "" { | 
 | 		actx.AddVariationDependencies(nil, CrtEndDepTag, deps.CrtEnd) | 
 | 	} | 
 | 	if deps.LinkerFlagsFile != "" { | 
 | 		actx.AddDependency(c, linkerFlagsDepTag, deps.LinkerFlagsFile) | 
 | 	} | 
 | 	if deps.DynamicLinker != "" { | 
 | 		actx.AddDependency(c, dynamicLinkerDepTag, deps.DynamicLinker) | 
 | 	} | 
 |  | 
 | 	version := ctx.sdkVersion() | 
 | 	actx.AddVariationDependencies([]blueprint.Variation{ | 
 | 		{Mutator: "ndk_api", Variation: version}, | 
 | 		{Mutator: "link", Variation: "shared"}, | 
 | 	}, ndkStubDepTag, variantNdkLibs...) | 
 | 	actx.AddVariationDependencies([]blueprint.Variation{ | 
 | 		{Mutator: "ndk_api", Variation: version}, | 
 | 		{Mutator: "link", Variation: "shared"}, | 
 | 	}, ndkLateStubDepTag, variantLateNdkLibs...) | 
 |  | 
 | 	if vndkdep := c.vndkdep; vndkdep != nil { | 
 | 		if vndkdep.isVndkExt() { | 
 | 			actx.AddVariationDependencies([]blueprint.Variation{ | 
 | 				c.ImageVariation(), | 
 | 				{Mutator: "link", Variation: "shared"}, | 
 | 			}, vndkExtDepTag, vndkdep.getVndkExtendsModuleName()) | 
 | 		} | 
 | 	} | 
 | } | 
 |  | 
 | func BeginMutator(ctx android.BottomUpMutatorContext) { | 
 | 	if c, ok := ctx.Module().(*Module); ok && c.Enabled() { | 
 | 		c.beginMutator(ctx) | 
 | 	} | 
 | } | 
 |  | 
 | // Whether a module can link to another module, taking into | 
 | // account NDK linking. | 
 | func checkLinkType(ctx android.ModuleContext, from LinkableInterface, to LinkableInterface, tag DependencyTag) { | 
 | 	if from.Module().Target().Os != android.Android { | 
 | 		// Host code is not restricted | 
 | 		return | 
 | 	} | 
 |  | 
 | 	// VNDK is cc.Module supported only for now. | 
 | 	if ccFrom, ok := from.(*Module); ok && from.UseVndk() { | 
 | 		// Though vendor code is limited by the vendor mutator, | 
 | 		// each vendor-available module needs to check | 
 | 		// link-type for VNDK. | 
 | 		if ccTo, ok := to.(*Module); ok { | 
 | 			if ccFrom.vndkdep != nil { | 
 | 				ccFrom.vndkdep.vndkCheckLinkType(ctx, ccTo, tag) | 
 | 			} | 
 | 		} else { | 
 | 			ctx.ModuleErrorf("Attempting to link VNDK cc.Module with unsupported module type") | 
 | 		} | 
 | 		return | 
 | 	} | 
 | 	if from.SdkVersion() == "" { | 
 | 		// Platform code can link to anything | 
 | 		return | 
 | 	} | 
 | 	if from.InRamdisk() { | 
 | 		// Ramdisk code is not NDK | 
 | 		return | 
 | 	} | 
 | 	if from.InRecovery() { | 
 | 		// Recovery code is not NDK | 
 | 		return | 
 | 	} | 
 | 	if to.ToolchainLibrary() { | 
 | 		// These are always allowed | 
 | 		return | 
 | 	} | 
 | 	if to.NdkPrebuiltStl() { | 
 | 		// These are allowed, but they don't set sdk_version | 
 | 		return | 
 | 	} | 
 | 	if to.StubDecorator() { | 
 | 		// These aren't real libraries, but are the stub shared libraries that are included in | 
 | 		// the NDK. | 
 | 		return | 
 | 	} | 
 |  | 
 | 	if strings.HasPrefix(ctx.ModuleName(), "libclang_rt.") && to.Module().Name() == "libc++" { | 
 | 		// Bug: http://b/121358700 - Allow libclang_rt.* shared libraries (with sdk_version) | 
 | 		// to link to libc++ (non-NDK and without sdk_version). | 
 | 		return | 
 | 	} | 
 |  | 
 | 	if to.SdkVersion() == "" { | 
 | 		// NDK code linking to platform code is never okay. | 
 | 		ctx.ModuleErrorf("depends on non-NDK-built library %q", | 
 | 			ctx.OtherModuleName(to.Module())) | 
 | 		return | 
 | 	} | 
 |  | 
 | 	// At this point we know we have two NDK libraries, but we need to | 
 | 	// check that we're not linking against anything built against a higher | 
 | 	// API level, as it is only valid to link against older or equivalent | 
 | 	// APIs. | 
 |  | 
 | 	// Current can link against anything. | 
 | 	if from.SdkVersion() != "current" { | 
 | 		// Otherwise we need to check. | 
 | 		if to.SdkVersion() == "current" { | 
 | 			// Current can't be linked against by anything else. | 
 | 			ctx.ModuleErrorf("links %q built against newer API version %q", | 
 | 				ctx.OtherModuleName(to.Module()), "current") | 
 | 		} else { | 
 | 			fromApi, err := strconv.Atoi(from.SdkVersion()) | 
 | 			if err != nil { | 
 | 				ctx.PropertyErrorf("sdk_version", | 
 | 					"Invalid sdk_version value (must be int or current): %q", | 
 | 					from.SdkVersion()) | 
 | 			} | 
 | 			toApi, err := strconv.Atoi(to.SdkVersion()) | 
 | 			if err != nil { | 
 | 				ctx.PropertyErrorf("sdk_version", | 
 | 					"Invalid sdk_version value (must be int or current): %q", | 
 | 					to.SdkVersion()) | 
 | 			} | 
 |  | 
 | 			if toApi > fromApi { | 
 | 				ctx.ModuleErrorf("links %q built against newer API version %q", | 
 | 					ctx.OtherModuleName(to.Module()), to.SdkVersion()) | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	// Also check that the two STL choices are compatible. | 
 | 	fromStl := from.SelectedStl() | 
 | 	toStl := to.SelectedStl() | 
 | 	if fromStl == "" || toStl == "" { | 
 | 		// Libraries that don't use the STL are unrestricted. | 
 | 	} else if fromStl == "ndk_system" || toStl == "ndk_system" { | 
 | 		// We can be permissive with the system "STL" since it is only the C++ | 
 | 		// ABI layer, but in the future we should make sure that everyone is | 
 | 		// using either libc++ or nothing. | 
 | 	} else if getNdkStlFamily(from) != getNdkStlFamily(to) { | 
 | 		ctx.ModuleErrorf("uses %q and depends on %q which uses incompatible %q", | 
 | 			from.SelectedStl(), ctx.OtherModuleName(to.Module()), | 
 | 			to.SelectedStl()) | 
 | 	} | 
 | } | 
 |  | 
 | // Tests whether the dependent library is okay to be double loaded inside a single process. | 
 | // If a library has a vendor variant and is a (transitive) dependency of an LLNDK library, | 
 | // it is subject to be double loaded. Such lib should be explicitly marked as double_loadable: true | 
 | // or as vndk-sp (vndk: { enabled: true, support_system_process: true}). | 
 | func checkDoubleLoadableLibraries(ctx android.TopDownMutatorContext) { | 
 | 	check := func(child, parent android.Module) bool { | 
 | 		to, ok := child.(*Module) | 
 | 		if !ok { | 
 | 			// follow thru cc.Defaults, etc. | 
 | 			return true | 
 | 		} | 
 |  | 
 | 		if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() { | 
 | 			return false | 
 | 		} | 
 |  | 
 | 		// if target lib has no vendor variant, keep checking dependency graph | 
 | 		if !to.HasVendorVariant() { | 
 | 			return true | 
 | 		} | 
 |  | 
 | 		if to.isVndkSp() || to.isLlndk(ctx.Config()) || Bool(to.VendorProperties.Double_loadable) { | 
 | 			return false | 
 | 		} | 
 |  | 
 | 		var stringPath []string | 
 | 		for _, m := range ctx.GetWalkPath() { | 
 | 			stringPath = append(stringPath, m.Name()) | 
 | 		} | 
 | 		ctx.ModuleErrorf("links a library %q which is not LL-NDK, "+ | 
 | 			"VNDK-SP, or explicitly marked as 'double_loadable:true'. "+ | 
 | 			"(dependency: %s)", ctx.OtherModuleName(to), strings.Join(stringPath, " -> ")) | 
 | 		return false | 
 | 	} | 
 | 	if module, ok := ctx.Module().(*Module); ok { | 
 | 		if lib, ok := module.linker.(*libraryDecorator); ok && lib.shared() { | 
 | 			if module.isLlndk(ctx.Config()) || Bool(module.VendorProperties.Double_loadable) { | 
 | 				ctx.WalkDeps(check) | 
 | 			} | 
 | 		} | 
 | 	} | 
 | } | 
 |  | 
 | // Convert dependencies to paths.  Returns a PathDeps containing paths | 
 | func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { | 
 | 	var depPaths PathDeps | 
 |  | 
 | 	directStaticDeps := []LinkableInterface{} | 
 | 	directSharedDeps := []LinkableInterface{} | 
 |  | 
 | 	vendorPublicLibraries := vendorPublicLibraries(ctx.Config()) | 
 |  | 
 | 	reexportExporter := func(exporter exportedFlagsProducer) { | 
 | 		depPaths.ReexportedDirs = append(depPaths.ReexportedDirs, exporter.exportedDirs()...) | 
 | 		depPaths.ReexportedSystemDirs = append(depPaths.ReexportedSystemDirs, exporter.exportedSystemDirs()...) | 
 | 		depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, exporter.exportedFlags()...) | 
 | 		depPaths.ReexportedDeps = append(depPaths.ReexportedDeps, exporter.exportedDeps()...) | 
 | 		depPaths.ReexportedGeneratedHeaders = append(depPaths.ReexportedGeneratedHeaders, exporter.exportedGeneratedHeaders()...) | 
 | 	} | 
 |  | 
 | 	ctx.VisitDirectDeps(func(dep android.Module) { | 
 | 		depName := ctx.OtherModuleName(dep) | 
 | 		depTag := ctx.OtherModuleDependencyTag(dep) | 
 |  | 
 | 		ccDep, ok := dep.(LinkableInterface) | 
 | 		if !ok { | 
 |  | 
 | 			// handling for a few module types that aren't cc Module but that are also supported | 
 | 			switch depTag { | 
 | 			case genSourceDepTag: | 
 | 				if genRule, ok := dep.(genrule.SourceFileGenerator); ok { | 
 | 					depPaths.GeneratedSources = append(depPaths.GeneratedSources, | 
 | 						genRule.GeneratedSourceFiles()...) | 
 | 				} else { | 
 | 					ctx.ModuleErrorf("module %q is not a gensrcs or genrule", depName) | 
 | 				} | 
 | 				// Support exported headers from a generated_sources dependency | 
 | 				fallthrough | 
 | 			case genHeaderDepTag, genHeaderExportDepTag: | 
 | 				if genRule, ok := dep.(genrule.SourceFileGenerator); ok { | 
 | 					depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders, | 
 | 						genRule.GeneratedSourceFiles()...) | 
 | 					depPaths.GeneratedDeps = append(depPaths.GeneratedDeps, | 
 | 						genRule.GeneratedDeps()...) | 
 | 					dirs := genRule.GeneratedHeaderDirs() | 
 | 					depPaths.IncludeDirs = append(depPaths.IncludeDirs, dirs...) | 
 | 					if depTag == genHeaderExportDepTag { | 
 | 						depPaths.ReexportedDirs = append(depPaths.ReexportedDirs, dirs...) | 
 | 						depPaths.ReexportedGeneratedHeaders = append(depPaths.ReexportedGeneratedHeaders, | 
 | 							genRule.GeneratedSourceFiles()...) | 
 | 						depPaths.ReexportedDeps = append(depPaths.ReexportedDeps, genRule.GeneratedDeps()...) | 
 | 						// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library. | 
 | 						c.sabi.Properties.ReexportedIncludes = append(c.sabi.Properties.ReexportedIncludes, dirs.Strings()...) | 
 |  | 
 | 					} | 
 | 				} else { | 
 | 					ctx.ModuleErrorf("module %q is not a genrule", depName) | 
 | 				} | 
 | 			case linkerFlagsDepTag: | 
 | 				if genRule, ok := dep.(genrule.SourceFileGenerator); ok { | 
 | 					files := genRule.GeneratedSourceFiles() | 
 | 					if len(files) == 1 { | 
 | 						depPaths.LinkerFlagsFile = android.OptionalPathForPath(files[0]) | 
 | 					} else if len(files) > 1 { | 
 | 						ctx.ModuleErrorf("module %q can only generate a single file if used for a linker flag file", depName) | 
 | 					} | 
 | 				} else { | 
 | 					ctx.ModuleErrorf("module %q is not a genrule", depName) | 
 | 				} | 
 | 			} | 
 | 			return | 
 | 		} | 
 |  | 
 | 		if depTag == android.ProtoPluginDepTag { | 
 | 			return | 
 | 		} | 
 | 		if depTag == llndkImplDep { | 
 | 			return | 
 | 		} | 
 |  | 
 | 		if dep.Target().Os != ctx.Os() { | 
 | 			ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName) | 
 | 			return | 
 | 		} | 
 | 		if dep.Target().Arch.ArchType != ctx.Arch().ArchType { | 
 | 			ctx.ModuleErrorf("Arch mismatch between %q(%v) and %q(%v)", | 
 | 				ctx.ModuleName(), ctx.Arch().ArchType, depName, dep.Target().Arch.ArchType) | 
 | 			return | 
 | 		} | 
 |  | 
 | 		// re-exporting flags | 
 | 		if depTag == reuseObjTag { | 
 | 			// reusing objects only make sense for cc.Modules. | 
 | 			if ccReuseDep, ok := ccDep.(*Module); ok && ccDep.CcLibraryInterface() { | 
 | 				c.staticVariant = ccDep | 
 | 				objs, exporter := ccReuseDep.compiler.(libraryInterface).reuseObjs() | 
 | 				depPaths.Objs = depPaths.Objs.Append(objs) | 
 | 				reexportExporter(exporter) | 
 | 				return | 
 | 			} | 
 | 		} | 
 |  | 
 | 		if depTag == staticVariantTag { | 
 | 			// staticVariants are a cc.Module specific concept. | 
 | 			if _, ok := ccDep.(*Module); ok && ccDep.CcLibraryInterface() { | 
 | 				c.staticVariant = ccDep | 
 | 				return | 
 | 			} | 
 | 		} | 
 |  | 
 | 		// For the dependency from platform to apex, use the latest stubs | 
 | 		c.apexSdkVersion = android.FutureApiLevel | 
 | 		if !c.IsForPlatform() { | 
 | 			c.apexSdkVersion = c.ApexProperties.Info.MinSdkVersion | 
 | 		} | 
 |  | 
 | 		if android.InList("hwaddress", ctx.Config().SanitizeDevice()) { | 
 | 			// In hwasan build, we override apexSdkVersion to the FutureApiLevel(10000) | 
 | 			// so that even Q(29/Android10) apexes could use the dynamic unwinder by linking the newer stubs(e.g libc(R+)). | 
 | 			// (b/144430859) | 
 | 			c.apexSdkVersion = android.FutureApiLevel | 
 | 		} | 
 |  | 
 | 		if depTag == staticUnwinderDepTag { | 
 | 			// Use static unwinder for legacy (min_sdk_version = 29) apexes (b/144430859) | 
 | 			if c.apexSdkVersion <= android.SdkVersion_Android10 { | 
 | 				depTag = StaticDepTag | 
 | 			} else { | 
 | 				return | 
 | 			} | 
 | 		} | 
 |  | 
 | 		// Extract ExplicitlyVersioned field from the depTag and reset it inside the struct. | 
 | 		// Otherwise, SharedDepTag and lateSharedDepTag with ExplicitlyVersioned set to true | 
 | 		// won't be matched to SharedDepTag and lateSharedDepTag. | 
 | 		explicitlyVersioned := false | 
 | 		if t, ok := depTag.(DependencyTag); ok { | 
 | 			explicitlyVersioned = t.ExplicitlyVersioned | 
 | 			t.ExplicitlyVersioned = false | 
 | 			depTag = t | 
 | 		} | 
 |  | 
 | 		if t, ok := depTag.(DependencyTag); ok && t.Library { | 
 | 			depIsStatic := false | 
 | 			switch depTag { | 
 | 			case StaticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag: | 
 | 				depIsStatic = true | 
 | 			} | 
 | 			if ccDep.CcLibrary() && !depIsStatic { | 
 | 				depIsStubs := ccDep.BuildStubs() | 
 | 				depHasStubs := VersionVariantAvailable(c) && ccDep.HasStubsVariants() | 
 | 				depInSameApex := android.DirectlyInApex(c.ApexName(), depName) | 
 | 				depInPlatform := !android.DirectlyInAnyApex(ctx, depName) | 
 |  | 
 | 				var useThisDep bool | 
 | 				if depIsStubs && explicitlyVersioned { | 
 | 					// Always respect dependency to the versioned stubs (i.e. libX#10) | 
 | 					useThisDep = true | 
 | 				} else if !depHasStubs { | 
 | 					// Use non-stub variant if that is the only choice | 
 | 					// (i.e. depending on a lib without stubs.version property) | 
 | 					useThisDep = true | 
 | 				} else if c.IsForPlatform() { | 
 | 					// If not building for APEX, use stubs only when it is from | 
 | 					// an APEX (and not from platform) | 
 | 					useThisDep = (depInPlatform != depIsStubs) | 
 | 					if c.bootstrap() { | 
 | 						// However, for host, ramdisk, recovery or bootstrap modules, | 
 | 						// always link to non-stub variant | 
 | 						useThisDep = !depIsStubs | 
 | 					} | 
 | 					for _, testFor := range c.TestFor() { | 
 | 						// Another exception: if this module is bundled with an APEX, then | 
 | 						// it is linked with the non-stub variant of a module in the APEX | 
 | 						// as if this is part of the APEX. | 
 | 						if android.DirectlyInApex(testFor, depName) { | 
 | 							useThisDep = !depIsStubs | 
 | 							break | 
 | 						} | 
 | 					} | 
 | 				} else { | 
 | 					// If building for APEX, use stubs only when it is not from | 
 | 					// the same APEX | 
 | 					useThisDep = (depInSameApex != depIsStubs) | 
 | 				} | 
 |  | 
 | 				// when to use (unspecified) stubs, check min_sdk_version and choose the right one | 
 | 				if useThisDep && depIsStubs && !explicitlyVersioned { | 
 | 					versionToUse, err := c.ChooseSdkVersion(ccDep.StubsVersions(), c.apexSdkVersion) | 
 | 					if err != nil { | 
 | 						ctx.OtherModuleErrorf(dep, err.Error()) | 
 | 						return | 
 | 					} | 
 | 					if versionToUse != ccDep.StubsVersion() { | 
 | 						useThisDep = false | 
 | 					} | 
 | 				} | 
 |  | 
 | 				if !useThisDep { | 
 | 					return // stop processing this dep | 
 | 				} | 
 | 			} | 
 | 			if c.UseVndk() { | 
 | 				if m, ok := ccDep.(*Module); ok && m.IsStubs() { // LLNDK | 
 | 					// by default, use current version of LLNDK | 
 | 					versionToUse := "" | 
 | 					versions := stubsVersionsFor(ctx.Config())[depName] | 
 | 					if c.ApexName() != "" && len(versions) > 0 { | 
 | 						// if this is for use_vendor apex && dep has stubsVersions | 
 | 						// apply the same rule of apex sdk enforcement to choose right version | 
 | 						var err error | 
 | 						versionToUse, err = c.ChooseSdkVersion(versions, c.apexSdkVersion) | 
 | 						if err != nil { | 
 | 							ctx.OtherModuleErrorf(dep, err.Error()) | 
 | 							return | 
 | 						} | 
 | 					} | 
 | 					if versionToUse != ccDep.StubsVersion() { | 
 | 						return | 
 | 					} | 
 | 				} | 
 | 			} | 
 |  | 
 | 			depPaths.IncludeDirs = append(depPaths.IncludeDirs, ccDep.IncludeDirs()...) | 
 |  | 
 | 			// Exporting flags only makes sense for cc.Modules | 
 | 			if _, ok := ccDep.(*Module); ok { | 
 | 				if i, ok := ccDep.(*Module).linker.(exportedFlagsProducer); ok { | 
 | 					depPaths.SystemIncludeDirs = append(depPaths.SystemIncludeDirs, i.exportedSystemDirs()...) | 
 | 					depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders, i.exportedGeneratedHeaders()...) | 
 | 					depPaths.GeneratedDeps = append(depPaths.GeneratedDeps, i.exportedDeps()...) | 
 | 					depPaths.Flags = append(depPaths.Flags, i.exportedFlags()...) | 
 |  | 
 | 					if t.ReexportFlags { | 
 | 						reexportExporter(i) | 
 | 						// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library. | 
 | 						// Re-exported shared library headers must be included as well since they can help us with type information | 
 | 						// about template instantiations (instantiated from their headers). | 
 | 						// -isystem headers are not included since for bionic libraries, abi-filtering is taken care of by version | 
 | 						// scripts. | 
 | 						c.sabi.Properties.ReexportedIncludes = append( | 
 | 							c.sabi.Properties.ReexportedIncludes, i.exportedDirs().Strings()...) | 
 | 					} | 
 | 				} | 
 | 			} | 
 | 			checkLinkType(ctx, c, ccDep, t) | 
 | 		} | 
 |  | 
 | 		var ptr *android.Paths | 
 | 		var depPtr *android.Paths | 
 |  | 
 | 		linkFile := ccDep.OutputFile() | 
 | 		depFile := android.OptionalPath{} | 
 |  | 
 | 		switch depTag { | 
 | 		case ndkStubDepTag, SharedDepTag, SharedFromStaticDepTag, sharedExportDepTag: | 
 | 			ptr = &depPaths.SharedLibs | 
 | 			depPtr = &depPaths.SharedLibsDeps | 
 | 			depFile = ccDep.Toc() | 
 | 			directSharedDeps = append(directSharedDeps, ccDep) | 
 |  | 
 | 		case earlySharedDepTag: | 
 | 			ptr = &depPaths.EarlySharedLibs | 
 | 			depPtr = &depPaths.EarlySharedLibsDeps | 
 | 			depFile = ccDep.Toc() | 
 | 			directSharedDeps = append(directSharedDeps, ccDep) | 
 | 		case lateSharedDepTag, ndkLateStubDepTag: | 
 | 			ptr = &depPaths.LateSharedLibs | 
 | 			depPtr = &depPaths.LateSharedLibsDeps | 
 | 			depFile = ccDep.Toc() | 
 | 		case StaticDepTag, staticExportDepTag: | 
 | 			ptr = nil | 
 | 			directStaticDeps = append(directStaticDeps, ccDep) | 
 | 		case lateStaticDepTag: | 
 | 			ptr = &depPaths.LateStaticLibs | 
 | 		case wholeStaticDepTag: | 
 | 			ptr = &depPaths.WholeStaticLibs | 
 | 			if !ccDep.CcLibraryInterface() || !ccDep.Static() { | 
 | 				ctx.ModuleErrorf("module %q not a static library", depName) | 
 | 				return | 
 | 			} | 
 |  | 
 | 			// Because the static library objects are included, this only makes sense | 
 | 			// in the context of proper cc.Modules. | 
 | 			if ccWholeStaticLib, ok := ccDep.(*Module); ok { | 
 | 				staticLib := ccWholeStaticLib.linker.(libraryInterface) | 
 | 				if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil { | 
 | 					postfix := " (required by " + ctx.OtherModuleName(dep) + ")" | 
 | 					for i := range missingDeps { | 
 | 						missingDeps[i] += postfix | 
 | 					} | 
 | 					ctx.AddMissingDependencies(missingDeps) | 
 | 				} | 
 | 				depPaths.WholeStaticLibObjs = depPaths.WholeStaticLibObjs.Append(staticLib.objs()) | 
 | 			} else { | 
 | 				ctx.ModuleErrorf( | 
 | 					"non-cc.Modules cannot be included as whole static libraries.", depName) | 
 | 				return | 
 | 			} | 
 | 		case headerDepTag: | 
 | 			// Nothing | 
 | 		case objDepTag: | 
 | 			depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path()) | 
 | 		case CrtBeginDepTag: | 
 | 			depPaths.CrtBegin = linkFile | 
 | 		case CrtEndDepTag: | 
 | 			depPaths.CrtEnd = linkFile | 
 | 		case dynamicLinkerDepTag: | 
 | 			depPaths.DynamicLinker = linkFile | 
 | 		} | 
 |  | 
 | 		switch depTag { | 
 | 		case StaticDepTag, staticExportDepTag, lateStaticDepTag: | 
 | 			if !ccDep.CcLibraryInterface() || !ccDep.Static() { | 
 | 				ctx.ModuleErrorf("module %q not a static library", depName) | 
 | 				return | 
 | 			} | 
 |  | 
 | 			// When combining coverage files for shared libraries and executables, coverage files | 
 | 			// in static libraries act as if they were whole static libraries. The same goes for | 
 | 			// source based Abi dump files. | 
 | 			// This should only be done for cc.Modules | 
 | 			if c, ok := ccDep.(*Module); ok { | 
 | 				staticLib := c.linker.(libraryInterface) | 
 | 				depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles, | 
 | 					staticLib.objs().coverageFiles...) | 
 | 				depPaths.StaticLibObjs.sAbiDumpFiles = append(depPaths.StaticLibObjs.sAbiDumpFiles, | 
 | 					staticLib.objs().sAbiDumpFiles...) | 
 | 			} | 
 | 		} | 
 |  | 
 | 		if ptr != nil { | 
 | 			if !linkFile.Valid() { | 
 | 				if !ctx.Config().AllowMissingDependencies() { | 
 | 					ctx.ModuleErrorf("module %q missing output file", depName) | 
 | 				} else { | 
 | 					ctx.AddMissingDependencies([]string{depName}) | 
 | 				} | 
 | 				return | 
 | 			} | 
 | 			*ptr = append(*ptr, linkFile.Path()) | 
 | 		} | 
 |  | 
 | 		if depPtr != nil { | 
 | 			dep := depFile | 
 | 			if !dep.Valid() { | 
 | 				dep = linkFile | 
 | 			} | 
 | 			*depPtr = append(*depPtr, dep.Path()) | 
 | 		} | 
 |  | 
 | 		vendorSuffixModules := vendorSuffixModules(ctx.Config()) | 
 |  | 
 | 		baseLibName := func(depName string) string { | 
 | 			libName := strings.TrimSuffix(depName, llndkLibrarySuffix) | 
 | 			libName = strings.TrimSuffix(libName, vendorPublicLibrarySuffix) | 
 | 			libName = strings.TrimPrefix(libName, "prebuilt_") | 
 | 			return libName | 
 | 		} | 
 |  | 
 | 		makeLibName := func(depName string) string { | 
 | 			libName := baseLibName(depName) | 
 | 			isLLndk := isLlndkLibrary(libName, ctx.Config()) | 
 | 			isVendorPublicLib := inList(libName, *vendorPublicLibraries) | 
 | 			bothVendorAndCoreVariantsExist := ccDep.HasVendorVariant() || isLLndk | 
 |  | 
 | 			if c, ok := ccDep.(*Module); ok { | 
 | 				// Use base module name for snapshots when exporting to Makefile. | 
 | 				if c.isSnapshotPrebuilt() { | 
 | 					baseName := c.BaseModuleName() | 
 |  | 
 | 					if c.IsVndk() { | 
 | 						return baseName + ".vendor" | 
 | 					} | 
 |  | 
 | 					if vendorSuffixModules[baseName] { | 
 | 						return baseName + ".vendor" | 
 | 					} else { | 
 | 						return baseName | 
 | 					} | 
 | 				} | 
 | 			} | 
 |  | 
 | 			if ctx.DeviceConfig().VndkUseCoreVariant() && ccDep.IsVndk() && !ccDep.MustUseVendorVariant() && !c.InRamdisk() && !c.InRecovery() { | 
 | 				// The vendor module is a no-vendor-variant VNDK library.  Depend on the | 
 | 				// core module instead. | 
 | 				return libName | 
 | 			} else if c.UseVndk() && bothVendorAndCoreVariantsExist { | 
 | 				// The vendor module in Make will have been renamed to not conflict with the core | 
 | 				// module, so update the dependency name here accordingly. | 
 | 				return libName + c.getNameSuffixWithVndkVersion(ctx) | 
 | 			} else if (ctx.Platform() || ctx.ProductSpecific()) && isVendorPublicLib { | 
 | 				return libName + vendorPublicLibrarySuffix | 
 | 			} else if ccDep.InRamdisk() && !ccDep.OnlyInRamdisk() { | 
 | 				return libName + ramdiskSuffix | 
 | 			} else if ccDep.InRecovery() && !ccDep.OnlyInRecovery() { | 
 | 				return libName + recoverySuffix | 
 | 			} else if ccDep.Module().Target().NativeBridge == android.NativeBridgeEnabled { | 
 | 				return libName + nativeBridgeSuffix | 
 | 			} else { | 
 | 				return libName | 
 | 			} | 
 | 		} | 
 |  | 
 | 		// Export the shared libs to Make. | 
 | 		switch depTag { | 
 | 		case SharedDepTag, sharedExportDepTag, lateSharedDepTag, earlySharedDepTag: | 
 | 			if ccDep.CcLibrary() { | 
 | 				if ccDep.BuildStubs() && android.InAnyApex(depName) { | 
 | 					// Add the dependency to the APEX(es) providing the library so that | 
 | 					// m <module> can trigger building the APEXes as well. | 
 | 					for _, an := range android.GetApexesForModule(depName) { | 
 | 						c.Properties.ApexesProvidingSharedLibs = append( | 
 | 							c.Properties.ApexesProvidingSharedLibs, an) | 
 | 					} | 
 | 				} | 
 | 			} | 
 |  | 
 | 			// Note: the order of libs in this list is not important because | 
 | 			// they merely serve as Make dependencies and do not affect this lib itself. | 
 | 			c.Properties.AndroidMkSharedLibs = append( | 
 | 				c.Properties.AndroidMkSharedLibs, makeLibName(depName)) | 
 | 			// Record baseLibName for snapshots. | 
 | 			c.Properties.SnapshotSharedLibs = append(c.Properties.SnapshotSharedLibs, baseLibName(depName)) | 
 | 		case ndkStubDepTag, ndkLateStubDepTag: | 
 | 			c.Properties.AndroidMkSharedLibs = append( | 
 | 				c.Properties.AndroidMkSharedLibs, | 
 | 				depName+"."+ccDep.ApiLevel()) | 
 | 		case StaticDepTag, staticExportDepTag, lateStaticDepTag: | 
 | 			c.Properties.AndroidMkStaticLibs = append( | 
 | 				c.Properties.AndroidMkStaticLibs, makeLibName(depName)) | 
 | 		case runtimeDepTag: | 
 | 			c.Properties.AndroidMkRuntimeLibs = append( | 
 | 				c.Properties.AndroidMkRuntimeLibs, makeLibName(depName)) | 
 | 			// Record baseLibName for snapshots. | 
 | 			c.Properties.SnapshotRuntimeLibs = append(c.Properties.SnapshotRuntimeLibs, baseLibName(depName)) | 
 | 		case wholeStaticDepTag: | 
 | 			c.Properties.AndroidMkWholeStaticLibs = append( | 
 | 				c.Properties.AndroidMkWholeStaticLibs, makeLibName(depName)) | 
 | 		case headerDepTag: | 
 | 			c.Properties.AndroidMkHeaderLibs = append( | 
 | 				c.Properties.AndroidMkHeaderLibs, makeLibName(depName)) | 
 | 		} | 
 | 	}) | 
 |  | 
 | 	// use the ordered dependencies as this module's dependencies | 
 | 	depPaths.StaticLibs = append(depPaths.StaticLibs, orderStaticModuleDeps(c, directStaticDeps, directSharedDeps)...) | 
 |  | 
 | 	// Dedup exported flags from dependencies | 
 | 	depPaths.Flags = android.FirstUniqueStrings(depPaths.Flags) | 
 | 	depPaths.IncludeDirs = android.FirstUniquePaths(depPaths.IncludeDirs) | 
 | 	depPaths.SystemIncludeDirs = android.FirstUniquePaths(depPaths.SystemIncludeDirs) | 
 | 	depPaths.GeneratedHeaders = android.FirstUniquePaths(depPaths.GeneratedHeaders) | 
 | 	depPaths.GeneratedDeps = android.FirstUniquePaths(depPaths.GeneratedDeps) | 
 | 	depPaths.ReexportedDirs = android.FirstUniquePaths(depPaths.ReexportedDirs) | 
 | 	depPaths.ReexportedSystemDirs = android.FirstUniquePaths(depPaths.ReexportedSystemDirs) | 
 | 	depPaths.ReexportedFlags = android.FirstUniqueStrings(depPaths.ReexportedFlags) | 
 | 	depPaths.ReexportedDeps = android.FirstUniquePaths(depPaths.ReexportedDeps) | 
 | 	depPaths.ReexportedGeneratedHeaders = android.FirstUniquePaths(depPaths.ReexportedGeneratedHeaders) | 
 |  | 
 | 	if c.sabi != nil { | 
 | 		c.sabi.Properties.ReexportedIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedIncludes) | 
 | 	} | 
 |  | 
 | 	return depPaths | 
 | } | 
 |  | 
 | func (c *Module) InstallInData() bool { | 
 | 	if c.installer == nil { | 
 | 		return false | 
 | 	} | 
 | 	return c.installer.inData() | 
 | } | 
 |  | 
 | func (c *Module) InstallInSanitizerDir() bool { | 
 | 	if c.installer == nil { | 
 | 		return false | 
 | 	} | 
 | 	if c.sanitize != nil && c.sanitize.inSanitizerDir() { | 
 | 		return true | 
 | 	} | 
 | 	return c.installer.inSanitizerDir() | 
 | } | 
 |  | 
 | func (c *Module) InstallInRamdisk() bool { | 
 | 	return c.InRamdisk() | 
 | } | 
 |  | 
 | func (c *Module) InstallInRecovery() bool { | 
 | 	return c.InRecovery() | 
 | } | 
 |  | 
 | func (c *Module) SkipInstall() { | 
 | 	if c.installer == nil { | 
 | 		c.ModuleBase.SkipInstall() | 
 | 		return | 
 | 	} | 
 | 	c.installer.skipInstall(c) | 
 | } | 
 |  | 
 | func (c *Module) HostToolPath() android.OptionalPath { | 
 | 	if c.installer == nil { | 
 | 		return android.OptionalPath{} | 
 | 	} | 
 | 	return c.installer.hostToolPath() | 
 | } | 
 |  | 
 | func (c *Module) IntermPathForModuleOut() android.OptionalPath { | 
 | 	return c.outputFile | 
 | } | 
 |  | 
 | func (c *Module) OutputFiles(tag string) (android.Paths, error) { | 
 | 	switch tag { | 
 | 	case "": | 
 | 		if c.outputFile.Valid() { | 
 | 			return android.Paths{c.outputFile.Path()}, nil | 
 | 		} | 
 | 		return android.Paths{}, nil | 
 | 	default: | 
 | 		return nil, fmt.Errorf("unsupported module reference tag %q", tag) | 
 | 	} | 
 | } | 
 |  | 
 | func (c *Module) static() bool { | 
 | 	if static, ok := c.linker.(interface { | 
 | 		static() bool | 
 | 	}); ok { | 
 | 		return static.static() | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) staticBinary() bool { | 
 | 	if static, ok := c.linker.(interface { | 
 | 		staticBinary() bool | 
 | 	}); ok { | 
 | 		return static.staticBinary() | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) header() bool { | 
 | 	if h, ok := c.linker.(interface { | 
 | 		header() bool | 
 | 	}); ok { | 
 | 		return h.header() | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) getMakeLinkType(actx android.ModuleContext) string { | 
 | 	if c.UseVndk() { | 
 | 		if lib, ok := c.linker.(*llndkStubDecorator); ok { | 
 | 			if Bool(lib.Properties.Vendor_available) { | 
 | 				return "native:vndk" | 
 | 			} | 
 | 			return "native:vndk_private" | 
 | 		} | 
 | 		if c.IsVndk() && !c.isVndkExt() { | 
 | 			if Bool(c.VendorProperties.Vendor_available) { | 
 | 				return "native:vndk" | 
 | 			} | 
 | 			return "native:vndk_private" | 
 | 		} | 
 | 		if c.inProduct() { | 
 | 			return "native:product" | 
 | 		} | 
 | 		return "native:vendor" | 
 | 	} else if c.InRamdisk() { | 
 | 		return "native:ramdisk" | 
 | 	} else if c.InRecovery() { | 
 | 		return "native:recovery" | 
 | 	} else if c.Target().Os == android.Android && String(c.Properties.Sdk_version) != "" { | 
 | 		return "native:ndk:none:none" | 
 | 		// TODO(b/114741097): use the correct ndk stl once build errors have been fixed | 
 | 		//family, link := getNdkStlFamilyAndLinkType(c) | 
 | 		//return fmt.Sprintf("native:ndk:%s:%s", family, link) | 
 | 	} else if actx.DeviceConfig().VndkUseCoreVariant() && !c.MustUseVendorVariant() { | 
 | 		return "native:platform_vndk" | 
 | 	} else { | 
 | 		return "native:platform" | 
 | 	} | 
 | } | 
 |  | 
 | // Overrides ApexModule.IsInstallabeToApex() | 
 | // Only shared/runtime libraries and "test_per_src" tests are installable to APEX. | 
 | func (c *Module) IsInstallableToApex() bool { | 
 | 	if shared, ok := c.linker.(interface { | 
 | 		shared() bool | 
 | 	}); ok { | 
 | 		// Stub libs and prebuilt libs in a versioned SDK are not | 
 | 		// installable to APEX even though they are shared libs. | 
 | 		return shared.shared() && !c.IsStubs() && c.ContainingSdk().Unversioned() | 
 | 	} else if _, ok := c.linker.(testPerSrc); ok { | 
 | 		return true | 
 | 	} | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) AvailableFor(what string) bool { | 
 | 	if linker, ok := c.linker.(interface { | 
 | 		availableFor(string) bool | 
 | 	}); ok { | 
 | 		return c.ApexModuleBase.AvailableFor(what) || linker.availableFor(what) | 
 | 	} else { | 
 | 		return c.ApexModuleBase.AvailableFor(what) | 
 | 	} | 
 | } | 
 |  | 
 | func (c *Module) TestFor() []string { | 
 | 	if test, ok := c.linker.(interface { | 
 | 		testFor() []string | 
 | 	}); ok { | 
 | 		return test.testFor() | 
 | 	} else { | 
 | 		return c.ApexModuleBase.TestFor() | 
 | 	} | 
 | } | 
 |  | 
 | // Return true if the module is ever installable. | 
 | func (c *Module) EverInstallable() bool { | 
 | 	return c.installer != nil && | 
 | 		// Check to see whether the module is actually ever installable. | 
 | 		c.installer.everInstallable() | 
 | } | 
 |  | 
 | func (c *Module) installable() bool { | 
 | 	ret := c.EverInstallable() && | 
 | 		// Check to see whether the module has been configured to not be installed. | 
 | 		proptools.BoolDefault(c.Properties.Installable, true) && | 
 | 		!c.Properties.PreventInstall && c.outputFile.Valid() | 
 |  | 
 | 	// The platform variant doesn't need further condition. Apex variants however might not | 
 | 	// be installable because it will likely to be included in the APEX and won't appear | 
 | 	// in the system partition. | 
 | 	if c.IsForPlatform() { | 
 | 		return ret | 
 | 	} | 
 |  | 
 | 	// Special case for modules that are configured to be installed to /data, which includes | 
 | 	// test modules. For these modules, both APEX and non-APEX variants are considered as | 
 | 	// installable. This is because even the APEX variants won't be included in the APEX, but | 
 | 	// will anyway be installed to /data/*. | 
 | 	// See b/146995717 | 
 | 	if c.InstallInData() { | 
 | 		return ret | 
 | 	} | 
 |  | 
 | 	return false | 
 | } | 
 |  | 
 | func (c *Module) AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) { | 
 | 	if c.linker != nil { | 
 | 		if library, ok := c.linker.(*libraryDecorator); ok { | 
 | 			library.androidMkWriteAdditionalDependenciesForSourceAbiDiff(w) | 
 | 		} | 
 | 	} | 
 | } | 
 |  | 
 | func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { | 
 | 	if depTag, ok := ctx.OtherModuleDependencyTag(dep).(DependencyTag); ok { | 
 | 		if cc, ok := dep.(*Module); ok { | 
 | 			if cc.HasStubsVariants() { | 
 | 				if depTag.Shared && depTag.Library { | 
 | 					// dynamic dep to a stubs lib crosses APEX boundary | 
 | 					return false | 
 | 				} | 
 | 				if IsRuntimeDepTag(depTag) { | 
 | 					// runtime dep to a stubs lib also crosses APEX boundary | 
 | 					return false | 
 | 				} | 
 | 			} | 
 | 			if depTag.FromStatic { | 
 | 				// shared_lib dependency from a static lib is considered as crossing | 
 | 				// the APEX boundary because the dependency doesn't actually is | 
 | 				// linked; the dependency is used only during the compilation phase. | 
 | 				return false | 
 | 			} | 
 | 		} | 
 | 	} | 
 | 	return true | 
 | } | 
 |  | 
 | // | 
 | // Defaults | 
 | // | 
 | type Defaults struct { | 
 | 	android.ModuleBase | 
 | 	android.DefaultsModuleBase | 
 | 	android.ApexModuleBase | 
 | } | 
 |  | 
 | // cc_defaults provides a set of properties that can be inherited by other cc | 
 | // modules. A module can use the properties from a cc_defaults using | 
 | // `defaults: ["<:default_module_name>"]`. Properties of both modules are | 
 | // merged (when possible) by prepending the default module's values to the | 
 | // depending module's values. | 
 | func defaultsFactory() android.Module { | 
 | 	return DefaultsFactory() | 
 | } | 
 |  | 
 | func DefaultsFactory(props ...interface{}) android.Module { | 
 | 	module := &Defaults{} | 
 |  | 
 | 	module.AddProperties(props...) | 
 | 	module.AddProperties( | 
 | 		&BaseProperties{}, | 
 | 		&VendorProperties{}, | 
 | 		&BaseCompilerProperties{}, | 
 | 		&BaseLinkerProperties{}, | 
 | 		&ObjectLinkerProperties{}, | 
 | 		&LibraryProperties{}, | 
 | 		&StaticProperties{}, | 
 | 		&SharedProperties{}, | 
 | 		&FlagExporterProperties{}, | 
 | 		&BinaryLinkerProperties{}, | 
 | 		&TestProperties{}, | 
 | 		&TestBinaryProperties{}, | 
 | 		&FuzzProperties{}, | 
 | 		&StlProperties{}, | 
 | 		&SanitizeProperties{}, | 
 | 		&StripProperties{}, | 
 | 		&InstallerProperties{}, | 
 | 		&TidyProperties{}, | 
 | 		&CoverageProperties{}, | 
 | 		&SAbiProperties{}, | 
 | 		&VndkProperties{}, | 
 | 		<OProperties{}, | 
 | 		&PgoProperties{}, | 
 | 		&android.ProtoProperties{}, | 
 | 	) | 
 |  | 
 | 	android.InitDefaultsModule(module) | 
 |  | 
 | 	return module | 
 | } | 
 |  | 
 | func squashVendorSrcs(m *Module) { | 
 | 	if lib, ok := m.compiler.(*libraryDecorator); ok { | 
 | 		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs, | 
 | 			lib.baseCompiler.Properties.Target.Vendor.Srcs...) | 
 |  | 
 | 		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, | 
 | 			lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...) | 
 | 	} | 
 | } | 
 |  | 
 | func squashRecoverySrcs(m *Module) { | 
 | 	if lib, ok := m.compiler.(*libraryDecorator); ok { | 
 | 		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs, | 
 | 			lib.baseCompiler.Properties.Target.Recovery.Srcs...) | 
 |  | 
 | 		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, | 
 | 			lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...) | 
 | 	} | 
 | } | 
 |  | 
 | var _ android.ImageInterface = (*Module)(nil) | 
 |  | 
 | func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) { | 
 | 	// Sanity check | 
 | 	vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific() | 
 | 	productSpecific := mctx.ProductSpecific() | 
 |  | 
 | 	if m.VendorProperties.Vendor_available != nil && vendorSpecific { | 
 | 		mctx.PropertyErrorf("vendor_available", | 
 | 			"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific:true`") | 
 | 	} | 
 |  | 
 | 	if vndkdep := m.vndkdep; vndkdep != nil { | 
 | 		if vndkdep.isVndk() { | 
 | 			if vendorSpecific || productSpecific { | 
 | 				if !vndkdep.isVndkExt() { | 
 | 					mctx.PropertyErrorf("vndk", | 
 | 						"must set `extends: \"...\"` to vndk extension") | 
 | 				} else if m.VendorProperties.Vendor_available != nil { | 
 | 					mctx.PropertyErrorf("vendor_available", | 
 | 						"must not set at the same time as `vndk: {extends: \"...\"}`") | 
 | 				} | 
 | 			} else { | 
 | 				if vndkdep.isVndkExt() { | 
 | 					mctx.PropertyErrorf("vndk", | 
 | 						"must set `vendor: true` or `product_specific: true` to set `extends: %q`", | 
 | 						m.getVndkExtendsModuleName()) | 
 | 				} | 
 | 				if m.VendorProperties.Vendor_available == nil { | 
 | 					mctx.PropertyErrorf("vndk", | 
 | 						"vendor_available must be set to either true or false when `vndk: {enabled: true}`") | 
 | 				} | 
 | 			} | 
 | 		} else { | 
 | 			if vndkdep.isVndkSp() { | 
 | 				mctx.PropertyErrorf("vndk", | 
 | 					"must set `enabled: true` to set `support_system_process: true`") | 
 | 			} | 
 | 			if vndkdep.isVndkExt() { | 
 | 				mctx.PropertyErrorf("vndk", | 
 | 					"must set `enabled: true` to set `extends: %q`", | 
 | 					m.getVndkExtendsModuleName()) | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	var coreVariantNeeded bool = false | 
 | 	var ramdiskVariantNeeded bool = false | 
 | 	var recoveryVariantNeeded bool = false | 
 |  | 
 | 	var vendorVariants []string | 
 | 	var productVariants []string | 
 |  | 
 | 	platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion() | 
 | 	boardVndkVersion := mctx.DeviceConfig().VndkVersion() | 
 | 	productVndkVersion := mctx.DeviceConfig().ProductVndkVersion() | 
 | 	if boardVndkVersion == "current" { | 
 | 		boardVndkVersion = platformVndkVersion | 
 | 	} | 
 | 	if productVndkVersion == "current" { | 
 | 		productVndkVersion = platformVndkVersion | 
 | 	} | 
 |  | 
 | 	if boardVndkVersion == "" { | 
 | 		// If the device isn't compiling against the VNDK, we always | 
 | 		// use the core mode. | 
 | 		coreVariantNeeded = true | 
 | 	} else if _, ok := m.linker.(*llndkStubDecorator); ok { | 
 | 		// LL-NDK stubs only exist in the vendor and product variants, | 
 | 		// since the real libraries will be used in the core variant. | 
 | 		vendorVariants = append(vendorVariants, | 
 | 			platformVndkVersion, | 
 | 			boardVndkVersion, | 
 | 		) | 
 | 		productVariants = append(productVariants, | 
 | 			platformVndkVersion, | 
 | 			productVndkVersion, | 
 | 		) | 
 | 	} else if _, ok := m.linker.(*llndkHeadersDecorator); ok { | 
 | 		// ... and LL-NDK headers as well | 
 | 		vendorVariants = append(vendorVariants, | 
 | 			platformVndkVersion, | 
 | 			boardVndkVersion, | 
 | 		) | 
 | 		productVariants = append(productVariants, | 
 | 			platformVndkVersion, | 
 | 			productVndkVersion, | 
 | 		) | 
 | 	} else if m.isSnapshotPrebuilt() { | 
 | 		// Make vendor variants only for the versions in BOARD_VNDK_VERSION and | 
 | 		// PRODUCT_EXTRA_VNDK_VERSIONS. | 
 | 		if snapshot, ok := m.linker.(interface { | 
 | 			version() string | 
 | 		}); ok { | 
 | 			vendorVariants = append(vendorVariants, snapshot.version()) | 
 | 		} else { | 
 | 			mctx.ModuleErrorf("version is unknown for snapshot prebuilt") | 
 | 		} | 
 | 	} else if m.HasVendorVariant() && !m.isVndkExt() { | 
 | 		// This will be available in /system, /vendor and /product | 
 | 		// or a /system directory that is available to vendor and product. | 
 | 		coreVariantNeeded = true | 
 | 		vendorVariants = append(vendorVariants, platformVndkVersion) | 
 | 		productVariants = append(productVariants, platformVndkVersion) | 
 | 		// VNDK modules must not create BOARD_VNDK_VERSION variant because its | 
 | 		// code is PLATFORM_VNDK_VERSION. | 
 | 		// On the other hand, vendor_available modules which are not VNDK should | 
 | 		// also build BOARD_VNDK_VERSION because it's installed in /vendor. | 
 | 		// vendor_available modules are also available to /product. | 
 | 		if !m.IsVndk() { | 
 | 			vendorVariants = append(vendorVariants, boardVndkVersion) | 
 | 			productVariants = append(productVariants, productVndkVersion) | 
 | 		} | 
 | 	} else if vendorSpecific && String(m.Properties.Sdk_version) == "" { | 
 | 		// This will be available in /vendor (or /odm) only | 
 | 		vendorVariants = append(vendorVariants, boardVndkVersion) | 
 | 	} else { | 
 | 		// This is either in /system (or similar: /data), or is a | 
 | 		// modules built with the NDK. Modules built with the NDK | 
 | 		// will be restricted using the existing link type checks. | 
 | 		coreVariantNeeded = true | 
 | 	} | 
 |  | 
 | 	if boardVndkVersion != "" && productVndkVersion != "" { | 
 | 		if coreVariantNeeded && productSpecific && String(m.Properties.Sdk_version) == "" { | 
 | 			// The module has "product_specific: true" that does not create core variant. | 
 | 			coreVariantNeeded = false | 
 | 			productVariants = append(productVariants, productVndkVersion) | 
 | 		} | 
 | 	} else { | 
 | 		// Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no | 
 | 		// restriction to use system libs. | 
 | 		// No product variants defined in this case. | 
 | 		productVariants = []string{} | 
 | 	} | 
 |  | 
 | 	if Bool(m.Properties.Ramdisk_available) { | 
 | 		ramdiskVariantNeeded = true | 
 | 	} | 
 |  | 
 | 	if m.ModuleBase.InstallInRamdisk() { | 
 | 		ramdiskVariantNeeded = true | 
 | 		coreVariantNeeded = false | 
 | 	} | 
 |  | 
 | 	if Bool(m.Properties.Recovery_available) { | 
 | 		recoveryVariantNeeded = true | 
 | 	} | 
 |  | 
 | 	if m.ModuleBase.InstallInRecovery() { | 
 | 		recoveryVariantNeeded = true | 
 | 		coreVariantNeeded = false | 
 | 	} | 
 |  | 
 | 	for _, variant := range android.FirstUniqueStrings(vendorVariants) { | 
 | 		m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, VendorVariationPrefix+variant) | 
 | 	} | 
 |  | 
 | 	for _, variant := range android.FirstUniqueStrings(productVariants) { | 
 | 		m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, ProductVariationPrefix+variant) | 
 | 	} | 
 |  | 
 | 	m.Properties.RamdiskVariantNeeded = ramdiskVariantNeeded | 
 | 	m.Properties.RecoveryVariantNeeded = recoveryVariantNeeded | 
 | 	m.Properties.CoreVariantNeeded = coreVariantNeeded | 
 | } | 
 |  | 
 | func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool { | 
 | 	return c.Properties.CoreVariantNeeded | 
 | } | 
 |  | 
 | func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { | 
 | 	return c.Properties.RamdiskVariantNeeded | 
 | } | 
 |  | 
 | func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { | 
 | 	return c.Properties.RecoveryVariantNeeded | 
 | } | 
 |  | 
 | func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string { | 
 | 	return c.Properties.ExtraVariants | 
 | } | 
 |  | 
 | func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) { | 
 | 	m := module.(*Module) | 
 | 	if variant == android.RamdiskVariation { | 
 | 		m.MakeAsPlatform() | 
 | 	} else if variant == android.RecoveryVariation { | 
 | 		m.MakeAsPlatform() | 
 | 		squashRecoverySrcs(m) | 
 | 	} else if strings.HasPrefix(variant, VendorVariationPrefix) { | 
 | 		m.Properties.ImageVariationPrefix = VendorVariationPrefix | 
 | 		m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix) | 
 | 		squashVendorSrcs(m) | 
 |  | 
 | 		// Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION. | 
 | 		// Hide other vendor variants to avoid collision. | 
 | 		vndkVersion := ctx.DeviceConfig().VndkVersion() | 
 | 		if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion { | 
 | 			m.Properties.HideFromMake = true | 
 | 			m.SkipInstall() | 
 | 		} | 
 | 	} else if strings.HasPrefix(variant, ProductVariationPrefix) { | 
 | 		m.Properties.ImageVariationPrefix = ProductVariationPrefix | 
 | 		m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix) | 
 | 		squashVendorSrcs(m) | 
 | 	} | 
 | } | 
 |  | 
 | func getCurrentNdkPrebuiltVersion(ctx DepsContext) string { | 
 | 	if ctx.Config().PlatformSdkVersionInt() > config.NdkMaxPrebuiltVersionInt { | 
 | 		return strconv.Itoa(config.NdkMaxPrebuiltVersionInt) | 
 | 	} | 
 | 	return ctx.Config().PlatformSdkVersion() | 
 | } | 
 |  | 
 | func kytheExtractAllFactory() android.Singleton { | 
 | 	return &kytheExtractAllSingleton{} | 
 | } | 
 |  | 
 | type kytheExtractAllSingleton struct { | 
 | } | 
 |  | 
 | func (ks *kytheExtractAllSingleton) GenerateBuildActions(ctx android.SingletonContext) { | 
 | 	var xrefTargets android.Paths | 
 | 	ctx.VisitAllModules(func(module android.Module) { | 
 | 		if ccModule, ok := module.(xref); ok { | 
 | 			xrefTargets = append(xrefTargets, ccModule.XrefCcFiles()...) | 
 | 		} | 
 | 	}) | 
 | 	// TODO(asmundak): Perhaps emit a rule to output a warning if there were no xrefTargets | 
 | 	if len(xrefTargets) > 0 { | 
 | 		ctx.Build(pctx, android.BuildParams{ | 
 | 			Rule:   blueprint.Phony, | 
 | 			Output: android.PathForPhony(ctx, "xref_cxx"), | 
 | 			Inputs: xrefTargets, | 
 | 			//Default: true, | 
 | 		}) | 
 | 	} | 
 | } | 
 |  | 
 | var Bool = proptools.Bool | 
 | var BoolDefault = proptools.BoolDefault | 
 | var BoolPtr = proptools.BoolPtr | 
 | var String = proptools.String | 
 | var StringPtr = proptools.StringPtr |