Merge "Create soong-generated filesystem diff test" into main
diff --git a/android/mutator.go b/android/mutator.go
index a8b5c7d..8265458 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -32,11 +32,11 @@
 // collateGloballyRegisteredMutators constructs the list of mutators that have been registered
 // with the InitRegistrationContext and will be used at runtime.
 func collateGloballyRegisteredMutators() sortableComponents {
-	return collateRegisteredMutators(preArch, preDeps, postDeps, finalDeps)
+	return collateRegisteredMutators(preArch, preDeps, postDeps, postApex, finalDeps)
 }
 
 // collateRegisteredMutators constructs a single list of mutators from the separate lists.
-func collateRegisteredMutators(preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) sortableComponents {
+func collateRegisteredMutators(preArch, preDeps, postDeps, postApex, finalDeps []RegisterMutatorFunc) sortableComponents {
 	mctx := &registerMutatorsContext{}
 
 	register := func(funcs []RegisterMutatorFunc) {
@@ -53,6 +53,8 @@
 
 	register(postDeps)
 
+	register(postApex)
+
 	mctx.finalPhase = true
 	register(finalDeps)
 
@@ -166,6 +168,8 @@
 	RegisterOverridePostDepsMutators,
 }
 
+var postApex = []RegisterMutatorFunc{}
+
 var finalDeps = []RegisterMutatorFunc{}
 
 func PreArchMutators(f RegisterMutatorFunc) {
@@ -180,6 +184,10 @@
 	postDeps = append(postDeps, f)
 }
 
+func PostApexMutators(f RegisterMutatorFunc) {
+	postApex = append(postApex, f)
+}
+
 func FinalDepsMutators(f RegisterMutatorFunc) {
 	finalDeps = append(finalDeps, f)
 }
diff --git a/android/register.go b/android/register.go
index eb6a35e..2ce6025 100644
--- a/android/register.go
+++ b/android/register.go
@@ -235,6 +235,7 @@
 
 	PreDepsMutators(f RegisterMutatorFunc)
 	PostDepsMutators(f RegisterMutatorFunc)
+	PostApexMutators(f RegisterMutatorFunc)
 	FinalDepsMutators(f RegisterMutatorFunc)
 }
 
@@ -326,6 +327,10 @@
 	PostDepsMutators(f)
 }
 
+func (ctx *initRegistrationContext) PostApexMutators(f RegisterMutatorFunc) {
+	PostApexMutators(f)
+}
+
 func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) {
 	FinalDepsMutators(f)
 }
diff --git a/android/testing.go b/android/testing.go
index 196b22e..7440869 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -197,8 +197,8 @@
 
 type TestContext struct {
 	*Context
-	preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc
-	NameResolver                          *NameResolver
+	preArch, preDeps, postDeps, postApex, finalDeps []RegisterMutatorFunc
+	NameResolver                                    *NameResolver
 
 	// The list of singletons registered for the test.
 	singletons sortableComponents
@@ -229,6 +229,10 @@
 	ctx.postDeps = append(ctx.postDeps, f)
 }
 
+func (ctx *TestContext) PostApexMutators(f RegisterMutatorFunc) {
+	ctx.postApex = append(ctx.postApex, f)
+}
+
 func (ctx *TestContext) FinalDepsMutators(f RegisterMutatorFunc) {
 	ctx.finalDeps = append(ctx.finalDeps, f)
 }
@@ -449,7 +453,7 @@
 func (ctx *TestContext) Register() {
 	globalOrder := globallyRegisteredComponentsOrder()
 
-	mutators := collateRegisteredMutators(ctx.preArch, ctx.preDeps, ctx.postDeps, ctx.finalDeps)
+	mutators := collateRegisteredMutators(ctx.preArch, ctx.preDeps, ctx.postDeps, ctx.postApex, ctx.finalDeps)
 	// Ensure that the mutators used in the test are in the same order as they are used at runtime.
 	globalOrder.mutatorOrder.enforceOrdering(mutators)
 	mutators.registerAll(ctx.Context)
diff --git a/cc/Android.bp b/cc/Android.bp
index 3688c8a..88a793c 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -102,6 +102,7 @@
         "orderfile_test.go",
         "prebuilt_test.go",
         "proto_test.go",
+        "sabi_test.go",
         "sanitize_test.go",
         "sdk_test.go",
         "test_data_test.go",
diff --git a/cc/compiler.go b/cc/compiler.go
index a6f623f..022b712 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -228,9 +228,6 @@
 		Static *bool `android:"arch_variant"`
 	} `android:"arch_variant"`
 
-	// Stores the original list of source files before being cleared by library reuse
-	OriginalSrcs proptools.Configurable[[]string] `blueprint:"mutated"`
-
 	// Build and link with OpenMP
 	Openmp *bool `android:"arch_variant"`
 }
