Set host and device arches from product variables
Read the host and device arches from soong.variables.
Bug: 23567214
Change-Id: Ie44db4dcf431a4c7dddcdc26117d4daa734c1f67
diff --git a/common/arch.go b/common/arch.go
index 22393cc..e9edf2e 100644
--- a/common/arch.go
+++ b/common/arch.go
@@ -44,6 +44,15 @@
}
)
+var archTypeMap = map[string]ArchType{
+ "arm": Arm,
+ "arm64": Arm64,
+ "mips": Mips,
+ "misp64": Mips64,
+ "x86": X86,
+ "x86_64": X86_64,
+}
+
/*
Example blueprints file containing all variant property groups, with comment listing what type
of variants get properties in that group:
@@ -198,7 +207,7 @@
ArchType ArchType
ArchVariant string
CpuVariant string
- Abi string
+ Abi []string
}
func (a Arch) String() string {
@@ -287,23 +296,6 @@
}
var (
- armArch = Arch{
- ArchType: Arm,
- ArchVariant: "armv7-a-neon",
- CpuVariant: "cortex-a15",
- Abi: "armeabi-v7a",
- }
- arm64Arch = Arch{
- ArchType: Arm64,
- CpuVariant: "denver64",
- Abi: "arm64-v8a",
- }
- x86Arch = Arch{
- ArchType: X86,
- }
- x8664Arch = Arch{
- ArchType: X86_64,
- }
commonArch = Arch{
ArchType: Common,
}
@@ -348,55 +340,45 @@
return
}
- // TODO: this is all hardcoded for arm64 primary, arm secondary for now
- // Replace with a configuration file written by lunch or bootstrap
+ hostArches, deviceArches, err := decodeArchProductVariables(mctx.Config().(Config).ProductVariables)
+ if err != nil {
+ mctx.ModuleErrorf("%s", err.Error())
+ }
- arches := []Arch{}
+ moduleArches := []Arch{}
+ multilib := module.base().commonProperties.Compile_multilib
if module.base().HostSupported() && module.base().HostOrDevice().Host() {
- switch module.base().commonProperties.Compile_multilib {
- case "common":
- arches = append(arches, commonArch)
- case "both":
- arches = append(arches, x8664Arch, x86Arch)
- case "first", "64":
- arches = append(arches, x8664Arch)
- case "32":
- arches = append(arches, x86Arch)
- default:
- arches = append(arches, x8664Arch)
+ hostModuleArches, err := decodeMultilib(multilib, hostArches)
+ if err != nil {
+ mctx.ModuleErrorf("%s", err.Error())
}
+
+ moduleArches = append(moduleArches, hostModuleArches...)
}
if module.base().DeviceSupported() && module.base().HostOrDevice().Device() {
- switch module.base().commonProperties.Compile_multilib {
- case "common":
- arches = append(arches, commonArch)
- case "both":
- arches = append(arches, arm64Arch, armArch)
- case "first", "64":
- arches = append(arches, arm64Arch)
- case "32":
- arches = append(arches, armArch)
- default:
- mctx.ModuleErrorf(`compile_multilib must be "both", "first", "32", or "64", found %q`,
- module.base().commonProperties.Compile_multilib)
+ deviceModuleArches, err := decodeMultilib(multilib, deviceArches)
+ if err != nil {
+ mctx.ModuleErrorf("%s", err.Error())
}
+
+ moduleArches = append(moduleArches, deviceModuleArches...)
}
- if len(arches) == 0 {
+ if len(moduleArches) == 0 {
return
}
archNames := []string{}
- for _, arch := range arches {
+ for _, arch := range moduleArches {
archNames = append(archNames, arch.String())
}
modules := mctx.CreateVariations(archNames...)
for i, m := range modules {
- m.(AndroidModule).base().SetArch(arches[i])
+ m.(AndroidModule).base().SetArch(moduleArches[i])
m.(AndroidModule).base().setArchProperties(mctx)
}
}
@@ -612,3 +594,106 @@
panic(fmt.Errorf("Unsupported kind %s", v.Kind()))
}
}
+
+// Convert the arch product variables into a list of host and device Arch structs
+func decodeArchProductVariables(variables productVariables) ([]Arch, []Arch, error) {
+ if variables.HostArch == nil {
+ return nil, nil, fmt.Errorf("No host primary architecture set")
+ }
+
+ hostArch, err := decodeArch(*variables.HostArch, nil, nil, nil)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ hostArches := []Arch{hostArch}
+
+ if variables.HostSecondaryArch != nil {
+ hostSecondaryArch, err := decodeArch(*variables.HostSecondaryArch, nil, nil, nil)
+ if err != nil {
+ return nil, nil, err
+ }
+ hostArches = append(hostArches, hostSecondaryArch)
+ }
+
+ if variables.DeviceArch == nil {
+ return nil, nil, fmt.Errorf("No device primary architecture set")
+ }
+
+ deviceArch, err := decodeArch(*variables.DeviceArch, variables.DeviceArchVariant,
+ variables.DeviceCpuVariant, variables.DeviceAbi)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ deviceArches := []Arch{deviceArch}
+
+ if variables.DeviceSecondaryArch != nil {
+ deviceSecondaryArch, err := decodeArch(*variables.DeviceSecondaryArch,
+ variables.DeviceSecondaryArchVariant, variables.DeviceSecondaryCpuVariant,
+ variables.DeviceSecondaryAbi)
+ if err != nil {
+ return nil, nil, err
+ }
+ deviceArches = append(deviceArches, deviceSecondaryArch)
+ }
+
+ return hostArches, deviceArches, nil
+}
+
+// Convert a set of strings from product variables into a single Arch struct
+func decodeArch(arch string, archVariant, cpuVariant *string, abi *[]string) (Arch, error) {
+ stringPtr := func(p *string) string {
+ if p != nil {
+ return *p
+ }
+ return ""
+ }
+
+ slicePtr := func(p *[]string) []string {
+ if p != nil {
+ return *p
+ }
+ return nil
+ }
+
+ archType := archTypeMap[arch]
+
+ return Arch{
+ ArchType: archType,
+ ArchVariant: stringPtr(archVariant),
+ CpuVariant: stringPtr(cpuVariant),
+ Abi: slicePtr(abi),
+ }, nil
+}
+
+// Use the module multilib setting to select one or more arches from an arch list
+func decodeMultilib(multilib string, arches []Arch) ([]Arch, error) {
+ buildArches := []Arch{}
+ switch multilib {
+ case "common":
+ buildArches = append(buildArches, commonArch)
+ case "both":
+ buildArches = append(buildArches, arches...)
+ case "first":
+ buildArches = append(buildArches, arches[0])
+ case "32":
+ for _, a := range arches {
+ if a.ArchType.Multilib == "lib32" {
+ buildArches = append(buildArches, a)
+ }
+ }
+ case "64":
+ for _, a := range arches {
+ if a.ArchType.Multilib == "lib64" {
+ buildArches = append(buildArches, a)
+ }
+ }
+ default:
+ return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", or "64", found %q`,
+ multilib)
+ //buildArches = append(buildArches, arches[0])
+ }
+
+ return buildArches, nil
+}