Move toolchain and global variables into separate package

Move all of the configuration into a cc/config package

Change-Id: If56fc7242062ed1ce3cb297f78a1e0ef7537373c
diff --git a/cc/builder.go b/cc/builder.go
index 5988140..02ea63d 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -19,15 +19,16 @@
 // functions.
 
 import (
-	"android/soong/android"
 	"fmt"
+	"path/filepath"
 	"runtime"
 	"strconv"
-
-	"path/filepath"
 	"strings"
 
 	"github.com/google/blueprint"
+
+	"android/soong/android"
+	"android/soong/cc/config"
 )
 
 const (
@@ -79,16 +80,16 @@
 
 	darwinAr = pctx.StaticRule("darwinAr",
 		blueprint.RuleParams{
-			Command:     "rm -f ${out} && ${macArPath} $arFlags $out $in",
-			CommandDeps: []string{"${macArPath}"},
+			Command:     "rm -f ${out} && ${config.MacArPath} $arFlags $out $in",
+			CommandDeps: []string{"${config.MacArPath}"},
 			Description: "ar $out",
 		},
 		"arFlags")
 
 	darwinAppendAr = pctx.StaticRule("darwinAppendAr",
 		blueprint.RuleParams{
-			Command:     "cp -f ${inAr} ${out}.tmp && ${macArPath} $arFlags ${out}.tmp $in && mv ${out}.tmp ${out}",
-			CommandDeps: []string{"${macArPath}", "${inAr}"},
+			Command:     "cp -f ${inAr} ${out}.tmp && ${config.MacArPath} $arFlags ${out}.tmp $in && mv ${out}.tmp ${out}",
+			CommandDeps: []string{"${config.MacArPath}", "${inAr}"},
 			Description: "ar $out",
 		},
 		"arFlags", "inAr")
@@ -161,7 +162,7 @@
 	libFlags    string
 	yaccFlags   string
 	nocrt       bool
-	toolchain   Toolchain
+	toolchain   config.Toolchain
 	clang       bool
 
 	stripKeepSymbols       bool
@@ -180,11 +181,11 @@
 	asflags := flags.globalFlags + " " + flags.asFlags
 
 	if flags.clang {
-		cflags += " ${noOverrideClangGlobalCflags}"
-		cppflags += " ${noOverrideClangGlobalCflags}"
+		cflags += " ${config.NoOverrideClangGlobalCflags}"
+		cppflags += " ${config.NoOverrideClangGlobalCflags}"
 	} else {
-		cflags += " ${noOverrideGlobalCflags}"
-		cppflags += " ${noOverrideGlobalCflags}"
+		cflags += " ${config.NoOverrideGlobalCflags}"
+		cppflags += " ${config.NoOverrideGlobalCflags}"
 	}
 
 	for i, srcFile := range srcFiles {
@@ -220,7 +221,7 @@
 				panic("unrecoginzied ccCmd")
 			}
 
-			ccCmd = "${clangBin}/" + ccCmd
+			ccCmd = "${config.ClangBin}/" + ccCmd
 		} else {
 			ccCmd = gccCmd(flags.toolchain, ccCmd)
 		}
@@ -345,7 +346,7 @@
 
 	var ldCmd string
 	if flags.clang {
-		ldCmd = "${clangBin}/clang++"
+		ldCmd = "${config.ClangBin}/clang++"
 	} else {
 		ldCmd = gccCmd(flags.toolchain, "g++")
 	}
@@ -416,7 +417,7 @@
 
 	var ldCmd string
 	if flags.clang {
-		ldCmd = "${clangBin}clang++"
+		ldCmd = "${config.ClangBin}/clang++"
 	} else {
 		ldCmd = gccCmd(flags.toolchain, "g++")
 	}
@@ -499,7 +500,7 @@
 	})
 }
 
-func gccCmd(toolchain Toolchain, cmd string) string {
+func gccCmd(toolchain config.Toolchain, cmd string) string {
 	return filepath.Join(toolchain.GccRoot(), "bin", toolchain.GccTriple()+"-"+cmd)
 }
 
diff --git a/cc/cc.go b/cc/cc.go
index 53345c5..5385eaa 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -27,6 +27,7 @@
 
 	"android/soong"
 	"android/soong/android"
+	"android/soong/cc/config"
 	"android/soong/genrule"
 )
 
@@ -48,6 +49,8 @@
 
 	android.RegisterTopDownMutator("tsan_deps", sanitizerDepsMutator(tsan))
 	android.RegisterBottomUpMutator("tsan", sanitizerMutator(tsan))
+
+	pctx.Import("android/soong/cc/config")
 }
 
 type Deps struct {
@@ -90,7 +93,7 @@
 	libFlags    []string // Flags to add libraries early to the link order
 
 	Nocrt     bool
-	Toolchain Toolchain
+	Toolchain config.Toolchain
 	Clang     bool
 
 	RequiredInstructionSet string
@@ -130,7 +133,7 @@
 	static() bool
 	staticBinary() bool
 	clang() bool
-	toolchain() Toolchain
+	toolchain() config.Toolchain
 	noDefaultCompilerFlags() bool
 	sdk() bool
 	sdkVersion() string
@@ -239,7 +242,7 @@
 
 	outputFile android.OptionalPath
 
-	cachedToolchain Toolchain
+	cachedToolchain config.Toolchain
 }
 
 func (c *Module) Init() (blueprint.Module, []interface{}) {
@@ -305,7 +308,7 @@
 	return ctx.mod.clang(ctx.ctx)
 }
 
-func (ctx *moduleContextImpl) toolchain() Toolchain {
+func (ctx *moduleContextImpl) toolchain() config.Toolchain {
 	return ctx.mod.toolchain(ctx.ctx)
 }
 
@@ -406,9 +409,9 @@
 		return
 	}
 
-	flags.CFlags, _ = filterList(flags.CFlags, illegalFlags)
-	flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags)
-	flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags)
+	flags.CFlags, _ = filterList(flags.CFlags, config.IllegalFlags)
+	flags.CppFlags, _ = filterList(flags.CppFlags, config.IllegalFlags)
+	flags.ConlyFlags, _ = filterList(flags.ConlyFlags, config.IllegalFlags)
 
 	// Optimization to reduce size of build.ninja
 	// Replace the long list of flags for each file with a module-local variable
@@ -450,16 +453,9 @@
 	}
 }
 
-func (c *Module) toolchain(ctx BaseModuleContext) Toolchain {
+func (c *Module) toolchain(ctx BaseModuleContext) config.Toolchain {
 	if c.cachedToolchain == nil {
-		arch := ctx.Arch()
-		os := ctx.Os()
-		factory := toolchainFactories[os][arch.ArchType]
-		if factory == nil {
-			ctx.ModuleErrorf("Toolchain not found for %s arch %q", os.String(), arch.String())
-			return nil
-		}
-		c.cachedToolchain = factory(arch)
+		c.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch())
 	}
 	return c.cachedToolchain
 }
diff --git a/cc/check.go b/cc/check.go
index f4b2834..82d5a9f 100644
--- a/cc/check.go
+++ b/cc/check.go
@@ -20,6 +20,8 @@
 import (
 	"path/filepath"
 	"strings"
+
+	"android/soong/cc/config"
 )
 
 // Check for invalid c/conly/cpp/asflags and suggest alternatives. Only use this
@@ -32,7 +34,7 @@
 			ctx.PropertyErrorf(prop, "Flag `%s` must start with `-`", flag)
 		} else if strings.HasPrefix(flag, "-I") || strings.HasPrefix(flag, "-isystem") {
 			ctx.PropertyErrorf(prop, "Bad flag `%s`, use local_include_dirs or include_dirs instead", flag)
-		} else if inList(flag, illegalFlags) {
+		} else if inList(flag, config.IllegalFlags) {
 			ctx.PropertyErrorf(prop, "Illegal flag `%s`", flag)
 		} else if strings.Contains(flag, " ") {
 			args := strings.Split(flag, " ")
diff --git a/cc/compiler.go b/cc/compiler.go
index 8fcab8f..4c30c98 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -20,6 +20,7 @@
 	"strings"
 
 	"android/soong/android"
+	"android/soong/cc/config"
 )
 
 // This file contains the basic C/C++/assembly to .o compliation steps
