Support cross-compiling Windows binaries on Linux

This defines another mutator between HostOrDevice and Arch that will
expand host modules into a module for each host type
(Darwin/Linux/Windows) that is currently being built.

Change-Id: I4c8ac6b616c229f6bd45ad8a35902652fb6a4fff
diff --git a/cc/arm64_device.go b/cc/arm64_device.go
index 4acb218..9d58a80 100644
--- a/cc/arm64_device.go
+++ b/cc/arm64_device.go
@@ -155,5 +155,5 @@
 }
 
 func init() {
-	registerToolchainFactory(common.Device, common.Arm64, arm64ToolchainFactory)
+	registerDeviceToolchainFactory(common.Arm64, arm64ToolchainFactory)
 }
diff --git a/cc/arm_device.go b/cc/arm_device.go
index 746de2e..2d6d38c 100644
--- a/cc/arm_device.go
+++ b/cc/arm_device.go
@@ -362,5 +362,5 @@
 }
 
 func init() {
-	registerToolchainFactory(common.Device, common.Arm, armToolchainFactory)
+	registerDeviceToolchainFactory(common.Arm, armToolchainFactory)
 }
diff --git a/cc/builder.go b/cc/builder.go
index e3b9983..64437d2 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -33,7 +33,6 @@
 
 const (
 	objectExtension        = ".o"
-	sharedLibraryExtension = ".so"
 	staticLibraryExtension = ".a"
 )
 
