Treat <x> and <x>_compressed prebuilt APEXes as being equivalent
(cherry picked from commit 1aa50564c7
)
When extracting dex files from prebuilt APEXes the build fails if it
finds two or more prebuilt APEXes that could provide the dex files.
This change treats <x> and <x>_compressed APEXes as being the same
and always selects the uncompressed APEX.
Bug: 235284603
Test: m nothing
# Added TestDuplicateButEquivalentDeapexersFromPrebuiltApexes
# Failed without this change, works with it.
Merged-In: I805cb9dfa9f590c91585d75c4f4586b212b73d41
Change-Id: I805cb9dfa9f590c91585d75c4f4586b212b73d41
This commit is contained in:
@@ -15,6 +15,8 @@
|
|||||||
package android
|
package android
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/google/blueprint"
|
"github.com/google/blueprint"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -148,12 +150,19 @@ type RequiresFilesFromPrebuiltApexTag interface {
|
|||||||
func FindDeapexerProviderForModule(ctx ModuleContext) *DeapexerInfo {
|
func FindDeapexerProviderForModule(ctx ModuleContext) *DeapexerInfo {
|
||||||
var di *DeapexerInfo
|
var di *DeapexerInfo
|
||||||
ctx.VisitDirectDepsWithTag(DeapexerTag, func(m Module) {
|
ctx.VisitDirectDepsWithTag(DeapexerTag, func(m Module) {
|
||||||
p := ctx.OtherModuleProvider(m, DeapexerProvider).(DeapexerInfo)
|
c := ctx.OtherModuleProvider(m, DeapexerProvider).(DeapexerInfo)
|
||||||
|
p := &c
|
||||||
if di != nil {
|
if di != nil {
|
||||||
|
// If two DeapexerInfo providers have been found then check if they are
|
||||||
|
// equivalent. If they are then use the selected one, otherwise fail.
|
||||||
|
if selected := equivalentDeapexerInfoProviders(di, p); selected != nil {
|
||||||
|
di = selected
|
||||||
|
return
|
||||||
|
}
|
||||||
ctx.ModuleErrorf("Multiple installable prebuilt APEXes provide ambiguous deapexers: %s and %s",
|
ctx.ModuleErrorf("Multiple installable prebuilt APEXes provide ambiguous deapexers: %s and %s",
|
||||||
di.ApexModuleName(), p.ApexModuleName())
|
di.ApexModuleName(), p.ApexModuleName())
|
||||||
}
|
}
|
||||||
di = &p
|
di = p
|
||||||
})
|
})
|
||||||
if di != nil {
|
if di != nil {
|
||||||
return di
|
return di
|
||||||
@@ -162,3 +171,33 @@ func FindDeapexerProviderForModule(ctx ModuleContext) *DeapexerInfo {
|
|||||||
ctx.ModuleErrorf("No prebuilt APEX provides a deapexer module for APEX variant %s", ai.ApexVariationName)
|
ctx.ModuleErrorf("No prebuilt APEX provides a deapexer module for APEX variant %s", ai.ApexVariationName)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// removeCompressedApexSuffix removes the _compressed suffix from the name if present.
|
||||||
|
func removeCompressedApexSuffix(name string) string {
|
||||||
|
return strings.TrimSuffix(name, "_compressed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// equivalentDeapexerInfoProviders checks to make sure that the two DeapexerInfo structures are
|
||||||
|
// equivalent.
|
||||||
|
//
|
||||||
|
// At the moment <x> and <x>_compressed APEXes are treated as being equivalent.
|
||||||
|
//
|
||||||
|
// If they are not equivalent then this returns nil, otherwise, this returns the DeapexerInfo that
|
||||||
|
// should be used by the build, which is always the uncompressed one. That ensures that the behavior
|
||||||
|
// of the build is not dependent on which prebuilt APEX is visited first.
|
||||||
|
func equivalentDeapexerInfoProviders(p1 *DeapexerInfo, p2 *DeapexerInfo) *DeapexerInfo {
|
||||||
|
n1 := removeCompressedApexSuffix(p1.ApexModuleName())
|
||||||
|
n2 := removeCompressedApexSuffix(p2.ApexModuleName())
|
||||||
|
|
||||||
|
// If the names don't match then they are not equivalent.
|
||||||
|
if n1 != n2 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select the uncompressed APEX.
|
||||||
|
if n1 == removeCompressedApexSuffix(n1) {
|
||||||
|
return p1
|
||||||
|
} else {
|
||||||
|
return p2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -7440,7 +7440,7 @@ func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, preparer android.F
|
|||||||
return result.TestContext
|
return result.TestContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDuplicateDeapexeresFromPrebuiltApexes(t *testing.T) {
|
func TestDuplicateDeapexersFromPrebuiltApexes(t *testing.T) {
|
||||||
preparers := android.GroupFixturePreparers(
|
preparers := android.GroupFixturePreparers(
|
||||||
java.PrepareForTestWithJavaDefaultModules,
|
java.PrepareForTestWithJavaDefaultModules,
|
||||||
PrepareForTestWithApexBuildComponents,
|
PrepareForTestWithApexBuildComponents,
|
||||||
@@ -7509,6 +7509,107 @@ func TestDuplicateDeapexeresFromPrebuiltApexes(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDuplicateButEquivalentDeapexersFromPrebuiltApexes(t *testing.T) {
|
||||||
|
preparers := android.GroupFixturePreparers(
|
||||||
|
java.PrepareForTestWithJavaDefaultModules,
|
||||||
|
PrepareForTestWithApexBuildComponents,
|
||||||
|
)
|
||||||
|
|
||||||
|
bpBase := `
|
||||||
|
apex_set {
|
||||||
|
name: "com.android.myapex",
|
||||||
|
installable: true,
|
||||||
|
exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
|
||||||
|
set: "myapex.apks",
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_set {
|
||||||
|
name: "com.android.myapex_compressed",
|
||||||
|
apex_name: "com.android.myapex",
|
||||||
|
installable: true,
|
||||||
|
exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
|
||||||
|
set: "myapex_compressed.apks",
|
||||||
|
}
|
||||||
|
|
||||||
|
prebuilt_bootclasspath_fragment {
|
||||||
|
name: "my-bootclasspath-fragment",
|
||||||
|
apex_available: [
|
||||||
|
"com.android.myapex",
|
||||||
|
"com.android.myapex_compressed",
|
||||||
|
],
|
||||||
|
hidden_api: {
|
||||||
|
annotation_flags: "annotation-flags.csv",
|
||||||
|
metadata: "metadata.csv",
|
||||||
|
index: "index.csv",
|
||||||
|
signature_patterns: "signature_patterns.csv",
|
||||||
|
},
|
||||||
|
%s
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
t.Run("java_import", func(t *testing.T) {
|
||||||
|
result := preparers.RunTestWithBp(t,
|
||||||
|
fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+`
|
||||||
|
java_import {
|
||||||
|
name: "libfoo",
|
||||||
|
jars: ["libfoo.jar"],
|
||||||
|
apex_available: [
|
||||||
|
"com.android.myapex",
|
||||||
|
"com.android.myapex_compressed",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
module := result.Module("libfoo", "android_common_com.android.myapex")
|
||||||
|
usesLibraryDep := module.(java.UsesLibraryDependency)
|
||||||
|
android.AssertPathRelativeToTopEquals(t, "dex jar path",
|
||||||
|
"out/soong/.intermediates/com.android.myapex.deapexer/android_common/deapexer/javalib/libfoo.jar",
|
||||||
|
usesLibraryDep.DexJarBuildPath().Path())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("java_sdk_library_import", func(t *testing.T) {
|
||||||
|
result := preparers.RunTestWithBp(t,
|
||||||
|
fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+`
|
||||||
|
java_sdk_library_import {
|
||||||
|
name: "libfoo",
|
||||||
|
public: {
|
||||||
|
jars: ["libbar.jar"],
|
||||||
|
},
|
||||||
|
apex_available: [
|
||||||
|
"com.android.myapex",
|
||||||
|
"com.android.myapex_compressed",
|
||||||
|
],
|
||||||
|
compile_dex: true,
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
module := result.Module("libfoo", "android_common_com.android.myapex")
|
||||||
|
usesLibraryDep := module.(java.UsesLibraryDependency)
|
||||||
|
android.AssertPathRelativeToTopEquals(t, "dex jar path",
|
||||||
|
"out/soong/.intermediates/com.android.myapex.deapexer/android_common/deapexer/javalib/libfoo.jar",
|
||||||
|
usesLibraryDep.DexJarBuildPath().Path())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("prebuilt_bootclasspath_fragment", func(t *testing.T) {
|
||||||
|
_ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `
|
||||||
|
image_name: "art",
|
||||||
|
contents: ["libfoo"],
|
||||||
|
`)+`
|
||||||
|
java_sdk_library_import {
|
||||||
|
name: "libfoo",
|
||||||
|
public: {
|
||||||
|
jars: ["libbar.jar"],
|
||||||
|
},
|
||||||
|
apex_available: [
|
||||||
|
"com.android.myapex",
|
||||||
|
"com.android.myapex_compressed",
|
||||||
|
],
|
||||||
|
compile_dex: true,
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestUpdatable_should_set_min_sdk_version(t *testing.T) {
|
func TestUpdatable_should_set_min_sdk_version(t *testing.T) {
|
||||||
testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
|
testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
|
||||||
apex {
|
apex {
|
||||||
|
Reference in New Issue
Block a user