Merge "Allow soong config variables to be boolean-typed" into main
diff --git a/android/module.go b/android/module.go
index 9c7410c..2dc63d6 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2537,8 +2537,7 @@
 // *inter-module-communication*.
 // If mctx module is the same as the param module the output files are obtained
 // from outputFiles property of module base, to avoid both setting and
-// reading OutputFilesProvider before  GenerateBuildActions is finished. Also
-// only empty-string-tag is supported in this case.
+// reading OutputFilesProvider before GenerateBuildActions is finished.
 // If a module doesn't have the OutputFilesProvider, nil is returned.
 func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
 	// TODO: support OutputFilesProvider for singletons
@@ -2559,6 +2558,8 @@
 	} else {
 		if tag == "" {
 			return mctx.Module().base().outputFiles.DefaultOutputFiles, nil
+		} else if taggedOutputFiles, hasTag := mctx.Module().base().outputFiles.TaggedOutputFiles[tag]; hasTag {
+			return taggedOutputFiles, nil
 		} else {
 			return nil, fmt.Errorf("unsupported tag %q for module getting its own output files", tag)
 		}
diff --git a/apex/apex.go b/apex/apex.go
index 754f898..5a7742b 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1370,25 +1370,6 @@
 	return true
 }
 
-var _ android.OutputFileProducer = (*apexBundle)(nil)
-
-// Implements android.OutputFileProducer
-func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
-	switch tag {
-	case "", android.DefaultDistTag:
-		// This is the default dist path.
-		return android.Paths{a.outputFile}, nil
-	case imageApexSuffix:
-		// uncompressed one
-		if a.outputApexFile != nil {
-			return android.Paths{a.outputApexFile}, nil
-		}
-		fallthrough
-	default:
-		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
-	}
-}
-
 var _ multitree.Exportable = (*apexBundle)(nil)
 
 func (a *apexBundle) Exportable() bool {
@@ -2432,6 +2413,8 @@
 	a.providePrebuiltInfo(ctx)
 
 	a.required = a.RequiredModuleNames(ctx)
+
+	a.setOutputFiles(ctx)
 }
 
 // Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
@@ -2460,6 +2443,18 @@
 	})
 }
 
+// Set output files to outputFiles property, which is later used to set the
+// OutputFilesProvider
+func (a *apexBundle) setOutputFiles(ctx android.ModuleContext) {
+	// default dist path
+	ctx.SetOutputFiles(android.Paths{a.outputFile}, "")
+	ctx.SetOutputFiles(android.Paths{a.outputFile}, android.DefaultDistTag)
+	// uncompressed one
+	if a.outputApexFile != nil {
+		ctx.SetOutputFiles(android.Paths{a.outputApexFile}, imageApexSuffix)
+	}
+}
+
 // apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
 // the bootclasspath_fragment contributes to the apex.
 func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index dfc4bb3..3c8700d 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -7125,6 +7125,46 @@
 	ensureMatches(t, contents, "<library\\n\\s+name=\\\"foo\\\"\\n\\s+file=\\\"/apex/myapex/javalib/foo.jar\\\"")
 }
 
