Revert "Revert "Enforce min_sdk_version of apex(use_vendor:true)""

This reverts commit bacf34d986.

Reason for revert: reland with fix

Change-Id: Ia03f2808353f5640597ae7ecbf2e06fc903c6977
This commit is contained in:
Jooyung Han
2020-03-21 14:21:46 +00:00
parent b1eb4d4a94
commit 61b66e9b34
6 changed files with 189 additions and 63 deletions

View File

@@ -874,13 +874,35 @@ func TestApexWithRuntimeLibsDependency(t *testing.T) {
} }
func TestApexDependencyToLLNDK(t *testing.T) { func TestApexDependsOnLLNDKTransitively(t *testing.T) {
testcases := []struct {
name string
minSdkVersion string
shouldLink string
shouldNotLink []string
}{
{
name: "should link to test latest",
minSdkVersion: "current",
shouldLink: "30",
shouldNotLink: []string{"29"},
},
{
name: "should link to llndk#29",
minSdkVersion: "29",
shouldLink: "29",
shouldNotLink: []string{"30"},
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
ctx, _ := testApex(t, ` ctx, _ := testApex(t, `
apex { apex {
name: "myapex", name: "myapex",
key: "myapex.key", key: "myapex.key",
use_vendor: true, use_vendor: true,
native_shared_libs: ["mylib"], native_shared_libs: ["mylib"],
min_sdk_version: "`+tc.minSdkVersion+`",
} }
apex_key { apex_key {
@@ -904,6 +926,7 @@ func TestApexDependencyToLLNDK(t *testing.T) {
srcs: ["mylib.cpp"], srcs: ["mylib.cpp"],
system_shared_libs: [], system_shared_libs: [],
stl: "none", stl: "none",
stubs: { versions: ["29","30"] },
} }
llndk_library { llndk_library {
@@ -912,20 +935,28 @@ func TestApexDependencyToLLNDK(t *testing.T) {
} }
`, func(fs map[string][]byte, config android.Config) { `, func(fs map[string][]byte, config android.Config) {
setUseVendorWhitelistForTest(config, []string{"myapex"}) setUseVendorWhitelistForTest(config, []string{"myapex"})
}) }, withUnbundledBuild)
apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
// Ensure that LLNDK dep is not included // Ensure that LLNDK dep is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so") ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
"lib64/mylib.so",
apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule") })
ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
// Ensure that LLNDK dep is required // Ensure that LLNDK dep is required
apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libbar.so") ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libbar.so")
mylibLdFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
ensureContains(t, mylibLdFlags, "libbar.llndk/android_vendor.VER_arm64_armv8-a_shared_"+tc.shouldLink+"/libbar.so")
for _, ver := range tc.shouldNotLink {
ensureNotContains(t, mylibLdFlags, "libbar.llndk/android_vendor.VER_arm64_armv8-a_shared_"+ver+"/libbar.so")
}
mylibCFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
ensureContains(t, mylibCFlags, "__LIBBAR_API__="+tc.shouldLink)
})
}
} }
func TestApexWithSystemLibsStubs(t *testing.T) { func TestApexWithSystemLibsStubs(t *testing.T) {
@@ -1255,10 +1286,6 @@ func TestQTargetApexUseStaticUnwinder(t *testing.T) {
// note that platform variant is not. // note that platform variant is not.
cm = ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared").Module().(*cc.Module) cm = ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared").Module().(*cc.Module)
ensureListNotContains(t, cm.Properties.AndroidMkStaticLibs, "libgcc_stripped") ensureListNotContains(t, cm.Properties.AndroidMkStaticLibs, "libgcc_stripped")
libFlags := ctx.ModuleForTests("libx", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
ensureContains(t, libFlags, "android_arm64_armv8-a_shared_myapex/libc++.so")
ensureContains(t, libFlags, "android_arm64_armv8-a_shared_29/libc.so") // min_sdk_version applied
} }
func TestInvalidMinSdkVersion(t *testing.T) { func TestInvalidMinSdkVersion(t *testing.T) {

View File

@@ -622,6 +622,10 @@ func (c *Module) SetBuildStubs() {
c.Properties.PreventInstall = true c.Properties.PreventInstall = true
return return
} }
if _, ok := c.linker.(*llndkStubDecorator); ok {
c.Properties.HideFromMake = true
return
}
} }
panic(fmt.Errorf("SetBuildStubs called on non-library module: %q", c.BaseModuleName())) panic(fmt.Errorf("SetBuildStubs called on non-library module: %q", c.BaseModuleName()))
} }
@@ -641,6 +645,10 @@ func (c *Module) SetStubsVersions(version string) {
library.MutatedProperties.StubsVersion = version library.MutatedProperties.StubsVersion = version
return return
} }
if llndk, ok := c.linker.(*llndkStubDecorator); ok {
llndk.libraryDecorator.MutatedProperties.StubsVersion = version
return
}
} }
panic(fmt.Errorf("SetStubsVersions called on non-library module: %q", c.BaseModuleName())) panic(fmt.Errorf("SetStubsVersions called on non-library module: %q", c.BaseModuleName()))
} }
@@ -650,6 +658,9 @@ func (c *Module) StubsVersion() string {
if library, ok := c.linker.(*libraryDecorator); ok { if library, ok := c.linker.(*libraryDecorator); ok {
return library.MutatedProperties.StubsVersion return library.MutatedProperties.StubsVersion
} }
if llndk, ok := c.linker.(*llndkStubDecorator); ok {
return llndk.libraryDecorator.MutatedProperties.StubsVersion
}
} }
panic(fmt.Errorf("StubsVersion called on non-library module: %q", c.BaseModuleName())) panic(fmt.Errorf("StubsVersion called on non-library module: %q", c.BaseModuleName()))
} }
@@ -1851,7 +1862,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
addSharedLibDependencies := func(depTag DependencyTag, name string, version string) { addSharedLibDependencies := func(depTag DependencyTag, name string, version string) {
var variations []blueprint.Variation var variations []blueprint.Variation
variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"}) variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"})
versionVariantAvail := !ctx.useVndk() && !c.InRecovery() && !c.InRamdisk() versionVariantAvail := !c.InRecovery() && !c.InRamdisk()
if version != "" && versionVariantAvail { if version != "" && versionVariantAvail {
// Version is explicitly specified. i.e. libFoo#30 // Version is explicitly specified. i.e. libFoo#30
variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version}) variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version})
@@ -2186,13 +2197,17 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
if depTag == android.ProtoPluginDepTag { if depTag == android.ProtoPluginDepTag {
return return
} }
if depTag == llndkImplDep {
return
}
if dep.Target().Os != ctx.Os() { if dep.Target().Os != ctx.Os() {
ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName) ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
return return
} }
if dep.Target().Arch.ArchType != ctx.Arch().ArchType { if dep.Target().Arch.ArchType != ctx.Arch().ArchType {
ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName) ctx.ModuleErrorf("Arch mismatch between %q(%v) and %q(%v)",
ctx.ModuleName(), ctx.Arch().ArchType, depName, dep.Target().Arch.ArchType)
return return
} }
@@ -2287,6 +2302,27 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
return // stop processing this dep return // stop processing this dep
} }
} }
if c.UseVndk() {
if m, ok := ccDep.(*Module); ok && m.IsStubs() { // LLNDK
// by default, use current version of LLNDK
versionToUse := ""
versions := stubsVersionsFor(ctx.Config())[depName]
if c.ApexName() != "" && len(versions) > 0 {
// if this is for use_vendor apex && dep has stubsVersions
// apply the same rule of apex sdk enforcement to choose right version
var err error
useLatest := c.ShouldSupportAndroid10() && !ctx.Config().UnbundledBuild()
versionToUse, err = c.ChooseSdkVersion(versions, useLatest)
if err != nil {
ctx.OtherModuleErrorf(dep, err.Error())
return
}
}
if versionToUse != ccDep.StubsVersion() {
return
}
}
}
depPaths.IncludeDirs = append(depPaths.IncludeDirs, ccDep.IncludeDirs()...) depPaths.IncludeDirs = append(depPaths.IncludeDirs, ccDep.IncludeDirs()...)