@@ -310,7 +309,7 @@
 	var libFlagsList []string
 
 	if len(wholeStaticLibs) > 0 {
-		if ctx.Host() && runtime.GOOS == "darwin" {
+		if ctx.Host() && ctx.Darwin() {
 			libFlagsList = append(libFlagsList, common.JoinWithPrefix(wholeStaticLibs, "-force_load "))
 		} else {
 			libFlagsList = append(libFlagsList, "-Wl,--whole-archive ")
@@ -334,11 +333,11 @@
 		if !strings.HasPrefix(file, "lib") {
 			panic("shared library " + lib + " does not start with lib")
 		}
-		if !strings.HasSuffix(file, sharedLibraryExtension) {
-			panic("shared library " + lib + " does not end with " + sharedLibraryExtension)
+		if !strings.HasSuffix(file, flags.toolchain.ShlibSuffix()) {
+			panic("shared library " + lib + " does not end with " + flags.toolchain.ShlibSuffix())
 		}
 		libFlagsList = append(libFlagsList,
-			"-l"+strings.TrimSuffix(strings.TrimPrefix(file, "lib"), sharedLibraryExtension))
+			"-l"+strings.TrimSuffix(strings.TrimPrefix(file, "lib"), flags.toolchain.ShlibSuffix()))
 		ldDirs = append(ldDirs, dir)
 	}
 
diff --git a/cc/cc.go b/cc/cc.go
index b1bc069..00a0908 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -21,7 +21,6 @@
 import (
 	"fmt"
 	"path/filepath"
-	"runtime"
 	"strings"
 
 	"github.com/google/blueprint"
@@ -82,7 +81,6 @@
 		"-Wno-unused",
 		"-Winit-self",
 		"-Wpointer-arith",
-		"-fdiagnostics-color",
 		"-fdebug-prefix-map=/proc/self/cwd=",
 
 		// COMMON_RELEASE_CFLAGS
@@ -91,6 +89,8 @@
 	}
 
 	deviceGlobalCflags = []string{
+		"-fdiagnostics-color",
+
 		// TARGET_ERROR_FLAGS
 		"-Werror=return-type",
 		"-Werror=non-virtual-dtor",
@@ -407,9 +407,10 @@
 func (c *CCBase) findToolchain(ctx common.AndroidModuleContext) Toolchain {
 	arch := ctx.Arch()
 	hod := ctx.HostOrDevice()
-	factory := toolchainFactories[hod][arch.ArchType]
+	ht := ctx.HostType()
+	factory := toolchainFactories[hod][ht][arch.ArchType]
 	if factory == nil {
-		ctx.ModuleErrorf("Toolchain not found for %s arch %q", hod.String(), arch.String())
+		ctx.ModuleErrorf("Toolchain not found for %s %s arch %q", hod.String(), ht.String(), arch.String())
 		return nil
 	}
 	return factory(arch)
@@ -512,6 +513,10 @@
 		}
 	}
 
+	if !toolchain.ClangSupported() {
+		flags.Clang = false
+	}
+
 	instructionSet := c.Properties.Instruction_set
 	instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
 	if flags.Clang {
@@ -826,33 +831,52 @@
 		}
 	}
 
-	switch c.Properties.Stl {
-	case "libc++", "libc++_static",
-		"libstdc++":
-		return c.Properties.Stl
-	case "none":
-		return ""
-	case "":
-		if c.static() {
-			return "libc++_static"
-		} else {
-			return "libc++" // TODO: mingw needs libstdc++
+	if ctx.HostType() == common.Windows {
+		switch c.Properties.Stl {
+		case "libc++", "libc++_static", "libstdc++", "":
+			// libc++ is not supported on mingw
+			return "libstdc++"
+		case "none":
+			return ""
+		default:
+			ctx.ModuleErrorf("stl: %q is not a supported STL", c.Properties.Stl)
+			return ""
 		}
-	default:
-		ctx.ModuleErrorf("stl: %q is not a supported STL", c.Properties.Stl)
-		return ""
+	} else {
+		switch c.Properties.Stl {
+		case "libc++", "libc++_static",
+			"libstdc++":
+			return c.Properties.Stl
+		case "none":
+			return ""
+		case "":
+			if c.static() {
+				return "libc++_static"
+			} else {
+				return "libc++"
+			}
+		default:
+			ctx.ModuleErrorf("stl: %q is not a supported STL", c.Properties.Stl)
+			return ""
+		}
 	}
 }
 
-var hostDynamicGccLibs, hostStaticGccLibs []string
+var hostDynamicGccLibs, hostStaticGccLibs map[common.HostType][]string
 
 func init() {
-	if runtime.GOOS == "darwin" {
-		hostDynamicGccLibs = []string{"-lc", "-lSystem"}
-		hostStaticGccLibs = []string{"NO_STATIC_HOST_BINARIES_ON_DARWIN"}
-	} else {
-		hostDynamicGccLibs = []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"}
-		hostStaticGccLibs = []string{"-Wl,--start-group", "-lgcc", "-lgcc_eh", "-lc", "-Wl,--end-group"}
+	hostDynamicGccLibs = map[common.HostType][]string{
+		common.Linux:  []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"},
+		common.Darwin: []string{"-lc", "-lSystem"},
+		common.Windows: []string{"-lmsvcr110", "-lmingw32", "-lgcc", "-lmoldname",
+			"-lmingwex", "-lmsvcrt", "-ladvapi32", "-lshell32", "-luser32",
+			"-lkernel32", "-lmingw32", "-lgcc", "-lmoldname", "-lmingwex",
+			"-lmsvcrt"},
+	}
+	hostStaticGccLibs = map[common.HostType][]string{
+		common.Linux:   []string{"-Wl,--start-group", "-lgcc", "-lgcc_eh", "-lc", "-Wl,--end-group"},
+		common.Darwin:  []string{"NO_STATIC_HOST_BINARIES_ON_DARWIN"},
+		common.Windows: []string{"NO_STATIC_HOST_BINARIES_ON_WINDOWS"},
 	}
 }
 
@@ -870,9 +894,9 @@
 			flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
 			flags.LdFlags = append(flags.LdFlags, "-lm", "-lpthread")
 			if c.staticBinary() {
-				flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs...)
+				flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.HostType()]...)
 			} else {
-				flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs...)
+				flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.HostType()]...)
 			}
 		} else {
 			if ctx.Arch().ArchType == common.Arm {
@@ -900,9 +924,9 @@
 			flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
 			flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
 			if c.staticBinary() {
-				flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs...)
+				flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.HostType()]...)
 			} else {
-				flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs...)
+				flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.HostType()]...)
 			}
 		}
 	default:
@@ -1148,7 +1172,12 @@
 func (c *CCLibrary) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
 	flags = c.CCLinked.flags(ctx, flags)
 
-	flags.CFlags = append(flags.CFlags, "-fPIC")
+	// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
+	// all code is position independent, and then those warnings get promoted to
+	// errors.
+	if ctx.HostType() != common.Windows {
+		flags.CFlags = append(flags.CFlags, "-fPIC")
+	}
 
 	if c.static() {
 		flags.CFlags = append(flags.CFlags, c.LibraryProperties.Static.Cflags...)
@@ -1172,13 +1201,13 @@
 				"-dynamiclib",
 				"-single_module",
 				//"-read_only_relocs suppress",
-				"-install_name @rpath/"+libName+sharedLibraryExtension,
+				"-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
 			)
 		} else {
 			flags.LdFlags = append(flags.LdFlags,
 				"-Wl,--gc-sections",
 				sharedFlag,
-				"-Wl,-soname,"+libName+sharedLibraryExtension,
+				"-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix(),
 			)
 		}
 	}
