diff options
Diffstat (limited to 'android/packaging.go')
| -rw-r--r-- | android/packaging.go | 216 |
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 } |