Merge "kzip build: pipe error message to stderr." into main
diff --git a/android/arch.go b/android/arch.go
index 4b4691b..152016c 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1884,10 +1884,10 @@
 		buildTargets = filterMultilibTargets(targets, "lib64")
 		// Reverse the targets so that the first architecture can depend on the second
 		// architecture module in order to merge the outputs.
-		reverseSliceInPlace(buildTargets)
+		ReverseSliceInPlace(buildTargets)
 	case "darwin_universal_common_first":
 		archTargets := filterMultilibTargets(targets, "lib64")
-		reverseSliceInPlace(archTargets)
+		ReverseSliceInPlace(archTargets)
 		buildTargets = append(getCommonTargets(targets), archTargets...)
 	default:
 		return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", "64", "prefer32" or "first_prefer32" found %q`,
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index d5ccfca..5d93f06 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -1270,6 +1270,12 @@
 		// because this would cause circular dependency. So, until we move aquery processing
 		// to the 'android' package, we need to handle special cases here.
 		switch buildStatement.Mnemonic {
+		case "RepoMappingManifest":
+			// It appears RepoMappingManifest files currently have
+			// non-deterministic content. Just emit empty files for
+			// now because they're unused.
+			out := PathForBazelOut(ctx, buildStatement.OutputPaths[0])
+			WriteFileRuleVerbatim(ctx, out, "")
 		case "FileWrite", "SourceSymlinkManifest":
 			out := PathForBazelOut(ctx, buildStatement.OutputPaths[0])
 			WriteFileRuleVerbatim(ctx, out, buildStatement.FileContents)
diff --git a/android/depset_generic.go b/android/depset_generic.go
index 4f31b86..45c1937 100644
--- a/android/depset_generic.go
+++ b/android/depset_generic.go
@@ -79,8 +79,8 @@
 	if order == TOPOLOGICAL {
 		// TOPOLOGICAL is implemented as a postorder traversal followed by reversing the output.
 		// Pre-reverse the inputs here so their order is maintained in the output.
-		directCopy = reverseSlice(direct)
-		transitiveCopy = reverseSlice(transitive)
+		directCopy = ReverseSlice(direct)
+		transitiveCopy = ReverseSlice(transitive)
 	} else {
 		directCopy = append([]T(nil), direct...)
 		transitiveCopy = append([]*DepSet[T](nil), transitive...)
@@ -184,7 +184,7 @@
 	})
 	list = firstUniqueInPlace(list)
 	if d.reverse {
-		reverseSliceInPlace(list)
+		ReverseSliceInPlace(list)
 	}
 	return list
 }
diff --git a/android/util.go b/android/util.go
index 50bf5aa..e17d7b2 100644
--- a/android/util.go
+++ b/android/util.go
@@ -351,15 +351,19 @@
 	return in[0:writeIndex]
 }
 
-// reverseSliceInPlace reverses the elements of a slice in place.
-func reverseSliceInPlace[T any](in []T) {
+// ReverseSliceInPlace reverses the elements of a slice in place and returns it.
+func ReverseSliceInPlace[T any](in []T) []T {
 	for i, j := 0, len(in)-1; i < j; i, j = i+1, j-1 {
 		in[i], in[j] = in[j], in[i]
 	}
+	return in
 }
 
-// reverseSlice returns a copy of a slice in reverse order.
-func reverseSlice[T any](in []T) []T {
+// ReverseSlice returns a copy of a slice in reverse order.
+func ReverseSlice[T any](in []T) []T {
+	if in == nil {
+		return in
+	}
 	out := make([]T, len(in))
 	for i := 0; i < len(in); i++ {
 		out[i] = in[len(in)-1-i]
diff --git a/android/util_test.go b/android/util_test.go
index 0e28b56..20161e5 100644
--- a/android/util_test.go
+++ b/android/util_test.go
@@ -20,6 +20,7 @@
 	"strconv"
 	"strings"
 	"testing"
+	"unsafe"
 )
 
 var firstUniqueStringsTestCases = []struct {
@@ -754,3 +755,65 @@
 		})
 	}
 }
+
+var reverseTestCases = []struct {
+	name     string
+	in       []string
+	expected []string
+}{
+	{
+		name:     "nil",
+		in:       nil,
+		expected: nil,
+	},
+	{
+		name:     "empty",
+		in:       []string{},
+		expected: []string{},
+	},
+	{
+		name:     "one",
+		in:       []string{"one"},
+		expected: []string{"one"},
+	},
+	{
+		name:     "even",
+		in:       []string{"one", "two"},
+		expected: []string{"two", "one"},
+	},
+	{
+		name:     "odd",
+		in:       []string{"one", "two", "three"},
+		expected: []string{"three", "two", "one"},
+	},
+}
+
+func TestReverseSliceInPlace(t *testing.T) {
+	for _, testCase := range reverseTestCases {
+		t.Run(testCase.name, func(t *testing.T) {
+			slice := CopyOf(testCase.in)
+			slice2 := slice
+			ReverseSliceInPlace(slice)
+			if !reflect.DeepEqual(slice, testCase.expected) {
+				t.Errorf("expected %#v, got %#v", testCase.expected, slice)
+			}
+			if unsafe.SliceData(slice) != unsafe.SliceData(slice2) {
+				t.Errorf("expected slices to share backing array")
+			}
+		})
+	}
+}
+
+func TestReverseSlice(t *testing.T) {
+	for _, testCase := range reverseTestCases {
+		t.Run(testCase.name, func(t *testing.T) {
+			slice := ReverseSlice(testCase.in)
+			if !reflect.DeepEqual(slice, testCase.expected) {
+				t.Errorf("expected %#v, got %#v", testCase.expected, slice)
+			}
+			if slice != nil && unsafe.SliceData(testCase.in) == unsafe.SliceData(slice) {
+				t.Errorf("expected slices to have different backing arrays")
+			}
+		})
+	}
+}
diff --git a/android_sdk/sdk_repo_host.go b/android_sdk/sdk_repo_host.go
index 9623a8b..7212a07 100644
--- a/android_sdk/sdk_repo_host.go
+++ b/android_sdk/sdk_repo_host.go
@@ -166,7 +166,7 @@
 		}
 	} else {
 		llvmStrip := config.ClangPath(ctx, "bin/llvm-strip")
-		llvmLib := config.ClangPath(ctx, "lib/x86_64-unknown-linux-gnu/libc++.so.1")
+		llvmLib := config.ClangPath(ctx, "lib/x86_64-unknown-linux-gnu/libc++.so")
 		for _, strip := range s.properties.Strip_files {
 			cmd := builder.Command().Tool(llvmStrip).ImplicitTool(llvmLib)
 			if !ctx.Windows() {
diff --git a/bazel/aquery.go b/bazel/aquery.go
index 95e52ae..480158c 100644
--- a/bazel/aquery.go
+++ b/bazel/aquery.go
@@ -677,7 +677,7 @@
 		if len(actionEntry.Arguments) < 1 {
 			return a.templateExpandActionBuildStatement(actionEntry)
 		}
-	case "FileWrite", "SourceSymlinkManifest":
+	case "FileWrite", "SourceSymlinkManifest", "RepoMappingManifest":
 		return a.fileWriteActionBuildStatement(actionEntry)
 	case "SymlinkTree":
 		return a.symlinkTreeActionBuildStatement(actionEntry)
diff --git a/build_kzip.bash b/build_kzip.bash
index 4cca37d..b161861 100755
--- a/build_kzip.bash
+++ b/build_kzip.bash
@@ -44,7 +44,7 @@
   # xref_rust
 )
 
-build/soong/soong_ui.bash --build-mode --all-modules --skip-soong-tests --dir=$PWD -k "${kzip_targets[@]}"
+build/soong/soong_ui.bash --build-mode --all-modules --dir=$PWD -k "${kzip_targets[@]}"
 
 # Build extraction file for Go the files in build/{blueprint,soong} directories.
 declare -r abspath_out=$(realpath "${out}")
diff --git a/cc/afdo.go b/cc/afdo.go
index 137ea97..bc7cd52 100644
--- a/cc/afdo.go
+++ b/cc/afdo.go
@@ -34,7 +34,8 @@
 
 var afdoProfileProjectsConfigKey = android.NewOnceKey("AfdoProfileProjects")
 
-const afdoCFlagsFormat = "-fprofile-sample-use=%s"
+// This flag needs to be in both CFlags and LdFlags to ensure correct symbol ordering
+const afdoFlagsFormat = "-fprofile-sample-use=%s"
 
 func recordMissingAfdoProfileFile(ctx android.BaseModuleContext, missing string) {
 	getNamedMapForConfig(ctx.Config(), modulesMissingProfileFileKey).Store(missing, true)
@@ -86,7 +87,7 @@
 	}
 	if path := afdo.Properties.FdoProfilePath; path != nil {
 		// The flags are prepended to allow overriding.
-		profileUseFlag := fmt.Sprintf(afdoCFlagsFormat, *path)
+		profileUseFlag := fmt.Sprintf(afdoFlagsFormat, *path)
 		flags.Local.CFlags = append([]string{profileUseFlag}, flags.Local.CFlags...)
 		flags.Local.LdFlags = append([]string{profileUseFlag, "-Wl,-mllvm,-no-warn-sample-unused=true"}, flags.Local.LdFlags...)
 
diff --git a/cc/config/global.go b/cc/config/global.go
index e450ba7..013b659 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -305,7 +305,7 @@
 
 	// prebuilts/clang default settings.
 	ClangDefaultBase         = "prebuilts/clang/host"
-	ClangDefaultVersion      = "clang-r487747c"
+	ClangDefaultVersion      = "clang-r498229"
 	ClangDefaultShortVersion = "17"
 
 	// Directories with warnings from Android.bp files.
diff --git a/cc/lto.go b/cc/lto.go
index 547ebff..510dd79 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -76,43 +76,44 @@
 		return flags
 	}
 	if lto.Properties.LtoEnabled {
-		var ltoCFlag string
-		var ltoLdFlag string
-		if lto.ThinLTO() {
-			ltoCFlag = "-flto=thin -fsplit-lto-unit"
-		} else {
-			ltoCFlag = "-flto=thin -fsplit-lto-unit"
-			ltoLdFlag = "-Wl,--lto-O0"
+		ltoCFlags := []string{"-flto=thin", "-fsplit-lto-unit"}
+		var ltoLdFlags []string
+
+		// The module did not explicitly turn on LTO. Only leverage LTO's
+		// better dead code elinmination and CFG simplification, but do
+		// not perform costly optimizations for a balance between compile
+		// time, binary size and performance.
+		if !lto.ThinLTO() {
+			ltoLdFlags = append(ltoLdFlags, "-Wl,--lto-O0")
 		}
 
-		flags.Local.CFlags = append(flags.Local.CFlags, ltoCFlag)
-		flags.Local.AsFlags = append(flags.Local.AsFlags, ltoCFlag)
-		flags.Local.LdFlags = append(flags.Local.LdFlags, ltoCFlag)
-		flags.Local.LdFlags = append(flags.Local.LdFlags, ltoLdFlag)
-
 		if Bool(lto.Properties.Whole_program_vtables) {
-			flags.Local.CFlags = append(flags.Local.CFlags, "-fwhole-program-vtables")
+			ltoCFlags = append(ltoCFlags, "-fwhole-program-vtables")
 		}
 
 		if ctx.Config().IsEnvTrue("USE_THINLTO_CACHE") {
 			// Set appropriate ThinLTO cache policy
 			cacheDirFormat := "-Wl,--thinlto-cache-dir="
 			cacheDir := android.PathForOutput(ctx, "thinlto-cache").String()
-			flags.Local.LdFlags = append(flags.Local.LdFlags, cacheDirFormat+cacheDir)
+			ltoLdFlags = append(ltoLdFlags, cacheDirFormat+cacheDir)
 
 			// Limit the size of the ThinLTO cache to the lesser of 10% of available
 			// disk space and 10GB.
 			cachePolicyFormat := "-Wl,--thinlto-cache-policy="
 			policy := "cache_size=10%:cache_size_bytes=10g"
-			flags.Local.LdFlags = append(flags.Local.LdFlags, cachePolicyFormat+policy)
+			ltoLdFlags = append(ltoLdFlags, cachePolicyFormat+policy)
 		}
 
 		// If the module does not have a profile, be conservative and limit cross TU inline
 		// limit to 5 LLVM IR instructions, to balance binary size increase and performance.
 		if !ctx.Darwin() && !ctx.isPgoCompile() && !ctx.isAfdoCompile() {
-			flags.Local.LdFlags = append(flags.Local.LdFlags,
-				"-Wl,-plugin-opt,-import-instr-limit=5")
+			ltoLdFlags = append(ltoLdFlags, "-Wl,-plugin-opt,-import-instr-limit=5")
 		}
+
+		flags.Local.CFlags = append(flags.Local.CFlags, ltoCFlags...)
+		flags.Local.AsFlags = append(flags.Local.AsFlags, ltoCFlags...)
+		flags.Local.LdFlags = append(flags.Local.LdFlags, ltoCFlags...)
+		flags.Local.LdFlags = append(flags.Local.LdFlags, ltoLdFlags...)
 	}
 	return flags
 }
diff --git a/genrule/allowlists.go b/genrule/allowlists.go
index c767685..02b1145 100644
--- a/genrule/allowlists.go
+++ b/genrule/allowlists.go
@@ -56,7 +56,6 @@
 		"RSTest-rscript",
 		"BluetoothGeneratedDumpsysBinarySchema_bfbs",
 		"TracingVMProtoStub_h",
-		"FrontendStub_h",
 		"VehicleServerProtoStub_cc",
 		"AudioFocusControlProtoStub_cc",
 		"AudioFocusControlProtoStub_h",
@@ -98,7 +97,6 @@
 		"BlueberryFacadeGeneratedStub_cc",
 		"BlueberryFacadeGeneratedStub_h",
 		"BluetoothGeneratedDumpsysDataSchema_h",
-		"FrontendStub_cc",
 		"OpenwrtControlServerProto_cc",
 		"OpenwrtControlServerProto_h",
 		"c2hal_test_genc++",
diff --git a/java/app_import.go b/java/app_import.go
index 9c01960..8427217 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -17,6 +17,7 @@
 // This file contains the module implementations for android_app_import and android_test_import.
 
 import (
+	"fmt"
 	"reflect"
 
 	"github.com/google/blueprint"
@@ -410,6 +411,15 @@
 	return a.outputFile
 }
 
+func (a *AndroidAppImport) OutputFiles(tag string) (android.Paths, error) {
+	switch tag {
+	case "":
+		return []android.Path{a.outputFile}, nil
+	default:
+		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+	}
+}
+
 func (a *AndroidAppImport) JacocoReportClassesFile() android.Path {
 	return nil
 }
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 96645b0..7dc1b4b 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -247,7 +247,7 @@
 
 	var cmd, cmdDesc string
 	if b.Properties.Custom_bindgen != "" {
-		cmd = ctx.GetDirectDepWithTag(b.Properties.Custom_bindgen, customBindgenDepTag).(*Module).HostToolPath().String()
+		cmd = ctx.GetDirectDepWithTag(b.Properties.Custom_bindgen, customBindgenDepTag).(android.HostToolProvider).HostToolPath().String()
 		cmdDesc = b.Properties.Custom_bindgen
 	} else {
 		cmd = "$bindgenCmd"
diff --git a/tests/run_integration_tests.sh b/tests/run_integration_tests.sh
index bec43ae..43a9f0f 100755
--- a/tests/run_integration_tests.sh
+++ b/tests/run_integration_tests.sh
@@ -16,8 +16,7 @@
 # mock client.
 "$TOP/build/soong/tests/apex_comparison_tests.sh"
 "$TOP/build/soong/tests/apex_comparison_tests.sh" "module_arm64only"
-# TODO(b/289141798): uncomment the first dcla_apex_comparison_test.sh
-#TEST_BAZEL=true extra_build_params=--bazel-mode-staging "$TOP/build/soong/tests/dcla_apex_comparison_test.sh"
+TEST_BAZEL=true extra_build_params=--bazel-mode-staging "$TOP/build/soong/tests/dcla_apex_comparison_test.sh"
 #BUILD_BROKEN_DISABLE_BAZEL=true "$TOP/build/soong/tests/dcla_apex_comparison_test.sh"
 "$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh"
 "$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh" "aosp_arm" "armv7-a"