Merge "Use note in linker.s to place linker"
diff --git a/android/bazel.go b/android/bazel.go
index 992d8aa..8d13762 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -180,7 +180,6 @@
 		//                                                       also depends on //system/logging/liblog:liblog (http://b/186822772)
 		"libc_ndk",          // http://b/187013218, cc_library_static, depends on //bionic/libm:libm (http://b/183064661)
 		"libc_malloc_hooks", // http://b/187016307, cc_library, ld.lld: error: undefined symbol: __malloc_hook
-		"libm",              // http://b/183064661, cc_library, math.h:25:16: error: unexpected token in argument list
 
 		// http://b/186823769: Needs C++ STL support, includes from unconverted standard libraries in //external/libcxx
 		// c++_static
@@ -189,7 +188,7 @@
 		"libBionicBenchmarksUtils", // cc_library_static, fatal error: 'map' file not found, from libcxx
 		"fmtlib",                   // cc_library_static, fatal error: 'cassert' file not found, from libcxx
 		"fmtlib_ndk",               // cc_library_static, fatal error: 'cassert' file not found
-		"libbase",                  // http://b/186826479, cc_library, fatal error: 'memory' file not found, from libcxx
+		"libbase",                  // Requires liblog. http://b/186826479, cc_library, fatal error: 'memory' file not found, from libcxx.
 
 		// http://b/186024507: Includes errors because of the system_shared_libs default value.
 		// Missing -isystem bionic/libc/include through the libc/libm/libdl
diff --git a/android/config.go b/android/config.go
index ed90c31..396b1a6 100644
--- a/android/config.go
+++ b/android/config.go
@@ -821,6 +821,12 @@
 	return Bool(c.productVariables.Unbundled_build_apps)
 }
 
+// Returns true if building image that aren't bundled with the platform.
+// UnbundledBuild() is always true when this is true.
+func (c *config) UnbundledBuildImage() bool {
+	return Bool(c.productVariables.Unbundled_build_image)
+}
+
 // Returns true if building modules against prebuilt SDKs.
 func (c *config) AlwaysUsePrebuiltSdks() bool {
 	return Bool(c.productVariables.Always_use_prebuilt_sdks)
diff --git a/android/module.go b/android/module.go
index 196b095..11f63bd 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2812,44 +2812,85 @@
 	return m.bp
 }
 
-// SrcIsModule decodes module references in the format ":name" into the module name, or empty string if the input
-// was not a module reference.
+// SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name"
+// into the module name, or empty string if the input was not a module reference.
 func SrcIsModule(s string) (module string) {
-	if len(s) > 1 && s[0] == ':' {
-		return s[1:]
+	if len(s) > 1 {
+		if s[0] == ':' {
+			module = s[1:]
+			if !isUnqualifiedModuleName(module) {
+				// The module name should be unqualified but is not so do not treat it as a module.
+				module = ""
+			}
+		} else if s[0] == '/' && s[1] == '/' {
+			module = s
+		}
 	}
-	return ""
+	return module
 }
 
-// SrcIsModule decodes module references in the format ":name{.tag}" into the module name and tag, ":name" into the
-// module name and an empty string for the tag, or empty strings if the input was not a module reference.
+// SrcIsModuleWithTag decodes module references in the format ":unqualified-name{.tag}" or
+// "//namespace:name{.tag}" into the module name and tag, ":unqualified-name" or "//namespace:name"
+// into the module name and an empty string for the tag, or empty strings if the input was not a
+// module reference.
 func SrcIsModuleWithTag(s string) (module, tag string) {
-	if len(s) > 1 && s[0] == ':' {
-		module = s[1:]
-		if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
-			if module[len(module)-1] == '}' {
-				tag = module[tagStart+1 : len(module)-1]
-				module = module[:tagStart]
-				return module, tag
+	if len(s) > 1 {
+		if s[0] == ':' {
+			module = s[1:]
+		} else if s[0] == '/' && s[1] == '/' {
+			module = s
+		}
+
+		if module != "" {
+			if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
+				if module[len(module)-1] == '}' {
+					tag = module[tagStart+1 : len(module)-1]
+					module = module[:tagStart]
+				}
+			}
+
+			if s[0] == ':' && !isUnqualifiedModuleName(module) {
+				// The module name should be unqualified but is not so do not treat it as a module.
+				module = ""
+				tag = ""
 			}
 		}
-		return module, ""
 	}
-	return "", ""
+
+	return module, tag
 }
 
+// isUnqualifiedModuleName makes sure that the supplied module is an unqualified module name, i.e.
+// does not contain any /.
+func isUnqualifiedModuleName(module string) bool {
+	return strings.IndexByte(module, '/') == -1
+}
+
+// sourceOrOutputDependencyTag is the dependency tag added automatically by pathDepsMutator for any
+// module reference in a property annotated with `android:"path"` or passed to ExtractSourceDeps
+// or ExtractSourcesDeps.
+//
+// If uniquely identifies the dependency that was added as it contains both the module name used to
+// add the dependency as well as the tag. That makes it very simple to find the matching dependency
+// in GetModuleFromPathDep as all it needs to do is find the dependency whose tag matches the tag
+// used to add it. It does not need to check that the module name as returned by one of
+// Module.Name(), BaseModuleContext.OtherModuleName() or ModuleBase.BaseModuleName() matches the
+// name supplied in the tag. That means it does not need to handle differences in module names
+// caused by prebuilt_ prefix, or fully qualified module names.
 type sourceOrOutputDependencyTag struct {
 	blueprint.BaseDependencyTag
+
+	// The name of the module.
+	moduleName string
+
+	// The tag that will be passed to the module's OutputFileProducer.OutputFiles(tag) method.
 	tag string
 }
 
-func sourceOrOutputDepTag(tag string) blueprint.DependencyTag {
-	return sourceOrOutputDependencyTag{tag: tag}
+func sourceOrOutputDepTag(moduleName, tag string) blueprint.DependencyTag {
+	return sourceOrOutputDependencyTag{moduleName: moduleName, tag: tag}
 }
 
-// Deprecated, use IsSourceDepTagWithOutputTag(tag, "") instead.
-var SourceDepTag = sourceOrOutputDepTag("")
-
 // IsSourceDepTag returns true if the supplied blueprint.DependencyTag is one that was used to add
 // dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for properties
 // tagged with `android:"path"`.
@@ -2880,7 +2921,7 @@
 				ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
 			} else {
 				set[s] = true
-				ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
+				ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
 			}
 		}
 	}
@@ -2893,7 +2934,7 @@
 func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
 	if s != nil {
 		if m, t := SrcIsModuleWithTag(*s); m != "" {
-			ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
+			ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
 		}
 	}
 }
diff --git a/android/module_test.go b/android/module_test.go
index 9ac9291..9e2b0ca 100644
--- a/android/module_test.go
+++ b/android/module_test.go
@@ -55,6 +55,27 @@
 			},
 			wantModule: "foo:bar",
 		},
+		{
+			name: "fully qualified",
+			args: args{
+				s: "//foo:bar",
+			},
+			wantModule: "//foo:bar",
+		},
+		{
+			name: "fully qualified with tag",
+			args: args{
+				s: "//foo:bar{.tag}",
+			},
+			wantModule: "//foo:bar{.tag}",
+		},
+		{
+			name: "invalid unqualified name",
+			args: args{
+				s: ":foo/bar",
+			},
+			wantModule: "",
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -128,6 +149,35 @@
 			},
 			wantModule: "foo.bar}",
 		},
+		{
+			name: "fully qualified",
+			args: args{
+				s: "//foo:bar",
+			},
+			wantModule: "//foo:bar",
+		},
+		{
+			name: "fully qualified with tag",
+			args: args{
+				s: "//foo:bar{.tag}",
+			},
+			wantModule: "//foo:bar",
+			wantTag:    ".tag",
+		},
+		{
+			name: "invalid unqualified name",
+			args: args{
+				s: ":foo/bar",
+			},
+			wantModule: "",
+		},
+		{
+			name: "invalid unqualified name with tag",
+			args: args{
+				s: ":foo/bar{.tag}",
+			},
+			wantModule: "",
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
diff --git a/android/path_properties.go b/android/path_properties.go
index 4446773..3976880 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -51,7 +51,7 @@
 	// Add dependencies to anything that is a module reference.
 	for _, s := range pathProperties {
 		if m, t := SrcIsModuleWithTag(s); m != "" {
-			ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
+			ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
 		}
 	}
 }
diff --git a/android/paths.go b/android/paths.go
index c5e4806..bec8a51 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -88,7 +88,8 @@
 // the Path methods that rely on module dependencies having been resolved.
 type ModuleWithDepsPathContext interface {
 	EarlyModulePathContext
-	GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
+	VisitDirectDepsBlueprint(visit func(blueprint.Module))
+	OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
 }
 
 // ModuleMissingDepsPathContext is a subset of *ModuleContext methods required by
@@ -484,10 +485,27 @@
 //
 // If tag is "" then the returned module will be the dependency that was added for ":moduleName".
 // Otherwise, it is the dependency that was added for ":moduleName{tag}".
-//
-// TODO(b/193228441) Make this handle fully qualified names, e.g. //namespace:moduleName.
 func GetModuleFromPathDep(ctx ModuleWithDepsPathContext, moduleName, tag string) blueprint.Module {
-	return ctx.GetDirectDepWithTag(moduleName, sourceOrOutputDepTag(tag))
+	var found blueprint.Module
+	// The sourceOrOutputDepTag uniquely identifies the module dependency as it contains both the
+	// module name and the tag. Dependencies added automatically for properties tagged with
+	// `android:"path"` are deduped so are guaranteed to be unique. It is possible for duplicate
+	// dependencies to be added manually using ExtractSourcesDeps or ExtractSourceDeps but even then
+	// it will always be the case that the dependencies will be identical, i.e. the same tag and same
+	// moduleName referring to the same dependency module.
+	//
+	// It does not matter whether the moduleName is a fully qualified name or if the module
+	// dependency is a prebuilt module. All that matters is the same information is supplied to
+	// create the tag here as was supplied to create the tag when the dependency was added so that
+	// this finds the matching dependency module.
+	expectedTag := sourceOrOutputDepTag(moduleName, tag)
+	ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
+		depTag := ctx.OtherModuleDependencyTag(module)
+		if depTag == expectedTag {
+			found = module
+		}
+	})
+	return found
 }
 
 // PathsAndMissingDepsForModuleSrcExcludes returns a Paths{} containing the resolved references in
@@ -1268,10 +1286,11 @@
 // PathForModuleSrc returns a Path representing the paths... under the
 // module's local source directory.
 func PathForModuleSrc(ctx ModuleMissingDepsPathContext, pathComponents ...string) Path {
-	p, err := validatePath(pathComponents...)
-	if err != nil {
-		reportPathError(ctx, err)
-	}
+	// Just join the components textually just to make sure that it does not corrupt a fully qualified
+	// module reference, e.g. if the pathComponents is "://other:foo" then using filepath.Join() or
+	// validatePath() will corrupt it, e.g. replace "//" with "/". If the path is not a module
+	// reference then it will be validated by expandOneSrcPath anyway when it calls expandOneSrcPath.
+	p := strings.Join(pathComponents, string(filepath.Separator))
 	paths, err := expandOneSrcPath(ctx, p, nil)
 	if err != nil {
 		if depErr, ok := err.(missingDependencyError); ok {
diff --git a/android/paths_test.go b/android/paths_test.go
index 6f5d79e..f4e4ce1 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -1125,6 +1125,12 @@
 	rels []string
 	src  string
 	rel  string
+
+	// Make test specific preparations to the test fixture.
+	preparer FixturePreparer
+
+	// A test specific error handler.
+	errorHandler FixtureErrorHandler
 }
 
 func testPathForModuleSrc(t *testing.T, tests []pathForModuleSrcTestCase) {
@@ -1157,14 +1163,23 @@
 				"foo/src_special/$": nil,
 			}
 
+			errorHandler := test.errorHandler
+			if errorHandler == nil {
+				errorHandler = FixtureExpectsNoErrors
+			}
+
 			result := GroupFixturePreparers(
 				FixtureRegisterWithContext(func(ctx RegistrationContext) {
 					ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
 					ctx.RegisterModuleType("output_file_provider", pathForModuleSrcOutputFileProviderModuleFactory)
-					ctx.RegisterModuleType("filegroup", FileGroupFactory)
 				}),
+				PrepareForTestWithFilegroup,
+				PrepareForTestWithNamespace,
 				mockFS.AddToFixture(),
-			).RunTest(t)
+				OptionalFixturePreparer(test.preparer),
+			).
+				ExtendWithErrorHandler(errorHandler).
+				RunTest(t)
 
 			m := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
 
@@ -1333,6 +1348,73 @@
 			src: "foo/src_special/$",
 			rel: "src_special/$",
 		},
+		{
+			// This test makes sure that an unqualified module name cannot contain characters that make
+			// it appear as a qualified module name.
+			name: "output file provider, invalid fully qualified name",
+			bp: `
+			test {
+				name: "foo",
+				src: "://other:b",
+				srcs: ["://other:c"],
+			}`,
+			preparer: FixtureAddTextFile("other/Android.bp", `
+				soong_namespace {}
+
+				output_file_provider {
+					name: "b",
+					outs: ["gen/b"],
+				}
+
+				output_file_provider {
+					name: "c",
+					outs: ["gen/c"],
+				}
+			`),
+			src:  "foo/:/other:b",
+			rel:  ":/other:b",
+			srcs: []string{"foo/:/other:c"},
+			rels: []string{":/other:c"},
+		},
+		{
+			name: "output file provider, missing fully qualified name",
+			bp: `
+			test {
+				name: "foo",
+				src: "//other:b",
+				srcs: ["//other:c"],
+			}`,
+			errorHandler: FixtureExpectsAllErrorsToMatchAPattern([]string{
+				`"foo" depends on undefined module "//other:b"`,
+				`"foo" depends on undefined module "//other:c"`,
+			}),
+		},
+		{
+			name: "output file provider, fully qualified name",
+			bp: `
+			test {
+				name: "foo",
+				src: "//other:b",
+				srcs: ["//other:c"],
+			}`,
+			src:  "out/soong/.intermediates/other/b/gen/b",
+			rel:  "gen/b",
+			srcs: []string{"out/soong/.intermediates/other/c/gen/c"},
+			rels: []string{"gen/c"},
+			preparer: FixtureAddTextFile("other/Android.bp", `
+				soong_namespace {}
+
+				output_file_provider {
+					name: "b",
+					outs: ["gen/b"],
+				}
+
+				output_file_provider {
+					name: "c",
+					outs: ["gen/c"],
+				}
+			`),
+		},
 	}
 
 	testPathForModuleSrc(t, tests)
diff --git a/android/prebuilt.go b/android/prebuilt.go
index f3493bd..e611502 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -61,6 +61,16 @@
 	// a matching name.
 	Prefer *bool `android:"arch_variant"`
 
+	// When specified this names a Soong config variable that controls the prefer property.
+	//
+	// If the value of the named Soong config variable is true then prefer is set to false and vice
+	// versa. If the Soong config variable is not set then it defaults to false, so prefer defaults
+	// to true.
+	//
+	// If specified then the prefer property is ignored in favor of the value of the Soong config
+	// variable.
+	Use_source_config_var *ConfigVarProperties
+
 	SourceExists bool `blueprint:"mutated"`
 	UsePrebuilt  bool `blueprint:"mutated"`
 
@@ -68,6 +78,22 @@
 	PrebuiltRenamedToSource bool `blueprint:"mutated"`
 }
 
+// Properties that can be used to select a Soong config variable.
+type ConfigVarProperties struct {
+	// Allow instances of this struct to be used as a property value in a BpPropertySet.
+	BpPrintableBase
+
+	// The name of the configuration namespace.
+	//
+	// As passed to add_soong_config_namespace in Make.
+	Config_namespace *string
+
+	// The name of the configuration variable.
+	//
+	// As passed to add_soong_config_var_value in Make.
+	Var_name *string
+}
+
 type Prebuilt struct {
 	properties PrebuiltProperties
 
@@ -364,12 +390,18 @@
 		return false
 	}
 
-	// TODO: use p.Properties.Name and ctx.ModuleDir to override preference
-	if Bool(p.properties.Prefer) {
+	// If source is not available or is disabled then always use the prebuilt.
+	if source == nil || !source.Enabled() {
 		return true
 	}
 
-	return source == nil || !source.Enabled()
+	// If the use_source_config_var property is set then it overrides the prefer property setting.
+	if configVar := p.properties.Use_source_config_var; configVar != nil {
+		return !ctx.Config().VendorConfig(proptools.String(configVar.Config_namespace)).Bool(proptools.String(configVar.Var_name))
+	}
+
+	// TODO: use p.Properties.Name and ctx.ModuleDir to override preference
+	return Bool(p.properties.Prefer)
 }
 
 func (p *Prebuilt) SourceExists() bool {
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 23524a5..dcd77ea 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -26,6 +26,7 @@
 	replaceBp bool // modules is added to default bp boilerplate if false.
 	modules   string
 	prebuilt  []OsType
+	preparer  FixturePreparer
 }{
 	{
 		name: "no prebuilt",
@@ -291,6 +292,86 @@
 			}`,
 		prebuilt: []OsType{Android, BuildOs},
 	},
+	{
+		name: "prebuilt use_source_config_var={acme, use_source} - no var specified",
+		modules: `
+			source {
+				name: "bar",
+			}
+
+			prebuilt {
+				name: "bar",
+				use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
+				srcs: ["prebuilt_file"],
+			}`,
+		// When use_source_env is specified then it will use the prebuilt by default if the environment
+		// variable is not set.
+		prebuilt: []OsType{Android, BuildOs},
+	},
+	{
+		name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=false",
+		modules: `
+			source {
+				name: "bar",
+			}
+
+			prebuilt {
+				name: "bar",
+				use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
+				srcs: ["prebuilt_file"],
+			}`,
+		preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+			variables.VendorVars = map[string]map[string]string{
+				"acme": {
+					"use_source": "false",
+				},
+			}
+		}),
+		// Setting the environment variable named in use_source_env to false will cause the prebuilt to
+		// be used.
+		prebuilt: []OsType{Android, BuildOs},
+	},
+	{
+		name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true",
+		modules: `
+			source {
+				name: "bar",
+			}
+
+			prebuilt {
+				name: "bar",
+				use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
+				srcs: ["prebuilt_file"],
+			}`,
+		preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+			variables.VendorVars = map[string]map[string]string{
+				"acme": {
+					"use_source": "true",
+				},
+			}
+		}),
+		// Setting the environment variable named in use_source_env to true will cause the source to be
+		// used.
+		prebuilt: nil,
+	},
+	{
+		name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true, no source",
+		modules: `
+			prebuilt {
+				name: "bar",
+				use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
+				srcs: ["prebuilt_file"],
+			}`,
+		preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+			variables.VendorVars = map[string]map[string]string{
+				"acme": {
+					"use_source": "true",
+				},
+			}
+		}),
+		// Although the environment variable says to use source there is no source available.
+		prebuilt: []OsType{Android, BuildOs},
+	},
 }
 
 func TestPrebuilts(t *testing.T) {
@@ -329,6 +410,7 @@
 				}),
 				fs.AddToFixture(),
 				FixtureRegisterWithContext(registerTestPrebuiltModules),
+				OptionalFixturePreparer(test.preparer),
 			).RunTestWithBp(t, bp)
 
 			for _, variant := range result.ModuleVariantsForTests("foo") {
diff --git a/android/soong_config_modules_test.go b/android/soong_config_modules_test.go
index 8f252d9..b2f8eaa 100644
--- a/android/soong_config_modules_test.go
+++ b/android/soong_config_modules_test.go
@@ -313,6 +313,51 @@
 	})
 }
 
+func TestNonExistentPropertyInSoongConfigModule(t *testing.T) {
+	bp := `
+		soong_config_module_type {
+			name: "acme_test",
+			module_type: "test",
+			config_namespace: "acme",
+			bool_variables: ["feature1"],
+			properties: ["made_up_property"],
+		}
+
+		acme_test {
+			name: "foo",
+			cflags: ["-DGENERIC"],
+			soong_config_variables: {
+				feature1: {
+					made_up_property: true,
+				},
+			},
+		}
+    `
+
+	fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
+		return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+			variables.VendorVars = vars
+		})
+	}
+
+	GroupFixturePreparers(
+		fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
+		PrepareForTestWithDefaults,
+		FixtureRegisterWithContext(func(ctx RegistrationContext) {
+			ctx.RegisterModuleType("soong_config_module_type_import", soongConfigModuleTypeImportFactory)
+			ctx.RegisterModuleType("soong_config_module_type", soongConfigModuleTypeFactory)
+			ctx.RegisterModuleType("soong_config_string_variable", soongConfigStringVariableDummyFactory)
+			ctx.RegisterModuleType("soong_config_bool_variable", soongConfigBoolVariableDummyFactory)
+			ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
+			ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
+		}),
+		FixtureWithRootAndroidBp(bp),
+	).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
+		// TODO(b/171232169): improve the error message for non-existent properties
+		`unrecognized property "soong_config_variables`,
+	})).RunTest(t)
+}
+
 func testConfigWithVendorVars(buildDir, bp string, fs map[string][]byte, vendorVars map[string]map[string]string) Config {
 	config := TestConfig(buildDir, nil, bp, fs)
 
diff --git a/android/variable.go b/android/variable.go
index b6e168c..bbb9868 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -225,6 +225,7 @@
 	Allow_missing_dependencies   *bool `json:",omitempty"`
 	Unbundled_build              *bool `json:",omitempty"`
 	Unbundled_build_apps         *bool `json:",omitempty"`
+	Unbundled_build_image        *bool `json:",omitempty"`
 	Always_use_prebuilt_sdks     *bool `json:",omitempty"`
 	Skip_boot_jars_check         *bool `json:",omitempty"`
 	Malloc_not_svelte            *bool `json:",omitempty"`
diff --git a/apex/apex_test.go b/apex/apex_test.go
index b5b1d44..422e46c 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -4687,16 +4687,26 @@
 		p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
 		dexJarBuildPath := p.DexJarBuildPath()
 		stem := android.RemoveOptionalPrebuiltPrefix(name)
-		if expected, actual := ".intermediates/myapex.deapexer/android_common/deapexer/javalib/"+stem+".jar", android.NormalizePathForTesting(dexJarBuildPath); actual != expected {
-			t.Errorf("Incorrect DexJarBuildPath value '%s', expected '%s'", actual, expected)
-		}
+		android.AssertStringEquals(t, "DexJarBuildPath should be apex-related path.",
+			".intermediates/myapex.deapexer/android_common/deapexer/javalib/"+stem+".jar",
+			android.NormalizePathForTesting(dexJarBuildPath))
+	}
+
+	checkDexJarInstallPath := func(t *testing.T, ctx *android.TestContext, name string) {
+		// Make sure the import has been given the correct path to the dex jar.
+		p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
+		dexJarBuildPath := p.DexJarInstallPath()
+		stem := android.RemoveOptionalPrebuiltPrefix(name)
+		android.AssertStringEquals(t, "DexJarInstallPath should be apex-related path.",
+			"target/product/test_device/apex/myapex/javalib/"+stem+".jar",
+			android.NormalizePathForTesting(dexJarBuildPath))
 	}
 
 	ensureNoSourceVariant := func(t *testing.T, ctx *android.TestContext, name string) {
 		// Make sure that an apex variant is not created for the source module.
-		if expected, actual := []string{"android_common"}, ctx.ModuleVariantsForTests(name); !reflect.DeepEqual(expected, actual) {
-			t.Errorf("invalid set of variants for %q: expected %q, found %q", "libfoo", expected, actual)
-		}
+		android.AssertArrayString(t, "Check if there is no source variant",
+			[]string{"android_common"},
+			ctx.ModuleVariantsForTests(name))
 	}
 
 	t.Run("prebuilt only", func(t *testing.T) {
@@ -4745,8 +4755,10 @@
 		}
 
 		checkDexJarBuildPath(t, ctx, "libfoo")
+		checkDexJarInstallPath(t, ctx, "libfoo")
 
 		checkDexJarBuildPath(t, ctx, "libbar")
+		checkDexJarInstallPath(t, ctx, "libbar")
 	})
 
 	t.Run("prebuilt with source preferred", func(t *testing.T) {
@@ -4792,9 +4804,11 @@
 		ctx := testDexpreoptWithApexes(t, bp, "", transform)
 
 		checkDexJarBuildPath(t, ctx, "prebuilt_libfoo")
+		checkDexJarInstallPath(t, ctx, "prebuilt_libfoo")
 		ensureNoSourceVariant(t, ctx, "libfoo")
 
 		checkDexJarBuildPath(t, ctx, "prebuilt_libbar")
+		checkDexJarInstallPath(t, ctx, "prebuilt_libbar")
 		ensureNoSourceVariant(t, ctx, "libbar")
 	})
 
@@ -4842,9 +4856,11 @@
 		ctx := testDexpreoptWithApexes(t, bp, "", transform)
 
 		checkDexJarBuildPath(t, ctx, "prebuilt_libfoo")
+		checkDexJarInstallPath(t, ctx, "prebuilt_libfoo")
 		ensureNoSourceVariant(t, ctx, "libfoo")
 
 		checkDexJarBuildPath(t, ctx, "prebuilt_libbar")
+		checkDexJarInstallPath(t, ctx, "prebuilt_libbar")
 		ensureNoSourceVariant(t, ctx, "libbar")
 	})
 }
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index 279cf54..7209c02 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -398,6 +398,7 @@
 			name: "foo",
 			prefer: false,
 			shared_library: false,
+			permitted_packages: ["foo"],
 			public: {
 				jars: ["sdk_library/public/foo-stubs.jar"],
 				stub_srcs: ["sdk_library/public/foo_stub_sources"],
diff --git a/bazel/properties.go b/bazel/properties.go
index 0dd47da..7ecc92b 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -558,6 +558,19 @@
 	return len(lla.ConfigurableValues) > 0
 }
 
+// IsEmpty returns true if the attribute has no values under any configuration.
+func (lla LabelListAttribute) IsEmpty() bool {
+	if len(lla.Value.Includes) > 0 {
+		return false
+	}
+	for axis, _ := range lla.ConfigurableValues {
+		if lla.ConfigurableValues[axis].HasConfigurableValues() {
+			return false
+		}
+	}
+	return true
+}
+
 // ResolveExcludes handles excludes across the various axes, ensuring that items are removed from
 // the base value and included in default values as appropriate.
 func (lla *LabelListAttribute) ResolveExcludes() {
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 285677a..4f720f5 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -674,6 +674,10 @@
 		blueprint: soongCcLibraryPreamble,
 		expectedBazelTargets: []string{`cc_library(
     name = "a",
+    asflags = [
+        "-Ifoo/bar",
+        "-I$(BINDIR)/foo/bar",
+    ],
     copts = [
         "-Ifoo/bar",
         "-I$(BINDIR)/foo/bar",
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 40edec8..c33889f 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -1413,7 +1413,7 @@
 
 func TestCcLibraryStaticProductVariableStringReplacement(t *testing.T) {
 	runCcLibraryStaticTestCase(t, bp2buildTestCase{
-		description:                        "cc_library_static product variable selects",
+		description:                        "cc_library_static product variable string replacement",
 		moduleTypeUnderTest:                "cc_library_static",
 		moduleTypeUnderTestFactory:         cc.LibraryStaticFactory,
 		moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
@@ -1422,7 +1422,7 @@
 		blueprint: soongCcLibraryStaticPreamble + `
 cc_library_static {
     name: "foo_static",
-    srcs: ["common.c"],
+    srcs: ["common.S"],
     product_variables: {
       platform_sdk_version: {
           asflags: ["-DPLATFORM_SDK_VERSION=%d"],
@@ -1431,7 +1431,10 @@
 } `,
 		expectedBazelTargets: []string{`cc_library_static(
     name = "foo_static",
-    asflags = select({
+    asflags = [
+        "-I.",
+        "-I$(BINDIR)/.",
+    ] + select({
         "//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"],
         "//conditions:default": [],
     }),
@@ -1440,7 +1443,7 @@
         "-I$(BINDIR)/.",
     ],
     linkstatic = True,
-    srcs_c = ["common.c"],
+    srcs_as = ["common.S"],
 )`},
 	})
 }
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index 8ede226..df4924b 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -211,6 +211,7 @@
             asflags: ["-DPLATFORM_SDK_VERSION=%d"],
         },
     },
+    srcs: ["src.S"],
 }
 `,
 		expectedBazelTargets: []string{`cc_object(
@@ -220,6 +221,7 @@
         "//conditions:default": [],
     }),
     copts = ["-fno-addrsig"],
+    srcs_as = ["src.S"],
 )`,
 		},
 	})
@@ -240,7 +242,7 @@
             cflags: ["-fPIC"], // string list
         },
         arm: {
-            srcs: ["arch/arm/file.S"], // label list
+            srcs: ["arch/arm/file.cpp"], // label list
         },
     },
 }
