Add llndk_stubs property

Prepare for making the relationship between an llndk_library stubs
module and the cc_library implementation module explicit by
adding an llndk_stubs property.  Each cc_library will be updated
to point to its llndk_library, and the llndk_library name will
be changed to make the .llndk suffix explicit.  Then the implicit
connection and suffix can be removed.

Bug: 170784825
Test: m checkbuild
Change-Id: I6b0482a3f286ec29b2e928551aa4317749f2b499
diff --git a/cc/androidmk.go b/cc/androidmk.go
index e58a172..2c402c6 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -33,6 +33,7 @@
 )
 
 type AndroidMkContext interface {
+	BaseModuleName() string
 	Target() android.Target
 	subAndroidMk(*android.AndroidMkEntries, interface{})
 	Arch() android.Arch
@@ -462,6 +463,7 @@
 
 func (c *llndkStubDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
 	entries.Class = "SHARED_LIBRARIES"
+	entries.OverrideName = c.implementationModuleName(ctx.BaseModuleName())
 
 	entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
 		c.libraryDecorator.androidMkWriteExportedFlags(entries)
diff --git a/cc/cc.go b/cc/cc.go
index dbe6346..be1ab8c 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1040,6 +1040,16 @@
 	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
+}
+
 func (c *Module) bootstrap() bool {
 	return Bool(c.Properties.Bootstrap)
 }
diff --git a/cc/cc_test.go b/cc/cc_test.go
index d1780cd..fef0c34 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -846,10 +846,11 @@
 		cc_library {
 			name: "libllndk",
 			shared_libs: ["libdoubleloadable"],
+			llndk_stubs: "libllndk.llndk",
 		}
 
 		llndk_library {
-			name: "libllndk",
+			name: "libllndk.llndk",
 			symbol_file: "",
 		}
 
@@ -867,10 +868,11 @@
 		cc_library {
 			name: "libllndk",
 			shared_libs: ["libvndksp"],
+			llndk_stubs: "libllndk.llndk",
 		}
 
 		llndk_library {
-			name: "libllndk",
+			name: "libllndk.llndk",
 			symbol_file: "",
 		}
 
@@ -924,10 +926,11 @@
 		cc_library {
 			name: "libllndk",
 			shared_libs: ["libcoreonly"],
+			llndk_stubs: "libllndk.llndk",
 		}
 
 		llndk_library {
-			name: "libllndk",
+			name: "libllndk.llndk",
 			symbol_file: "",
 		}
 
@@ -1523,10 +1526,11 @@
 		cc_library {
 			name: "libllndk",
 			shared_libs: ["libnondoubleloadable"],
+			llndk_stubs: "libllndk.llndk",
 		}
 
 		llndk_library {
-			name: "libllndk",
+			name: "libllndk.llndk",
 			symbol_file: "",
 		}
 
@@ -1545,10 +1549,11 @@
 			name: "libllndk",
 			no_libcrt: true,
 			shared_libs: ["libnondoubleloadable"],
+			llndk_stubs: "libllndk.llndk",
 		}
 
 		llndk_library {
-			name: "libllndk",
+			name: "libllndk.llndk",
 			symbol_file: "",
 		}
 
@@ -1617,10 +1622,11 @@
 		cc_library {
 			name: "libllndk",
 			shared_libs: ["libcoreonly"],
+			llndk_stubs: "libllndk.llndk",
 		}
 
 		llndk_library {
-			name: "libllndk",
+			name: "libllndk.llndk",
 			symbol_file: "",
 		}
 
@@ -2361,9 +2367,10 @@
 	bp := `
 		cc_library {
 			name: "libllndk",
+			llndk_stubs: "libllndk.llndk",
 		}
 		llndk_library {
-			name: "libllndk",
+			name: "libllndk.llndk",
 			symbol_file: "",
 		}
 		cc_library {
@@ -2564,16 +2571,18 @@
 		}
 		cc_library {
 			name: "libllndk",
+			llndk_stubs: "libllndk.llndk",
 		}
 		llndk_library {
-			name: "libllndk",
+			name: "libllndk.llndk",
 			symbol_file: "",
 		}
 		cc_library {
 			name: "libllndkprivate",
+			llndk_stubs: "libllndkprivate.llndk",
 		}
 		llndk_library {
-			name: "libllndkprivate",
+			name: "libllndkprivate.llndk",
 			vendor_available: false,
 			symbol_file: "",
 		}`
