Don't use APEX stubs between internal libs in the same APEX when
building test_for modules. This extends the current approach where test modules always depend on the platform variants of the APEX libs, and only skips the stubs on them. It still has the limitation that the internal libs must have the exact same apex_available lists. Also some improvement of the test accuracy in TestTestFor. Test: m libartagent-target with http://r.android.com/q/topic:libdexfile-noext applied Bug: 183217299 Change-Id: I2118b8a22c887077867a3ddbbe73437b4a29a6ad
This commit is contained in:
parent
1461c4dbca
commit
4e6c269de5
|
@ -453,6 +453,23 @@ func (m *ApexModuleBase) checkApexAvailableProperty(mctx BaseModuleContext) {
|
|||
}
|
||||
}
|
||||
|
||||
// AvailableToSameApexes returns true if the two modules are apex_available to
|
||||
// exactly the same set of APEXes (and platform), i.e. if their apex_available
|
||||
// properties have the same elements.
|
||||
func AvailableToSameApexes(mod1, mod2 ApexModule) bool {
|
||||
mod1ApexAvail := SortedUniqueStrings(mod1.apexModuleBase().ApexProperties.Apex_available)
|
||||
mod2ApexAvail := SortedUniqueStrings(mod2.apexModuleBase().ApexProperties.Apex_available)
|
||||
if len(mod1ApexAvail) != len(mod2ApexAvail) {
|
||||
return false
|
||||
}
|
||||
for i, v := range mod1ApexAvail {
|
||||
if v != mod2ApexAvail[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type byApexName []ApexInfo
|
||||
|
||||
func (a byApexName) Len() int { return len(a) }
|
||||
|
|
|
@ -6859,21 +6859,77 @@ func TestTestFor(t *testing.T) {
|
|||
}
|
||||
`)
|
||||
|
||||
// the test 'mytest' is a test for the apex, therefore is linked to the
|
||||
ensureLinkedLibIs := func(mod, variant, linkedLib, expectedVariant string) {
|
||||
ldFlags := strings.Split(ctx.ModuleForTests(mod, variant).Rule("ld").RelativeToTop().Args["libFlags"], " ")
|
||||
mylibLdFlags := android.FilterListPred(ldFlags, func(s string) bool { return strings.HasPrefix(s, linkedLib) })
|
||||
android.AssertArrayString(t, "unexpected "+linkedLib+" link library for "+mod, []string{linkedLib + expectedVariant}, mylibLdFlags)
|
||||
}
|
||||
|
||||
// These modules are tests for the apex, therefore are linked to the
|
||||
// actual implementation of mylib instead of its stub.
|
||||
ldFlags := ctx.ModuleForTests("mytest", "android_arm64_armv8-a").Rule("ld").Args["libFlags"]
|
||||
ensureContains(t, ldFlags, "mylib/android_arm64_armv8-a_shared/mylib.so")
|
||||
ensureNotContains(t, ldFlags, "mylib/android_arm64_armv8-a_shared_1/mylib.so")
|
||||
ensureLinkedLibIs("mytest", "android_arm64_armv8-a", "out/soong/.intermediates/mylib/", "android_arm64_armv8-a_shared/mylib.so")
|
||||
ensureLinkedLibIs("mytestlib", "android_arm64_armv8-a_shared", "out/soong/.intermediates/mylib/", "android_arm64_armv8-a_shared/mylib.so")
|
||||
ensureLinkedLibIs("mybench", "android_arm64_armv8-a", "out/soong/.intermediates/mylib/", "android_arm64_armv8-a_shared/mylib.so")
|
||||
}
|
||||
|
||||
// The same should be true for cc_library
|
||||
ldFlags = ctx.ModuleForTests("mytestlib", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"]
|
||||
ensureContains(t, ldFlags, "mylib/android_arm64_armv8-a_shared/mylib.so")
|
||||
ensureNotContains(t, ldFlags, "mylib/android_arm64_armv8-a_shared_1/mylib.so")
|
||||
func TestIndirectTestFor(t *testing.T) {
|
||||
ctx := testApex(t, `
|
||||
apex {
|
||||
name: "myapex",
|
||||
key: "myapex.key",
|
||||
native_shared_libs: ["mylib", "myprivlib"],
|
||||
updatable: false,
|
||||
}
|
||||
|
||||
// ... and for cc_benchmark
|
||||
ldFlags = ctx.ModuleForTests("mybench", "android_arm64_armv8-a").Rule("ld").Args["libFlags"]
|
||||
ensureContains(t, ldFlags, "mylib/android_arm64_armv8-a_shared/mylib.so")
|
||||
ensureNotContains(t, ldFlags, "mylib/android_arm64_armv8-a_shared_1/mylib.so")
|
||||
apex_key {
|
||||
name: "myapex.key",
|
||||
public_key: "testkey.avbpubkey",
|
||||
private_key: "testkey.pem",
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "mylib",
|
||||
srcs: ["mylib.cpp"],
|
||||
system_shared_libs: [],
|
||||
stl: "none",
|
||||
stubs: {
|
||||
versions: ["1"],
|
||||
},
|
||||
apex_available: ["myapex"],
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "myprivlib",
|
||||
srcs: ["mylib.cpp"],
|
||||
system_shared_libs: [],
|
||||
stl: "none",
|
||||
shared_libs: ["mylib"],
|
||||
apex_available: ["myapex"],
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "mytestlib",
|
||||
srcs: ["mylib.cpp"],
|
||||
system_shared_libs: [],
|
||||
shared_libs: ["myprivlib"],
|
||||
stl: "none",
|
||||
test_for: ["myapex"],
|
||||
}
|
||||
`)
|
||||
|
||||
ensureLinkedLibIs := func(mod, variant, linkedLib, expectedVariant string) {
|
||||
ldFlags := strings.Split(ctx.ModuleForTests(mod, variant).Rule("ld").RelativeToTop().Args["libFlags"], " ")
|
||||
mylibLdFlags := android.FilterListPred(ldFlags, func(s string) bool { return strings.HasPrefix(s, linkedLib) })
|
||||
android.AssertArrayString(t, "unexpected "+linkedLib+" link library for "+mod, []string{linkedLib + expectedVariant}, mylibLdFlags)
|
||||
}
|
||||
|
||||
// The platform variant of mytestlib links to the platform variant of the
|
||||
// internal myprivlib.
|
||||
ensureLinkedLibIs("mytestlib", "android_arm64_armv8-a_shared", "out/soong/.intermediates/myprivlib/", "android_arm64_armv8-a_shared/myprivlib.so")
|
||||
|
||||
// The platform variant of myprivlib links to the platform variant of mylib
|
||||
// and bypasses its stubs.
|
||||
ensureLinkedLibIs("myprivlib", "android_arm64_armv8-a_shared", "out/soong/.intermediates/mylib/", "android_arm64_armv8-a_shared/mylib.so")
|
||||
}
|
||||
|
||||
// TODO(jungjw): Move this to proptools
|
||||
|
|
31
cc/cc.go
31
cc/cc.go
|
@ -2631,14 +2631,31 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||
// However, for host, ramdisk, vendor_ramdisk, recovery or bootstrap modules,
|
||||
// always link to non-stub variant
|
||||
useStubs = dep.(android.ApexModule).NotInPlatform() && !c.bootstrap()
|
||||
// Another exception: if this module is bundled with an APEX, then
|
||||
// it is linked with the non-stub variant of a module in the APEX
|
||||
// as if this is part of the APEX.
|
||||
testFor := ctx.Provider(android.ApexTestForInfoProvider).(android.ApexTestForInfo)
|
||||
for _, apexContents := range testFor.ApexContents {
|
||||
if apexContents.DirectlyInApex(depName) {
|
||||
if useStubs {
|
||||
// Another exception: if this module is a test for an APEX, then
|
||||
// it is linked with the non-stub variant of a module in the APEX
|
||||
// as if this is part of the APEX.
|
||||
testFor := ctx.Provider(android.ApexTestForInfoProvider).(android.ApexTestForInfo)
|
||||
for _, apexContents := range testFor.ApexContents {
|
||||
if apexContents.DirectlyInApex(depName) {
|
||||
useStubs = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if useStubs {
|
||||
// Yet another exception: If this module and the dependency are
|
||||
// available to the same APEXes then skip stubs between their
|
||||
// platform variants. This complements the test_for case above,
|
||||
// which avoids the stubs on a direct APEX library dependency, by
|
||||
// avoiding stubs for indirect test dependencies as well.
|
||||
//
|
||||
// TODO(b/183882457): This doesn't work if the two libraries have
|
||||
// only partially overlapping apex_available. For that test_for
|
||||
// modules would need to be split into APEX variants and resolved
|
||||
// separately for each APEX they have access to.
|
||||
if android.AvailableToSameApexes(c, dep.(android.ApexModule)) {
|
||||
useStubs = false
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue