shared_lib dependency from a static lib crosses the APEX boundary

cc_library_static {
    name: "libfoo",
    shared_libs: ["libbar"],
}

cc_library {
   name: "libbar",
}

If libfoo is part of an APEX, then libbar is no longer considered as a
member of the APEX, because it isn't actually linked to libfoo.

To distinguish such a shared lib dependency from a static library from a
shared lib dependency from a shared library, a new dep type
SharedFromStaticDepTag is introduced. It is treated exactly the same as
SharedDepTag, except when we determine whether a dependency is crossing
the APEX boundary or not.

This allows us to check the apex_available property more correctly.
Previously, modules were incorrectly considered as being used for an
APEX due to the shared lib dependency from a static lib.

As a good side effect, this also reduces the number of APEX variants.
Specifically, on aosp_arm64, the number of the generated modules were
reduced from 44745 to 44180.

Exempt-From-Owner-Approval: cherry-pick from internal

Bug: 147671264
Test: m

Merged-In: I899ccb9eae1574effef77ca1bc3a0df145983861
(cherry picked from commit 931b676a69c092451ed25a5dda67accf90ce6457)
Change-Id: I899ccb9eae1574effef77ca1bc3a0df145983861
diff --git a/cc/cc.go b/cc/cc.go
index 67e7d7c..f467c73 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1777,6 +1777,9 @@
 
 	for _, lib := range deps.SharedLibs {
 		depTag := SharedDepTag
+		if c.static() {
+			depTag = SharedFromStaticDepTag
+		}
 		if inList(lib, deps.ReexportSharedLibHeaders) {
 			depTag = sharedExportDepTag
 		}
@@ -2194,7 +2197,7 @@
 		depFile := android.OptionalPath{}
 
 		switch depTag {
-		case ndkStubDepTag, SharedDepTag, sharedExportDepTag:
+		case ndkStubDepTag, SharedDepTag, SharedFromStaticDepTag, sharedExportDepTag:
 			ptr = &depPaths.SharedLibs
 			depPtr = &depPaths.SharedLibsDeps
 			depFile = ccDep.Toc()
@@ -2547,9 +2550,17 @@
 
 func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
 	if depTag, ok := ctx.OtherModuleDependencyTag(dep).(DependencyTag); ok {
-		if cc, ok := dep.(*Module); ok && cc.HasStubsVariants() && depTag.Shared && depTag.Library {
-			// dynamic dep to a stubs lib crosses APEX boundary
-			return false
+		if cc, ok := dep.(*Module); ok {
+			if cc.HasStubsVariants() && depTag.Shared && depTag.Library {
+				// dynamic dep to a stubs lib crosses APEX boundary
+				return false
+			}
+			if depTag.FromStatic {
+				// shared_lib dependency from a static lib is considered as crossing
+				// the APEX boundary because the dependency doesn't actually is
+				// linked; the dependency is used only during the compilation phase.
+				return false
+			}
 		}
 	}
 	return true
diff --git a/cc/linkable.go b/cc/linkable.go
index 3c46d9d..2abb112 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -67,12 +67,17 @@
 	ReexportFlags bool
 
 	ExplicitlyVersioned bool
+
+	FromStatic bool
 }
 
 var (
 	SharedDepTag = DependencyTag{Name: "shared", Library: true, Shared: true}
 	StaticDepTag = DependencyTag{Name: "static", Library: true}
 
+	// Same as SharedDepTag, but from a static lib
+	SharedFromStaticDepTag = DependencyTag{Name: "shared from static", Library: true, Shared: true, FromStatic: true}
+
 	CrtBeginDepTag = DependencyTag{Name: "crtbegin"}
 	CrtEndDepTag   = DependencyTag{Name: "crtend"}
 )