diff options
author | Dan Willemsen <dwillemsen@google.com> | 2015-11-24 17:53:15 -0800 |
---|---|---|
committer | Dan Willemsen <dwillemsen@google.com> | 2015-11-30 15:28:31 -0800 |
commit | 490fd4955747c9d3715954359d72937960f02a22 (patch) | |
tree | 3b4ae5b86149ee178f60c21faf65e03ad7e23a51 /common | |
parent | 3b336c20566becb20324e25deb52ee08d8b1f9f8 (diff) | |
download | build_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.go | 167 | ||||
-rw-r--r-- | common/module.go | 36 | ||||
-rw-r--r-- | common/variable.go | 10 |
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) { |