Add multilib.prefer32.deps to packaging base
The property is used to prefer the 32-bit variant of a dep over the
64-bit variant. If 64-bit variant is the only available one, it is
depended on.
This will be used to include 32-bit preferred modules like drmserver and
mediaserver in filesystem modules.
Bug: N/A
Test: go test ./... under soong/android
Change-Id: Ic7185eb2044c9987f8d1e9b6cf7f0dbd235cf04c
diff --git a/android/packaging.go b/android/packaging.go
index a2b8755..ae412e1 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -155,11 +155,12 @@
}
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"`
+ 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 {
@@ -198,8 +199,20 @@
ret = append(ret, get(p.properties.Deps)...)
} else if arch.Multilib == "lib32" {
ret = append(ret, get(p.properties.Multilib.Lib32.Deps)...)
+ // multilib.prefer32.deps are added for lib32 only when they support 32-bit arch
+ for _, dep := range get(p.properties.Multilib.Prefer32.Deps) {
+ if checkIfOtherModuleSupportsLib32(ctx, dep) {
+ ret = append(ret, dep)
+ }
+ }
} else if arch.Multilib == "lib64" {
ret = append(ret, get(p.properties.Multilib.Lib64.Deps)...)
+ // 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) {
+ if !checkIfOtherModuleSupportsLib32(ctx, dep) {
+ ret = append(ret, dep)
+ }
+ }
} else if arch == Common {
ret = append(ret, get(p.properties.Multilib.Common.Deps)...)
}
@@ -246,7 +259,7 @@
return FirstUniqueStrings(ret)
}
-func (p *PackagingBase) getSupportedTargets(ctx BaseModuleContext) []Target {
+func getSupportedTargets(ctx BaseModuleContext) []Target {
var ret []Target
// The current and the common OS targets are always supported
ret = append(ret, ctx.Target())
@@ -258,6 +271,28 @@
return ret
}
+// getLib32Target returns the 32-bit target from the list of targets this module supports. If this
+// module doesn't support 32-bit target, nil is returned.
+func getLib32Target(ctx BaseModuleContext) *Target {
+ for _, t := range getSupportedTargets(ctx) {
+ if t.Arch.ArchType.Multilib == "lib32" {
+ return &t
+ }
+ }
+ return nil
+}
+
+// checkIfOtherModuleSUpportsLib32 returns true if 32-bit variant of dep exists.
+func checkIfOtherModuleSupportsLib32(ctx BaseModuleContext, dep string) bool {
+ t := getLib32Target(ctx)
+ if t == nil {
+ // This packaging module doesn't support 32bit. No point of checking if dep supports 32-bit
+ // or not.
+ return false
+ }
+ return ctx.OtherModuleFarDependencyVariantExists(t.Variations(), dep)
+}
+
// PackagingItem is a marker interface for dependency tags.
// Direct dependencies with a tag implementing PackagingItem are packaged in CopyDepsToZip().
type PackagingItem interface {
@@ -278,7 +313,7 @@
// See PackageModule.AddDeps
func (p *PackagingBase) AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag) {
- for _, t := range p.getSupportedTargets(ctx) {
+ for _, t := range getSupportedTargets(ctx) {
for _, dep := range p.getDepsForArch(ctx, t.Arch.ArchType) {
if p.IgnoreMissingDependencies && !ctx.OtherModuleExists(dep) {
continue
@@ -292,7 +327,7 @@
m := make(map[string]PackagingSpec)
var arches []ArchType
- for _, target := range p.getSupportedTargets(ctx) {
+ for _, target := range getSupportedTargets(ctx) {
arches = append(arches, target.Arch.ArchType)
}
diff --git a/android/packaging_test.go b/android/packaging_test.go
index 0570ec5..89df8ef 100644
--- a/android/packaging_test.go
+++ b/android/packaging_test.go
@@ -15,6 +15,8 @@
package android
import (
+ "fmt"
+ "strings"
"testing"
"github.com/google/blueprint"
@@ -584,3 +586,69 @@
runPackagingTest(t, config, bp, tc.expected)
}
}
+
+func TestPrefer32Deps(t *testing.T) {
+ bpTemplate := `
+ component {
+ name: "foo",
+ compile_multilib: "both", // not needed but for clarity
+ }
+
+ component {
+ name: "foo_32only",
+ compile_multilib: "prefer32",
+ }
+
+ component {
+ name: "foo_64only",
+ compile_multilib: "64",
+ }
+
+ package_module {
+ name: "package",
+ compile_multilib: "%COMPILE_MULTILIB%",
+ multilib: {
+ prefer32: {
+ deps: %DEPS%,
+ },
+ },
+ }
+ `
+
+ testcases := []struct {
+ compileMultilib string
+ deps []string
+ expected []string
+ }{
+ {
+ compileMultilib: "first",
+ deps: []string{"foo", "foo_64only"},
+ expected: []string{"lib64/foo", "lib64/foo_64only"},
+ },
+ {
+ compileMultilib: "64",
+ deps: []string{"foo", "foo_64only"},
+ expected: []string{"lib64/foo", "lib64/foo_64only"},
+ },
+ {
+ compileMultilib: "32",
+ deps: []string{"foo", "foo_32only"},
+ expected: []string{"lib32/foo", "lib32/foo_32only"},
+ },
+ {
+ compileMultilib: "both",
+ deps: []string{"foo", "foo_32only", "foo_64only"},
+ expected: []string{"lib32/foo", "lib32/foo_32only", "lib64/foo_64only"},
+ },
+ }
+ for _, tc := range testcases {
+ config := testConfig{
+ multiTarget: true,
+ depsCollectFirstTargetOnly: true,
+ }
+ bp := strings.Replace(bpTemplate, "%COMPILE_MULTILIB%", tc.compileMultilib, -1)
+ bp = strings.Replace(bp, "%DEPS%", `["`+strings.Join(tc.deps, `", "`)+`"]`, -1)
+ fmt.Printf("bp = %s\n", bp)
+ runPackagingTest(t, config, bp, tc.expected)
+ }
+}