summaryrefslogtreecommitdiff
path: root/android/packaging.go
diff options
context:
space:
mode:
Diffstat (limited to 'android/packaging.go')
-rw-r--r--android/packaging.go216
1 files changed, 149 insertions, 67 deletions
diff --git a/android/packaging.go b/android/packaging.go
index acafcd4f2..98c85fa0c 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -207,38 +207,49 @@ type PackagingBase struct {
// If this is set to true by a module type inheriting PackagingBase, the deps property
// collects the first target only even with compile_multilib: true.
DepsCollectFirstTargetOnly bool
+
+ // If this is set to try by a module type inheriting PackagingBase, the module type is
+ // allowed to utilize High_priority_deps.
+ AllowHighPriorityDeps bool
}
-type depsProperty struct {
+type DepsProperty struct {
+ // Deps that have higher priority in packaging when there is a packaging conflict.
+ // For example, if multiple files are being installed to same filepath, the install file
+ // of the module listed in this property will have a higher priority over those in other
+ // deps properties.
+ High_priority_deps []string `android:"arch_variant"`
+
// Modules to include in this package
Deps proptools.Configurable[[]string] `android:"arch_variant"`
}
type packagingMultilibProperties struct {
- First depsProperty `android:"arch_variant"`
- Common depsProperty `android:"arch_variant"`
- Lib32 depsProperty `android:"arch_variant"`
- Lib64 depsProperty `android:"arch_variant"`
- Both depsProperty `android:"arch_variant"`
- Prefer32 depsProperty `android:"arch_variant"`
+ First DepsProperty `android:"arch_variant"`
+ Common DepsProperty `android:"arch_variant"`
+ Lib32 DepsProperty `android:"arch_variant"`
+ Lib64 DepsProperty `android:"arch_variant"`
+ Both DepsProperty `android:"arch_variant"`
+ Prefer32 DepsProperty `android:"arch_variant"`
}
type packagingArchProperties struct {
- Arm64 depsProperty
- Arm depsProperty
- X86_64 depsProperty
- X86 depsProperty
+ Arm64 DepsProperty
+ Arm DepsProperty
+ X86_64 DepsProperty
+ X86 DepsProperty
}
type PackagingProperties struct {
- Deps proptools.Configurable[[]string] `android:"arch_variant"`
- Multilib packagingMultilibProperties `android:"arch_variant"`
+ DepsProperty
+
+ Multilib packagingMultilibProperties `android:"arch_variant"`
Arch packagingArchProperties
}
func InitPackageModule(p PackageModule) {
base := p.packagingBase()
- p.AddProperties(&base.properties)
+ p.AddProperties(&base.properties, &base.properties.DepsProperty)
}
func (p *PackagingBase) packagingBase() *PackagingBase {
@@ -249,55 +260,72 @@ func (p *PackagingBase) packagingBase() *PackagingBase {
// the current archicture when this module is not configured for multi target. When configured for
// multi target, deps is selected for each of the targets and is NOT selected for the current
// architecture which would be Common.
-func (p *PackagingBase) getDepsForArch(ctx BaseModuleContext, arch ArchType) []string {
- get := func(prop proptools.Configurable[[]string]) []string {
- return prop.GetOrDefault(ctx, nil)
+// It returns two lists, the normal and high priority deps, respectively.
+func (p *PackagingBase) getDepsForArch(ctx BaseModuleContext, arch ArchType) ([]string, []string) {
+ var normalDeps []string
+ var highPriorityDeps []string
+
+ get := func(prop DepsProperty) {
+ normalDeps = append(normalDeps, prop.Deps.GetOrDefault(ctx, nil)...)
+ highPriorityDeps = append(highPriorityDeps, prop.High_priority_deps...)
+ }
+ has := func(prop DepsProperty) bool {
+ return len(prop.Deps.GetOrDefault(ctx, nil)) > 0 || len(prop.High_priority_deps) > 0
}
- var ret []string
if arch == ctx.Target().Arch.ArchType && len(ctx.MultiTargets()) == 0 {
- ret = append(ret, get(p.properties.Deps)...)
+ get(p.properties.DepsProperty)
} else if arch.Multilib == "lib32" {
- ret = append(ret, get(p.properties.Multilib.Lib32.Deps)...)
+ get(p.properties.Multilib.Lib32)
// multilib.prefer32.deps are added for lib32 only when they support 32-bit arch
- for _, dep := range get(p.properties.Multilib.Prefer32.Deps) {
+ for _, dep := range p.properties.Multilib.Prefer32.Deps.GetOrDefault(ctx, nil) {
+ if checkIfOtherModuleSupportsLib32(ctx, dep) {
+ normalDeps = append(normalDeps, dep)
+ }
+ }
+ for _, dep := range p.properties.Multilib.Prefer32.High_priority_deps {
if checkIfOtherModuleSupportsLib32(ctx, dep) {
- ret = append(ret, dep)
+ highPriorityDeps = append(highPriorityDeps, dep)
}
}
} else if arch.Multilib == "lib64" {
- ret = append(ret, get(p.properties.Multilib.Lib64.Deps)...)
+ get(p.properties.Multilib.Lib64)
// multilib.prefer32.deps are added for lib64 only when they don't support 32-bit arch
- for _, dep := range get(p.properties.Multilib.Prefer32.Deps) {
+ for _, dep := range p.properties.Multilib.Prefer32.Deps.GetOrDefault(ctx, nil) {
if !checkIfOtherModuleSupportsLib32(ctx, dep) {
- ret = append(ret, dep)
+ normalDeps = append(normalDeps, dep)
+ }
+ }
+ for _, dep := range p.properties.Multilib.Prefer32.High_priority_deps {
+ if !checkIfOtherModuleSupportsLib32(ctx, dep) {
+ highPriorityDeps = append(highPriorityDeps, dep)
}
}
} else if arch == Common {
- ret = append(ret, get(p.properties.Multilib.Common.Deps)...)
+ get(p.properties.Multilib.Common)
}
if p.DepsCollectFirstTargetOnly {
- if len(get(p.properties.Multilib.First.Deps)) > 0 {
+ if has(p.properties.Multilib.First) {
ctx.PropertyErrorf("multilib.first.deps", "not supported. use \"deps\" instead")
}
for i, t := range ctx.MultiTargets() {
if t.Arch.ArchType == arch {
- ret = append(ret, get(p.properties.Multilib.Both.Deps)...)
+ get(p.properties.Multilib.Both)
if i == 0 {
- ret = append(ret, get(p.properties.Deps)...)
+ get(p.properties.DepsProperty)
}
}
}
} else {
- if len(get(p.properties.Multilib.Both.Deps)) > 0 {
+ if has(p.properties.Multilib.Both) {
ctx.PropertyErrorf("multilib.both.deps", "not supported. use \"deps\" instead")
}
for i, t := range ctx.MultiTargets() {
if t.Arch.ArchType == arch {
- ret = append(ret, get(p.properties.Deps)...)
+ get(p.properties.DepsProperty)
if i == 0 {
- ret = append(ret, get(p.properties.Multilib.First.Deps)...)
+ get(p.properties.Multilib.First)
}
}
}
@@ -306,17 +334,21 @@ func (p *PackagingBase) getDepsForArch(ctx BaseModuleContext, arch ArchType) []s
if ctx.Arch().ArchType == Common {
switch arch {
case Arm64:
- ret = append(ret, get(p.properties.Arch.Arm64.Deps)...)
+ get(p.properties.Arch.Arm64)
case Arm:
- ret = append(ret, get(p.properties.Arch.Arm.Deps)...)
+ get(p.properties.Arch.Arm)
case X86_64:
- ret = append(ret, get(p.properties.Arch.X86_64.Deps)...)
+ get(p.properties.Arch.X86_64)
case X86:
- ret = append(ret, get(p.properties.Arch.X86.Deps)...)
+ get(p.properties.Arch.X86)
}
}
- return FirstUniqueStrings(ret)
+ if len(highPriorityDeps) > 0 && !p.AllowHighPriorityDeps {
+ ctx.ModuleErrorf("Usage of high_priority_deps is not allowed for %s module type", ctx.ModuleType())
+ }
+
+ return FirstUniqueStrings(normalDeps), FirstUniqueStrings(highPriorityDeps)
}
func getSupportedTargets(ctx BaseModuleContext) []Target {
@@ -360,6 +392,8 @@ type PackagingItem interface {
IsPackagingItem() bool
}
+var _ PackagingItem = (*PackagingItemAlwaysDepTag)(nil)
+
// DepTag provides default implementation of PackagingItem interface.
// PackagingBase-derived modules can define their own dependency tag by embedding this, which
// can be passed to AddDeps() or AddDependencies().
@@ -371,31 +405,52 @@ func (PackagingItemAlwaysDepTag) IsPackagingItem() bool {
return true
}
+// highPriorityDepTag provides default implementation of HighPriorityPackagingItem interface.
+type highPriorityDepTag struct {
+ blueprint.DependencyTag
+}
+
// See PackageModule.AddDeps
func (p *PackagingBase) AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag) {
+ addDep := func(t Target, dep string, highPriority bool) {
+ if p.IgnoreMissingDependencies && !ctx.OtherModuleExists(dep) {
+ return
+ }
+ targetVariation := t.Variations()
+ sharedVariation := blueprint.Variation{
+ Mutator: "link",
+ Variation: "shared",
+ }
+ // If a shared variation exists, use that. Static variants do not provide any standalone files
+ // for packaging.
+ if ctx.OtherModuleFarDependencyVariantExists([]blueprint.Variation{sharedVariation}, dep) {
+ targetVariation = append(targetVariation, sharedVariation)
+ }
+ depTagToUse := depTag
+ if highPriority {
+ depTagToUse = highPriorityDepTag{depTag}
+ }
+
+ ctx.AddFarVariationDependencies(targetVariation, depTagToUse, dep)
+ }
for _, t := range getSupportedTargets(ctx) {
- for _, dep := range p.getDepsForArch(ctx, t.Arch.ArchType) {
- if p.IgnoreMissingDependencies && !ctx.OtherModuleExists(dep) {
- continue
- }
- targetVariation := t.Variations()
- sharedVariation := blueprint.Variation{
- Mutator: "link",
- Variation: "shared",
- }
- // If a shared variation exists, use that. Static variants do not provide any standalone files
- // for packaging.
- if ctx.OtherModuleFarDependencyVariantExists([]blueprint.Variation{sharedVariation}, dep) {
- targetVariation = append(targetVariation, sharedVariation)
- }
- ctx.AddFarVariationDependencies(targetVariation, depTag, dep)
+ normalDeps, highPriorityDeps := p.getDepsForArch(ctx, t.Arch.ArchType)
+ for _, dep := range normalDeps {
+ addDep(t, dep, false)
+ }
+ for _, dep := range highPriorityDeps {
+ addDep(t, dep, true)
}
}
}
func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter func(PackagingSpec) bool) map[string]PackagingSpec {
- // all packaging specs gathered from the dep.
- var all []PackagingSpec
+ // packaging specs gathered from the dep that are not high priorities.
+ var regularPriorities []PackagingSpec
+
+ // all packaging specs gathered from the high priority deps.
+ var highPriorities []PackagingSpec
+
// Name of the dependency which requested the packaging spec.
// If this dep is overridden, the packaging spec will not be installed via this dependency chain.
// (the packaging spec might still be installed if there are some other deps which depend on it).
@@ -420,7 +475,8 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter
}
ctx.VisitDirectDeps(func(child Module) {
- if pi, ok := ctx.OtherModuleDependencyTag(child).(PackagingItem); !ok || !pi.IsPackagingItem() {
+ depTag := ctx.OtherModuleDependencyTag(child)
+ if pi, ok := depTag.(PackagingItem); !ok || !pi.IsPackagingItem() {
return
}
for _, ps := range OtherModuleProviderOrDefault(
@@ -434,7 +490,13 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter
continue
}
}
- all = append(all, ps)
+
+ if _, ok := depTag.(highPriorityDepTag); ok {
+ highPriorities = append(highPriorities, ps)
+ } else {
+ regularPriorities = append(regularPriorities, ps)
+ }
+
depNames = append(depNames, child.Name())
if ps.overrides != nil {
overridden = append(overridden, *ps.overrides...)
@@ -442,21 +504,26 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter
}
})
- // all minus packaging specs that are overridden
- var filtered []PackagingSpec
- for index, ps := range all {
- if ps.owner != "" && InList(ps.owner, overridden) {
- continue
- }
- // The dependency which requested this packaging spec has been overridden.
- if InList(depNames[index], overridden) {
- continue
+ filterOverridden := func(input []PackagingSpec) []PackagingSpec {
+ // input minus packaging specs that are overridden
+ var filtered []PackagingSpec
+ for index, ps := range input {
+ if ps.owner != "" && InList(ps.owner, overridden) {
+ continue
+ }
+ // The dependency which requested this packaging spec has been overridden.
+ if InList(depNames[index], overridden) {
+ continue
+ }
+ filtered = append(filtered, ps)
}
- filtered = append(filtered, ps)
+ return filtered
}
+ filteredRegularPriority := filterOverridden(regularPriorities)
+
m := make(map[string]PackagingSpec)
- for _, ps := range filtered {
+ for _, ps := range filteredRegularPriority {
dstPath := ps.relPathInPackage
if existingPs, ok := m[dstPath]; ok {
if !existingPs.Equals(&ps) {
@@ -466,6 +533,21 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter
}
m[dstPath] = ps
}
+
+ filteredHighPriority := filterOverridden(highPriorities)
+ highPriorityPs := make(map[string]PackagingSpec)
+ for _, ps := range filteredHighPriority {
+ dstPath := ps.relPathInPackage
+ if existingPs, ok := highPriorityPs[dstPath]; ok {
+ if !existingPs.Equals(&ps) {
+ ctx.ModuleErrorf("packaging conflict at %v:\n%v\n%v", dstPath, existingPs, ps)
+ }
+ continue
+ }
+ highPriorityPs[dstPath] = ps
+ m[dstPath] = ps
+ }
+
return m
}