@@ -257,7 +259,7 @@
         "//conditions:default": [],
     }),
     srcs = ["a.cpp"] + select({
-        "//build/bazel/platforms/arch:arm": ["arch/arm/file.S"],
+        "//build/bazel/platforms/arch:arm": ["arch/arm/file.cpp"],
         "//conditions:default": [],
     }),
 )`,
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index adb0a7b..a608630 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -136,6 +136,10 @@
 		Name: "removeScudoProperty",
 		Fix:  runPatchListMod(removeObsoleteProperty("sanitize.scudo")),
 	},
+	{
+		Name: "formatFlagProperties",
+		Fix:  runPatchListMod(formatFlagProperties),
+	},
 }
 
 func NewFixRequest() FixRequest {
@@ -1343,3 +1347,69 @@
 	}
 	return false
 }
+
+func formatFlagProperty(mod *parser.Module, field string, buf []byte, patchlist *parser.PatchList) error {
+	// the comment or empty lines in the value of the field are skipped
+	listValue, ok := getLiteralListProperty(mod, field)
+	if !ok {
+		// if do not find
+		return nil
+	}
+	for i := 0; i < len(listValue.Values); i++ {
+		curValue, ok := listValue.Values[i].(*parser.String)
+		if !ok {
+			return fmt.Errorf("Expecting string for %s.%s fields", mod.Type, field)
+		}
+		if !strings.HasPrefix(curValue.Value, "-") {
+			return fmt.Errorf("Expecting the string `%s` starting with '-'", curValue.Value)
+		}
+		if i+1 < len(listValue.Values) {
+			nextValue, ok := listValue.Values[i+1].(*parser.String)
+			if !ok {
+				return fmt.Errorf("Expecting string for %s.%s fields", mod.Type, field)
+			}
+			if !strings.HasPrefix(nextValue.Value, "-") {
+				// delete the line
+				err := patchlist.Add(curValue.Pos().Offset, curValue.End().Offset+2, "")
+				if err != nil {
+					return err
+				}
+				// replace the line
+				value := "\"" + curValue.Value + " " + nextValue.Value + "\","
+				err = patchlist.Add(nextValue.Pos().Offset, nextValue.End().Offset+1, value)
+				if err != nil {
+					return err
+				}
+				// combined two lines to one
+				i++
+			}
+		}
+	}
+	return nil
+}
+
+func formatFlagProperties(mod *parser.Module, buf []byte, patchlist *parser.PatchList) error {
+	relevantFields := []string{
+		// cc flags
+		"asflags",
+		"cflags",
+		"clang_asflags",
+		"clang_cflags",
+		"conlyflags",
+		"cppflags",
+		"ldflags",
+		"tidy_flags",
+		// java flags
+		"aaptflags",
+		"dxflags",
+		"javacflags",
+		"kotlincflags",
+	}
+	for _, field := range relevantFields {
+		err := formatFlagProperty(mod, field, buf, patchlist)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go
index b994e25..d8772c1 100644
--- a/bpfix/bpfix/bpfix_test.go
+++ b/bpfix/bpfix/bpfix_test.go
@@ -1336,3 +1336,275 @@
 		})
 	}
 }
+
+func TestFormatFlagProperty(t *testing.T) {
+	tests := []struct {
+		name string
+		in   string
+		out  string
+	}{
+		{
+			name: "group options and values for apptflags, dxflags, javacflags, and kotlincflags",
+			in: `
+				android_test {
+					name: "foo",
+					aaptflags: [
+						// comment1_1
+						"--flag1",
+						// comment1_2
+						"1",
+						// comment2_1
+						// comment2_2
+						"--flag2",
+						// comment3_1
+						// comment3_2
+						// comment3_3
+						"--flag3",
+						// comment3_4
+						// comment3_5
+						// comment3_6
+						"3",
+						// other comment1_1
+						// other comment1_2
+					],
+					dxflags: [
+						"--flag1",
+						// comment1_1
+						"1",
+						// comment2_1
+						"--flag2",
+						// comment3_1
+						"--flag3",
+						// comment3_2
+						"3",
+					],
+					javacflags: [
+						"--flag1",
+
+						"1",
+						"--flag2",
+						"--flag3",
+						"3",
+					],
+					kotlincflags: [
+
+						"--flag1",
+						"1",
+
+						"--flag2",
+						"--flag3",
+						"3",
+
+					],
+				}
+			`,
+			out: `
+				android_test {
+					name: "foo",
+					aaptflags: [
+						// comment1_1
+						// comment1_2
+						"--flag1 1",
+						// comment2_1
+						// comment2_2
+						"--flag2",
+						// comment3_1
+						// comment3_2
+						// comment3_3
+						// comment3_4
+						// comment3_5
+						// comment3_6
+						"--flag3 3",
+						// other comment1_1
+						// other comment1_2
+					],
+					dxflags: [
+						// comment1_1
+						"--flag1 1",
+						// comment2_1
+						"--flag2",
+						// comment3_1
+						// comment3_2
+						"--flag3 3",
+					],
+					javacflags: [
+
+						"--flag1 1",
+						"--flag2",
+						"--flag3 3",
+					],
+					kotlincflags: [
+
+						"--flag1 1",
+
+						"--flag2",
+						"--flag3 3",
+
+					],
+				}
+			`,
+		},
+		{
+			name: "group options and values for asflags, cflags, clang_asflags, clang_cflags, conlyflags, cppflags, ldflags, and tidy_flags",
+			in: `
+				cc_test {
+					name: "foo",
+					asflags: [
+						// comment1_1
+						"--flag1",
+						"1",
+						// comment2_1
+						// comment2_2
+						"--flag2",
+						// comment2_3
+						"2",
+						// comment3_1
+						// comment3_2
+						"--flag3",
+						// comment3_3
+						// comment3_4
+						// comment3_4
+						"3",
+						// comment4_1
+						// comment4_2
+						// comment4_3
+						"--flag4",
+					],
+					cflags: [
+						"--flag1",
+						"1",
+						"--flag2",
+						"2",
+						"--flag3",
+						"3",
+						"--flag4",
+					],
+					clang_asflags: [
+						"--flag1",
+						"1",
+						"--flag2",
+						"2",
+						"--flag3",
+						"3",
+						"--flag4",
+					],
+					clang_cflags: [
+						"--flag1",
+						"1",
+						"--flag2",
+						"2",
+						"--flag3",
+						"3",
+						"--flag4",
+					],
+					conlyflags: [
+						"--flag1",
+						"1",
+						"--flag2",
+						"2",
+						"--flag3",
+						"3",
+						"--flag4",
+					],
+					cppflags: [
+						"--flag1",
+						"1",
+						"--flag2",
+						"2",
+						"--flag3",
+						"3",
+						"--flag4",
+					],
+					ldflags: [
+						"--flag1",
+						"1",
+						"--flag2",
+						"2",
+						"--flag3",
+						"3",
+						"--flag4",
+					],
+					tidy_flags: [
+						"--flag1",
+						"1",
+						"--flag2",
+						"2",
+						"--flag3",
+						"3",
+						"--flag4",
+					],
+				}
+			`,
+			out: `
+				cc_test {
+					name: "foo",
+					asflags: [
+						// comment1_1
+						"--flag1 1",
+						// comment2_1
+						// comment2_2
+						// comment2_3
+						"--flag2 2",
+						// comment3_1
+						// comment3_2
+						// comment3_3
+						// comment3_4
+						// comment3_4
+						"--flag3 3",
+						// comment4_1
+						// comment4_2
+						// comment4_3
+						"--flag4",
+					],
+					cflags: [
+						"--flag1 1",
+						"--flag2 2",
+						"--flag3 3",
+						"--flag4",
+					],
+					clang_asflags: [
+						"--flag1 1",
+						"--flag2 2",
+						"--flag3 3",
+						"--flag4",
+					],
+					clang_cflags: [
+						"--flag1 1",
+						"--flag2 2",
+						"--flag3 3",
+						"--flag4",
+					],
+					conlyflags: [
+						"--flag1 1",
+						"--flag2 2",
+						"--flag3 3",
+						"--flag4",
+					],
+					cppflags: [
+						"--flag1 1",
+						"--flag2 2",
+						"--flag3 3",
+						"--flag4",
+					],
+					ldflags: [
+						"--flag1 1",
+						"--flag2 2",
+						"--flag3 3",
+						"--flag4",
+					],
+					tidy_flags: [
+						"--flag1 1",
+						"--flag2 2",
+						"--flag3 3",
+						"--flag4",
+					],
+				}
+			`,
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			runPass(t, test.in, test.out, runPatchListMod(formatFlagProperties))
+		})
+	}
+}
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 76c5f3b..536f112 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -90,8 +90,11 @@
 
 		// TODO(b/186024507, b/186489250): Temporarily exclude adding
 		// system_shared_libs deps until libc and libm builds.
-		// allDeps = append(allDeps, lib.SharedProperties.Shared.System_shared_libs...)
-		// allDeps = append(allDeps, lib.StaticProperties.Static.System_shared_libs...)
+		if lib.static() {
+			allDeps = append(allDeps, lib.StaticProperties.Static.System_shared_libs...)
+		} else if lib.shared() {
+			allDeps = append(allDeps, lib.SharedProperties.Shared.System_shared_libs...)
+		}
 
 		// Deps in the target/arch nested static: { .. } and shared: { .. } props of a cc_library.
 		// target: { <target>: shared: { ... } }
@@ -253,7 +256,7 @@
 		Copts:              bazel.StringListAttribute{Value: props.Cflags},
 		Srcs:               bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, props.Srcs)),
 		Static_deps:        bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Static_libs)),
-		Dynamic_deps:       bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Shared_libs)),
+		Dynamic_deps:       bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, append(props.Shared_libs, props.System_shared_libs...))),
 		Whole_archive_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs)),
 	}
 
@@ -385,16 +388,6 @@
 		return result
 	}
 
-	// Parse the list of copts.
-	parseCopts := func(baseCompilerProps *BaseCompilerProperties) []string {
-		var copts []string
-		copts = append(copts, parseCommandLineFlags(baseCompilerProps.Cflags)...)
-		for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
-			copts = append(copts, includeFlags(dir)...)
-		}
-		return copts
-	}
-
 	// Parse srcs from an arch or OS's props value.
 	parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList {
 		// Add srcs-like dependencies such as generated files.
@@ -410,11 +403,15 @@
 	for _, props := range module.compiler.compilerProps() {
 		if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
 			srcs.SetValue(parseSrcs(baseCompilerProps))
-			copts.Value = parseCopts(baseCompilerProps)
+			copts.Value = parseCommandLineFlags(baseCompilerProps.Cflags)
 			asFlags.Value = parseCommandLineFlags(baseCompilerProps.Asflags)
 			conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags)
 			cppFlags.Value = parseCommandLineFlags(baseCompilerProps.Cppflags)
 
+			for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
+				copts.Value = append(copts.Value, includeFlags(dir)...)
+				asFlags.Value = append(asFlags.Value, includeFlags(dir)...)
+			}
 			break
 		}
 	}
@@ -424,8 +421,10 @@
 	// "-I<module-dir>" in its copts.
 	if c, ok := module.compiler.(*baseCompiler); ok && c.includeBuildDirectory() {
 		copts.Value = append(copts.Value, includeFlags(".")...)
+		asFlags.Value = append(asFlags.Value, includeFlags(".")...)
 	} else if c, ok := module.compiler.(*libraryDecorator); ok && c.includeBuildDirectory() {
 		copts.Value = append(copts.Value, includeFlags(".")...)
+		asFlags.Value = append(asFlags.Value, includeFlags(".")...)
 	}
 
 	archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
@@ -440,8 +439,15 @@
 					srcs.SetSelectValue(axis, config, srcsList)
 				}
 
-				copts.SetSelectValue(axis, config, parseCopts(baseCompilerProps))
-				asFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Asflags))
+				archVariantCopts := parseCommandLineFlags(baseCompilerProps.Cflags)
+				archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags)
+				for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
+					archVariantCopts = append(archVariantCopts, includeFlags(dir)...)
+					archVariantAsflags = append(archVariantAsflags, includeFlags(dir)...)
+				}
+
+				copts.SetSelectValue(axis, config, archVariantCopts)
+				asFlags.SetSelectValue(axis, config, archVariantAsflags)
 				conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags))
 				cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Cppflags))
 			}
@@ -554,7 +560,9 @@
 			staticDeps.Value = android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)
 			wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
 			wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
-			sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
+			// TODO(b/186024507): Handle system_shared_libs as its own attribute, so that the appropriate default
+			// may be supported.
+			sharedLibs := android.FirstUniqueStrings(append(baseLinkerProps.Shared_libs, baseLinkerProps.System_shared_libs...))
 			dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
 
 			headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
@@ -581,7 +589,7 @@
 				staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs))
 				wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
 				wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
-				sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
+				sharedLibs := android.FirstUniqueStrings(append(baseLinkerProps.Shared_libs, baseLinkerProps.System_shared_libs...))
 				dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
 
 				headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
diff --git a/cc/builder.go b/cc/builder.go
index bde8c96..b0842ec 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -500,10 +500,10 @@
 		sAbiDumpFiles = make(android.Paths, 0, len(srcFiles))
 	}
 
-	cflags += " ${config.NoOverrideClangGlobalCflags}"
-	toolingCflags += " ${config.NoOverrideClangGlobalCflags}"
-	cppflags += " ${config.NoOverrideClangGlobalCflags}"
-	toolingCppflags += " ${config.NoOverrideClangGlobalCflags}"
+	cflags += " ${config.NoOverrideGlobalCflags}"
+	toolingCflags += " ${config.NoOverrideGlobalCflags}"
+	cppflags += " ${config.NoOverrideGlobalCflags}"
+	toolingCppflags += " ${config.NoOverrideGlobalCflags}"
 
 	for i, srcFile := range srcFiles {
 		objFile := android.ObjPathWithExt(ctx, subdir, srcFile, "o")
diff --git a/cc/cc.go b/cc/cc.go
index 90c0237..aeebaef 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -2014,9 +2014,9 @@
 }
 
 func GetSnapshot(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android.BottomUpMutatorContext) SnapshotInfo {
-	// Only modules with BOARD_VNDK_VERSION uses snapshot.  Others use the zero value of
+	// Only device modules with BOARD_VNDK_VERSION uses snapshot.  Others use the zero value of
 	// SnapshotInfo, which provides no mappings.
-	if *snapshotInfo == nil {
+	if *snapshotInfo == nil && c.Device() {
 		// Only retrieve the snapshot on demand in order to avoid circular dependencies
 		// between the modules in the snapshot and the snapshot itself.
 		var snapshotModule []blueprint.Module
@@ -2025,16 +2025,16 @@
 		} else if recoverySnapshotVersion := actx.DeviceConfig().RecoverySnapshotVersion(); recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" && c.InRecovery() {
 			snapshotModule = actx.AddVariationDependencies(nil, nil, "recovery_snapshot")
 		}
-		if len(snapshotModule) > 0 {
+		if len(snapshotModule) > 0 && snapshotModule[0] != nil {
 			snapshot := actx.OtherModuleProvider(snapshotModule[0], SnapshotInfoProvider).(SnapshotInfo)
 			*snapshotInfo = &snapshot
 			// republish the snapshot for use in later mutators on this module
 			actx.SetProvider(SnapshotInfoProvider, snapshot)
-		} else {
-			*snapshotInfo = &SnapshotInfo{}
 		}
 	}
-
+	if *snapshotInfo == nil {
+		*snapshotInfo = &SnapshotInfo{}
+	}
 	return **snapshotInfo
 }
 
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 0a74e58..0a3acb9 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -4038,14 +4038,14 @@
 	}
 
 	want := []string{
-		"${config.ArmClangThumbCflags}",
-		"${config.ArmClangCflags}",
-		"${config.CommonClangGlobalCflags}",
-		"${config.DeviceClangGlobalCflags}",
-		"${config.ClangExternalCflags}",
-		"${config.ArmToolchainClangCflags}",
-		"${config.ArmClangArmv7ANeonCflags}",
-		"${config.ArmClangGenericCflags}",
+		"${config.ArmThumbCflags}",
+		"${config.ArmCflags}",
+		"${config.CommonGlobalCflags}",
+		"${config.DeviceGlobalCflags}",
+		"${config.ExternalCflags}",
+		"${config.ArmToolchainCflags}",
+		"${config.ArmArmv7ANeonCflags}",
+		"${config.ArmGenericCflags}",
 		"android_arm_export_include_dirs",
 		"lib32_export_include_dirs",
 		"arm_export_include_dirs",
@@ -4076,7 +4076,7 @@
 		"defaults/cc/common/ndk_libandroid_support",
 		"out/soong/ndk/sysroot/usr/include",
 		"out/soong/ndk/sysroot/usr/include/arm-linux-androideabi",
-		"${config.NoOverrideClangGlobalCflags}",
+		"${config.NoOverrideGlobalCflags}",
 	}
 
 	android.AssertArrayString(t, "includes", want, includes)
diff --git a/cc/compiler.go b/cc/compiler.go
index 69ead30..b01ba43 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -392,7 +392,7 @@
 	if flags.RequiredInstructionSet != "" {
 		instructionSet = flags.RequiredInstructionSet
 	}
-	instructionSetFlags, err := tc.ClangInstructionSetFlags(instructionSet)
+	instructionSetFlags, err := tc.InstructionSetFlags(instructionSet)
 	if err != nil {
 		ctx.ModuleErrorf("%s", err)
 	}
@@ -437,15 +437,15 @@
 	flags.Global.ConlyFlags = append([]string{"${config.CommonGlobalConlyflags}"}, flags.Global.ConlyFlags...)
 	flags.Global.CppFlags = append([]string{fmt.Sprintf("${config.%sGlobalCppflags}", hod)}, flags.Global.CppFlags...)
 
-	flags.Global.AsFlags = append(flags.Global.AsFlags, tc.ClangAsflags())
-	flags.Global.CppFlags = append([]string{"${config.CommonClangGlobalCppflags}"}, flags.Global.CppFlags...)
+	flags.Global.AsFlags = append(flags.Global.AsFlags, tc.Asflags())
+	flags.Global.CppFlags = append([]string{"${config.CommonGlobalCppflags}"}, flags.Global.CppFlags...)
 	flags.Global.CommonFlags = append(flags.Global.CommonFlags,
-		tc.ClangCflags(),
-		"${config.CommonClangGlobalCflags}",
-		fmt.Sprintf("${config.%sClangGlobalCflags}", hod))
+		tc.Cflags(),
+		"${config.CommonGlobalCflags}",
+		fmt.Sprintf("${config.%sGlobalCflags}", hod))
 
 	if isThirdParty(modulePath) {
-		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "${config.ClangExternalCflags}")
+		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "${config.ExternalCflags}")
 	}
 
 	if tc.Bionic() {
@@ -458,11 +458,11 @@
 
 	flags.Global.AsFlags = append(flags.Global.AsFlags, "-D__ASSEMBLY__")
 
-	flags.Global.CppFlags = append(flags.Global.CppFlags, tc.ClangCppflags())
+	flags.Global.CppFlags = append(flags.Global.CppFlags, tc.Cppflags())
 
 	flags.Global.YasmFlags = append(flags.Global.YasmFlags, tc.YasmFlags())
 
-	flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.ToolchainClangCflags())
+	flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.ToolchainCflags())
 
 	cStd := config.CStdVersion
 	if String(compiler.Properties.C_std) == "experimental" {
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index af6361b..812a245 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -48,12 +48,12 @@
 		"-Wl,-z,separate-code",
 	}
 
-	arm64Lldflags = append(ClangFilterUnknownLldflags(arm64Ldflags),
+	arm64Lldflags = append(arm64Ldflags,
 		"-Wl,-z,max-page-size=4096")
 
 	arm64Cppflags = []string{}
 
-	arm64ClangCpuVariantCflags = map[string][]string{
+	arm64CpuVariantCflags = map[string][]string{
 		"cortex-a53": []string{
 			"-mcpu=cortex-a53",
 		},
@@ -99,52 +99,50 @@
 	pctx.StaticVariable("Arm64Ldflags", strings.Join(arm64Ldflags, " "))
 	pctx.StaticVariable("Arm64Lldflags", strings.Join(arm64Lldflags, " "))
 
-	pctx.StaticVariable("Arm64ClangCflags", strings.Join(ClangFilterUnknownCflags(arm64Cflags), " "))
-	pctx.StaticVariable("Arm64ClangLdflags", strings.Join(ClangFilterUnknownCflags(arm64Ldflags), " "))
-	pctx.StaticVariable("Arm64ClangLldflags", strings.Join(ClangFilterUnknownCflags(arm64Lldflags), " "))
-	pctx.StaticVariable("Arm64ClangCppflags", strings.Join(ClangFilterUnknownCflags(arm64Cppflags), " "))
+	pctx.StaticVariable("Arm64Cflags", strings.Join(arm64Cflags, " "))
+	pctx.StaticVariable("Arm64Cppflags", strings.Join(arm64Cppflags, " "))
 
-	pctx.StaticVariable("Arm64ClangArmv8ACflags", strings.Join(arm64ArchVariantCflags["armv8-a"], " "))
-	pctx.StaticVariable("Arm64ClangArmv8ABranchProtCflags", strings.Join(arm64ArchVariantCflags["armv8-a-branchprot"], " "))
-	pctx.StaticVariable("Arm64ClangArmv82ACflags", strings.Join(arm64ArchVariantCflags["armv8-2a"], " "))
-	pctx.StaticVariable("Arm64ClangArmv82ADotprodCflags", strings.Join(arm64ArchVariantCflags["armv8-2a-dotprod"], " "))
+	pctx.StaticVariable("Arm64Armv8ACflags", strings.Join(arm64ArchVariantCflags["armv8-a"], " "))
+	pctx.StaticVariable("Arm64Armv8ABranchProtCflags", strings.Join(arm64ArchVariantCflags["armv8-a-branchprot"], " "))
+	pctx.StaticVariable("Arm64Armv82ACflags", strings.Join(arm64ArchVariantCflags["armv8-2a"], " "))
+	pctx.StaticVariable("Arm64Armv82ADotprodCflags", strings.Join(arm64ArchVariantCflags["armv8-2a-dotprod"], " "))
 
-	pctx.StaticVariable("Arm64ClangCortexA53Cflags",
-		strings.Join(arm64ClangCpuVariantCflags["cortex-a53"], " "))
+	pctx.StaticVariable("Arm64CortexA53Cflags",
+		strings.Join(arm64CpuVariantCflags["cortex-a53"], " "))
 
-	pctx.StaticVariable("Arm64ClangCortexA55Cflags",
-		strings.Join(arm64ClangCpuVariantCflags["cortex-a55"], " "))
+	pctx.StaticVariable("Arm64CortexA55Cflags",
+		strings.Join(arm64CpuVariantCflags["cortex-a55"], " "))
 
-	pctx.StaticVariable("Arm64ClangKryoCflags",
-		strings.Join(arm64ClangCpuVariantCflags["kryo"], " "))
+	pctx.StaticVariable("Arm64KryoCflags",
+		strings.Join(arm64CpuVariantCflags["kryo"], " "))
 
-	pctx.StaticVariable("Arm64ClangExynosM1Cflags",
-		strings.Join(arm64ClangCpuVariantCflags["exynos-m1"], " "))
+	pctx.StaticVariable("Arm64ExynosM1Cflags",
+		strings.Join(arm64CpuVariantCflags["exynos-m1"], " "))
 
-	pctx.StaticVariable("Arm64ClangExynosM2Cflags",
-		strings.Join(arm64ClangCpuVariantCflags["exynos-m2"], " "))
+	pctx.StaticVariable("Arm64ExynosM2Cflags",
+		strings.Join(arm64CpuVariantCflags["exynos-m2"], " "))
 }
 
 var (
-	arm64ClangArchVariantCflagsVar = map[string]string{
-		"armv8-a":            "${config.Arm64ClangArmv8ACflags}",
-		"armv8-a-branchprot": "${config.Arm64ClangArmv8ABranchProtCflags}",
-		"armv8-2a":           "${config.Arm64ClangArmv82ACflags}",
-		"armv8-2a-dotprod":   "${config.Arm64ClangArmv82ADotprodCflags}",
+	arm64ArchVariantCflagsVar = map[string]string{
+		"armv8-a":            "${config.Arm64Armv8ACflags}",
+		"armv8-a-branchprot": "${config.Arm64Armv8ABranchProtCflags}",
+		"armv8-2a":           "${config.Arm64Armv82ACflags}",
+		"armv8-2a-dotprod":   "${config.Arm64Armv82ADotprodCflags}",
 	}
 
-	arm64ClangCpuVariantCflagsVar = map[string]string{
+	arm64CpuVariantCflagsVar = map[string]string{
 		"":           "",
-		"cortex-a53": "${config.Arm64ClangCortexA53Cflags}",
-		"cortex-a55": "${config.Arm64ClangCortexA55Cflags}",
-		"cortex-a72": "${config.Arm64ClangCortexA53Cflags}",
-		"cortex-a73": "${config.Arm64ClangCortexA53Cflags}",
-		"cortex-a75": "${config.Arm64ClangCortexA55Cflags}",
-		"cortex-a76": "${config.Arm64ClangCortexA55Cflags}",
-		"kryo":       "${config.Arm64ClangKryoCflags}",
-		"kryo385":    "${config.Arm64ClangCortexA53Cflags}",
-		"exynos-m1":  "${config.Arm64ClangExynosM1Cflags}",
-		"exynos-m2":  "${config.Arm64ClangExynosM2Cflags}",
+		"cortex-a53": "${config.Arm64CortexA53Cflags}",
+		"cortex-a55": "${config.Arm64CortexA55Cflags}",
+		"cortex-a72": "${config.Arm64CortexA53Cflags}",
+		"cortex-a73": "${config.Arm64CortexA53Cflags}",
+		"cortex-a75": "${config.Arm64CortexA55Cflags}",
+		"cortex-a76": "${config.Arm64CortexA55Cflags}",
+		"kryo":       "${config.Arm64KryoCflags}",
+		"kryo385":    "${config.Arm64CortexA53Cflags}",
+		"exynos-m1":  "${config.Arm64ExynosM1Cflags}",
+		"exynos-m2":  "${config.Arm64ExynosM2Cflags}",
 	}
 )
 
@@ -152,9 +150,9 @@
 	toolchainBionic
 	toolchain64Bit
 
-	ldflags              string
-	lldflags             string
-	toolchainClangCflags string
+	ldflags         string
+	lldflags        string
+	toolchainCflags string
 }
 
 func (t *toolchainArm64) Name() string {
@@ -181,24 +179,24 @@
 	return t.GccTriple()
 }
 
-func (t *toolchainArm64) ClangCflags() string {
-	return "${config.Arm64ClangCflags}"
+func (t *toolchainArm64) Cflags() string {
+	return "${config.Arm64Cflags}"
 }
 
-func (t *toolchainArm64) ClangCppflags() string {
-	return "${config.Arm64ClangCppflags}"
+func (t *toolchainArm64) Cppflags() string {
+	return "${config.Arm64Cppflags}"
 }
 
-func (t *toolchainArm64) ClangLdflags() string {
+func (t *toolchainArm64) Ldflags() string {
 	return t.ldflags
 }
 
-func (t *toolchainArm64) ClangLldflags() string {
+func (t *toolchainArm64) Lldflags() string {
 	return t.lldflags
 }
 
-func (t *toolchainArm64) ToolchainClangCflags() string {
-	return t.toolchainClangCflags
+func (t *toolchainArm64) ToolchainCflags() string {
+	return t.toolchainCflags
 }
 
 func (toolchainArm64) LibclangRuntimeLibraryArch() string {
@@ -216,9 +214,9 @@
 		panic(fmt.Sprintf("Unknown ARM architecture version: %q", arch.ArchVariant))
 	}
 
-	toolchainClangCflags := []string{arm64ClangArchVariantCflagsVar[arch.ArchVariant]}
-	toolchainClangCflags = append(toolchainClangCflags,
-		variantOrDefault(arm64ClangCpuVariantCflagsVar, arch.CpuVariant))
+	toolchainCflags := []string{arm64ArchVariantCflagsVar[arch.ArchVariant]}
+	toolchainCflags = append(toolchainCflags,
+		variantOrDefault(arm64CpuVariantCflagsVar, arch.CpuVariant))
 
 	var extraLdflags string
 	switch arch.CpuVariant {
@@ -235,7 +233,7 @@
 			"${config.Arm64Lldflags}",
 			extraLdflags,
 		}, " "),
-		toolchainClangCflags: strings.Join(toolchainClangCflags, " "),
+		toolchainCflags: strings.Join(toolchainCflags, " "),
 	}
 }
 
diff --git a/cc/config/arm64_fuchsia_device.go b/cc/config/arm64_fuchsia_device.go
index a6b5e8c..5ab27a0 100644
--- a/cc/config/arm64_fuchsia_device.go
+++ b/cc/config/arm64_fuchsia_device.go
@@ -42,47 +42,31 @@
 	return arm64GccVersion
 }
 
-func (t *toolchainFuchsiaArm64) Cflags() string {
-	return ""
-}
-
-func (t *toolchainFuchsiaArm64) Cppflags() string {
-	return ""
-}
-
-func (t *toolchainFuchsiaArm64) Ldflags() string {
-	return "-Wl,--fix-cortex-a53-843419"
-}
-
 func (t *toolchainFuchsiaArm64) IncludeFlags() string {
 	return ""
 }
 
-func (t *toolchainFuchsiaArm64) ToolchainCflags() string {
-	return "-mcpu=cortex-a53"
-}
-
 func (t *toolchainFuchsiaArm64) ClangTriple() string {
 	return "arm64-fuchsia-android"
 }
 
-func (t *toolchainFuchsiaArm64) ClangCppflags() string {
+func (t *toolchainFuchsiaArm64) Cppflags() string {
 	return "-Wno-error=deprecated-declarations"
 }
 
-func (t *toolchainFuchsiaArm64) ClangLdflags() string {
+func (t *toolchainFuchsiaArm64) Ldflags() string {
 	return "--target=arm64-fuchsia --sysroot=" + fuchsiaArm64SysRoot + " -L" + fuchsiaArm64PrebuiltLibsRoot + "/aarch64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/arm64/dist/"
 }
 
-func (t *toolchainFuchsiaArm64) ClangLldflags() string {
+func (t *toolchainFuchsiaArm64) Lldflags() string {
 	return "--target=arm64-fuchsia --sysroot=" + fuchsiaArm64SysRoot + " -L" + fuchsiaArm64PrebuiltLibsRoot + "/aarch64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/arm64/dist/"
 }
 
-func (t *toolchainFuchsiaArm64) ClangCflags() string {
+func (t *toolchainFuchsiaArm64) Cflags() string {
 	return "--target=arm64-fuchsia --sysroot=" + fuchsiaArm64SysRoot + " -I" + fuchsiaArm64SysRoot + "/include"
 }
 
-func (t *toolchainFuchsiaArm64) ToolchainClangCflags() string {
+func (t *toolchainFuchsiaArm64) ToolchainCflags() string {
 	return "-march=armv8-a"
 }
 
diff --git a/cc/config/arm64_linux_host.go b/cc/config/arm64_linux_host.go
index 83bd799..853d818 100644
--- a/cc/config/arm64_linux_host.go
+++ b/cc/config/arm64_linux_host.go
@@ -15,14 +15,15 @@
 package config
 
 import (
-	"android/soong/android"
 	"strings"
+
+	"android/soong/android"
 )
 
 var (
 	// This is a host toolchain but flags for device toolchain are required
 	// as the flags are actually for Bionic-based builds.
-	linuxCrossCflags = ClangFilterUnknownCflags(append(deviceGlobalCflags,
+	linuxCrossCflags = append(deviceGlobalCflags,
 		// clang by default enables PIC when the clang triple is set to *-android.
 		// See toolchain/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp#920.
 		// However, for this host target, we don't set "-android" to avoid __ANDROID__ macro
@@ -33,9 +34,9 @@
 		// This is normally in ClangExtraTargetCflags, but that's for device and we need
 		// the same for host
 		"-nostdlibinc",
-	))
+	)
 
-	linuxCrossLdflags = ClangFilterUnknownCflags([]string{
+	linuxCrossLdflags = []string{
 		"-Wl,-z,noexecstack",
 		"-Wl,-z,relro",
 		"-Wl,-z,now",
@@ -44,7 +45,7 @@
 		"-Wl,--fatal-warnings",
 		"-Wl,--hash-style=gnu",
 		"-Wl,--no-undefined-version",
-	})
+	}
 
 	// Embed the linker into host bionic binaries. This is needed to support host bionic,
 	// as the linux kernel requires that the ELF interpreter referenced by PT_INTERP be
@@ -73,9 +74,9 @@
 	return "aarch64-linux"
 }
 
-func (toolchainLinuxArm64) ClangCflags() string {
+func (toolchainLinuxArm64) Cflags() string {
 	// The inherited flags + extra flags
-	return "${config.Arm64ClangCflags} ${config.LinuxBionicArm64Cflags}"
+	return "${config.Arm64Cflags} ${config.LinuxBionicArm64Cflags}"
 }
 
 func (toolchainLinuxArm64) CrtBeginSharedBinary() []string {
@@ -84,7 +85,7 @@
 
 func linuxArm64ToolchainFactory(arch android.Arch) Toolchain {
 	archVariant := "armv8-a" // for host, default to armv8-a
-	toolchainClangCflags := []string{arm64ClangArchVariantCflagsVar[archVariant]}
+	toolchainCflags := []string{arm64ArchVariantCflagsVar[archVariant]}
 
 	// We don't specify CPU architecture for host. Conservatively assume
 	// the host CPU needs the fix
@@ -103,7 +104,7 @@
 		"${config.LinuxBionicArm64Ldflags}",
 		extraLdflags,
 	}, " ")
-	ret.toolchainArm64.toolchainClangCflags = strings.Join(toolchainClangCflags, " ")
+	ret.toolchainArm64.toolchainCflags = strings.Join(toolchainCflags, " ")
 	return &ret
 }
 
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index 3c27730..b5afe40 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -23,7 +23,6 @@
 
 var (
 	armToolchainCflags = []string{
-		"-mthumb-interwork",
 		"-msoft-float",
 	}
 
@@ -38,7 +37,7 @@
 		"-Wl,-m,armelf",
 	}
 
-	armLldflags = ClangFilterUnknownLldflags(armLdflags)
+	armLldflags = armLdflags
 
 	armArmCflags = []string{
 		"-fstrict-aliasing",
@@ -49,7 +48,7 @@
 		"-Os",
 	}
 
-	armClangArchVariantCflags = map[string][]string{
+	armArchVariantCflags = map[string][]string{
 		"armv7-a": []string{
 			"-march=armv7-a",
 			"-mfloat-abi=softfp",
@@ -72,7 +71,7 @@
 		},
 	}
 
-	armClangCpuVariantCflags = map[string][]string{
+	armCpuVariantCflags = map[string][]string{
 		"cortex-a7": []string{
 			"-mcpu=cortex-a7",
 			"-mfpu=neon-vfpv4",
@@ -181,67 +180,65 @@
 	exportStringListStaticVariable("ArmLldflags", armLldflags)
 
 	// Clang cflags
-	exportStringListStaticVariable("ArmToolchainClangCflags", ClangFilterUnknownCflags(armToolchainCflags))
-	exportStringListStaticVariable("ArmClangCflags", ClangFilterUnknownCflags(armCflags))
-	exportStringListStaticVariable("ArmClangLdflags", ClangFilterUnknownCflags(armLdflags))
-	exportStringListStaticVariable("ArmClangLldflags", ClangFilterUnknownCflags(armLldflags))
-	exportStringListStaticVariable("ArmClangCppflags", ClangFilterUnknownCflags(armCppflags))
+	exportStringListStaticVariable("ArmToolchainCflags", armToolchainCflags)
+	exportStringListStaticVariable("ArmCflags", armCflags)
+	exportStringListStaticVariable("ArmCppflags", armCppflags)
 
 	// Clang ARM vs. Thumb instruction set cflags
-	exportStringListStaticVariable("ArmClangArmCflags", ClangFilterUnknownCflags(armArmCflags))
-	exportStringListStaticVariable("ArmClangThumbCflags", ClangFilterUnknownCflags(armThumbCflags))
+	exportStringListStaticVariable("ArmArmCflags", armArmCflags)
+	exportStringListStaticVariable("ArmThumbCflags", armThumbCflags)
 
 	// Clang arch variant cflags
-	exportStringListStaticVariable("ArmClangArmv7ACflags", armClangArchVariantCflags["armv7-a"])
-	exportStringListStaticVariable("ArmClangArmv7ANeonCflags", armClangArchVariantCflags["armv7-a-neon"])
-	exportStringListStaticVariable("ArmClangArmv8ACflags", armClangArchVariantCflags["armv8-a"])
-	exportStringListStaticVariable("ArmClangArmv82ACflags", armClangArchVariantCflags["armv8-2a"])
+	exportStringListStaticVariable("ArmArmv7ACflags", armArchVariantCflags["armv7-a"])
+	exportStringListStaticVariable("ArmArmv7ANeonCflags", armArchVariantCflags["armv7-a-neon"])
+	exportStringListStaticVariable("ArmArmv8ACflags", armArchVariantCflags["armv8-a"])
+	exportStringListStaticVariable("ArmArmv82ACflags", armArchVariantCflags["armv8-2a"])
 
 	// Clang cpu variant cflags
-	exportStringListStaticVariable("ArmClangGenericCflags", armClangCpuVariantCflags[""])
-	exportStringListStaticVariable("ArmClangCortexA7Cflags", armClangCpuVariantCflags["cortex-a7"])
-	exportStringListStaticVariable("ArmClangCortexA8Cflags", armClangCpuVariantCflags["cortex-a8"])
-	exportStringListStaticVariable("ArmClangCortexA15Cflags", armClangCpuVariantCflags["cortex-a15"])
-	exportStringListStaticVariable("ArmClangCortexA53Cflags", armClangCpuVariantCflags["cortex-a53"])
-	exportStringListStaticVariable("ArmClangCortexA55Cflags", armClangCpuVariantCflags["cortex-a55"])
-	exportStringListStaticVariable("ArmClangKraitCflags", armClangCpuVariantCflags["krait"])
-	exportStringListStaticVariable("ArmClangKryoCflags", armClangCpuVariantCflags["kryo"])
+	exportStringListStaticVariable("ArmGenericCflags", armCpuVariantCflags[""])
+	exportStringListStaticVariable("ArmCortexA7Cflags", armCpuVariantCflags["cortex-a7"])
+	exportStringListStaticVariable("ArmCortexA8Cflags", armCpuVariantCflags["cortex-a8"])
+	exportStringListStaticVariable("ArmCortexA15Cflags", armCpuVariantCflags["cortex-a15"])
+	exportStringListStaticVariable("ArmCortexA53Cflags", armCpuVariantCflags["cortex-a53"])
+	exportStringListStaticVariable("ArmCortexA55Cflags", armCpuVariantCflags["cortex-a55"])
+	exportStringListStaticVariable("ArmKraitCflags", armCpuVariantCflags["krait"])
+	exportStringListStaticVariable("ArmKryoCflags", armCpuVariantCflags["kryo"])
 }
 
 var (
-	armClangArchVariantCflagsVar = map[string]string{
-		"armv7-a":      "${config.ArmClangArmv7ACflags}",
-		"armv7-a-neon": "${config.ArmClangArmv7ANeonCflags}",
-		"armv8-a":      "${config.ArmClangArmv8ACflags}",
-		"armv8-2a":     "${config.ArmClangArmv82ACflags}",
+	armArchVariantCflagsVar = map[string]string{
+		"armv7-a":      "${config.ArmArmv7ACflags}",
+		"armv7-a-neon": "${config.ArmArmv7ANeonCflags}",
+		"armv8-a":      "${config.ArmArmv8ACflags}",
+		"armv8-2a":     "${config.ArmArmv82ACflags}",
 	}
 
-	armClangCpuVariantCflagsVar = map[string]string{
-		"":               "${config.ArmClangGenericCflags}",
-		"cortex-a7":      "${config.ArmClangCortexA7Cflags}",
-		"cortex-a8":      "${config.ArmClangCortexA8Cflags}",
-		"cortex-a15":     "${config.ArmClangCortexA15Cflags}",
-		"cortex-a53":     "${config.ArmClangCortexA53Cflags}",
-		"cortex-a53.a57": "${config.ArmClangCortexA53Cflags}",
-		"cortex-a55":     "${config.ArmClangCortexA55Cflags}",
-		"cortex-a72":     "${config.ArmClangCortexA53Cflags}",
-		"cortex-a73":     "${config.ArmClangCortexA53Cflags}",
-		"cortex-a75":     "${config.ArmClangCortexA55Cflags}",
-		"cortex-a76":     "${config.ArmClangCortexA55Cflags}",
-		"krait":          "${config.ArmClangKraitCflags}",
-		"kryo":           "${config.ArmClangKryoCflags}",
-		"kryo385":        "${config.ArmClangCortexA53Cflags}",
-		"exynos-m1":      "${config.ArmClangCortexA53Cflags}",
-		"exynos-m2":      "${config.ArmClangCortexA53Cflags}",
+	armCpuVariantCflagsVar = map[string]string{
+		"":               "${config.ArmGenericCflags}",
+		"cortex-a7":      "${config.ArmCortexA7Cflags}",
+		"cortex-a8":      "${config.ArmCortexA8Cflags}",
+		"cortex-a15":     "${config.ArmCortexA15Cflags}",
+		"cortex-a53":     "${config.ArmCortexA53Cflags}",
+		"cortex-a53.a57": "${config.ArmCortexA53Cflags}",
+		"cortex-a55":     "${config.ArmCortexA55Cflags}",
+		"cortex-a72":     "${config.ArmCortexA53Cflags}",
+		"cortex-a73":     "${config.ArmCortexA53Cflags}",
+		"cortex-a75":     "${config.ArmCortexA55Cflags}",
+		"cortex-a76":     "${config.ArmCortexA55Cflags}",
+		"krait":          "${config.ArmKraitCflags}",
+		"kryo":           "${config.ArmKryoCflags}",
+		"kryo385":        "${config.ArmCortexA53Cflags}",
+		"exynos-m1":      "${config.ArmCortexA53Cflags}",
+		"exynos-m2":      "${config.ArmCortexA53Cflags}",
 	}
 )
 
 type toolchainArm struct {
 	toolchainBionic
 	toolchain32Bit
-	ldflags              string
-	lldflags             string
-	toolchainClangCflags string
+	ldflags         string
+	lldflags        string
+	toolchainCflags string
 }
 
 func (t *toolchainArm) Name() string {
@@ -274,34 +271,34 @@
 	return t.GccTriple()
 }
 
-func (t *toolchainArm) ToolchainClangCflags() string {
-	return t.toolchainClangCflags
+func (t *toolchainArm) ToolchainCflags() string {
+	return t.toolchainCflags
 }
 
-func (t *toolchainArm) ClangCflags() string {
-	return "${config.ArmClangCflags}"
+func (t *toolchainArm) Cflags() string {
+	return "${config.ArmCflags}"
 }
 
-func (t *toolchainArm) ClangCppflags() string {
-	return "${config.ArmClangCppflags}"
+func (t *toolchainArm) Cppflags() string {
+	return "${config.ArmCppflags}"
 }
 
-func (t *toolchainArm) ClangLdflags() string {
+func (t *toolchainArm) Ldflags() string {
 	return t.ldflags
 }
 
-func (t *toolchainArm) ClangLldflags() string {
+func (t *toolchainArm) Lldflags() string {
 	return t.lldflags // TODO: handle V8 cases
 }
 
-func (t *toolchainArm) ClangInstructionSetFlags(isa string) (string, error) {
+func (t *toolchainArm) InstructionSetFlags(isa string) (string, error) {
 	switch isa {
 	case "arm":
-		return "${config.ArmClangArmCflags}", nil
+		return "${config.ArmArmCflags}", nil
 	case "thumb", "":
-		return "${config.ArmClangThumbCflags}", nil
+		return "${config.ArmThumbCflags}", nil
 	default:
-		return t.toolchainBase.ClangInstructionSetFlags(isa)
+		return t.toolchainBase.InstructionSetFlags(isa)
 	}
 }
 
@@ -311,13 +308,13 @@
 
 func armToolchainFactory(arch android.Arch) Toolchain {
 	var fixCortexA8 string
-	toolchainClangCflags := make([]string, 2, 3)
+	toolchainCflags := make([]string, 2, 3)
 
-	toolchainClangCflags[0] = "${config.ArmToolchainClangCflags}"
-	toolchainClangCflags[1] = armClangArchVariantCflagsVar[arch.ArchVariant]
+	toolchainCflags[0] = "${config.ArmToolchainCflags}"
+	toolchainCflags[1] = armArchVariantCflagsVar[arch.ArchVariant]
 
-	toolchainClangCflags = append(toolchainClangCflags,
-		variantOrDefault(armClangCpuVariantCflagsVar, arch.CpuVariant))
+	toolchainCflags = append(toolchainCflags,
+		variantOrDefault(armCpuVariantCflagsVar, arch.CpuVariant))
 
 	switch arch.ArchVariant {
 	case "armv7-a-neon":
@@ -341,8 +338,8 @@
 			"${config.ArmLdflags}",
 			fixCortexA8,
 		}, " "),
-		lldflags:             "${config.ArmLldflags}",
-		toolchainClangCflags: strings.Join(toolchainClangCflags, " "),
+		lldflags:        "${config.ArmLldflags}",
+		toolchainCflags: strings.Join(toolchainCflags, " "),
 	}
 }
 
diff --git a/cc/config/bp2build.go b/cc/config/bp2build.go
index 19571f1..e7e94a8 100644
--- a/cc/config/bp2build.go
+++ b/cc/config/bp2build.go
@@ -118,7 +118,7 @@
 // quite complex to track depth-first interpolations. It's also unlikely the
 // interpolation stacks are deep (n > 1).
 func expandVar(toExpand string, stringScope exportedStringVariables, stringListScope exportedStringListVariables) []string {
-	// e.g. "${ClangExternalCflags}"
+	// e.g. "${ExternalCflags}"
 	r := regexp.MustCompile(`\${([a-zA-Z0-9_]+)}`)
 
 	// Internal recursive function.
diff --git a/cc/config/clang.go b/cc/config/clang.go
index c484fc9..9cfe28f 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -15,9 +15,10 @@
 package config
 
 import (
-	"android/soong/android"
 	"sort"
 	"strings"
+
+	"android/soong/android"
 )
 
 // Cflags that should be filtered out when compiling with clang
@@ -80,12 +81,6 @@
 	"--enable-stdcall-fixup",
 })
 
-// Ldflags that should be filtered out when linking with clang lld
-var ClangUnknownLldflags = sorted([]string{
-	"-Wl,--fix-cortex-a8",
-	"-Wl,--no-fix-cortex-a8",
-})
-
 var ClangLibToolingUnknownCflags = sorted([]string{})
 
 // List of tidy checks that should be disabled globally. When the compiler is
@@ -153,80 +148,6 @@
 		"-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__",
 	})
 
-	exportStringListStaticVariable("ClangExtraCppflags", []string{
-		// -Wimplicit-fallthrough is not enabled by -Wall.
-		"-Wimplicit-fallthrough",
-
-		// Enable clang's thread-safety annotations in libcxx.
-		"-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS",
-
-		// libc++'s math.h has an #include_next outside of system_headers.
-		"-Wno-gnu-include-next",
-	})
-
-	exportStringListStaticVariable("ClangExtraTargetCflags", []string{"-nostdlibinc"})
-
-	exportStringListStaticVariable("ClangExtraNoOverrideCflags", []string{
-		"-Werror=address-of-temporary",
-		// Bug: http://b/29823425 Disable -Wnull-dereference until the
-		// new cases detected by this warning in Clang r271374 are
-		// fixed.
-		//"-Werror=null-dereference",
-		"-Werror=return-type",
-
-		// http://b/72331526 Disable -Wtautological-* until the instances detected by these
-		// new warnings are fixed.
-		"-Wno-tautological-constant-compare",
-		"-Wno-tautological-type-limit-compare",
-		// http://b/145210666
-		"-Wno-reorder-init-list",
-		// http://b/145211066
-		"-Wno-implicit-int-float-conversion",
-		// New warnings to be fixed after clang-r377782.
-		"-Wno-int-in-bool-context",          // http://b/148287349
-		"-Wno-sizeof-array-div",             // http://b/148815709
-		"-Wno-tautological-overlap-compare", // http://b/148815696
-		// New warnings to be fixed after clang-r383902.
-		"-Wno-deprecated-copy",                      // http://b/153746672
-		"-Wno-range-loop-construct",                 // http://b/153747076
-		"-Wno-misleading-indentation",               // http://b/153746954
-		"-Wno-zero-as-null-pointer-constant",        // http://b/68236239
-		"-Wno-deprecated-anon-enum-enum-conversion", // http://b/153746485
-		"-Wno-deprecated-enum-enum-conversion",      // http://b/153746563
-		"-Wno-string-compare",                       // http://b/153764102
-		"-Wno-enum-enum-conversion",                 // http://b/154138986
-		"-Wno-enum-float-conversion",                // http://b/154255917
-		"-Wno-pessimizing-move",                     // http://b/154270751
-		// New warnings to be fixed after clang-r399163
-		"-Wno-non-c-typedef-for-linkage", // http://b/161304145
-		// New warnings to be fixed after clang-r407598
-		"-Wno-string-concatenation", // http://b/175068488
-	})
-
-	// Extra cflags for external third-party projects to disable warnings that
-	// are infeasible to fix in all the external projects and their upstream repos.
-	exportStringListStaticVariable("ClangExtraExternalCflags", []string{
-		"-Wno-enum-compare",
-		"-Wno-enum-compare-switch",
-
-		// http://b/72331524 Allow null pointer arithmetic until the instances detected by
-		// this new warning are fixed.
-		"-Wno-null-pointer-arithmetic",
-
-		// Bug: http://b/29823425 Disable -Wnull-dereference until the
-		// new instances detected by this warning are fixed.
-		"-Wno-null-dereference",
-
-		// http://b/145211477
-		"-Wno-pointer-compare",
-		// http://b/145211022
-		"-Wno-xor-used-as-pow",
-		// http://b/145211022
-		"-Wno-final-dtor-non-final-class",
-
-		// http://b/165945989
-		"-Wno-psabi",
-	})
 }
 
 func ClangFilterUnknownCflags(cflags []string) []string {
@@ -255,26 +176,10 @@
 	return result
 }
 
-func ClangFilterUnknownLldflags(lldflags []string) []string {
-	result, _ := android.FilterList(lldflags, ClangUnknownLldflags)
-	return result
-}
-
 func ClangLibToolingFilterUnknownCflags(libToolingFlags []string) []string {
 	return android.RemoveListFromList(libToolingFlags, ClangLibToolingUnknownCflags)
 }
 
-func inListSorted(s string, list []string) bool {
-	for _, l := range list {
-		if s == l {
-			return true
-		} else if s < l {
-			return false
-		}
-	}
-	return false
-}
-
 func sorted(list []string) []string {
 	sort.Strings(list)
 	return list
diff --git a/cc/config/global.go b/cc/config/global.go
index 4957767..bcee06a 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -36,7 +36,6 @@
 
 		// Make paths in deps files relative
 		"-no-canonical-prefixes",
-		"-fno-canonical-system-headers",
 
 		"-DNDEBUG",
 		"-UDEBUG",
@@ -61,8 +60,6 @@
 	commonGlobalConlyflags = []string{}
 
 	deviceGlobalCflags = []string{
-		"-fdiagnostics-color",
-
 		"-ffunction-sections",
 		"-fdata-sections",
 		"-fno-short-enums",
@@ -78,6 +75,7 @@
 		"-Werror=address",
 		"-Werror=sequence-point",
 		"-Werror=format-security",
+		"-nostdlibinc",
 	}
 
 	deviceGlobalCppflags = []string{
@@ -101,7 +99,7 @@
 		"-Wl,--icf=safe",
 	}
 
-	deviceGlobalLldflags = append(ClangFilterUnknownLldflags(deviceGlobalLdflags),
+	deviceGlobalLldflags = append(deviceGlobalLdflags,
 		[]string{
 			"-fuse-ld=lld",
 		}...)
@@ -116,6 +114,15 @@
 
 	commonGlobalCppflags = []string{
 		"-Wsign-promo",
+
+		// -Wimplicit-fallthrough is not enabled by -Wall.
+		"-Wimplicit-fallthrough",
+
+		// Enable clang's thread-safety annotations in libcxx.
+		"-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS",
+
+		// libc++'s math.h has an #include_next outside of system_headers.
+		"-Wno-gnu-include-next",
 	}
 
 	noOverrideGlobalCflags = []string{
@@ -133,6 +140,66 @@
 		// http://b/161386391 for -Wno-pointer-to-int-cast
 		"-Wno-pointer-to-int-cast",
 		"-Werror=fortify-source",
+
+		"-Werror=address-of-temporary",
+		// Bug: http://b/29823425 Disable -Wnull-dereference until the
+		// new cases detected by this warning in Clang r271374 are
+		// fixed.
+		//"-Werror=null-dereference",
+		"-Werror=return-type",
+
+		// http://b/72331526 Disable -Wtautological-* until the instances detected by these
+		// new warnings are fixed.
+		"-Wno-tautological-constant-compare",
+		"-Wno-tautological-type-limit-compare",
+		// http://b/145210666
+		"-Wno-reorder-init-list",
+		// http://b/145211066
+		"-Wno-implicit-int-float-conversion",
+		// New warnings to be fixed after clang-r377782.
+		"-Wno-int-in-bool-context",          // http://b/148287349
+		"-Wno-sizeof-array-div",             // http://b/148815709
+		"-Wno-tautological-overlap-compare", // http://b/148815696
+		// New warnings to be fixed after clang-r383902.
+		"-Wno-deprecated-copy",                      // http://b/153746672
+		"-Wno-range-loop-construct",                 // http://b/153747076
+		"-Wno-misleading-indentation",               // http://b/153746954
+		"-Wno-zero-as-null-pointer-constant",        // http://b/68236239
+		"-Wno-deprecated-anon-enum-enum-conversion", // http://b/153746485
+		"-Wno-deprecated-enum-enum-conversion",      // http://b/153746563
+		"-Wno-string-compare",                       // http://b/153764102
+		"-Wno-enum-enum-conversion",                 // http://b/154138986
+		"-Wno-enum-float-conversion",                // http://b/154255917
+		"-Wno-pessimizing-move",                     // http://b/154270751
+		// New warnings to be fixed after clang-r399163
+		"-Wno-non-c-typedef-for-linkage", // http://b/161304145
+		// New warnings to be fixed after clang-r407598
+		"-Wno-string-concatenation", // http://b/175068488
+	}
+
+	// Extra cflags for external third-party projects to disable warnings that
+	// are infeasible to fix in all the external projects and their upstream repos.
+	extraExternalCflags = []string{
+		"-Wno-enum-compare",
+		"-Wno-enum-compare-switch",
+
+		// http://b/72331524 Allow null pointer arithmetic until the instances detected by
+		// this new warning are fixed.
+		"-Wno-null-pointer-arithmetic",
+
+		// Bug: http://b/29823425 Disable -Wnull-dereference until the
+		// new instances detected by this warning are fixed.
+		"-Wno-null-dereference",
+
+		// http://b/145211477
+		"-Wno-pointer-compare",
+		// http://b/145211022
+		"-Wno-xor-used-as-pow",
+		// http://b/145211022
+		"-Wno-final-dtor-non-final-class",
+
+		// http://b/165945989
+		"-Wno-psabi",
 	}
 
 	IllegalFlags = []string{
@@ -174,20 +241,20 @@
 	exportStringListStaticVariable("HostGlobalLdflags", hostGlobalLdflags)
 	exportStringListStaticVariable("HostGlobalLldflags", hostGlobalLldflags)
 
-	// Export the static default CommonClangGlobalCflags to Bazel.
+	// Export the static default CommonGlobalCflags to Bazel.
 	// TODO(187086342): handle cflags that are set in VariableFuncs.
-	commonClangGlobalCFlags := append(
-		ClangFilterUnknownCflags(commonGlobalCflags),
+	bazelCommonGlobalCflags := append(
+		commonGlobalCflags,
 		[]string{
 			"${ClangExtraCflags}",
 			// Default to zero initialization.
 			"-ftrivial-auto-var-init=zero",
 			"-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang",
 		}...)
-	exportedStringListVars.Set("CommonClangGlobalCflags", commonClangGlobalCFlags)
+	exportedStringListVars.Set("CommonGlobalCflags", bazelCommonGlobalCflags)
 
-	pctx.VariableFunc("CommonClangGlobalCflags", func(ctx android.PackageVarContext) string {
-		flags := ClangFilterUnknownCflags(commonGlobalCflags)
+	pctx.VariableFunc("CommonGlobalCflags", func(ctx android.PackageVarContext) string {
+		flags := commonGlobalCflags
 		flags = append(flags, "${ClangExtraCflags}")
 
 		// http://b/131390872
@@ -206,23 +273,18 @@
 		return strings.Join(flags, " ")
 	})
 
-	// Export the static default DeviceClangGlobalCflags to Bazel.
+	// Export the static default DeviceGlobalCflags to Bazel.
 	// TODO(187086342): handle cflags that are set in VariableFuncs.
-	deviceClangGlobalCflags := append(ClangFilterUnknownCflags(deviceGlobalCflags), "${ClangExtraTargetCflags}")
-	exportedStringListVars.Set("DeviceClangGlobalCflags", deviceClangGlobalCflags)
+	exportedStringListVars.Set("DeviceGlobalCflags", deviceGlobalCflags)
 
-	pctx.VariableFunc("DeviceClangGlobalCflags", func(ctx android.PackageVarContext) string {
-		if ctx.Config().Fuchsia() {
-			return strings.Join(ClangFilterUnknownCflags(deviceGlobalCflags), " ")
-		} else {
-			return strings.Join(deviceClangGlobalCflags, " ")
-		}
+	pctx.VariableFunc("DeviceGlobalCflags", func(ctx android.PackageVarContext) string {
+		return strings.Join(deviceGlobalCflags, " ")
 	})
 
-	exportStringListStaticVariable("HostClangGlobalCflags", ClangFilterUnknownCflags(hostGlobalCflags))
-	exportStringListStaticVariable("NoOverrideClangGlobalCflags", append(ClangFilterUnknownCflags(noOverrideGlobalCflags), "${ClangExtraNoOverrideCflags}"))
-	exportStringListStaticVariable("CommonClangGlobalCppflags", append(ClangFilterUnknownCflags(commonGlobalCppflags), "${ClangExtraCppflags}"))
-	exportStringListStaticVariable("ClangExternalCflags", []string{"${ClangExtraExternalCflags}"})
+	exportStringListStaticVariable("HostGlobalCflags", hostGlobalCflags)
+	exportStringListStaticVariable("NoOverrideGlobalCflags", noOverrideGlobalCflags)
+	exportStringListStaticVariable("CommonGlobalCppflags", commonGlobalCppflags)
+	exportStringListStaticVariable("ExternalCflags", extraExternalCflags)
 
 	// Everything in these lists is a crime against abstraction and dependency tracking.
 	// Do not add anything to this list.
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index ab09751..ff556f1 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -82,14 +82,14 @@
 	IncludeFlags() string
 
 	ClangTriple() string
-	ToolchainClangCflags() string
-	ToolchainClangLdflags() string
-	ClangAsflags() string
-	ClangCflags() string
-	ClangCppflags() string
-	ClangLdflags() string
-	ClangLldflags() string
-	ClangInstructionSetFlags(string) (string, error)
+	ToolchainCflags() string
+	ToolchainLdflags() string
+	Asflags() string
+	Cflags() string
+	Cppflags() string
+	Ldflags() string
+	Lldflags() string
+	InstructionSetFlags(string) (string, error)
 
 	ndkTriple() string
 
@@ -136,18 +136,18 @@
 	return triple
 }
 
-func (toolchainBase) ClangInstructionSetFlags(s string) (string, error) {
+func (toolchainBase) InstructionSetFlags(s string) (string, error) {
 	if s != "" {
 		return "", fmt.Errorf("instruction_set: %s is not a supported instruction set", s)
 	}
 	return "", nil
 }
 
-func (toolchainBase) ToolchainClangCflags() string {
+func (toolchainBase) ToolchainCflags() string {
 	return ""
 }
 
-func (toolchainBase) ToolchainClangLdflags() string {
+func (toolchainBase) ToolchainLdflags() string {
 	return ""
 }
 
@@ -159,7 +159,7 @@
 	return ""
 }
 
-func (toolchainBase) ClangAsflags() string {
+func (toolchainBase) Asflags() string {
 	return ""
 }
 
diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go
index 54dc6d5..c4f47a7 100644
--- a/cc/config/x86_64_device.go
+++ b/cc/config/x86_64_device.go
@@ -32,8 +32,6 @@
 		"-Wl,--hash-style=gnu",
 	}
 
-	x86_64Lldflags = ClangFilterUnknownLldflags(x86_64Ldflags)
-
 	x86_64ArchVariantCflags = map[string][]string{
 		"": []string{
 			"-march=x86-64",
@@ -102,13 +100,11 @@
 	pctx.StaticVariable("X86_64ToolchainLdflags", "-m64")
 
 	pctx.StaticVariable("X86_64Ldflags", strings.Join(x86_64Ldflags, " "))
-	pctx.StaticVariable("X86_64Lldflags", strings.Join(x86_64Lldflags, " "))
+	pctx.StaticVariable("X86_64Lldflags", strings.Join(x86_64Ldflags, " "))
 
 	// Clang cflags
-	pctx.StaticVariable("X86_64ClangCflags", strings.Join(ClangFilterUnknownCflags(x86_64Cflags), " "))
-	pctx.StaticVariable("X86_64ClangLdflags", strings.Join(ClangFilterUnknownCflags(x86_64Ldflags), " "))
-	pctx.StaticVariable("X86_64ClangLldflags", strings.Join(ClangFilterUnknownCflags(x86_64Lldflags), " "))
-	pctx.StaticVariable("X86_64ClangCppflags", strings.Join(ClangFilterUnknownCflags(x86_64Cppflags), " "))
+	pctx.StaticVariable("X86_64Cflags", strings.Join(x86_64Cflags, " "))
+	pctx.StaticVariable("X86_64Cppflags", strings.Join(x86_64Cppflags, " "))
 
 	// Yasm flags
 	pctx.StaticVariable("X86_64YasmFlags", "-f elf64 -m amd64")
@@ -117,15 +113,15 @@
 
 	// Architecture variant cflags
 	for variant, cflags := range x86_64ArchVariantCflags {
-		pctx.StaticVariable("X86_64"+variant+"VariantClangCflags",
-			strings.Join(ClangFilterUnknownCflags(cflags), " "))
+		pctx.StaticVariable("X86_64"+variant+"VariantCflags",
+			strings.Join(cflags, " "))
 	}
 }
 
 type toolchainX86_64 struct {
 	toolchainBionic
 	toolchain64Bit
-	toolchainClangCflags string
+	toolchainCflags string
 }
 
 func (t *toolchainX86_64) Name() string {
@@ -152,27 +148,27 @@
 	return t.GccTriple()
 }
 
-func (t *toolchainX86_64) ToolchainClangLdflags() string {
+func (t *toolchainX86_64) ToolchainLdflags() string {
 	return "${config.X86_64ToolchainLdflags}"
 }
 
-func (t *toolchainX86_64) ToolchainClangCflags() string {
-	return t.toolchainClangCflags
+func (t *toolchainX86_64) ToolchainCflags() string {
+	return t.toolchainCflags
 }
 
-func (t *toolchainX86_64) ClangCflags() string {
-	return "${config.X86_64ClangCflags}"
+func (t *toolchainX86_64) Cflags() string {
+	return "${config.X86_64Cflags}"
 }
 
-func (t *toolchainX86_64) ClangCppflags() string {
-	return "${config.X86_64ClangCppflags}"
+func (t *toolchainX86_64) Cppflags() string {
+	return "${config.X86_64Cppflags}"
 }
 
-func (t *toolchainX86_64) ClangLdflags() string {
+func (t *toolchainX86_64) Ldflags() string {
 	return "${config.X86_64Ldflags}"
 }
 
-func (t *toolchainX86_64) ClangLldflags() string {
+func (t *toolchainX86_64) Lldflags() string {
 	return "${config.X86_64Lldflags}"
 }
 
@@ -185,17 +181,17 @@
 }
 
 func x86_64ToolchainFactory(arch android.Arch) Toolchain {
-	toolchainClangCflags := []string{
+	toolchainCflags := []string{
 		"${config.X86_64ToolchainCflags}",
-		"${config.X86_64" + arch.ArchVariant + "VariantClangCflags}",
+		"${config.X86_64" + arch.ArchVariant + "VariantCflags}",
 	}
 
 	for _, feature := range arch.ArchFeatures {
-		toolchainClangCflags = append(toolchainClangCflags, x86_64ArchFeatureCflags[feature]...)
+		toolchainCflags = append(toolchainCflags, x86_64ArchFeatureCflags[feature]...)
 	}
 
 	return &toolchainX86_64{
-		toolchainClangCflags: strings.Join(toolchainClangCflags, " "),
+		toolchainCflags: strings.Join(toolchainCflags, " "),
 	}
 }
 
diff --git a/cc/config/x86_64_fuchsia_device.go b/cc/config/x86_64_fuchsia_device.go
index d6837c8..86558a6 100644
--- a/cc/config/x86_64_fuchsia_device.go
+++ b/cc/config/x86_64_fuchsia_device.go
@@ -46,18 +46,6 @@
 	return x86_64GccVersion
 }
 
-func (t *toolchainFuchsiaX8664) Cflags() string {
-	return ""
-}
-
-func (t *toolchainFuchsiaX8664) Cppflags() string {
-	return ""
-}
-
-func (t *toolchainFuchsiaX8664) Ldflags() string {
-	return ""
-}
-
 func (t *toolchainFuchsiaX8664) IncludeFlags() string {
 	return ""
 }
@@ -66,20 +54,20 @@
 	return "x86_64-fuchsia-android"
 }
 
-func (t *toolchainFuchsiaX8664) ClangCppflags() string {
+func (t *toolchainFuchsiaX8664) Cppflags() string {
 	return "-Wno-error=deprecated-declarations"
 }
 
-func (t *toolchainFuchsiaX8664) ClangLdflags() string {
+func (t *toolchainFuchsiaX8664) Ldflags() string {
 	return "--target=x86_64-fuchsia --sysroot=" + fuchsiaSysRoot + " -L" + fuchsiaPrebuiltLibsRoot + "/x86_64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/x64/dist/"
 
 }
 
-func (t *toolchainFuchsiaX8664) ClangLldflags() string {
+func (t *toolchainFuchsiaX8664) Lldflags() string {
 	return "--target=x86_64-fuchsia --sysroot=" + fuchsiaSysRoot + " -L" + fuchsiaPrebuiltLibsRoot + "/x86_64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/x64/dist/"
 }
 
-func (t *toolchainFuchsiaX8664) ClangCflags() string {
+func (t *toolchainFuchsiaX8664) Cflags() string {
 	return "--target=x86_64-fuchsia --sysroot=" + fuchsiaSysRoot + " -I" + fuchsiaSysRoot + "/include"
 }
 
@@ -87,7 +75,7 @@
 	return "-f elf64 -m amd64"
 }
 
-func (t *toolchainFuchsiaX8664) ToolchainClangCflags() string {
+func (t *toolchainFuchsiaX8664) ToolchainCflags() string {
 	return "-mssse3"
 }
 
diff --git a/cc/config/x86_darwin_host.go b/cc/config/x86_darwin_host.go
index 4e3e2a6..d8e70e1 100644
--- a/cc/config/x86_darwin_host.go
+++ b/cc/config/x86_darwin_host.go
@@ -26,8 +26,6 @@
 
 var (
 	darwinCflags = []string{
-		"-fdiagnostics-color",
-
 		"-fPIC",
 		"-funwind-tables",
 
@@ -41,6 +39,9 @@
 		"-DMACOSX_DEPLOYMENT_TARGET=${macMinVersion}",
 
 		"-m64",
+
+		"-integrated-as",
+		"-fstack-protector-strong",
 	}
 
 	darwinLdflags = []string{
@@ -50,15 +51,6 @@
 		"-m64",
 	}
 
-	darwinClangCflags = append(ClangFilterUnknownCflags(darwinCflags), []string{
-		"-integrated-as",
-		"-fstack-protector-strong",
-	}...)
-
-	darwinClangLdflags = ClangFilterUnknownCflags(darwinLdflags)
-
-	darwinClangLldflags = ClangFilterUnknownLldflags(darwinClangLdflags)
-
 	darwinSupportedSdkVersions = []string{
 		"10.10",
 		"10.11",
@@ -115,9 +107,9 @@
 
 	pctx.StaticVariable("DarwinGccTriple", "i686-apple-darwin11")
 
-	pctx.StaticVariable("DarwinClangCflags", strings.Join(darwinClangCflags, " "))
-	pctx.StaticVariable("DarwinClangLdflags", strings.Join(darwinClangLdflags, " "))
-	pctx.StaticVariable("DarwinClangLldflags", strings.Join(darwinClangLldflags, " "))
+	pctx.StaticVariable("DarwinCflags", strings.Join(darwinCflags, " "))
+	pctx.StaticVariable("DarwinLdflags", strings.Join(darwinLdflags, " "))
+	pctx.StaticVariable("DarwinLldflags", strings.Join(darwinLdflags, " "))
 
 	pctx.StaticVariable("DarwinYasmFlags", "-f macho -m amd64")
 }
@@ -213,20 +205,20 @@
 	return "x86_64-apple-darwin"
 }
 
-func (t *toolchainDarwin) ClangCflags() string {
-	return "${config.DarwinClangCflags}"
+func (t *toolchainDarwin) Cflags() string {
+	return "${config.DarwinCflags}"
 }
 
-func (t *toolchainDarwin) ClangCppflags() string {
+func (t *toolchainDarwin) Cppflags() string {
 	return ""
 }
 
-func (t *toolchainDarwin) ClangLdflags() string {
-	return "${config.DarwinClangLdflags}"
+func (t *toolchainDarwin) Ldflags() string {
+	return "${config.DarwinLdflags}"
 }
 
-func (t *toolchainDarwin) ClangLldflags() string {
-	return "${config.DarwinClangLldflags}"
+func (t *toolchainDarwin) Lldflags() string {
+	return "${config.DarwinLldflags}"
 }
 
 func (t *toolchainDarwin) YasmFlags() string {
diff --git a/cc/config/x86_device.go b/cc/config/x86_device.go
index 1507d98..5e510a4 100644
--- a/cc/config/x86_device.go
+++ b/cc/config/x86_device.go
@@ -21,16 +21,14 @@
 )
 
 var (
-	x86Cflags = []string{}
-
-	x86ClangCflags = append(x86Cflags, []string{
+	x86Cflags = []string{
 		"-msse3",
 
 		// -mstackrealign is needed to realign stack in native code
 		// that could be called from JNI, so that movaps instruction
 		// will work on assumed stack aligned local variables.
 		"-mstackrealign",
-	}...)
+	}
 
 	x86Cppflags = []string{}
 
@@ -38,8 +36,6 @@
 		"-Wl,--hash-style=gnu",
 	}
 
-	x86Lldflags = ClangFilterUnknownLldflags(x86Ldflags)
-
 	x86ArchVariantCflags = map[string][]string{
 		"": []string{
 			"-march=prescott",
@@ -49,35 +45,27 @@
 		},
 		"atom": []string{
 			"-march=atom",
-			"-mfpmath=sse",
 		},
 		"broadwell": []string{
 			"-march=broadwell",
-			"-mfpmath=sse",
 		},
 		"haswell": []string{
 			"-march=core-avx2",
-			"-mfpmath=sse",
 		},
 		"ivybridge": []string{
 			"-march=core-avx-i",
-			"-mfpmath=sse",
 		},
 		"sandybridge": []string{
 			"-march=corei7",
-			"-mfpmath=sse",
 		},
 		"silvermont": []string{
 			"-march=slm",
-			"-mfpmath=sse",
 		},
 		"skylake": []string{
 			"-march=skylake",
-			"-mfpmath=sse",
 		},
 		"stoneyridge": []string{
 			"-march=bdver4",
-			"-mfpmath=sse",
 		},
 	}
 
@@ -113,13 +101,11 @@
 	pctx.StaticVariable("X86ToolchainLdflags", "-m32")
 
 	pctx.StaticVariable("X86Ldflags", strings.Join(x86Ldflags, " "))
-	pctx.StaticVariable("X86Lldflags", strings.Join(x86Lldflags, " "))
+	pctx.StaticVariable("X86Lldflags", strings.Join(x86Ldflags, " "))
 
 	// Clang cflags
-	pctx.StaticVariable("X86ClangCflags", strings.Join(ClangFilterUnknownCflags(x86ClangCflags), " "))
-	pctx.StaticVariable("X86ClangLdflags", strings.Join(ClangFilterUnknownCflags(x86Ldflags), " "))
-	pctx.StaticVariable("X86ClangLldflags", strings.Join(ClangFilterUnknownCflags(x86Lldflags), " "))
-	pctx.StaticVariable("X86ClangCppflags", strings.Join(ClangFilterUnknownCflags(x86Cppflags), " "))
+	pctx.StaticVariable("X86Cflags", strings.Join(x86Cflags, " "))
+	pctx.StaticVariable("X86Cppflags", strings.Join(x86Cppflags, " "))
 
 	// Yasm flags
 	pctx.StaticVariable("X86YasmFlags", "-f elf32 -m x86")
@@ -128,15 +114,15 @@
 
 	// Architecture variant cflags
 	for variant, cflags := range x86ArchVariantCflags {
-		pctx.StaticVariable("X86"+variant+"VariantClangCflags",
-			strings.Join(ClangFilterUnknownCflags(cflags), " "))
+		pctx.StaticVariable("X86"+variant+"VariantCflags",
+			strings.Join(cflags, " "))
 	}
 }
 
 type toolchainX86 struct {
 	toolchainBionic
 	toolchain32Bit
-	toolchainClangCflags string
+	toolchainCflags string
 }
 
 func (t *toolchainX86) Name() string {
@@ -163,27 +149,27 @@
 	return "i686-linux-android"
 }
 
-func (t *toolchainX86) ToolchainClangLdflags() string {
+func (t *toolchainX86) ToolchainLdflags() string {
 	return "${config.X86ToolchainLdflags}"
 }
 
-func (t *toolchainX86) ToolchainClangCflags() string {
-	return t.toolchainClangCflags
+func (t *toolchainX86) ToolchainCflags() string {
+	return t.toolchainCflags
 }
 
-func (t *toolchainX86) ClangCflags() string {
-	return "${config.X86ClangCflags}"
+func (t *toolchainX86) Cflags() string {
+	return "${config.X86Cflags}"
 }
 
-func (t *toolchainX86) ClangCppflags() string {
-	return "${config.X86ClangCppflags}"
+func (t *toolchainX86) Cppflags() string {
+	return "${config.X86Cppflags}"
 }
 
-func (t *toolchainX86) ClangLdflags() string {
+func (t *toolchainX86) Ldflags() string {
 	return "${config.X86Ldflags}"
 }
 
-func (t *toolchainX86) ClangLldflags() string {
+func (t *toolchainX86) Lldflags() string {
 	return "${config.X86Lldflags}"
 }
 
@@ -196,17 +182,17 @@
 }
 
 func x86ToolchainFactory(arch android.Arch) Toolchain {
-	toolchainClangCflags := []string{
+	toolchainCflags := []string{
 		"${config.X86ToolchainCflags}",
-		"${config.X86" + arch.ArchVariant + "VariantClangCflags}",
+		"${config.X86" + arch.ArchVariant + "VariantCflags}",
 	}
 
 	for _, feature := range arch.ArchFeatures {
-		toolchainClangCflags = append(toolchainClangCflags, x86ArchFeatureCflags[feature]...)
+		toolchainCflags = append(toolchainCflags, x86ArchFeatureCflags[feature]...)
 	}
 
 	return &toolchainX86{
-		toolchainClangCflags: strings.Join(toolchainClangCflags, " "),
+		toolchainCflags: strings.Join(toolchainCflags, " "),
 	}
 }
 
diff --git a/cc/config/x86_linux_bionic_host.go b/cc/config/x86_linux_bionic_host.go
index e7e5f2d..4b7ba6a 100644
--- a/cc/config/x86_linux_bionic_host.go
+++ b/cc/config/x86_linux_bionic_host.go
@@ -21,9 +21,7 @@
 )
 
 var (
-	linuxBionicCflags = ClangFilterUnknownCflags([]string{
-		"-fdiagnostics-color",
-
+	linuxBionicCflags = []string{
 		"-Wa,--noexecstack",
 
 		"-fPIC",
@@ -34,21 +32,17 @@
 
 		// From x86_64_device
 		"-ffunction-sections",
-		"-finline-functions",
-		"-finline-limit=300",
 		"-fno-short-enums",
-		"-funswitch-loops",
 		"-funwind-tables",
-		"-fno-canonical-system-headers",
 
 		// Tell clang where the gcc toolchain is
 		"--gcc-toolchain=${LinuxBionicGccRoot}",
 
 		// This is normally in ClangExtraTargetCflags, but this is considered host
 		"-nostdlibinc",
-	})
+	}
 
-	linuxBionicLdflags = ClangFilterUnknownCflags([]string{
+	linuxBionicLdflags = []string{
 		"-Wl,-z,noexecstack",
 		"-Wl,-z,relro",
 		"-Wl,-z,now",
@@ -60,9 +54,7 @@
 
 		// Use the device gcc toolchain
 		"--gcc-toolchain=${LinuxBionicGccRoot}",
-	})
-
-	linuxBionicLldflags = ClangFilterUnknownLldflags(linuxBionicLdflags)
+	}
 
 	// Embed the linker into host bionic binaries. This is needed to support host bionic,
 	// as the linux kernel requires that the ELF interpreter referenced by PT_INTERP be
@@ -78,7 +70,7 @@
 func init() {
 	pctx.StaticVariable("LinuxBionicCflags", strings.Join(linuxBionicCflags, " "))
 	pctx.StaticVariable("LinuxBionicLdflags", strings.Join(linuxBionicLdflags, " "))
-	pctx.StaticVariable("LinuxBionicLldflags", strings.Join(linuxBionicLldflags, " "))
+	pctx.StaticVariable("LinuxBionicLldflags", strings.Join(linuxBionicLdflags, " "))
 
 	// Use the device gcc toolchain for now
 	pctx.StaticVariable("LinuxBionicGccRoot", "${X86_64GccRoot}")
@@ -114,29 +106,29 @@
 	return "x86_64-linux-android"
 }
 
-func (t *toolchainLinuxBionic) ClangCflags() string {
+func (t *toolchainLinuxBionic) Cflags() string {
 	return "${config.LinuxBionicCflags}"
 }
 
-func (t *toolchainLinuxBionic) ClangCppflags() string {
+func (t *toolchainLinuxBionic) Cppflags() string {
 	return ""
 }
 
-func (t *toolchainLinuxBionic) ClangLdflags() string {
+func (t *toolchainLinuxBionic) Ldflags() string {
 	return "${config.LinuxBionicLdflags}"
 }
 
-func (t *toolchainLinuxBionic) ClangLldflags() string {
+func (t *toolchainLinuxBionic) Lldflags() string {
 	return "${config.LinuxBionicLldflags}"
 }
 
-func (t *toolchainLinuxBionic) ToolchainClangCflags() string {
+func (t *toolchainLinuxBionic) ToolchainCflags() string {
 	return "-m64 -march=x86-64" +
 		// TODO: We're not really android, but we don't have a triple yet b/31393676
 		" -U__ANDROID__"
 }
 
-func (t *toolchainLinuxBionic) ToolchainClangLdflags() string {
+func (t *toolchainLinuxBionic) ToolchainLdflags() string {
 	return "-m64"
 }
 
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
index c406c88..85d95d8 100644
--- a/cc/config/x86_linux_host.go
+++ b/cc/config/x86_linux_host.go
@@ -22,8 +22,6 @@
 
 var (
 	linuxCflags = []string{
-		"-fdiagnostics-color",
-
 		"-Wa,--noexecstack",
 
 		"-fPIC",
@@ -36,6 +34,10 @@
 		//See bug 12708004.
 		"-D__STDC_FORMAT_MACROS",
 		"-D__STDC_CONSTANT_MACROS",
+
+		"--gcc-toolchain=${LinuxGccRoot}",
+		"--sysroot ${LinuxGccRoot}/sysroot",
+		"-fstack-protector-strong",
 	}
 
 	linuxLdflags = []string{
@@ -43,12 +45,14 @@
 		"-Wl,-z,relro",
 		"-Wl,-z,now",
 		"-Wl,--no-undefined-version",
+
+		"--gcc-toolchain=${LinuxGccRoot}",
+		"--sysroot ${LinuxGccRoot}/sysroot",
 	}
 
 	// Extended cflags
 	linuxX86Cflags = []string{
 		"-msse3",
-		"-mfpmath=sse",
 		"-m32",
 		"-march=prescott",
 		"-D_FILE_OFFSET_BITS=64",
@@ -61,40 +65,17 @@
 
 	linuxX86Ldflags = []string{
 		"-m32",
+		"-B${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32",
+		"-L${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32",
+		"-L${LinuxGccRoot}/${LinuxGccTriple}/lib32",
 	}
 
 	linuxX8664Ldflags = []string{
 		"-m64",
-	}
-
-	linuxClangCflags = append(ClangFilterUnknownCflags(linuxCflags), []string{
-		"--gcc-toolchain=${LinuxGccRoot}",
-		"--sysroot ${LinuxGccRoot}/sysroot",
-		"-fstack-protector-strong",
-	}...)
-
-	linuxClangLdflags = append(ClangFilterUnknownCflags(linuxLdflags), []string{
-		"--gcc-toolchain=${LinuxGccRoot}",
-		"--sysroot ${LinuxGccRoot}/sysroot",
-	}...)
-
-	linuxClangLldflags = ClangFilterUnknownLldflags(linuxClangLdflags)
-
-	linuxX86ClangLdflags = append(ClangFilterUnknownCflags(linuxX86Ldflags), []string{
-		"-B${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32",
-		"-L${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32",
-		"-L${LinuxGccRoot}/${LinuxGccTriple}/lib32",
-	}...)
-
-	linuxX86ClangLldflags = ClangFilterUnknownLldflags(linuxX86ClangLdflags)
-
-	linuxX8664ClangLdflags = append(ClangFilterUnknownCflags(linuxX8664Ldflags), []string{
 		"-B${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}",
 		"-L${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}",
 		"-L${LinuxGccRoot}/${LinuxGccTriple}/lib64",
-	}...)
-
-	linuxX8664ClangLldflags = ClangFilterUnknownLldflags(linuxX8664ClangLdflags)
+	}
 
 	linuxAvailableLibraries = addPrefix([]string{
 		"c",
@@ -130,18 +111,16 @@
 
 	pctx.StaticVariable("LinuxGccTriple", "x86_64-linux")
 
-	pctx.StaticVariable("LinuxClangCflags", strings.Join(linuxClangCflags, " "))
-	pctx.StaticVariable("LinuxClangLdflags", strings.Join(linuxClangLdflags, " "))
-	pctx.StaticVariable("LinuxClangLldflags", strings.Join(linuxClangLldflags, " "))
+	pctx.StaticVariable("LinuxCflags", strings.Join(linuxCflags, " "))
+	pctx.StaticVariable("LinuxLdflags", strings.Join(linuxLdflags, " "))
+	pctx.StaticVariable("LinuxLldflags", strings.Join(linuxLdflags, " "))
 
-	pctx.StaticVariable("LinuxX86ClangCflags",
-		strings.Join(ClangFilterUnknownCflags(linuxX86Cflags), " "))
-	pctx.StaticVariable("LinuxX8664ClangCflags",
-		strings.Join(ClangFilterUnknownCflags(linuxX8664Cflags), " "))
-	pctx.StaticVariable("LinuxX86ClangLdflags", strings.Join(linuxX86ClangLdflags, " "))
-	pctx.StaticVariable("LinuxX86ClangLldflags", strings.Join(linuxX86ClangLldflags, " "))
-	pctx.StaticVariable("LinuxX8664ClangLdflags", strings.Join(linuxX8664ClangLdflags, " "))
-	pctx.StaticVariable("LinuxX8664ClangLldflags", strings.Join(linuxX8664ClangLldflags, " "))
+	pctx.StaticVariable("LinuxX86Cflags", strings.Join(linuxX86Cflags, " "))
+	pctx.StaticVariable("LinuxX8664Cflags", strings.Join(linuxX8664Cflags, " "))
+	pctx.StaticVariable("LinuxX86Ldflags", strings.Join(linuxX86Ldflags, " "))
+	pctx.StaticVariable("LinuxX86Lldflags", strings.Join(linuxX86Ldflags, " "))
+	pctx.StaticVariable("LinuxX8664Ldflags", strings.Join(linuxX8664Ldflags, " "))
+	pctx.StaticVariable("LinuxX8664Lldflags", strings.Join(linuxX8664Ldflags, " "))
 	// Yasm flags
 	pctx.StaticVariable("LinuxX86YasmFlags", "-f elf32 -m x86")
 	pctx.StaticVariable("LinuxX8664YasmFlags", "-f elf64 -m amd64")
@@ -189,11 +168,11 @@
 	return "i686-linux-gnu"
 }
 
-func (t *toolchainLinuxX86) ClangCflags() string {
-	return "${config.LinuxClangCflags} ${config.LinuxX86ClangCflags}"
+func (t *toolchainLinuxX86) Cflags() string {
+	return "${config.LinuxCflags} ${config.LinuxX86Cflags}"
 }
 
-func (t *toolchainLinuxX86) ClangCppflags() string {
+func (t *toolchainLinuxX86) Cppflags() string {
 	return ""
 }
 
@@ -201,28 +180,28 @@
 	return "x86_64-linux-gnu"
 }
 
-func (t *toolchainLinuxX8664) ClangCflags() string {
-	return "${config.LinuxClangCflags} ${config.LinuxX8664ClangCflags}"
+func (t *toolchainLinuxX8664) Cflags() string {
+	return "${config.LinuxCflags} ${config.LinuxX8664Cflags}"
 }
 
-func (t *toolchainLinuxX8664) ClangCppflags() string {
+func (t *toolchainLinuxX8664) Cppflags() string {
 	return ""
 }
 
-func (t *toolchainLinuxX86) ClangLdflags() string {
-	return "${config.LinuxClangLdflags} ${config.LinuxX86ClangLdflags}"
+func (t *toolchainLinuxX86) Ldflags() string {
+	return "${config.LinuxLdflags} ${config.LinuxX86Ldflags}"
 }
 
-func (t *toolchainLinuxX86) ClangLldflags() string {
-	return "${config.LinuxClangLldflags} ${config.LinuxX86ClangLldflags}"
+func (t *toolchainLinuxX86) Lldflags() string {
+	return "${config.LinuxLldflags} ${config.LinuxX86Lldflags}"
 }
 
-func (t *toolchainLinuxX8664) ClangLdflags() string {
-	return "${config.LinuxClangLdflags} ${config.LinuxX8664ClangLdflags}"
+func (t *toolchainLinuxX8664) Ldflags() string {
+	return "${config.LinuxLdflags} ${config.LinuxX8664Ldflags}"
 }
 
-func (t *toolchainLinuxX8664) ClangLldflags() string {
-	return "${config.LinuxClangLldflags} ${config.LinuxX8664ClangLldflags}"
+func (t *toolchainLinuxX8664) Lldflags() string {
+	return "${config.LinuxLldflags} ${config.LinuxX8664Lldflags}"
 }
 
 func (t *toolchainLinuxX86) YasmFlags() string {
diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go
index b77df79..d9a7537 100644
--- a/cc/config/x86_windows_host.go
+++ b/cc/config/x86_windows_host.go
@@ -44,32 +44,28 @@
 
 		"--sysroot ${WindowsGccRoot}/${WindowsGccTriple}",
 	}
-	windowsClangCflags = append(ClangFilterUnknownCflags(windowsCflags), []string{}...)
 
 	windowsIncludeFlags = []string{
 		"-isystem ${WindowsGccRoot}/${WindowsGccTriple}/include",
 	}
 
-	windowsClangCppflags = []string{}
+	windowsCppflags = []string{}
 
-	windowsX86ClangCppflags = []string{
+	windowsX86Cppflags = []string{
 		// Use SjLj exceptions for 32-bit.  libgcc_eh implements SjLj
 		// exception model for 32-bit.
 		"-fsjlj-exceptions",
 	}
 
-	windowsX8664ClangCppflags = []string{}
+	windowsX8664Cppflags = []string{}
 
 	windowsLdflags = []string{
-		"--enable-stdcall-fixup",
 		"-Wl,--dynamicbase",
 		"-Wl,--nxcompat",
 	}
-	windowsLldflags = []string{
+	windowsLldflags = append(windowsLdflags, []string{
 		"-Wl,--Xlink=-Brepro", // Enable deterministic build
-	}
-	windowsClangLdflags  = append(ClangFilterUnknownCflags(windowsLdflags), []string{}...)
-	windowsClangLldflags = append(ClangFilterUnknownLldflags(windowsClangLdflags), windowsLldflags...)
+	}...)
 
 	windowsX86Cflags = []string{
 		"-m32",
@@ -84,28 +80,24 @@
 		"-Wl,--large-address-aware",
 		"-L${WindowsGccRoot}/${WindowsGccTriple}/lib32",
 		"-static-libgcc",
-	}
-	windowsX86ClangLdflags = append(ClangFilterUnknownCflags(windowsX86Ldflags), []string{
+
 		"-B${WindowsGccRoot}/${WindowsGccTriple}/bin",
 		"-B${WindowsGccRoot}/lib/gcc/${WindowsGccTriple}/4.8.3/32",
 		"-L${WindowsGccRoot}/lib/gcc/${WindowsGccTriple}/4.8.3/32",
 		"-B${WindowsGccRoot}/${WindowsGccTriple}/lib32",
-	}...)
-	windowsX86ClangLldflags = ClangFilterUnknownLldflags(windowsX86ClangLdflags)
+	}
 
 	windowsX8664Ldflags = []string{
 		"-m64",
 		"-L${WindowsGccRoot}/${WindowsGccTriple}/lib64",
 		"-Wl,--high-entropy-va",
 		"-static-libgcc",
-	}
-	windowsX8664ClangLdflags = append(ClangFilterUnknownCflags(windowsX8664Ldflags), []string{
+
 		"-B${WindowsGccRoot}/${WindowsGccTriple}/bin",
 		"-B${WindowsGccRoot}/lib/gcc/${WindowsGccTriple}/4.8.3",
 		"-L${WindowsGccRoot}/lib/gcc/${WindowsGccTriple}/4.8.3",
 		"-B${WindowsGccRoot}/${WindowsGccTriple}/lib64",
-	}...)
-	windowsX8664ClangLldflags = ClangFilterUnknownLldflags(windowsX8664ClangLdflags)
+	}
 
 	windowsAvailableLibraries = addPrefix([]string{
 		"gdi32",
@@ -138,21 +130,19 @@
 
 	pctx.StaticVariable("WindowsGccTriple", "x86_64-w64-mingw32")
 
-	pctx.StaticVariable("WindowsClangCflags", strings.Join(windowsClangCflags, " "))
-	pctx.StaticVariable("WindowsClangLdflags", strings.Join(windowsClangLdflags, " "))
-	pctx.StaticVariable("WindowsClangLldflags", strings.Join(windowsClangLldflags, " "))
-	pctx.StaticVariable("WindowsClangCppflags", strings.Join(windowsClangCppflags, " "))
+	pctx.StaticVariable("WindowsCflags", strings.Join(windowsCflags, " "))
+	pctx.StaticVariable("WindowsLdflags", strings.Join(windowsLdflags, " "))
+	pctx.StaticVariable("WindowsLldflags", strings.Join(windowsLldflags, " "))
+	pctx.StaticVariable("WindowsCppflags", strings.Join(windowsCppflags, " "))
 
-	pctx.StaticVariable("WindowsX86ClangCflags",
-		strings.Join(ClangFilterUnknownCflags(windowsX86Cflags), " "))
-	pctx.StaticVariable("WindowsX8664ClangCflags",
-		strings.Join(ClangFilterUnknownCflags(windowsX8664Cflags), " "))
-	pctx.StaticVariable("WindowsX86ClangLdflags", strings.Join(windowsX86ClangLdflags, " "))
-	pctx.StaticVariable("WindowsX86ClangLldflags", strings.Join(windowsX86ClangLldflags, " "))
-	pctx.StaticVariable("WindowsX8664ClangLdflags", strings.Join(windowsX8664ClangLdflags, " "))
-	pctx.StaticVariable("WindowsX8664ClangLldflags", strings.Join(windowsX8664ClangLldflags, " "))
-	pctx.StaticVariable("WindowsX86ClangCppflags", strings.Join(windowsX86ClangCppflags, " "))
-	pctx.StaticVariable("WindowsX8664ClangCppflags", strings.Join(windowsX8664ClangCppflags, " "))
+	pctx.StaticVariable("WindowsX86Cflags", strings.Join(windowsX86Cflags, " "))
+	pctx.StaticVariable("WindowsX8664Cflags", strings.Join(windowsX8664Cflags, " "))
+	pctx.StaticVariable("WindowsX86Ldflags", strings.Join(windowsX86Ldflags, " "))
+	pctx.StaticVariable("WindowsX86Lldflags", strings.Join(windowsX86Ldflags, " "))
+	pctx.StaticVariable("WindowsX8664Ldflags", strings.Join(windowsX8664Ldflags, " "))
+	pctx.StaticVariable("WindowsX8664Lldflags", strings.Join(windowsX8664Ldflags, " "))
+	pctx.StaticVariable("WindowsX86Cppflags", strings.Join(windowsX86Cppflags, " "))
+	pctx.StaticVariable("WindowsX8664Cppflags", strings.Join(windowsX8664Cppflags, " "))
 
 	pctx.StaticVariable("WindowsIncludeFlags", strings.Join(windowsIncludeFlags, " "))
 	// Yasm flags
@@ -214,36 +204,36 @@
 	return "x86_64-pc-windows-gnu"
 }
 
-func (t *toolchainWindowsX86) ClangCflags() string {
-	return "${config.WindowsClangCflags} ${config.WindowsX86ClangCflags}"
+func (t *toolchainWindowsX86) Cflags() string {
+	return "${config.WindowsCflags} ${config.WindowsX86Cflags}"
 }
 
-func (t *toolchainWindowsX8664) ClangCflags() string {
-	return "${config.WindowsClangCflags} ${config.WindowsX8664ClangCflags}"
+func (t *toolchainWindowsX8664) Cflags() string {
+	return "${config.WindowsCflags} ${config.WindowsX8664Cflags}"
 }
 
-func (t *toolchainWindowsX86) ClangCppflags() string {
-	return "${config.WindowsClangCppflags} ${config.WindowsX86ClangCppflags}"
+func (t *toolchainWindowsX86) Cppflags() string {
+	return "${config.WindowsCppflags} ${config.WindowsX86Cppflags}"
 }
 
-func (t *toolchainWindowsX8664) ClangCppflags() string {
-	return "${config.WindowsClangCppflags} ${config.WindowsX8664ClangCppflags}"
+func (t *toolchainWindowsX8664) Cppflags() string {
+	return "${config.WindowsCppflags} ${config.WindowsX8664Cppflags}"
 }
 
-func (t *toolchainWindowsX86) ClangLdflags() string {
-	return "${config.WindowsClangLdflags} ${config.WindowsX86ClangLdflags}"
+func (t *toolchainWindowsX86) Ldflags() string {
+	return "${config.WindowsLdflags} ${config.WindowsX86Ldflags}"
 }
 
-func (t *toolchainWindowsX86) ClangLldflags() string {
-	return "${config.WindowsClangLldflags} ${config.WindowsX86ClangLldflags}"
+func (t *toolchainWindowsX86) Lldflags() string {
+	return "${config.WindowsLldflags} ${config.WindowsX86Lldflags}"
 }
 
-func (t *toolchainWindowsX8664) ClangLdflags() string {
-	return "${config.WindowsClangLdflags} ${config.WindowsX8664ClangLdflags}"
+func (t *toolchainWindowsX8664) Ldflags() string {
+	return "${config.WindowsLdflags} ${config.WindowsX8664Ldflags}"
 }
 
-func (t *toolchainWindowsX8664) ClangLldflags() string {
-	return "${config.WindowsClangLldflags} ${config.WindowsX8664ClangLldflags}"
+func (t *toolchainWindowsX8664) Lldflags() string {
+	return "${config.WindowsLldflags} ${config.WindowsX8664Lldflags}"
 }
 
 func (t *toolchainWindowsX86) YasmFlags() string {
diff --git a/cc/library.go b/cc/library.go
index 4fd7c74..56c460c 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -300,6 +300,12 @@
 
 	srcs := compilerAttrs.srcs
 
+	asFlags := compilerAttrs.asFlags
+	if compilerAttrs.asSrcs.IsEmpty() && sharedAttrs.Srcs_as.IsEmpty() && staticAttrs.Srcs_as.IsEmpty() {
+		// Skip asflags for BUILD file simplicity if there are no assembly sources.
+		asFlags = bazel.MakeStringListAttribute(nil)
+	}
+
 	attrs := &bazelCcLibraryAttributes{
 		Srcs:    srcs,
 		Srcs_c:  compilerAttrs.cSrcs,
@@ -308,7 +314,7 @@
 		Copts:      compilerAttrs.copts,
 		Cppflags:   compilerAttrs.cppFlags,
 		Conlyflags: compilerAttrs.conlyFlags,
-		Asflags:    compilerAttrs.asFlags,
+		Asflags:    asFlags,
 
 		Implementation_deps: linkerAttrs.deps,
 		Deps:                linkerAttrs.exportedDeps,
@@ -2370,6 +2376,12 @@
 	linkerAttrs := bp2BuildParseLinkerProps(ctx, module)
 	exportedIncludes := bp2BuildParseExportedIncludes(ctx, module)
 
+	asFlags := compilerAttrs.asFlags
+	if compilerAttrs.asSrcs.IsEmpty() {
+		// Skip asflags for BUILD file simplicity if there are no assembly sources.
+		asFlags = bazel.MakeStringListAttribute(nil)
+	}
+
 	attrs := &bazelCcLibraryStaticAttributes{
 		Copts:               compilerAttrs.copts,
 		Srcs:                compilerAttrs.srcs,
@@ -2386,7 +2398,7 @@
 		Srcs_c:     compilerAttrs.cSrcs,
 		Conlyflags: compilerAttrs.conlyFlags,
 		Srcs_as:    compilerAttrs.asSrcs,
-		Asflags:    compilerAttrs.asFlags,
+		Asflags:    asFlags,
 	}
 
 	props := bazel.BazelTargetModuleProperties{
diff --git a/cc/linkable.go b/cc/linkable.go
index 84141e2..6232efb 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -125,6 +125,7 @@
 	IsPrebuilt() bool
 	Toc() android.OptionalPath
 
+	Device() bool
 	Host() bool
 
 	InRamdisk() bool
diff --git a/cc/linker.go b/cc/linker.go
index 13df232..a712391 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -479,9 +479,9 @@
 	}
 
 	if linker.useClangLld(ctx) {
-		flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ClangLldflags())
+		flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Lldflags())
 	} else {
-		flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ClangLdflags())
+		flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Ldflags())
 	}
 
 	if !ctx.toolchain().Bionic() && !ctx.Fuchsia() {
@@ -535,7 +535,7 @@
 		flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--hash-style=both")
 	}
 
-	flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ToolchainClangLdflags())
+	flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ToolchainLdflags())
 
 	if Bool(linker.Properties.Group_static_libs) {
 		flags.GroupStaticLibs = true
diff --git a/cc/makevars.go b/cc/makevars.go
index 2b326ef..393170a 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -92,8 +92,8 @@
 	ctx.Strict("RS_LLVM_AS", "${config.RSLLVMPrebuiltsPath}/llvm-as")
 	ctx.Strict("RS_LLVM_LINK", "${config.RSLLVMPrebuiltsPath}/llvm-link")
 
-	ctx.Strict("CLANG_EXTERNAL_CFLAGS", "${config.ClangExternalCflags}")
-	ctx.Strict("GLOBAL_CLANG_CFLAGS_NO_OVERRIDE", "${config.NoOverrideClangGlobalCflags}")
+	ctx.Strict("CLANG_EXTERNAL_CFLAGS", "${config.ExternalCflags}")
+	ctx.Strict("GLOBAL_CLANG_CFLAGS_NO_OVERRIDE", "${config.NoOverrideGlobalCflags}")
 	ctx.Strict("GLOBAL_CLANG_CPPFLAGS_NO_OVERRIDE", "")
 
 	ctx.Strict("BOARD_VNDK_VERSION", ctx.DeviceConfig().VndkVersion())
@@ -212,13 +212,13 @@
 	ctx.StrictRaw(makePrefix+"C_SYSTEM_INCLUDES", strings.Join(systemIncludes, " "))
 
 	if target.Arch.ArchType == android.Arm {
-		flags, err := toolchain.ClangInstructionSetFlags("arm")
+		flags, err := toolchain.InstructionSetFlags("arm")
 		if err != nil {
 			panic(err)
 		}
 		ctx.Strict(makePrefix+"arm_CFLAGS", flags)
 
-		flags, err = toolchain.ClangInstructionSetFlags("thumb")
+		flags, err = toolchain.InstructionSetFlags("thumb")
 		if err != nil {
 			panic(err)
 		}
@@ -230,29 +230,29 @@
 
 	ctx.Strict(clangPrefix+"TRIPLE", toolchain.ClangTriple())
 	ctx.Strict(clangPrefix+"GLOBAL_CFLAGS", strings.Join([]string{
-		toolchain.ClangCflags(),
-		"${config.CommonClangGlobalCflags}",
-		fmt.Sprintf("${config.%sClangGlobalCflags}", hod),
-		toolchain.ToolchainClangCflags(),
+		toolchain.Cflags(),
+		"${config.CommonGlobalCflags}",
+		fmt.Sprintf("${config.%sGlobalCflags}", hod),
+		toolchain.ToolchainCflags(),
 		clangExtras,
 		productExtraCflags,
 	}, " "))
 	ctx.Strict(clangPrefix+"GLOBAL_CPPFLAGS", strings.Join([]string{
-		"${config.CommonClangGlobalCppflags}",
+		"${config.CommonGlobalCppflags}",
 		fmt.Sprintf("${config.%sGlobalCppflags}", hod),
-		toolchain.ClangCppflags(),
+		toolchain.Cppflags(),
 	}, " "))
 	ctx.Strict(clangPrefix+"GLOBAL_LDFLAGS", strings.Join([]string{
 		fmt.Sprintf("${config.%sGlobalLdflags}", hod),
-		toolchain.ClangLdflags(),
-		toolchain.ToolchainClangLdflags(),
+		toolchain.Ldflags(),
+		toolchain.ToolchainLdflags(),
 		productExtraLdflags,
 		clangExtras,
 	}, " "))
 	ctx.Strict(clangPrefix+"GLOBAL_LLDFLAGS", strings.Join([]string{
 		fmt.Sprintf("${config.%sGlobalLldflags}", hod),
-		toolchain.ClangLldflags(),
-		toolchain.ToolchainClangLdflags(),
+		toolchain.Lldflags(),
+		toolchain.ToolchainLdflags(),
 		productExtraLdflags,
 		clangExtras,
 	}, " "))
diff --git a/cc/object.go b/cc/object.go
index 9f2db2e..0f983c8 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -123,6 +123,7 @@
 // For bp2build conversion.
 type bazelObjectAttributes struct {
 	Srcs    bazel.LabelListAttribute
+	Srcs_as bazel.LabelListAttribute
 	Hdrs    bazel.LabelListAttribute
 	Deps    bazel.LabelListAttribute
 	Copts   bazel.StringListAttribute
@@ -179,13 +180,19 @@
 	// and this isn't typically done for cc_object.
 	srcs := compilerAttrs.srcs
 	srcs.Append(compilerAttrs.cSrcs)
-	srcs.Append(compilerAttrs.asSrcs)
+
+	asFlags := compilerAttrs.asFlags
+	if compilerAttrs.asSrcs.IsEmpty() {
+		// Skip asflags for BUILD file simplicity if there are no assembly sources.
+		asFlags = bazel.MakeStringListAttribute(nil)
+	}
 
 	attrs := &bazelObjectAttributes{
 		Srcs:    srcs,
+		Srcs_as: compilerAttrs.asSrcs,
 		Deps:    deps,
 		Copts:   compilerAttrs.copts,
-		Asflags: compilerAttrs.asFlags,
+		Asflags: asFlags,
 	}
 
 	props := bazel.BazelTargetModuleProperties{
@@ -224,7 +231,7 @@
 }
 
 func (object *objectLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
-	flags.Global.LdFlags = append(flags.Global.LdFlags, ctx.toolchain().ToolchainClangLdflags())
+	flags.Global.LdFlags = append(flags.Global.LdFlags, ctx.toolchain().ToolchainLdflags())
 
 	if lds := android.OptionalPathForModuleSrc(ctx, object.Properties.Linker_script); lds.Valid() {
 		flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-T,"+lds.String())
diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go
index fb89224..4f031ff 100644
--- a/cc/snapshot_prebuilt.go
+++ b/cc/snapshot_prebuilt.go
@@ -264,6 +264,7 @@
 func init() {
 	VendorSnapshotImageSingleton.Init(android.InitRegistrationContext)
 	recoverySnapshotImageSingleton.init(android.InitRegistrationContext)
+	android.RegisterMakeVarsProvider(pctx, snapshotMakeVarsProvider)
 }
 
 const (
@@ -383,6 +384,24 @@
 
 var _ android.ImageInterface = (*snapshot)(nil)
 
+func snapshotMakeVarsProvider(ctx android.MakeVarsContext) {
+	snapshotSet := map[string]struct{}{}
+	ctx.VisitAllModules(func(m android.Module) {
+		if s, ok := m.(*snapshot); ok {
+			if _, ok := snapshotSet[s.Name()]; ok {
+				// arch variant generates duplicated modules
+				// skip this as we only need to know the path of the module.
+				return
+			}
+			snapshotSet[s.Name()] = struct{}{}
+			imageNameVersion := strings.Split(s.image.imageVariantName(ctx.DeviceConfig()), ".")
+			ctx.Strict(
+				strings.Join([]string{strings.ToUpper(imageNameVersion[0]), s.baseSnapshot.Version(), "SNAPSHOT_DIR"}, "_"),
+				ctx.ModuleDir(s))
+		}
+	})
+}
+
 func vendorSnapshotFactory() android.Module {
 	return snapshotFactory(VendorSnapshotImageSingleton)
 }
diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go
index f76a205..245af2c 100644
--- a/dexpreopt/class_loader_context.go
+++ b/dexpreopt/class_loader_context.go
@@ -15,6 +15,7 @@
 package dexpreopt
 
 import (
+	"encoding/json"
 	"fmt"
 	"sort"
 	"strconv"
@@ -257,6 +258,9 @@
 func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathContext, sdkVer int, lib string,
 	hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) error {
 
+	// For prebuilts, library should have the same name as the source module.
+	lib = android.RemoveOptionalPrebuiltPrefix(lib)
+
 	devicePath := UnknownInstallLibraryPath
 	if installPath == nil {
 		if android.InList(lib, CompatUsesLibs) || android.InList(lib, OptionalCompatUsesLibs) {
@@ -282,11 +286,19 @@
 	}
 	subcontexts := nestedClcMap[AnySdkVersion]
 
-	// If the library with this name is already present as one of the unconditional top-level
-	// components, do not re-add it.
+	// Check if the library with this name is already present in unconditional top-level CLC.
 	for _, clc := range clcMap[sdkVer] {
-		if clc.Name == lib {
+		if clc.Name != lib {
+			// Ok, a different library.
+		} else if clc.Host == hostPath && clc.Device == devicePath {
+			// Ok, the same library with the same paths. Don't re-add it, but don't raise an error
+			// either, as the same library may be reachable via different transitional dependencies.
 			return nil
+		} else {
+			// Fail, as someone is trying to add the same library with different paths. This likely
+			// indicates an error somewhere else, like trying to add a stub library.
+			return fmt.Errorf("a <uses-library> named %q is already in class loader context,"+
+				"but the library paths are different:\t\n", lib)
 		}
 	}
 
@@ -360,6 +372,15 @@
 	return ulibs
 }
 
+func (clcMap ClassLoaderContextMap) Dump() string {
+	jsonCLC := toJsonClassLoaderContext(clcMap)
+	bytes, err := json.MarshalIndent(jsonCLC, "", "  ")
+	if err != nil {
+		panic(err)
+	}
+	return string(bytes)
+}
+
 // Now that the full unconditional context is known, reconstruct conditional context.
 // Apply filters for individual libraries, mirroring what the PackageManager does when it
 // constructs class loader context on device.
diff --git a/java/app.go b/java/app.go
index fc1ace0..4e967ad 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1213,7 +1213,7 @@
 }
 
 func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) {
-	if !ctx.Config().UnbundledBuild() {
+	if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
 		ctx.AddVariationDependencies(nil, usesLibTag, u.usesLibraryProperties.Uses_libs...)
 		ctx.AddVariationDependencies(nil, usesLibTag, u.presentOptionalUsesLibs(ctx)...)
 		// Only add these extra dependencies if the module depends on framework libs. This avoids
@@ -1245,36 +1245,52 @@
 	}
 }
 
-// Returns a map of module names of shared library dependencies to the paths
-// to their dex jars on host and on device.
+// Returns a map of module names of shared library dependencies to the paths to their dex jars on
+// host and on device.
 func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
 	clcMap := make(dexpreopt.ClassLoaderContextMap)
 
-	if !ctx.Config().UnbundledBuild() {
-		ctx.VisitDirectDeps(func(m android.Module) {
-			if tag, ok := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag); ok {
-				dep := ctx.OtherModuleName(m)
-				if lib, ok := m.(UsesLibraryDependency); ok {
-					libName := dep
-					if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
-						libName = *ulib.ProvidesUsesLib()
-						// Replace module name with library name in `uses_libs`/`optional_uses_libs`
-						// in order to pass verify_uses_libraries check (which compares these
-						// properties against library names written in the manifest).
-						replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName)
-						replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName)
-					}
-					clcMap.AddContext(ctx, tag.sdkVersion, libName,
-						lib.DexJarBuildPath(), lib.DexJarInstallPath(), lib.ClassLoaderContexts())
-				} else if ctx.Config().AllowMissingDependencies() {
-					ctx.AddMissingDependencies([]string{dep})
-				} else {
-					ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
-				}
-			}
-		})
+	// Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
+	// UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
+	if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
+		return clcMap
 	}
 
+	ctx.VisitDirectDeps(func(m android.Module) {
+		tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
+		if !isUsesLibTag {
+			return
+		}
+
+		dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
+
+		// Skip stub libraries. A dependency on the implementation library has been added earlier,
+		// so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
+		// from implementation libraries by their name, which is different as it has a suffix.
+		if comp, ok := m.(SdkLibraryComponentDependency); ok {
+			if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
+				return
+			}
+		}
+
+		if lib, ok := m.(UsesLibraryDependency); ok {
+			libName := dep
+			if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
+				libName = *ulib.ProvidesUsesLib()
+				// Replace module name with library name in `uses_libs`/`optional_uses_libs` in
+				// order to pass verify_uses_libraries check (which compares these properties
+				// against library names written in the manifest).
+				replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName)
+				replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName)
+			}
+			clcMap.AddContext(ctx, tag.sdkVersion, libName,
+				lib.DexJarBuildPath(), lib.DexJarInstallPath(), lib.ClassLoaderContexts())
+		} else if ctx.Config().AllowMissingDependencies() {
+			ctx.AddMissingDependencies([]string{dep})
+		} else {
+			ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
+		}
+	})
 	return clcMap
 }
 
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 2e46d74..0faae36 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -141,10 +141,9 @@
 		}
 	}
 
-	// If it is neither app nor test, make config files regardless of its dexpreopt setting.
+	// If it is test, make config files regardless of its dexpreopt setting.
 	// The config files are required for apps defined in make which depend on the lib.
-	// TODO(b/158843648): The config for apps should be generated as well regardless of setting.
-	if (d.isApp || d.isTest) && d.dexpreoptDisabled(ctx) {
+	if d.isTest && d.dexpreoptDisabled(ctx) {
 		return
 	}
 
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 19c65ca..dff9543 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -154,12 +154,23 @@
 // PRODUCT_BOOT_JARS_EXTRA variables. The AOSP makefiles specify some common Framework libraries,
 // but more product-specific libraries can be added in the product makefiles.
 //
-// Each component of the PRODUCT_BOOT_JARS and PRODUCT_BOOT_JARS_EXTRA variables is either a simple
-// name (if the library is a part of the Platform), or a colon-separated pair <apex, name> (if the
-// library is a part of a non-updatable APEX).
+// Each component of the PRODUCT_BOOT_JARS and PRODUCT_BOOT_JARS_EXTRA variables is a
+// colon-separated pair <apex>:<library>, where <apex> is the variant name of a non-updatable APEX,
+// "platform" if the library is a part of the platform in the system partition, or "system_ext" if
+// it's in the system_ext partition.
+//
+// In these variables APEXes are identified by their "variant names", i.e. the names they get
+// mounted as in /apex on device. In Soong modules that is the name set in the "apex_name"
+// properties, which default to the "name" values. For example, many APEXes have both
+// com.android.xxx and com.google.android.xxx modules in Soong, but take the same place
+// /apex/com.android.xxx at runtime. In these cases the variant name is always com.android.xxx,
+// regardless which APEX goes into the product. See also android.ApexInfo.ApexVariationName and
+// apex.apexBundleProperties.Apex_name.
 //
 // A related variable PRODUCT_UPDATABLE_BOOT_JARS contains bootclasspath libraries that are in
-// updatable APEXes. They are not included in the boot image.
+// APEXes. They are not included in the boot image. The only exception here is core-icu4j.jar that
+// has been historically part of the boot image and is now in a non updatable apex; it is treated
+// as being part of PRODUCT_BOOT_JARS and is in the boot image.
 //
 // One exception to the above rules are "coverage" builds (a special build flavor which requires
 // setting environment variable EMMA_INSTRUMENT_FRAMEWORK=true). In coverage builds the Java code in
diff --git a/java/java.go b/java/java.go
index be1ad87..83e9fe1 100644
--- a/java/java.go
+++ b/java/java.go
@@ -21,7 +21,6 @@
 import (
 	"fmt"
 	"path/filepath"
-	"strings"
 
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
@@ -581,6 +580,10 @@
 
 	JarToExport     android.Path `android:"arch_variant"`
 	AidlIncludeDirs android.Paths
+
+	// The list of permitted packages that need to be passed to the prebuilts as they are used to
+	// create the updatable-bcp-packages.txt file.
+	PermittedPackages []string
 }
 
 func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
@@ -589,6 +592,8 @@
 	p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j)
 
 	p.AidlIncludeDirs = j.AidlIncludeDirs()
+
+	p.PermittedPackages = j.PermittedPackagesForUpdatableBootJars()
 }
 
 func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
@@ -607,6 +612,10 @@
 		propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
 	}
 
+	if len(p.PermittedPackages) > 0 {
+		propertySet.AddProperty("permitted_packages", p.PermittedPackages)
+	}
+
 	// Do not copy anything else to the snapshot.
 	if memberType.onlyCopyJarToSnapshot {
 		return
@@ -1127,6 +1136,10 @@
 
 	Installable *bool
 
+	// If not empty, classes are restricted to the specified packages and their sub-packages.
+	// This information is used to generate the updatable-bcp-packages.txt file.
+	Permitted_packages []string
+
 	// List of shared java libs that this module has dependencies to
 	Libs []string
 
@@ -1166,7 +1179,8 @@
 	properties ImportProperties
 
 	// output file containing classes.dex and resources
-	dexJarFile android.Path
+	dexJarFile        android.Path
+	dexJarInstallFile android.Path
 
 	combinedClasspathFile android.Path
 	classLoaderContexts   dexpreopt.ClassLoaderContextMap
@@ -1178,6 +1192,12 @@
 	minSdkVersion android.SdkSpec
 }
 
+var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil)
+
+func (j *Import) PermittedPackagesForUpdatableBootJars() []string {
+	return j.properties.Permitted_packages
+}
+
 func (j *Import) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
 	return android.SdkSpecFrom(ctx, String(j.properties.Sdk_version))
 }
@@ -1311,6 +1331,7 @@
 			di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo)
 			if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil {
 				j.dexJarFile = dexOutputPath
+				j.dexJarInstallFile = android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName()))
 
 				// Initialize the hiddenapi structure.
 				j.initHiddenAPI(ctx, dexOutputPath, outputFile, nil)
@@ -1351,6 +1372,7 @@
 			dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)
 
 			j.dexJarFile = dexOutputFile
+			j.dexJarInstallFile = android.PathForModuleInstall(ctx, "framework", jarName)
 		}
 	}
 
@@ -1392,7 +1414,7 @@
 }
 
 func (j *Import) DexJarInstallPath() android.Path {
-	return nil
+	return j.dexJarInstallFile
 }
 
 func (j *Import) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
@@ -1462,11 +1484,7 @@
 	// TODO(b/113562217): Extract the base module name from the Import name, often the Import name
 	// has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better
 	// solution to get the Import name.
-	name := j.Name()
-	if strings.HasPrefix(name, removedPrefix) {
-		name = strings.TrimPrefix(name, removedPrefix)
-	}
-	return name
+	return android.RemoveOptionalPrebuiltPrefix(j.Name())
 }
 
 var _ android.PrebuiltInterface = (*Import)(nil)
@@ -1768,22 +1786,16 @@
 		return
 	}
 
-	// Find out if the dependency is either an SDK library or an ordinary library that is disguised
-	// as an SDK library by the means of `provides_uses_lib` property. If yes, the library is itself
-	// a <uses-library> and should be added as a node in the CLC tree, and its CLC should be added
-	// as subtree of that node. Otherwise the library is not a <uses_library> and should not be
-	// added to CLC, but the transitive <uses-library> dependencies from its CLC should be added to
-	// the current CLC.
-	var implicitSdkLib *string
-	comp, isComp := depModule.(SdkLibraryComponentDependency)
-	if isComp {
-		implicitSdkLib = comp.OptionalImplicitSdkLibrary()
-		// OptionalImplicitSdkLibrary() may be nil so need to fall through to ProvidesUsesLib().
-	}
-	if implicitSdkLib == nil {
-		if ulib, ok := depModule.(ProvidesUsesLib); ok {
-			implicitSdkLib = ulib.ProvidesUsesLib()
-		}
+	depName := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(depModule))
+
+	var sdkLib *string
+	if lib, ok := depModule.(SdkLibraryDependency); ok && lib.sharedLibrary() {
+		// A shared SDK library. This should be added as a top-level CLC element.
+		sdkLib = &depName
+	} else if ulib, ok := depModule.(ProvidesUsesLib); ok {
+		// A non-SDK library disguised as an SDK library by the means of `provides_uses_lib`
+		// property. This should be handled in the same way as a shared SDK library.
+		sdkLib = ulib.ProvidesUsesLib()
 	}
 
 	depTag := ctx.OtherModuleDependencyTag(depModule)
@@ -1793,7 +1805,7 @@
 		// Propagate <uses-library> through static library dependencies, unless it is a component
 		// library (such as stubs). Component libraries have a dependency on their SDK library,
 		// which should not be pulled just because of a static component library.
-		if implicitSdkLib != nil {
+		if sdkLib != nil {
 			return
 		}
 	} else {
@@ -1801,11 +1813,14 @@
 		return
 	}
 
-	if implicitSdkLib != nil {
-		clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *implicitSdkLib,
+	// If this is an SDK (or SDK-like) library, then it should be added as a node in the CLC tree,
+	// and its CLC should be added as subtree of that node. Otherwise the library is not a
+	// <uses_library> and should not be added to CLC, but the transitive <uses-library> dependencies
+	// from its CLC should be added to the current CLC.
+	if sdkLib != nil {
+		clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib,
 			dep.DexJarBuildPath(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
 	} else {
-		depName := ctx.OtherModuleName(depModule)
 		clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
 	}
 }
diff --git a/java/lint.go b/java/lint.go
index dd5e4fb..fe3218e 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -391,8 +391,9 @@
 	rule.Command().Text("rm -f").Output(html).Output(text).Output(xml)
 
 	var apiVersionsName, apiVersionsPrebuilt string
-	if l.compileSdkKind == android.SdkModule {
-		// When compiling an SDK module we use the filtered database because otherwise lint's
+	if l.compileSdkKind == android.SdkModule || l.compileSdkKind == android.SdkSystemServer {
+		// When compiling an SDK module (or system server) we use the filtered
+		// database because otherwise lint's
 		// NewApi check produces too many false positives; This database excludes information
 		// about classes created in mainline modules hence removing those false positives.
 		apiVersionsName = "api_versions_public_filtered.xml"
diff --git a/java/lint_test.go b/java/lint_test.go
index 9cf1c33..456e6ba 100644
--- a/java/lint_test.go
+++ b/java/lint_test.go
@@ -261,6 +261,9 @@
 }
 
 func TestJavaLintDatabaseSelectionPublicFiltered(t *testing.T) {
+	testCases := []string{
+		"module_current", "system_server_current",
+	}
 	bp := `
 		java_library {
 			name: "foo",
@@ -274,17 +277,20 @@
 			},
 		}
 `
-	result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules).
-		RunTestWithBp(t, bp)
+	for _, testCase := range testCases {
+		thisBp := strings.Replace(bp, "XXX", testCase, 1)
+		result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules).
+			RunTestWithBp(t, thisBp)
 
-	foo := result.ModuleForTests("foo", "android_common")
-	sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
-	if !strings.Contains(*sboxProto.Commands[0].Command,
-		"/api_versions_public_filtered.xml") {
-		t.Error("did not use public-filtered lint api database", *sboxProto.Commands[0].Command)
-	}
-	if strings.Contains(*sboxProto.Commands[0].Command,
-		"/api_versions.xml") {
-		t.Error("used full api database")
+		foo := result.ModuleForTests("foo", "android_common")
+		sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
+		if !strings.Contains(*sboxProto.Commands[0].Command,
+			"/api_versions_public_filtered.xml") {
+			t.Error("did not use public-filtered lint api database for case", testCase)
+		}
+		if strings.Contains(*sboxProto.Commands[0].Command,
+			"/api_versions.xml") {
+			t.Error("used full api database for case", testCase)
+		}
 	}
 }
diff --git a/java/robolectric.go b/java/robolectric.go
index 00f233e..a37a118 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -179,7 +179,7 @@
 			continue
 		} else if strings.HasSuffix(s, "/BaseRobolectricTest.java") {
 			continue
-		} else if strings.HasPrefix(s, "src/") {
+		} else {
 			s = strings.TrimPrefix(s, "src/")
 		}
 		r.tests = append(r.tests, s)
diff --git a/java/sdk_library.go b/java/sdk_library.go
index ed9aeff..d1b4a47 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1897,6 +1897,10 @@
 
 	// If set to true, compile dex files for the stubs. Defaults to false.
 	Compile_dex *bool
+
+	// If not empty, classes are restricted to the specified packages and their sub-packages.
+	// This information is used to generate the updatable-bcp-packages.txt file.
+	Permitted_packages []string
 }
 
 type SdkLibraryImport struct {
@@ -1923,8 +1927,12 @@
 	// Is nil if the source module does not exist.
 	xmlPermissionsFileModule *sdkLibraryXml
 
-	// Path to the dex implementation jar obtained from the prebuilt_apex, if any.
+	// Build path to the dex implementation jar obtained from the prebuilt_apex, if any.
 	dexJarFile android.Path
+
+	// Expected install file path of the source module(sdk_library)
+	// or dex implementation jar obtained from the prebuilt_apex, if any.
+	installFile android.Path
 }
 
 var _ SdkLibraryDependency = (*SdkLibraryImport)(nil)
@@ -1991,6 +1999,12 @@
 	return module
 }
 
+var _ PermittedPackagesForUpdatableBootJars = (*SdkLibraryImport)(nil)
+
+func (module *SdkLibraryImport) PermittedPackagesForUpdatableBootJars() []string {
+	return module.properties.Permitted_packages
+}
+
 func (module *SdkLibraryImport) Prebuilt() *android.Prebuilt {
 	return &module.prebuilt
 }
@@ -2136,6 +2150,9 @@
 
 	var deapexerModule android.Module
 
+	// Assume that source module(sdk_library) is installed in /<sdk_library partition>/framework
+	module.installFile = android.PathForModuleInstall(ctx, "framework", module.Stem()+".jar")
+
 	// Record the paths to the prebuilt stubs library and stubs source.
 	ctx.VisitDirectDeps(func(to android.Module) {
 		tag := ctx.OtherModuleDependencyTag(to)
@@ -2195,6 +2212,7 @@
 			di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo)
 			if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(module.BaseModuleName())); dexOutputPath != nil {
 				module.dexJarFile = dexOutputPath
+				module.installFile = android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(module.BaseModuleName()))
 				module.initHiddenAPI(ctx, dexOutputPath, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil)
 			} else {
 				// This should never happen as a variant for a prebuilt_apex is only created if the
@@ -2249,11 +2267,7 @@
 
 // to satisfy UsesLibraryDependency interface
 func (module *SdkLibraryImport) DexJarInstallPath() android.Path {
-	if module.implLibraryModule == nil {
-		return nil
-	} else {
-		return module.implLibraryModule.DexJarInstallPath()
-	}
+	return module.installFile
 }
 
 // to satisfy UsesLibraryDependency interface
@@ -2506,6 +2520,8 @@
 
 	// The paths to the doctag files to add to the prebuilt.
 	Doctag_paths android.Paths
+
+	Permitted_packages []string
 }
 
 type scopeProperties struct {
@@ -2546,6 +2562,7 @@
 	s.Shared_library = proptools.BoolPtr(sdk.sharedLibrary())
 	s.Compile_dex = sdk.dexProperties.Compile_dex
 	s.Doctag_paths = sdk.doctagPaths
+	s.Permitted_packages = sdk.PermittedPackagesForUpdatableBootJars()
 }
 
 func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
@@ -2558,6 +2575,9 @@
 	if s.Compile_dex != nil {
 		propertySet.AddProperty("compile_dex", *s.Compile_dex)
 	}
+	if len(s.Permitted_packages) > 0 {
+		propertySet.AddProperty("permitted_packages", s.Permitted_packages)
+	}
 
 	for _, apiScope := range allApiScopes {
 		if properties, ok := s.Scopes[apiScope]; ok {
diff --git a/rust/benchmark.go b/rust/benchmark.go
index b89f5cd..0e84243 100644
--- a/rust/benchmark.go
+++ b/rust/benchmark.go
@@ -101,6 +101,7 @@
 func (benchmark *benchmarkDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
 	deps = benchmark.binaryDecorator.compilerDeps(ctx, deps)
 
+	deps.Rustlibs = append(deps.Rustlibs, "libtest")
 	deps.Rustlibs = append(deps.Rustlibs, "libcriterion")
 
 	return deps
diff --git a/rust/bindgen.go b/rust/bindgen.go
index f9e6cd0..3470e51 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -137,15 +137,15 @@
 	implicits = append(implicits, deps.depGeneratedHeaders...)
 
 	// Default clang flags
-	cflags = append(cflags, "${cc_config.CommonClangGlobalCflags}")
+	cflags = append(cflags, "${cc_config.CommonGlobalCflags}")
 	if ctx.Device() {
-		cflags = append(cflags, "${cc_config.DeviceClangGlobalCflags}")
+		cflags = append(cflags, "${cc_config.DeviceGlobalCflags}")
 	}
 
 	// Toolchain clang flags
 	cflags = append(cflags, "-target "+ccToolchain.ClangTriple())
-	cflags = append(cflags, strings.ReplaceAll(ccToolchain.ClangCflags(), "${config.", "${cc_config."))
-	cflags = append(cflags, strings.ReplaceAll(ccToolchain.ToolchainClangCflags(), "${config.", "${cc_config."))
+	cflags = append(cflags, strings.ReplaceAll(ccToolchain.Cflags(), "${config.", "${cc_config."))
+	cflags = append(cflags, strings.ReplaceAll(ccToolchain.ToolchainCflags(), "${config.", "${cc_config."))
 
 	// Dependency clang flags and include paths
 	cflags = append(cflags, deps.depClangFlags...)
diff --git a/rust/config/global.go b/rust/config/global.go
index 43b49d1..1b56237 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -29,7 +29,6 @@
 	DefaultEdition     = "2018"
 	Stdlibs            = []string{
 		"libstd",
-		"libtest",
 	}
 
 	// Mapping between Soong internal arch types and std::env constants.
diff --git a/rust/config/x86_darwin_host.go b/rust/config/x86_darwin_host.go
index ddd93e8..8ff0dd4 100644
--- a/rust/config/x86_darwin_host.go
+++ b/rust/config/x86_darwin_host.go
@@ -78,7 +78,7 @@
 
 func (t *toolchainDarwinX8664) ToolchainLinkFlags() string {
 	// Prepend the lld flags from cc_config so we stay in sync with cc
-	return "${cc_config.DarwinClangLldflags} ${config.DarwinToolchainLinkFlags} ${config.DarwinToolchainX8664LinkFlags}"
+	return "${cc_config.DarwinLldflags} ${config.DarwinToolchainLinkFlags} ${config.DarwinToolchainX8664LinkFlags}"
 }
 
 func (t *toolchainDarwinX8664) ToolchainRustFlags() string {
diff --git a/rust/config/x86_device.go b/rust/config/x86_device.go
index aae1125..5ae30e7 100644
--- a/rust/config/x86_device.go
+++ b/rust/config/x86_device.go
@@ -65,7 +65,7 @@
 
 func (t *toolchainX86) ToolchainLinkFlags() string {
 	// Prepend the lld flags from cc_config so we stay in sync with cc
-	return "${config.DeviceGlobalLinkFlags} ${cc_config.X86ClangLldflags} ${config.X86ToolchainLinkFlags}"
+	return "${config.DeviceGlobalLinkFlags} ${cc_config.X86Lldflags} ${config.X86ToolchainLinkFlags}"
 }
 
 func (t *toolchainX86) ToolchainRustFlags() string {
diff --git a/rust/config/x86_linux_host.go b/rust/config/x86_linux_host.go
index b63e14d..a9fdaed 100644
--- a/rust/config/x86_linux_host.go
+++ b/rust/config/x86_linux_host.go
@@ -79,7 +79,7 @@
 
 func (t *toolchainLinuxX8664) ToolchainLinkFlags() string {
 	// Prepend the lld flags from cc_config so we stay in sync with cc
-	return "${cc_config.LinuxClangLldflags} ${cc_config.LinuxX8664ClangLldflags} " +
+	return "${cc_config.LinuxLldflags} ${cc_config.LinuxX8664Lldflags} " +
 		"${config.LinuxToolchainLinkFlags} ${config.LinuxToolchainX8664LinkFlags}"
 }
 
@@ -117,7 +117,7 @@
 
 func (t *toolchainLinuxX86) ToolchainLinkFlags() string {
 	// Prepend the lld flags from cc_config so we stay in sync with cc
-	return "${cc_config.LinuxClangLldflags} ${cc_config.LinuxX86ClangLldflags} " +
+	return "${cc_config.LinuxLldflags} ${cc_config.LinuxX86Lldflags} " +
 		"${config.LinuxToolchainLinkFlags} ${config.LinuxToolchainX86LinkFlags}"
 }
 
diff --git a/rust/test.go b/rust/test.go
index 6caa7b1..e95b47c 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -169,3 +169,11 @@
 func (test *testDecorator) stdLinkage(ctx *depsContext) RustLinkage {
 	return RlibLinkage
 }
+
+func (test *testDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
+	deps = test.binaryDecorator.compilerDeps(ctx, deps)
+
+	deps.Rustlibs = append(deps.Rustlibs, "libtest")
+
+	return deps
+}
diff --git a/rust/testing.go b/rust/testing.go
index 72f87e1..94cdd9d 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -170,12 +170,10 @@
 			name: "libtest",
 			crate_name: "test",
 			srcs: ["foo.rs"],
-			no_stdlibs: true,
 			host_supported: true,
 			vendor_available: true,
 			vendor_ramdisk_available: true,
 			native_coverage: false,
-			sysroot: true,
 			apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
 			min_sdk_version: "29",
 		}
diff --git a/rust/vendor_snapshot_test.go b/rust/vendor_snapshot_test.go
index 815f80e..60ddb65 100644
--- a/rust/vendor_snapshot_test.go
+++ b/rust/vendor_snapshot_test.go
@@ -569,7 +569,6 @@
 				],
 				rlibs: [
 					"libstd",
-					"libtest",
 					"librust_vendor_available",
 				],
 				binaries: [
@@ -597,7 +596,6 @@
 				],
 				rlibs: [
 					"libstd",
-					"libtest",
 					"librust_vendor_available",
 				],
 				binaries: [
@@ -665,22 +663,6 @@
 	}
 
 	vendor_snapshot_rlib {
-		name: "libtest",
-		version: "30",
-		target_arch: "arm64",
-		vendor: true,
-		sysroot: true,
-		arch: {
-			arm64: {
-				src: "libtest.rlib",
-			},
-			arm: {
-				src: "libtest.rlib",
-			},
-		},
-	}
-
-	vendor_snapshot_rlib {
 		name: "librust_vendor_available",
 		version: "30",
 		target_arch: "arm64",
@@ -917,7 +899,6 @@
 		"vendor/lib64.so":                               nil,
 		"vendor/liblog.so":                              nil,
 		"vendor/libstd.rlib":                            nil,
-		"vendor/libtest.rlib":                           nil,
 		"vendor/librust_vendor_available.rlib":          nil,
 		"vendor/crtbegin_so.o":                          nil,
 		"vendor/crtend_so.o":                            nil,
@@ -962,7 +943,7 @@
 	}
 
 	libclientAndroidMkRlibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkRlibs
-	if g, w := libclientAndroidMkRlibs, []string{"librust_vendor_available.vendor_rlib.30.arm64.rlib-std", "libstd.vendor_rlib.30.arm64", "libtest.vendor_rlib.30.arm64"}; !reflect.DeepEqual(g, w) {
+	if g, w := libclientAndroidMkRlibs, []string{"librust_vendor_available.vendor_rlib.30.arm64.rlib-std", "libstd.vendor_rlib.30.arm64"}; !reflect.DeepEqual(g, w) {
 		t.Errorf("wanted libclient libclientAndroidMkRlibs %q, got %q", w, g)
 	}
 
@@ -977,7 +958,7 @@
 	}
 
 	libclientRustAndroidMkRlibs := ctx.ModuleForTests("libclient_rust", rlibVariant).Module().(*Module).Properties.AndroidMkRlibs
-	if g, w := libclientRustAndroidMkRlibs, []string{"librust_vendor_available.vendor_rlib.30.arm64.rlib-std", "libstd.vendor_rlib.30.arm64", "libtest.vendor_rlib.30.arm64"}; !reflect.DeepEqual(g, w) {
+	if g, w := libclientRustAndroidMkRlibs, []string{"librust_vendor_available.vendor_rlib.30.arm64.rlib-std", "libstd.vendor_rlib.30.arm64"}; !reflect.DeepEqual(g, w) {
 		t.Errorf("wanted libclient libclientAndroidMkRlibs %q, got %q", w, g)
 	}
 
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index a458cba..1d2ab42 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -327,6 +327,7 @@
     visibility: ["//visibility:public"],
     apex_available: ["myapex"],
     jars: ["java/mybootlib.jar"],
+    permitted_packages: ["mybootlib"],
 }
 
 java_sdk_library_import {
@@ -336,6 +337,7 @@
     apex_available: ["myapex"],
     shared_library: true,
     compile_dex: true,
+    permitted_packages: ["myothersdklibrary"],
     public: {
         jars: ["sdk_library/public/myothersdklibrary-stubs.jar"],
         stub_srcs: ["sdk_library/public/myothersdklibrary_stub_sources"],
@@ -409,6 +411,7 @@
     visibility: ["//visibility:public"],
     apex_available: ["myapex"],
     jars: ["java/mybootlib.jar"],
+    permitted_packages: ["mybootlib"],
 }
 
 java_sdk_library_import {
@@ -418,6 +421,7 @@
     apex_available: ["myapex"],
     shared_library: true,
     compile_dex: true,
+    permitted_packages: ["myothersdklibrary"],
     public: {
         jars: ["sdk_library/public/myothersdklibrary-stubs.jar"],
         stub_srcs: ["sdk_library/public/myothersdklibrary_stub_sources"],
@@ -509,6 +513,12 @@
 				out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
         snapshot/hiddenapi/index.csv
 			`, rule)