@@ -118,7 +119,7 @@
 // Create a Flags struct that collects the compile flags from global values,
 // per-target values, module type values, and per-module Blueprints properties
 func (compiler *baseCompiler) flags(ctx ModuleContext, flags Flags) Flags {
-	toolchain := ctx.toolchain()
+	tc := ctx.toolchain()
 
 	CheckBadCompilerFlags(ctx, "cflags", compiler.Properties.Cflags)
 	CheckBadCompilerFlags(ctx, "cppflags", compiler.Properties.Cppflags)
@@ -141,9 +142,9 @@
 	if !ctx.noDefaultCompilerFlags() {
 		if !ctx.sdk() || ctx.Host() {
 			flags.GlobalFlags = append(flags.GlobalFlags,
-				"${commonGlobalIncludes}",
-				toolchain.IncludeFlags(),
-				"${commonNativehelperInclude}")
+				"${config.CommonGlobalIncludes}",
+				tc.IncludeFlags(),
+				"${config.CommonNativehelperInclude}")
 		}
 
 		flags.GlobalFlags = append(flags.GlobalFlags, []string{
@@ -160,7 +161,7 @@
 		// behavior here, and the NDK always has all the NDK headers available.
 		flags.GlobalFlags = append(flags.GlobalFlags,
 			"-isystem "+getCurrentIncludePath(ctx).String(),
-			"-isystem "+getCurrentIncludePath(ctx).Join(ctx, toolchain.ClangTriple()).String())
+			"-isystem "+getCurrentIncludePath(ctx).Join(ctx, tc.ClangTriple()).String())
 
 		// Traditionally this has come from android/api-level.h, but with the
 		// libc headers unified it must be set by the build system since we
@@ -181,9 +182,9 @@
 	if flags.RequiredInstructionSet != "" {
 		instructionSet = flags.RequiredInstructionSet
 	}
-	instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
+	instructionSetFlags, err := tc.InstructionSetFlags(instructionSet)
 	if flags.Clang {
-		instructionSetFlags, err = toolchain.ClangInstructionSetFlags(instructionSet)
+		instructionSetFlags, err = tc.ClangInstructionSetFlags(instructionSet)
 	}
 	if err != nil {
 		ctx.ModuleErrorf("%s", err)
@@ -198,17 +199,17 @@
 		CheckBadCompilerFlags(ctx, "clang_cflags", compiler.Properties.Clang_cflags)
 		CheckBadCompilerFlags(ctx, "clang_asflags", compiler.Properties.Clang_asflags)
 
-		flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
+		flags.CFlags = config.ClangFilterUnknownCflags(flags.CFlags)
 		flags.CFlags = append(flags.CFlags, compiler.Properties.Clang_cflags...)
 		flags.AsFlags = append(flags.AsFlags, compiler.Properties.Clang_asflags...)
-		flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
-		flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
-		flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
+		flags.CppFlags = config.ClangFilterUnknownCflags(flags.CppFlags)
+		flags.ConlyFlags = config.ClangFilterUnknownCflags(flags.ConlyFlags)
+		flags.LdFlags = config.ClangFilterUnknownCflags(flags.LdFlags)
 
-		target := "-target " + toolchain.ClangTriple()
+		target := "-target " + tc.ClangTriple()
 		var gccPrefix string
 		if !ctx.Darwin() {
-			gccPrefix = "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
+			gccPrefix = "-B" + filepath.Join(tc.GccRoot(), tc.GccTriple(), "bin")
 		}
 
 		flags.CFlags = append(flags.CFlags, target, gccPrefix)
@@ -216,29 +217,29 @@
 		flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
 	}
 
-	hod := "host"
+	hod := "Host"
 	if ctx.Os().Class == android.Device {
-		hod = "device"
+		hod = "Device"
 	}
 
 	if !ctx.noDefaultCompilerFlags() {
 		flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
 
 		if flags.Clang {
-			flags.AsFlags = append(flags.AsFlags, toolchain.ClangAsflags())
-			flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
+			flags.AsFlags = append(flags.AsFlags, tc.ClangAsflags())
+			flags.CppFlags = append(flags.CppFlags, "${config.CommonClangGlobalCppflags}")
 			flags.GlobalFlags = append(flags.GlobalFlags,
-				toolchain.ClangCflags(),
-				"${commonClangGlobalCflags}",
-				fmt.Sprintf("${%sClangGlobalCflags}", hod))
+				tc.ClangCflags(),
+				"${config.CommonClangGlobalCflags}",
+				fmt.Sprintf("${config.%sClangGlobalCflags}", hod))
 
-			flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
+			flags.ConlyFlags = append(flags.ConlyFlags, "${config.ClangExtraConlyflags}")
 		} else {
-			flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
+			flags.CppFlags = append(flags.CppFlags, "${config.CommonGlobalCppflags}")
 			flags.GlobalFlags = append(flags.GlobalFlags,
-				toolchain.Cflags(),
-				"${commonGlobalCflags}",
-				fmt.Sprintf("${%sGlobalCflags}", hod))
+				tc.Cflags(),
+				"${config.CommonGlobalCflags}",
+				fmt.Sprintf("${config.%sGlobalCflags}", hod))
 		}
 
 		if Bool(ctx.AConfig().ProductVariables.Brillo) {
@@ -256,16 +257,16 @@
 		flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
 
 		if flags.Clang {
-			flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
+			flags.CppFlags = append(flags.CppFlags, tc.ClangCppflags())
 		} else {
-			flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
+			flags.CppFlags = append(flags.CppFlags, tc.Cppflags())
 		}
 	}
 
 	if flags.Clang {
-		flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainClangCflags())
+		flags.GlobalFlags = append(flags.GlobalFlags, tc.ToolchainClangCflags())
 	} else {
-		flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainCflags())
+		flags.GlobalFlags = append(flags.GlobalFlags, tc.ToolchainCflags())
 	}
 
 	if !ctx.sdk() {
diff --git a/cc/arm64_device.go b/cc/config/arm64_device.go
similarity index 81%
rename from cc/arm64_device.go
rename to cc/config/arm64_device.go
index 1dc0ecd..9d425c1 100644
--- a/cc/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package cc
+package config
 
 import (
 	"fmt"
@@ -91,33 +91,33 @@
 func init() {
 	pctx.StaticVariable("arm64GccVersion", arm64GccVersion)
 
-	pctx.SourcePathVariable("arm64GccRoot",
+	pctx.SourcePathVariable("Arm64GccRoot",
 		"prebuilts/gcc/${HostPrebuiltTag}/aarch64/aarch64-linux-android-${arm64GccVersion}")
 
-	pctx.StaticVariable("arm64Cflags", strings.Join(arm64Cflags, " "))
-	pctx.StaticVariable("arm64Ldflags", strings.Join(arm64Ldflags, " "))
-	pctx.StaticVariable("arm64Cppflags", strings.Join(arm64Cppflags, " "))
-	pctx.StaticVariable("arm64IncludeFlags", bionicHeaders("arm64", "arm64"))
+	pctx.StaticVariable("Arm64Cflags", strings.Join(arm64Cflags, " "))
+	pctx.StaticVariable("Arm64Ldflags", strings.Join(arm64Ldflags, " "))
+	pctx.StaticVariable("Arm64Cppflags", strings.Join(arm64Cppflags, " "))
+	pctx.StaticVariable("Arm64IncludeFlags", bionicHeaders("arm64", "arm64"))
 
-	pctx.StaticVariable("arm64ClangCflags", strings.Join(clangFilterUnknownCflags(arm64Cflags), " "))
-	pctx.StaticVariable("arm64ClangLdflags", strings.Join(clangFilterUnknownCflags(arm64Ldflags), " "))
-	pctx.StaticVariable("arm64ClangCppflags", strings.Join(clangFilterUnknownCflags(arm64Cppflags), " "))
+	pctx.StaticVariable("Arm64ClangCflags", strings.Join(ClangFilterUnknownCflags(arm64Cflags), " "))
+	pctx.StaticVariable("Arm64ClangLdflags", strings.Join(ClangFilterUnknownCflags(arm64Ldflags), " "))
+	pctx.StaticVariable("Arm64ClangCppflags", strings.Join(ClangFilterUnknownCflags(arm64Cppflags), " "))
 
-	pctx.StaticVariable("arm64CortexA53Cflags",
+	pctx.StaticVariable("Arm64CortexA53Cflags",
 		strings.Join(arm64CpuVariantCflags["cortex-a53"], " "))
-	pctx.StaticVariable("arm64ClangCortexA53Cflags",
+	pctx.StaticVariable("Arm64ClangCortexA53Cflags",
 		strings.Join(arm64ClangCpuVariantCflags["cortex-a53"], " "))
 }
 
 var (
 	arm64CpuVariantCflagsVar = map[string]string{
 		"":           "",
-		"cortex-a53": "${arm64CortexA53Cflags}",
+		"cortex-a53": "${config.Arm64CortexA53Cflags}",
 	}
 
 	arm64ClangCpuVariantCflagsVar = map[string]string{
 		"":           "",
-		"cortex-a53": "${arm64ClangCortexA53Cflags}",
+		"cortex-a53": "${config.Arm64ClangCortexA53Cflags}",
 	}
 )
 
@@ -133,7 +133,7 @@
 }
 
 func (t *toolchainArm64) GccRoot() string {
-	return "${arm64GccRoot}"
+	return "${config.Arm64GccRoot}"
 }
 
 func (t *toolchainArm64) GccTriple() string {
@@ -149,19 +149,19 @@
 }
 
 func (t *toolchainArm64) Cflags() string {
-	return "${arm64Cflags}"
+	return "${config.Arm64Cflags}"
 }
 
 func (t *toolchainArm64) Cppflags() string {
-	return "${arm64Cppflags}"
+	return "${config.Arm64Cppflags}"
 }
 
 func (t *toolchainArm64) Ldflags() string {
-	return "${arm64Ldflags}"
+	return "${config.Arm64Ldflags}"
 }
 
 func (t *toolchainArm64) IncludeFlags() string {
-	return "${arm64IncludeFlags}"
+	return "${config.Arm64IncludeFlags}"
 }
 
 func (t *toolchainArm64) ClangTriple() string {
@@ -169,15 +169,15 @@
 }
 
 func (t *toolchainArm64) ClangCflags() string {
-	return "${arm64ClangCflags}"
+	return "${config.Arm64ClangCflags}"
 }
 
 func (t *toolchainArm64) ClangCppflags() string {
-	return "${arm64ClangCppflags}"
+	return "${config.Arm64ClangCppflags}"
 }
 
 func (t *toolchainArm64) ClangLdflags() string {
-	return "${arm64Ldflags}"
+	return "${config.Arm64Ldflags}"
 }
 
 func (t *toolchainArm64) ToolchainClangCflags() string {
diff --git a/cc/arm_device.go b/cc/config/arm_device.go
similarity index 70%
rename from cc/arm_device.go
rename to cc/config/arm_device.go
index a6c1911..f15d8da 100644
--- a/cc/arm_device.go
+++ b/cc/config/arm_device.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package cc
+package config
 
 import (
 	"fmt"
@@ -158,97 +158,97 @@
 
 	pctx.StaticVariable("armGccVersion", armGccVersion)
 
-	pctx.SourcePathVariable("armGccRoot",
+	pctx.SourcePathVariable("ArmGccRoot",
 		"prebuilts/gcc/${HostPrebuiltTag}/arm/arm-linux-androideabi-${armGccVersion}")
 
-	pctx.StaticVariable("armToolchainCflags", strings.Join(armToolchainCflags, " "))
-	pctx.StaticVariable("armCflags", strings.Join(armCflags, " "))
-	pctx.StaticVariable("armLdflags", strings.Join(armLdflags, " "))
-	pctx.StaticVariable("armCppflags", strings.Join(armCppflags, " "))
-	pctx.StaticVariable("armIncludeFlags", bionicHeaders("arm", "arm"))
+	pctx.StaticVariable("ArmToolchainCflags", strings.Join(armToolchainCflags, " "))
+	pctx.StaticVariable("ArmCflags", strings.Join(armCflags, " "))
+	pctx.StaticVariable("ArmLdflags", strings.Join(armLdflags, " "))
+	pctx.StaticVariable("ArmCppflags", strings.Join(armCppflags, " "))
+	pctx.StaticVariable("ArmIncludeFlags", bionicHeaders("arm", "arm"))
 
 	// Extended cflags
 
 	// ARM vs. Thumb instruction set flags
-	pctx.StaticVariable("armArmCflags", strings.Join(armArmCflags, " "))
-	pctx.StaticVariable("armThumbCflags", strings.Join(armThumbCflags, " "))
+	pctx.StaticVariable("ArmArmCflags", strings.Join(armArmCflags, " "))
+	pctx.StaticVariable("ArmThumbCflags", strings.Join(armThumbCflags, " "))
 
 	// Architecture variant cflags
-	pctx.StaticVariable("armArmv5TECflags", strings.Join(armArchVariantCflags["armv5te"], " "))
-	pctx.StaticVariable("armArmv7ACflags", strings.Join(armArchVariantCflags["armv7-a"], " "))
-	pctx.StaticVariable("armArmv7ANeonCflags", strings.Join(armArchVariantCflags["armv7-a-neon"], " "))
+	pctx.StaticVariable("ArmArmv5TECflags", strings.Join(armArchVariantCflags["armv5te"], " "))
+	pctx.StaticVariable("ArmArmv7ACflags", strings.Join(armArchVariantCflags["armv7-a"], " "))
+	pctx.StaticVariable("ArmArmv7ANeonCflags", strings.Join(armArchVariantCflags["armv7-a-neon"], " "))
 
 	// Cpu variant cflags
-	pctx.StaticVariable("armGenericCflags", strings.Join(armCpuVariantCflags[""], " "))
-	pctx.StaticVariable("armCortexA7Cflags", strings.Join(armCpuVariantCflags["cortex-a7"], " "))
-	pctx.StaticVariable("armCortexA8Cflags", strings.Join(armCpuVariantCflags["cortex-a8"], " "))
-	pctx.StaticVariable("armCortexA15Cflags", strings.Join(armCpuVariantCflags["cortex-a15"], " "))
-	pctx.StaticVariable("armKraitCflags", strings.Join(armCpuVariantCflags["krait"], " "))
+	pctx.StaticVariable("ArmGenericCflags", strings.Join(armCpuVariantCflags[""], " "))
+	pctx.StaticVariable("ArmCortexA7Cflags", strings.Join(armCpuVariantCflags["cortex-a7"], " "))
+	pctx.StaticVariable("ArmCortexA8Cflags", strings.Join(armCpuVariantCflags["cortex-a8"], " "))
+	pctx.StaticVariable("ArmCortexA15Cflags", strings.Join(armCpuVariantCflags["cortex-a15"], " "))
+	pctx.StaticVariable("ArmKraitCflags", strings.Join(armCpuVariantCflags["krait"], " "))
 
 	// Clang cflags
-	pctx.StaticVariable("armToolchainClangCflags", strings.Join(clangFilterUnknownCflags(armToolchainCflags), " "))
-	pctx.StaticVariable("armClangCflags", strings.Join(clangFilterUnknownCflags(armCflags), " "))
-	pctx.StaticVariable("armClangLdflags", strings.Join(clangFilterUnknownCflags(armLdflags), " "))
-	pctx.StaticVariable("armClangCppflags", strings.Join(clangFilterUnknownCflags(armCppflags), " "))
+	pctx.StaticVariable("ArmToolchainClangCflags", strings.Join(ClangFilterUnknownCflags(armToolchainCflags), " "))
+	pctx.StaticVariable("ArmClangCflags", strings.Join(ClangFilterUnknownCflags(armCflags), " "))
+	pctx.StaticVariable("ArmClangLdflags", strings.Join(ClangFilterUnknownCflags(armLdflags), " "))
+	pctx.StaticVariable("ArmClangCppflags", strings.Join(ClangFilterUnknownCflags(armCppflags), " "))
 
 	// Clang ARM vs. Thumb instruction set cflags
-	pctx.StaticVariable("armClangArmCflags", strings.Join(clangFilterUnknownCflags(armArmCflags), " "))
-	pctx.StaticVariable("armClangThumbCflags", strings.Join(clangFilterUnknownCflags(armThumbCflags), " "))
+	pctx.StaticVariable("ArmClangArmCflags", strings.Join(ClangFilterUnknownCflags(armArmCflags), " "))
+	pctx.StaticVariable("ArmClangThumbCflags", strings.Join(ClangFilterUnknownCflags(armThumbCflags), " "))
 
 	// Clang arch variant cflags
-	pctx.StaticVariable("armClangArmv5TECflags",
+	pctx.StaticVariable("ArmClangArmv5TECflags",
 		strings.Join(armClangArchVariantCflags["armv5te"], " "))
-	pctx.StaticVariable("armClangArmv7ACflags",
+	pctx.StaticVariable("ArmClangArmv7ACflags",
 		strings.Join(armClangArchVariantCflags["armv7-a"], " "))
-	pctx.StaticVariable("armClangArmv7ANeonCflags",
+	pctx.StaticVariable("ArmClangArmv7ANeonCflags",
 		strings.Join(armClangArchVariantCflags["armv7-a-neon"], " "))
 
 	// Clang cpu variant cflags
-	pctx.StaticVariable("armClangGenericCflags",
+	pctx.StaticVariable("ArmClangGenericCflags",
 		strings.Join(armClangCpuVariantCflags[""], " "))
-	pctx.StaticVariable("armClangCortexA7Cflags",
+	pctx.StaticVariable("ArmClangCortexA7Cflags",
 		strings.Join(armClangCpuVariantCflags["cortex-a7"], " "))
-	pctx.StaticVariable("armClangCortexA8Cflags",
+	pctx.StaticVariable("ArmClangCortexA8Cflags",
 		strings.Join(armClangCpuVariantCflags["cortex-a8"], " "))
-	pctx.StaticVariable("armClangCortexA15Cflags",
+	pctx.StaticVariable("ArmClangCortexA15Cflags",
 		strings.Join(armClangCpuVariantCflags["cortex-a15"], " "))
-	pctx.StaticVariable("armClangKraitCflags",
+	pctx.StaticVariable("ArmClangKraitCflags",
 		strings.Join(armClangCpuVariantCflags["krait"], " "))
 }
 
 var (
 	armArchVariantCflagsVar = map[string]string{
-		"armv5te":      "${armArmv5TECflags}",
-		"armv7-a":      "${armArmv7ACflags}",
-		"armv7-a-neon": "${armArmv7ANeonCflags}",
+		"armv5te":      "${config.ArmArmv5TECflags}",
+		"armv7-a":      "${config.ArmArmv7ACflags}",
+		"armv7-a-neon": "${config.ArmArmv7ANeonCflags}",
 	}
 
 	armCpuVariantCflagsVar = map[string]string{
-		"":               "${armGenericCflags}",
-		"cortex-a7":      "${armCortexA7Cflags}",
-		"cortex-a8":      "${armCortexA8Cflags}",
-		"cortex-a15":     "${armCortexA15Cflags}",
-		"cortex-a53":     "${armCortexA7Cflags}",
-		"cortex-a53.a57": "${armCortexA7Cflags}",
-		"krait":          "${armKraitCflags}",
-		"denver":         "${armCortexA15Cflags}",
+		"":               "${config.ArmGenericCflags}",
+		"cortex-a7":      "${config.ArmCortexA7Cflags}",
+		"cortex-a8":      "${config.ArmCortexA8Cflags}",
+		"cortex-a15":     "${config.ArmCortexA15Cflags}",
+		"cortex-a53":     "${config.ArmCortexA7Cflags}",
+		"cortex-a53.a57": "${config.ArmCortexA7Cflags}",
+		"krait":          "${config.ArmKraitCflags}",
+		"denver":         "${config.ArmCortexA15Cflags}",
 	}
 
 	armClangArchVariantCflagsVar = map[string]string{
-		"armv5te":      "${armClangArmv5TECflags}",
-		"armv7-a":      "${armClangArmv7ACflags}",
-		"armv7-a-neon": "${armClangArmv7ANeonCflags}",
+		"armv5te":      "${config.ArmClangArmv5TECflags}",
+		"armv7-a":      "${config.ArmClangArmv7ACflags}",
+		"armv7-a-neon": "${config.ArmClangArmv7ANeonCflags}",
 	}
 
 	armClangCpuVariantCflagsVar = map[string]string{
-		"":               "${armClangGenericCflags}",
-		"cortex-a7":      "${armClangCortexA7Cflags}",
-		"cortex-a8":      "${armClangCortexA8Cflags}",
-		"cortex-a15":     "${armClangCortexA15Cflags}",
-		"cortex-a53":     "${armClangCortexA7Cflags}",
-		"cortex-a53.a57": "${armClangCortexA7Cflags}",
-		"krait":          "${armClangKraitCflags}",
-		"denver":         "${armClangCortexA15Cflags}",
+		"":               "${config.ArmClangGenericCflags}",
+		"cortex-a7":      "${config.ArmClangCortexA7Cflags}",
+		"cortex-a8":      "${config.ArmClangCortexA8Cflags}",
+		"cortex-a15":     "${config.ArmClangCortexA15Cflags}",
+		"cortex-a53":     "${config.ArmClangCortexA7Cflags}",
+		"cortex-a53.a57": "${config.ArmClangCortexA7Cflags}",
+		"krait":          "${config.ArmClangKraitCflags}",
+		"denver":         "${config.ArmClangCortexA15Cflags}",
 	}
 )
 
@@ -263,7 +263,7 @@
 }
 
 func (t *toolchainArm) GccRoot() string {
-	return "${armGccRoot}"
+	return "${config.ArmGccRoot}"
 }
 
 func (t *toolchainArm) GccTriple() string {
@@ -279,11 +279,11 @@
 }
 
 func (t *toolchainArm) Cflags() string {
-	return "${armCflags}"
+	return "${config.ArmCflags}"
 }
 
 func (t *toolchainArm) Cppflags() string {
-	return "${armCppflags}"
+	return "${config.ArmCppflags}"
 }
 
 func (t *toolchainArm) Ldflags() string {
@@ -291,15 +291,15 @@
 }
 
 func (t *toolchainArm) IncludeFlags() string {
-	return "${armIncludeFlags}"
+	return "${config.ArmIncludeFlags}"
 }
 
 func (t *toolchainArm) InstructionSetFlags(isa string) (string, error) {
 	switch isa {
 	case "arm":
-		return "${armArmCflags}", nil
+		return "${config.ArmArmCflags}", nil
 	case "thumb", "":
-		return "${armThumbCflags}", nil
+		return "${config.ArmThumbCflags}", nil
 	default:
 		return t.toolchainBase.InstructionSetFlags(isa)
 	}
@@ -314,11 +314,11 @@
 }
 
 func (t *toolchainArm) ClangCflags() string {
-	return "${armClangCflags}"
+	return "${config.ArmClangCflags}"
 }
 
 func (t *toolchainArm) ClangCppflags() string {
-	return "${armClangCppflags}"
+	return "${config.ArmClangCppflags}"
 }
 
 func (t *toolchainArm) ClangLdflags() string {
@@ -328,9 +328,9 @@
 func (t *toolchainArm) ClangInstructionSetFlags(isa string) (string, error) {
 	switch isa {
 	case "arm":
-		return "${armClangArmCflags}", nil
+		return "${config.ArmClangArmCflags}", nil
 	case "thumb", "":
-		return "${armClangThumbCflags}", nil
+		return "${config.ArmClangThumbCflags}", nil
 	default:
 		return t.toolchainBase.ClangInstructionSetFlags(isa)
 	}
@@ -345,9 +345,9 @@
 	toolchainCflags := make([]string, 2, 3)
 	toolchainClangCflags := make([]string, 2, 3)
 
-	toolchainCflags[0] = "${armToolchainCflags}"
+	toolchainCflags[0] = "${config.ArmToolchainCflags}"
 	toolchainCflags[1] = armArchVariantCflagsVar[arch.ArchVariant]
-	toolchainClangCflags[0] = "${armToolchainClangCflags}"
+	toolchainClangCflags[0] = "${config.ArmToolchainClangCflags}"
 	toolchainClangCflags[1] = armClangArchVariantCflagsVar[arch.ArchVariant]
 
 	switch arch.ArchVariant {
@@ -375,7 +375,7 @@
 	return &toolchainArm{
 		toolchainCflags: strings.Join(toolchainCflags, " "),
 		ldflags: strings.Join([]string{
-			"${armLdflags}",
+			"${config.ArmLdflags}",
 			fixCortexA8,
 		}, " "),
 		toolchainClangCflags: strings.Join(toolchainClangCflags, " "),
diff --git a/cc/clang.go b/cc/config/clang.go
similarity index 86%
rename from cc/clang.go
rename to cc/config/clang.go
index be2bfe1..13a7e66 100644
--- a/cc/clang.go
+++ b/cc/config/clang.go
@@ -1,4 +1,4 @@
-package cc
+package config
 
 import (
 	"sort"
@@ -6,7 +6,7 @@
 )
 
 // Cflags that should be filtered out when compiling with clang
-var clangUnknownCflags = sorted([]string{
+var ClangUnknownCflags = sorted([]string{
 	"-finline-functions",
 	"-finline-limit=64",
 	"-fno-canonical-system-headers",
@@ -66,7 +66,7 @@
 })
 
 func init() {
-	pctx.StaticVariable("clangExtraCflags", strings.Join([]string{
+	pctx.StaticVariable("ClangExtraCflags", strings.Join([]string{
 		"-D__compiler_offsetof=__builtin_offsetof",
 
 		// Help catch common 32/64-bit errors.
@@ -93,11 +93,11 @@
 		"-Wno-expansion-to-defined",
 	}, " "))
 
-	pctx.StaticVariable("clangExtraConlyflags", strings.Join([]string{
+	pctx.StaticVariable("ClangExtraConlyflags", strings.Join([]string{
 		"-std=gnu99",
 	}, " "))
 
-	pctx.StaticVariable("clangExtraCppflags", strings.Join([]string{
+	pctx.StaticVariable("ClangExtraCppflags", strings.Join([]string{
 		// Disable -Winconsistent-missing-override until we can clean up the existing
 		// codebase for it.
 		"-Wno-inconsistent-missing-override",
@@ -107,11 +107,11 @@
 		"-Wno-null-dereference",
 	}, " "))
 
-	pctx.StaticVariable("clangExtraTargetCflags", strings.Join([]string{
+	pctx.StaticVariable("ClangExtraTargetCflags", strings.Join([]string{
 		"-nostdlibinc",
 	}, " "))
 
-	pctx.StaticVariable("clangExtraNoOverrideCflags", strings.Join([]string{
+	pctx.StaticVariable("ClangExtraNoOverrideCflags", strings.Join([]string{
 		"-Werror=address-of-temporary",
 		// Bug: http://b/29823425 Disable -Wnull-dereference until the
 		// new cases detected by this warning in Clang r271374 are
@@ -121,10 +121,10 @@
 	}, " "))
 }
 
-func clangFilterUnknownCflags(cflags []string) []string {
+func ClangFilterUnknownCflags(cflags []string) []string {
 	ret := make([]string, 0, len(cflags))
 	for _, f := range cflags {
-		if !inListSorted(f, clangUnknownCflags) {
+		if !inListSorted(f, ClangUnknownCflags) {
 			ret = append(ret, f)
 		}
 	}
diff --git a/cc/global.go b/cc/config/global.go
similarity index 64%
rename from cc/global.go
rename to cc/config/global.go
index ec0f572..cdb68ff 100644
--- a/cc/global.go
+++ b/cc/config/global.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package cc
+package config
 
 import (
 	"strings"
@@ -59,38 +59,40 @@
 		"-Werror=pointer-to-int-cast",
 	}
 
-	illegalFlags = []string{
+	IllegalFlags = []string{
 		"-w",
 	}
 )
 
+var pctx = android.NewPackageContext("android/soong/cc/config")
+
 func init() {
 	if android.BuildOs == android.Linux {
 		commonGlobalCflags = append(commonGlobalCflags, "-fdebug-prefix-map=/proc/self/cwd=")
 	}
 
-	pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " "))
-	pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
-	pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " "))
-	pctx.StaticVariable("noOverrideGlobalCflags", strings.Join(noOverrideGlobalCflags, " "))
+	pctx.StaticVariable("CommonGlobalCflags", strings.Join(commonGlobalCflags, " "))
+	pctx.StaticVariable("DeviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
+	pctx.StaticVariable("HostGlobalCflags", strings.Join(hostGlobalCflags, " "))
+	pctx.StaticVariable("NoOverrideGlobalCflags", strings.Join(noOverrideGlobalCflags, " "))
 
-	pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
+	pctx.StaticVariable("CommonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
 
-	pctx.StaticVariable("commonClangGlobalCflags",
-		strings.Join(append(clangFilterUnknownCflags(commonGlobalCflags), "${clangExtraCflags}"), " "))
-	pctx.StaticVariable("deviceClangGlobalCflags",
-		strings.Join(append(clangFilterUnknownCflags(deviceGlobalCflags), "${clangExtraTargetCflags}"), " "))
-	pctx.StaticVariable("hostClangGlobalCflags",
-		strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " "))
-	pctx.StaticVariable("noOverrideClangGlobalCflags",
-		strings.Join(append(clangFilterUnknownCflags(noOverrideGlobalCflags), "${clangExtraNoOverrideCflags}"), " "))
+	pctx.StaticVariable("CommonClangGlobalCflags",
+		strings.Join(append(ClangFilterUnknownCflags(commonGlobalCflags), "${ClangExtraCflags}"), " "))
+	pctx.StaticVariable("DeviceClangGlobalCflags",
+		strings.Join(append(ClangFilterUnknownCflags(deviceGlobalCflags), "${ClangExtraTargetCflags}"), " "))
+	pctx.StaticVariable("HostClangGlobalCflags",
+		strings.Join(ClangFilterUnknownCflags(hostGlobalCflags), " "))
+	pctx.StaticVariable("NoOverrideClangGlobalCflags",
+		strings.Join(append(ClangFilterUnknownCflags(noOverrideGlobalCflags), "${ClangExtraNoOverrideCflags}"), " "))
 
-	pctx.StaticVariable("commonClangGlobalCppflags",
-		strings.Join(append(clangFilterUnknownCflags(commonGlobalCppflags), "${clangExtraCppflags}"), " "))
+	pctx.StaticVariable("CommonClangGlobalCppflags",
+		strings.Join(append(ClangFilterUnknownCflags(commonGlobalCppflags), "${ClangExtraCppflags}"), " "))
 
 	// Everything in this list is a crime against abstraction and dependency tracking.
 	// Do not add anything to this list.
-	pctx.PrefixedPathsForOptionalSourceVariable("commonGlobalIncludes", "-isystem ",
+	pctx.PrefixedPathsForOptionalSourceVariable("CommonGlobalIncludes", "-isystem ",
 		[]string{
 			"system/core/include",
 			"system/media/audio/include",
@@ -105,24 +107,26 @@
 		})
 	// This is used by non-NDK modules to get jni.h. export_include_dirs doesn't help
 	// with this, since there is no associated library.
-	pctx.PrefixedPathsForOptionalSourceVariable("commonNativehelperInclude", "-I",
+	pctx.PrefixedPathsForOptionalSourceVariable("CommonNativehelperInclude", "-I",
 		[]string{"libnativehelper/include/nativehelper"})
 
-	pctx.SourcePathVariable("clangDefaultBase", "prebuilts/clang/host")
-	pctx.VariableFunc("clangBase", func(config interface{}) (string, error) {
+	pctx.SourcePathVariable("ClangDefaultBase", "prebuilts/clang/host")
+	pctx.VariableFunc("ClangBase", func(config interface{}) (string, error) {
 		if override := config.(android.Config).Getenv("LLVM_PREBUILTS_BASE"); override != "" {
 			return override, nil
 		}
-		return "${clangDefaultBase}", nil
+		return "${ClangDefaultBase}", nil
 	})
-	pctx.VariableFunc("clangVersion", func(config interface{}) (string, error) {
+	pctx.VariableFunc("ClangVersion", func(config interface{}) (string, error) {
 		if override := config.(android.Config).Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
 			return override, nil
 		}
 		return "clang-3016494", nil
 	})
-	pctx.StaticVariable("clangPath", "${clangBase}/${HostPrebuiltTag}/${clangVersion}")
-	pctx.StaticVariable("clangBin", "${clangPath}/bin")
+	pctx.StaticVariable("ClangPath", "${ClangBase}/${HostPrebuiltTag}/${ClangVersion}")
+	pctx.StaticVariable("ClangBin", "${ClangPath}/bin")
+
+	pctx.StaticVariable("ClangAsanLibDir", "${ClangPath}/lib64/clang/3.8/lib/linux")
 }
 
 var HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
diff --git a/cc/mips64_device.go b/cc/config/mips64_device.go
similarity index 76%
rename from cc/mips64_device.go
rename to cc/config/mips64_device.go
index 51b605c..f6132dc 100644
--- a/cc/mips64_device.go
+++ b/cc/config/mips64_device.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package cc
+package config
 
 import (
 	"strings"
@@ -92,26 +92,26 @@
 
 	pctx.StaticVariable("mips64GccVersion", mips64GccVersion)
 
-	pctx.SourcePathVariable("mips64GccRoot",
+	pctx.SourcePathVariable("Mips64GccRoot",
 		"prebuilts/gcc/${HostPrebuiltTag}/mips/mips64el-linux-android-${mips64GccVersion}")
 
-	pctx.StaticVariable("mips64Cflags", strings.Join(mips64Cflags, " "))
-	pctx.StaticVariable("mips64Ldflags", strings.Join(mips64Ldflags, " "))
-	pctx.StaticVariable("mips64Cppflags", strings.Join(mips64Cppflags, " "))
-	pctx.StaticVariable("mips64IncludeFlags", bionicHeaders("mips64", "mips"))
+	pctx.StaticVariable("Mips64Cflags", strings.Join(mips64Cflags, " "))
+	pctx.StaticVariable("Mips64Ldflags", strings.Join(mips64Ldflags, " "))
+	pctx.StaticVariable("Mips64Cppflags", strings.Join(mips64Cppflags, " "))
+	pctx.StaticVariable("Mips64IncludeFlags", bionicHeaders("mips64", "mips"))
 
 	// Clang cflags
-	pctx.StaticVariable("mips64ClangCflags", strings.Join(clangFilterUnknownCflags(mips64Cflags), " "))
-	pctx.StaticVariable("mips64ClangLdflags", strings.Join(clangFilterUnknownCflags(mips64Ldflags), " "))
-	pctx.StaticVariable("mips64ClangCppflags", strings.Join(clangFilterUnknownCflags(mips64Cppflags), " "))
+	pctx.StaticVariable("Mips64ClangCflags", strings.Join(ClangFilterUnknownCflags(mips64Cflags), " "))
+	pctx.StaticVariable("Mips64ClangLdflags", strings.Join(ClangFilterUnknownCflags(mips64Ldflags), " "))
+	pctx.StaticVariable("Mips64ClangCppflags", strings.Join(ClangFilterUnknownCflags(mips64Cppflags), " "))
 
 	// Extended cflags
 
 	// Architecture variant cflags
 	for variant, cflags := range mips64ArchVariantCflags {
-		pctx.StaticVariable("mips64"+variant+"VariantCflags", strings.Join(cflags, " "))
-		pctx.StaticVariable("mips64"+variant+"VariantClangCflags",
-			strings.Join(clangFilterUnknownCflags(cflags), " "))
+		pctx.StaticVariable("Mips64"+variant+"VariantCflags", strings.Join(cflags, " "))
+		pctx.StaticVariable("Mips64"+variant+"VariantClangCflags",
+			strings.Join(ClangFilterUnknownCflags(cflags), " "))
 	}
 }
 
@@ -126,7 +126,7 @@
 }
 
 func (t *toolchainMips64) GccRoot() string {
-	return "${mips64GccRoot}"
+	return "${config.Mips64GccRoot}"
 }
 
 func (t *toolchainMips64) GccTriple() string {
@@ -146,15 +146,15 @@
 }
 
 func (t *toolchainMips64) Cppflags() string {
-	return "${mips64Cppflags}"
+	return "${config.Mips64Cppflags}"
 }
 
 func (t *toolchainMips64) Ldflags() string {
-	return "${mips64Ldflags}"
+	return "${config.Mips64Ldflags}"
 }
 
 func (t *toolchainMips64) IncludeFlags() string {
-	return "${mips64IncludeFlags}"
+	return "${config.Mips64IncludeFlags}"
 }
 
 func (t *toolchainMips64) ClangTriple() string {
@@ -170,11 +170,11 @@
 }
 
 func (t *toolchainMips64) ClangCppflags() string {
-	return "${mips64ClangCppflags}"
+	return "${config.Mips64ClangCppflags}"
 }
 
 func (t *toolchainMips64) ClangLdflags() string {
-	return "${mips64ClangLdflags}"
+	return "${config.Mips64ClangLdflags}"
 }
 
 func (toolchainMips64) AddressSanitizerRuntimeLibrary() string {
@@ -183,10 +183,10 @@
 
 func mips64ToolchainFactory(arch android.Arch) Toolchain {
 	return &toolchainMips64{
-		cflags:               "${mips64Cflags}",
-		clangCflags:          "${mips64ClangCflags}",
-		toolchainCflags:      "${mips64" + arch.ArchVariant + "VariantCflags}",
-		toolchainClangCflags: "${mips64" + arch.ArchVariant + "VariantClangCflags}",
+		cflags:               "${config.Mips64Cflags}",
+		clangCflags:          "${config.Mips64ClangCflags}",
+		toolchainCflags:      "${config.Mips64" + arch.ArchVariant + "VariantCflags}",
+		toolchainClangCflags: "${config.Mips64" + arch.ArchVariant + "VariantClangCflags}",
 	}
 }
 
diff --git a/cc/mips_device.go b/cc/config/mips_device.go
similarity index 77%
rename from cc/mips_device.go
rename to cc/config/mips_device.go
index 583a153..3c77a48 100644
--- a/cc/mips_device.go
+++ b/cc/config/mips_device.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package cc
+package config
 
 import (
 	"strings"
@@ -128,27 +128,27 @@
 
 	pctx.StaticVariable("mipsGccVersion", mipsGccVersion)
 
-	pctx.SourcePathVariable("mipsGccRoot",
+	pctx.SourcePathVariable("MipsGccRoot",
 		"prebuilts/gcc/${HostPrebuiltTag}/mips/mips64el-linux-android-${mipsGccVersion}")
 
-	pctx.StaticVariable("mipsToolchainLdflags", strings.Join(mipsToolchainLdflags, " "))
-	pctx.StaticVariable("mipsCflags", strings.Join(mipsCflags, " "))
-	pctx.StaticVariable("mipsLdflags", strings.Join(mipsLdflags, " "))
-	pctx.StaticVariable("mipsCppflags", strings.Join(mipsCppflags, " "))
-	pctx.StaticVariable("mipsIncludeFlags", bionicHeaders("mips", "mips"))
+	pctx.StaticVariable("MipsToolchainLdflags", strings.Join(mipsToolchainLdflags, " "))
+	pctx.StaticVariable("MipsCflags", strings.Join(mipsCflags, " "))
+	pctx.StaticVariable("MipsLdflags", strings.Join(mipsLdflags, " "))
+	pctx.StaticVariable("MipsCppflags", strings.Join(mipsCppflags, " "))
+	pctx.StaticVariable("MipsIncludeFlags", bionicHeaders("mips", "mips"))
 
 	// Clang cflags
-	pctx.StaticVariable("mipsClangCflags", strings.Join(clangFilterUnknownCflags(mipsClangCflags), " "))
-	pctx.StaticVariable("mipsClangLdflags", strings.Join(clangFilterUnknownCflags(mipsLdflags), " "))
-	pctx.StaticVariable("mipsClangCppflags", strings.Join(clangFilterUnknownCflags(mipsCppflags), " "))
+	pctx.StaticVariable("MipsClangCflags", strings.Join(ClangFilterUnknownCflags(mipsClangCflags), " "))
+	pctx.StaticVariable("MipsClangLdflags", strings.Join(ClangFilterUnknownCflags(mipsLdflags), " "))
+	pctx.StaticVariable("MipsClangCppflags", strings.Join(ClangFilterUnknownCflags(mipsCppflags), " "))
 
 	// Extended cflags
 
 	// Architecture variant cflags
 	for variant, cflags := range mipsArchVariantCflags {
-		pctx.StaticVariable("mips"+variant+"VariantCflags", strings.Join(cflags, " "))
-		pctx.StaticVariable("mips"+variant+"VariantClangCflags",
-			strings.Join(clangFilterUnknownCflags(cflags), " "))
+		pctx.StaticVariable("Mips"+variant+"VariantCflags", strings.Join(cflags, " "))
+		pctx.StaticVariable("Mips"+variant+"VariantClangCflags",
+			strings.Join(ClangFilterUnknownCflags(cflags), " "))
 	}
 }
 
@@ -163,7 +163,7 @@
 }
 
 func (t *toolchainMips) GccRoot() string {
-	return "${mipsGccRoot}"
+	return "${config.MipsGccRoot}"
 }
 
 func (t *toolchainMips) GccTriple() string {
@@ -175,7 +175,7 @@
 }
 
 func (t *toolchainMips) ToolchainLdflags() string {
-	return "${mipsToolchainLdflags}"
+	return "${config.MipsToolchainLdflags}"
 }
 
 func (t *toolchainMips) ToolchainCflags() string {
@@ -187,15 +187,15 @@
 }
 
 func (t *toolchainMips) Cppflags() string {
-	return "${mipsCppflags}"
+	return "${config.MipsCppflags}"
 }
 
 func (t *toolchainMips) Ldflags() string {
-	return "${mipsLdflags}"
+	return "${config.MipsLdflags}"
 }
 
 func (t *toolchainMips) IncludeFlags() string {
-	return "${mipsIncludeFlags}"
+	return "${config.MipsIncludeFlags}"
 }
 
 func (t *toolchainMips) ClangTriple() string {
@@ -203,7 +203,7 @@
 }
 
 func (t *toolchainMips) ToolchainClangLdflags() string {
-	return "${mipsToolchainLdflags}"
+	return "${config.MipsToolchainLdflags}"
 }
 
 func (t *toolchainMips) ToolchainClangCflags() string {
@@ -219,11 +219,11 @@
 }
 
 func (t *toolchainMips) ClangCppflags() string {
-	return "${mipsClangCppflags}"
+	return "${config.MipsClangCppflags}"
 }
 
 func (t *toolchainMips) ClangLdflags() string {
-	return "${mipsClangLdflags}"
+	return "${config.MipsClangLdflags}"
 }
 
 func (toolchainMips) AddressSanitizerRuntimeLibrary() string {
@@ -232,10 +232,10 @@
 
 func mipsToolchainFactory(arch android.Arch) Toolchain {
 	return &toolchainMips{
-		cflags:               "${mipsCflags}",
-		clangCflags:          "${mipsClangCflags}",
-		toolchainCflags:      "${mips" + arch.ArchVariant + "VariantCflags}",
-		toolchainClangCflags: "${mips" + arch.ArchVariant + "VariantClangCflags}",
+		cflags:               "${config.MipsCflags}",
+		clangCflags:          "${config.MipsClangCflags}",
+		toolchainCflags:      "${config.Mips" + arch.ArchVariant + "VariantCflags}",
+		toolchainClangCflags: "${config.Mips" + arch.ArchVariant + "VariantClangCflags}",
 	}
 }
 
diff --git a/cc/toolchain.go b/cc/config/toolchain.go
similarity index 75%
rename from cc/toolchain.go
rename to cc/config/toolchain.go
index 2e2ee5a..c286a9a 100644
--- a/cc/toolchain.go
+++ b/cc/config/toolchain.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package cc
+package config
 
 import (
 	"fmt"
@@ -31,6 +31,15 @@
 	toolchainFactories[os][arch] = factory
 }
 
+func FindToolchain(os android.OsType, arch android.Arch) Toolchain {
+	factory := toolchainFactories[os][arch.ArchType]
+	if factory == nil {
+		panic(fmt.Errorf("Toolchain not found for %s arch %q", os.String(), arch.String()))
+		return nil
+	}
+	return factory(arch)
+}
+
 type Toolchain interface {
 	Name() string
 
@@ -139,3 +148,43 @@
 func (toolchain32Bit) Is64Bit() bool {
 	return false
 }
+
+func copyVariantFlags(m map[string][]string) map[string][]string {
+	ret := make(map[string][]string, len(m))
+	for k, v := range m {
+		l := make([]string, len(m[k]))
+		for i := range m[k] {
+			l[i] = v[i]
+		}
+		ret[k] = l
+	}
+	return ret
+}
+
+func variantOrDefault(variants map[string]string, choice string) string {
+	if ret, ok := variants[choice]; ok {
+		return ret
+	}
+	return variants[""]
+}
+
+func addPrefix(list []string, prefix string) []string {
+	for i := range list {
+		list[i] = prefix + list[i]
+	}
+	return list
+}
+
+func indexList(s string, list []string) int {
+	for i, l := range list {
+		if l == s {
+			return i
+		}
+	}
+
+	return -1
+}
+
+func inList(s string, list []string) bool {
+	return indexList(s, list) != -1
+}
diff --git a/cc/x86_64_device.go b/cc/config/x86_64_device.go
similarity index 78%
rename from cc/x86_64_device.go
rename to cc/config/x86_64_device.go
index 2747cf0..ec02bed 100644
--- a/cc/x86_64_device.go
+++ b/cc/config/x86_64_device.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package cc
+package config
 
 import (
 	"strings"
@@ -137,29 +137,29 @@
 
 	pctx.StaticVariable("x86_64GccVersion", x86_64GccVersion)
 
-	pctx.SourcePathVariable("x86_64GccRoot",
+	pctx.SourcePathVariable("X86_64GccRoot",
 		"prebuilts/gcc/${HostPrebuiltTag}/x86/x86_64-linux-android-${x86_64GccVersion}")
 
-	pctx.StaticVariable("x86_64ToolchainCflags", "-m64")
-	pctx.StaticVariable("x86_64ToolchainLdflags", "-m64")
+	pctx.StaticVariable("X86_64ToolchainCflags", "-m64")
+	pctx.StaticVariable("X86_64ToolchainLdflags", "-m64")
 
-	pctx.StaticVariable("x86_64Cflags", strings.Join(x86_64Cflags, " "))
-	pctx.StaticVariable("x86_64Ldflags", strings.Join(x86_64Ldflags, " "))
-	pctx.StaticVariable("x86_64Cppflags", strings.Join(x86_64Cppflags, " "))
-	pctx.StaticVariable("x86_64IncludeFlags", bionicHeaders("x86_64", "x86"))
+	pctx.StaticVariable("X86_64Cflags", strings.Join(x86_64Cflags, " "))
+	pctx.StaticVariable("X86_64Ldflags", strings.Join(x86_64Ldflags, " "))
+	pctx.StaticVariable("X86_64Cppflags", strings.Join(x86_64Cppflags, " "))
+	pctx.StaticVariable("X86_64IncludeFlags", bionicHeaders("x86_64", "x86"))
 
 	// Clang cflags
-	pctx.StaticVariable("x86_64ClangCflags", strings.Join(clangFilterUnknownCflags(x86_64Cflags), " "))
-	pctx.StaticVariable("x86_64ClangLdflags", strings.Join(clangFilterUnknownCflags(x86_64Ldflags), " "))
-	pctx.StaticVariable("x86_64ClangCppflags", strings.Join(clangFilterUnknownCflags(x86_64Cppflags), " "))
+	pctx.StaticVariable("X86_64ClangCflags", strings.Join(ClangFilterUnknownCflags(x86_64Cflags), " "))
+	pctx.StaticVariable("X86_64ClangLdflags", strings.Join(ClangFilterUnknownCflags(x86_64Ldflags), " "))
+	pctx.StaticVariable("X86_64ClangCppflags", strings.Join(ClangFilterUnknownCflags(x86_64Cppflags), " "))
 
 	// Extended cflags
 
 	// Architecture variant cflags
 	for variant, cflags := range x86_64ArchVariantCflags {
-		pctx.StaticVariable("x86_64"+variant+"VariantCflags", strings.Join(cflags, " "))
-		pctx.StaticVariable("x86_64"+variant+"VariantClangCflags",
-			strings.Join(clangFilterUnknownCflags(cflags), " "))
+		pctx.StaticVariable("X86_64"+variant+"VariantCflags", strings.Join(cflags, " "))
+		pctx.StaticVariable("X86_64"+variant+"VariantClangCflags",
+			strings.Join(ClangFilterUnknownCflags(cflags), " "))
 	}
 }
 
@@ -173,7 +173,7 @@
 }
 
 func (t *toolchainX86_64) GccRoot() string {
-	return "${x86_64GccRoot}"
+	return "${config.X86_64GccRoot}"
 }
 
 func (t *toolchainX86_64) GccTriple() string {
@@ -185,7 +185,7 @@
 }
 
 func (t *toolchainX86_64) ToolchainLdflags() string {
-	return "${x86_64ToolchainLdflags}"
+	return "${config.X86_64ToolchainLdflags}"
 }
 
 func (t *toolchainX86_64) ToolchainCflags() string {
@@ -193,19 +193,19 @@
 }
 
 func (t *toolchainX86_64) Cflags() string {
-	return "${x86_64Cflags}"
+	return "${config.X86_64Cflags}"
 }
 
 func (t *toolchainX86_64) Cppflags() string {
-	return "${x86_64Cppflags}"
+	return "${config.X86_64Cppflags}"
 }
 
 func (t *toolchainX86_64) Ldflags() string {
-	return "${x86_64Ldflags}"
+	return "${config.X86_64Ldflags}"
 }
 
 func (t *toolchainX86_64) IncludeFlags() string {
-	return "${x86_64IncludeFlags}"
+	return "${config.X86_64IncludeFlags}"
 }
 
 func (t *toolchainX86_64) ClangTriple() string {
@@ -213,7 +213,7 @@
 }
 
 func (t *toolchainX86_64) ToolchainClangLdflags() string {
-	return "${x86_64ToolchainLdflags}"
+	return "${config.X86_64ToolchainLdflags}"
 }
 
 func (t *toolchainX86_64) ToolchainClangCflags() string {
@@ -221,26 +221,26 @@
 }
 
 func (t *toolchainX86_64) ClangCflags() string {
-	return "${x86_64ClangCflags}"
+	return "${config.X86_64ClangCflags}"
 }
 
 func (t *toolchainX86_64) ClangCppflags() string {
-	return "${x86_64ClangCppflags}"
+	return "${config.X86_64ClangCppflags}"
 }
 
 func (t *toolchainX86_64) ClangLdflags() string {
-	return "${x86_64Ldflags}"
+	return "${config.X86_64Ldflags}"
 }
 
 func x86_64ToolchainFactory(arch android.Arch) Toolchain {
 	toolchainCflags := []string{
-		"${x86_64ToolchainCflags}",
-		"${x86_64" + arch.ArchVariant + "VariantCflags}",
+		"${config.X86_64ToolchainCflags}",
+		"${config.X86_64" + arch.ArchVariant + "VariantCflags}",
 	}
 
 	toolchainClangCflags := []string{
-		"${x86_64ToolchainCflags}",
-		"${x86_64" + arch.ArchVariant + "VariantClangCflags}",
+		"${config.X86_64ToolchainCflags}",
+		"${config.X86_64" + arch.ArchVariant + "VariantClangCflags}",
 	}
 
 	for _, feature := range arch.ArchFeatures {
diff --git a/cc/x86_darwin_host.go b/cc/config/x86_darwin_host.go
similarity index 65%
rename from cc/x86_darwin_host.go
rename to cc/config/x86_darwin_host.go
index d514c14..e89fc9c 100644
--- a/cc/x86_darwin_host.go
+++ b/cc/config/x86_darwin_host.go
@@ -1,4 +1,18 @@
-package cc
+// Copyright 2016 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package config
 
 import (
 	"fmt"
@@ -55,20 +69,20 @@
 		"-m64",
 	}
 
-	darwinClangCflags = append(clangFilterUnknownCflags(darwinCflags), []string{
+	darwinClangCflags = append(ClangFilterUnknownCflags(darwinCflags), []string{
 		"-integrated-as",
 		"-fstack-protector-strong",
 	}...)
 
-	darwinX86ClangCflags = append(clangFilterUnknownCflags(darwinX86Cflags), []string{
+	darwinX86ClangCflags = append(ClangFilterUnknownCflags(darwinX86Cflags), []string{
 		"-msse3",
 	}...)
 
-	darwinClangLdflags = clangFilterUnknownCflags(darwinLdflags)
+	darwinClangLdflags = ClangFilterUnknownCflags(darwinLdflags)
 
-	darwinX86ClangLdflags = clangFilterUnknownCflags(darwinX86Ldflags)
+	darwinX86ClangLdflags = ClangFilterUnknownCflags(darwinX86Ldflags)
 
-	darwinX8664ClangLdflags = clangFilterUnknownCflags(darwinX8664Ldflags)
+	darwinX8664ClangLdflags = ClangFilterUnknownCflags(darwinX8664Ldflags)
 
 	darwinSupportedSdkVersions = []string{
 		"10.8",
@@ -96,44 +110,43 @@
 		bytes, err := exec.Command("xcode-select", "--print-path").Output()
 		return strings.TrimSpace(string(bytes)), err
 	})
-	pctx.StaticVariable("macToolchainRoot", "${macSdkPath}/Toolchains/XcodeDefault.xctoolchain")
 	pctx.VariableFunc("macSdkRoot", func(config interface{}) (string, error) {
 		return xcrunSdk(config.(android.Config), "--show-sdk-path")
 	})
 	pctx.StaticVariable("macSdkVersion", darwinSupportedSdkVersions[0])
-	pctx.VariableFunc("macArPath", func(config interface{}) (string, error) {
+	pctx.VariableFunc("MacArPath", func(config interface{}) (string, error) {
 		bytes, err := exec.Command("xcrun", "--find", "ar").Output()
 		return strings.TrimSpace(string(bytes)), err
 	})
 
-	pctx.VariableFunc("macStripPath", func(config interface{}) (string, error) {
+	pctx.VariableFunc("MacStripPath", func(config interface{}) (string, error) {
 		bytes, err := exec.Command("xcrun", "--find", "strip").Output()
 		return strings.TrimSpace(string(bytes)), err
 	})
 
-	pctx.StaticVariable("darwinGccVersion", darwinGccVersion)
-	pctx.SourcePathVariable("darwinGccRoot",
-		"prebuilts/gcc/${HostPrebuiltTag}/host/i686-apple-darwin-${darwinGccVersion}")
+	pctx.StaticVariable("DarwinGccVersion", darwinGccVersion)
+	pctx.SourcePathVariable("DarwinGccRoot",
+		"prebuilts/gcc/${HostPrebuiltTag}/host/i686-apple-darwin-${DarwinGccVersion}")
 
-	pctx.StaticVariable("darwinGccTriple", "i686-apple-darwin11")
+	pctx.StaticVariable("DarwinGccTriple", "i686-apple-darwin11")
 
-	pctx.StaticVariable("darwinCflags", strings.Join(darwinCflags, " "))
-	pctx.StaticVariable("darwinLdflags", strings.Join(darwinLdflags, " "))
+	pctx.StaticVariable("DarwinCflags", strings.Join(darwinCflags, " "))
+	pctx.StaticVariable("DarwinLdflags", strings.Join(darwinLdflags, " "))
 
-	pctx.StaticVariable("darwinClangCflags", strings.Join(darwinClangCflags, " "))
-	pctx.StaticVariable("darwinClangLdflags", strings.Join(darwinClangLdflags, " "))
+	pctx.StaticVariable("DarwinClangCflags", strings.Join(darwinClangCflags, " "))
+	pctx.StaticVariable("DarwinClangLdflags", strings.Join(darwinClangLdflags, " "))
 
 	// Extended cflags
-	pctx.StaticVariable("darwinX86Cflags", strings.Join(darwinX86Cflags, " "))
-	pctx.StaticVariable("darwinX8664Cflags", strings.Join(darwinX8664Cflags, " "))
-	pctx.StaticVariable("darwinX86Ldflags", strings.Join(darwinX86Ldflags, " "))
-	pctx.StaticVariable("darwinX8664Ldflags", strings.Join(darwinX8664Ldflags, " "))
+	pctx.StaticVariable("DarwinX86Cflags", strings.Join(darwinX86Cflags, " "))
+	pctx.StaticVariable("DarwinX8664Cflags", strings.Join(darwinX8664Cflags, " "))
+	pctx.StaticVariable("DarwinX86Ldflags", strings.Join(darwinX86Ldflags, " "))
+	pctx.StaticVariable("DarwinX8664Ldflags", strings.Join(darwinX8664Ldflags, " "))
 
-	pctx.StaticVariable("darwinX86ClangCflags", strings.Join(darwinX86ClangCflags, " "))
-	pctx.StaticVariable("darwinX8664ClangCflags",
-		strings.Join(clangFilterUnknownCflags(darwinX8664Cflags), " "))
-	pctx.StaticVariable("darwinX86ClangLdflags", strings.Join(darwinX86ClangLdflags, " "))
-	pctx.StaticVariable("darwinX8664ClangLdflags", strings.Join(darwinX8664ClangLdflags, " "))
+	pctx.StaticVariable("DarwinX86ClangCflags", strings.Join(darwinX86ClangCflags, " "))
+	pctx.StaticVariable("DarwinX8664ClangCflags",
+		strings.Join(ClangFilterUnknownCflags(darwinX8664Cflags), " "))
+	pctx.StaticVariable("DarwinX86ClangLdflags", strings.Join(darwinX86ClangLdflags, " "))
+	pctx.StaticVariable("DarwinX8664ClangLdflags", strings.Join(darwinX8664ClangLdflags, " "))
 }
 
 func xcrunSdk(config android.Config, arg string) (string, error) {
@@ -181,11 +194,11 @@
 }
 
 func (t *toolchainDarwin) GccRoot() string {
-	return "${darwinGccRoot}"
+	return "${config.DarwinGccRoot}"
 }
 
 func (t *toolchainDarwin) GccTriple() string {
-	return "${darwinGccTriple}"
+	return "${config.DarwinGccTriple}"
 }
 
 func (t *toolchainDarwin) GccVersion() string {
@@ -193,11 +206,11 @@
 }
 
 func (t *toolchainDarwin) Cflags() string {
-	return "${darwinCflags} ${darwinX86Cflags}"
+	return "${config.DarwinCflags} ${config.DarwinX86Cflags}"
 }
 
 func (t *toolchainDarwinX8664) Cflags() string {
-	return "${darwinCflags} ${darwinX8664Cflags}"
+	return "${config.DarwinCflags} ${config.DarwinX8664Cflags}"
 }
 
 func (t *toolchainDarwin) Cppflags() string {
@@ -205,11 +218,11 @@
 }
 
 func (t *toolchainDarwinX86) Ldflags() string {
-	return "${darwinLdflags} ${darwinX86Ldflags}"
+	return "${config.DarwinLdflags} ${config.DarwinX86Ldflags}"
 }
 
 func (t *toolchainDarwinX8664) Ldflags() string {
-	return "${darwinLdflags} ${darwinX8664Ldflags}"
+	return "${config.DarwinLdflags} ${config.DarwinX8664Ldflags}"
 }
 
 func (t *toolchainDarwin) IncludeFlags() string {
@@ -221,7 +234,7 @@
 }
 
 func (t *toolchainDarwinX86) ClangCflags() string {
-	return "${darwinClangCflags} ${darwinX86ClangCflags}"
+	return "${config.DarwinClangCflags} ${config.DarwinX86ClangCflags}"
 }
 
 func (t *toolchainDarwinX8664) ClangTriple() string {
@@ -229,7 +242,7 @@
 }
 
 func (t *toolchainDarwinX8664) ClangCflags() string {
-	return "${darwinClangCflags} ${darwinX8664ClangCflags}"
+	return "${config.DarwinClangCflags} ${config.DarwinX8664ClangCflags}"
 }
 
 func (t *toolchainDarwin) ClangCppflags() string {
@@ -237,11 +250,11 @@
 }
 
 func (t *toolchainDarwinX86) ClangLdflags() string {
-	return "${darwinClangLdflags} ${darwinX86ClangLdflags}"
+	return "${config.DarwinClangLdflags} ${config.DarwinX86ClangLdflags}"
 }
 
 func (t *toolchainDarwinX8664) ClangLdflags() string {
-	return "${darwinClangLdflags} ${darwinX8664ClangLdflags}"
+	return "${config.DarwinClangLdflags} ${config.DarwinX8664ClangLdflags}"
 }
 
 func (t *toolchainDarwin) ShlibSuffix() string {
diff --git a/cc/x86_device.go b/cc/config/x86_device.go
similarity index 80%
rename from cc/x86_device.go
rename to cc/config/x86_device.go
index 550aca0..032b1f0 100644
--- a/cc/x86_device.go
+++ b/cc/config/x86_device.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package cc
+package config
 
 import (
 	"strings"
@@ -156,29 +156,29 @@
 
 	pctx.StaticVariable("x86GccVersion", x86GccVersion)
 
-	pctx.SourcePathVariable("x86GccRoot",
+	pctx.SourcePathVariable("X86GccRoot",
 		"prebuilts/gcc/${HostPrebuiltTag}/x86/x86_64-linux-android-${x86GccVersion}")
 
-	pctx.StaticVariable("x86ToolchainCflags", "-m32")
-	pctx.StaticVariable("x86ToolchainLdflags", "-m32")
+	pctx.StaticVariable("X86ToolchainCflags", "-m32")
+	pctx.StaticVariable("X86ToolchainLdflags", "-m32")
 
-	pctx.StaticVariable("x86Cflags", strings.Join(x86Cflags, " "))
-	pctx.StaticVariable("x86Ldflags", strings.Join(x86Ldflags, " "))
-	pctx.StaticVariable("x86Cppflags", strings.Join(x86Cppflags, " "))
-	pctx.StaticVariable("x86IncludeFlags", bionicHeaders("x86", "x86"))
+	pctx.StaticVariable("X86Cflags", strings.Join(x86Cflags, " "))
+	pctx.StaticVariable("X86Ldflags", strings.Join(x86Ldflags, " "))
+	pctx.StaticVariable("X86Cppflags", strings.Join(x86Cppflags, " "))
+	pctx.StaticVariable("X86IncludeFlags", bionicHeaders("x86", "x86"))
 
 	// Clang cflags
-	pctx.StaticVariable("x86ClangCflags", strings.Join(clangFilterUnknownCflags(x86ClangCflags), " "))
-	pctx.StaticVariable("x86ClangLdflags", strings.Join(clangFilterUnknownCflags(x86Ldflags), " "))
-	pctx.StaticVariable("x86ClangCppflags", strings.Join(clangFilterUnknownCflags(x86Cppflags), " "))
+	pctx.StaticVariable("X86ClangCflags", strings.Join(ClangFilterUnknownCflags(x86ClangCflags), " "))
+	pctx.StaticVariable("X86ClangLdflags", strings.Join(ClangFilterUnknownCflags(x86Ldflags), " "))
+	pctx.StaticVariable("X86ClangCppflags", strings.Join(ClangFilterUnknownCflags(x86Cppflags), " "))
 
 	// Extended cflags
 
 	// Architecture variant cflags
 	for variant, cflags := range x86ArchVariantCflags {
-		pctx.StaticVariable("x86"+variant+"VariantCflags", strings.Join(cflags, " "))
-		pctx.StaticVariable("x86"+variant+"VariantClangCflags",
-			strings.Join(clangFilterUnknownCflags(cflags), " "))
+		pctx.StaticVariable("X86"+variant+"VariantCflags", strings.Join(cflags, " "))
+		pctx.StaticVariable("X86"+variant+"VariantClangCflags",
+			strings.Join(ClangFilterUnknownCflags(cflags), " "))
 	}
 }
 
@@ -192,7 +192,7 @@
 }
 
 func (t *toolchainX86) GccRoot() string {
-	return "${x86GccRoot}"
+	return "${config.X86GccRoot}"
 }
 
 func (t *toolchainX86) GccTriple() string {
@@ -204,7 +204,7 @@
 }
 
 func (t *toolchainX86) ToolchainLdflags() string {
-	return "${x86ToolchainLdflags}"
+	return "${config.X86ToolchainLdflags}"
 }
 
 func (t *toolchainX86) ToolchainCflags() string {
@@ -212,19 +212,19 @@
 }
 
 func (t *toolchainX86) Cflags() string {
-	return "${x86Cflags}"
+	return "${config.X86Cflags}"
 }
 
 func (t *toolchainX86) Cppflags() string {
-	return "${x86Cppflags}"
+	return "${config.X86Cppflags}"
 }
 
 func (t *toolchainX86) Ldflags() string {
-	return "${x86Ldflags}"
+	return "${config.X86Ldflags}"
 }
 
 func (t *toolchainX86) IncludeFlags() string {
-	return "${x86IncludeFlags}"
+	return "${config.X86IncludeFlags}"
 }
 
 func (t *toolchainX86) ClangTriple() string {
@@ -232,7 +232,7 @@
 }
 
 func (t *toolchainX86) ToolchainClangLdflags() string {
-	return "${x86ToolchainLdflags}"
+	return "${config.X86ToolchainLdflags}"
 }
 
 func (t *toolchainX86) ToolchainClangCflags() string {
@@ -240,15 +240,15 @@
 }
 
 func (t *toolchainX86) ClangCflags() string {
-	return "${x86ClangCflags}"
+	return "${config.X86ClangCflags}"
 }
 
 func (t *toolchainX86) ClangCppflags() string {
-	return "${x86ClangCppflags}"
+	return "${config.X86ClangCppflags}"
 }
 
 func (t *toolchainX86) ClangLdflags() string {
-	return "${x86Ldflags}"
+	return "${config.X86Ldflags}"
 }
 
 func (toolchainX86) AddressSanitizerRuntimeLibrary() string {
@@ -257,13 +257,13 @@
 
 func x86ToolchainFactory(arch android.Arch) Toolchain {
 	toolchainCflags := []string{
-		"${x86ToolchainCflags}",
-		"${x86" + arch.ArchVariant + "VariantCflags}",
+		"${config.X86ToolchainCflags}",
+		"${config.X86" + arch.ArchVariant + "VariantCflags}",
 	}
 
 	toolchainClangCflags := []string{
-		"${x86ToolchainCflags}",
-		"${x86" + arch.ArchVariant + "VariantClangCflags}",
+		"${config.X86ToolchainCflags}",
+		"${config.X86" + arch.ArchVariant + "VariantClangCflags}",
 	}
 
 	for _, feature := range arch.ArchFeatures {
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
new file mode 100644
index 0000000..676ea5c
--- /dev/null
+++ b/cc/config/x86_linux_host.go
@@ -0,0 +1,273 @@
+// Copyright 2016 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package config
+
+import (
+	"strings"
+
+	"android/soong/android"
+)
+
+var (
+	linuxCflags = []string{
+		"-fno-exceptions", // from build/core/combo/select.mk
+		"-Wno-multichar",  // from build/core/combo/select.mk
+
+		"-fdiagnostics-color",
+
+		"-Wa,--noexecstack",
+
+		"-fPIC",
+		"-no-canonical-prefixes",
+
+		"-U_FORTIFY_SOURCE",
+		"-D_FORTIFY_SOURCE=2",
+		"-fstack-protector",
+
+		// Workaround differences in inttypes.h between host and target.
+		//See bug 12708004.
+		"-D__STDC_FORMAT_MACROS",
+		"-D__STDC_CONSTANT_MACROS",
+
+		// HOST_RELEASE_CFLAGS
+		"-O2", // from build/core/combo/select.mk
+		"-g",  // from build/core/combo/select.mk
+		"-fno-strict-aliasing", // from build/core/combo/select.mk
+	}
+
+	linuxLdflags = []string{
+		"-Wl,-z,noexecstack",
+		"-Wl,-z,relro",
+		"-Wl,-z,now",
+		"-Wl,--no-undefined-version",
+	}
+
+	// Extended cflags
+	linuxX86Cflags = []string{
+		"-msse3",
+		"-mfpmath=sse",
+		"-m32",
+		"-march=prescott",
+		"-D_FILE_OFFSET_BITS=64",
+		"-D_LARGEFILE_SOURCE=1",
+	}
+
+	linuxX8664Cflags = []string{
+		"-m64",
+	}
+
+	linuxX86Ldflags = []string{
+		"-m32",
+	}
+
+	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",
+	}...)
+
+	linuxX86ClangLdflags = append(ClangFilterUnknownCflags(linuxX86Ldflags), []string{
+		"-B${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32",
+		"-L${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32",
+		"-L${LinuxGccRoot}/${LinuxGccTriple}/lib32",
+	}...)
+
+	linuxX8664ClangLdflags = append(ClangFilterUnknownCflags(linuxX8664Ldflags), []string{
+		"-B${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}",
+		"-L${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}",
+		"-L${LinuxGccRoot}/${LinuxGccTriple}/lib64",
+	}...)
+
+	linuxClangCppflags = []string{
+		"-isystem ${LinuxGccRoot}/${LinuxGccTriple}/include/c++/${LinuxGccVersion}",
+		"-isystem ${LinuxGccRoot}/${LinuxGccTriple}/include/c++/${LinuxGccVersion}/backward",
+	}
+
+	linuxX86ClangCppflags = []string{
+		"-isystem ${LinuxGccRoot}/${LinuxGccTriple}/include/c++/${LinuxGccVersion}/${LinuxGccTriple}/32",
+	}
+
+	linuxX8664ClangCppflags = []string{
+		"-isystem ${LinuxGccRoot}/${LinuxGccTriple}/include/c++/${LinuxGccVersion}/${LinuxGccTriple}",
+	}
+
+	linuxAvailableLibraries = addPrefix([]string{
+		"c",
+		"dl",
+		"gcc",
+		"gcc_s",
+		"m",
+		"ncurses",
+		"pthread",
+		"resolv",
+		"rt",
+		"util",
+		"z",
+	}, "-l")
+)
+
+const (
+	linuxGccVersion = "4.8"
+)
+
+func init() {
+	pctx.StaticVariable("LinuxGccVersion", linuxGccVersion)
+
+	pctx.SourcePathVariable("LinuxGccRoot",
+		"prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-linux-glibc2.15-${LinuxGccVersion}")
+
+	pctx.StaticVariable("LinuxGccTriple", "x86_64-linux")
+
+	pctx.StaticVariable("LinuxCflags", strings.Join(linuxCflags, " "))
+	pctx.StaticVariable("LinuxLdflags", strings.Join(linuxLdflags, " "))
+
+	pctx.StaticVariable("LinuxClangCflags", strings.Join(linuxClangCflags, " "))
+	pctx.StaticVariable("LinuxClangLdflags", strings.Join(linuxClangLdflags, " "))
+	pctx.StaticVariable("LinuxClangCppflags", strings.Join(linuxClangCppflags, " "))
+
+	// Extended cflags
+	pctx.StaticVariable("LinuxX86Cflags", strings.Join(linuxX86Cflags, " "))
+	pctx.StaticVariable("LinuxX8664Cflags", strings.Join(linuxX8664Cflags, " "))
+	pctx.StaticVariable("LinuxX86Ldflags", strings.Join(linuxX86Ldflags, " "))
+	pctx.StaticVariable("LinuxX8664Ldflags", strings.Join(linuxX8664Ldflags, " "))
+
+	pctx.StaticVariable("LinuxX86ClangCflags",
+		strings.Join(ClangFilterUnknownCflags(linuxX86Cflags), " "))
+	pctx.StaticVariable("LinuxX8664ClangCflags",
+		strings.Join(ClangFilterUnknownCflags(linuxX8664Cflags), " "))
+	pctx.StaticVariable("LinuxX86ClangLdflags", strings.Join(linuxX86ClangLdflags, " "))
+	pctx.StaticVariable("LinuxX8664ClangLdflags", strings.Join(linuxX8664ClangLdflags, " "))
+	pctx.StaticVariable("LinuxX86ClangCppflags", strings.Join(linuxX86ClangCppflags, " "))
+	pctx.StaticVariable("LinuxX8664ClangCppflags", strings.Join(linuxX8664ClangCppflags, " "))
+}
+
+type toolchainLinux struct {
+	cFlags, ldFlags string
+}
+
+type toolchainLinuxX86 struct {
+	toolchain32Bit
+	toolchainLinux
+}
+
+type toolchainLinuxX8664 struct {
+	toolchain64Bit
+	toolchainLinux
+}
+
+func (t *toolchainLinuxX86) Name() string {
+	return "x86"
+}
+
+func (t *toolchainLinuxX8664) Name() string {
+	return "x86_64"
+}
+
+func (t *toolchainLinux) GccRoot() string {
+	return "${config.LinuxGccRoot}"
+}
+
+func (t *toolchainLinux) GccTriple() string {
+	return "${config.LinuxGccTriple}"
+}
+
+func (t *toolchainLinux) GccVersion() string {
+	return linuxGccVersion
+}
+
+func (t *toolchainLinuxX86) Cflags() string {
+	return "${config.LinuxCflags} ${config.LinuxX86Cflags}"
+}
+
+func (t *toolchainLinuxX8664) Cflags() string {
+	return "${config.LinuxCflags} ${config.LinuxX8664Cflags}"
+}
+
+func (t *toolchainLinux) Cppflags() string {
+	return ""
+}
+
+func (t *toolchainLinuxX86) Ldflags() string {
+	return "${config.LinuxLdflags} ${config.LinuxX86Ldflags}"
+}
+
+func (t *toolchainLinuxX8664) Ldflags() string {
+	return "${config.LinuxLdflags} ${config.LinuxX8664Ldflags}"
+}
+
+func (t *toolchainLinux) IncludeFlags() string {
+	return ""
+}
+
+func (t *toolchainLinuxX86) ClangTriple() string {
+	return "i686-linux-gnu"
+}
+
+func (t *toolchainLinuxX86) ClangCflags() string {
+	return "${config.LinuxClangCflags} ${config.LinuxX86ClangCflags}"
+}
+
+func (t *toolchainLinuxX86) ClangCppflags() string {
+	return "${config.LinuxClangCppflags} ${config.LinuxX86ClangCppflags}"
+}
+
+func (t *toolchainLinuxX8664) ClangTriple() string {
+	return "x86_64-linux-gnu"
+}
+
+func (t *toolchainLinuxX8664) ClangCflags() string {
+	return "${config.LinuxClangCflags} ${config.LinuxX8664ClangCflags}"
+}
+
+func (t *toolchainLinuxX8664) ClangCppflags() string {
+	return "${config.LinuxClangCppflags} ${config.LinuxX8664ClangCppflags}"
+}
+
+func (t *toolchainLinuxX86) ClangLdflags() string {
+	return "${config.LinuxClangLdflags} ${config.LinuxX86ClangLdflags}"
+}
+
+func (t *toolchainLinuxX8664) ClangLdflags() string {
+	return "${config.LinuxClangLdflags} ${config.LinuxX8664ClangLdflags}"
+}
+
+func (t *toolchainLinux) AvailableLibraries() []string {
+	return linuxAvailableLibraries
+}
+
+var toolchainLinuxX86Singleton Toolchain = &toolchainLinuxX86{}
+var toolchainLinuxX8664Singleton Toolchain = &toolchainLinuxX8664{}
+
+func linuxX86ToolchainFactory(arch android.Arch) Toolchain {
+	return toolchainLinuxX86Singleton
+}
+
+func linuxX8664ToolchainFactory(arch android.Arch) Toolchain {
+	return toolchainLinuxX8664Singleton
+}
+
+func init() {
+	registerToolchainFactory(android.Linux, android.X86, linuxX86ToolchainFactory)
+	registerToolchainFactory(android.Linux, android.X86_64, linuxX8664ToolchainFactory)
+}
diff --git a/cc/x86_windows_host.go b/cc/config/x86_windows_host.go
similarity index 75%
rename from cc/x86_windows_host.go
rename to cc/config/x86_windows_host.go
index 3a55dbf..125d02d 100644
--- a/cc/x86_windows_host.go
+++ b/cc/config/x86_windows_host.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package cc
+package config
 
 import (
 	"strings"
@@ -42,7 +42,7 @@
 		// Get 64-bit off_t and related functions.
 		"-D_FILE_OFFSET_BITS=64",
 
-		"--sysroot ${windowsGccRoot}/${windowsGccTriple}",
+		"--sysroot ${WindowsGccRoot}/${WindowsGccTriple}",
 
 		// HOST_RELEASE_CFLAGS
 		"-O2", // from build/core/combo/select.mk
@@ -51,8 +51,8 @@
 	}
 
 	windowsIncludeFlags = []string{
-		"-isystem ${windowsGccRoot}/${windowsGccTriple}/include",
-		"-isystem ${windowsGccRoot}/lib/gcc/${windowsGccTriple}/4.8.3/include",
+		"-isystem ${WindowsGccRoot}/${WindowsGccTriple}/include",
+		"-isystem ${WindowsGccRoot}/lib/gcc/${WindowsGccTriple}/4.8.3/include",
 	}
 
 	windowsLdflags = []string{
@@ -69,12 +69,12 @@
 
 	windowsX86Ldflags = []string{
 		"-m32",
-		"-L${windowsGccRoot}/${windowsGccTriple}/lib32",
+		"-L${WindowsGccRoot}/${WindowsGccTriple}/lib32",
 	}
 
 	windowsX8664Ldflags = []string{
 		"-m64",
-		"-L${windowsGccRoot}/${windowsGccTriple}/lib64",
+		"-L${WindowsGccRoot}/${WindowsGccTriple}/lib64",
 	}
 
 	windowsAvailableLibraries = addPrefix([]string{
@@ -93,22 +93,22 @@
 )
 
 func init() {
-	pctx.StaticVariable("windowsGccVersion", windowsGccVersion)
+	pctx.StaticVariable("WindowsGccVersion", windowsGccVersion)
 
-	pctx.SourcePathVariable("windowsGccRoot",
-		"prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-w64-mingw32-${windowsGccVersion}")
+	pctx.SourcePathVariable("WindowsGccRoot",
+		"prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-w64-mingw32-${WindowsGccVersion}")
 
-	pctx.StaticVariable("windowsGccTriple", "x86_64-w64-mingw32")
+	pctx.StaticVariable("WindowsGccTriple", "x86_64-w64-mingw32")
 
-	pctx.StaticVariable("windowsCflags", strings.Join(windowsCflags, " "))
-	pctx.StaticVariable("windowsLdflags", strings.Join(windowsLdflags, " "))
+	pctx.StaticVariable("WindowsCflags", strings.Join(windowsCflags, " "))
+	pctx.StaticVariable("WindowsLdflags", strings.Join(windowsLdflags, " "))
 
-	pctx.StaticVariable("windowsX86Cflags", strings.Join(windowsX86Cflags, " "))
-	pctx.StaticVariable("windowsX8664Cflags", strings.Join(windowsX8664Cflags, " "))
-	pctx.StaticVariable("windowsX86Ldflags", strings.Join(windowsX86Ldflags, " "))
-	pctx.StaticVariable("windowsX8664Ldflags", strings.Join(windowsX8664Ldflags, " "))
+	pctx.StaticVariable("WindowsX86Cflags", strings.Join(windowsX86Cflags, " "))
+	pctx.StaticVariable("WindowsX8664Cflags", strings.Join(windowsX8664Cflags, " "))
+	pctx.StaticVariable("WindowsX86Ldflags", strings.Join(windowsX86Ldflags, " "))
+	pctx.StaticVariable("WindowsX8664Ldflags", strings.Join(windowsX8664Ldflags, " "))
 
-	pctx.StaticVariable("windowsIncludeFlags", strings.Join(windowsIncludeFlags, " "))
+	pctx.StaticVariable("WindowsIncludeFlags", strings.Join(windowsIncludeFlags, " "))
 }
 
 type toolchainWindows struct {
@@ -134,11 +134,11 @@
 }
 
 func (t *toolchainWindows) GccRoot() string {
-	return "${windowsGccRoot}"
+	return "${config.WindowsGccRoot}"
 }
 
 func (t *toolchainWindows) GccTriple() string {
-	return "${windowsGccTriple}"
+	return "${config.WindowsGccTriple}"
 }
 
 func (t *toolchainWindows) GccVersion() string {
@@ -146,11 +146,11 @@
 }
 
 func (t *toolchainWindowsX86) Cflags() string {
-	return "${windowsCflags} ${windowsX86Cflags}"
+	return "${config.WindowsCflags} ${config.WindowsX86Cflags}"
 }
 
 func (t *toolchainWindowsX8664) Cflags() string {
-	return "${windowsCflags} ${windowsX8664Cflags}"
+	return "${config.WindowsCflags} ${config.WindowsX8664Cflags}"
 }
 
 func (t *toolchainWindows) Cppflags() string {
@@ -158,15 +158,15 @@
 }
 
 func (t *toolchainWindowsX86) Ldflags() string {
-	return "${windowsLdflags} ${windowsX86Ldflags}"
+	return "${config.WindowsLdflags} ${config.WindowsX86Ldflags}"
 }
 
 func (t *toolchainWindowsX8664) Ldflags() string {
-	return "${windowsLdflags} ${windowsX8664Ldflags}"
+	return "${config.WindowsLdflags} ${config.WindowsX8664Ldflags}"
 }
 
 func (t *toolchainWindows) IncludeFlags() string {
-	return "${windowsIncludeFlags}"
+	return "${config.WindowsIncludeFlags}"
 }
 
 func (t *toolchainWindows) ClangSupported() bool {
diff --git a/cc/makevars.go b/cc/makevars.go
index ae95a18..56698f2 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -20,6 +20,7 @@
 	"strings"
 
 	"android/soong/android"
+	"android/soong/cc/config"
 )
 
 func init() {
@@ -27,22 +28,22 @@
 }
 
 func makeVarsProvider(ctx android.MakeVarsContext) {
-	ctx.Strict("LLVM_PREBUILTS_VERSION", "${clangVersion}")
-	ctx.Strict("LLVM_PREBUILTS_BASE", "${clangBase}")
-	ctx.Strict("LLVM_PREBUILTS_PATH", "${clangBin}")
-	ctx.Strict("CLANG", "${clangBin}/clang")
-	ctx.Strict("CLANG_CXX", "${clangBin}/clang++")
-	ctx.Strict("LLVM_AS", "${clangBin}/llvm-as")
-	ctx.Strict("LLVM_LINK", "${clangBin}/llvm-link")
-	ctx.StrictSorted("CLANG_CONFIG_UNKNOWN_CFLAGS", strings.Join(clangUnknownCflags, " "))
+	ctx.Strict("LLVM_PREBUILTS_VERSION", "${config.ClangVersion}")
+	ctx.Strict("LLVM_PREBUILTS_BASE", "${config.ClangBase}")
+	ctx.Strict("LLVM_PREBUILTS_PATH", "${config.ClangBin}")
+	ctx.Strict("CLANG", "${config.ClangBin}/clang")
+	ctx.Strict("CLANG_CXX", "${config.ClangBin}/clang++")
+	ctx.Strict("LLVM_AS", "${config.ClangBin}/llvm-as")
+	ctx.Strict("LLVM_LINK", "${config.ClangBin}/llvm-link")
+	ctx.StrictSorted("CLANG_CONFIG_UNKNOWN_CFLAGS", strings.Join(config.ClangUnknownCflags, " "))
 
-	ctx.Strict("GLOBAL_CFLAGS_NO_OVERRIDE", "${noOverrideGlobalCflags}")
-	ctx.Strict("GLOBAL_CLANG_CFLAGS_NO_OVERRIDE", "${clangExtraNoOverrideCflags}")
+	ctx.Strict("GLOBAL_CFLAGS_NO_OVERRIDE", "${config.NoOverrideGlobalCflags}")
+	ctx.Strict("GLOBAL_CLANG_CFLAGS_NO_OVERRIDE", "${config.ClangExtraNoOverrideCflags}")
 	ctx.Strict("GLOBAL_CPPFLAGS_NO_OVERRIDE", "")
 	ctx.Strict("GLOBAL_CLANG_CPPFLAGS_NO_OVERRIDE", "")
 	ctx.Strict("NDK_PREBUILT_SHARED_LIBRARIES", strings.Join(ndkPrebuiltSharedLibs, " "))
 
-	includeFlags, err := ctx.Eval("${commonGlobalIncludes}")
+	includeFlags, err := ctx.Eval("${config.CommonGlobalIncludes}")
 	if err != nil {
 		panic(err)
 	}
@@ -86,14 +87,14 @@
 	}
 	makePrefix := secondPrefix + typePrefix
 
-	toolchain := toolchainFactories[target.Os][target.Arch.ArchType](target.Arch)
+	toolchain := config.FindToolchain(target.Os, target.Arch)
 
 	var productExtraCflags string
 	var productExtraLdflags string
 
-	hod := "host"
+	hod := "Host"
 	if target.Os.Class == android.Device {
-		hod = "device"
+		hod = "Device"
 	}
 
 	if target.Os.Class == android.Device && Bool(ctx.Config().ProductVariables.Brillo) {
@@ -105,14 +106,14 @@
 
 	ctx.Strict(makePrefix+"GLOBAL_CFLAGS", strings.Join([]string{
 		toolchain.Cflags(),
-		"${commonGlobalCflags}",
-		fmt.Sprintf("${%sGlobalCflags}", hod),
+		"${config.CommonGlobalCflags}",
+		fmt.Sprintf("${config.%sGlobalCflags}", hod),
 		toolchain.ToolchainCflags(),
 		productExtraCflags,
 	}, " "))
 	ctx.Strict(makePrefix+"GLOBAL_CONLYFLAGS", "")
 	ctx.Strict(makePrefix+"GLOBAL_CPPFLAGS", strings.Join([]string{
-		"${commonGlobalCppflags}",
+		"${config.CommonGlobalCppflags}",
 		toolchain.Cppflags(),
 	}, " "))
 	ctx.Strict(makePrefix+"GLOBAL_LDFLAGS", strings.Join([]string{
@@ -152,15 +153,15 @@
 
 		ctx.Strict(clangPrefix+"GLOBAL_CFLAGS", strings.Join([]string{
 			toolchain.ClangCflags(),
-			"${commonClangGlobalCflags}",
-			fmt.Sprintf("${%sClangGlobalCflags}", hod),
+			"${config.CommonClangGlobalCflags}",
+			fmt.Sprintf("${config.%sClangGlobalCflags}", hod),
 			toolchain.ToolchainClangCflags(),
 			clangExtras,
 			productExtraCflags,
 		}, " "))
-		ctx.Strict(clangPrefix+"GLOBAL_CONLYFLAGS", "${clangExtraConlyflags}")
+		ctx.Strict(clangPrefix+"GLOBAL_CONLYFLAGS", "${config.ClangExtraConlyflags}")
 		ctx.Strict(clangPrefix+"GLOBAL_CPPFLAGS", strings.Join([]string{
-			"${commonClangGlobalCppflags}",
+			"${config.CommonClangGlobalCppflags}",
 			toolchain.ClangCppflags(),
 		}, " "))
 		ctx.Strict(clangPrefix+"GLOBAL_LDFLAGS", strings.Join([]string{
@@ -183,7 +184,7 @@
 	ctx.Strict(makePrefix+"CXX", gccCmd(toolchain, "g++"))
 
 	if target.Os == android.Darwin {
-		ctx.Strict(makePrefix+"AR", "${macArPath}")
+		ctx.Strict(makePrefix+"AR", "${config.MacArPath}")
 	} else {
 		ctx.Strict(makePrefix+"AR", gccCmd(toolchain, "ar"))
 		ctx.Strict(makePrefix+"READELF", gccCmd(toolchain, "readelf"))
diff --git a/cc/ndk_prebuilt.go b/cc/ndk_prebuilt.go
index f66f5b5..40cd207 100644
--- a/cc/ndk_prebuilt.go
+++ b/cc/ndk_prebuilt.go
@@ -22,6 +22,7 @@
 
 	"android/soong"
 	"android/soong/android"
+	"android/soong/cc/config"
 )
 
 func init() {
@@ -37,7 +38,7 @@
 // either (with the exception of the shared STLs, which are installed to the app's directory rather
 // than to the system image).
 
-func getNdkLibDir(ctx android.ModuleContext, toolchain Toolchain, version string) android.SourcePath {
+func getNdkLibDir(ctx android.ModuleContext, toolchain config.Toolchain, version string) android.SourcePath {
 	suffix := ""
 	// Most 64-bit NDK prebuilts store libraries in "lib64", except for arm64 which is not a
 	// multilib toolchain and stores the libraries in "lib".
@@ -48,7 +49,7 @@
 		version, toolchain.Name(), suffix))
 }
 
-func ndkPrebuiltModuleToPath(ctx android.ModuleContext, toolchain Toolchain,
+func ndkPrebuiltModuleToPath(ctx android.ModuleContext, toolchain config.Toolchain,
 	ext string, version string) android.Path {
 
 	// NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
@@ -144,7 +145,7 @@
 	return module.Init()
 }
 
-func getNdkStlLibDir(ctx android.ModuleContext, toolchain Toolchain, stl string) android.SourcePath {
+func getNdkStlLibDir(ctx android.ModuleContext, toolchain config.Toolchain, stl string) android.SourcePath {
 	gccVersion := toolchain.GccVersion()
 	var libDir string
 	switch stl {
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 08ffff4..e7f021a 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -33,10 +33,6 @@
 	}
 }
 
-func init() {
-	pctx.StaticVariable("clangAsanLibDir", "${clangPath}/lib64/clang/3.8/lib/linux")
-}
-
 const (
 	asan sanitizerType = iota + 1
 	tsan
@@ -244,7 +240,7 @@
 		// ASan runtime library must be the first in the link order.
 		runtimeLibrary := ctx.toolchain().AddressSanitizerRuntimeLibrary()
 		if runtimeLibrary != "" {
-			flags.libFlags = append([]string{"${clangAsanLibDir}/" + runtimeLibrary}, flags.libFlags...)
+			flags.libFlags = append([]string{"${config.ClangAsanLibDir}/" + runtimeLibrary}, flags.libFlags...)
 		}
 		if ctx.Host() {
 			// -nodefaultlibs (provided with libc++) prevents the driver from linking
diff --git a/cc/util.go b/cc/util.go
index ee7720d..ca6aa5d 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -101,25 +101,6 @@
 	}
 }
 
-func copyVariantFlags(m map[string][]string) map[string][]string {
-	ret := make(map[string][]string, len(m))
-	for k, v := range m {
-		l := make([]string, len(m[k]))
-		for i := range m[k] {
-			l[i] = v[i]
-		}
-		ret[k] = l
-	}
-	return ret
-}
-
-func variantOrDefault(variants map[string]string, choice string) string {
-	if ret, ok := variants[choice]; ok {
-		return ret
-	}
-	return variants[""]
-}
-
 func addPrefix(list []string, prefix string) []string {
 	for i := range list {
 		list[i] = prefix + list[i]
diff --git a/cc/x86_linux_host.go b/cc/x86_linux_host.go
deleted file mode 100644
index b2d8462..0000000
--- a/cc/x86_linux_host.go
+++ /dev/null
@@ -1,259 +0,0 @@
-package cc
-
-import (
-	"strings"
-
-	"android/soong/android"
-)
-
-var (
-	linuxCflags = []string{
-		"-fno-exceptions", // from build/core/combo/select.mk
-		"-Wno-multichar",  // from build/core/combo/select.mk
-
-		"-fdiagnostics-color",
-
-		"-Wa,--noexecstack",
-
-		"-fPIC",
-		"-no-canonical-prefixes",
-
-		"-U_FORTIFY_SOURCE",
-		"-D_FORTIFY_SOURCE=2",
-		"-fstack-protector",
-
-		// Workaround differences in inttypes.h between host and target.
-		//See bug 12708004.
-		"-D__STDC_FORMAT_MACROS",
-		"-D__STDC_CONSTANT_MACROS",
-
-		// HOST_RELEASE_CFLAGS
-		"-O2", // from build/core/combo/select.mk
-		"-g",  // from build/core/combo/select.mk
-		"-fno-strict-aliasing", // from build/core/combo/select.mk
-	}
-
-	linuxLdflags = []string{
-		"-Wl,-z,noexecstack",
-		"-Wl,-z,relro",
-		"-Wl,-z,now",
-		"-Wl,--no-undefined-version",
-	}
-
-	// Extended cflags
-	linuxX86Cflags = []string{
-		"-msse3",
-		"-mfpmath=sse",
-		"-m32",
-		"-march=prescott",
-		"-D_FILE_OFFSET_BITS=64",
-		"-D_LARGEFILE_SOURCE=1",
-	}
-
-	linuxX8664Cflags = []string{
-		"-m64",
-	}
-
-	linuxX86Ldflags = []string{
-		"-m32",
-	}
-
-	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",
-	}...)
-
-	linuxX86ClangLdflags = append(clangFilterUnknownCflags(linuxX86Ldflags), []string{
-		"-B${linuxGccRoot}/lib/gcc/${linuxGccTriple}/${linuxGccVersion}/32",
-		"-L${linuxGccRoot}/lib/gcc/${linuxGccTriple}/${linuxGccVersion}/32",
-		"-L${linuxGccRoot}/${linuxGccTriple}/lib32",
-	}...)
-
-	linuxX8664ClangLdflags = append(clangFilterUnknownCflags(linuxX8664Ldflags), []string{
-		"-B${linuxGccRoot}/lib/gcc/${linuxGccTriple}/${linuxGccVersion}",
-		"-L${linuxGccRoot}/lib/gcc/${linuxGccTriple}/${linuxGccVersion}",
-		"-L${linuxGccRoot}/${linuxGccTriple}/lib64",
-	}...)
-
-	linuxClangCppflags = []string{
-		"-isystem ${linuxGccRoot}/${linuxGccTriple}/include/c++/${linuxGccVersion}",
-		"-isystem ${linuxGccRoot}/${linuxGccTriple}/include/c++/${linuxGccVersion}/backward",
-	}
-
-	linuxX86ClangCppflags = []string{
-		"-isystem ${linuxGccRoot}/${linuxGccTriple}/include/c++/${linuxGccVersion}/${linuxGccTriple}/32",
-	}
-
-	linuxX8664ClangCppflags = []string{
-		"-isystem ${linuxGccRoot}/${linuxGccTriple}/include/c++/${linuxGccVersion}/${linuxGccTriple}",
-	}
-
-	linuxAvailableLibraries = addPrefix([]string{
-		"c",
-		"dl",
-		"gcc",
-		"gcc_s",
-		"m",
-		"ncurses",
-		"pthread",
-		"resolv",
-		"rt",
-		"util",
-		"z",
-	}, "-l")
-)
-
-const (
-	linuxGccVersion = "4.8"
-)
-
-func init() {
-	pctx.StaticVariable("linuxGccVersion", linuxGccVersion)
-
-	pctx.SourcePathVariable("linuxGccRoot",
-		"prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-linux-glibc2.15-${linuxGccVersion}")
-
-	pctx.StaticVariable("linuxGccTriple", "x86_64-linux")
-
-	pctx.StaticVariable("linuxCflags", strings.Join(linuxCflags, " "))
-	pctx.StaticVariable("linuxLdflags", strings.Join(linuxLdflags, " "))
-
-	pctx.StaticVariable("linuxClangCflags", strings.Join(linuxClangCflags, " "))
-	pctx.StaticVariable("linuxClangLdflags", strings.Join(linuxClangLdflags, " "))
-	pctx.StaticVariable("linuxClangCppflags", strings.Join(linuxClangCppflags, " "))
-
-	// Extended cflags
-	pctx.StaticVariable("linuxX86Cflags", strings.Join(linuxX86Cflags, " "))
-	pctx.StaticVariable("linuxX8664Cflags", strings.Join(linuxX8664Cflags, " "))
-	pctx.StaticVariable("linuxX86Ldflags", strings.Join(linuxX86Ldflags, " "))
-	pctx.StaticVariable("linuxX8664Ldflags", strings.Join(linuxX8664Ldflags, " "))
-
-	pctx.StaticVariable("linuxX86ClangCflags",
-		strings.Join(clangFilterUnknownCflags(linuxX86Cflags), " "))
-	pctx.StaticVariable("linuxX8664ClangCflags",
-		strings.Join(clangFilterUnknownCflags(linuxX8664Cflags), " "))
-	pctx.StaticVariable("linuxX86ClangLdflags", strings.Join(linuxX86ClangLdflags, " "))
-	pctx.StaticVariable("linuxX8664ClangLdflags", strings.Join(linuxX8664ClangLdflags, " "))
-	pctx.StaticVariable("linuxX86ClangCppflags", strings.Join(linuxX86ClangCppflags, " "))
-	pctx.StaticVariable("linuxX8664ClangCppflags", strings.Join(linuxX8664ClangCppflags, " "))
-}
-
-type toolchainLinux struct {
-	cFlags, ldFlags string
-}
-
-type toolchainLinuxX86 struct {
-	toolchain32Bit
-	toolchainLinux
-}
-
-type toolchainLinuxX8664 struct {
-	toolchain64Bit
-	toolchainLinux
-}
-
-func (t *toolchainLinuxX86) Name() string {
-	return "x86"
-}
-
-func (t *toolchainLinuxX8664) Name() string {
-	return "x86_64"
-}
-
-func (t *toolchainLinux) GccRoot() string {
-	return "${linuxGccRoot}"
-}
-
-func (t *toolchainLinux) GccTriple() string {
-	return "${linuxGccTriple}"
-}
-
-func (t *toolchainLinux) GccVersion() string {
-	return linuxGccVersion
-}
-
-func (t *toolchainLinuxX86) Cflags() string {
-	return "${linuxCflags} ${linuxX86Cflags}"
-}
-
-func (t *toolchainLinuxX8664) Cflags() string {
-	return "${linuxCflags} ${linuxX8664Cflags}"
-}
-
-func (t *toolchainLinux) Cppflags() string {
-	return ""
-}
-
-func (t *toolchainLinuxX86) Ldflags() string {
-	return "${linuxLdflags} ${linuxX86Ldflags}"
-}
-
-func (t *toolchainLinuxX8664) Ldflags() string {
-	return "${linuxLdflags} ${linuxX8664Ldflags}"
-}
-
-func (t *toolchainLinux) IncludeFlags() string {
-	return ""
-}
-
-func (t *toolchainLinuxX86) ClangTriple() string {
-	return "i686-linux-gnu"
-}
-
-func (t *toolchainLinuxX86) ClangCflags() string {
-	return "${linuxClangCflags} ${linuxX86ClangCflags}"
-}
-
-func (t *toolchainLinuxX86) ClangCppflags() string {
-	return "${linuxClangCppflags} ${linuxX86ClangCppflags}"
-}
-
-func (t *toolchainLinuxX8664) ClangTriple() string {
-	return "x86_64-linux-gnu"
-}
-
-func (t *toolchainLinuxX8664) ClangCflags() string {
-	return "${linuxClangCflags} ${linuxX8664ClangCflags}"
-}
-
-func (t *toolchainLinuxX8664) ClangCppflags() string {
-	return "${linuxClangCppflags} ${linuxX8664ClangCppflags}"
-}
-
-func (t *toolchainLinuxX86) ClangLdflags() string {
-	return "${linuxClangLdflags} ${linuxX86ClangLdflags}"
-}
-
-func (t *toolchainLinuxX8664) ClangLdflags() string {
-	return "${linuxClangLdflags} ${linuxX8664ClangLdflags}"
-}
-
-func (t *toolchainLinux) AvailableLibraries() []string {
-	return linuxAvailableLibraries
-}
-
-var toolchainLinuxX86Singleton Toolchain = &toolchainLinuxX86{}
-var toolchainLinuxX8664Singleton Toolchain = &toolchainLinuxX8664{}
-
-func linuxX86ToolchainFactory(arch android.Arch) Toolchain {
-	return toolchainLinuxX86Singleton
-}
-
-func linuxX8664ToolchainFactory(arch android.Arch) Toolchain {
-	return toolchainLinuxX8664Singleton
-}
-
-func init() {
-	registerToolchainFactory(android.Linux, android.X86, linuxX86ToolchainFactory)
-	registerToolchainFactory(android.Linux, android.X86_64, linuxX8664ToolchainFactory)
-}