@@ -2987,9 +2996,10 @@
 	cc_library {
 		name: "libllndk",
 		stubs: { versions: ["1", "2"] },
+		llndk_stubs: "libllndk.llndk",
 	}
 	llndk_library {
-		name: "libllndk",
+		name: "libllndk.llndk",
 	}
 	`)
 	actual := ctx.ModuleVariantsForTests("libllndk.llndk")
@@ -3017,10 +3027,15 @@
 		export_include_dirs: ["my_include"],
 	}
 	llndk_library {
-		name: "libllndk",
+		name: "libllndk.llndk",
 		export_llndk_headers: ["libllndk_headers"],
 	}
 	cc_library {
+		name: "libllndk",
+		llndk_stubs: "libllndk.llndk",
+	}
+
+	cc_library {
 		name: "libvendor",
 		shared_libs: ["libllndk"],
 		vendor: true,
diff --git a/cc/library.go b/cc/library.go
index 090abf9..c2ebc49 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -110,6 +110,9 @@
 
 	// Inject boringssl hash into the shared library.  This is only intended for use by external/boringssl.
 	Inject_bssl_hash *bool `android:"arch_variant"`
+
+	// If this is an LLNDK library, the name of the equivalent llndk_library module.
+	Llndk_stubs *string
 }
 
 type StaticProperties struct {
@@ -695,6 +698,8 @@
 	stubsVersions(ctx android.BaseMutatorContext) []string
 	setAllStubsVersions([]string)
 	allStubsVersions() []string
+
+	implementationModuleName(name string) string
 }
 
 var _ libraryInterface = (*libraryDecorator)(nil)
@@ -1205,7 +1210,7 @@
 	}
 
 	if library.buildStubs() && !library.skipAPIDefine {
-		library.reexportFlags("-D" + versioningMacroName(ctx.baseModuleName()) + "=" + library.stubsVersion())
+		library.reexportFlags("-D" + versioningMacroName(ctx.Module().(*Module).ImplementationModuleName(ctx)) + "=" + library.stubsVersion())
 	}
 
 	library.flagExporter.setProvider(ctx)
@@ -1358,6 +1363,10 @@
 	library.MutatedProperties.BuildStatic = false
 }
 
+func (library *libraryDecorator) implementationModuleName(name string) string {
+	return name
+}
+
 func (library *libraryDecorator) buildStubs() bool {
 	return library.MutatedProperties.BuildStubs
 }
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 4425a10..9f4444d 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -72,6 +72,8 @@
 	movedToApex bool
 }
 
+var _ versionedInterface = (*llndkStubDecorator)(nil)
+
 func (stub *llndkStubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
 	flags = stub.baseCompiler.compilerFlags(ctx, flags, deps)
 	return addStubLibraryCompilerFlags(flags)
@@ -101,12 +103,14 @@
 }
 
 func (stub *llndkStubDecorator) Name(name string) string {
+	if strings.HasSuffix(name, llndkLibrarySuffix) {
+		return name
+	}
 	return name + llndkLibrarySuffix
 }
 
 func (stub *llndkStubDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
-	stub.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(),
-		llndkLibrarySuffix)
+	stub.libraryDecorator.libName = stub.implementationModuleName(ctx.ModuleName())
 	return stub.libraryDecorator.linkerFlags(ctx, flags)
 }
 
@@ -133,7 +137,7 @@
 func (stub *llndkStubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps,
 	objs Objects) android.Path {
 
-	impl := ctx.GetDirectDepWithTag(ctx.baseModuleName(), llndkImplDep)
+	impl := ctx.GetDirectDepWithTag(stub.implementationModuleName(ctx.ModuleName()), llndkImplDep)
 	if implApexModule, ok := impl.(android.ApexModule); ok {
 		stub.movedToApex = implApexModule.DirectlyInAnyApex()
 	}
@@ -167,6 +171,10 @@
 	return false
 }
 
+func (stub *llndkStubDecorator) implementationModuleName(name string) string {
+	return strings.TrimSuffix(name, llndkLibrarySuffix)
+}
+
 func (stub *llndkStubDecorator) buildStubs() bool {
 	return true
 }
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index f2ad652..02b38a6 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -100,10 +100,16 @@
 	unversionedUntil android.ApiLevel
 }
 
+var _ versionedInterface = (*stubDecorator)(nil)
+
 func shouldUseVersionScript(ctx BaseModuleContext, stub *stubDecorator) bool {
 	return stub.apiLevel.GreaterThanOrEqualTo(stub.unversionedUntil)
 }
 
+func (stub *stubDecorator) implementationModuleName(name string) string {
+	return strings.TrimSuffix(name, ndkLibrarySuffix)
+}
+
 func ndkLibraryVersions(ctx android.BaseMutatorContext, from android.ApiLevel) []string {
 	var versions []android.ApiLevel
 	versionStrs := []string{}
diff --git a/cc/testing.go b/cc/testing.go
index 52f0829..019a186 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -172,9 +172,10 @@
 			stubs: {
 				versions: ["27", "28", "29"],
 			},
-		}
+			llndk_stubs: "libc.llndk",
+}
 		llndk_library {
-			name: "libc",
+			name: "libc.llndk",
 			symbol_file: "",
 			sdk_version: "current",
 		}
@@ -193,9 +194,10 @@
 				"//apex_available:platform",
 				"myapex"
 			],
+			llndk_stubs: "libm.llndk",
 		}
 		llndk_library {
-			name: "libm",
+			name: "libm.llndk",
 			symbol_file: "",
 			sdk_version: "current",
 		}
@@ -253,9 +255,10 @@
 				"//apex_available:platform",
 				"myapex"
 			],
+			llndk_stubs: "libdl.llndk",
 		}
 		llndk_library {
-			name: "libdl",
+			name: "libdl.llndk",
 			symbol_file: "",
 			sdk_version: "current",
 		}
@@ -265,9 +268,10 @@
 			nocrt: true,
 			system_shared_libs: [],
 			recovery_available: true,
+			llndk_stubs: "libft2.llndk",
 		}
 		llndk_library {
-			name: "libft2",
+			name: "libft2.llndk",
 			symbol_file: "",
 			vendor_available: false,
 			sdk_version: "current",
diff --git a/cc/vndk.go b/cc/vndk.go
index 981e039..aeaec03 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -247,7 +247,7 @@
 }
 
 func isLlndkLibrary(baseModuleName string, config android.Config) bool {
-	_, ok := llndkLibraries(config)[baseModuleName]
+	_, ok := llndkLibraries(config)[strings.TrimSuffix(baseModuleName, llndkLibrarySuffix)]
 	return ok
 }
 
@@ -290,8 +290,8 @@
 
 func processLlndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
 	lib := m.linker.(*llndkStubDecorator)
-	name := m.BaseModuleName()
-	filename := m.BaseModuleName() + ".so"
+	name := m.ImplementationModuleName(mctx)
+	filename := name + ".so"
 
 	vndkLibrariesLock.Lock()
 	defer vndkLibrariesLock.Unlock()
@@ -834,8 +834,8 @@
 		if m, ok := module.(*Module); ok {
 			if llndk, ok := m.linker.(*llndkStubDecorator); ok {
 				// Skip bionic libs, they are handled in different manner
-				name := m.BaseModuleName()
-				if llndk.movedToApex && !isBionic(m.BaseModuleName()) {
+				name := llndk.implementationModuleName(m.BaseModuleName())
+				if llndk.movedToApex && !isBionic(name) {
 					movedToApexLlndkLibraries[name] = true
 				}
 			}