+
+			// Make sure that the permitted packages from the prebuilts end up in the
+			// updatable-bcp-packages.txt file.
+			rule = module.Output("updatable-bcp-packages.txt")
+			expectedContents := `'mybootlib\nmyothersdklibrary\n'`
+			android.AssertStringEquals(t, "updatable-bcp-packages.txt", expectedContents, rule.Args["content"])
 		}),
 		snapshotTestPreparer(checkSnapshotWithSourcePreferred, preparerForSnapshot),
 		snapshotTestPreparer(checkSnapshotPreferredWithSource, preparerForSnapshot),
@@ -779,6 +789,7 @@
 				srcs: ["Test.java"],
 				compile_dex: true,
 				public: {enabled: true},
+				permitted_packages: ["mysdklibrary"],
 			}
 		`),
 	).RunTest(t)
@@ -822,6 +833,7 @@
     visibility: ["//visibility:public"],
     apex_available: ["myapex"],
     jars: ["java/mybootlib.jar"],
+    permitted_packages: ["mybootlib"],
 }
 
 java_sdk_library_import {
@@ -831,6 +843,7 @@
     apex_available: ["//apex_available:platform"],
     shared_library: true,
     compile_dex: true,
+    permitted_packages: ["mysdklibrary"],
     public: {
         jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
         stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index a2cfe6d..813dcfd 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -175,6 +175,7 @@
 			sdk_version: "none",
 			compile_dex: true,
 			host_supported: true,
+			permitted_packages: ["pkg.myjavalib"],
 		}
 	`)
 