View File

@@ -2398,6 +2398,34 @@ func checkEquals(t *testing.T, message string, expected, actual interface{}) {
} }
} }
func TestLlndkLibrary(t *testing.T) {
ctx := testCc(t, `
cc_library {
name: "libllndk",
stubs: { versions: ["1", "2"] },
}
llndk_library {
name: "libllndk",
}
`)
actual := ctx.ModuleVariantsForTests("libllndk.llndk")
expected := []string{
"android_vendor.VER_arm64_armv8-a_shared",
"android_vendor.VER_arm64_armv8-a_shared_1",
"android_vendor.VER_arm64_armv8-a_shared_2",
"android_vendor.VER_arm_armv7-a-neon_shared",
"android_vendor.VER_arm_armv7-a-neon_shared_1",
"android_vendor.VER_arm_armv7-a-neon_shared_2",
}
checkEquals(t, "variants for llndk stubs", expected, actual)
params := ctx.ModuleForTests("libllndk.llndk", "android_vendor.VER_arm_armv7-a-neon_shared").Description("generate stub")
checkEquals(t, "use VNDK version for default stubs", "current", params.Args["apiLevel"])
params = ctx.ModuleForTests("libllndk.llndk", "android_vendor.VER_arm_armv7-a-neon_shared_1").Description("generate stub")
checkEquals(t, "override apiLevel for versioned stubs", "1", params.Args["apiLevel"])
}
func TestLlndkHeaders(t *testing.T) { func TestLlndkHeaders(t *testing.T) {
ctx := testCc(t, ` ctx := testCc(t, `
llndk_headers { llndk_headers {

View File

@@ -1487,6 +1487,19 @@ func checkVersions(ctx android.BaseModuleContext, versions []string) {
} }
} }
func createVersionVariations(mctx android.BottomUpMutatorContext, versions []string) {
// "" is for the non-stubs variant
versions = append([]string{""}, versions...)
modules := mctx.CreateVariations(versions...)
for i, m := range modules {
if versions[i] != "" {
m.(LinkableInterface).SetBuildStubs()
m.(LinkableInterface).SetStubsVersions(versions[i])
}
}
}
// Version mutator splits a module into the mandatory non-stubs variant // Version mutator splits a module into the mandatory non-stubs variant
// (which is unnamed) and zero or more stubs variants. // (which is unnamed) and zero or more stubs variants.
func VersionMutator(mctx android.BottomUpMutatorContext) { func VersionMutator(mctx android.BottomUpMutatorContext) {
@@ -1498,24 +1511,30 @@ func VersionMutator(mctx android.BottomUpMutatorContext) {
return return
} }
// save the list of versions for later use
stubsVersionsLock.Lock() stubsVersionsLock.Lock()
defer stubsVersionsLock.Unlock() defer stubsVersionsLock.Unlock()
// save the list of versions for later use
stubsVersionsFor(mctx.Config())[mctx.ModuleName()] = versions stubsVersionsFor(mctx.Config())[mctx.ModuleName()] = versions
// "" is for the non-stubs variant createVersionVariations(mctx, versions)
versions = append([]string{""}, versions...) return
}
modules := mctx.CreateVariations(versions...) if c, ok := library.(*Module); ok && c.IsStubs() {
for i, m := range modules { stubsVersionsLock.Lock()
if versions[i] != "" { defer stubsVersionsLock.Unlock()
m.(LinkableInterface).SetBuildStubs() // For LLNDK llndk_library, we borrow vstubs.ersions from its implementation library.
m.(LinkableInterface).SetStubsVersions(versions[i]) // Since llndk_library has dependency to its implementation library,
// we can safely access stubsVersionsFor() with its baseModuleName.
versions := stubsVersionsFor(mctx.Config())[c.BaseModuleName()]
// save the list of versions for later use
stubsVersionsFor(mctx.Config())[mctx.ModuleName()] = versions
createVersionVariations(mctx, versions)
return
} }
}
} else {
mctx.CreateVariations("") mctx.CreateVariations("")
}
return return
} }
if genrule, ok := mctx.Module().(*genrule.Module); ok { if genrule, ok := mctx.Module().(*genrule.Module); ok {

View File

@@ -19,8 +19,14 @@ import (
"strings" "strings"
"android/soong/android" "android/soong/android"
"github.com/google/blueprint"
) )
var llndkImplDep = struct {
blueprint.DependencyTag
}{}
var ( var (
llndkLibrarySuffix = ".llndk" llndkLibrarySuffix = ".llndk"
llndkHeadersSuffix = ".llndk" llndkHeadersSuffix = ".llndk"
@@ -81,6 +87,9 @@ func (stub *llndkStubDecorator) compile(ctx ModuleContext, flags Flags, deps Pat
// For non-enforcing devices, vndkVer is empty. Use "current" in that case, too. // For non-enforcing devices, vndkVer is empty. Use "current" in that case, too.
vndkVer = "current" vndkVer = "current"
} }
if stub.stubsVersion() != "" {
vndkVer = stub.stubsVersion()
}
objs, versionScript := compileStubLibrary(ctx, flags, String(stub.Properties.Symbol_file), vndkVer, "--llndk") objs, versionScript := compileStubLibrary(ctx, flags, String(stub.Properties.Symbol_file), vndkVer, "--llndk")
stub.versionScriptPath = versionScript stub.versionScriptPath = versionScript
return objs return objs
@@ -154,6 +163,10 @@ func (stub *llndkStubDecorator) link(ctx ModuleContext, flags Flags, deps PathDe
stub.libraryDecorator.flagExporter.Properties.Export_include_dirs = []string{} stub.libraryDecorator.flagExporter.Properties.Export_include_dirs = []string{}
} }
if stub.stubsVersion() != "" {
stub.reexportFlags("-D" + versioningMacroName(ctx.baseModuleName()) + "=" + stub.stubsVersion())
}
return stub.libraryDecorator.link(ctx, flags, deps, objs) return stub.libraryDecorator.link(ctx, flags, deps, objs)
} }

View File

@@ -297,6 +297,9 @@ func processLlndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
if !Bool(lib.Properties.Vendor_available) { if !Bool(lib.Properties.Vendor_available) {
vndkPrivateLibraries(mctx.Config())[name] = filename vndkPrivateLibraries(mctx.Config())[name] = filename
} }
if mctx.OtherModuleExists(name) {
mctx.AddFarVariationDependencies(m.Target().Variations(), llndkImplDep, name)
}
} }
func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) { func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {