|  | // 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" | 
|  |  | 
|  | "android/soong/testing" | 
|  | "github.com/google/blueprint" | 
|  | "github.com/google/blueprint/proptools" | 
|  |  | 
|  | "android/soong/aidl_library" | 
|  | "android/soong/android" | 
|  | "android/soong/cc/config" | 
|  | "android/soong/fuzz" | 
|  | "android/soong/genrule" | 
|  | "android/soong/multitree" | 
|  | "android/soong/snapshot" | 
|  | ) | 
|  |  | 
|  | func init() { | 
|  | RegisterCCBuildComponents(android.InitRegistrationContext) | 
|  |  | 
|  | pctx.Import("android/soong/android") | 
|  | 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("test_per_src", TestPerSrcMutator).Parallel() | 
|  | ctx.BottomUp("version", versionMutator).Parallel() | 
|  | ctx.BottomUp("begin", BeginMutator).Parallel() | 
|  | ctx.BottomUp("fdo_profile", fdoProfileMutator) | 
|  | }) | 
|  |  | 
|  | ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { | 
|  | for _, san := range Sanitizers { | 
|  | san.registerMutators(ctx) | 
|  | } | 
|  |  | 
|  | ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel() | 
|  | ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel() | 
|  |  | 
|  | ctx.TopDown("fuzz_deps", fuzzMutatorDeps) | 
|  |  | 
|  | ctx.BottomUp("coverage", coverageMutator).Parallel() | 
|  |  | 
|  | ctx.TopDown("afdo_deps", afdoDepsMutator) | 
|  | ctx.BottomUp("afdo", afdoMutator).Parallel() | 
|  |  | 
|  | ctx.TopDown("orderfile_deps", orderfileDepsMutator) | 
|  | ctx.BottomUp("orderfile", orderfileMutator).Parallel() | 
|  |  | 
|  | ctx.TopDown("lto_deps", ltoDepsMutator) | 
|  | ctx.BottomUp("lto", ltoMutator).Parallel() | 
|  |  | 
|  | ctx.BottomUp("check_linktype", checkLinkTypeMutator).Parallel() | 
|  | ctx.TopDown("double_loadable", checkDoubleLoadableLibraries).Parallel() | 
|  | }) | 
|  |  | 
|  | ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { | 
|  | // sabi mutator needs to be run after apex mutator finishes. | 
|  | ctx.TopDown("sabi_deps", sabiDepsMutator) | 
|  | }) | 
|  |  | 
|  | ctx.RegisterParallelSingletonType("kythe_extract_all", kytheExtractAllFactory) | 
|  | } | 
|  |  | 
|  | // Deps is a struct containing module names of dependencies, separated by the kind of dependency. | 
|  | // Mutators should use `AddVariationDependencies` or its sibling methods to add actual dependency | 
|  | // edges to these modules. | 
|  | // This object is constructed in DepsMutator, by calling to various module delegates to set | 
|  | // relevant fields. For example, `module.compiler.compilerDeps()` may append type-specific | 
|  | // dependencies. | 
|  | // This is then consumed by the same DepsMutator, which will call `ctx.AddVariationDependencies()` | 
|  | // (or its sibling methods) to set real dependencies on the given modules. | 
|  | type Deps struct { | 
|  | SharedLibs, LateSharedLibs                  []string | 
|  | StaticLibs, LateStaticLibs, WholeStaticLibs []string | 
|  | HeaderLibs                                  []string | 
|  | RuntimeLibs                                 []string | 
|  |  | 
|  | // UnexportedStaticLibs are static libraries that are also passed to -Wl,--exclude-libs= to | 
|  | // prevent automatically exporting symbols. | 
|  | UnexportedStaticLibs []string | 
|  |  | 
|  | // Used for data dependencies adjacent to tests | 
|  | DataLibs []string | 
|  | DataBins []string | 
|  |  | 
|  | // Used by DepsMutator to pass system_shared_libs information to check_elf_file.py. | 
|  | SystemSharedLibs []string | 
|  |  | 
|  | // Used by DepMutator to pass aidl_library modules to aidl compiler | 
|  | AidlLibs []string | 
|  |  | 
|  | // If true, statically link the unwinder into native libraries/binaries. | 
|  | StaticUnwinderIfLegacy bool | 
|  |  | 
|  | ReexportSharedLibHeaders, ReexportStaticLibHeaders, ReexportHeaderLibHeaders []string | 
|  |  | 
|  | ObjFiles []string | 
|  |  | 
|  | GeneratedSources []string | 
|  | GeneratedHeaders []string | 
|  | GeneratedDeps    []string | 
|  |  | 
|  | ReexportGeneratedHeaders []string | 
|  |  | 
|  | CrtBegin, CrtEnd []string | 
|  |  | 
|  | // Used for host bionic | 
|  | DynamicLinker string | 
|  |  | 
|  | // List of libs that need to be excluded for APEX variant | 
|  | ExcludeLibsForApex []string | 
|  | // List of libs that need to be excluded for non-APEX variant | 
|  | ExcludeLibsForNonApex []string | 
|  | } | 
|  |  | 
|  | // PathDeps is a struct containing file paths to dependencies of a module. | 
|  | // It's constructed in depsToPath() by traversing the direct dependencies of the current module. | 
|  | // It's used to construct flags for various build statements (such as for compiling and linking). | 
|  | // It is then passed to module decorator functions responsible for registering build statements | 
|  | // (such as `module.compiler.compile()`).` | 
|  | 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 | 
|  |  | 
|  | // Transitive static library dependencies of static libraries for use in ordering. | 
|  | TranstiveStaticLibrariesForOrdering *android.DepSet[android.Path] | 
|  |  | 
|  | // Paths to .o files | 
|  | Objs Objects | 
|  | // Paths to .o files in dependencies that provide them. Note that these lists | 
|  | // aren't complete since prebuilt modules don't provide the .o files. | 
|  | StaticLibObjs      Objects | 
|  | WholeStaticLibObjs Objects | 
|  |  | 
|  | // Paths to .a files in prebuilts. Complements WholeStaticLibObjs to contain | 
|  | // the libs from all whole_static_lib dependencies. | 
|  | WholeStaticLibsFromPrebuilts android.Paths | 
|  |  | 
|  | // Paths to generated source files | 
|  | GeneratedSources android.Paths | 
|  | GeneratedDeps    android.Paths | 
|  |  | 
|  | Flags                      []string | 
|  | LdFlags                    []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.Paths | 
|  |  | 
|  | // Path to the dynamic linker binary | 
|  | DynamicLinker android.OptionalPath | 
|  |  | 
|  | // For Darwin builds, the path to the second architecture's output that should | 
|  | // be combined with this architectures's output into a FAT MachO file. | 
|  | DarwinSecondArchOutput android.OptionalPath | 
|  |  | 
|  | // Paths to direct srcs and transitive include dirs from direct aidl_library deps | 
|  | AidlLibraryInfos []aidl_library.AidlLibraryInfo | 
|  | } | 
|  |  | 
|  | // 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 | 
|  | } | 
|  |  | 
|  | // Flags contains various types of command line flags (and settings) for use in building build | 
|  | // statements related to C++. | 
|  | type Flags struct { | 
|  | // Local flags (which individual modules are responsible for). These may override global flags. | 
|  | Local LocalOrGlobalFlags | 
|  | // Global flags (which build system or toolchain is responsible for). | 
|  | 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 // True if ninja .tidy rules should be generated. | 
|  | NeedTidyFiles bool // True if module link should depend on .tidy files | 
|  | GcovCoverage  bool // True if coverage files should be generated. | 
|  | SAbiDump      bool // True if header abi dumps should be generated. | 
|  | EmitXrefs     bool // If true, generate Ninja rules to generate emitXrefs input files for Kythe | 
|  |  | 
|  | // The instruction set required for clang ("arm" or "thumb"). | 
|  | RequiredInstructionSet string | 
|  | // The target-device system path to the dynamic linker. | 
|  | DynamicLinker string | 
|  |  | 
|  | CFlagsDeps  android.Paths // Files depended on by compiler flags | 
|  | LdFlagsDeps android.Paths // Files depended on by linker flags | 
|  |  | 
|  | // True if .s files should be processed with the c preprocessor. | 
|  | AssemblerWithCpp 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 | 
|  | Lex  *LexProperties | 
|  | } | 
|  |  | 
|  | // 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"` | 
|  |  | 
|  | // The API level that this module is built against. The APIs of this API level will be | 
|  | // visible at build time, but use of any APIs newer than min_sdk_version will render the | 
|  | // module unloadable on older devices.  In the future it will be possible to weakly-link new | 
|  | // APIs, making the behavior match Java: such modules will load on older devices, but | 
|  | // calling new APIs on devices that do not support them will result in a crash. | 
|  | // | 
|  | // This property has the same behavior as sdk_version does for Java modules. For those | 
|  | // familiar with Android Gradle, the property behaves similarly to how compileSdkVersion | 
|  | // does for Java code. | 
|  | // | 
|  | // In addition, setting this property causes two variants to be built, one for the platform | 
|  | // and one for apps. | 
|  | Sdk_version *string | 
|  |  | 
|  | // Minimum OS API level supported by this C or C++ module. This property becomes the value | 
|  | // of the __ANDROID_API__ macro. When the C or C++ module is included in an APEX or an APK, | 
|  | // this property is also used to ensure that the min_sdk_version of the containing module is | 
|  | // not older (i.e. less) than this module's min_sdk_version. When not set, this property | 
|  | // defaults to the value of sdk_version.  When this is set to "apex_inherit", this tracks | 
|  | // min_sdk_version of the containing APEX. When the module | 
|  | // is not built for an APEX, "apex_inherit" defaults to sdk_version. | 
|  | 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"` | 
|  |  | 
|  | // Set by DepsMutator. | 
|  | AndroidMkSystemSharedLibs []string `blueprint:"mutated"` | 
|  |  | 
|  | // The name of the image this module is built for, suffixed with a '.' | 
|  | ImageVariationPrefix string `blueprint:"mutated"` | 
|  |  | 
|  | // The VNDK version this module is built against. If empty, the module is not | 
|  | // build against the VNDK. | 
|  | VndkVersion string `blueprint:"mutated"` | 
|  |  | 
|  | // Suffix for the name of Android.mk entries generated by this module | 
|  | 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. | 
|  | // On device without a dedicated recovery partition, the module is only | 
|  | // available after switching root into | 
|  | // /first_stage_ramdisk. To expose the module before switching root, install | 
|  | // the recovery variant instead. | 
|  | Ramdisk_available *bool | 
|  |  | 
|  | // Make this module available when building for vendor ramdisk. | 
|  | // On device without a dedicated recovery partition, the module is only | 
|  | // available after switching root into | 
|  | // /first_stage_ramdisk. To expose the module before switching root, install | 
|  | // the recovery variant instead. | 
|  | Vendor_ramdisk_available *bool | 
|  |  | 
|  | // Make this module available when building for recovery | 
|  | Recovery_available *bool | 
|  |  | 
|  | // Used by imageMutator, set by ImageMutatorBegin() | 
|  | CoreVariantNeeded          bool `blueprint:"mutated"` | 
|  | RamdiskVariantNeeded       bool `blueprint:"mutated"` | 
|  | VendorRamdiskVariantNeeded bool `blueprint:"mutated"` | 
|  | RecoveryVariantNeeded      bool `blueprint:"mutated"` | 
|  |  | 
|  | // A list of variations for the "image" mutator of the form | 
|  | //<image name> '.' <version char>, for example, 'vendor.S' | 
|  | ExtraVersionedImageVariations []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"` | 
|  | SnapshotStaticLibs  []string `blueprint:"mutated"` | 
|  | SnapshotRuntimeLibs []string `blueprint:"mutated"` | 
|  |  | 
|  | Installable *bool `android:"arch_variant"` | 
|  |  | 
|  | // 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"` | 
|  |  | 
|  | // Normally Soong uses the directory structure to decide which modules | 
|  | // should be included (framework) or excluded (non-framework) from the | 
|  | // different snapshots (vendor, recovery, etc.), but this property | 
|  | // allows a partner to exclude a module normally thought of as a | 
|  | // framework module from the vendor snapshot. | 
|  | Exclude_from_vendor_snapshot *bool | 
|  |  | 
|  | // Normally Soong uses the directory structure to decide which modules | 
|  | // should be included (framework) or excluded (non-framework) from the | 
|  | // different snapshots (vendor, recovery, etc.), but this property | 
|  | // allows a partner to exclude a module normally thought of as a | 
|  | // framework module from the recovery snapshot. | 
|  | Exclude_from_recovery_snapshot *bool | 
|  |  | 
|  | // List of APEXes that this module has private access to for testing purpose. The module | 
|  | // can depend on libraries that are not exported by the APEXes and use private symbols | 
|  | // from the exported libraries. | 
|  | Test_for []string `android:"arch_variant"` | 
|  |  | 
|  | Target struct { | 
|  | Platform struct { | 
|  | // List of modules required by the core variant. | 
|  | Required []string `android:"arch_variant"` | 
|  |  | 
|  | // List of modules not required by the core variant. | 
|  | Exclude_required []string `android:"arch_variant"` | 
|  | } `android:"arch_variant"` | 
|  |  | 
|  | Recovery struct { | 
|  | // List of modules required by the recovery variant. | 
|  | Required []string `android:"arch_variant"` | 
|  |  | 
|  | // List of modules not required by the recovery variant. | 
|  | Exclude_required []string `android:"arch_variant"` | 
|  | } `android:"arch_variant"` | 
|  | } `android:"arch_variant"` | 
|  | } | 
|  |  | 
|  | 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`. | 
|  | // If set to true, two variants will be built separately, one like | 
|  | // normal, and the other limited to the set of libraries and headers | 
|  | // that are exposed to /vendor modules. | 
|  | // | 
|  | // The vendor variant 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 modules. | 
|  | // | 
|  | // The modules with vndk: {enabled: true} must define 'vendor_available' | 
|  | // to 'true'. | 
|  | // | 
|  | // Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk | 
|  | Vendor_available *bool | 
|  |  | 
|  | // This is the same as the "vendor_available" except that the install path | 
|  | // of the vendor variant is /odm or /vendor/odm. | 
|  | // By replacing "vendor_available: true" with "odm_available: true", the | 
|  | // module will install its vendor variant to the /odm partition or /vendor/odm. | 
|  | // As the modules with "odm_available: true" still create the vendor variants, | 
|  | // they can link to the other vendor modules as the vendor_available modules do. | 
|  | // Also, the vendor modules can link to odm_available modules. | 
|  | // | 
|  | // It may not be used for VNDK modules. | 
|  | Odm_available *bool | 
|  |  | 
|  | // whether this module should be allowed to be directly depended by other | 
|  | // modules with `product_specific: true` or `product_available: true`. | 
|  | // If set to true, an additional product variant will be built separately | 
|  | // that is limited to the set of libraries and headers that are exposed to | 
|  | // /product modules. | 
|  | // | 
|  | // The product variant 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 /product modules. | 
|  | // | 
|  | // Different from the 'vendor_available' property, the modules with | 
|  | // vndk: {enabled: true} don't have to define 'product_available'. The VNDK | 
|  | // library without 'product_available' may not be depended on by any other | 
|  | // modules that has product variants including the product available VNDKs. | 
|  | // | 
|  | // Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk | 
|  | // and PRODUCT_PRODUCT_VNDK_VERSION isn't set. | 
|  | Product_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 | 
|  |  | 
|  | // IsLLNDK is set to true for the vendor variant of a cc_library module that has LLNDK stubs. | 
|  | IsLLNDK bool `blueprint:"mutated"` | 
|  |  | 
|  | // IsVNDKUsingCoreVariant is true for VNDK modules if the global VndkUseCoreVariant option is | 
|  | // set and the module is not listed in VndkMustUseVendorVariantList. | 
|  | IsVNDKUsingCoreVariant bool `blueprint:"mutated"` | 
|  |  | 
|  | // IsVNDKCore is set if a VNDK module does not set the vndk.support_system_process property. | 
|  | IsVNDKCore bool `blueprint:"mutated"` | 
|  |  | 
|  | // IsVNDKSP is set if a VNDK module sets the vndk.support_system_process property. | 
|  | IsVNDKSP bool `blueprint:"mutated"` | 
|  |  | 
|  | // IsVNDKPrivate is set if a VNDK module sets the vndk.private property or an LLNDK | 
|  | // module sets the llndk.private property. | 
|  | IsVNDKPrivate bool `blueprint:"mutated"` | 
|  |  | 
|  | // IsVNDKProduct is set if a VNDK module sets the product_available property. | 
|  | IsVNDKProduct bool `blueprint:"mutated"` | 
|  |  | 
|  | // IsVendorPublicLibrary is set for the core and product variants of a library that has | 
|  | // vendor_public_library stubs. | 
|  | IsVendorPublicLibrary bool `blueprint:"mutated"` | 
|  | } | 
|  |  | 
|  | // ModuleContextIntf is an interface (on a module context helper) consisting of functions related | 
|  | // to understanding  details about the type of the current module. | 
|  | // For example, one might call these functions to determine whether the current module is a static | 
|  | // library and/or is installed in vendor directories. | 
|  | type ModuleContextIntf interface { | 
|  | static() bool | 
|  | staticBinary() bool | 
|  | testBinary() bool | 
|  | testLibrary() bool | 
|  | header() bool | 
|  | binary() bool | 
|  | object() bool | 
|  | toolchain() config.Toolchain | 
|  | canUseSdk() bool | 
|  | useSdk() bool | 
|  | sdkVersion() string | 
|  | minSdkVersion() string | 
|  | isSdkVariant() bool | 
|  | useVndk() bool | 
|  | isNdk(config android.Config) bool | 
|  | IsLlndk() bool | 
|  | IsLlndkPublic() bool | 
|  | isImplementationForLLNDKPublic() bool | 
|  | IsVndkPrivate() bool | 
|  | isVndk() bool | 
|  | isVndkSp() bool | 
|  | IsVndkExt() bool | 
|  | IsVendorPublicLibrary() bool | 
|  | inProduct() bool | 
|  | inVendor() bool | 
|  | inRamdisk() bool | 
|  | inVendorRamdisk() bool | 
|  | inRecovery() bool | 
|  | selectedStl() string | 
|  | baseModuleName() string | 
|  | getVndkExtendsModuleName() string | 
|  | isAfdoCompile() bool | 
|  | isOrderfileCompile() bool | 
|  | isCfi() bool | 
|  | isFuzzer() bool | 
|  | isNDKStubLibrary() bool | 
|  | useClangLld(actx ModuleContext) bool | 
|  | isForPlatform() bool | 
|  | apexVariationName() string | 
|  | apexSdkVersion() android.ApiLevel | 
|  | bootstrap() bool | 
|  | mustUseVendorVariant() bool | 
|  | nativeCoverage() bool | 
|  | directlyInAnyApex() bool | 
|  | isPreventInstall() bool | 
|  | isCfiAssemblySupportEnabled() bool | 
|  | getSharedFlags() *SharedFlags | 
|  | notInPlatform() bool | 
|  | } | 
|  |  | 
|  | type SharedFlags struct { | 
|  | numSharedFlags int | 
|  | flagsMap       map[string]string | 
|  | } | 
|  |  | 
|  | type ModuleContext interface { | 
|  | android.ModuleContext | 
|  | ModuleContextIntf | 
|  | } | 
|  |  | 
|  | type BaseModuleContext interface { | 
|  | android.BaseModuleContext | 
|  | ModuleContextIntf | 
|  | } | 
|  |  | 
|  | type DepsContext interface { | 
|  | android.BottomUpMutatorContext | 
|  | ModuleContextIntf | 
|  | } | 
|  |  | 
|  | // feature represents additional (optional) steps to building cc-related modules, such as invocation | 
|  | // of clang-tidy. | 
|  | type feature interface { | 
|  | flags(ctx ModuleContext, flags Flags) Flags | 
|  | props() []interface{} | 
|  | } | 
|  |  | 
|  | // Information returned from Generator about the source code it's generating | 
|  | type GeneratedSource struct { | 
|  | IncludeDirs    android.Paths | 
|  | Sources        android.Paths | 
|  | Headers        android.Paths | 
|  | ReexportedDirs android.Paths | 
|  | } | 
|  |  | 
|  | // generator allows injection of generated code | 
|  | type Generator interface { | 
|  | GeneratorProps() []interface{} | 
|  | GeneratorInit(ctx BaseModuleContext) | 
|  | GeneratorDeps(ctx DepsContext, deps Deps) Deps | 
|  | GeneratorFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags | 
|  | GeneratorSources(ctx ModuleContext) GeneratedSource | 
|  | GeneratorBuildActions(ctx ModuleContext, flags Flags, deps PathDeps) | 
|  | } | 
|  |  | 
|  | // compiler is the interface for a compiler helper object. Different module decorators may implement | 
|  | // this helper differently. | 
|  | 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 | 
|  | } | 
|  |  | 
|  | // linker is the interface for a linker decorator object. Individual module types can provide | 
|  | // their own implementation for this decorator, and thus specify custom logic regarding build | 
|  | // statements pertaining to linking. | 
|  | 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 | 
|  | strippedAllOutputFilePath() android.Path | 
|  |  | 
|  | nativeCoverage() bool | 
|  | coverageOutputFilePath() android.OptionalPath | 
|  |  | 
|  | // Get the deps that have been explicitly specified in the properties. | 
|  | linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps | 
|  |  | 
|  | moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) | 
|  | } | 
|  |  | 
|  | // specifiedDeps is a tuple struct representing dependencies of a linked binary owned by the linker. | 
|  | type specifiedDeps struct { | 
|  | sharedLibs []string | 
|  | // Note nil and [] are semantically distinct. [] prevents linking against the defaults (usually | 
|  | // libc, libm, etc.) | 
|  | systemSharedLibs []string | 
|  | } | 
|  |  | 
|  | // installer is the interface for an installer helper object. This helper is responsible for | 
|  | // copying build outputs to the appropriate locations so that they may be installed on device. | 
|  | type installer interface { | 
|  | installerProps() []interface{} | 
|  | install(ctx ModuleContext, path android.Path) | 
|  | everInstallable() bool | 
|  | inData() bool | 
|  | inSanitizerDir() bool | 
|  | hostToolPath() android.OptionalPath | 
|  | relativeInstallPath() string | 
|  | makeUninstallable(mod *Module) | 
|  | installInRoot() bool | 
|  | } | 
|  |  | 
|  | type xref interface { | 
|  | XrefCcFiles() android.Paths | 
|  | } | 
|  |  | 
|  | type overridable interface { | 
|  | overriddenModules() []string | 
|  | } | 
|  |  | 
|  | type libraryDependencyKind int | 
|  |  | 
|  | const ( | 
|  | headerLibraryDependency = iota | 
|  | sharedLibraryDependency | 
|  | staticLibraryDependency | 
|  | ) | 
|  |  | 
|  | func (k libraryDependencyKind) String() string { | 
|  | switch k { | 
|  | case headerLibraryDependency: | 
|  | return "headerLibraryDependency" | 
|  | case sharedLibraryDependency: | 
|  | return "sharedLibraryDependency" | 
|  | case staticLibraryDependency: | 
|  | return "staticLibraryDependency" | 
|  | default: | 
|  | panic(fmt.Errorf("unknown libraryDependencyKind %d", k)) | 
|  | } | 
|  | } | 
|  |  | 
|  | type libraryDependencyOrder int | 
|  |  | 
|  | const ( | 
|  | earlyLibraryDependency  = -1 | 
|  | normalLibraryDependency = 0 | 
|  | lateLibraryDependency   = 1 | 
|  | ) | 
|  |  | 
|  | func (o libraryDependencyOrder) String() string { | 
|  | switch o { | 
|  | case earlyLibraryDependency: | 
|  | return "earlyLibraryDependency" | 
|  | case normalLibraryDependency: | 
|  | return "normalLibraryDependency" | 
|  | case lateLibraryDependency: | 
|  | return "lateLibraryDependency" | 
|  | default: | 
|  | panic(fmt.Errorf("unknown libraryDependencyOrder %d", o)) | 
|  | } | 
|  | } | 
|  |  | 
|  | // libraryDependencyTag is used to tag dependencies on libraries.  Unlike many dependency | 
|  | // tags that have a set of predefined tag objects that are reused for each dependency, a | 
|  | // libraryDependencyTag is designed to contain extra metadata and is constructed as needed. | 
|  | // That means that comparing a libraryDependencyTag for equality will only be equal if all | 
|  | // of the metadata is equal.  Most usages will want to type assert to libraryDependencyTag and | 
|  | // then check individual metadata fields instead. | 
|  | type libraryDependencyTag struct { | 
|  | blueprint.BaseDependencyTag | 
|  |  | 
|  | // These are exported so that fmt.Printf("%#v") can call their String methods. | 
|  | Kind  libraryDependencyKind | 
|  | Order libraryDependencyOrder | 
|  |  | 
|  | wholeStatic bool | 
|  |  | 
|  | reexportFlags       bool | 
|  | explicitlyVersioned bool | 
|  | dataLib             bool | 
|  | ndk                 bool | 
|  |  | 
|  | staticUnwinder bool | 
|  |  | 
|  | makeSuffix string | 
|  |  | 
|  | // Whether or not this dependency should skip the apex dependency check | 
|  | skipApexAllowedDependenciesCheck bool | 
|  |  | 
|  | // Whether or not this dependency has to be followed for the apex variants | 
|  | excludeInApex bool | 
|  | // Whether or not this dependency has to be followed for the non-apex variants | 
|  | excludeInNonApex bool | 
|  |  | 
|  | // If true, don't automatically export symbols from the static library into a shared library. | 
|  | unexportedSymbols bool | 
|  | } | 
|  |  | 
|  | // header returns true if the libraryDependencyTag is tagging a header lib dependency. | 
|  | func (d libraryDependencyTag) header() bool { | 
|  | return d.Kind == headerLibraryDependency | 
|  | } | 
|  |  | 
|  | // shared returns true if the libraryDependencyTag is tagging a shared lib dependency. | 
|  | func (d libraryDependencyTag) shared() bool { | 
|  | return d.Kind == sharedLibraryDependency | 
|  | } | 
|  |  | 
|  | // shared returns true if the libraryDependencyTag is tagging a static lib dependency. | 
|  | func (d libraryDependencyTag) static() bool { | 
|  | return d.Kind == staticLibraryDependency | 
|  | } | 
|  |  | 
|  | func (d libraryDependencyTag) LicenseAnnotations() []android.LicenseAnnotation { | 
|  | if d.shared() { | 
|  | return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency} | 
|  | } | 
|  | return nil | 
|  | } | 
|  |  | 
|  | var _ android.LicenseAnnotationsDependencyTag = libraryDependencyTag{} | 
|  |  | 
|  | // InstallDepNeeded returns true for shared libraries so that shared library dependencies of | 
|  | // binaries or other shared libraries are installed as dependencies. | 
|  | func (d libraryDependencyTag) InstallDepNeeded() bool { | 
|  | return d.shared() | 
|  | } | 
|  |  | 
|  | var _ android.InstallNeededDependencyTag = libraryDependencyTag{} | 
|  |  | 
|  | // dependencyTag is used for tagging miscellaneous dependency types that don't fit into | 
|  | // libraryDependencyTag.  Each tag object is created globally and reused for multiple | 
|  | // dependencies (although since the object contains no references, assigning a tag to a | 
|  | // variable and modifying it will not modify the original).  Users can compare the tag | 
|  | // returned by ctx.OtherModuleDependencyTag against the global original | 
|  | type dependencyTag struct { | 
|  | blueprint.BaseDependencyTag | 
|  | name string | 
|  | } | 
|  |  | 
|  | // installDependencyTag is used for tagging miscellaneous dependency types that don't fit into | 
|  | // libraryDependencyTag, but where the dependency needs to be installed when the parent is | 
|  | // installed. | 
|  | type installDependencyTag struct { | 
|  | blueprint.BaseDependencyTag | 
|  | android.InstallAlwaysNeededDependencyTag | 
|  | name string | 
|  | } | 
|  |  | 
|  | var ( | 
|  | genSourceDepTag       = dependencyTag{name: "gen source"} | 
|  | genHeaderDepTag       = dependencyTag{name: "gen header"} | 
|  | genHeaderExportDepTag = dependencyTag{name: "gen header export"} | 
|  | objDepTag             = dependencyTag{name: "obj"} | 
|  | dynamicLinkerDepTag   = installDependencyTag{name: "dynamic linker"} | 
|  | reuseObjTag           = dependencyTag{name: "reuse objects"} | 
|  | staticVariantTag      = dependencyTag{name: "static variant"} | 
|  | vndkExtDepTag         = dependencyTag{name: "vndk extends"} | 
|  | dataLibDepTag         = dependencyTag{name: "data lib"} | 
|  | dataBinDepTag         = dependencyTag{name: "data bin"} | 
|  | runtimeDepTag         = installDependencyTag{name: "runtime lib"} | 
|  | testPerSrcDepTag      = dependencyTag{name: "test_per_src"} | 
|  | stubImplDepTag        = dependencyTag{name: "stub_impl"} | 
|  | JniFuzzLibTag         = dependencyTag{name: "jni_fuzz_lib_tag"} | 
|  | FdoProfileTag         = dependencyTag{name: "fdo_profile"} | 
|  | aidlLibraryTag        = dependencyTag{name: "aidl_library"} | 
|  | ) | 
|  |  | 
|  | func IsSharedDepTag(depTag blueprint.DependencyTag) bool { | 
|  | ccLibDepTag, ok := depTag.(libraryDependencyTag) | 
|  | return ok && ccLibDepTag.shared() | 
|  | } | 
|  |  | 
|  | func IsStaticDepTag(depTag blueprint.DependencyTag) bool { | 
|  | ccLibDepTag, ok := depTag.(libraryDependencyTag) | 
|  | return ok && ccLibDepTag.static() | 
|  | } | 
|  |  | 
|  | func IsHeaderDepTag(depTag blueprint.DependencyTag) bool { | 
|  | ccLibDepTag, ok := depTag.(libraryDependencyTag) | 
|  | return ok && ccLibDepTag.header() | 
|  | } | 
|  |  | 
|  | func IsRuntimeDepTag(depTag blueprint.DependencyTag) bool { | 
|  | return depTag == 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, or "decorator", | 
|  | // interface. | 
|  | // | 
|  | // To define a C/C++ related module, construct a new Module object and point its delegates to | 
|  | // type-specific structs. These delegates will be invoked to register module-specific build | 
|  | // statements which may be unique to the module type. For example, module.compiler.compile() should | 
|  | // be defined so as to register build statements which are responsible for compiling the module. | 
|  | // | 
|  | // Another example: to construct a cc_binary module, one can create a `cc.binaryDecorator` struct | 
|  | // which implements the `linker` and `installer` interfaces, and points the `linker` and `installer` | 
|  | // members of the cc.Module to this decorator. Thus, a cc_binary module has custom linker and | 
|  | // installer logic. | 
|  | type Module struct { | 
|  | fuzz.FuzzModule | 
|  |  | 
|  | VendorProperties VendorProperties | 
|  | Properties       BaseProperties | 
|  |  | 
|  | // initialize before calling Init | 
|  | hod        android.HostOrDeviceSupported | 
|  | multilib   android.Multilib | 
|  | testModule bool | 
|  |  | 
|  | // Allowable SdkMemberTypes of this module type. | 
|  | sdkMemberTypes []android.SdkMemberType | 
|  |  | 
|  | // decorator delegates, initialize before calling Init | 
|  | // these may contain module-specific implementations, and effectively allow for custom | 
|  | // type-specific logic. These members may reference different objects or the same object. | 
|  | // Functions of these decorators will be invoked to initialize and register type-specific | 
|  | // build statements. | 
|  | generators []Generator | 
|  | compiler   compiler | 
|  | linker     linker | 
|  | installer  installer | 
|  |  | 
|  | features  []feature | 
|  | stl       *stl | 
|  | sanitize  *sanitize | 
|  | coverage  *coverage | 
|  | fuzzer    *fuzzer | 
|  | sabi      *sabi | 
|  | vndkdep   *vndkdep | 
|  | lto       *lto | 
|  | afdo      *afdo | 
|  | orderfile *orderfile | 
|  |  | 
|  | library libraryInterface | 
|  |  | 
|  | outputFile android.OptionalPath | 
|  |  | 
|  | cachedToolchain config.Toolchain | 
|  |  | 
|  | subAndroidMkOnce map[subAndroidMkProvider]bool | 
|  |  | 
|  | // Flags used to compile this module | 
|  | flags Flags | 
|  |  | 
|  | // Shared flags among build rules of this module | 
|  | sharedFlags SharedFlags | 
|  |  | 
|  | // only non-nil when this is a shared library that reuses the objects of a static library | 
|  | staticAnalogue *StaticLibraryInfo | 
|  |  | 
|  | makeLinkType string | 
|  | // Kythe (source file indexer) paths for this compilation module | 
|  | kytheFiles android.Paths | 
|  | // Object .o file output paths for this compilation module | 
|  | objFiles android.Paths | 
|  | // Tidy .tidy file output paths for this compilation module | 
|  | tidyFiles android.Paths | 
|  |  | 
|  | // For apex variants, this is set as apex.min_sdk_version | 
|  | apexSdkVersion android.ApiLevel | 
|  |  | 
|  | hideApexVariantFromMake bool | 
|  |  | 
|  | // Aconfig files for all transitive deps.  Also exposed via TransitiveDeclarationsInfo | 
|  | mergedAconfigFiles map[string]android.Paths | 
|  | } | 
|  |  | 
|  | func (c *Module) AddJSONData(d *map[string]interface{}) { | 
|  | var hasAidl, hasLex, hasProto, hasRenderscript, hasSysprop, hasWinMsg, hasYacc bool | 
|  | if b, ok := c.compiler.(*baseCompiler); ok { | 
|  | hasAidl = b.hasSrcExt(".aidl") | 
|  | hasLex = b.hasSrcExt(".l") || b.hasSrcExt(".ll") | 
|  | hasProto = b.hasSrcExt(".proto") | 
|  | hasRenderscript = b.hasSrcExt(".rscript") || b.hasSrcExt(".fs") | 
|  | hasSysprop = b.hasSrcExt(".sysprop") | 
|  | hasWinMsg = b.hasSrcExt(".mc") | 
|  | hasYacc = b.hasSrcExt(".y") || b.hasSrcExt(".yy") | 
|  | } | 
|  | c.AndroidModuleBase().AddJSONData(d) | 
|  | (*d)["Cc"] = map[string]interface{}{ | 
|  | "SdkVersion":             c.SdkVersion(), | 
|  | "MinSdkVersion":          c.MinSdkVersion(), | 
|  | "VndkVersion":            c.VndkVersion(), | 
|  | "ProductSpecific":        c.ProductSpecific(), | 
|  | "SocSpecific":            c.SocSpecific(), | 
|  | "DeviceSpecific":         c.DeviceSpecific(), | 
|  | "InProduct":              c.InProduct(), | 
|  | "InVendor":               c.InVendor(), | 
|  | "InRamdisk":              c.InRamdisk(), | 
|  | "InVendorRamdisk":        c.InVendorRamdisk(), | 
|  | "InRecovery":             c.InRecovery(), | 
|  | "VendorAvailable":        c.VendorAvailable(), | 
|  | "ProductAvailable":       c.ProductAvailable(), | 
|  | "RamdiskAvailable":       c.RamdiskAvailable(), | 
|  | "VendorRamdiskAvailable": c.VendorRamdiskAvailable(), | 
|  | "RecoveryAvailable":      c.RecoveryAvailable(), | 
|  | "OdmAvailable":           c.OdmAvailable(), | 
|  | "InstallInData":          c.InstallInData(), | 
|  | "InstallInRamdisk":       c.InstallInRamdisk(), | 
|  | "InstallInSanitizerDir":  c.InstallInSanitizerDir(), | 
|  | "InstallInVendorRamdisk": c.InstallInVendorRamdisk(), | 
|  | "InstallInRecovery":      c.InstallInRecovery(), | 
|  | "InstallInRoot":          c.InstallInRoot(), | 
|  | "IsVndk":                 c.IsVndk(), | 
|  | "IsVndkExt":              c.IsVndkExt(), | 
|  | "IsVndkPrivate":          c.IsVndkPrivate(), | 
|  | "IsVndkSp":               c.IsVndkSp(), | 
|  | "IsLlndk":                c.IsLlndk(), | 
|  | "IsLlndkPublic":          c.IsLlndkPublic(), | 
|  | "IsSnapshotLibrary":      c.IsSnapshotLibrary(), | 
|  | "IsSnapshotPrebuilt":     c.IsSnapshotPrebuilt(), | 
|  | "IsVendorPublicLibrary":  c.IsVendorPublicLibrary(), | 
|  | "ApexSdkVersion":         c.apexSdkVersion, | 
|  | "TestFor":                c.TestFor(), | 
|  | "AidlSrcs":               hasAidl, | 
|  | "LexSrcs":                hasLex, | 
|  | "ProtoSrcs":              hasProto, | 
|  | "RenderscriptSrcs":       hasRenderscript, | 
|  | "SyspropSrcs":            hasSysprop, | 
|  | "WinMsgSrcs":             hasWinMsg, | 
|  | "YaccSrsc":               hasYacc, | 
|  | "OnlyCSrcs":              !(hasAidl || hasLex || hasProto || hasRenderscript || hasSysprop || hasWinMsg || hasYacc), | 
|  | } | 
|  | } | 
|  |  | 
|  | func (c *Module) SetPreventInstall() { | 
|  | c.Properties.PreventInstall = true | 
|  | } | 
|  |  | 
|  | func (c *Module) SetHideFromMake() { | 
|  | c.Properties.HideFromMake = true | 
|  | } | 
|  |  | 
|  | func (c *Module) HiddenFromMake() bool { | 
|  | return c.Properties.HideFromMake | 
|  | } | 
|  |  | 
|  | func (c *Module) RequiredModuleNames() []string { | 
|  | required := android.CopyOf(c.ModuleBase.RequiredModuleNames()) | 
|  | if c.ImageVariation().Variation == android.CoreVariation { | 
|  | required = append(required, c.Properties.Target.Platform.Required...) | 
|  | required = removeListFromList(required, c.Properties.Target.Platform.Exclude_required) | 
|  | } else if c.InRecovery() { | 
|  | required = append(required, c.Properties.Target.Recovery.Required...) | 
|  | required = removeListFromList(required, c.Properties.Target.Recovery.Exclude_required) | 
|  | } | 
|  | return android.FirstUniqueStrings(required) | 
|  | } | 
|  |  | 
|  | 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.apiLevel.String() | 
|  | } | 
|  | } | 
|  | 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) 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) isCrt() bool { | 
|  | if linker, ok := c.linker.(*objectLinker); ok { | 
|  | return linker.isCrt() | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) SplitPerApiLevel() bool { | 
|  | return c.canUseSdk() && c.isCrt() | 
|  | } | 
|  |  | 
|  | func (c *Module) AlwaysSdk() bool { | 
|  | return c.Properties.AlwaysSdk || Bool(c.Properties.Sdk_variant_only) | 
|  | } | 
|  |  | 
|  | func (c *Module) CcLibrary() bool { | 
|  | if c.linker != nil { | 
|  | if _, ok := c.linker.(*libraryDecorator); ok { | 
|  | return true | 
|  | } | 
|  | if _, ok := c.linker.(*prebuiltLibraryLinker); ok { | 
|  | return true | 
|  | } | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) CcLibraryInterface() bool { | 
|  | if _, ok := c.linker.(libraryInterface); ok { | 
|  | return true | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) IsNdkPrebuiltStl() bool { | 
|  | if c.linker == nil { | 
|  | return false | 
|  | } | 
|  | if _, ok := c.linker.(*ndkPrebuiltStlLinker); ok { | 
|  | return true | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) RlibStd() bool { | 
|  | panic(fmt.Errorf("RlibStd called on non-Rust module: %q", c.BaseModuleName())) | 
|  | } | 
|  |  | 
|  | func (c *Module) RustLibraryInterface() bool { | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) IsFuzzModule() bool { | 
|  | if _, ok := c.compiler.(*fuzzBinary); ok { | 
|  | return true | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) FuzzModuleStruct() fuzz.FuzzModule { | 
|  | return c.FuzzModule | 
|  | } | 
|  |  | 
|  | func (c *Module) FuzzPackagedModule() fuzz.FuzzPackagedModule { | 
|  | if fuzzer, ok := c.compiler.(*fuzzBinary); ok { | 
|  | return fuzzer.fuzzPackagedModule | 
|  | } | 
|  | panic(fmt.Errorf("FuzzPackagedModule called on non-fuzz module: %q", c.BaseModuleName())) | 
|  | } | 
|  |  | 
|  | func (c *Module) FuzzSharedLibraries() android.RuleBuilderInstalls { | 
|  | if fuzzer, ok := c.compiler.(*fuzzBinary); ok { | 
|  | return fuzzer.sharedLibraries | 
|  | } | 
|  | panic(fmt.Errorf("FuzzSharedLibraries called on non-fuzz module: %q", c.BaseModuleName())) | 
|  | } | 
|  |  | 
|  | func (c *Module) NonCcVariants() bool { | 
|  | return false | 
|  | } | 
|  |  | 
|  | 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 | 
|  | } | 
|  |  | 
|  | func (c *Module) CoverageFiles() android.Paths { | 
|  | if c.linker != nil { | 
|  | if library, ok := c.linker.(libraryInterface); ok { | 
|  | return library.objs().coverageFiles | 
|  | } | 
|  | } | 
|  | panic(fmt.Errorf("CoverageFiles called on non-library module: %q", c.BaseModuleName())) | 
|  | } | 
|  |  | 
|  | 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) | 
|  | for _, generator := range c.generators { | 
|  | c.AddProperties(generator.GeneratorProps()...) | 
|  | } | 
|  | 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.fuzzer != nil { | 
|  | c.AddProperties(c.fuzzer.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.afdo != nil { | 
|  | c.AddProperties(c.afdo.props()...) | 
|  | } | 
|  | if c.orderfile != nil { | 
|  | c.AddProperties(c.orderfile.props()...) | 
|  | } | 
|  | for _, feature := range c.features { | 
|  | c.AddProperties(feature.props()...) | 
|  | } | 
|  |  | 
|  | android.InitAndroidArchModule(c, c.hod, c.multilib) | 
|  | android.InitApexModule(c) | 
|  | android.InitDefaultableModule(c) | 
|  |  | 
|  | return c | 
|  | } | 
|  |  | 
|  | // UseVndk() returns true if this module is built against VNDK. | 
|  | // This means the vendor and product variants of a module. | 
|  | func (c *Module) UseVndk() bool { | 
|  | return c.Properties.VndkVersion != "" | 
|  | } | 
|  |  | 
|  | func (c *Module) canUseSdk() bool { | 
|  | return c.Os() == android.Android && c.Target().NativeBridge == android.NativeBridgeDisabled && | 
|  | !c.UseVndk() && !c.InRamdisk() && !c.InRecovery() && !c.InVendorRamdisk() | 
|  | } | 
|  |  | 
|  | 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(config android.Config) bool { | 
|  | return inList(c.BaseModuleName(), *getNDKKnownLibs(config)) | 
|  | } | 
|  |  | 
|  | func (c *Module) IsLlndk() bool { | 
|  | return c.VendorProperties.IsLLNDK | 
|  | } | 
|  |  | 
|  | func (c *Module) IsLlndkPublic() bool { | 
|  | return c.VendorProperties.IsLLNDK && !c.VendorProperties.IsVNDKPrivate | 
|  | } | 
|  |  | 
|  | func (m *Module) NeedsLlndkVariants() bool { | 
|  | lib := moduleLibraryInterface(m) | 
|  | return lib != nil && (lib.hasLLNDKStubs() || lib.hasLLNDKHeaders()) | 
|  | } | 
|  |  | 
|  | func (m *Module) NeedsVendorPublicLibraryVariants() bool { | 
|  | lib := moduleLibraryInterface(m) | 
|  | return lib != nil && (lib.hasVendorPublicLibrary()) | 
|  | } | 
|  |  | 
|  | // IsVendorPublicLibrary returns true for vendor public libraries. | 
|  | func (c *Module) IsVendorPublicLibrary() bool { | 
|  | return c.VendorProperties.IsVendorPublicLibrary | 
|  | } | 
|  |  | 
|  | func (c *Module) IsVndkPrebuiltLibrary() bool { | 
|  | if _, ok := c.linker.(*vndkPrebuiltLibraryDecorator); ok { | 
|  | return true | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) SdkAndPlatformVariantVisibleToMake() bool { | 
|  | return c.Properties.SdkAndPlatformVariantVisibleToMake | 
|  | } | 
|  |  | 
|  | func (c *Module) HasLlndkStubs() bool { | 
|  | lib := moduleLibraryInterface(c) | 
|  | return lib != nil && lib.hasLLNDKStubs() | 
|  | } | 
|  |  | 
|  | func (c *Module) StubsVersion() string { | 
|  | if lib, ok := c.linker.(versionedInterface); ok { | 
|  | return lib.stubsVersion() | 
|  | } | 
|  | panic(fmt.Errorf("StubsVersion called on non-versioned module: %q", c.BaseModuleName())) | 
|  | } | 
|  |  | 
|  | // isImplementationForLLNDKPublic returns true for any variant of a cc_library that has LLNDK stubs | 
|  | // and does not set llndk.vendor_available: false. | 
|  | func (c *Module) isImplementationForLLNDKPublic() bool { | 
|  | library, _ := c.library.(*libraryDecorator) | 
|  | return library != nil && library.hasLLNDKStubs() && | 
|  | !Bool(library.Properties.Llndk.Private) | 
|  | } | 
|  |  | 
|  | // Returns true for LLNDK-private, VNDK-SP-private, and VNDK-core-private. | 
|  | func (c *Module) IsVndkPrivate() bool { | 
|  | // Check if VNDK-core-private or VNDK-SP-private | 
|  | if c.IsVndk() { | 
|  | return Bool(c.vndkdep.Properties.Vndk.Private) | 
|  | } | 
|  |  | 
|  | // Check if LLNDK-private | 
|  | if library, ok := c.library.(*libraryDecorator); ok && c.IsLlndk() { | 
|  | return Bool(library.Properties.Llndk.Private) | 
|  | } | 
|  |  | 
|  | return false | 
|  | } | 
|  |  | 
|  | // IsVndk() returns true if this module has a vndk variant. | 
|  | // Note that IsVndk() returns true for all variants of vndk-enabled libraries. Not only vendor variant, | 
|  | // but also platform and product variants of vndk-enabled libraries return true for IsVndk(). | 
|  | func (c *Module) IsVndk() bool { | 
|  | if vndkdep := c.vndkdep; vndkdep != nil { | 
|  | return vndkdep.isVndk() | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) isAfdoCompile() bool { | 
|  | if afdo := c.afdo; afdo != nil { | 
|  | return afdo.Properties.FdoProfilePath != nil | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) isOrderfileCompile() bool { | 
|  | if orderfile := c.orderfile; orderfile != nil { | 
|  | return orderfile.Properties.OrderfileLoad | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) isCfi() bool { | 
|  | if sanitize := c.sanitize; sanitize != nil { | 
|  | return Bool(sanitize.Properties.SanitizeMutated.Cfi) | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) isFuzzer() bool { | 
|  | if sanitize := c.sanitize; sanitize != nil { | 
|  | return Bool(sanitize.Properties.SanitizeMutated.Fuzzer) | 
|  | } | 
|  | 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) SubName() string { | 
|  | return c.Properties.SubName | 
|  | } | 
|  |  | 
|  | 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 "" | 
|  | } | 
|  |  | 
|  | func (c *Module) IsStubs() bool { | 
|  | if lib := c.library; lib != nil { | 
|  | return lib.buildStubs() | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) HasStubsVariants() bool { | 
|  | if lib := c.library; lib != nil { | 
|  | return lib.hasStubsVariants() | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) IsStubsImplementationRequired() bool { | 
|  | if lib := c.library; lib != nil { | 
|  | return lib.isStubsImplementationRequired() | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | // If this is a stubs library, ImplementationModuleName returns the name of the module that contains | 
|  | // the implementation.  If it is an implementation library it returns its own name. | 
|  | func (c *Module) ImplementationModuleName(ctx android.BaseModuleContext) string { | 
|  | name := ctx.OtherModuleName(c) | 
|  | if versioned, ok := c.linker.(versionedInterface); ok { | 
|  | name = versioned.implementationModuleName(name) | 
|  | } | 
|  | return name | 
|  | } | 
|  |  | 
|  | // Similar to ImplementationModuleName, but uses the Make variant of the module | 
|  | // name as base name, for use in AndroidMk output. E.g. for a prebuilt module | 
|  | // where the Soong name is prebuilt_foo, this returns foo (which works in Make | 
|  | // under the premise that the prebuilt module overrides its source counterpart | 
|  | // if it is exposed to Make). | 
|  | func (c *Module) ImplementationModuleNameForMake(ctx android.BaseModuleContext) string { | 
|  | name := c.BaseModuleName() | 
|  | if versioned, ok := c.linker.(versionedInterface); ok { | 
|  | name = versioned.implementationModuleName(name) | 
|  | } | 
|  | return name | 
|  | } | 
|  |  | 
|  | 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 p, ok := c.linker.(SnapshotInterface); ok { | 
|  | return p.IsSnapshotPrebuilt() | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) ExcludeFromVendorSnapshot() bool { | 
|  | return Bool(c.Properties.Exclude_from_vendor_snapshot) | 
|  | } | 
|  |  | 
|  | func (c *Module) ExcludeFromRecoverySnapshot() bool { | 
|  | return Bool(c.Properties.Exclude_from_recovery_snapshot) | 
|  | } | 
|  |  | 
|  | 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" || name == "libc_hwasan" { | 
|  | return true | 
|  | } | 
|  | return isBionic(name) | 
|  | } | 
|  |  | 
|  | func (c *Module) XrefCcFiles() android.Paths { | 
|  | return c.kytheFiles | 
|  | } | 
|  |  | 
|  | func (c *Module) isCfiAssemblySupportEnabled() bool { | 
|  | return c.sanitize != nil && | 
|  | Bool(c.sanitize.Properties.Sanitize.Config.Cfi_assembly_support) | 
|  | } | 
|  |  | 
|  | func (c *Module) InstallInRoot() bool { | 
|  | return c.installer != nil && c.installer.installInRoot() | 
|  | } | 
|  |  | 
|  | type baseModuleContext struct { | 
|  | android.BaseModuleContext | 
|  | moduleContextImpl | 
|  | } | 
|  |  | 
|  | type depsContext struct { | 
|  | android.BottomUpMutatorContext | 
|  | moduleContextImpl | 
|  | } | 
|  |  | 
|  | type moduleContext struct { | 
|  | android.ModuleContext | 
|  | moduleContextImpl | 
|  | } | 
|  |  | 
|  | 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) testBinary() bool { | 
|  | return ctx.mod.testBinary() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) testLibrary() bool { | 
|  | return ctx.mod.testLibrary() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) header() bool { | 
|  | return ctx.mod.Header() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) binary() bool { | 
|  | return ctx.mod.Binary() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) object() bool { | 
|  | return ctx.mod.Object() | 
|  | } | 
|  |  | 
|  | 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) minSdkVersion() string { | 
|  | ver := ctx.mod.MinSdkVersion() | 
|  | if ver == "apex_inherit" && !ctx.isForPlatform() { | 
|  | ver = ctx.apexSdkVersion().String() | 
|  | } | 
|  | if ver == "apex_inherit" || ver == "" { | 
|  | ver = ctx.sdkVersion() | 
|  | } | 
|  | // For crt objects, the meaning of min_sdk_version is very different from other types of | 
|  | // module. For them, min_sdk_version defines the oldest version that the build system will | 
|  | // create versioned variants for. For example, if min_sdk_version is 16, then sdk variant of | 
|  | // the crt object has local variants of 16, 17, ..., up to the latest version. sdk_version | 
|  | // and min_sdk_version properties of the variants are set to the corresponding version | 
|  | // numbers. However, the non-sdk variant (for apex or platform) of the crt object is left | 
|  | // untouched.  min_sdk_version: 16 doesn't actually mean that the non-sdk variant has to | 
|  | // support such an old version. The version is set to the later version in case when the | 
|  | // non-sdk variant is for the platform, or the min_sdk_version of the containing APEX if | 
|  | // it's for an APEX. | 
|  | if ctx.mod.isCrt() && !ctx.isSdkVariant() { | 
|  | if ctx.isForPlatform() { | 
|  | ver = strconv.Itoa(android.FutureApiLevelInt) | 
|  | } else { // for apex | 
|  | ver = ctx.apexSdkVersion().String() | 
|  | if ver == "" { // in case when min_sdk_version was not set by the APEX | 
|  | ver = ctx.sdkVersion() | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // Also make sure that minSdkVersion is not greater than sdkVersion, if they are both numbers | 
|  | sdkVersionInt, err := strconv.Atoi(ctx.sdkVersion()) | 
|  | minSdkVersionInt, err2 := strconv.Atoi(ver) | 
|  | if err == nil && err2 == nil { | 
|  | if sdkVersionInt < minSdkVersionInt { | 
|  | return strconv.Itoa(sdkVersionInt) | 
|  | } | 
|  | } | 
|  | return ver | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) isSdkVariant() bool { | 
|  | return ctx.mod.IsSdkVariant() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) useVndk() bool { | 
|  | return ctx.mod.UseVndk() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) isNdk(config android.Config) bool { | 
|  | return ctx.mod.IsNdk(config) | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) IsLlndk() bool { | 
|  | return ctx.mod.IsLlndk() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) IsLlndkPublic() bool { | 
|  | return ctx.mod.IsLlndkPublic() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) isImplementationForLLNDKPublic() bool { | 
|  | return ctx.mod.isImplementationForLLNDKPublic() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) IsVndkPrivate() bool { | 
|  | return ctx.mod.IsVndkPrivate() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) isVndk() bool { | 
|  | return ctx.mod.IsVndk() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) isAfdoCompile() bool { | 
|  | return ctx.mod.isAfdoCompile() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) isOrderfileCompile() bool { | 
|  | return ctx.mod.isOrderfileCompile() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) isCfi() bool { | 
|  | return ctx.mod.isCfi() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) isFuzzer() bool { | 
|  | return ctx.mod.isFuzzer() | 
|  | } | 
|  |  | 
|  | 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) IsVendorPublicLibrary() bool { | 
|  | return ctx.mod.IsVendorPublicLibrary() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) mustUseVendorVariant() bool { | 
|  | return ctx.mod.MustUseVendorVariant() | 
|  | } | 
|  |  | 
|  | 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 { | 
|  | apexInfo, _ := android.ModuleProvider(ctx.ctx, android.ApexInfoProvider) | 
|  | return apexInfo.IsForPlatform() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) apexVariationName() string { | 
|  | apexInfo, _ := android.ModuleProvider(ctx.ctx, android.ApexInfoProvider) | 
|  | return apexInfo.ApexVariationName | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) apexSdkVersion() android.ApiLevel { | 
|  | return ctx.mod.apexSdkVersion | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) bootstrap() bool { | 
|  | return ctx.mod.Bootstrap() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) nativeCoverage() bool { | 
|  | return ctx.mod.nativeCoverage() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) directlyInAnyApex() bool { | 
|  | return ctx.mod.DirectlyInAnyApex() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) isPreventInstall() bool { | 
|  | return ctx.mod.Properties.PreventInstall | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) getSharedFlags() *SharedFlags { | 
|  | shared := &ctx.mod.sharedFlags | 
|  | if shared.flagsMap == nil { | 
|  | shared.numSharedFlags = 0 | 
|  | shared.flagsMap = make(map[string]string) | 
|  | } | 
|  | return shared | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) isCfiAssemblySupportEnabled() bool { | 
|  | return ctx.mod.isCfiAssemblySupportEnabled() | 
|  | } | 
|  |  | 
|  | func (ctx *moduleContextImpl) notInPlatform() bool { | 
|  | return ctx.mod.NotInPlatform() | 
|  | } | 
|  |  | 
|  | 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.fuzzer = &fuzzer{} | 
|  | module.sabi = &sabi{} | 
|  | module.vndkdep = &vndkdep{} | 
|  | module.lto = <o{} | 
|  | module.afdo = &afdo{} | 
|  | module.orderfile = &orderfile{} | 
|  | return module | 
|  | } | 
|  |  | 
|  | func (c *Module) Prebuilt() *android.Prebuilt { | 
|  | if p, ok := c.linker.(prebuiltLinkerInterface); ok { | 
|  | return p.prebuilt() | 
|  | } | 
|  | return nil | 
|  | } | 
|  |  | 
|  | func (c *Module) IsPrebuilt() bool { | 
|  | return c.Prebuilt() != 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 | 
|  | } | 
|  |  | 
|  | func (c *Module) IsTestPerSrcAllTestsVariation() bool { | 
|  | test, ok := c.linker.(testPerSrc) | 
|  | return ok && test.isAllTestsVariation() | 
|  | } | 
|  |  | 
|  | func (c *Module) DataPaths() []android.DataPath { | 
|  | if p, ok := c.installer.(interface { | 
|  | dataPaths() []android.DataPath | 
|  | }); ok { | 
|  | return p.dataPaths() | 
|  | } | 
|  | return nil | 
|  | } | 
|  |  | 
|  | func getNameSuffixWithVndkVersion(ctx android.ModuleContext, c LinkableInterface) 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() { | 
|  | if c.ProductSpecific() { | 
|  | // If the module is product specific with 'product_specific: true', | 
|  | // do not add a name suffix because it is a base module. | 
|  | return "" | 
|  | } | 
|  | return ProductSuffix | 
|  | } else { | 
|  | vndkVersion = ctx.DeviceConfig().VndkVersion() | 
|  | nameSuffix = VendorSuffix | 
|  | } | 
|  | if vndkVersion == "current" { | 
|  | vndkVersion = ctx.DeviceConfig().PlatformVndkVersion() | 
|  | } | 
|  | if c.VndkVersion() != vndkVersion && c.VndkVersion() != "" { | 
|  | // add version suffix only if the module is using different vndk version than the | 
|  | // version in product or vendor partition. | 
|  | nameSuffix += "." + c.VndkVersion() | 
|  | } | 
|  | return nameSuffix | 
|  | } | 
|  |  | 
|  | func GetSubnameProperty(actx android.ModuleContext, c LinkableInterface) string { | 
|  | var subName = "" | 
|  |  | 
|  | if c.Target().NativeBridge == android.NativeBridgeEnabled { | 
|  | subName += NativeBridgeSuffix | 
|  | } | 
|  |  | 
|  | llndk := c.IsLlndk() | 
|  | if llndk || (c.UseVndk() && c.HasNonSystemVariants()) { | 
|  | // .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. | 
|  | subName += getNameSuffixWithVndkVersion(actx, c) | 
|  | } else if c.IsVendorPublicLibrary() { | 
|  | subName += vendorPublicLibrarySuffix | 
|  | } else if c.IsVndkPrebuiltLibrary() { | 
|  | // .vendor suffix is added for backward compatibility with VNDK snapshot whose names with | 
|  | // such suffixes are already hard-coded in prebuilts/vndk/.../Android.bp. | 
|  | subName += VendorSuffix | 
|  | } else if c.InRamdisk() && !c.OnlyInRamdisk() { | 
|  | subName += RamdiskSuffix | 
|  | } else if c.InVendorRamdisk() && !c.OnlyInVendorRamdisk() { | 
|  | subName += VendorRamdiskSuffix | 
|  | } else if c.InRecovery() && !c.OnlyInRecovery() { | 
|  | subName += RecoverySuffix | 
|  | } else if c.IsSdkVariant() && (c.SdkAndPlatformVariantVisibleToMake() || c.SplitPerApiLevel()) { | 
|  | subName += sdkSuffix | 
|  | if c.SplitPerApiLevel() { | 
|  | subName += "." + c.SdkVersion() | 
|  | } | 
|  | } else if c.IsStubs() && c.IsSdkVariant() { | 
|  | // Public API surface (NDK) | 
|  | // Add a suffix to this stub variant to distinguish it from the module-lib stub variant. | 
|  | subName = sdkSuffix | 
|  | } | 
|  |  | 
|  | return subName | 
|  | } | 
|  |  | 
|  | func moduleContextFromAndroidModuleContext(actx android.ModuleContext, c *Module) ModuleContext { | 
|  | ctx := &moduleContext{ | 
|  | ModuleContext: actx, | 
|  | moduleContextImpl: moduleContextImpl{ | 
|  | mod: c, | 
|  | }, | 
|  | } | 
|  | ctx.ctx = ctx | 
|  | return ctx | 
|  | } | 
|  |  | 
|  | // TODO (b/277651159): Remove this allowlist | 
|  | var ( | 
|  | skipStubLibraryMultipleApexViolation = map[string]bool{ | 
|  | "libclang_rt.asan":   true, | 
|  | "libclang_rt.hwasan": true, | 
|  | // runtime apex | 
|  | "libc":          true, | 
|  | "libc_hwasan":   true, | 
|  | "libdl_android": true, | 
|  | "libm":          true, | 
|  | "libdl":         true, | 
|  | // art apex | 
|  | "libandroidio":    true, | 
|  | "libdexfile":      true, | 
|  | "libnativebridge": true, | 
|  | "libnativehelper": true, | 
|  | "libnativeloader": true, | 
|  | "libsigchain":     true, | 
|  | } | 
|  | ) | 
|  |  | 
|  | // Returns true if a stub library could be installed in multiple apexes | 
|  | func (c *Module) stubLibraryMultipleApexViolation(ctx android.ModuleContext) bool { | 
|  | // If this is not an apex variant, no check necessary | 
|  | if !c.InAnyApex() { | 
|  | return false | 
|  | } | 
|  | // If this is not a stub library, no check necessary | 
|  | if !c.HasStubsVariants() { | 
|  | return false | 
|  | } | 
|  | // Skip the allowlist | 
|  | // Use BaseModuleName so that this matches prebuilts. | 
|  | if _, exists := skipStubLibraryMultipleApexViolation[c.BaseModuleName()]; exists { | 
|  | return false | 
|  | } | 
|  |  | 
|  | _, aaWithoutTestApexes, _ := android.ListSetDifference(c.ApexAvailable(), c.TestApexes()) | 
|  | // Stub libraries should not have more than one apex_available | 
|  | if len(aaWithoutTestApexes) > 1 { | 
|  | return true | 
|  | } | 
|  | // Stub libraries should not use the wildcard | 
|  | if aaWithoutTestApexes[0] == android.AvailableToAnyApex { | 
|  | return true | 
|  | } | 
|  | // Default: no violation | 
|  | return false | 
|  | } | 
|  |  | 
|  | 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.Properties.SubName = GetSubnameProperty(actx, c) | 
|  | apexInfo, _ := android.ModuleProvider(actx, android.ApexInfoProvider) | 
|  | if !apexInfo.IsForPlatform() { | 
|  | c.hideApexVariantFromMake = true | 
|  | } | 
|  |  | 
|  | c.makeLinkType = GetMakeLinkType(actx, c) | 
|  |  | 
|  | ctx := moduleContextFromAndroidModuleContext(actx, c) | 
|  |  | 
|  | deps := c.depsToPaths(ctx) | 
|  | if ctx.Failed() { | 
|  | return | 
|  | } | 
|  |  | 
|  | for _, generator := range c.generators { | 
|  | gen := generator.GeneratorSources(ctx) | 
|  | deps.IncludeDirs = append(deps.IncludeDirs, gen.IncludeDirs...) | 
|  | deps.ReexportedDirs = append(deps.ReexportedDirs, gen.ReexportedDirs...) | 
|  | deps.GeneratedDeps = append(deps.GeneratedDeps, gen.Headers...) | 
|  | deps.ReexportedGeneratedHeaders = append(deps.ReexportedGeneratedHeaders, gen.Headers...) | 
|  | deps.ReexportedDeps = append(deps.ReexportedDeps, gen.Headers...) | 
|  | if len(deps.Objs.objFiles) == 0 { | 
|  | // If we are reusuing object files (which happens when we're a shared library and we're | 
|  | // reusing our static variant's object files), then skip adding the actual source files, | 
|  | // because we already have the object for it. | 
|  | deps.GeneratedSources = append(deps.GeneratedSources, gen.Sources...) | 
|  | } | 
|  | } | 
|  |  | 
|  | if ctx.Failed() { | 
|  | return | 
|  | } | 
|  |  | 
|  | if c.stubLibraryMultipleApexViolation(actx) { | 
|  | actx.PropertyErrorf("apex_available", | 
|  | "Stub libraries should have a single apex_available (test apexes excluded). Got %v", c.ApexAvailable()) | 
|  | } | 
|  | if c.Properties.Clang != nil && *c.Properties.Clang == false { | 
|  | ctx.PropertyErrorf("clang", "false (GCC) is no longer supported") | 
|  | } else if c.Properties.Clang != nil && !ctx.DeviceConfig().BuildBrokenClangProperty() { | 
|  | ctx.PropertyErrorf("clang", "property is deprecated, see Changes.md file") | 
|  | } | 
|  |  | 
|  | flags := Flags{ | 
|  | Toolchain: c.toolchain(ctx), | 
|  | EmitXrefs: ctx.Config().EmitXrefRules(), | 
|  | } | 
|  | for _, generator := range c.generators { | 
|  | flags = generator.GeneratorFlags(ctx, flags, deps) | 
|  | } | 
|  | 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.fuzzer != nil { | 
|  | flags = c.fuzzer.flags(ctx, flags) | 
|  | } | 
|  | if c.lto != nil { | 
|  | flags = c.lto.flags(ctx, flags) | 
|  | } | 
|  | if c.afdo != nil { | 
|  | flags = c.afdo.flags(ctx, flags) | 
|  | } | 
|  | if c.orderfile != nil { | 
|  | flags = c.orderfile.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()) | 
|  | } | 
|  |  | 
|  | flags.Local.LdFlags = append(flags.Local.LdFlags, deps.LdFlags...) | 
|  |  | 
|  | 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) | 
|  |  | 
|  | for _, generator := range c.generators { | 
|  | generator.GeneratorBuildActions(ctx, flags, deps) | 
|  | } | 
|  |  | 
|  | var objs Objects | 
|  | if c.compiler != nil { | 
|  | objs = c.compiler.compile(ctx, flags, deps) | 
|  | if ctx.Failed() { | 
|  | return | 
|  | } | 
|  | c.kytheFiles = objs.kytheFiles | 
|  | c.objFiles = objs.objFiles | 
|  | c.tidyFiles = objs.tidyFiles | 
|  | } | 
|  |  | 
|  | if c.linker != nil { | 
|  | outputFile := c.linker.link(ctx, flags, deps, objs) | 
|  | if ctx.Failed() { | 
|  | return | 
|  | } | 
|  | c.outputFile = android.OptionalPathForPath(outputFile) | 
|  |  | 
|  | c.maybeUnhideFromMake() | 
|  |  | 
|  | // glob exported headers for snapshot, if BOARD_VNDK_VERSION is current or | 
|  | // RECOVERY_SNAPSHOT_VERSION is current. | 
|  | if i, ok := c.linker.(snapshotLibraryInterface); ok { | 
|  | if ShouldCollectHeadersForSnapshot(ctx, c, apexInfo) { | 
|  | i.collectHeadersForSnapshot(ctx) | 
|  | } | 
|  | } | 
|  | } | 
|  | if c.testModule { | 
|  | android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{}) | 
|  | } | 
|  | android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: deps.GeneratedSources.Strings()}) | 
|  |  | 
|  | android.CollectDependencyAconfigFiles(ctx, &c.mergedAconfigFiles) | 
|  |  | 
|  | c.maybeInstall(ctx, apexInfo) | 
|  |  | 
|  | if c.linker != nil { | 
|  | moduleInfoJSON := ctx.ModuleInfoJSON() | 
|  | c.linker.moduleInfoJSON(ctx, moduleInfoJSON) | 
|  | moduleInfoJSON.SharedLibs = c.Properties.AndroidMkSharedLibs | 
|  | moduleInfoJSON.StaticLibs = c.Properties.AndroidMkStaticLibs | 
|  | moduleInfoJSON.SystemSharedLibs = c.Properties.AndroidMkSystemSharedLibs | 
|  | moduleInfoJSON.RuntimeDependencies = c.Properties.AndroidMkRuntimeLibs | 
|  |  | 
|  | moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, c.Properties.AndroidMkSharedLibs...) | 
|  | moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, c.Properties.AndroidMkStaticLibs...) | 
|  | moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, c.Properties.AndroidMkHeaderLibs...) | 
|  | moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, c.Properties.AndroidMkWholeStaticLibs...) | 
|  |  | 
|  | if c.sanitize != nil && len(moduleInfoJSON.Class) > 0 && | 
|  | (moduleInfoJSON.Class[0] == "STATIC_LIBRARIES" || moduleInfoJSON.Class[0] == "HEADER_LIBRARIES") { | 
|  | if Bool(c.sanitize.Properties.SanitizeMutated.Cfi) { | 
|  | moduleInfoJSON.SubName += ".cfi" | 
|  | } | 
|  | if Bool(c.sanitize.Properties.SanitizeMutated.Hwaddress) { | 
|  | moduleInfoJSON.SubName += ".hwasan" | 
|  | } | 
|  | if Bool(c.sanitize.Properties.SanitizeMutated.Scs) { | 
|  | moduleInfoJSON.SubName += ".scs" | 
|  | } | 
|  | } | 
|  | moduleInfoJSON.SubName += c.Properties.SubName | 
|  |  | 
|  | if c.Properties.IsSdkVariant && c.Properties.SdkAndPlatformVariantVisibleToMake { | 
|  | moduleInfoJSON.Uninstallable = true | 
|  | } | 
|  |  | 
|  | } | 
|  | } | 
|  |  | 
|  | func (c *Module) maybeUnhideFromMake() { | 
|  | // If a lib is directly included in any of the APEXes or is not available to the | 
|  | // platform (which is often the case when the stub is provided as a prebuilt), | 
|  | // 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() && c.NotInPlatform() && !c.InRamdisk() && | 
|  | !c.InRecovery() && !c.UseVndk() && !c.static() && !c.isCoverageVariant() && | 
|  | c.IsStubs() && !c.InVendorRamdisk() { | 
|  | c.Properties.HideFromMake = false // unhide | 
|  | // Note: this is still non-installable | 
|  | } | 
|  | } | 
|  |  | 
|  | // maybeInstall is called at the end of both GenerateAndroidBuildActions to run the | 
|  | // install hooks for installable modules, like binaries and tests. | 
|  | func (c *Module) maybeInstall(ctx ModuleContext, apexInfo android.ApexInfo) { | 
|  | if !proptools.BoolDefault(c.Installable(), true) { | 
|  | // If the module has been specifically configure to not be installed then | 
|  | // hide from make as otherwise it will break when running inside make | 
|  | // as the output path to install will not be specified. Not all uninstallable | 
|  | // modules can be hidden from make as some are needed for resolving make side | 
|  | // dependencies. | 
|  | c.HideFromMake() | 
|  | } else if !installable(c, apexInfo) { | 
|  | c.SkipInstall() | 
|  | } | 
|  |  | 
|  | // Still call c.installer.install though, the installs will be stored as PackageSpecs | 
|  | // to allow using the outputs in a genrule. | 
|  | if c.installer != nil && c.outputFile.Valid() { | 
|  | c.installer.install(ctx, c.outputFile.Path()) | 
|  | if ctx.Failed() { | 
|  | return | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | func (c *Module) toolchain(ctx android.BaseModuleContext) config.Toolchain { | 
|  | if c.cachedToolchain == nil { | 
|  | c.cachedToolchain = config.FindToolchainWithContext(ctx) | 
|  | } | 
|  | return c.cachedToolchain | 
|  | } | 
|  |  | 
|  | func (c *Module) begin(ctx BaseModuleContext) { | 
|  | for _, generator := range c.generators { | 
|  | generator.GeneratorInit(ctx) | 
|  | } | 
|  | 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.afdo != nil { | 
|  | c.afdo.begin(ctx) | 
|  | } | 
|  | if c.lto != nil { | 
|  | c.lto.begin(ctx) | 
|  | } | 
|  | if c.orderfile != nil { | 
|  | c.orderfile.begin(ctx) | 
|  | } | 
|  | if ctx.useSdk() && c.IsSdkVariant() { | 
|  | version, err := nativeApiLevelFromUser(ctx, ctx.sdkVersion()) | 
|  | if err != nil { | 
|  | ctx.PropertyErrorf("sdk_version", err.Error()) | 
|  | c.Properties.Sdk_version = nil | 
|  | } else { | 
|  | c.Properties.Sdk_version = StringPtr(version.String()) | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | func (c *Module) deps(ctx DepsContext) Deps { | 
|  | deps := Deps{} | 
|  |  | 
|  | for _, generator := range c.generators { | 
|  | deps = generator.GeneratorDeps(ctx, deps) | 
|  | } | 
|  | if c.compiler != nil { | 
|  | deps = c.compiler.compilerDeps(ctx, deps) | 
|  | } | 
|  | if c.linker != nil { | 
|  | deps = c.linker.linkerDeps(ctx, deps) | 
|  | } | 
|  | if c.stl != nil { | 
|  | deps = c.stl.deps(ctx, deps) | 
|  | } | 
|  | if c.coverage != nil { | 
|  | deps = c.coverage.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) && !inList(lib, deps.WholeStaticLibs) { | 
|  | ctx.PropertyErrorf("export_static_lib_headers", "Static library not in static_libs or whole_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 | 
|  |  | 
|  | if !actx.Host() || !ctx.static() || ctx.staticBinary() { | 
|  | c.afdo.addDep(ctx, actx) | 
|  | } | 
|  |  | 
|  | 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 GetCrtVariations(ctx android.BottomUpMutatorContext, | 
|  | m LinkableInterface) []blueprint.Variation { | 
|  | if ctx.Os() != android.Android { | 
|  | return nil | 
|  | } | 
|  | if m.UseSdk() { | 
|  | // Choose the CRT that best satisfies the min_sdk_version requirement of this module | 
|  | minSdkVersion := m.MinSdkVersion() | 
|  | if minSdkVersion == "" || minSdkVersion == "apex_inherit" { | 
|  | minSdkVersion = m.SdkVersion() | 
|  | } | 
|  | apiLevel, err := android.ApiLevelFromUser(ctx, minSdkVersion) | 
|  | if err != nil { | 
|  | ctx.PropertyErrorf("min_sdk_version", err.Error()) | 
|  | } | 
|  |  | 
|  | // Raise the minSdkVersion to the minimum supported for the architecture. | 
|  | minApiForArch := MinApiForArch(ctx, m.Target().Arch.ArchType) | 
|  | if apiLevel.LessThan(minApiForArch) { | 
|  | apiLevel = minApiForArch | 
|  | } | 
|  |  | 
|  | return []blueprint.Variation{ | 
|  | {Mutator: "sdk", Variation: "sdk"}, | 
|  | {Mutator: "version", Variation: apiLevel.String()}, | 
|  | } | 
|  | } | 
|  | return []blueprint.Variation{ | 
|  | {Mutator: "sdk", Variation: ""}, | 
|  | } | 
|  | } | 
|  |  | 
|  | func AddSharedLibDependenciesWithVersions(ctx android.BottomUpMutatorContext, mod LinkableInterface, | 
|  | variations []blueprint.Variation, depTag blueprint.DependencyTag, name, version string, far bool) { | 
|  |  | 
|  | variations = append([]blueprint.Variation(nil), variations...) | 
|  |  | 
|  | if version != "" && canBeOrLinkAgainstVersionVariants(mod) { | 
|  | // Version is explicitly specified. i.e. libFoo#30 | 
|  | variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version}) | 
|  | if tag, ok := depTag.(libraryDependencyTag); ok { | 
|  | tag.explicitlyVersioned = true | 
|  | } else { | 
|  | panic(fmt.Errorf("Unexpected dependency tag: %T", depTag)) | 
|  | } | 
|  | } | 
|  |  | 
|  | if far { | 
|  | ctx.AddFarVariationDependencies(variations, depTag, name) | 
|  | } else { | 
|  | ctx.AddVariationDependencies(variations, depTag, name) | 
|  | } | 
|  | } | 
|  |  | 
|  | func GetApiImports(c LinkableInterface, actx android.BottomUpMutatorContext) multitree.ApiImportInfo { | 
|  | apiImportInfo := multitree.ApiImportInfo{} | 
|  |  | 
|  | if c.Device() { | 
|  | var apiImportModule []blueprint.Module | 
|  | if actx.OtherModuleExists("api_imports") { | 
|  | apiImportModule = actx.AddDependency(c, nil, "api_imports") | 
|  | if len(apiImportModule) > 0 && apiImportModule[0] != nil { | 
|  | apiInfo, _ := android.OtherModuleProvider(actx, apiImportModule[0], multitree.ApiImportsProvider) | 
|  | apiImportInfo = apiInfo | 
|  | android.SetProvider(actx, multitree.ApiImportsProvider, apiInfo) | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | return apiImportInfo | 
|  | } | 
|  |  | 
|  | func GetSnapshot(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android.BottomUpMutatorContext) SnapshotInfo { | 
|  | // Only device modules with BOARD_VNDK_VERSION uses snapshot.  Others use the zero value of | 
|  | // SnapshotInfo, which provides no mappings. | 
|  | if *snapshotInfo == nil && c.Device() { | 
|  | // Only retrieve the snapshot on demand in order to avoid circular dependencies | 
|  | // between the modules in the snapshot and the snapshot itself. | 
|  | var snapshotModule []blueprint.Module | 
|  | if c.InVendor() && c.VndkVersion() == actx.DeviceConfig().VndkVersion() { | 
|  | snapshotModule = actx.AddVariationDependencies(nil, nil, "vendor_snapshot") | 
|  | } else if recoverySnapshotVersion := actx.DeviceConfig().RecoverySnapshotVersion(); recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" && c.InRecovery() { | 
|  | snapshotModule = actx.AddVariationDependencies(nil, nil, "recovery_snapshot") | 
|  | } | 
|  | if len(snapshotModule) > 0 && snapshotModule[0] != nil { | 
|  | snapshot, _ := android.OtherModuleProvider(actx, snapshotModule[0], SnapshotInfoProvider) | 
|  | *snapshotInfo = &snapshot | 
|  | // republish the snapshot for use in later mutators on this module | 
|  | android.SetProvider(actx, SnapshotInfoProvider, snapshot) | 
|  | } | 
|  | } | 
|  | if *snapshotInfo == nil { | 
|  | *snapshotInfo = &SnapshotInfo{} | 
|  | } | 
|  | return **snapshotInfo | 
|  | } | 
|  |  | 
|  | func GetReplaceModuleName(lib string, replaceMap map[string]string) string { | 
|  | if snapshot, ok := replaceMap[lib]; ok { | 
|  | return snapshot | 
|  | } | 
|  |  | 
|  | return lib | 
|  | } | 
|  |  | 
|  | // 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 | 
|  | func RewriteLibs(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android.BottomUpMutatorContext, config android.Config, list []string) (nonvariantLibs []string, variantLibs []string) { | 
|  | variantLibs = []string{} | 
|  |  | 
|  | nonvariantLibs = []string{} | 
|  | for _, entry := range list { | 
|  | // strip #version suffix out | 
|  | name, _ := StubsLibNameAndVersion(entry) | 
|  | if c.InRecovery() { | 
|  | nonvariantLibs = append(nonvariantLibs, GetReplaceModuleName(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs)) | 
|  | } else if c.UseSdk() && inList(name, *getNDKKnownLibs(config)) { | 
|  | variantLibs = append(variantLibs, name+ndkLibrarySuffix) | 
|  | } else if c.UseVndk() { | 
|  | nonvariantLibs = append(nonvariantLibs, GetReplaceModuleName(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs)) | 
|  | } else { | 
|  | // put name#version back | 
|  | nonvariantLibs = append(nonvariantLibs, entry) | 
|  | } | 
|  | } | 
|  | return nonvariantLibs, variantLibs | 
|  | } | 
|  |  | 
|  | func rewriteLibsForApiImports(c LinkableInterface, libs []string, replaceList map[string]string, config android.Config) ([]string, []string) { | 
|  | nonVariantLibs := []string{} | 
|  | variantLibs := []string{} | 
|  |  | 
|  | for _, lib := range libs { | 
|  | replaceLibName := GetReplaceModuleName(lib, replaceList) | 
|  | if replaceLibName == lib { | 
|  | // Do not handle any libs which are not in API imports | 
|  | nonVariantLibs = append(nonVariantLibs, replaceLibName) | 
|  | } else if c.UseSdk() && inList(replaceLibName, *getNDKKnownLibs(config)) { | 
|  | variantLibs = append(variantLibs, replaceLibName) | 
|  | } else { | 
|  | nonVariantLibs = append(nonVariantLibs, replaceLibName) | 
|  | } | 
|  | } | 
|  |  | 
|  | return nonVariantLibs, variantLibs | 
|  | } | 
|  |  | 
|  | func (c *Module) shouldUseApiSurface() bool { | 
|  | if c.Os() == android.Android && c.Target().NativeBridge != android.NativeBridgeEnabled { | 
|  | if GetImageVariantType(c) == vendorImageVariant || GetImageVariantType(c) == productImageVariant { | 
|  | // LLNDK Variant | 
|  | return true | 
|  | } | 
|  |  | 
|  | if c.Properties.IsSdkVariant { | 
|  | // NDK Variant | 
|  | return true | 
|  | } | 
|  |  | 
|  | if c.isImportedApiLibrary() { | 
|  | // API Library should depend on API headers | 
|  | return true | 
|  | } | 
|  | } | 
|  |  | 
|  | return false | 
|  | } | 
|  |  | 
|  | 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) | 
|  | apiImportInfo := GetApiImports(c, actx) | 
|  |  | 
|  | apiNdkLibs := []string{} | 
|  | apiLateNdkLibs := []string{} | 
|  |  | 
|  | if c.shouldUseApiSurface() { | 
|  | deps.SharedLibs, apiNdkLibs = rewriteLibsForApiImports(c, deps.SharedLibs, apiImportInfo.SharedLibs, ctx.Config()) | 
|  | deps.LateSharedLibs, apiLateNdkLibs = rewriteLibsForApiImports(c, deps.LateSharedLibs, apiImportInfo.SharedLibs, ctx.Config()) | 
|  | deps.SystemSharedLibs, _ = rewriteLibsForApiImports(c, deps.SystemSharedLibs, apiImportInfo.SharedLibs, ctx.Config()) | 
|  | deps.ReexportHeaderLibHeaders, _ = rewriteLibsForApiImports(c, deps.ReexportHeaderLibHeaders, apiImportInfo.SharedLibs, ctx.Config()) | 
|  | deps.ReexportSharedLibHeaders, _ = rewriteLibsForApiImports(c, deps.ReexportSharedLibHeaders, apiImportInfo.SharedLibs, ctx.Config()) | 
|  | } | 
|  |  | 
|  | c.Properties.AndroidMkSystemSharedLibs = deps.SystemSharedLibs | 
|  |  | 
|  | var snapshotInfo *SnapshotInfo | 
|  |  | 
|  | variantNdkLibs := []string{} | 
|  | variantLateNdkLibs := []string{} | 
|  | if ctx.Os() == android.Android { | 
|  | deps.SharedLibs, variantNdkLibs = RewriteLibs(c, &snapshotInfo, actx, ctx.Config(), deps.SharedLibs) | 
|  | deps.LateSharedLibs, variantLateNdkLibs = RewriteLibs(c, &snapshotInfo, actx, ctx.Config(), deps.LateSharedLibs) | 
|  | deps.ReexportSharedLibHeaders, _ = RewriteLibs(c, &snapshotInfo, actx, ctx.Config(), deps.ReexportSharedLibHeaders) | 
|  |  | 
|  | for idx, lib := range deps.RuntimeLibs { | 
|  | deps.RuntimeLibs[idx] = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).SharedLibs) | 
|  | } | 
|  | } | 
|  |  | 
|  | for _, lib := range deps.HeaderLibs { | 
|  | depTag := libraryDependencyTag{Kind: headerLibraryDependency} | 
|  | if inList(lib, deps.ReexportHeaderLibHeaders) { | 
|  | depTag.reexportFlags = true | 
|  | } | 
|  |  | 
|  | // Check header lib replacement from API surface first, and then check again with VSDK | 
|  | if c.shouldUseApiSurface() { | 
|  | lib = GetReplaceModuleName(lib, apiImportInfo.HeaderLibs) | 
|  | } | 
|  | lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).HeaderLibs) | 
|  |  | 
|  | if c.isNDKStubLibrary() { | 
|  | // ndk_headers do not have any variations | 
|  | actx.AddFarVariationDependencies([]blueprint.Variation{}, depTag, lib) | 
|  | } else if c.IsStubs() && !c.isImportedApiLibrary() { | 
|  | actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()), | 
|  | depTag, lib) | 
|  | } else { | 
|  | actx.AddVariationDependencies(nil, depTag, lib) | 
|  | } | 
|  | } | 
|  |  | 
|  | if c.isNDKStubLibrary() { | 
|  | // NDK stubs depend on their implementation because the ABI dumps are | 
|  | // generated from the implementation library. | 
|  |  | 
|  | actx.AddFarVariationDependencies(append(ctx.Target().Variations(), | 
|  | c.ImageVariation(), | 
|  | blueprint.Variation{Mutator: "link", Variation: "shared"}, | 
|  | ), stubImplementation, c.BaseModuleName()) | 
|  | } | 
|  |  | 
|  | for _, lib := range deps.WholeStaticLibs { | 
|  | depTag := libraryDependencyTag{Kind: staticLibraryDependency, wholeStatic: true, reexportFlags: true} | 
|  |  | 
|  | lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs) | 
|  |  | 
|  | actx.AddVariationDependencies([]blueprint.Variation{ | 
|  | {Mutator: "link", Variation: "static"}, | 
|  | }, depTag, lib) | 
|  | } | 
|  |  | 
|  | for _, lib := range deps.StaticLibs { | 
|  | depTag := libraryDependencyTag{Kind: staticLibraryDependency} | 
|  | if inList(lib, deps.ReexportStaticLibHeaders) { | 
|  | depTag.reexportFlags = true | 
|  | } | 
|  | if inList(lib, deps.ExcludeLibsForApex) { | 
|  | depTag.excludeInApex = true | 
|  | } | 
|  |  | 
|  | lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs) | 
|  |  | 
|  | 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 { | 
|  | depTag := libraryDependencyTag{Kind: staticLibraryDependency, staticUnwinder: true} | 
|  | actx.AddVariationDependencies([]blueprint.Variation{ | 
|  | {Mutator: "link", Variation: "static"}, | 
|  | }, depTag, GetReplaceModuleName(staticUnwinder(actx), GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) | 
|  | } | 
|  |  | 
|  | // shared lib names without the #version suffix | 
|  | var sharedLibNames []string | 
|  |  | 
|  | for _, lib := range deps.SharedLibs { | 
|  | depTag := libraryDependencyTag{Kind: sharedLibraryDependency} | 
|  | if inList(lib, deps.ReexportSharedLibHeaders) { | 
|  | depTag.reexportFlags = true | 
|  | } | 
|  | if inList(lib, deps.ExcludeLibsForApex) { | 
|  | depTag.excludeInApex = true | 
|  | } | 
|  | if inList(lib, deps.ExcludeLibsForNonApex) { | 
|  | depTag.excludeInNonApex = true | 
|  | } | 
|  |  | 
|  | name, version := StubsLibNameAndVersion(lib) | 
|  | if apiLibraryName, ok := apiImportInfo.SharedLibs[name]; ok && !ctx.OtherModuleExists(name) { | 
|  | name = apiLibraryName | 
|  | } | 
|  | sharedLibNames = append(sharedLibNames, name) | 
|  |  | 
|  | variations := []blueprint.Variation{ | 
|  | {Mutator: "link", Variation: "shared"}, | 
|  | } | 
|  |  | 
|  | if _, ok := apiImportInfo.ApexSharedLibs[name]; !ok || ctx.OtherModuleExists(name) { | 
|  | AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, name, version, false) | 
|  | } | 
|  |  | 
|  | if apiLibraryName, ok := apiImportInfo.ApexSharedLibs[name]; ok { | 
|  | AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, apiLibraryName, version, false) | 
|  | } | 
|  | } | 
|  |  | 
|  | for _, lib := range deps.LateStaticLibs { | 
|  | depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency} | 
|  | actx.AddVariationDependencies([]blueprint.Variation{ | 
|  | {Mutator: "link", Variation: "static"}, | 
|  | }, depTag, GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) | 
|  | } | 
|  |  | 
|  | for _, lib := range deps.UnexportedStaticLibs { | 
|  | depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency, unexportedSymbols: true} | 
|  | actx.AddVariationDependencies([]blueprint.Variation{ | 
|  | {Mutator: "link", Variation: "static"}, | 
|  | }, depTag, GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) | 
|  | } | 
|  |  | 
|  | 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 | 
|  | } | 
|  | depTag := libraryDependencyTag{Kind: sharedLibraryDependency, Order: lateLibraryDependency} | 
|  | variations := []blueprint.Variation{ | 
|  | {Mutator: "link", Variation: "shared"}, | 
|  | } | 
|  | AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, lib, "", false) | 
|  | } | 
|  |  | 
|  | actx.AddVariationDependencies([]blueprint.Variation{ | 
|  | {Mutator: "link", Variation: "shared"}, | 
|  | }, dataLibDepTag, deps.DataLibs...) | 
|  |  | 
|  | actx.AddVariationDependencies(nil, dataBinDepTag, deps.DataBins...) | 
|  |  | 
|  | 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) | 
|  | } | 
|  |  | 
|  | crtVariations := GetCrtVariations(ctx, c) | 
|  | actx.AddVariationDependencies(crtVariations, objDepTag, deps.ObjFiles...) | 
|  | for _, crt := range deps.CrtBegin { | 
|  | actx.AddVariationDependencies(crtVariations, CrtBeginDepTag, | 
|  | GetReplaceModuleName(crt, GetSnapshot(c, &snapshotInfo, actx).Objects)) | 
|  | } | 
|  | for _, crt := range deps.CrtEnd { | 
|  | actx.AddVariationDependencies(crtVariations, CrtEndDepTag, | 
|  | GetReplaceModuleName(crt, GetSnapshot(c, &snapshotInfo, actx).Objects)) | 
|  | } | 
|  | if deps.DynamicLinker != "" { | 
|  | actx.AddDependency(c, dynamicLinkerDepTag, deps.DynamicLinker) | 
|  | } | 
|  |  | 
|  | version := ctx.sdkVersion() | 
|  |  | 
|  | ndkStubDepTag := libraryDependencyTag{Kind: sharedLibraryDependency, ndk: true, makeSuffix: "." + version} | 
|  | actx.AddVariationDependencies([]blueprint.Variation{ | 
|  | {Mutator: "version", Variation: version}, | 
|  | {Mutator: "link", Variation: "shared"}, | 
|  | }, ndkStubDepTag, variantNdkLibs...) | 
|  | actx.AddVariationDependencies([]blueprint.Variation{ | 
|  | {Mutator: "version", Variation: version}, | 
|  | {Mutator: "link", Variation: "shared"}, | 
|  | }, ndkStubDepTag, apiNdkLibs...) | 
|  |  | 
|  | ndkLateStubDepTag := libraryDependencyTag{Kind: sharedLibraryDependency, Order: lateLibraryDependency, ndk: true, makeSuffix: "." + version} | 
|  | actx.AddVariationDependencies([]blueprint.Variation{ | 
|  | {Mutator: "version", Variation: version}, | 
|  | {Mutator: "link", Variation: "shared"}, | 
|  | }, ndkLateStubDepTag, variantLateNdkLibs...) | 
|  | actx.AddVariationDependencies([]blueprint.Variation{ | 
|  | {Mutator: "version", Variation: version}, | 
|  | {Mutator: "link", Variation: "shared"}, | 
|  | }, ndkLateStubDepTag, apiLateNdkLibs...) | 
|  |  | 
|  | if vndkdep := c.vndkdep; vndkdep != nil { | 
|  | if vndkdep.isVndkExt() { | 
|  | actx.AddVariationDependencies([]blueprint.Variation{ | 
|  | c.ImageVariation(), | 
|  | {Mutator: "link", Variation: "shared"}, | 
|  | }, vndkExtDepTag, GetReplaceModuleName(vndkdep.getVndkExtendsModuleName(), GetSnapshot(c, &snapshotInfo, actx).SharedLibs)) | 
|  | } | 
|  | } | 
|  |  | 
|  | if len(deps.AidlLibs) > 0 { | 
|  | actx.AddDependency( | 
|  | c, | 
|  | aidlLibraryTag, | 
|  | deps.AidlLibs..., | 
|  | ) | 
|  | } | 
|  |  | 
|  | updateImportedLibraryDependency(ctx) | 
|  | } | 
|  |  | 
|  | 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.BaseModuleContext, from LinkableInterface, to LinkableInterface, | 
|  | tag blueprint.DependencyTag) { | 
|  |  | 
|  | switch t := tag.(type) { | 
|  | case dependencyTag: | 
|  | if t != vndkExtDepTag { | 
|  | return | 
|  | } | 
|  | case libraryDependencyTag: | 
|  | default: | 
|  | return | 
|  | } | 
|  |  | 
|  | if from.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 allowed dependency is limited by the image mutator, | 
|  | // each vendor and product 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 if _, ok := to.(LinkableInterface); !ok { | 
|  | ctx.ModuleErrorf("Attempting to link VNDK cc.Module with unsupported module type") | 
|  | } | 
|  | return | 
|  | } | 
|  | // TODO(b/244244438) : Remove this once all variants are implemented | 
|  | if ccFrom, ok := from.(*Module); ok && ccFrom.isImportedApiLibrary() { | 
|  | return | 
|  | } | 
|  | if from.SdkVersion() == "" { | 
|  | // Platform code can link to anything | 
|  | return | 
|  | } | 
|  | if from.InRamdisk() { | 
|  | // Ramdisk code is not NDK | 
|  | return | 
|  | } | 
|  | if from.InVendorRamdisk() { | 
|  | // Vendor ramdisk code is not NDK | 
|  | return | 
|  | } | 
|  | if from.InRecovery() { | 
|  | // Recovery code is not NDK | 
|  | return | 
|  | } | 
|  | if c, ok := to.(*Module); ok { | 
|  | if c.NdkPrebuiltStl() { | 
|  | // These are allowed, but they don't set sdk_version | 
|  | return | 
|  | } | 
|  | if c.StubDecorator() { | 
|  | // These aren't real libraries, but are the stub shared libraries that are included in | 
|  | // the NDK. | 
|  | return | 
|  | } | 
|  | if c.isImportedApiLibrary() { | 
|  | // Imported library from the API surface is a stub library built against interface definition. | 
|  | 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 := android.ApiLevelFromUserWithConfig(ctx.Config(), from.SdkVersion()) | 
|  | if err != nil { | 
|  | ctx.PropertyErrorf("sdk_version", | 
|  | "Invalid sdk_version value (must be int, preview or current): %q", | 
|  | from.SdkVersion()) | 
|  | } | 
|  | toApi, err := android.ApiLevelFromUserWithConfig(ctx.Config(), to.SdkVersion()) | 
|  | if err != nil { | 
|  | ctx.PropertyErrorf("sdk_version", | 
|  | "Invalid sdk_version value (must be int, preview or current): %q", | 
|  | to.SdkVersion()) | 
|  | } | 
|  |  | 
|  | if toApi.GreaterThan(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()) | 
|  | } | 
|  | } | 
|  |  | 
|  | func checkLinkTypeMutator(ctx android.BottomUpMutatorContext) { | 
|  | if c, ok := ctx.Module().(*Module); ok { | 
|  | ctx.VisitDirectDeps(func(dep android.Module) { | 
|  | depTag := ctx.OtherModuleDependencyTag(dep) | 
|  | ccDep, ok := dep.(LinkableInterface) | 
|  | if ok { | 
|  | checkLinkType(ctx, c, ccDep, depTag) | 
|  | } | 
|  | }) | 
|  | } | 
|  | } | 
|  |  | 
|  | // 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 { | 
|  | return false | 
|  | } | 
|  |  | 
|  | if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() { | 
|  | return false | 
|  | } | 
|  |  | 
|  | // These dependencies are not excercised at runtime. Tracking these will give us | 
|  | // false negative, so skip. | 
|  | depTag := ctx.OtherModuleDependencyTag(child) | 
|  | if IsHeaderDepTag(depTag) { | 
|  | return false | 
|  | } | 
|  | if depTag == staticVariantTag { | 
|  | return false | 
|  | } | 
|  | if depTag == stubImplDepTag { | 
|  | return false | 
|  | } | 
|  |  | 
|  | // Even if target lib has no vendor variant, keep checking dependency | 
|  | // graph in case it depends on vendor_available or product_available | 
|  | // but not double_loadable transtively. | 
|  | if !to.HasNonSystemVariants() { | 
|  | return true | 
|  | } | 
|  |  | 
|  | // The happy path. Keep tracking dependencies until we hit a non double-loadable | 
|  | // one. | 
|  | if Bool(to.VendorProperties.Double_loadable) { | 
|  | return true | 
|  | } | 
|  |  | 
|  | if to.IsVndkSp() || to.IsLlndk() { | 
|  | return false | 
|  | } | 
|  |  | 
|  | ctx.ModuleErrorf("links a library %q which is not LL-NDK, "+ | 
|  | "VNDK-SP, or explicitly marked as 'double_loadable:true'. "+ | 
|  | "Dependency list: %s", ctx.OtherModuleName(to), ctx.GetPathString(false)) | 
|  | return false | 
|  | } | 
|  | if module, ok := ctx.Module().(*Module); ok { | 
|  | if lib, ok := module.linker.(*libraryDecorator); ok && lib.shared() { | 
|  | if lib.hasLLNDKStubs() { | 
|  | ctx.WalkDeps(check) | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | func findApexSdkVersion(ctx android.BaseModuleContext, apexInfo android.ApexInfo) android.ApiLevel { | 
|  | // For the dependency from platform to apex, use the latest stubs | 
|  | apexSdkVersion := android.FutureApiLevel | 
|  | if !apexInfo.IsForPlatform() { | 
|  | apexSdkVersion = apexInfo.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) | 
|  | apexSdkVersion = android.FutureApiLevel | 
|  | } | 
|  |  | 
|  | return apexSdkVersion | 
|  | } | 
|  |  | 
|  | // Convert dependencies to paths.  Returns a PathDeps containing paths | 
|  | func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { | 
|  | var depPaths PathDeps | 
|  |  | 
|  | var directStaticDeps []StaticLibraryInfo | 
|  | var directSharedDeps []SharedLibraryInfo | 
|  |  | 
|  | reexportExporter := func(exporter FlagExporterInfo) { | 
|  | depPaths.ReexportedDirs = append(depPaths.ReexportedDirs, exporter.IncludeDirs...) | 
|  | depPaths.ReexportedSystemDirs = append(depPaths.ReexportedSystemDirs, exporter.SystemIncludeDirs...) | 
|  | depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, exporter.Flags...) | 
|  | depPaths.ReexportedDeps = append(depPaths.ReexportedDeps, exporter.Deps...) | 
|  | depPaths.ReexportedGeneratedHeaders = append(depPaths.ReexportedGeneratedHeaders, exporter.GeneratedHeaders...) | 
|  | } | 
|  |  | 
|  | apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) | 
|  | c.apexSdkVersion = findApexSdkVersion(ctx, apexInfo) | 
|  |  | 
|  | skipModuleList := map[string]bool{} | 
|  |  | 
|  | var apiImportInfo multitree.ApiImportInfo | 
|  | hasApiImportInfo := false | 
|  |  | 
|  | ctx.VisitDirectDeps(func(dep android.Module) { | 
|  | if dep.Name() == "api_imports" { | 
|  | apiImportInfo, _ = android.OtherModuleProvider(ctx, dep, multitree.ApiImportsProvider) | 
|  | hasApiImportInfo = true | 
|  | } | 
|  | }) | 
|  |  | 
|  | if hasApiImportInfo { | 
|  | targetStubModuleList := map[string]string{} | 
|  | targetOrigModuleList := map[string]string{} | 
|  |  | 
|  | // Search for dependency which both original module and API imported library with APEX stub exists | 
|  | ctx.VisitDirectDeps(func(dep android.Module) { | 
|  | depName := ctx.OtherModuleName(dep) | 
|  | if apiLibrary, ok := apiImportInfo.ApexSharedLibs[depName]; ok { | 
|  | targetStubModuleList[apiLibrary] = depName | 
|  | } | 
|  | }) | 
|  | ctx.VisitDirectDeps(func(dep android.Module) { | 
|  | depName := ctx.OtherModuleName(dep) | 
|  | if origLibrary, ok := targetStubModuleList[depName]; ok { | 
|  | targetOrigModuleList[origLibrary] = depName | 
|  | } | 
|  | }) | 
|  |  | 
|  | // Decide which library should be used between original and API imported library | 
|  | ctx.VisitDirectDeps(func(dep android.Module) { | 
|  | depName := ctx.OtherModuleName(dep) | 
|  | if apiLibrary, ok := targetOrigModuleList[depName]; ok { | 
|  | if ShouldUseStubForApex(ctx, dep) { | 
|  | skipModuleList[depName] = true | 
|  | } else { | 
|  | skipModuleList[apiLibrary] = true | 
|  | } | 
|  | } | 
|  | }) | 
|  | } | 
|  |  | 
|  | ctx.VisitDirectDeps(func(dep android.Module) { | 
|  | depName := ctx.OtherModuleName(dep) | 
|  | depTag := ctx.OtherModuleDependencyTag(dep) | 
|  |  | 
|  | if _, ok := skipModuleList[depName]; ok { | 
|  | // skip this module because original module or API imported module matching with this should be used instead. | 
|  | return | 
|  | } | 
|  |  | 
|  | if depTag == android.DarwinUniversalVariantTag { | 
|  | depPaths.DarwinSecondArchOutput = dep.(*Module).OutputFile() | 
|  | return | 
|  | } | 
|  |  | 
|  | if depTag == aidlLibraryTag { | 
|  | if aidlLibraryInfo, ok := android.OtherModuleProvider(ctx, dep, aidl_library.AidlLibraryProvider); ok { | 
|  | depPaths.AidlLibraryInfos = append( | 
|  | depPaths.AidlLibraryInfos, | 
|  | aidlLibraryInfo, | 
|  | ) | 
|  | } | 
|  | } | 
|  |  | 
|  | 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.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 CrtBeginDepTag: | 
|  | depPaths.CrtBegin = append(depPaths.CrtBegin, android.OutputFileForModule(ctx, dep, "")) | 
|  | case CrtEndDepTag: | 
|  | depPaths.CrtEnd = append(depPaths.CrtEnd, android.OutputFileForModule(ctx, dep, "")) | 
|  | } | 
|  | return | 
|  | } | 
|  |  | 
|  | if depTag == android.ProtoPluginDepTag { | 
|  | 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 | 
|  | } | 
|  |  | 
|  | if depTag == reuseObjTag { | 
|  | // Skip reused objects for stub libraries, they use their own stub object file instead. | 
|  | // The reuseObjTag dependency still exists because the LinkageMutator runs before the | 
|  | // version mutator, so the stubs variant is created from the shared variant that | 
|  | // already has the reuseObjTag dependency on the static variant. | 
|  | if !c.library.buildStubs() { | 
|  | staticAnalogue, _ := android.OtherModuleProvider(ctx, dep, StaticLibraryInfoProvider) | 
|  | objs := staticAnalogue.ReuseObjects | 
|  | depPaths.Objs = depPaths.Objs.Append(objs) | 
|  | depExporterInfo, _ := android.OtherModuleProvider(ctx, dep, FlagExporterInfoProvider) | 
|  | reexportExporter(depExporterInfo) | 
|  | } | 
|  | return | 
|  | } | 
|  |  | 
|  | linkFile := ccDep.OutputFile() | 
|  |  | 
|  | if libDepTag, ok := depTag.(libraryDependencyTag); ok { | 
|  | // Only use static unwinder for legacy (min_sdk_version = 29) apexes (b/144430859) | 
|  | if libDepTag.staticUnwinder && c.apexSdkVersion.GreaterThan(android.SdkVersion_Android10) { | 
|  | return | 
|  | } | 
|  |  | 
|  | if !apexInfo.IsForPlatform() && libDepTag.excludeInApex { | 
|  | return | 
|  | } | 
|  | if apexInfo.IsForPlatform() && libDepTag.excludeInNonApex { | 
|  | return | 
|  | } | 
|  |  | 
|  | depExporterInfo, _ := android.OtherModuleProvider(ctx, dep, FlagExporterInfoProvider) | 
|  |  | 
|  | var ptr *android.Paths | 
|  | var depPtr *android.Paths | 
|  |  | 
|  | depFile := android.OptionalPath{} | 
|  |  | 
|  | switch { | 
|  | case libDepTag.header(): | 
|  | if _, isHeaderLib := android.OtherModuleProvider(ctx, dep, HeaderLibraryInfoProvider); !isHeaderLib { | 
|  | if !ctx.Config().AllowMissingDependencies() { | 
|  | ctx.ModuleErrorf("module %q is not a header library", depName) | 
|  | } else { | 
|  | ctx.AddMissingDependencies([]string{depName}) | 
|  | } | 
|  | return | 
|  | } | 
|  | case libDepTag.shared(): | 
|  | if _, isSharedLib := android.OtherModuleProvider(ctx, dep, SharedLibraryInfoProvider); !isSharedLib { | 
|  | if !ctx.Config().AllowMissingDependencies() { | 
|  | ctx.ModuleErrorf("module %q is not a shared library", depName) | 
|  | } else { | 
|  | ctx.AddMissingDependencies([]string{depName}) | 
|  | } | 
|  | return | 
|  | } | 
|  |  | 
|  | sharedLibraryInfo, returnedDepExporterInfo := ChooseStubOrImpl(ctx, dep) | 
|  | depExporterInfo = returnedDepExporterInfo | 
|  |  | 
|  | // Stubs lib doesn't link to the shared lib dependencies. Don't set | 
|  | // linkFile, depFile, and ptr. | 
|  | if c.IsStubs() { | 
|  | break | 
|  | } | 
|  |  | 
|  | linkFile = android.OptionalPathForPath(sharedLibraryInfo.SharedLibrary) | 
|  | depFile = sharedLibraryInfo.TableOfContents | 
|  |  | 
|  | ptr = &depPaths.SharedLibs | 
|  | switch libDepTag.Order { | 
|  | case earlyLibraryDependency: | 
|  | ptr = &depPaths.EarlySharedLibs | 
|  | depPtr = &depPaths.EarlySharedLibsDeps | 
|  | case normalLibraryDependency: | 
|  | ptr = &depPaths.SharedLibs | 
|  | depPtr = &depPaths.SharedLibsDeps | 
|  | directSharedDeps = append(directSharedDeps, sharedLibraryInfo) | 
|  | case lateLibraryDependency: | 
|  | ptr = &depPaths.LateSharedLibs | 
|  | depPtr = &depPaths.LateSharedLibsDeps | 
|  | default: | 
|  | panic(fmt.Errorf("unexpected library dependency order %d", libDepTag.Order)) | 
|  | } | 
|  | case libDepTag.static(): | 
|  | staticLibraryInfo, isStaticLib := android.OtherModuleProvider(ctx, dep, StaticLibraryInfoProvider) | 
|  | if !isStaticLib { | 
|  | if !ctx.Config().AllowMissingDependencies() { | 
|  | ctx.ModuleErrorf("module %q is not a static library", depName) | 
|  | } else { | 
|  | ctx.AddMissingDependencies([]string{depName}) | 
|  | } | 
|  | return | 
|  | } | 
|  |  | 
|  | // Stubs lib doesn't link to the static lib dependencies. Don't set | 
|  | // linkFile, depFile, and ptr. | 
|  | if c.IsStubs() { | 
|  | break | 
|  | } | 
|  |  | 
|  | linkFile = android.OptionalPathForPath(staticLibraryInfo.StaticLibrary) | 
|  | if libDepTag.wholeStatic { | 
|  | ptr = &depPaths.WholeStaticLibs | 
|  | if len(staticLibraryInfo.Objects.objFiles) > 0 { | 
|  | depPaths.WholeStaticLibObjs = depPaths.WholeStaticLibObjs.Append(staticLibraryInfo.Objects) | 
|  | } else { | 
|  | // This case normally catches prebuilt static | 
|  | // libraries, but it can also occur when | 
|  | // AllowMissingDependencies is on and the | 
|  | // dependencies has no sources of its own | 
|  | // but has a whole_static_libs dependency | 
|  | // on a missing library.  We want to depend | 
|  | // on the .a file so that there is something | 
|  | // in the dependency tree that contains the | 
|  | // error rule for the missing transitive | 
|  | // dependency. | 
|  | depPaths.WholeStaticLibsFromPrebuilts = append(depPaths.WholeStaticLibsFromPrebuilts, linkFile.Path()) | 
|  | } | 
|  | depPaths.WholeStaticLibsFromPrebuilts = append(depPaths.WholeStaticLibsFromPrebuilts, | 
|  | staticLibraryInfo.WholeStaticLibsFromPrebuilts...) | 
|  | } else { | 
|  | switch libDepTag.Order { | 
|  | case earlyLibraryDependency: | 
|  | panic(fmt.Errorf("early static libs not suppported")) | 
|  | case normalLibraryDependency: | 
|  | // static dependencies will be handled separately so they can be ordered | 
|  | // using transitive dependencies. | 
|  | ptr = nil | 
|  | directStaticDeps = append(directStaticDeps, staticLibraryInfo) | 
|  | case lateLibraryDependency: | 
|  | ptr = &depPaths.LateStaticLibs | 
|  | default: | 
|  | panic(fmt.Errorf("unexpected library dependency order %d", libDepTag.Order)) | 
|  | } | 
|  | } | 
|  | if libDepTag.unexportedSymbols { | 
|  | depPaths.LdFlags = append(depPaths.LdFlags, | 
|  | "-Wl,--exclude-libs="+staticLibraryInfo.StaticLibrary.Base()) | 
|  | } | 
|  | } | 
|  |  | 
|  | if libDepTag.static() && !libDepTag.wholeStatic { | 
|  | 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. | 
|  | 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...) | 
|  | } else { | 
|  | // Handle non-CC modules here | 
|  | depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles, | 
|  | ccDep.CoverageFiles()...) | 
|  | } | 
|  | } | 
|  |  | 
|  | 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()) | 
|  | } | 
|  |  | 
|  | depPaths.IncludeDirs = append(depPaths.IncludeDirs, depExporterInfo.IncludeDirs...) | 
|  | depPaths.SystemIncludeDirs = append(depPaths.SystemIncludeDirs, depExporterInfo.SystemIncludeDirs...) | 
|  | depPaths.GeneratedDeps = append(depPaths.GeneratedDeps, depExporterInfo.Deps...) | 
|  | depPaths.Flags = append(depPaths.Flags, depExporterInfo.Flags...) | 
|  |  | 
|  | if libDepTag.reexportFlags { | 
|  | reexportExporter(depExporterInfo) | 
|  | // 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, depExporterInfo.IncludeDirs.Strings()...) | 
|  | } | 
|  |  | 
|  | makeLibName := MakeLibName(ctx, c, ccDep, depName) + libDepTag.makeSuffix | 
|  | switch { | 
|  | case libDepTag.header(): | 
|  | c.Properties.AndroidMkHeaderLibs = append( | 
|  | c.Properties.AndroidMkHeaderLibs, makeLibName) | 
|  | case libDepTag.shared(): | 
|  | if lib := moduleLibraryInterface(dep); lib != nil { | 
|  | if lib.buildStubs() && dep.(android.ApexModule).InAnyApex() { | 
|  | // Add the dependency to the APEX(es) providing the library so that | 
|  | // m <module> can trigger building the APEXes as well. | 
|  | depApexInfo, _ := android.OtherModuleProvider(ctx, dep, android.ApexInfoProvider) | 
|  | for _, an := range depApexInfo.InApexVariants { | 
|  | 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) | 
|  | // Record BaseLibName for snapshots. | 
|  | c.Properties.SnapshotSharedLibs = append(c.Properties.SnapshotSharedLibs, BaseLibName(depName)) | 
|  | case libDepTag.static(): | 
|  | if libDepTag.wholeStatic { | 
|  | c.Properties.AndroidMkWholeStaticLibs = append( | 
|  | c.Properties.AndroidMkWholeStaticLibs, makeLibName) | 
|  | } else { | 
|  | c.Properties.AndroidMkStaticLibs = append( | 
|  | c.Properties.AndroidMkStaticLibs, makeLibName) | 
|  | } | 
|  | // Record BaseLibName for snapshots. | 
|  | c.Properties.SnapshotStaticLibs = append(c.Properties.SnapshotStaticLibs, BaseLibName(depName)) | 
|  | } | 
|  | } else if !c.IsStubs() { | 
|  | // Stubs lib doesn't link to the runtime lib, object, crt, etc. dependencies. | 
|  |  | 
|  | switch depTag { | 
|  | case runtimeDepTag: | 
|  | c.Properties.AndroidMkRuntimeLibs = append( | 
|  | c.Properties.AndroidMkRuntimeLibs, MakeLibName(ctx, c, ccDep, depName)+libDepTag.makeSuffix) | 
|  | // Record BaseLibName for snapshots. | 
|  | c.Properties.SnapshotRuntimeLibs = append(c.Properties.SnapshotRuntimeLibs, BaseLibName(depName)) | 
|  | case objDepTag: | 
|  | depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path()) | 
|  | case CrtBeginDepTag: | 
|  | depPaths.CrtBegin = append(depPaths.CrtBegin, linkFile.Path()) | 
|  | case CrtEndDepTag: | 
|  | depPaths.CrtEnd = append(depPaths.CrtEnd, linkFile.Path()) | 
|  | case dynamicLinkerDepTag: | 
|  | depPaths.DynamicLinker = linkFile | 
|  | } | 
|  | } | 
|  | }) | 
|  |  | 
|  | // use the ordered dependencies as this module's dependencies | 
|  | orderedStaticPaths, transitiveStaticLibs := orderStaticModuleDeps(directStaticDeps, directSharedDeps) | 
|  | depPaths.TranstiveStaticLibrariesForOrdering = transitiveStaticLibs | 
|  | depPaths.StaticLibs = append(depPaths.StaticLibs, orderedStaticPaths...) | 
|  |  | 
|  | // Dedup exported flags from dependencies | 
|  | depPaths.Flags = android.FirstUniqueStrings(depPaths.Flags) | 
|  | depPaths.IncludeDirs = android.FirstUniquePaths(depPaths.IncludeDirs) | 
|  | depPaths.SystemIncludeDirs = android.FirstUniquePaths(depPaths.SystemIncludeDirs) | 
|  | 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 ShouldUseStubForApex(ctx android.ModuleContext, dep android.Module) bool { | 
|  | depName := ctx.OtherModuleName(dep) | 
|  | thisModule, ok := ctx.Module().(android.ApexModule) | 
|  | if !ok { | 
|  | panic(fmt.Errorf("Not an APEX module: %q", ctx.ModuleName())) | 
|  | } | 
|  |  | 
|  | useVndk := false | 
|  | bootstrap := false | 
|  | if linkable, ok := ctx.Module().(LinkableInterface); !ok { | 
|  | panic(fmt.Errorf("Not a Linkable module: %q", ctx.ModuleName())) | 
|  | } else { | 
|  | useVndk = linkable.UseVndk() | 
|  | bootstrap = linkable.Bootstrap() | 
|  | } | 
|  |  | 
|  | apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) | 
|  |  | 
|  | useStubs := false | 
|  |  | 
|  | if lib := moduleLibraryInterface(dep); lib.buildStubs() && useVndk { // LLNDK | 
|  | if !apexInfo.IsForPlatform() { | 
|  | // For platform libraries, use current version of LLNDK | 
|  | // If this is for use_vendor apex we will apply the same rules | 
|  | // of apex sdk enforcement below to choose right version. | 
|  | useStubs = true | 
|  | } | 
|  | } else if apexInfo.IsForPlatform() || apexInfo.UsePlatformApis { | 
|  | // If not building for APEX or the containing APEX allows the use of | 
|  | // platform APIs, use stubs only when it is from an APEX (and not from | 
|  | // platform) However, for host, ramdisk, vendor_ramdisk, recovery or | 
|  | // bootstrap modules, always link to non-stub variant | 
|  | isNotInPlatform := dep.(android.ApexModule).NotInPlatform() | 
|  |  | 
|  | isApexImportedApiLibrary := false | 
|  |  | 
|  | if cc, ok := dep.(*Module); ok { | 
|  | if apiLibrary, ok := cc.linker.(*apiLibraryDecorator); ok { | 
|  | if apiLibrary.hasApexStubs() { | 
|  | isApexImportedApiLibrary = true | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | useStubs = (isNotInPlatform || isApexImportedApiLibrary) && !bootstrap | 
|  |  | 
|  | if useStubs { | 
|  | // Another exception: if this module is a test for 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. | 
|  | testFor, _ := android.ModuleProvider(ctx, android.ApexTestForInfoProvider) | 
|  | for _, apexContents := range testFor.ApexContents { | 
|  | if apexContents.DirectlyInApex(depName) { | 
|  | useStubs = false | 
|  | break | 
|  | } | 
|  | } | 
|  | } | 
|  | if useStubs { | 
|  | // Yet another exception: If this module and the dependency are | 
|  | // available to the same APEXes then skip stubs between their | 
|  | // platform variants. This complements the test_for case above, | 
|  | // which avoids the stubs on a direct APEX library dependency, by | 
|  | // avoiding stubs for indirect test dependencies as well. | 
|  | // | 
|  | // TODO(b/183882457): This doesn't work if the two libraries have | 
|  | // only partially overlapping apex_available. For that test_for | 
|  | // modules would need to be split into APEX variants and resolved | 
|  | // separately for each APEX they have access to. | 
|  | if !isApexImportedApiLibrary && android.AvailableToSameApexes(thisModule, dep.(android.ApexModule)) { | 
|  | useStubs = false | 
|  | } | 
|  | } | 
|  | } else { | 
|  | // If building for APEX, use stubs when the parent is in any APEX that | 
|  | // the child is not in. | 
|  | useStubs = !android.DirectlyInAllApexes(apexInfo, depName) | 
|  | } | 
|  |  | 
|  | return useStubs | 
|  | } | 
|  |  | 
|  | // ChooseStubOrImpl determines whether a given dependency should be redirected to the stub variant | 
|  | // of the dependency or not, and returns the SharedLibraryInfo and FlagExporterInfo for the right | 
|  | // dependency. The stub variant is selected when the dependency crosses a boundary where each side | 
|  | // has different level of updatability. For example, if a library foo in an APEX depends on a | 
|  | // library bar which provides stable interface and exists in the platform, foo uses the stub variant | 
|  | // of bar. If bar doesn't provide a stable interface (i.e. buildStubs() == false) or is in the | 
|  | // same APEX as foo, the non-stub variant of bar is used. | 
|  | func ChooseStubOrImpl(ctx android.ModuleContext, dep android.Module) (SharedLibraryInfo, FlagExporterInfo) { | 
|  | depTag := ctx.OtherModuleDependencyTag(dep) | 
|  | libDepTag, ok := depTag.(libraryDependencyTag) | 
|  | if !ok || !libDepTag.shared() { | 
|  | panic(fmt.Errorf("Unexpected dependency tag: %T", depTag)) | 
|  | } | 
|  |  | 
|  | sharedLibraryInfo, _ := android.OtherModuleProvider(ctx, dep, SharedLibraryInfoProvider) | 
|  | depExporterInfo, _ := android.OtherModuleProvider(ctx, dep, FlagExporterInfoProvider) | 
|  | sharedLibraryStubsInfo, _ := android.OtherModuleProvider(ctx, dep, SharedLibraryStubsProvider) | 
|  |  | 
|  | if !libDepTag.explicitlyVersioned && len(sharedLibraryStubsInfo.SharedStubLibraries) > 0 { | 
|  | // when to use (unspecified) stubs, use the latest one. | 
|  | if ShouldUseStubForApex(ctx, dep) { | 
|  | stubs := sharedLibraryStubsInfo.SharedStubLibraries | 
|  | toUse := stubs[len(stubs)-1] | 
|  | sharedLibraryInfo = toUse.SharedLibraryInfo | 
|  | depExporterInfo = toUse.FlagExporterInfo | 
|  | } | 
|  | } | 
|  | return sharedLibraryInfo, depExporterInfo | 
|  | } | 
|  |  | 
|  | // orderStaticModuleDeps rearranges the order of the static library dependencies of the module | 
|  | // to match the topological order of the dependency tree, including any static analogues of | 
|  | // direct shared libraries.  It returns the ordered static dependencies, and an android.DepSet | 
|  | // of the transitive dependencies. | 
|  | func orderStaticModuleDeps(staticDeps []StaticLibraryInfo, sharedDeps []SharedLibraryInfo) (ordered android.Paths, transitive *android.DepSet[android.Path]) { | 
|  | transitiveStaticLibsBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL) | 
|  | var staticPaths android.Paths | 
|  | for _, staticDep := range staticDeps { | 
|  | staticPaths = append(staticPaths, staticDep.StaticLibrary) | 
|  | transitiveStaticLibsBuilder.Transitive(staticDep.TransitiveStaticLibrariesForOrdering) | 
|  | } | 
|  | for _, sharedDep := range sharedDeps { | 
|  | if sharedDep.TransitiveStaticLibrariesForOrdering != nil { | 
|  | transitiveStaticLibsBuilder.Transitive(sharedDep.TransitiveStaticLibrariesForOrdering) | 
|  | } | 
|  | } | 
|  | transitiveStaticLibs := transitiveStaticLibsBuilder.Build() | 
|  |  | 
|  | orderedTransitiveStaticLibs := transitiveStaticLibs.ToList() | 
|  |  | 
|  | // reorder the dependencies based on transitive dependencies | 
|  | staticPaths = android.FirstUniquePaths(staticPaths) | 
|  | _, orderedStaticPaths := android.FilterPathList(orderedTransitiveStaticLibs, staticPaths) | 
|  |  | 
|  | if len(orderedStaticPaths) != len(staticPaths) { | 
|  | missing, _ := android.FilterPathList(staticPaths, orderedStaticPaths) | 
|  | panic(fmt.Errorf("expected %d ordered static paths , got %d, missing %q %q %q", len(staticPaths), len(orderedStaticPaths), missing, orderedStaticPaths, staticPaths)) | 
|  | } | 
|  |  | 
|  | return orderedStaticPaths, transitiveStaticLibs | 
|  | } | 
|  |  | 
|  | // BaseLibName trims known prefixes and suffixes | 
|  | func BaseLibName(depName string) string { | 
|  | libName := strings.TrimSuffix(depName, llndkLibrarySuffix) | 
|  | libName = strings.TrimSuffix(libName, vendorPublicLibrarySuffix) | 
|  | libName = android.RemoveOptionalPrebuiltPrefix(libName) | 
|  | return libName | 
|  | } | 
|  |  | 
|  | func MakeLibName(ctx android.ModuleContext, c LinkableInterface, ccDep LinkableInterface, depName string) string { | 
|  | libName := BaseLibName(depName) | 
|  | ccDepModule, _ := ccDep.(*Module) | 
|  | isLLndk := ccDepModule != nil && ccDepModule.IsLlndk() | 
|  | nonSystemVariantsExist := ccDep.HasNonSystemVariants() || isLLndk | 
|  |  | 
|  | if ccDepModule != nil { | 
|  | // Use base module name for snapshots when exporting to Makefile. | 
|  | if snapshotPrebuilt, ok := ccDepModule.linker.(SnapshotInterface); ok { | 
|  | baseName := ccDepModule.BaseModuleName() | 
|  |  | 
|  | return baseName + snapshotPrebuilt.SnapshotAndroidMkSuffix() | 
|  | } | 
|  | } | 
|  |  | 
|  | if ctx.DeviceConfig().VndkUseCoreVariant() && ccDep.IsVndk() && !ccDep.MustUseVendorVariant() && | 
|  | !c.InRamdisk() && !c.InVendorRamdisk() && !c.InRecovery() { | 
|  | // The vendor module is a no-vendor-variant VNDK library.  Depend on the | 
|  | // core module instead. | 
|  | return libName | 
|  | } else if ccDep.UseVndk() && nonSystemVariantsExist { | 
|  | // The vendor and product modules in Make will have been renamed to not conflict with the | 
|  | // core module, so update the dependency name here accordingly. | 
|  | return libName + ccDep.SubName() | 
|  | } else if ccDep.InRamdisk() && !ccDep.OnlyInRamdisk() { | 
|  | return libName + RamdiskSuffix | 
|  | } else if ccDep.InVendorRamdisk() && !ccDep.OnlyInVendorRamdisk() { | 
|  | return libName + VendorRamdiskSuffix | 
|  | } else if ccDep.InRecovery() && !ccDep.OnlyInRecovery() { | 
|  | return libName + RecoverySuffix | 
|  | } else if ccDep.Target().NativeBridge == android.NativeBridgeEnabled { | 
|  | return libName + NativeBridgeSuffix | 
|  | } else { | 
|  | return libName | 
|  | } | 
|  | } | 
|  |  | 
|  | 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) InstallInVendorRamdisk() bool { | 
|  | return c.InVendorRamdisk() | 
|  | } | 
|  |  | 
|  | func (c *Module) InstallInRecovery() bool { | 
|  | return c.InRecovery() | 
|  | } | 
|  |  | 
|  | func (c *Module) MakeUninstallable() { | 
|  | if c.installer == nil { | 
|  | c.ModuleBase.MakeUninstallable() | 
|  | return | 
|  | } | 
|  | c.installer.makeUninstallable(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 | 
|  | case "unstripped": | 
|  | if c.linker != nil { | 
|  | return android.PathsIfNonNil(c.linker.unstrippedOutputFilePath()), nil | 
|  | } | 
|  | return nil, nil | 
|  | case "stripped_all": | 
|  | if c.linker != nil { | 
|  | return android.PathsIfNonNil(c.linker.strippedAllOutputFilePath()), nil | 
|  | } | 
|  | return nil, 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) testBinary() bool { | 
|  | if test, ok := c.linker.(interface { | 
|  | testBinary() bool | 
|  | }); ok { | 
|  | return test.testBinary() | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) testLibrary() bool { | 
|  | if test, ok := c.linker.(interface { | 
|  | testLibrary() bool | 
|  | }); ok { | 
|  | return test.testLibrary() | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) benchmarkBinary() bool { | 
|  | if b, ok := c.linker.(interface { | 
|  | benchmarkBinary() bool | 
|  | }); ok { | 
|  | return b.benchmarkBinary() | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) fuzzBinary() bool { | 
|  | if f, ok := c.linker.(interface { | 
|  | fuzzBinary() bool | 
|  | }); ok { | 
|  | return f.fuzzBinary() | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | // Header returns true if the module is a header-only variant. (See cc/library.go header()). | 
|  | func (c *Module) Header() bool { | 
|  | if h, ok := c.linker.(interface { | 
|  | header() bool | 
|  | }); ok { | 
|  | return h.header() | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) Binary() bool { | 
|  | if b, ok := c.linker.(interface { | 
|  | binary() bool | 
|  | }); ok { | 
|  | return b.binary() | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) StaticExecutable() bool { | 
|  | if b, ok := c.linker.(*binaryDecorator); ok { | 
|  | return b.static() | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (c *Module) Object() bool { | 
|  | if o, ok := c.linker.(interface { | 
|  | object() bool | 
|  | }); ok { | 
|  | return o.object() | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func GetMakeLinkType(actx android.ModuleContext, c LinkableInterface) string { | 
|  | if c.UseVndk() { | 
|  | if c.IsLlndk() { | 
|  | if !c.IsLlndkPublic() { | 
|  | return "native:vndk_private" | 
|  | } | 
|  | return "native:vndk" | 
|  | } | 
|  | if c.IsVndk() && !c.IsVndkExt() { | 
|  | if c.IsVndkPrivate() { | 
|  | return "native:vndk_private" | 
|  | } | 
|  | return "native:vndk" | 
|  | } | 
|  | if c.InProduct() { | 
|  | return "native:product" | 
|  | } | 
|  | return "native:vendor" | 
|  | } else if c.InRamdisk() { | 
|  | return "native:ramdisk" | 
|  | } else if c.InVendorRamdisk() { | 
|  | return "native:vendor_ramdisk" | 
|  | } else if c.InRecovery() { | 
|  | return "native:recovery" | 
|  | } else if c.Target().Os == android.Android && c.SdkVersion() != "" { | 
|  | 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 lib := c.library; lib != nil { | 
|  | // Stub libs and prebuilt libs in a versioned SDK are not | 
|  | // installable to APEX even though they are shared libs. | 
|  | return lib.shared() && !lib.buildStubs() | 
|  | } 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 { | 
|  | return c.Properties.Test_for | 
|  | } | 
|  |  | 
|  | 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) PreventInstall() bool { | 
|  | return c.Properties.PreventInstall | 
|  | } | 
|  |  | 
|  | func (c *Module) Installable() *bool { | 
|  | if c.library != nil { | 
|  | if i := c.library.installable(); i != nil { | 
|  | return i | 
|  | } | 
|  | } | 
|  | return c.Properties.Installable | 
|  | } | 
|  |  | 
|  | func installable(c LinkableInterface, apexInfo android.ApexInfo) bool { | 
|  | ret := c.EverInstallable() && | 
|  | // Check to see whether the module has been configured to not be installed. | 
|  | proptools.BoolDefault(c.Installable(), true) && | 
|  | !c.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 apexInfo.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) | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | var _ android.ApexModule = (*Module)(nil) | 
|  |  | 
|  | // Implements android.ApexModule | 
|  | func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { | 
|  | depTag := ctx.OtherModuleDependencyTag(dep) | 
|  | libDepTag, isLibDepTag := depTag.(libraryDependencyTag) | 
|  |  | 
|  | if cc, ok := dep.(*Module); ok { | 
|  | if cc.HasStubsVariants() { | 
|  | if isLibDepTag && libDepTag.shared() { | 
|  | // 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 cc.IsLlndk() { | 
|  | return false | 
|  | } | 
|  | if isLibDepTag && c.static() && libDepTag.shared() { | 
|  | // 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 | 
|  | } | 
|  |  | 
|  | if isLibDepTag && libDepTag.excludeInApex { | 
|  | return false | 
|  | } | 
|  | } | 
|  | if depTag == stubImplDepTag { | 
|  | // We don't track from an implementation library to its stubs. | 
|  | return false | 
|  | } | 
|  | if depTag == staticVariantTag { | 
|  | // This dependency is for optimization (reuse *.o from the static lib). It doesn't | 
|  | // actually mean that the static lib (and its dependencies) are copied into the | 
|  | // APEX. | 
|  | return false | 
|  | } | 
|  | return true | 
|  | } | 
|  |  | 
|  | // Implements android.ApexModule | 
|  | func (c *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, | 
|  | sdkVersion android.ApiLevel) error { | 
|  | // We ignore libclang_rt.* prebuilt libs since they declare sdk_version: 14(b/121358700) | 
|  | if strings.HasPrefix(ctx.OtherModuleName(c), "libclang_rt") { | 
|  | return nil | 
|  | } | 
|  | // We don't check for prebuilt modules | 
|  | if _, ok := c.linker.(prebuiltLinkerInterface); ok { | 
|  | return nil | 
|  | } | 
|  |  | 
|  | minSdkVersion := c.MinSdkVersion() | 
|  | if minSdkVersion == "apex_inherit" { | 
|  | return nil | 
|  | } | 
|  | if minSdkVersion == "" { | 
|  | // JNI libs within APK-in-APEX fall into here | 
|  | // Those are okay to set sdk_version instead | 
|  | // We don't have to check if this is a SDK variant because | 
|  | // non-SDK variant resets sdk_version, which works too. | 
|  | minSdkVersion = c.SdkVersion() | 
|  | } | 
|  | if minSdkVersion == "" { | 
|  | return fmt.Errorf("neither min_sdk_version nor sdk_version specificed") | 
|  | } | 
|  | // Not using nativeApiLevelFromUser because the context here is not | 
|  | // necessarily a native context. | 
|  | ver, err := android.ApiLevelFromUser(ctx, minSdkVersion) | 
|  | if err != nil { | 
|  | return err | 
|  | } | 
|  |  | 
|  | // A dependency only needs to support a min_sdk_version at least | 
|  | // as high as  the api level that the architecture was introduced in. | 
|  | // This allows introducing new architectures in the platform that | 
|  | // need to be included in apexes that normally require an older | 
|  | // min_sdk_version. | 
|  | minApiForArch := MinApiForArch(ctx, c.Target().Arch.ArchType) | 
|  | if sdkVersion.LessThan(minApiForArch) { | 
|  | sdkVersion = minApiForArch | 
|  | } | 
|  |  | 
|  | if ver.GreaterThan(sdkVersion) { | 
|  | return fmt.Errorf("newer SDK(%v)", ver) | 
|  | } | 
|  | return nil | 
|  | } | 
|  |  | 
|  | // Implements android.ApexModule | 
|  | func (c *Module) AlwaysRequiresPlatformApexVariant() bool { | 
|  | // stub libraries and native bridge libraries are always available to platform | 
|  | return c.IsStubs() || c.Target().NativeBridge == android.NativeBridgeEnabled | 
|  | } | 
|  |  | 
|  | // Overrides android.ApexModuleBase.UniqueApexVariations | 
|  | func (c *Module) UniqueApexVariations() bool { | 
|  | // When a vendor APEX needs a VNDK lib in it (use_vndk_as_stable: false), it should be a unique | 
|  | // APEX variation. Otherwise, another vendor APEX with use_vndk_as_stable:true may use a wrong | 
|  | // variation of the VNDK lib because APEX variations are merged/grouped. | 
|  | // TODO(b/274401041) Find a way to merge APEX variations for vendor apexes. | 
|  | return c.UseVndk() && c.IsVndk() | 
|  | } | 
|  |  | 
|  | func (c *Module) overriddenModules() []string { | 
|  | if o, ok := c.linker.(overridable); ok { | 
|  | return o.overriddenModules() | 
|  | } | 
|  | return nil | 
|  | } | 
|  |  | 
|  | var _ snapshot.RelativeInstallPath = (*Module)(nil) | 
|  |  | 
|  | type moduleType int | 
|  |  | 
|  | const ( | 
|  | unknownType moduleType = iota | 
|  | binary | 
|  | object | 
|  | fullLibrary | 
|  | staticLibrary | 
|  | sharedLibrary | 
|  | headerLibrary | 
|  | testBin // testBinary already declared | 
|  | ndkLibrary | 
|  | ndkPrebuiltStl | 
|  | ) | 
|  |  | 
|  | func (c *Module) typ() moduleType { | 
|  | if c.testBinary() { | 
|  | // testBinary is also a binary, so this comes before the c.Binary() | 
|  | // conditional. A testBinary has additional implicit dependencies and | 
|  | // other test-only semantics. | 
|  | return testBin | 
|  | } else if c.Binary() { | 
|  | return binary | 
|  | } else if c.Object() { | 
|  | return object | 
|  | } else if c.testLibrary() { | 
|  | // TODO(b/244431896) properly convert cc_test_library to its own macro. This | 
|  | // will let them add implicit compile deps on gtest, for example. | 
|  | // | 
|  | // For now, treat them as regular libraries. | 
|  | return fullLibrary | 
|  | } else if c.CcLibrary() { | 
|  | static := false | 
|  | shared := false | 
|  | if library, ok := c.linker.(*libraryDecorator); ok { | 
|  | static = library.MutatedProperties.BuildStatic | 
|  | shared = library.MutatedProperties.BuildShared | 
|  | } else if library, ok := c.linker.(*prebuiltLibraryLinker); ok { | 
|  | static = library.MutatedProperties.BuildStatic | 
|  | shared = library.MutatedProperties.BuildShared | 
|  | } | 
|  | if static && shared { | 
|  | return fullLibrary | 
|  | } else if !static && !shared { | 
|  | return headerLibrary | 
|  | } else if static { | 
|  | return staticLibrary | 
|  | } | 
|  | return sharedLibrary | 
|  | } else if c.isNDKStubLibrary() { | 
|  | return ndkLibrary | 
|  | } else if c.IsNdkPrebuiltStl() { | 
|  | return ndkPrebuiltStl | 
|  | } | 
|  | return unknownType | 
|  | } | 
|  |  | 
|  | // 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{}, | 
|  | &TestLinkerProperties{}, | 
|  | &TestInstallerProperties{}, | 
|  | &TestBinaryProperties{}, | 
|  | &BenchmarkProperties{}, | 
|  | &fuzz.FuzzProperties{}, | 
|  | &StlProperties{}, | 
|  | &SanitizeProperties{}, | 
|  | &StripProperties{}, | 
|  | &InstallerProperties{}, | 
|  | &TidyProperties{}, | 
|  | &CoverageProperties{}, | 
|  | &SAbiProperties{}, | 
|  | &VndkProperties{}, | 
|  | <OProperties{}, | 
|  | &AfdoProperties{}, | 
|  | &OrderfileProperties{}, | 
|  | &android.ProtoProperties{}, | 
|  | // RustBindgenProperties is included here so that cc_defaults can be used for rust_bindgen modules. | 
|  | &RustBindgenClangProperties{}, | 
|  | &prebuiltLinkerProperties{}, | 
|  | ) | 
|  |  | 
|  | android.InitDefaultsModule(module) | 
|  |  | 
|  | return module | 
|  | } | 
|  |  | 
|  | func (c *Module) IsSdkVariant() bool { | 
|  | return c.Properties.IsSdkVariant | 
|  | } | 
|  |  | 
|  | func (c *Module) isImportedApiLibrary() bool { | 
|  | _, ok := c.linker.(*apiLibraryDecorator) | 
|  | return ok | 
|  | } | 
|  |  | 
|  | 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.Phony("xref_cxx", xrefTargets...) | 
|  | } | 
|  | } | 
|  |  | 
|  | func (c *Module) Partition() string { | 
|  | if p, ok := c.installer.(interface { | 
|  | getPartition() string | 
|  | }); ok { | 
|  | return p.getPartition() | 
|  | } | 
|  | return "" | 
|  | } | 
|  |  | 
|  | var Bool = proptools.Bool | 
|  | var BoolDefault = proptools.BoolDefault | 
|  | var BoolPtr = proptools.BoolPtr | 
|  | var String = proptools.String | 
|  | var StringPtr = proptools.StringPtr |