@@ -188,6 +189,7 @@
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     jars: ["java/myjavalib.jar"],
+    permitted_packages: ["pkg.myjavalib"],
 }
 `),
 		checkVersionedAndroidBpContents(`
@@ -199,6 +201,7 @@
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     jars: ["java/myjavalib.jar"],
+    permitted_packages: ["pkg.myjavalib"],
 }
 
 sdk_snapshot {
@@ -437,6 +440,7 @@
 			system_modules: "none",
 			sdk_version: "none",
 			compile_dex: true,
+			permitted_packages: ["pkg.myjavalib"],
 		}
 	`)
 
@@ -450,6 +454,7 @@
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     jars: ["java/myjavalib.jar"],
+    permitted_packages: ["pkg.myjavalib"],
 }
 `),
 		checkVersionedAndroidBpContents(`
@@ -461,6 +466,7 @@
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     jars: ["java/myjavalib.jar"],
+    permitted_packages: ["pkg.myjavalib"],
 }
 
 module_exports_snapshot {
@@ -1045,6 +1051,7 @@
 			shared_library: false,
 			stubs_library_visibility: ["//other"],
 			stubs_source_visibility: ["//another"],
+			permitted_packages: ["pkg.myjavalib"],
 		}
 	`)
 
@@ -1058,6 +1065,7 @@
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:anyapex"],
     shared_library: false,
