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/common/module.go b/common/module.go
index b64342f..7bb21a2 100644
--- a/common/module.go
+++ b/common/module.go
@@ -17,7 +17,6 @@
 import (
 	"android/soong"
 	"path/filepath"
-	"runtime"
 
 	"android/soong/glob"
 
@@ -37,6 +36,7 @@
 type androidBaseContext interface {
 	Arch() Arch
 	HostOrDevice() HostOrDevice
+	HostType() HostType
 	Host() bool
 	Device() bool
 	Darwin() bool
@@ -88,6 +88,9 @@
 	// Set by HostOrDeviceMutator
 	CompileHostOrDevice HostOrDevice `blueprint:"mutated"`
 
+	// Set by HostTypeMutator
+	CompileHostType HostType `blueprint:"mutated"`
+
 	// Set by ArchMutator
 	CompileArch Arch `blueprint:"mutated"`
 
@@ -208,6 +211,10 @@
 	a.commonProperties.CompileHostOrDevice = hod
 }
 
+func (a *AndroidModuleBase) SetHostType(ht HostType) {
+	a.commonProperties.CompileHostType = ht
+}
+
 func (a *AndroidModuleBase) SetArch(arch Arch) {
 	a.commonProperties.CompileArch = arch
 }
@@ -216,6 +223,10 @@
 	return a.commonProperties.CompileHostOrDevice
 }
 
+func (a *AndroidModuleBase) HostType() HostType {
+	return a.commonProperties.CompileHostType
+}
+
 func (a *AndroidModuleBase) HostSupported() bool {
 	return a.commonProperties.HostOrDeviceSupported == HostSupported ||
 		a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
@@ -229,6 +240,12 @@
 }
 
 func (a *AndroidModuleBase) Disabled() bool {
+	if a.commonProperties.CompileHostOrDevice == Host &&
+		a.commonProperties.CompileHostType == Windows &&
+		a.commonProperties.Disabled == nil {
+
+		return true
+	}
 	return proptools.Bool(a.commonProperties.Disabled)
 }
 
@@ -308,6 +325,7 @@
 	return androidBaseContextImpl{
 		arch:   a.commonProperties.CompileArch,
 		hod:    a.commonProperties.CompileHostOrDevice,
+		ht:     a.commonProperties.CompileHostType,
 		config: ctx.Config().(Config),
 	}
 }
@@ -320,7 +338,7 @@
 		installFiles:           a.installFiles,
 	}
 
-	if proptools.Bool(a.commonProperties.Disabled) {
+	if a.Disabled() {
 		return
 	}
 
@@ -341,6 +359,7 @@
 type androidBaseContextImpl struct {
 	arch   Arch
 	hod    HostOrDevice
+	ht     HostType
 	debug  bool
 	config Config
 }
@@ -366,6 +385,10 @@
 	return a.hod
 }
 
+func (a *androidBaseContextImpl) HostType() HostType {
+	return a.ht
+}
+
 func (a *androidBaseContextImpl) Host() bool {
 	return a.hod.Host()
 }
@@ -375,7 +398,7 @@
 }
 
 func (a *androidBaseContextImpl) Darwin() bool {
-	return a.hod.Host() && runtime.GOOS == "darwin"
+	return a.hod.Host() && a.ht == Darwin
 }
 
 func (a *androidBaseContextImpl) Debug() bool {
@@ -396,7 +419,12 @@
 		fullInstallPath = filepath.Join(config.DeviceOut(), "system",
 			installPath, name)
 	} else {
-		fullInstallPath = filepath.Join(config.HostOut(), installPath, name)
+		// TODO
+		if a.ht == Windows {
+			fullInstallPath = filepath.Join(config.BuildDir(), "host", "windows-x86", installPath, name)
+		} else {
+			fullInstallPath = filepath.Join(config.HostOut(), installPath, name)
+		}
 	}
 
 	deps = append(deps, a.installDeps...)