@@ -1224,7 +1253,7 @@
 
 	objFiles = append(objFiles, objFilesShared...)
 
-	outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+sharedLibraryExtension)
+	outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+flags.Toolchain.ShlibSuffix())
 
 	var linkerDeps []string
 
@@ -1448,7 +1477,19 @@
 func (c *CCBinary) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
 	flags = c.CCLinked.flags(ctx, flags)
 
-	flags.CFlags = append(flags.CFlags, "-fpie")
+	if ctx.Host() {
+		flags.LdFlags = append(flags.LdFlags, "-pie")
+		if ctx.HostType() == common.Windows {
+			flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
+		}
+	}
+
+	// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
+	// all code is position independent, and then those warnings get promoted to
+	// errors.
+	if ctx.HostType() != common.Windows {
+		flags.CFlags = append(flags.CFlags, "-fpie")
+	}
 
 	if ctx.Device() {
 		if Bool(c.BinaryProperties.Static_executable) {
@@ -1495,7 +1536,7 @@
 			"from static libs or set static_executable: true")
 	}
 
-	outputFile := filepath.Join(common.ModuleOutDir(ctx), c.getStem(ctx))
+	outputFile := filepath.Join(common.ModuleOutDir(ctx), c.getStem(ctx)+flags.Toolchain.ExecutableSuffix())
 	c.out = outputFile
 	if c.BinaryProperties.Prefix_symbols != "" {
 		afterPrefixSymbols := outputFile
@@ -1843,7 +1884,7 @@
 	includeDirs := pathtools.PrefixPaths(c.Properties.Export_include_dirs, common.ModuleSrcDir(ctx))
 	c.exportFlags = []string{common.JoinWithPrefix(includeDirs, "-isystem ")}
 
-	c.out = ndkPrebuiltModuleToPath(ctx, flags.Toolchain, sharedLibraryExtension,
+	c.out = ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
 		c.Properties.Sdk_version)
 }
 
@@ -1911,7 +1952,7 @@
 	c.exportFlags = []string{includeDirsToFlags(includeDirs)}
 
 	libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
-	libExt := sharedLibraryExtension
+	libExt := flags.Toolchain.ShlibSuffix()
 	if c.LibraryProperties.BuildStatic {
 		libExt = staticLibraryExtension
 	}
diff --git a/cc/mips64_device.go b/cc/mips64_device.go
index d792d00..e0b6a89 100644
--- a/cc/mips64_device.go
+++ b/cc/mips64_device.go
@@ -195,5 +195,5 @@
 }
 
 func init() {
-	registerToolchainFactory(common.Device, common.Mips64, mips64ToolchainFactory)
+	registerDeviceToolchainFactory(common.Mips64, mips64ToolchainFactory)
 }
diff --git a/cc/mips_device.go b/cc/mips_device.go
index 52bc1ec..c3372fe 100644
--- a/cc/mips_device.go
+++ b/cc/mips_device.go
@@ -227,5 +227,5 @@
 }
 
 func init() {
-	registerToolchainFactory(common.Device, common.Mips, mipsToolchainFactory)
+	registerDeviceToolchainFactory(common.Mips, mipsToolchainFactory)
 }
diff --git a/cc/toolchain.go b/cc/toolchain.go
index 71a8979..5e4d02f 100644
--- a/cc/toolchain.go
+++ b/cc/toolchain.go
@@ -22,15 +22,23 @@
 
 type toolchainFactory func(arch common.Arch) Toolchain
 