+    permitted_packages: ["pkg.myjavalib"],
     public: {
         jars: ["sdk_library/public/myjavalib-stubs.jar"],
         stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
@@ -1090,6 +1098,7 @@
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:anyapex"],
     shared_library: false,
+    permitted_packages: ["pkg.myjavalib"],
     public: {
         jars: ["sdk_library/public/myjavalib-stubs.jar"],
         stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index a13b0d7..97fb248 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -565,6 +565,49 @@
 		)
 	})
 
+	t.Run("SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR=module:build_from_source", func(t *testing.T) {
+		result := android.GroupFixturePreparers(
+			preparer,
+			android.FixtureMergeEnv(map[string]string{
+				"SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR": "module:build_from_source",
+			}),
+		).RunTest(t)
+
+		checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip")
+
+		CheckSnapshot(t, result, "mysdk", "",
+			checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_import {
+    name: "mysdk_myjavalib@current",
+    sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
+    apex_available: ["//apex_available:platform"],
+    jars: ["java/myjavalib.jar"],
+}
+
+java_import {
+    name: "myjavalib",
+    prefer: false,
+    use_source_config_var: {
+        config_namespace: "module",
+        var_name: "build_from_source",
+    },
+    visibility: ["//visibility:public"],
+    apex_available: ["//apex_available:platform"],
+    jars: ["java/myjavalib.jar"],
+}
+
+sdk_snapshot {
+    name: "mysdk@current",
+    visibility: ["//visibility:public"],
+    java_header_libs: ["mysdk_myjavalib@current"],
+}
+			`),
+		)
+	})
+
 	t.Run("SOONG_SDK_SNAPSHOT_VERSION=unversioned", func(t *testing.T) {
 		result := android.GroupFixturePreparers(
 			preparer,
diff --git a/sdk/update.go b/sdk/update.go
index b146b62..6da3756 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -35,6 +35,37 @@
 //     By default every unversioned module in the generated snapshot has prefer: false. Building it
 //     with SOONG_SDK_SNAPSHOT_PREFER=true will force them to use prefer: true.
 //
+// SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR
+//     If set this specifies the Soong config var that can be used to control whether the prebuilt
+//     modules from the generated snapshot or the original source modules. Values must be a colon
+//     separated pair of strings, the first of which is the Soong config namespace, and the second
+//     is the name of the variable within that namespace.
+//
+//     The config namespace and var name are used to set the `use_source_config_var` property. That
+//     in turn will cause the generated prebuilts to use the soong config variable to select whether
+//     source or the prebuilt is used.
+//     e.g. If an sdk snapshot is built using:
+//       m SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR=acme:build_from_source sdkextensions-sdk
+//     Then the resulting snapshot will include:
+//       use_source_config_var: {
+//         config_namespace: "acme",
+//         var_name: "build_from_source",
+//       }
+//
+//     Assuming that the config variable is defined in .mk using something like:
+//       $(call add_soong_config_namespace,acme)
+//       $(call add_soong_config_var_value,acme,build_from_source,true)
+//
+//     Then when the snapshot is unpacked in the repository it will have the following behavior:
+//       m droid - will use the sdkextensions-sdk prebuilts if present. Otherwise, it will use the
+//           sources.
+//       m SOONG_CONFIG_acme_build_from_source=true droid - will use the sdkextensions-sdk
+//            sources, if present. Otherwise, it will use the prebuilts.
+//
+//     This is a temporary mechanism to control the prefer flags and will be removed once a more
+//     maintainable solution has been implemented.
+//     TODO(b/174997203): Remove when no longer necessary.
+//
 // SOONG_SDK_SNAPSHOT_VERSION
 //     This provides control over the version of the generated snapshot.
 //
@@ -760,6 +791,8 @@
 	module.insertAfter("name", "sdk_member_name", name)
 	// Remove the prefer property if present as versioned modules never need marking with prefer.
 	module.removeProperty("prefer")
+	// Ditto for use_source_config_var
+	module.removeProperty("use_source_config_var")
 	return module
 }
 
@@ -1627,13 +1660,24 @@
 		// snapshot to be created that sets prefer: true.
 		// TODO(b/174997203): Remove once the ability to select the modules to prefer can be done
 		//  dynamically at build time not at snapshot generation time.
-		prefer := ctx.sdkMemberContext.Config().IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER")
+		config := ctx.sdkMemberContext.Config()
+		prefer := config.IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER")
 
 		// Set prefer. Setting this to false is not strictly required as that is the default but it does
 		// provide a convenient hook to post-process the generated Android.bp file, e.g. in tests to
 		// check the behavior when a prebuilt is preferred. It also makes it explicit what the default
 		// behavior is for the module.
 		bpModule.insertAfter("name", "prefer", prefer)
+
+		configVar := config.Getenv("SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR")
+		if configVar != "" {
+			parts := strings.Split(configVar, ":")
+			cfp := android.ConfigVarProperties{
+				Config_namespace: proptools.StringPtr(parts[0]),
+				Var_name:         proptools.StringPtr(parts[1]),
+			}
+			bpModule.insertAfter("prefer", "use_source_config_var", cfp)
+		}
 	}
 
 	// Group the variants by os type.
diff --git a/ui/build/config.go b/ui/build/config.go
index 7370627..cd6d549 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -345,12 +345,7 @@
 		return
 	}
 
-	b := &smpb.BuildConfig{
-		ForceUseGoma: proto.Bool(config.ForceUseGoma()),
-		UseGoma:      proto.Bool(config.UseGoma()),
-		UseRbe:       proto.Bool(config.UseRBE()),
-	}
-	ctx.Metrics.BuildConfig(b)
+	ctx.Metrics.BuildConfig(buildConfig(config))
 
 	s := &smpb.SystemResourceInfo{
 		TotalPhysicalMemory: proto.Uint64(config.TotalRAM()),
@@ -359,6 +354,16 @@
 	ctx.Metrics.SystemResourceInfo(s)
 }
 
+func buildConfig(config Config) *smpb.BuildConfig {
+	return &smpb.BuildConfig{
+		ForceUseGoma:    proto.Bool(config.ForceUseGoma()),
+		UseGoma:         proto.Bool(config.UseGoma()),
+		UseRbe:          proto.Bool(config.UseRBE()),
+		BazelAsNinja:    proto.Bool(config.UseBazel()),
+		BazelMixedBuild: proto.Bool(config.bazelBuildMode() == mixedBuild),
+	}
+}
+
 // getConfigArgs processes the command arguments based on the build action and creates a set of new
 // arguments to be accepted by Config.
 func getConfigArgs(action BuildAction, dir string, ctx Context, args []string) []string {
diff --git a/ui/build/config_test.go b/ui/build/config_test.go
index 7b14c47..7d4c76b 100644
--- a/ui/build/config_test.go
+++ b/ui/build/config_test.go
@@ -26,7 +26,10 @@
 	"testing"
 
 	"android/soong/ui/logger"
+	smpb "android/soong/ui/metrics/metrics_proto"
 	"android/soong/ui/status"
+
+	"github.com/golang/protobuf/proto"
 )
 
 func testContext() Context {
@@ -995,3 +998,111 @@
 		})
 	}
 }
+
+func TestBuildConfig(t *testing.T) {
+	tests := []struct {
+		name                string
+		environ             Environment
+		useBazel            bool
+		expectedBuildConfig *smpb.BuildConfig
+	}{
+		{
+			name:    "none set",
+			environ: Environment{},
+			expectedBuildConfig: &smpb.BuildConfig{
+				ForceUseGoma:    proto.Bool(false),
+				UseGoma:         proto.Bool(false),
+				UseRbe:          proto.Bool(false),
+				BazelAsNinja:    proto.Bool(false),
+				BazelMixedBuild: proto.Bool(false),
+			},
+		},
+		{
+			name:    "force use goma",
+			environ: Environment{"FORCE_USE_GOMA=1"},
+			expectedBuildConfig: &smpb.BuildConfig{
+				ForceUseGoma:    proto.Bool(true),
+				UseGoma:         proto.Bool(false),
+				UseRbe:          proto.Bool(false),
+				BazelAsNinja:    proto.Bool(false),
+				BazelMixedBuild: proto.Bool(false),
+			},
+		},
+		{
+			name:    "use goma",
+			environ: Environment{"USE_GOMA=1"},
+			expectedBuildConfig: &smpb.BuildConfig{
+				ForceUseGoma:    proto.Bool(false),
+				UseGoma:         proto.Bool(true),
+				UseRbe:          proto.Bool(false),
+				BazelAsNinja:    proto.Bool(false),
+				BazelMixedBuild: proto.Bool(false),
+			},
+		},
+		{
+			name:    "use rbe",
+			environ: Environment{"USE_RBE=1"},
+			expectedBuildConfig: &smpb.BuildConfig{
+				ForceUseGoma:    proto.Bool(false),
+				UseGoma:         proto.Bool(false),
+				UseRbe:          proto.Bool(true),
+				BazelAsNinja:    proto.Bool(false),
+				BazelMixedBuild: proto.Bool(false),
+			},
+		},
+		{
+			name:     "use bazel as ninja",
+			environ:  Environment{},
+			useBazel: true,
+			expectedBuildConfig: &smpb.BuildConfig{
+				ForceUseGoma:    proto.Bool(false),
+				UseGoma:         proto.Bool(false),
+				UseRbe:          proto.Bool(false),
+				BazelAsNinja:    proto.Bool(true),
+				BazelMixedBuild: proto.Bool(false),
+			},
+		},
+		{
+			name:    "bazel mixed build",
+			environ: Environment{"USE_BAZEL_ANALYSIS=1"},
+			expectedBuildConfig: &smpb.BuildConfig{
+				ForceUseGoma:    proto.Bool(false),
+				UseGoma:         proto.Bool(false),
+				UseRbe:          proto.Bool(false),
+				BazelAsNinja:    proto.Bool(false),
+				BazelMixedBuild: proto.Bool(true),
+			},
+		},
+		{
+			name: "all set",
+			environ: Environment{
+				"FORCE_USE_GOMA=1",
+				"USE_GOMA=1",
+				"USE_RBE=1",
+				"USE_BAZEL_ANALYSIS=1",
+			},
+			useBazel: true,
+			expectedBuildConfig: &smpb.BuildConfig{
+				ForceUseGoma:    proto.Bool(true),
+				UseGoma:         proto.Bool(true),
+				UseRbe:          proto.Bool(true),
+				BazelAsNinja:    proto.Bool(true),
+				BazelMixedBuild: proto.Bool(true),
+			},
+		},
+	}
+
+	for _, tc := range tests {
+		t.Run(tc.name, func(t *testing.T) {
+			c := &configImpl{
+				environ:  &tc.environ,
+				useBazel: tc.useBazel,
+			}
+			config := Config{c}
+			actualBuildConfig := buildConfig(config)
+			if expected := tc.expectedBuildConfig; !proto.Equal(expected, actualBuildConfig) {
+				t.Errorf("Expected build config != actual build config: %#v != %#v", *expected, *actualBuildConfig)
+			}
+		})
+	}
+}
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index 83c8865..f3c442e 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -163,6 +163,7 @@
 	"AUX_OS_VARIANT_LIST",
 	"PRODUCT_SOONG_NAMESPACES",
 	"SOONG_SDK_SNAPSHOT_PREFER",
+	"SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR",
 	"SOONG_SDK_SNAPSHOT_VERSION",
 }
 
diff --git a/ui/metrics/metrics_proto/metrics.pb.go b/ui/metrics/metrics_proto/metrics.pb.go
index fc2cfa4..1063337 100644
--- a/ui/metrics/metrics_proto/metrics.pb.go
+++ b/ui/metrics/metrics_proto/metrics.pb.go
@@ -433,9 +433,14 @@
 }
 
 type BuildConfig struct {
-	UseGoma              *bool    `protobuf:"varint,1,opt,name=use_goma,json=useGoma" json:"use_goma,omitempty"`
-	UseRbe               *bool    `protobuf:"varint,2,opt,name=use_rbe,json=useRbe" json:"use_rbe,omitempty"`
-	ForceUseGoma         *bool    `protobuf:"varint,3,opt,name=force_use_goma,json=forceUseGoma" json:"force_use_goma,omitempty"`
+	UseGoma      *bool `protobuf:"varint,1,opt,name=use_goma,json=useGoma" json:"use_goma,omitempty"`
+	UseRbe       *bool `protobuf:"varint,2,opt,name=use_rbe,json=useRbe" json:"use_rbe,omitempty"`
+	ForceUseGoma *bool `protobuf:"varint,3,opt,name=force_use_goma,json=forceUseGoma" json:"force_use_goma,omitempty"`
+	// Whether the Bazel is acting as the Ninja executor for this build.
+	BazelAsNinja *bool `protobuf:"varint,4,opt,name=bazel_as_ninja,json=bazelAsNinja" json:"bazel_as_ninja,omitempty"`
+	// Whether build is occurring in a mixed build mode, where Bazel maintains the
+	// definition and build of some modules in cooperation with Soong.
+	BazelMixedBuild      *bool    `protobuf:"varint,5,opt,name=bazel_mixed_build,json=bazelMixedBuild" json:"bazel_mixed_build,omitempty"`
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
 	XXX_sizecache        int32    `json:"-"`
@@ -487,6 +492,20 @@
 	return false
 }
 
+func (m *BuildConfig) GetBazelAsNinja() bool {
+	if m != nil && m.BazelAsNinja != nil {
+		return *m.BazelAsNinja
+	}
+	return false
+}
+
+func (m *BuildConfig) GetBazelMixedBuild() bool {
+	if m != nil && m.BazelMixedBuild != nil {
+		return *m.BazelMixedBuild
+	}
+	return false
+}
+
 type SystemResourceInfo struct {
 	// The total physical memory in bytes.
 	TotalPhysicalMemory *uint64 `protobuf:"varint,1,opt,name=total_physical_memory,json=totalPhysicalMemory" json:"total_physical_memory,omitempty"`
@@ -990,92 +1009,94 @@
 }
 
 var fileDescriptor_6039342a2ba47b72 = []byte{
-	// 1380 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xef, 0x52, 0x1b, 0x37,
-	0x10, 0x8f, 0xc1, 0x60, 0x7b, 0xfd, 0x07, 0x23, 0xa0, 0x5c, 0x48, 0xd2, 0x52, 0xb7, 0x49, 0x99,
-	0x4e, 0x43, 0x32, 0x34, 0xc3, 0x64, 0x98, 0x4c, 0xa7, 0xe0, 0xd0, 0x34, 0x65, 0xc0, 0x8c, 0x08,
-	0x69, 0xda, 0x7e, 0x50, 0xe5, 0xb3, 0x0c, 0x97, 0xdc, 0x9d, 0x6e, 0x24, 0x1d, 0xc5, 0x79, 0xb3,
-	0x7e, 0xee, 0x4b, 0xf4, 0x05, 0xfa, 0x04, 0x7d, 0x81, 0x8e, 0x56, 0x77, 0xe6, 0x20, 0x6e, 0xc2,
-	0xe4, 0xdb, 0xe9, 0xb7, 0xbf, 0xdf, 0x6a, 0xb5, 0xd2, 0xee, 0xda, 0xd0, 0x8c, 0x84, 0x51, 0x81,
-	0xaf, 0xd7, 0x13, 0x25, 0x8d, 0x24, 0x0b, 0x5a, 0xca, 0xf8, 0x84, 0xf5, 0xd3, 0x20, 0x1c, 0xb0,
-	0xcc, 0xd4, 0xf9, 0xbb, 0x01, 0xf5, 0x7d, 0xf7, 0xbd, 0xc3, 0xb5, 0x20, 0x0f, 0x61, 0xd1, 0x11,
-	0x06, 0xdc, 0x08, 0x66, 0x82, 0x48, 0x68, 0xc3, 0xa3, 0xc4, 0x2b, 0xad, 0x96, 0xd6, 0xa6, 0x29,
-	0x41, 0xdb, 0x53, 0x6e, 0xc4, 0x8b, 0xdc, 0x42, 0x6e, 0x42, 0xd5, 0x29, 0x82, 0x81, 0x37, 0xb5,
-	0x5a, 0x5a, 0xab, 0xd1, 0x0a, 0xae, 0x9f, 0x0f, 0xc8, 0x16, 0xdc, 0x4c, 0x42, 0x6e, 0x86, 0x52,
-	0x45, 0xec, 0x4c, 0x28, 0x1d, 0xc8, 0x98, 0xf9, 0x72, 0x20, 0x62, 0x1e, 0x09, 0x6f, 0x1a, 0xb9,
-	0xcb, 0x39, 0xe1, 0xa5, 0xb3, 0x77, 0x33, 0x33, 0xb9, 0x0b, 0x2d, 0xc3, 0xd5, 0x89, 0x30, 0x2c,
-	0x51, 0x72, 0x90, 0xfa, 0xc6, 0x2b, 0xa3, 0xa0, 0xe9, 0xd0, 0x43, 0x07, 0x92, 0x01, 0x2c, 0x66,
-	0x34, 0x17, 0xc4, 0x19, 0x57, 0x01, 0x8f, 0x8d, 0x37, 0xb3, 0x5a, 0x5a, 0x6b, 0x6d, 0xdc, 0x5f,
-	0x9f, 0x70, 0xe6, 0xf5, 0xc2, 0x79, 0xd7, 0x77, 0xac, 0xe5, 0xa5, 0x13, 0x6d, 0x4d, 0xef, 0x1e,
-	0x3c, 0xa3, 0xc4, 0xf9, 0x2b, 0x1a, 0x48, 0x0f, 0xea, 0xd9, 0x2e, 0x5c, 0xf9, 0xa7, 0xde, 0x2c,
-	0x3a, 0xbf, 0xfb, 0x41, 0xe7, 0xdb, 0xca, 0x3f, 0xdd, 0xaa, 0x1c, 0x1f, 0xec, 0x1d, 0xf4, 0x7e,
-	0x3e, 0xa0, 0xe0, 0x5c, 0x58, 0x90, 0xac, 0xc3, 0x42, 0xc1, 0xe1, 0x38, 0xea, 0x0a, 0x1e, 0x71,
-	0xfe, 0x82, 0x98, 0x07, 0xf0, 0x0d, 0x64, 0x61, 0x31, 0x3f, 0x49, 0xc7, 0xf4, 0x2a, 0xd2, 0xdb,
-	0xce, 0xd2, 0x4d, 0xd2, 0x9c, 0xbd, 0x07, 0xb5, 0x53, 0xa9, 0xb3, 0x60, 0x6b, 0x1f, 0x15, 0x6c,
-	0xd5, 0x3a, 0xc0, 0x50, 0x29, 0x34, 0xd1, 0xd9, 0x46, 0x3c, 0x70, 0x0e, 0xe1, 0xa3, 0x1c, 0xd6,
-	0xad, 0x93, 0x8d, 0x78, 0x80, 0x3e, 0x97, 0xa1, 0x82, 0x3e, 0xa5, 0xf6, 0xea, 0x78, 0x86, 0x59,
-	0xbb, 0xec, 0x69, 0xd2, 0xc9, 0x36, 0x93, 0x9a, 0x89, 0x73, 0xa3, 0xb8, 0xd7, 0x40, 0x73, 0xdd,
-	0x99, 0x77, 0x2d, 0x34, 0xe6, 0xf8, 0x4a, 0x6a, 0x6d, 0x5d, 0x34, 0x2f, 0x38, 0x5d, 0x8b, 0xf5,
-	0x34, 0xb9, 0x07, 0x73, 0x05, 0x0e, 0x86, 0xdd, 0x72, 0xcf, 0x67, 0xcc, 0xc2, 0x40, 0xee, 0xc3,
-	0x42, 0x81, 0x37, 0x3e, 0xe2, 0x9c, 0x4b, 0xec, 0x98, 0x5b, 0x88, 0x5b, 0xa6, 0x86, 0x0d, 0x02,
-	0xe5, 0xb5, 0x5d, 0xdc, 0x32, 0x35, 0x4f, 0x03, 0x45, 0xbe, 0x83, 0xba, 0x16, 0x26, 0x4d, 0x98,
-	0x91, 0x32, 0xd4, 0xde, 0xfc, 0xea, 0xf4, 0x5a, 0x7d, 0xe3, 0xce, 0xc4, 0x14, 0x1d, 0x0a, 0x35,
-	0x7c, 0x1e, 0x0f, 0x25, 0x05, 0x54, 0xbc, 0xb0, 0x02, 0xb2, 0x05, 0xb5, 0x37, 0xdc, 0x04, 0x4c,
-	0xa5, 0xb1, 0xf6, 0xc8, 0x75, 0xd4, 0x55, 0xcb, 0xa7, 0x69, 0xac, 0xc9, 0x13, 0x00, 0xc7, 0x44,
-	0xf1, 0xc2, 0x75, 0xc4, 0x35, 0xb4, 0xe6, 0xea, 0x38, 0x88, 0x5f, 0x73, 0xa7, 0x5e, 0xbc, 0x96,
-	0x1a, 0x05, 0xa8, 0xfe, 0x16, 0x66, 0x8c, 0x34, 0x3c, 0xf4, 0x96, 0x56, 0x4b, 0x1f, 0x16, 0x3a,
-	0x2e, 0x79, 0x09, 0x93, 0x5a, 0x91, 0xf7, 0x09, 0xba, 0xb8, 0x37, 0xd1, 0xc5, 0x91, 0xc5, 0xb0,
-	0x24, 0xb3, 0x17, 0x46, 0xe7, 0xf5, 0x55, 0x88, 0x74, 0xa1, 0xe1, 0x54, 0xbe, 0x8c, 0x87, 0xc1,
-	0x89, 0xb7, 0x8c, 0x0e, 0x57, 0x27, 0x3a, 0x44, 0x61, 0x17, 0x79, 0xb4, 0xde, 0xbf, 0x58, 0x90,
-	0x15, 0xc0, 0xa7, 0x8f, 0x2d, 0xca, 0xc3, 0x3b, 0x1e, 0xaf, 0xc9, 0x2f, 0xb0, 0xa8, 0x47, 0xda,
-	0x88, 0x88, 0x29, 0xa1, 0x65, 0xaa, 0x7c, 0xc1, 0x82, 0x78, 0x28, 0xbd, 0x9b, 0xb8, 0xd1, 0x57,
-	0x93, 0x23, 0x47, 0x01, 0xcd, 0xf8, 0x98, 0x06, 0xa2, 0xdf, 0xc1, 0xc8, 0x17, 0xd0, 0xcc, 0x63,
-	0x8f, 0x22, 0x1e, 0x0f, 0xbc, 0x15, 0xdc, 0xbb, 0x91, 0x85, 0x86, 0x98, 0xbd, 0xab, 0x3e, 0x7f,
-	0x2b, 0x42, 0x77, 0x57, 0xb7, 0xae, 0x75, 0x57, 0x28, 0xb0, 0x77, 0xd5, 0x79, 0x08, 0x8d, 0x4b,
-	0x4d, 0xad, 0x0a, 0xe5, 0xe3, 0xa3, 0x5d, 0xda, 0xbe, 0x41, 0x9a, 0x50, 0xb3, 0x5f, 0x4f, 0x77,
-	0x77, 0x8e, 0x9f, 0xb5, 0x4b, 0xa4, 0x02, 0xb6, 0x11, 0xb6, 0xa7, 0x3a, 0x4f, 0xa0, 0x8c, 0xcf,
-	0xbe, 0x0e, 0x79, 0x19, 0xb7, 0x6f, 0x58, 0xeb, 0x36, 0xdd, 0x6f, 0x97, 0x48, 0x0d, 0x66, 0xb6,
-	0xe9, 0xfe, 0xe6, 0xa3, 0xf6, 0x94, 0xc5, 0x5e, 0x3d, 0xde, 0x6c, 0x4f, 0x13, 0x80, 0xd9, 0x57,
-	0x8f, 0x37, 0xd9, 0xe6, 0xa3, 0x76, 0xb9, 0x73, 0x02, 0xf5, 0x42, 0x96, 0xed, 0x9c, 0x48, 0xb5,
-	0x60, 0x27, 0x32, 0xe2, 0x38, 0x4d, 0xaa, 0xb4, 0x92, 0x6a, 0xf1, 0x4c, 0x46, 0xdc, 0x96, 0x95,
-	0x35, 0xa9, 0xbe, 0xc0, 0x09, 0x52, 0xa5, 0xb3, 0xa9, 0x16, 0xb4, 0x2f, 0xc8, 0x97, 0xd0, 0x1a,
-	0x4a, 0x9b, 0xe6, 0xb1, 0x72, 0x1a, 0xed, 0x0d, 0x44, 0x8f, 0x9d, 0xbc, 0x23, 0x81, 0xbc, 0x9b,
-	0x65, 0xb2, 0x01, 0x4b, 0xf8, 0xdc, 0x58, 0x72, 0x3a, 0xd2, 0x81, 0xcf, 0x43, 0x16, 0x89, 0x48,
-	0xaa, 0x11, 0x6e, 0x5e, 0xa6, 0x0b, 0x68, 0x3c, 0xcc, 0x6c, 0xfb, 0x68, 0xb2, 0x43, 0x87, 0x9f,
-	0xf1, 0x20, 0xe4, 0xfd, 0x50, 0xd8, 0x4e, 0xab, 0x31, 0x9e, 0x19, 0xda, 0x1c, 0xa3, 0xdd, 0x24,
-	0xd5, 0x9d, 0x7f, 0x4b, 0x50, 0xcd, 0x33, 0x4c, 0x08, 0x94, 0x07, 0x42, 0xfb, 0xe8, 0xb6, 0x46,
-	0xf1, 0xdb, 0x62, 0xf8, 0x80, 0xdc, 0x3c, 0xc4, 0x6f, 0x72, 0x07, 0x40, 0x1b, 0xae, 0x0c, 0x0e,
-	0x55, 0x3c, 0x47, 0x99, 0xd6, 0x10, 0xb1, 0xb3, 0x94, 0xdc, 0x82, 0x9a, 0x12, 0x3c, 0x74, 0xd6,
-	0x32, 0x5a, 0xab, 0x16, 0x40, 0xe3, 0xe7, 0x00, 0x2e, 0x78, 0x9b, 0x08, 0x9c, 0x6d, 0xe5, 0x9d,
-	0x29, 0xaf, 0x44, 0x6b, 0x0e, 0x3d, 0xd6, 0x82, 0xfc, 0x0e, 0xcb, 0x89, 0x92, 0xbe, 0xd0, 0x5a,
-	0xe8, 0x2b, 0xcf, 0x73, 0x16, 0x1f, 0xca, 0xda, 0xe4, 0x87, 0xe2, 0x34, 0x97, 0xde, 0xe7, 0xd2,
-	0xd8, 0x51, 0x11, 0xee, 0xfc, 0x39, 0x0d, 0x0b, 0x13, 0xe8, 0xe3, 0xc3, 0x96, 0x0a, 0x87, 0x5d,
-	0x83, 0x76, 0xaa, 0x85, 0xc2, 0xd3, 0xb0, 0x28, 0xb0, 0xed, 0x15, 0x93, 0x51, 0xa6, 0x2d, 0x8b,
-	0xdb, 0x43, 0xed, 0x23, 0x6a, 0x27, 0x5b, 0x56, 0x53, 0x45, 0xae, 0x4b, 0x4f, 0xdb, 0x59, 0x0a,
-	0xec, 0xdb, 0x00, 0x11, 0x3f, 0x67, 0x4a, 0x6b, 0xf6, 0xa6, 0x9f, 0xa7, 0x29, 0xe2, 0xe7, 0x54,
-	0xeb, 0xbd, 0x3e, 0xf9, 0x1a, 0xe6, 0xa3, 0x20, 0x96, 0x8a, 0x25, 0xfc, 0x44, 0xb0, 0x21, 0x4f,
-	0x43, 0xa3, 0x5d, 0xb6, 0xe8, 0x1c, 0x1a, 0x0e, 0xf9, 0x89, 0xf8, 0x01, 0x61, 0xe4, 0xf2, 0xd7,
-	0x57, 0xb8, 0xb3, 0x19, 0xd7, 0x1a, 0x0a, 0xdc, 0x4f, 0xa1, 0x1e, 0x48, 0x16, 0xc4, 0x49, 0x6a,
-	0xec, 0xb6, 0x15, 0x77, 0x77, 0x81, 0x7c, 0x6e, 0x91, 0xbd, 0x3e, 0x59, 0x85, 0x46, 0x20, 0x99,
-	0x4c, 0x4d, 0x46, 0xa8, 0x22, 0x01, 0x02, 0xd9, 0x43, 0x68, 0xaf, 0x4f, 0x9e, 0xc0, 0xca, 0x99,
-	0x0c, 0xd3, 0xd8, 0x70, 0x35, 0xb2, 0xed, 0xc9, 0x88, 0x73, 0xc3, 0xf4, 0x1f, 0x81, 0xf1, 0x4f,
-	0x85, 0xc6, 0x11, 0x5d, 0xa6, 0xde, 0x98, 0xd1, 0x75, 0x84, 0xa3, 0xcc, 0x4e, 0xbe, 0x87, 0xdb,
-	0x41, 0xfc, 0x1e, 0x3d, 0xa0, 0x7e, 0xa5, 0xc0, 0xb9, 0xe2, 0xa1, 0xf3, 0x4f, 0x09, 0x5a, 0xfb,
-	0x72, 0x90, 0x86, 0xe2, 0xc5, 0x28, 0x71, 0xd7, 0xf6, 0x5b, 0xde, 0x2d, 0x5d, 0x92, 0xf1, 0xfa,
-	0x5a, 0x1b, 0x0f, 0x26, 0x8f, 0xf5, 0x4b, 0x52, 0xd7, 0x3c, 0x5d, 0xc9, 0x15, 0x06, 0x7c, 0xff,
-	0x02, 0x25, 0x9f, 0x41, 0x3d, 0x42, 0x0d, 0x33, 0xa3, 0x24, 0xaf, 0x03, 0x88, 0xc6, 0x6e, 0x6c,
-	0x65, 0xc7, 0x69, 0xc4, 0xe4, 0x90, 0x39, 0xd0, 0x5d, 0x79, 0x93, 0x36, 0xe2, 0x34, 0xea, 0x0d,
-	0xdd, 0x7e, 0xba, 0xf3, 0x20, 0x6b, 0x21, 0x99, 0xd7, 0x4b, 0x7d, 0xa8, 0x06, 0x33, 0x47, 0xbd,
-	0xde, 0x81, 0x6d, 0x58, 0x55, 0x28, 0xef, 0x6f, 0xef, 0xed, 0xb6, 0xa7, 0x3a, 0x21, 0xac, 0x74,
-	0x55, 0x60, 0x6c, 0x49, 0x1f, 0x6b, 0xa1, 0x7e, 0x92, 0xa9, 0x8a, 0xc5, 0x28, 0x1f, 0x10, 0x93,
-	0x5e, 0xea, 0x16, 0x54, 0xf2, 0x01, 0x34, 0xf5, 0x9e, 0x79, 0x51, 0xf8, 0x61, 0x43, 0x73, 0x41,
-	0xa7, 0x0f, 0xb7, 0x26, 0xec, 0xa6, 0x2f, 0xe6, 0x51, 0xd9, 0x4f, 0x5f, 0x6b, 0xaf, 0x84, 0xf5,
-	0x37, 0x39, 0xb3, 0xff, 0x1f, 0x2d, 0x45, 0x71, 0xe7, 0xaf, 0x12, 0xcc, 0xbf, 0x33, 0xfd, 0x88,
-	0x07, 0x95, 0x3c, 0x6f, 0x25, 0xcc, 0x5b, 0xbe, 0xb4, 0xf3, 0x2b, 0xfb, 0x79, 0xe8, 0x0e, 0xd4,
-	0xa4, 0xe3, 0xb5, 0x7d, 0xf3, 0xae, 0x25, 0xf2, 0x30, 0x94, 0x3e, 0xf3, 0x65, 0x1a, 0x9b, 0xac,
-	0xd4, 0xe6, 0xd0, 0xb0, 0x6d, 0xf1, 0xae, 0x85, 0x6d, 0x05, 0x17, 0xb9, 0x3a, 0x78, 0x9b, 0xb7,
-	0xa5, 0xd6, 0x05, 0xf5, 0x28, 0x78, 0x2b, 0xec, 0xef, 0x31, 0x5b, 0x93, 0xa7, 0x82, 0x27, 0x8e,
-	0xe6, 0x2a, 0xae, 0x1e, 0xf1, 0xf3, 0x1f, 0x05, 0x4f, 0x2c, 0x67, 0x67, 0xe9, 0xd7, 0x6c, 0xe4,
-	0x67, 0xe7, 0x66, 0xf8, 0x97, 0xe4, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcb, 0xfb, 0x8e, 0xf5,
-	0xa2, 0x0c, 0x00, 0x00,
+	// 1423 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xdd, 0x52, 0x1b, 0xc7,
+	0x12, 0xb6, 0x40, 0x20, 0xa9, 0xf5, 0x83, 0x18, 0xe0, 0xb0, 0xc6, 0xf6, 0x39, 0x1c, 0xc5, 0x76,
+	0xa8, 0x54, 0x8c, 0x5d, 0xc4, 0x45, 0xb9, 0x28, 0x57, 0x2a, 0x20, 0x13, 0xc7, 0xa1, 0x84, 0xa8,
+	0xc1, 0x38, 0x4e, 0x72, 0x31, 0x19, 0xad, 0x46, 0xb0, 0xf6, 0xee, 0xce, 0xd6, 0xcc, 0x2c, 0x01,
+	0xbf, 0x99, 0xaf, 0xf3, 0x12, 0x79, 0x81, 0x3c, 0x41, 0x5e, 0x20, 0x35, 0x3d, 0xbb, 0x62, 0xc1,
+	0x8a, 0x4d, 0xf9, 0x4e, 0xfb, 0xf5, 0xf7, 0xf5, 0x76, 0xf7, 0xf4, 0x74, 0xaf, 0xa0, 0x19, 0x09,
+	0xa3, 0x02, 0x5f, 0xaf, 0x27, 0x4a, 0x1a, 0x49, 0x16, 0xb4, 0x94, 0xf1, 0x31, 0x1b, 0xa4, 0x41,
+	0x38, 0x64, 0x99, 0xa9, 0xf3, 0x67, 0x03, 0xea, 0x3d, 0xf7, 0x7b, 0x87, 0x6b, 0x41, 0x1e, 0xc1,
+	0xa2, 0x23, 0x0c, 0xb9, 0x11, 0xcc, 0x04, 0x91, 0xd0, 0x86, 0x47, 0x89, 0x57, 0x5a, 0x2d, 0xad,
+	0x4d, 0x53, 0x82, 0xb6, 0x67, 0xdc, 0x88, 0x97, 0xb9, 0x85, 0xdc, 0x84, 0xaa, 0x53, 0x04, 0x43,
+	0x6f, 0x6a, 0xb5, 0xb4, 0x56, 0xa3, 0x15, 0x7c, 0x7e, 0x31, 0x24, 0x5b, 0x70, 0x33, 0x09, 0xb9,
+	0x19, 0x49, 0x15, 0xb1, 0x53, 0xa1, 0x74, 0x20, 0x63, 0xe6, 0xcb, 0xa1, 0x88, 0x79, 0x24, 0xbc,
+	0x69, 0xe4, 0x2e, 0xe7, 0x84, 0x57, 0xce, 0xde, 0xcd, 0xcc, 0xe4, 0x1e, 0xb4, 0x0c, 0x57, 0xc7,
+	0xc2, 0xb0, 0x44, 0xc9, 0x61, 0xea, 0x1b, 0xaf, 0x8c, 0x82, 0xa6, 0x43, 0x0f, 0x1c, 0x48, 0x86,
+	0xb0, 0x98, 0xd1, 0x5c, 0x10, 0xa7, 0x5c, 0x05, 0x3c, 0x36, 0xde, 0xcc, 0x6a, 0x69, 0xad, 0xb5,
+	0xf1, 0x60, 0x7d, 0x42, 0xce, 0xeb, 0x85, 0x7c, 0xd7, 0x77, 0xac, 0xe5, 0x95, 0x13, 0x6d, 0x4d,
+	0xef, 0xee, 0x3f, 0xa7, 0xc4, 0xf9, 0x2b, 0x1a, 0x48, 0x1f, 0xea, 0xd9, 0x5b, 0xb8, 0xf2, 0x4f,
+	0xbc, 0x59, 0x74, 0x7e, 0xef, 0x93, 0xce, 0xb7, 0x95, 0x7f, 0xb2, 0x55, 0x39, 0xda, 0xdf, 0xdb,
+	0xef, 0xff, 0xb4, 0x4f, 0xc1, 0xb9, 0xb0, 0x20, 0x59, 0x87, 0x85, 0x82, 0xc3, 0x71, 0xd4, 0x15,
+	0x4c, 0x71, 0xfe, 0x82, 0x98, 0x07, 0xf0, 0x35, 0x64, 0x61, 0x31, 0x3f, 0x49, 0xc7, 0xf4, 0x2a,
+	0xd2, 0xdb, 0xce, 0xd2, 0x4d, 0xd2, 0x9c, 0xbd, 0x07, 0xb5, 0x13, 0xa9, 0xb3, 0x60, 0x6b, 0x9f,
+	0x15, 0x6c, 0xd5, 0x3a, 0xc0, 0x50, 0x29, 0x34, 0xd1, 0xd9, 0x46, 0x3c, 0x74, 0x0e, 0xe1, 0xb3,
+	0x1c, 0xd6, 0xad, 0x93, 0x8d, 0x78, 0x88, 0x3e, 0x97, 0xa1, 0x82, 0x3e, 0xa5, 0xf6, 0xea, 0x98,
+	0xc3, 0xac, 0x7d, 0xec, 0x6b, 0xd2, 0xc9, 0x5e, 0x26, 0x35, 0x13, 0x67, 0x46, 0x71, 0xaf, 0x81,
+	0xe6, 0xba, 0x33, 0xef, 0x5a, 0x68, 0xcc, 0xf1, 0x95, 0xd4, 0xda, 0xba, 0x68, 0x5e, 0x70, 0xba,
+	0x16, 0xeb, 0x6b, 0x72, 0x1f, 0xe6, 0x0a, 0x1c, 0x0c, 0xbb, 0xe5, 0xda, 0x67, 0xcc, 0xc2, 0x40,
+	0x1e, 0xc0, 0x42, 0x81, 0x37, 0x4e, 0x71, 0xce, 0x15, 0x76, 0xcc, 0x2d, 0xc4, 0x2d, 0x53, 0xc3,
+	0x86, 0x81, 0xf2, 0xda, 0x2e, 0x6e, 0x99, 0x9a, 0x67, 0x81, 0x22, 0xdf, 0x42, 0x5d, 0x0b, 0x93,
+	0x26, 0xcc, 0x48, 0x19, 0x6a, 0x6f, 0x7e, 0x75, 0x7a, 0xad, 0xbe, 0x71, 0x67, 0x62, 0x89, 0x0e,
+	0x84, 0x1a, 0xbd, 0x88, 0x47, 0x92, 0x02, 0x2a, 0x5e, 0x5a, 0x01, 0xd9, 0x82, 0xda, 0x5b, 0x6e,
+	0x02, 0xa6, 0xd2, 0x58, 0x7b, 0xe4, 0x3a, 0xea, 0xaa, 0xe5, 0xd3, 0x34, 0xd6, 0xe4, 0x29, 0x80,
+	0x63, 0xa2, 0x78, 0xe1, 0x3a, 0xe2, 0x1a, 0x5a, 0x73, 0x75, 0x1c, 0xc4, 0x6f, 0xb8, 0x53, 0x2f,
+	0x5e, 0x4b, 0x8d, 0x02, 0x54, 0x7f, 0x03, 0x33, 0x46, 0x1a, 0x1e, 0x7a, 0x4b, 0xab, 0xa5, 0x4f,
+	0x0b, 0x1d, 0x97, 0xbc, 0x82, 0x49, 0xa3, 0xc8, 0xfb, 0x0f, 0xba, 0xb8, 0x3f, 0xd1, 0xc5, 0xa1,
+	0xc5, 0xf0, 0x4a, 0x66, 0x1d, 0x46, 0xe7, 0xf5, 0x55, 0x88, 0x74, 0xa1, 0xe1, 0x54, 0xbe, 0x8c,
+	0x47, 0xc1, 0xb1, 0xb7, 0x8c, 0x0e, 0x57, 0x27, 0x3a, 0x44, 0x61, 0x17, 0x79, 0xb4, 0x3e, 0xb8,
+	0x78, 0x20, 0x2b, 0x80, 0xad, 0x8f, 0x23, 0xca, 0xc3, 0x33, 0x1e, 0x3f, 0x93, 0x9f, 0x61, 0x51,
+	0x9f, 0x6b, 0x23, 0x22, 0xa6, 0x84, 0x96, 0xa9, 0xf2, 0x05, 0x0b, 0xe2, 0x91, 0xf4, 0x6e, 0xe2,
+	0x8b, 0xbe, 0x9c, 0x1c, 0x39, 0x0a, 0x68, 0xc6, 0xc7, 0x32, 0x10, 0xfd, 0x01, 0x46, 0xbe, 0x80,
+	0x66, 0x1e, 0x7b, 0x14, 0xf1, 0x78, 0xe8, 0xad, 0xe0, 0xbb, 0x1b, 0x59, 0x68, 0x88, 0xd9, 0xb3,
+	0x1a, 0xf0, 0x77, 0x22, 0x74, 0x67, 0x75, 0xeb, 0x5a, 0x67, 0x85, 0x02, 0x7b, 0x56, 0x9d, 0x47,
+	0xd0, 0xb8, 0x34, 0xd4, 0xaa, 0x50, 0x3e, 0x3a, 0xdc, 0xa5, 0xed, 0x1b, 0xa4, 0x09, 0x35, 0xfb,
+	0xeb, 0xd9, 0xee, 0xce, 0xd1, 0xf3, 0x76, 0x89, 0x54, 0xc0, 0x0e, 0xc2, 0xf6, 0x54, 0xe7, 0x29,
+	0x94, 0xb1, 0xed, 0xeb, 0x90, 0x5f, 0xe3, 0xf6, 0x0d, 0x6b, 0xdd, 0xa6, 0xbd, 0x76, 0x89, 0xd4,
+	0x60, 0x66, 0x9b, 0xf6, 0x36, 0x1f, 0xb7, 0xa7, 0x2c, 0xf6, 0xfa, 0xc9, 0x66, 0x7b, 0x9a, 0x00,
+	0xcc, 0xbe, 0x7e, 0xb2, 0xc9, 0x36, 0x1f, 0xb7, 0xcb, 0x9d, 0xf7, 0x25, 0xa8, 0x17, 0xca, 0x6c,
+	0x17, 0x45, 0xaa, 0x05, 0x3b, 0x96, 0x11, 0xc7, 0x75, 0x52, 0xa5, 0x95, 0x54, 0x8b, 0xe7, 0x32,
+	0xe2, 0xf6, 0x5e, 0x59, 0x93, 0x1a, 0x08, 0x5c, 0x21, 0x55, 0x3a, 0x9b, 0x6a, 0x41, 0x07, 0x82,
+	0xdc, 0x85, 0xd6, 0x48, 0xda, 0x3a, 0x8f, 0x95, 0xd3, 0x68, 0x6f, 0x20, 0x7a, 0x94, 0xc9, 0xef,
+	0x42, 0xcb, 0xd5, 0x85, 0x6b, 0x86, 0xbd, 0x89, 0xbb, 0xa2, 0x4a, 0x1b, 0x88, 0x6e, 0xeb, 0x7d,
+	0x8b, 0x91, 0xaf, 0x60, 0xde, 0xb1, 0xa2, 0xe0, 0x4c, 0x0c, 0x5d, 0xc1, 0x70, 0x4f, 0x54, 0xe9,
+	0x1c, 0x1a, 0x7a, 0x16, 0xc7, 0x88, 0x3b, 0x12, 0xc8, 0x87, 0x07, 0x47, 0x36, 0x60, 0x09, 0x3b,
+	0x98, 0x25, 0x27, 0xe7, 0x3a, 0xf0, 0x79, 0xc8, 0x22, 0x11, 0x49, 0x75, 0x8e, 0xe9, 0x94, 0xe9,
+	0x02, 0x1a, 0x0f, 0x32, 0x5b, 0x0f, 0x4d, 0x76, 0x8f, 0xf1, 0x53, 0x1e, 0x84, 0x7c, 0x10, 0x0a,
+	0x3b, 0xbc, 0x35, 0x66, 0x38, 0x43, 0x9b, 0x63, 0xb4, 0x9b, 0xa4, 0xba, 0xf3, 0x77, 0x09, 0xaa,
+	0xf9, 0xa1, 0x11, 0x02, 0xe5, 0xa1, 0xd0, 0x3e, 0xba, 0xad, 0x51, 0xfc, 0x6d, 0x31, 0xec, 0x49,
+	0xb7, 0x62, 0xf1, 0x37, 0xb9, 0x03, 0xa0, 0x0d, 0x57, 0x06, 0xf7, 0x34, 0x56, 0xa6, 0x4c, 0x6b,
+	0x88, 0xd8, 0xf5, 0x4c, 0x6e, 0x41, 0x4d, 0x09, 0x1e, 0x3a, 0x6b, 0x19, 0xad, 0x55, 0x0b, 0xa0,
+	0xf1, 0xff, 0x00, 0x2e, 0x78, 0x5b, 0x5a, 0x2c, 0x43, 0x79, 0x67, 0xca, 0x2b, 0xd1, 0x9a, 0x43,
+	0x8f, 0xb4, 0x20, 0xbf, 0xc1, 0x72, 0xa2, 0xa4, 0x2f, 0xb4, 0x16, 0xfa, 0x4a, 0xc7, 0xcf, 0x62,
+	0xef, 0xad, 0x4d, 0xee, 0x3d, 0xa7, 0xb9, 0xd4, 0xf2, 0x4b, 0x63, 0x47, 0x45, 0xb8, 0xf3, 0x7e,
+	0x1a, 0x16, 0x26, 0xd0, 0xc7, 0xc9, 0x96, 0x0a, 0xc9, 0xae, 0x41, 0x3b, 0xd5, 0x42, 0x61, 0x36,
+	0x2c, 0x0a, 0xec, 0xc4, 0xc6, 0x62, 0x94, 0x69, 0xcb, 0xe2, 0x36, 0xa9, 0x1e, 0xa2, 0x76, 0x59,
+	0x66, 0xd7, 0xb4, 0xc8, 0x75, 0xe5, 0x69, 0x3b, 0x4b, 0x81, 0x7d, 0x1b, 0x20, 0xe2, 0x67, 0x4c,
+	0x69, 0xcd, 0xde, 0x0e, 0xf2, 0x32, 0x45, 0xfc, 0x8c, 0x6a, 0xbd, 0x37, 0xb0, 0x4d, 0x13, 0x05,
+	0xb1, 0x54, 0x2c, 0xe1, 0xc7, 0x82, 0x8d, 0x78, 0x1a, 0x1a, 0xed, 0xaa, 0x45, 0xe7, 0xd0, 0x70,
+	0xc0, 0x8f, 0xc5, 0xf7, 0x08, 0x23, 0x97, 0xbf, 0xb9, 0xc2, 0x9d, 0xcd, 0xb8, 0xd6, 0x50, 0xe0,
+	0xfe, 0x17, 0xea, 0x81, 0x64, 0x41, 0x9c, 0xa4, 0xc6, 0xbe, 0xb6, 0xe2, 0xce, 0x2e, 0x90, 0x2f,
+	0x2c, 0xb2, 0x37, 0x20, 0xab, 0xd0, 0x08, 0x24, 0x93, 0xa9, 0xc9, 0x08, 0x55, 0x24, 0x40, 0x20,
+	0xfb, 0x08, 0xed, 0x0d, 0xc8, 0x53, 0x58, 0x39, 0x95, 0x61, 0x1a, 0x1b, 0xae, 0xce, 0xed, 0xc4,
+	0x33, 0xe2, 0xcc, 0x30, 0xfd, 0x7b, 0x60, 0xfc, 0x13, 0xa1, 0x71, 0xeb, 0x97, 0xa9, 0x37, 0x66,
+	0x74, 0x1d, 0xe1, 0x30, 0xb3, 0x93, 0xef, 0xe0, 0x76, 0x10, 0x7f, 0x44, 0x0f, 0xa8, 0x5f, 0x29,
+	0x70, 0xae, 0x78, 0xe8, 0xfc, 0x55, 0x82, 0x56, 0x4f, 0x0e, 0xd3, 0x50, 0xbc, 0x3c, 0x4f, 0xdc,
+	0xb1, 0xfd, 0x9a, 0x0f, 0x60, 0x57, 0x64, 0x3c, 0xbe, 0xd6, 0xc6, 0xc3, 0xc9, 0x5f, 0x0a, 0x97,
+	0xa4, 0x6e, 0x1e, 0xbb, 0x2b, 0x57, 0xf8, 0x66, 0x18, 0x5c, 0xa0, 0xe4, 0x7f, 0x50, 0x8f, 0x50,
+	0xc3, 0xcc, 0x79, 0x92, 0xdf, 0x03, 0x88, 0xc6, 0x6e, 0xec, 0x14, 0x88, 0xd3, 0x88, 0xc9, 0x11,
+	0x73, 0xa0, 0x3b, 0xf2, 0x26, 0x6d, 0xc4, 0x69, 0xd4, 0x1f, 0xb9, 0xf7, 0xe9, 0xce, 0xc3, 0x6c,
+	0x28, 0x65, 0x5e, 0x2f, 0x8d, 0xb6, 0x1a, 0xcc, 0x1c, 0xf6, 0xfb, 0xfb, 0x76, 0x06, 0x56, 0xa1,
+	0xdc, 0xdb, 0xde, 0xdb, 0x6d, 0x4f, 0x75, 0x42, 0x58, 0xe9, 0xaa, 0xc0, 0xd8, 0x2b, 0x7d, 0xa4,
+	0x85, 0xfa, 0x51, 0xa6, 0x2a, 0x16, 0xe7, 0xf9, 0xce, 0x99, 0xd4, 0xa9, 0x5b, 0x50, 0xc9, 0x77,
+	0xda, 0xd4, 0x47, 0x56, 0x50, 0xe1, 0x5b, 0x89, 0xe6, 0x82, 0xce, 0x00, 0x6e, 0x4d, 0x78, 0x9b,
+	0xbe, 0x58, 0x71, 0x65, 0x3f, 0x7d, 0xa3, 0xbd, 0x12, 0xde, 0xbf, 0xc9, 0x95, 0xfd, 0xf7, 0x68,
+	0x29, 0x8a, 0x3b, 0x7f, 0x94, 0x60, 0xfe, 0x83, 0x85, 0x4a, 0x3c, 0xa8, 0xe4, 0x75, 0x2b, 0x61,
+	0xdd, 0xf2, 0x47, 0xbb, 0x12, 0xb3, 0x2f, 0x4e, 0x97, 0x50, 0x93, 0x8e, 0x9f, 0x6d, 0xcf, 0xbb,
+	0x91, 0xc8, 0xc3, 0x50, 0xfa, 0xcc, 0x97, 0x69, 0x6c, 0xb2, 0xab, 0x36, 0x87, 0x86, 0x6d, 0x8b,
+	0x77, 0x2d, 0x6c, 0x6f, 0x70, 0x91, 0xab, 0x83, 0x77, 0xf9, 0x58, 0x6a, 0x5d, 0x50, 0x0f, 0x83,
+	0x77, 0xc2, 0x7e, 0xe2, 0xd9, 0x3b, 0x79, 0x22, 0x78, 0xe2, 0x68, 0xee, 0xc6, 0xd5, 0x23, 0x7e,
+	0xf6, 0x83, 0xe0, 0x89, 0xe5, 0xec, 0x2c, 0xfd, 0x92, 0x7d, 0x45, 0x64, 0x79, 0x33, 0xfc, 0x97,
+	0xf3, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe9, 0x63, 0x09, 0x14, 0xf5, 0x0c, 0x00, 0x00,
 }
diff --git a/ui/metrics/metrics_proto/metrics.proto b/ui/metrics/metrics_proto/metrics.proto
index 91d8dd9..b284bf9 100644
--- a/ui/metrics/metrics_proto/metrics.proto
+++ b/ui/metrics/metrics_proto/metrics.proto
@@ -116,6 +116,13 @@
   optional bool use_rbe = 2;
 
   optional bool force_use_goma = 3;
+
+  // Whether the Bazel is acting as the Ninja executor for this build.
+  optional bool bazel_as_ninja = 4;
+
+  // Whether build is occurring in a mixed build mode, where Bazel maintains the
+  // definition and build of some modules in cooperation with Soong.
+  optional bool bazel_mixed_build = 5;
 }
 
 message SystemResourceInfo {