Introduce runtime_libs to cc_binary and cc_library

This commit adds `runtime_libs` to cc_binary and cc_library.

Similar to the `required` property, if a module specifies the
`runtime_libs` properties and it is installed, then the modules
specified in `runtime_libs` will be installed as well.

Differnt from the `required` property, if a module is using VNDK and the
module names specified in `runtime_libs` are resolved to the modules
with both core and vendor variants, then '.vendor' will be appended to
those module names.

For example, if `libb` is vendor_available and `libd` is a vendor lib,
then LOCAL_REQUIRED_MODULES will contain `libb.vendor` (instead of
`libb`).

Bug: 72343507
Test: lunch aosp_arm64_ab-userdebug && make  # this runs the unit tests
Test: Create a vendor module with runtime_libs property to a
vendor_available shared library and check the generated Android.mk.

Change-Id: I9e245d80004dab597a5d3db5acd8a09117118db7
diff --git a/cc/cc.go b/cc/cc.go
index 9722cf0..76e6645 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -68,6 +68,7 @@
 	SharedLibs, LateSharedLibs                  []string
 	StaticLibs, LateStaticLibs, WholeStaticLibs []string
 	HeaderLibs                                  []string
+	RuntimeLibs                                 []string
 
 	ReexportSharedLibHeaders, ReexportStaticLibHeaders, ReexportHeaderLibHeaders []string
 
@@ -164,9 +165,10 @@
 	// Minimum sdk version supported when compiling against the ndk
 	Sdk_version *string
 
-	AndroidMkSharedLibs []string `blueprint:"mutated"`
-	HideFromMake        bool     `blueprint:"mutated"`
-	PreventInstall      bool     `blueprint:"mutated"`
+	AndroidMkSharedLibs  []string `blueprint:"mutated"`
+	AndroidMkRuntimeLibs []string `blueprint:"mutated"`
+	HideFromMake         bool     `blueprint:"mutated"`
+	PreventInstall       bool     `blueprint:"mutated"`
 
 	UseVndk bool `blueprint:"mutated"`
 
@@ -306,6 +308,7 @@
 	ndkStubDepTag         = dependencyTag{name: "ndk stub", library: true}
 	ndkLateStubDepTag     = dependencyTag{name: "ndk late stub", library: true}
 	vndkExtDepTag         = dependencyTag{name: "vndk extends", library: true}
+	runtimeDepTag         = dependencyTag{name: "runtime lib"}
 )
 
 // Module contains the properties and members used by all C/C++ module types, and implements
@@ -667,7 +670,6 @@
 }
 
 func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
-
 	ctx := &moduleContext{
 		ModuleContext: actx,
 		moduleContextImpl: moduleContextImpl{
@@ -846,6 +848,7 @@
 	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) {
@@ -987,6 +990,9 @@
 	actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag,
 		deps.LateSharedLibs...)
 
+	actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, runtimeDepTag,
+		deps.RuntimeLibs...)
+
 	actx.AddDependency(c, genSourceDepTag, deps.GeneratedSources...)
 
 	for _, gen := range deps.GeneratedHeaders {
@@ -1346,28 +1352,34 @@
 			*depPtr = append(*depPtr, dep.Path())
 		}
 
-		// Export the shared libs to Make.
-		switch depTag {
-		case sharedDepTag, sharedExportDepTag, lateSharedDepTag:
+		makeLibName := func(depName string) string {
 			libName := strings.TrimSuffix(depName, llndkLibrarySuffix)
 			libName = strings.TrimSuffix(libName, vendorPublicLibrarySuffix)
 			libName = strings.TrimPrefix(libName, "prebuilt_")
 			isLLndk := inList(libName, llndkLibraries)
 			isVendorPublicLib := inList(libName, vendorPublicLibraries)
-			var makeLibName string
 			bothVendorAndCoreVariantsExist := ccDep.hasVendorVariant() || isLLndk
 			if c.useVndk() && bothVendorAndCoreVariantsExist {
 				// The vendor module in Make will have been renamed to not conflict with the core
 				// module, so update the dependency name here accordingly.
-				makeLibName = libName + vendorSuffix
+				return libName + vendorSuffix
 			} else if (ctx.Platform() || ctx.ProductSpecific()) && isVendorPublicLib {
-				makeLibName = libName + vendorPublicLibrarySuffix
+				return libName + vendorPublicLibrarySuffix
 			} else {
-				makeLibName = libName
+				return libName
 			}
+		}
+
+		// Export the shared libs to Make.
+		switch depTag {
+		case sharedDepTag, sharedExportDepTag, lateSharedDepTag:
 			// 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)
+			c.Properties.AndroidMkSharedLibs = append(
+				c.Properties.AndroidMkSharedLibs, makeLibName(depName))
+		case runtimeDepTag:
+			c.Properties.AndroidMkRuntimeLibs = append(
+				c.Properties.AndroidMkRuntimeLibs, makeLibName(depName))
 		}
 	})