-var toolchainFactories = map[common.HostOrDevice]map[common.ArchType]toolchainFactory{
-	common.Host:   make(map[common.ArchType]toolchainFactory),
-	common.Device: make(map[common.ArchType]toolchainFactory),
+var toolchainFactories = map[common.HostOrDevice]map[common.HostType]map[common.ArchType]toolchainFactory{
+	common.Host: map[common.HostType]map[common.ArchType]toolchainFactory{
+		common.Linux:   make(map[common.ArchType]toolchainFactory),
+		common.Darwin:  make(map[common.ArchType]toolchainFactory),
+		common.Windows: make(map[common.ArchType]toolchainFactory),
+	},
+	common.Device: map[common.HostType]map[common.ArchType]toolchainFactory{
+		common.NoHostType: make(map[common.ArchType]toolchainFactory),
+	},
 }
 
-func registerToolchainFactory(hod common.HostOrDevice, arch common.ArchType,
-	factory toolchainFactory) {
+func registerDeviceToolchainFactory(arch common.ArchType, factory toolchainFactory) {
+	toolchainFactories[common.Device][common.NoHostType][arch] = factory
+}
 
-	toolchainFactories[hod][arch] = factory
+func registerHostToolchainFactory(ht common.HostType, arch common.ArchType, factory toolchainFactory) {
+	toolchainFactories[common.Host][ht][arch] = factory
 }
 
 type Toolchain interface {
@@ -47,6 +55,7 @@
 	IncludeFlags() string
 	InstructionSetFlags(string) (string, error)
 
+	ClangSupported() bool
 	ClangTriple() string
 	ToolchainClangCflags() string
 	ClangCflags() string
@@ -55,6 +64,9 @@
 	ClangInstructionSetFlags(string) (string, error)
 
 	Is64Bit() bool
+
+	ShlibSuffix() string
+	ExecutableSuffix() string
 }
 
 type toolchainBase struct {
@@ -86,6 +98,18 @@
 	return ""
 }
 
+func (toolchainBase) ClangSupported() bool {
+	return true
+}
+
+func (toolchainBase) ShlibSuffix() string {
+	return ".so"
+}
+
+func (toolchainBase) ExecutableSuffix() string {
+	return ""
+}
+
 type toolchain64Bit struct {
 	toolchainBase
 }
diff --git a/cc/x86_64_device.go b/cc/x86_64_device.go
index bd68ca5..728442c 100644
--- a/cc/x86_64_device.go
+++ b/cc/x86_64_device.go
@@ -256,5 +256,5 @@
 }
 
 func init() {
-	registerToolchainFactory(common.Device, common.X86_64, x86_64ToolchainFactory)
+	registerDeviceToolchainFactory(common.X86_64, x86_64ToolchainFactory)
 }
diff --git a/cc/x86_darwin_host.go b/cc/x86_darwin_host.go
index 4195dae..9ca03ba 100644
--- a/cc/x86_darwin_host.go
+++ b/cc/x86_darwin_host.go
@@ -1,7 +1,6 @@
 package cc
 
 import (
-	"runtime"
 	"strings"
 
 	"android/soong/common"
@@ -12,6 +11,8 @@
 		"-fno-exceptions", // from build/core/combo/select.mk
 		"-Wno-multichar",  // from build/core/combo/select.mk
 
+		"-fdiagnostics-color",
+
 		"-fPIC",
 		"-funwind-tables",
 
@@ -195,6 +196,10 @@
 	return "${darwinClangLdflags} ${darwinX8664ClangLdflags}"
 }
 
+func (t *toolchainDarwin) ShlibSuffix() string {
+	return ".dylib"
+}
+
 var toolchainDarwinX86Singleton Toolchain = &toolchainDarwinX86{}
 var toolchainDarwinX8664Singleton Toolchain = &toolchainDarwinX8664{}
 
@@ -207,8 +212,6 @@
 }
 
 func init() {
-	if runtime.GOOS == "darwin" {
-		registerToolchainFactory(common.Host, common.X86, darwinX86ToolchainFactory)
-		registerToolchainFactory(common.Host, common.X86_64, darwinX8664ToolchainFactory)
-	}
+	registerHostToolchainFactory(common.Darwin, common.X86, darwinX86ToolchainFactory)
+	registerHostToolchainFactory(common.Darwin, common.X86_64, darwinX8664ToolchainFactory)
 }
diff --git a/cc/x86_device.go b/cc/x86_device.go
index df0c0ff..8543240 100644
--- a/cc/x86_device.go
+++ b/cc/x86_device.go
@@ -258,5 +258,5 @@
 }
 
 func init() {
-	registerToolchainFactory(common.Device, common.X86, x86ToolchainFactory)
+	registerDeviceToolchainFactory(common.X86, x86ToolchainFactory)
 }
diff --git a/cc/x86_linux_host.go b/cc/x86_linux_host.go
index f544476..09a0803 100644
--- a/cc/x86_linux_host.go
+++ b/cc/x86_linux_host.go
@@ -1,7 +1,6 @@
 package cc
 
 import (
-	"runtime"
 	"strings"
 
 	"android/soong/common"
@@ -12,6 +11,8 @@
 		"-fno-exceptions", // from build/core/combo/select.mk
 		"-Wno-multichar",  // from build/core/combo/select.mk
 
+		"-fdiagnostics-color",
+
 		"-Wa,--noexecstack",
 
 		"-fPIC",
@@ -233,8 +234,6 @@
 }
 
 func init() {
-	if runtime.GOOS == "linux" {
-		registerToolchainFactory(common.Host, common.X86, linuxX86ToolchainFactory)
-		registerToolchainFactory(common.Host, common.X86_64, linuxX8664ToolchainFactory)
-	}
+	registerHostToolchainFactory(common.Linux, common.X86, linuxX86ToolchainFactory)
+	registerHostToolchainFactory(common.Linux, common.X86_64, linuxX8664ToolchainFactory)
 }
