aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2015-11-24 17:53:15 -0800
committerDan Willemsen <dwillemsen@google.com>2015-11-30 15:28:31 -0800
commit490fd4955747c9d3715954359d72937960f02a22 (patch)
tree3b4ae5b86149ee178f60c21faf65e03ad7e23a51 /common
parent3b336c20566becb20324e25deb52ee08d8b1f9f8 (diff)
downloadbuild_soong-490fd4955747c9d3715954359d72937960f02a22.tar.gz
build_soong-490fd4955747c9d3715954359d72937960f02a22.tar.bz2
build_soong-490fd4955747c9d3715954359d72937960f02a22.zip
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
Diffstat (limited to 'common')
-rw-r--r--common/arch.go167
-rw-r--r--common/module.go36
-rw-r--r--common/variable.go10
3 files changed, 184 insertions, 29 deletions
diff --git a/common/arch.go b/common/arch.go
index 8ac52e66..4cddc00e 100644
--- a/common/arch.go
+++ b/common/arch.go
@@ -29,6 +29,7 @@ func init() {
RegisterTopDownMutator("defaults", defaultsMutator)
RegisterBottomUpMutator("host_or_device", HostOrDeviceMutator)
+ RegisterBottomUpMutator("host_type", HostTypeMutator)
RegisterBottomUpMutator("arch", ArchMutator)
}
@@ -261,6 +262,8 @@ type archProperties struct {
Darwin_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
// Properties for module variants being built to run on windows hosts
Windows interface{} `blueprint:"filter(android:\"arch_variant\")"`
+ // Properties for module variants being built to run on windows x86 hosts
+ Windows_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
// Properties for module variants being built to run on linux or darwin hosts
Not_windows interface{} `blueprint:"filter(android:\"arch_variant\")"`
}
@@ -383,6 +386,52 @@ var hostOrDeviceName = map[HostOrDevice]string{
Host: "host",
}
+type HostType int
+
+const (
+ NoHostType HostType = iota
+ Linux
+ Darwin
+ Windows
+)
+
+func CurrentHostType() HostType {
+ switch runtime.GOOS {
+ case "linux":
+ return Linux
+ case "darwin":
+ return Darwin
+ default:
+ panic(fmt.Sprintf("unsupported OS: %s", runtime.GOOS))
+ }
+}
+
+func (ht HostType) String() string {
+ switch ht {
+ case Linux:
+ return "linux"
+ case Darwin:
+ return "darwin"
+ case Windows:
+ return "windows"
+ default:
+ panic(fmt.Sprintf("unexpected HostType value %d", ht))
+ }
+}
+
+func (ht HostType) Field() string {
+ switch ht {
+ case Linux:
+ return "Linux"
+ case Darwin:
+ return "Darwin"
+ case Windows:
+ return "Windows"
+ default:
+ panic(fmt.Sprintf("unexpected HostType value %d", ht))
+ }
+}
+
var (
commonArch = Arch{
ArchType: Common,
@@ -421,6 +470,34 @@ func HostOrDeviceMutator(mctx AndroidBottomUpMutatorContext) {
}
}
+func HostTypeMutator(mctx AndroidBottomUpMutatorContext) {
+ var module AndroidModule
+ var ok bool
+ if module, ok = mctx.Module().(AndroidModule); !ok {
+ return
+ }
+
+ if !module.base().HostSupported() || !module.base().HostOrDevice().Host() {
+ return
+ }
+
+ buildTypes, err := decodeHostTypesProductVariables(mctx.Config().(Config).ProductVariables)
+ if err != nil {
+ mctx.ModuleErrorf("%s", err.Error())
+ return
+ }
+
+ typeNames := []string{}
+ for _, ht := range buildTypes {
+ typeNames = append(typeNames, ht.String())
+ }
+
+ modules := mctx.CreateVariations(typeNames...)
+ for i, m := range modules {
+ m.(AndroidModule).base().SetHostType(buildTypes[i])
+ }
+}
+
func ArchMutator(mctx AndroidBottomUpMutatorContext) {
var module AndroidModule
var ok bool
@@ -437,7 +514,7 @@ func ArchMutator(mctx AndroidBottomUpMutatorContext) {
multilib := module.base().commonProperties.Compile_multilib
if module.base().HostSupported() && module.base().HostOrDevice().Host() {
- hostModuleArches, err := decodeMultilib(multilib, hostArches)
+ hostModuleArches, err := decodeMultilib(multilib, hostArches[module.base().HostType()])
if err != nil {
mctx.ModuleErrorf("%s", err.Error())
}
@@ -560,6 +637,7 @@ func (a *AndroidModuleBase) appendProperties(ctx AndroidBottomUpMutatorContext,
func (a *AndroidModuleBase) setArchProperties(ctx AndroidBottomUpMutatorContext) {
arch := a.commonProperties.CompileArch
hod := a.commonProperties.CompileHostOrDevice
+ ht := a.commonProperties.CompileHostType
if arch.ArchType == Common {
return
@@ -654,30 +732,21 @@ func (a *AndroidModuleBase) setArchProperties(ctx AndroidBottomUpMutatorContext)
// key: value,
// },
// },
- var osList = []struct {
- goos string
- field string
- }{
- {"darwin", "Darwin"},
- {"linux", "Linux"},
- {"windows", "Windows"},
- }
-
if hod.Host() {
- for _, v := range osList {
- if v.goos == runtime.GOOS {
- field := v.field
- prefix := "target." + v.goos
- a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
- t := arch.ArchType
- field = v.field + "_" + t.Name
- prefix = "target." + v.goos + "_" + t.Name
- a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
- }
- }
- field := "Not_windows"
- prefix := "target.not_windows"
+ field := ht.Field()
+ prefix := "target." + ht.String()
+ a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
+
+ t := arch.ArchType
+ field = ht.Field() + "_" + t.Name
+ prefix = "target." + ht.String() + "_" + t.Name
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
+
+ if ht != Windows {
+ field := "Not_windows"
+ prefix := "target.not_windows"
+ a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
+ }
}
// Handle 64-bit device properties in the form:
@@ -742,8 +811,24 @@ func forEachInterface(v reflect.Value, f func(reflect.Value)) {
}
}
+// Get a list of HostTypes from the product variables
+func decodeHostTypesProductVariables(variables productVariables) ([]HostType, error) {
+ ret := []HostType{CurrentHostType()}
+
+ if variables.CrossHost != nil && *variables.CrossHost != "" {
+ switch *variables.CrossHost {
+ case "windows":
+ ret = append(ret, Windows)
+ default:
+ return nil, fmt.Errorf("Unsupported secondary host: %s", *variables.CrossHost)
+ }
+ }
+
+ return ret, nil
+}
+
// Convert the arch product variables into a list of host and device Arch structs
-func decodeArchProductVariables(variables productVariables) ([]Arch, []Arch, error) {
+func decodeArchProductVariables(variables productVariables) (map[HostType][]Arch, []Arch, error) {
if variables.HostArch == nil {
return nil, nil, fmt.Errorf("No host primary architecture set")
}
@@ -763,6 +848,38 @@ func decodeArchProductVariables(variables productVariables) ([]Arch, []Arch, err
hostArches = append(hostArches, hostSecondaryArch)
}
+ hostTypeArches := map[HostType][]Arch{
+ CurrentHostType(): hostArches,
+ }
+
+ if variables.CrossHost != nil && *variables.CrossHost != "" {
+ if variables.CrossHostArch == nil || *variables.CrossHostArch == "" {
+ return nil, nil, fmt.Errorf("No cross-host primary architecture set")
+ }
+
+ crossHostArch, err := decodeArch(*variables.CrossHostArch, nil, nil, nil)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ crossHostArches := []Arch{crossHostArch}
+
+ if variables.CrossHostSecondaryArch != nil && *variables.CrossHostSecondaryArch != "" {
+ crossHostSecondaryArch, err := decodeArch(*variables.CrossHostSecondaryArch, nil, nil, nil)
+ if err != nil {
+ return nil, nil, err
+ }
+ crossHostArches = append(crossHostArches, crossHostSecondaryArch)
+ }
+
+ switch *variables.CrossHost {
+ case "windows":
+ hostTypeArches[Windows] = crossHostArches
+ default:
+ return nil, nil, fmt.Errorf("Unsupported cross-host: %s", *variables.CrossHost)
+ }
+ }
+
if variables.DeviceArch == nil {
return nil, nil, fmt.Errorf("No device primary architecture set")
}
@@ -785,7 +902,7 @@ func decodeArchProductVariables(variables productVariables) ([]Arch, []Arch, err
deviceArches = append(deviceArches, deviceSecondaryArch)
}
- return hostArches, deviceArches, nil
+ return hostTypeArches, deviceArches, nil
}
// Convert a set of strings from product variables into a single Arch struct
diff --git a/common/module.go b/common/module.go
index b64342f6..7bb21a25 100644
--- a/common/module.go
+++ b/common/module.go
@@ -17,7 +17,6 @@ package common
import (
"android/soong"
"path/filepath"
- "runtime"
"android/soong/glob"
@@ -37,6 +36,7 @@ var (
type androidBaseContext interface {
Arch() Arch
HostOrDevice() HostOrDevice
+ HostType() HostType
Host() bool
Device() bool
Darwin() bool
@@ -88,6 +88,9 @@ type commonProperties struct {
// 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 @@ func (a *AndroidModuleBase) SetHostOrDevice(hod HostOrDevice) {
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 @@ func (a *AndroidModuleBase) HostOrDevice() HostOrDevice {
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) DeviceSupported() bool {
}
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 @@ func (a *AndroidModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleCo
return androidBaseContextImpl{
arch: a.commonProperties.CompileArch,
hod: a.commonProperties.CompileHostOrDevice,
+ ht: a.commonProperties.CompileHostType,
config: ctx.Config().(Config),
}
}
@@ -320,7 +338,7 @@ func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
installFiles: a.installFiles,
}
- if proptools.Bool(a.commonProperties.Disabled) {
+ if a.Disabled() {
return
}
@@ -341,6 +359,7 @@ func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
type androidBaseContextImpl struct {
arch Arch
hod HostOrDevice
+ ht HostType
debug bool
config Config
}
@@ -366,6 +385,10 @@ func (a *androidBaseContextImpl) HostOrDevice() HostOrDevice {
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) Device() bool {
}
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 @@ func (a *androidModuleContext) InstallFileName(installPath, name, srcPath string
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...)
diff --git a/common/variable.go b/common/variable.go
index 9a5998f7..5b9092f3 100644
--- a/common/variable.go
+++ b/common/variable.go
@@ -17,6 +17,7 @@ package common
import (
"fmt"
"reflect"
+ "runtime"
"strings"
"github.com/google/blueprint/proptools"
@@ -69,6 +70,10 @@ type productVariables struct {
HostArch *string `json:",omitempty"`
HostSecondaryArch *string `json:",omitempty"`
+
+ CrossHost *string `json:",omitempty"`
+ CrossHostArch *string `json:",omitempty"`
+ CrossHostSecondaryArch *string `json:",omitempty"`
}
func boolPtr(v bool) *bool {
@@ -99,6 +104,11 @@ func (v *productVariables) SetDefaultConfig() {
DeviceSecondaryCpuVariant: stringPtr("denver"),
DeviceSecondaryAbi: &[]string{"armeabi-v7a"},
}
+
+ if runtime.GOOS == "linux" {
+ v.CrossHost = stringPtr("windows")
+ v.CrossHostArch = stringPtr("x86")
+ }
}
func variableMutator(mctx AndroidBottomUpMutatorContext) {