+func TestJavaSDKLibraryOverrideApexes(t *testing.T) {
+	ctx := testApex(t, `
+		override_apex {
+			name: "mycompanyapex",
+			base: "myapex",
+		}
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			java_libs: ["foo"],
+			updatable: false,
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		java_sdk_library {
+			name: "foo",
+			srcs: ["a.java"],
+			api_packages: ["foo"],
+			apex_available: [ "myapex" ],
+		}
+
+		prebuilt_apis {
+			name: "sdk",
+			api_dirs: ["100"],
+		}
+	`, withFiles(filesForSdkLibrary))
+
+	// Permission XML should point to the activated path of impl jar of java_sdk_library.
+	// Since override variants (com.mycompany.android.foo) are installed in the same package as the overridden variant
+	// (com.android.foo), the filepath should not contain override apex name.
+	sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_mycompanyapex").Output("foo.xml")
+	contents := android.ContentFromFileRuleForTests(t, ctx, sdkLibrary)
+	ensureMatches(t, contents, "<library\\n\\s+name=\\\"foo\\\"\\n\\s+file=\\\"/apex/myapex/javalib/foo.jar\\\"")
+}
+
 func TestJavaSDKLibrary_WithinApex(t *testing.T) {
 	ctx := testApex(t, `
 		apex {
diff --git a/bin/soongdbg b/bin/soongdbg
index bfdbbde..a73bdf9 100755
--- a/bin/soongdbg
+++ b/bin/soongdbg
@@ -32,11 +32,13 @@
                 dep.rdeps.add(node)
                 node.dep_tags.setdefault(dep, list()).append(d)
 
-    def find_paths(self, id1, id2):
+    def find_paths(self, id1, id2, tag_filter):
         # Throws KeyError if one of the names isn't found
         def recurse(node1, node2, visited):
             result = set()
             for dep in node1.rdeps:
+                if not matches_tag(dep, node1, tag_filter):
+                    continue
                 if dep == node2:
                     result.add(node2)
                 if dep not in visited:
@@ -214,6 +216,8 @@
                         help="jq query for each module metadata")
     parser.add_argument("--deptags", action="store_true",
                         help="show dependency tags (makes the graph much more complex)")
+    parser.add_argument("--tag", action="append",
+                        help="Limit output to these dependency tags.")
 
     group = parser.add_argument_group("output formats",
                                       "If no format is provided, a dot file will be written to"
@@ -259,13 +263,21 @@
         sys.stdout.write(text)
 
 
-def get_deps(nodes, root, maxdepth, reverse):
+def matches_tag(node, dep, tag_filter):
+    if not tag_filter:
+        return True
+    return not tag_filter.isdisjoint([t.tag_type for t in node.dep_tags[dep]])
+
+
+def get_deps(nodes, root, maxdepth, reverse, tag_filter):
     if root in nodes:
         return
     nodes.add(root)
     if maxdepth != 0:
         for dep in (root.rdeps if reverse else root.deps):
-            get_deps(nodes, dep, maxdepth-1, reverse)
+            if not matches_tag(root, dep, tag_filter):
+                continue
+            get_deps(nodes, dep, maxdepth-1, reverse, tag_filter)
 
 
 def new_module_formatter(args):
@@ -302,7 +314,7 @@
 
     def run(self, args):
         graph = load_graph()
-        print_nodes(args, graph.find_paths(args.module[0], args.module[1]),
+        print_nodes(args, graph.find_paths(args.module[0], args.module[1], set(args.tag)),
                     new_module_formatter(args))
 
 
@@ -328,7 +340,7 @@
                 sys.stderr.write(f"error: Can't find root: {id}\n")
                 err = True
                 continue
-            get_deps(nodes, root, args.depth, args.reverse)
+            get_deps(nodes, root, args.depth, args.reverse, set(args.tag))
         if err:
             sys.exit(1)
         print_nodes(args, nodes, new_module_formatter(args))
diff --git a/cc/cc_test.go b/cc/cc_test.go
index c2bb25a..776d133 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -2908,8 +2908,6 @@
 				PrepareForIntegrationTestWithCc,
 				android.FixtureAddTextFile("external/foo/Android.bp", bp),
 			).RunTest(t)
-			// Use the arm variant instead of the arm64 variant so that it gets headers from
-			// ndk_libandroid_support to test LateStaticLibs.
 			cflags := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_sdk_static").Output("obj/external/foo/foo.o").Args["cFlags"]
 
 			var includes []string
diff --git a/cc/cmake_ext_add_aidl_library.txt b/cc/cmake_ext_add_aidl_library.txt
index af5bdf6..aa3235e3 100644
--- a/cc/cmake_ext_add_aidl_library.txt
+++ b/cc/cmake_ext_add_aidl_library.txt
@@ -25,7 +25,7 @@
         endif()
 
         set(DEPFILE_ARG)
-        if (NOT ${CMAKE_GENERATOR} MATCHES "Unix Makefiles")
+        if (NOT ${CMAKE_GENERATOR} STREQUAL "Unix Makefiles")
             set(DEPFILE_ARG DEPFILE "${GEN_SOURCE}.d")
         endif()
 
@@ -57,7 +57,7 @@
         "${GEN_DIR}/include"
     )
 
-    if (${LANG} MATCHES "ndk")
+    if (${LANG} STREQUAL "ndk")
         set(BINDER_LIB_NAME "libbinder_ndk_sdk")
     else()
         set(BINDER_LIB_NAME "libbinder_sdk")
diff --git a/cc/cmake_main.txt b/cc/cmake_main.txt
index e9177d6..f6e21a6 100644
--- a/cc/cmake_main.txt
+++ b/cc/cmake_main.txt
@@ -11,7 +11,11 @@
     set(ANDROID_BUILD_TOP "${CMAKE_CURRENT_SOURCE_DIR}")
 endif()
 
-set(PREBUILTS_BIN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/prebuilts/host/linux-x86/bin")
+if ("${CMAKE_HOST_SYSTEM_PROCESSOR}" MATCHES "^(arm|aarch)")
+    set(PREBUILTS_BIN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/prebuilts/host/linux_musl-arm64/bin")
+else()
+    set(PREBUILTS_BIN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/prebuilts/host/linux-x86/bin")
+endif()
 if (NOT AIDL_BIN)
     find_program(AIDL_BIN aidl REQUIRED HINTS "${PREBUILTS_BIN_DIR}")
 endif()
diff --git a/cc/cmake_snapshot.go b/cc/cmake_snapshot.go
index b016369..1284da4 100644
--- a/cc/cmake_snapshot.go
+++ b/cc/cmake_snapshot.go
@@ -62,8 +62,13 @@
 }
 
 var ignoredSystemLibs []string = []string{
+	"crtbegin_dynamic",
+	"crtend_android",
+	"libc",
 	"libc++",
 	"libc++_static",
+	"libdl",
+	"libm",
 	"prebuilt_libclang_rt.builtins",
 	"prebuilt_libclang_rt.ubsan_minimal",
 }
@@ -272,7 +277,11 @@
 		{"arch", "x86_64"},
 	}
 	ctx.AddVariationDependencies(variations, cmakeSnapshotModuleTag, m.Properties.Modules...)
-	ctx.AddVariationDependencies(variations, cmakeSnapshotPrebuiltTag, m.Properties.Prebuilts...)
+
+	if len(m.Properties.Prebuilts) > 0 {
+		prebuilts := append(m.Properties.Prebuilts, "libc++")
+		ctx.AddVariationDependencies(variations, cmakeSnapshotPrebuiltTag, prebuilts...)
+	}
 }
 
 func (m *CmakeSnapshot) GenerateAndroidBuildActions(ctx android.ModuleContext) {
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index 45b9944..7cc6231 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -15,7 +15,6 @@
 package java
 
 import (
-	"fmt"
 	"path/filepath"
 
 	"android/soong/android"
@@ -290,32 +289,23 @@
 	android.ModuleBase
 
 	properties globalCompatConfigProperties
-
-	outputFilePath android.OutputPath
 }
 
 func (c *globalCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	filename := String(c.properties.Filename)
 
 	inputPath := platformCompatConfigPath(ctx)
-	c.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath
+	outputFilePath := android.PathForModuleOut(ctx, filename).OutputPath
 
 	// This ensures that outputFilePath has the correct name for others to
 	// use, as the source file may have a different name.
 	ctx.Build(pctx, android.BuildParams{
 		Rule:   android.Cp,
-		Output: c.outputFilePath,
+		Output: outputFilePath,
 		Input:  inputPath,
 	})
-}
 
-func (h *globalCompatConfig) OutputFiles(tag string) (android.Paths, error) {
-	switch tag {
-	case "":
-		return android.Paths{h.outputFilePath}, nil
-	default:
-		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
-	}
+	ctx.SetOutputFiles(android.Paths{outputFilePath}, "")
 }
 
 // global_compat_config provides access to the merged compat config xml file generated by the build.
diff --git a/multitree/api_surface.go b/multitree/api_surface.go
index f739a24..0f605d8 100644
--- a/multitree/api_surface.go
+++ b/multitree/api_surface.go
@@ -16,8 +16,6 @@
 
 import (
 	"android/soong/android"
-	"fmt"
-
 	"github.com/google/blueprint"
 )
 
@@ -40,7 +38,6 @@
 	ExportableModuleBase
 	properties apiSurfaceProperties
 
-	allOutputs    android.Paths
 	taggedOutputs map[string]android.Paths
 }
 
@@ -86,15 +83,9 @@
 		Inputs: allOutputs,
 	})
 
-	surface.allOutputs = allOutputs
 	surface.taggedOutputs = contributionFiles
-}
 
-func (surface *ApiSurface) OutputFiles(tag string) (android.Paths, error) {
-	if tag != "" {
-		return nil, fmt.Errorf("unknown tag: %q", tag)
-	}
-	return surface.allOutputs, nil
+	ctx.SetOutputFiles(allOutputs, "")
 }
 
 func (surface *ApiSurface) TaggedOutputs() map[string]android.Paths {
@@ -105,7 +96,6 @@
 	return true
 }
 
-var _ android.OutputFileProducer = (*ApiSurface)(nil)
 var _ Exportable = (*ApiSurface)(nil)
 
 type ApiContribution interface {
diff --git a/multitree/export.go b/multitree/export.go
index aecade5..8be8f70 100644
--- a/multitree/export.go
+++ b/multitree/export.go
@@ -50,7 +50,6 @@
 
 type ExportableModule interface {
 	android.Module
-	android.OutputFileProducer
 	Exportable
 }
 
diff --git a/python/binary.go b/python/binary.go
index b935aba..5f60761 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -103,6 +103,7 @@
 	p.buildBinary(ctx)
 	p.installedDest = ctx.InstallFile(installDir(ctx, "bin", "", ""),
 		p.installSource.Base(), p.installSource)
+	ctx.SetOutputFiles(android.Paths{p.installSource}, "")
 }
 
 func (p *PythonBinaryModule) buildBinary(ctx android.ModuleContext) {
@@ -187,16 +188,6 @@
 	return android.OptionalPathForPath(p.installedDest)
 }
 
-// OutputFiles returns output files based on given tag, returns an error if tag is unsupported.
-func (p *PythonBinaryModule) OutputFiles(tag string) (android.Paths, error) {
-	switch tag {
-	case "":
-		return android.Paths{p.installSource}, nil
-	default:
-		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
-	}
-}
-
 func (p *PythonBinaryModule) isEmbeddedLauncherEnabled() bool {
 	return BoolDefault(p.properties.Embedded_launcher, true)
 }