@@ -363,10 +360,20 @@
 	tc := ctx.toolchain()
 	modulePath := ctx.ModuleDir()
 
-	srcs := compiler.Properties.Srcs.GetOrDefault(ctx, nil)
-	exclude_srcs := compiler.Properties.Exclude_srcs.GetOrDefault(ctx, nil)
-	compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, srcs, exclude_srcs)
-	compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...)
+	reuseObjs := false
+	if len(ctx.GetDirectDepsWithTag(reuseObjTag)) > 0 {
+		reuseObjs = true
+	}
+
+	// If a reuseObjTag dependency exists then this module is reusing the objects (generally the shared variant
+	// reusing objects from the static variant), and doesn't need to compile any sources of its own.
+	var srcs []string
+	if !reuseObjs {
+		srcs = compiler.Properties.Srcs.GetOrDefault(ctx, nil)
+		exclude_srcs := compiler.Properties.Exclude_srcs.GetOrDefault(ctx, nil)
+		compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, srcs, exclude_srcs)
+		compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...)
+	}
 
 	cflags := compiler.Properties.Cflags.GetOrDefault(ctx, nil)
 	cppflags := compiler.Properties.Cppflags.GetOrDefault(ctx, nil)
@@ -721,11 +728,6 @@
 			return true
 		}
 	}
-	for _, src := range compiler.Properties.OriginalSrcs.GetOrDefault(ctx, nil) {
-		if filepath.Ext(src) == ext {
-			return true
-		}
-	}
 
 	return false
 }
diff --git a/cc/library.go b/cc/library.go
index 3833b98..988d55a 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -2071,12 +2071,7 @@
 			sharedCompiler.StaticProperties.Static.System_shared_libs == nil &&
 			sharedCompiler.SharedProperties.Shared.System_shared_libs == nil {
 
-			// TODO: namespaces?
 			ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, reuseObjTag, ctx.ModuleName())
-			sharedCompiler.baseCompiler.Properties.OriginalSrcs =
-				sharedCompiler.baseCompiler.Properties.Srcs
-			sharedCompiler.baseCompiler.Properties.Srcs = proptools.NewConfigurable[[]string](nil, nil)
-			sharedCompiler.baseCompiler.Properties.Generated_sources = nil
 		}
 
 		// This dep is just to reference static variant from shared variant
diff --git a/cc/sabi_test.go b/cc/sabi_test.go
new file mode 100644
index 0000000..849fc36
--- /dev/null
+++ b/cc/sabi_test.go
@@ -0,0 +1,66 @@
+// Copyright 2024 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
+
+import (
+	"android/soong/android"
+	"testing"
+)
+
+func TestSabi(t *testing.T) {
+	bp := `
+		cc_library {
+			name: "libsabi",
+			srcs: ["sabi.cpp"],
+			static_libs: ["libdirect"],
+			header_abi_checker: {
+				enabled: true,
+				symbol_file: "libsabi.map.txt",
+                ref_dump_dirs: ["abi-dumps"],
+			},
+		}
+
+		cc_library {
+			name: "libdirect",
+			srcs: ["direct.cpp"],
+			whole_static_libs: ["libtransitive"],
+		}
+
+		cc_library {
+			name: "libtransitive",
+			srcs: ["transitive.cpp"],
+		}
+	`
+
+	result := android.GroupFixturePreparers(
+		PrepareForTestWithCcDefaultModules,
+	).RunTestWithBp(t, bp)
+
+	libsabiStatic := result.ModuleForTests("libsabi", "android_arm64_armv8-a_static")
+	sabiObjSDump := libsabiStatic.Output("obj/sabi.sdump")
+
+	libDirect := result.ModuleForTests("libdirect", "android_arm64_armv8-a_static")
+	directObjSDump := libDirect.Output("obj/direct.sdump")
+
+	libTransitive := result.ModuleForTests("libtransitive", "android_arm64_armv8-a_static")
+	transitiveObjSDump := libTransitive.Output("obj/transitive.sdump")
+
+	libsabiShared := result.ModuleForTests("libsabi", "android_arm64_armv8-a_shared")
+	sabiLink := libsabiShared.Rule("sAbiLink")
+
+	android.AssertStringListContains(t, "sabi link inputs", sabiLink.Inputs.Strings(), sabiObjSDump.Output.String())
+	android.AssertStringListContains(t, "sabi link inputs", sabiLink.Inputs.Strings(), directObjSDump.Output.String())
+	android.AssertStringListContains(t, "sabi link inputs", sabiLink.Inputs.Strings(), transitiveObjSDump.Output.String())
+}