diff --git a/cc/x86_windows_host.go b/cc/x86_windows_host.go
new file mode 100644
index 0000000..70ce74d
--- /dev/null
+++ b/cc/x86_windows_host.go
@@ -0,0 +1,150 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cc
+
+import (
+	"strings"
+
+	"android/soong/common"
+)
+
+var (
+	windowsCflags = []string{
+		"-fno-exceptions", // from build/core/combo/select.mk
+		"-Wno-multichar",  // from build/core/combo/select.mk
+
+		"-DUSE_MINGW",
+		"-DWIN32_LEAN_AND_MEAN",
+		"-Wno-unused-parameter",
+		"-m32",
+
+		// Workaround differences in inttypes.h between host and target.
+		//See bug 12708004.
+		"-D__STDC_FORMAT_MACROS",
+		"-D__STDC_CONSTANT_MACROS",
+
+		// Use C99-compliant printf functions (%zd).
+		"-D__USE_MINGW_ANSI_STDIO=1",
+		// Admit to using >= Win2K. Both are needed because of <_mingw.h>.
+		"-D_WIN32_WINNT=0x0500",
+		"-DWINVER=0x0500",
+		// Get 64-bit off_t and related functions.
+		"-D_FILE_OFFSET_BITS=64",
+
+		// 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
+	}
+
+	windowsIncludeFlags = []string{
+		"-I${windowsGccRoot}/${windowsGccTriple}/include",
+		"-I${windowsGccRoot}/lib/gcc/${windowsGccTriple}/4.8.3/include",
+	}
+
+	windowsLdflags = []string{
+		"-m32",
+		"-L${windowsGccRoot}/${windowsGccTriple}",
+		"--enable-stdcall-fixup",
+	}
+)
+
+func init() {
+	pctx.StaticVariable("windowsGccVersion", "4.8")
+
+	pctx.StaticVariable("windowsGccRoot",
+		"${SrcDir}/prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-w64-mingw32-${windowsGccVersion}")
+
+	pctx.StaticVariable("windowsGccTriple", "x86_64-w64-mingw32")
+
+	pctx.StaticVariable("windowsCflags", strings.Join(windowsCflags, " "))
+	pctx.StaticVariable("windowsLdflags", strings.Join(windowsLdflags, " "))
+}
+
+type toolchainWindows struct {
+	toolchain32Bit
+
+	cFlags, ldFlags string
+}
+
+func (t *toolchainWindows) Name() string {
+	return "x86"
+}
+
+func (t *toolchainWindows) GccRoot() string {
+	return "${windowsGccRoot}"
+}
+
+func (t *toolchainWindows) GccTriple() string {
+	return "${windowsGccTriple}"
+}
+
+func (t *toolchainWindows) GccVersion() string {
+	return "${windowsGccVersion}"
+}
+
+func (t *toolchainWindows) Cflags() string {
+	return "${windowsCflags}"
+}
+
+func (t *toolchainWindows) Cppflags() string {
+	return ""
+}
+
+func (t *toolchainWindows) Ldflags() string {
+	return "${windowsLdflags}"
+}
+
+func (t *toolchainWindows) IncludeFlags() string {
+	return ""
+}
+
+func (t *toolchainWindows) ClangSupported() bool {
+	return false
+}
+
+func (t *toolchainWindows) ClangTriple() string {
+	panic("Clang is not supported under mingw")
+}
+
+func (t *toolchainWindows) ClangCflags() string {
+	panic("Clang is not supported under mingw")
+}
+
+func (t *toolchainWindows) ClangCppflags() string {
+	panic("Clang is not supported under mingw")
+}
+
+func (t *toolchainWindows) ClangLdflags() string {
+	panic("Clang is not supported under mingw")
+}
+
+func (t *toolchainWindows) ShlibSuffix() string {
+	return ".dll"
+}
+
+func (t *toolchainWindows) ExecutableSuffix() string {
+	return ".exe"
+}
+
+var toolchainWindowsSingleton Toolchain = &toolchainWindows{}
+
+func windowsToolchainFactory(arch common.Arch) Toolchain {
+	return toolchainWindowsSingleton
+}
+
+func init() {
+	registerHostToolchainFactory(common.Windows, common.X86, windowsToolchainFactory)
+}