Add multi-target variants
Allow modules to specify that they will handle multiple targets in the common variant. This will be used by android_app modules to handle JNI libraries from multiple architectures. Bug: 80095087 Test: m checkbuild Change-Id: Iede3e9c23b64fb516341c3ae08074a322b511d40
This commit is contained in:
@@ -288,6 +288,30 @@ func (target Target) String() string {
|
|||||||
return target.Os.String() + "_" + target.Arch.String()
|
return target.Os.String() + "_" + target.Arch.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// archMutator splits a module into a variant for each Target requested by the module. Target selection
|
||||||
|
// for a module is in three levels, OsClass, mulitlib, and then Target.
|
||||||
|
// OsClass selection is determined by:
|
||||||
|
// - The HostOrDeviceSupported value passed in to InitAndroidArchModule by the module type factory, which selects
|
||||||
|
// whether the module type can compile for host, device or both.
|
||||||
|
// - The host_supported and device_supported properties on the module.
|
||||||
|
// If host is supported for the module, the Host and HostCross OsClasses are are selected. If device is supported
|
||||||
|
// for the module, the Device OsClass is selected.
|
||||||
|
// Within each selected OsClass, the multilib selection is determined by:
|
||||||
|
// - The compile_multilib property if it set (which may be overriden by target.android.compile_multlib or
|
||||||
|
// target.host.compile_multilib).
|
||||||
|
// - The default multilib passed to InitAndroidArchModule if compile_multilib was not set.
|
||||||
|
// Valid multilib values include:
|
||||||
|
// "both": compile for all Targets supported by the OsClass (generally x86_64 and x86, or arm64 and arm).
|
||||||
|
// "first": compile for only a single preferred Target supported by the OsClass. This is generally x86_64 or arm64,
|
||||||
|
// but may be arm for a 32-bit only build or a build with TARGET_PREFER_32_BIT=true set.
|
||||||
|
// "32": compile for only a single 32-bit Target supported by the OsClass.
|
||||||
|
// "64": compile for only a single 64-bit Target supported by the OsClass.
|
||||||
|
// "common": compile a for a single Target that will work on all Targets suported by the OsClass (for example Java).
|
||||||
|
//
|
||||||
|
// Once the list of Targets is determined, the module is split into a variant for each Target.
|
||||||
|
//
|
||||||
|
// Modules can be initialized with InitAndroidMultiTargetsArchModule, in which case they will be split by OsClass,
|
||||||
|
// but will have a common Target that is expected to handle all other selected Targets via ctx.MultiTargets().
|
||||||
func archMutator(mctx BottomUpMutatorContext) {
|
func archMutator(mctx BottomUpMutatorContext) {
|
||||||
var module Module
|
var module Module
|
||||||
var ok bool
|
var ok bool
|
||||||
@@ -304,6 +328,7 @@ func archMutator(mctx BottomUpMutatorContext) {
|
|||||||
osClasses := base.OsClassSupported()
|
osClasses := base.OsClassSupported()
|
||||||
|
|
||||||
var moduleTargets []Target
|
var moduleTargets []Target
|
||||||
|
moduleMultiTargets := make(map[int][]Target)
|
||||||
primaryModules := make(map[int]bool)
|
primaryModules := make(map[int]bool)
|
||||||
|
|
||||||
for _, class := range osClasses {
|
for _, class := range osClasses {
|
||||||
@@ -311,36 +336,34 @@ func archMutator(mctx BottomUpMutatorContext) {
|
|||||||
if len(classTargets) == 0 {
|
if len(classTargets) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// only the primary arch in the recovery partition
|
// only the primary arch in the recovery partition
|
||||||
if module.InstallInRecovery() {
|
if module.InstallInRecovery() {
|
||||||
classTargets = []Target{mctx.Config().Targets[Device][0]}
|
classTargets = []Target{mctx.Config().Targets[Device][0]}
|
||||||
}
|
}
|
||||||
|
|
||||||
var multilib string
|
|
||||||
switch class {
|
|
||||||
case Device:
|
|
||||||
multilib = String(base.commonProperties.Target.Android.Compile_multilib)
|
|
||||||
case Host, HostCross:
|
|
||||||
multilib = String(base.commonProperties.Target.Host.Compile_multilib)
|
|
||||||
}
|
|
||||||
if multilib == "" {
|
|
||||||
multilib = String(base.commonProperties.Compile_multilib)
|
|
||||||
}
|
|
||||||
if multilib == "" {
|
|
||||||
multilib = base.commonProperties.Default_multilib
|
|
||||||
}
|
|
||||||
|
|
||||||
prefer32 := false
|
prefer32 := false
|
||||||
if base.prefer32 != nil {
|
if base.prefer32 != nil {
|
||||||
prefer32 = base.prefer32(mctx, base, class)
|
prefer32 = base.prefer32(mctx, base, class)
|
||||||
}
|
}
|
||||||
|
|
||||||
targets, err := decodeMultilib(multilib, classTargets, prefer32)
|
multilib, extraMultilib := decodeMultilib(base, class)
|
||||||
|
targets, err := decodeMultilibTargets(multilib, classTargets, prefer32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mctx.ModuleErrorf("%s", err.Error())
|
mctx.ModuleErrorf("%s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var multiTargets []Target
|
||||||
|
if extraMultilib != "" {
|
||||||
|
multiTargets, err = decodeMultilibTargets(extraMultilib, classTargets, prefer32)
|
||||||
|
if err != nil {
|
||||||
|
mctx.ModuleErrorf("%s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(targets) > 0 {
|
if len(targets) > 0 {
|
||||||
primaryModules[len(moduleTargets)] = true
|
primaryModules[len(moduleTargets)] = true
|
||||||
|
moduleMultiTargets[len(moduleTargets)] = multiTargets
|
||||||
moduleTargets = append(moduleTargets, targets...)
|
moduleTargets = append(moduleTargets, targets...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -358,11 +381,37 @@ func archMutator(mctx BottomUpMutatorContext) {
|
|||||||
|
|
||||||
modules := mctx.CreateVariations(targetNames...)
|
modules := mctx.CreateVariations(targetNames...)
|
||||||
for i, m := range modules {
|
for i, m := range modules {
|
||||||
m.(Module).base().SetTarget(moduleTargets[i], primaryModules[i])
|
m.(Module).base().SetTarget(moduleTargets[i], moduleMultiTargets[i], primaryModules[i])
|
||||||
m.(Module).base().setArchProperties(mctx)
|
m.(Module).base().setArchProperties(mctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeMultilib(base *ModuleBase, class OsClass) (multilib, extraMultilib string) {
|
||||||
|
switch class {
|
||||||
|
case Device:
|
||||||
|
multilib = String(base.commonProperties.Target.Android.Compile_multilib)
|
||||||
|
case Host, HostCross:
|
||||||
|
multilib = String(base.commonProperties.Target.Host.Compile_multilib)
|
||||||
|
}
|
||||||
|
if multilib == "" {
|
||||||
|
multilib = String(base.commonProperties.Compile_multilib)
|
||||||
|
}
|
||||||
|
if multilib == "" {
|
||||||
|
multilib = base.commonProperties.Default_multilib
|
||||||
|
}
|
||||||
|
|
||||||
|
if base.commonProperties.UseTargetVariants {
|
||||||
|
return multilib, ""
|
||||||
|
} else {
|
||||||
|
// For app modules a single arch variant will be created per OS class which is expected to handle all the
|
||||||
|
// selected arches. Return the common-type as multilib and any Android.bp provided multilib as extraMultilib
|
||||||
|
if multilib == base.commonProperties.Default_multilib {
|
||||||
|
multilib = "first"
|
||||||
|
}
|
||||||
|
return base.commonProperties.Default_multilib, multilib
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func filterArchStruct(prop reflect.Type) (reflect.Type, bool) {
|
func filterArchStruct(prop reflect.Type) (reflect.Type, bool) {
|
||||||
var fields []reflect.StructField
|
var fields []reflect.StructField
|
||||||
|
|
||||||
@@ -1114,7 +1163,7 @@ func firstTarget(targets []Target, filters ...string) []Target {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use the module multilib setting to select one or more targets from a target list
|
// Use the module multilib setting to select one or more targets from a target list
|
||||||
func decodeMultilib(multilib string, targets []Target, prefer32 bool) ([]Target, error) {
|
func decodeMultilibTargets(multilib string, targets []Target, prefer32 bool) ([]Target, error) {
|
||||||
buildTargets := []Target{}
|
buildTargets := []Target{}
|
||||||
|
|
||||||
switch multilib {
|
switch multilib {
|
||||||
|
@@ -58,6 +58,7 @@ type ModuleBuildParams BuildParams
|
|||||||
type androidBaseContext interface {
|
type androidBaseContext interface {
|
||||||
Target() Target
|
Target() Target
|
||||||
TargetPrimary() bool
|
TargetPrimary() bool
|
||||||
|
MultiTargets() []Target
|
||||||
Arch() Arch
|
Arch() Arch
|
||||||
Os() OsType
|
Os() OsType
|
||||||
Host() bool
|
Host() bool
|
||||||
@@ -215,6 +216,7 @@ type commonProperties struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UseTargetVariants bool `blueprint:"mutated"`
|
||||||
Default_multilib string `blueprint:"mutated"`
|
Default_multilib string `blueprint:"mutated"`
|
||||||
|
|
||||||
// whether this is a proprietary vendor module, and should be installed into /vendor
|
// whether this is a proprietary vendor module, and should be installed into /vendor
|
||||||
@@ -265,6 +267,7 @@ type commonProperties struct {
|
|||||||
|
|
||||||
// Set by TargetMutator
|
// Set by TargetMutator
|
||||||
CompileTarget Target `blueprint:"mutated"`
|
CompileTarget Target `blueprint:"mutated"`
|
||||||
|
CompileMultiTargets []Target `blueprint:"mutated"`
|
||||||
CompilePrimary bool `blueprint:"mutated"`
|
CompilePrimary bool `blueprint:"mutated"`
|
||||||
|
|
||||||
// Set by InitAndroidModule
|
// Set by InitAndroidModule
|
||||||
@@ -362,6 +365,7 @@ func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib
|
|||||||
base.commonProperties.HostOrDeviceSupported = hod
|
base.commonProperties.HostOrDeviceSupported = hod
|
||||||
base.commonProperties.Default_multilib = string(defaultMultilib)
|
base.commonProperties.Default_multilib = string(defaultMultilib)
|
||||||
base.commonProperties.ArchSpecific = true
|
base.commonProperties.ArchSpecific = true
|
||||||
|
base.commonProperties.UseTargetVariants = true
|
||||||
|
|
||||||
switch hod {
|
switch hod {
|
||||||
case HostAndDeviceSupported, HostAndDeviceDefault:
|
case HostAndDeviceSupported, HostAndDeviceDefault:
|
||||||
@@ -371,6 +375,11 @@ func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib
|
|||||||
InitArchModule(m)
|
InitArchModule(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
|
||||||
|
InitAndroidArchModule(m, hod, defaultMultilib)
|
||||||
|
m.base().commonProperties.UseTargetVariants = false
|
||||||
|
}
|
||||||
|
|
||||||
// A ModuleBase object contains the properties that are common to all Android
|
// A ModuleBase object contains the properties that are common to all Android
|
||||||
// modules. It should be included as an anonymous field in every module
|
// modules. It should be included as an anonymous field in every module
|
||||||
// struct definition. InitAndroidModule should then be called from the module's
|
// struct definition. InitAndroidModule should then be called from the module's
|
||||||
@@ -477,8 +486,9 @@ func (a *ModuleBase) base() *ModuleBase {
|
|||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ModuleBase) SetTarget(target Target, primary bool) {
|
func (a *ModuleBase) SetTarget(target Target, multiTargets []Target, primary bool) {
|
||||||
a.commonProperties.CompileTarget = target
|
a.commonProperties.CompileTarget = target
|
||||||
|
a.commonProperties.CompileMultiTargets = multiTargets
|
||||||
a.commonProperties.CompilePrimary = primary
|
a.commonProperties.CompilePrimary = primary
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,6 +500,10 @@ func (a *ModuleBase) TargetPrimary() bool {
|
|||||||
return a.commonProperties.CompilePrimary
|
return a.commonProperties.CompilePrimary
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *ModuleBase) MultiTargets() []Target {
|
||||||
|
return a.commonProperties.CompileMultiTargets
|
||||||
|
}
|
||||||
|
|
||||||
func (a *ModuleBase) Os() OsType {
|
func (a *ModuleBase) Os() OsType {
|
||||||
return a.Target().Os
|
return a.Target().Os
|
||||||
}
|
}
|
||||||
@@ -731,6 +745,7 @@ func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext)
|
|||||||
return androidBaseContextImpl{
|
return androidBaseContextImpl{
|
||||||
target: a.commonProperties.CompileTarget,
|
target: a.commonProperties.CompileTarget,
|
||||||
targetPrimary: a.commonProperties.CompilePrimary,
|
targetPrimary: a.commonProperties.CompilePrimary,
|
||||||
|
multiTargets: a.commonProperties.CompileMultiTargets,
|
||||||
kind: determineModuleKind(a, ctx),
|
kind: determineModuleKind(a, ctx),
|
||||||
config: ctx.Config().(Config),
|
config: ctx.Config().(Config),
|
||||||
}
|
}
|
||||||
@@ -785,6 +800,7 @@ func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
|
|||||||
|
|
||||||
type androidBaseContextImpl struct {
|
type androidBaseContextImpl struct {
|
||||||
target Target
|
target Target
|
||||||
|
multiTargets []Target
|
||||||
targetPrimary bool
|
targetPrimary bool
|
||||||
debug bool
|
debug bool
|
||||||
kind moduleKind
|
kind moduleKind
|
||||||
@@ -1022,6 +1038,10 @@ func (a *androidBaseContextImpl) TargetPrimary() bool {
|
|||||||
return a.targetPrimary
|
return a.targetPrimary
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *androidBaseContextImpl) MultiTargets() []Target {
|
||||||
|
return a.multiTargets
|
||||||
|
}
|
||||||
|
|
||||||
func (a *androidBaseContextImpl) Arch() Arch {
|
func (a *androidBaseContextImpl) Arch() Arch {
|
||||||
return a.target.Arch
|
return a.target.Arch
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user