Revert^2 "Add sdk mutator for native modules"

f8e80229fe

Change-Id: Ic30ab6b844684bfc3e8ece5a1913980d5fbf8de2
This commit is contained in:
Colin Cross 2020-04-07 16:50:32 +00:00
parent f8e80229fe
commit c511bc50dc
21 changed files with 401 additions and 18 deletions

View File

@ -186,6 +186,7 @@ bootstrap_go_package {
"cc/rs.go",
"cc/sanitize.go",
"cc/sabi.go",
"cc/sdk.go",
"cc/snapshot_utils.go",
"cc/stl.go",
"cc/strip.go",

View File

@ -53,6 +53,7 @@ func init() {
AddNeverAllowRules(createLibcoreRules()...)
AddNeverAllowRules(createMediaRules()...)
AddNeverAllowRules(createJavaDeviceForHostRules()...)
AddNeverAllowRules(createCcSdkVariantRules()...)
}
// Add a NeverAllow rule to the set of rules to apply.
@ -175,6 +176,37 @@ func createJavaDeviceForHostRules() []Rule {
}
}
func createCcSdkVariantRules() []Rule {
sdkVersionOnlyWhitelist := []string{
// derive_sdk_prefer32 has stem: "derive_sdk" which conflicts with the derive_sdk.
// This sometimes works because the APEX modules that contain derive_sdk and
// derive_sdk_prefer32 suppress the platform installation rules, but fails when
// the APEX modules contain the SDK variant and the platform variant still exists.
"frameworks/base/apex/sdkextensions/derive_sdk",
}
platformVariantPropertiesWhitelist := []string{
// android_native_app_glue and libRSSupport use native_window.h but target old
// sdk versions (minimum and 9 respectively) where libnativewindow didn't exist,
// so they can't add libnativewindow to shared_libs to get the header directory
// for the platform variant. Allow them to use the platform variant
// property to set shared_libs.
"prebuilts/ndk",
"frameworks/rs",
}
return []Rule{
NeverAllow().
NotIn(sdkVersionOnlyWhitelist...).
WithMatcher("sdk_variant_only", isSetMatcherInstance).
Because("sdk_variant_only can only be used in whitelisted projects"),
NeverAllow().
NotIn(platformVariantPropertiesWhitelist...).
WithMatcher("platform.shared_libs", isSetMatcherInstance).
Because("platform variant properties can only be used in whitelisted projects"),
}
}
func neverallowMutator(ctx BottomUpMutatorContext) {
m, ok := ctx.Module().(Module)
if !ok {
@ -254,6 +286,18 @@ func (m *startsWithMatcher) String() string {
return ".starts-with(" + m.prefix + ")"
}
type isSetMatcher struct{}
func (m *isSetMatcher) test(value string) bool {
return value != ""
}
func (m *isSetMatcher) String() string {
return ".is-set"
}
var isSetMatcherInstance = &isSetMatcher{}
type ruleProperty struct {
fields []string // e.x.: Vndk.Enabled
matcher ValueMatcher

View File

@ -249,6 +249,50 @@ var neverallowTests = []struct {
}`),
},
},
// CC sdk rule tests
{
name: `"sdk_variant_only" outside whitelist`,
fs: map[string][]byte{
"Android.bp": []byte(`
cc_library {
name: "outside_whitelist",
sdk_version: "current",
sdk_variant_only: true,
}`),
},
expectedErrors: []string{
`module "outside_whitelist": violates neverallow`,
},
},
{
name: `"sdk_variant_only: false" outside whitelist`,
fs: map[string][]byte{
"Android.bp": []byte(`
cc_library {
name: "outside_whitelist",
sdk_version: "current",
sdk_variant_only: false,
}`),
},
expectedErrors: []string{
`module "outside_whitelist": violates neverallow`,
},
},
{
name: `"platform" outside whitelist`,
fs: map[string][]byte{
"Android.bp": []byte(`
cc_library {
name: "outside_whitelist",
platform: {
shared_libs: ["libfoo"],
},
}`),
},
expectedErrors: []string{
`module "outside_whitelist": violates neverallow`,
},
},
}
func TestNeverallow(t *testing.T) {
@ -289,6 +333,8 @@ type mockCcLibraryProperties struct {
Include_dirs []string
Vendor_available *bool
Static_libs []string
Sdk_version *string
Sdk_variant_only *bool
Vndk struct {
Enabled *bool
@ -305,6 +351,10 @@ type mockCcLibraryProperties struct {
Cflags []string
}
}
Platform struct {
Shared_libs []string
}
}
type mockCcLibraryModule struct {

View File

@ -3350,7 +3350,7 @@ func TestApexWithApps(t *testing.T) {
}
// JNI libraries including transitive deps are
for _, jni := range []string{"libjni", "libfoo"} {
jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_shared_myapex").Module().(*cc.Module).OutputFile()
jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_sdk_shared_myapex").Module().(*cc.Module).OutputFile()
// ... embedded inside APK (jnilibs.zip)
ensureListContains(t, appZipRule.Implicits.Strings(), jniOutput.String())
// ... and not directly inside the APEX

View File

@ -90,6 +90,7 @@ func TestVndkApexUsesVendorVariant(t *testing.T) {
system_shared_libs: [],
stl: "none",
notice: "custom_notice",
sdk_version: "current",
}
cc_library {
name: "libprofile-clang-extras_ndk",
@ -98,6 +99,7 @@ func TestVndkApexUsesVendorVariant(t *testing.T) {
system_shared_libs: [],
stl: "none",
notice: "custom_notice",
sdk_version: "current",
}
`, func(fs map[string][]byte, config android.Config) {
config.TestProductVariables.Native_coverage = proptools.BoolPtr(true)

View File

@ -29,6 +29,7 @@ var (
vendorSuffix = ".vendor"
ramdiskSuffix = ".ramdisk"
recoverySuffix = ".recovery"
sdkSuffix = ".sdk"
)
type AndroidMkContext interface {
@ -103,6 +104,28 @@ func (c *Module) AndroidMkEntries() []android.AndroidMkEntries {
}
}
}
if c.Properties.IsSdkVariant && c.Properties.SdkAndPlatformVariantVisibleToMake {
// Make the SDK variant uninstallable so that there are not two rules to install
// to the same location.
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
// Add the unsuffixed name to SOONG_SDK_VARIANT_MODULES so that Make can rewrite
// dependencies to the .sdk suffix when building a module that uses the SDK.
entries.SetString("SOONG_SDK_VARIANT_MODULES",
"$(SOONG_SDK_VARIANT_MODULES) $(patsubst %.sdk,%,$(LOCAL_MODULE))")
}
},
},
ExtraFooters: []android.AndroidMkExtraFootersFunc{
func(w io.Writer, name, prefix, moduleDir string, entries *android.AndroidMkEntries) {
if c.Properties.IsSdkVariant && c.Properties.SdkAndPlatformVariantVisibleToMake &&
c.CcLibraryInterface() && c.Shared() {
// Using the SDK variant as a JNI library needs a copy of the .so that
// is not named .sdk.so so that it can be packaged into the APK with
// the right name.
fmt.Fprintln(w, "$(eval $(call copy-one-file,",
"$(LOCAL_BUILT_MODULE),",
"$(patsubst %.sdk.so,%.so,$(LOCAL_BUILT_MODULE))))")
}
},
},
}
@ -393,6 +416,9 @@ func (library *toolchainLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext,
}
func (installer *baseInstaller) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
if installer.path == (android.InstallPath{}) {
return
}
// Soong installation is only supported for host modules. Have Make
// installation trigger Soong installation.
if ctx.Target().Os.Class == android.Host {

View File

@ -42,6 +42,7 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("cc_defaults", defaultsFactory)
ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("sdk", sdkMutator).Parallel()
ctx.BottomUp("vndk", VndkMutator).Parallel()
ctx.BottomUp("link", LinkageMutator).Parallel()
ctx.BottomUp("ndk_api", NdkApiMutator).Parallel()
@ -208,9 +209,13 @@ type BaseProperties struct {
// Deprecated. true is the default, false is invalid.
Clang *bool `android:"arch_variant"`
// Minimum sdk version supported when compiling against the ndk
// Minimum sdk version supported when compiling against the ndk. Setting this property causes
// two variants to be built, one for the platform and one for apps.
Sdk_version *string
// If true, always create an sdk variant and don't create a platform variant.
Sdk_variant_only *bool
AndroidMkSharedLibs []string `blueprint:"mutated"`
AndroidMkStaticLibs []string `blueprint:"mutated"`
AndroidMkRuntimeLibs []string `blueprint:"mutated"`
@ -252,6 +257,16 @@ type BaseProperties struct {
SnapshotRuntimeLibs []string `blueprint:"mutated"`
Installable *bool
// Set by factories of module types that can only be referenced from variants compiled against
// the SDK.
AlwaysSdk bool `blueprint:"mutated"`
// Variant is an SDK variant created by sdkMutator
IsSdkVariant bool `blueprint:"mutated"`
// Set when both SDK and platform variants are exported to Make to trigger renaming the SDK
// variant to have a ".sdk" suffix.
SdkAndPlatformVariantVisibleToMake bool `blueprint:"mutated"`
}
type VendorProperties struct {
@ -527,7 +542,10 @@ func (c *Module) Shared() bool {
}
func (c *Module) SelectedStl() string {
return c.stl.Properties.SelectedStl
if c.stl != nil {
return c.stl.Properties.SelectedStl
}
return ""
}
func (c *Module) ToolchainLibrary() bool {
@ -555,6 +573,10 @@ func (c *Module) SdkVersion() string {
return String(c.Properties.Sdk_version)
}
func (c *Module) AlwaysSdk() bool {
return c.Properties.AlwaysSdk || Bool(c.Properties.Sdk_variant_only)
}
func (c *Module) IncludeDirs() android.Paths {
if c.linker != nil {
if library, ok := c.linker.(exportedFlagsProducer); ok {
@ -803,6 +825,17 @@ func (c *Module) UseVndk() bool {
return c.Properties.VndkVersion != ""
}
func (c *Module) canUseSdk() bool {
return c.Os() == android.Android && !c.UseVndk() && !c.InRamdisk() && !c.InRecovery()
}
func (c *Module) UseSdk() bool {
if c.canUseSdk() {
return String(c.Properties.Sdk_version) != ""
}
return false
}
func (c *Module) isCoverageVariant() bool {
return c.coverage.Properties.IsCoverageVariant
}
@ -1060,14 +1093,11 @@ func (ctx *moduleContextImpl) header() bool {
}
func (ctx *moduleContextImpl) canUseSdk() bool {
return ctx.ctx.Device() && !ctx.useVndk() && !ctx.inRamdisk() && !ctx.inRecovery() && !ctx.ctx.Fuchsia()
return ctx.mod.canUseSdk()
}
func (ctx *moduleContextImpl) useSdk() bool {
if ctx.canUseSdk() {
return String(ctx.mod.Properties.Sdk_version) != ""
}
return false
return ctx.mod.UseSdk()
}
func (ctx *moduleContextImpl) sdkVersion() string {
@ -1386,6 +1416,8 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
c.Properties.SubName += ramdiskSuffix
} else if c.InRecovery() && !c.OnlyInRecovery() {
c.Properties.SubName += recoverySuffix
} else if c.Properties.IsSdkVariant && c.Properties.SdkAndPlatformVariantVisibleToMake {
c.Properties.SubName += sdkSuffix
}
ctx := &moduleContext{

View File

@ -27,6 +27,7 @@ type GenruleExtraProperties struct {
Vendor_available *bool
Ramdisk_available *bool
Recovery_available *bool
Sdk_version *string
}
// cc_genrule is a genrule that can depend on other cc_* objects.

View File

@ -1223,7 +1223,7 @@ func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
if Bool(library.Properties.Static_ndk_lib) && library.static() &&
!ctx.useVndk() && !ctx.inRamdisk() && !ctx.inRecovery() && ctx.Device() &&
library.baseLinker.sanitize.isUnsanitizedVariant() &&
!library.buildStubs() {
!library.buildStubs() && ctx.sdkVersion() == "" {
installPath := getNdkSysrootBase(ctx).Join(
ctx, "usr/lib", config.NDKTriple(ctx.toolchain()), file.Base())

View File

@ -45,12 +45,14 @@ type LinkableInterface interface {
InRecovery() bool
OnlyInRecovery() bool
UseSdk() bool
UseVndk() bool
MustUseVendorVariant() bool
IsVndk() bool
HasVendorVariant() bool
SdkVersion() string
AlwaysSdk() bool
ToolchainLibrary() bool
NdkPrebuiltStl() bool

View File

@ -158,6 +158,13 @@ type BaseLinkerProperties struct {
// the ramdisk variant of the C/C++ module.
Exclude_static_libs []string
}
Platform struct {
// list of shared libs that should be use to build the platform variant
// of a module that sets sdk_version. This should rarely be necessary,
// in most cases the same libraries are available for the SDK and platform
// variants.
Shared_libs []string
}
}
// make android::build:GetBuildNumber() available containing the build ID.
@ -255,6 +262,10 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Recovery.Exclude_static_libs)
}
if !ctx.useSdk() {
deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Platform.Shared_libs...)
}
if ctx.toolchain().Bionic() {
// libclang_rt.builtins and libatomic have to be last on the command line
if !Bool(linker.Properties.No_libcrt) {

View File

@ -381,6 +381,9 @@ func newStubLibrary() *Module {
module.linker = stub
module.installer = stub
module.Properties.AlwaysSdk = true
module.Properties.Sdk_version = StringPtr("current")
module.AddProperties(&stub.properties, &library.MutatedProperties)
return module

View File

@ -76,6 +76,8 @@ func NdkPrebuiltObjectFactory() android.Module {
baseLinker: NewBaseLinker(nil),
},
}
module.Properties.AlwaysSdk = true
module.Properties.Sdk_version = StringPtr("current")
module.Properties.HideFromMake = true
return module.Init()
}
@ -115,10 +117,9 @@ func NdkPrebuiltSharedStlFactory() android.Module {
libraryDecorator: library,
}
module.installer = nil
minVersionString := "minimum"
noStlString := "none"
module.Properties.Sdk_version = &minVersionString
module.stl.Properties.Stl = &noStlString
module.Properties.Sdk_version = StringPtr("minimum")
module.Properties.AlwaysSdk = true
module.stl.Properties.Stl = StringPtr("none")
return module.Init()
}
@ -135,6 +136,9 @@ func NdkPrebuiltStaticStlFactory() android.Module {
}
module.installer = nil
module.Properties.HideFromMake = true
module.Properties.AlwaysSdk = true
module.Properties.Sdk_version = StringPtr("current")
module.stl.Properties.Stl = StringPtr("none")
module.ModuleBase.EnableNativeBridgeSupportByDefault()
return module.Init()
}

65
cc/sdk.go Normal file
View File

@ -0,0 +1,65 @@
// Copyright 2020 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cc
import (
"android/soong/android"
"android/soong/genrule"
)
// sdkMutator sets a creates a platform and an SDK variant for modules
// that set sdk_version, and ignores sdk_version for the platform
// variant. The SDK variant will be used for embedding in APKs
// that may be installed on older platforms. Apexes use their own
// variants that enforce backwards compatibility.
func sdkMutator(ctx android.BottomUpMutatorContext) {
if ctx.Os() != android.Android {
return
}
switch m := ctx.Module().(type) {
case LinkableInterface:
if m.AlwaysSdk() {
if !m.UseSdk() {
ctx.ModuleErrorf("UseSdk() must return true when AlwaysSdk is set, did the factory forget to set Sdk_version?")
}
ctx.CreateVariations("sdk")
} else if m.UseSdk() {
modules := ctx.CreateVariations("", "sdk")
modules[0].(*Module).Properties.Sdk_version = nil
modules[1].(*Module).Properties.IsSdkVariant = true
if ctx.Config().UnbundledBuild() {
modules[0].(*Module).Properties.HideFromMake = true
} else {
modules[1].(*Module).Properties.SdkAndPlatformVariantVisibleToMake = true
modules[1].(*Module).Properties.PreventInstall = true
}
ctx.AliasVariation("")
} else {
ctx.CreateVariations("")
ctx.AliasVariation("")
}
case *genrule.Module:
if p, ok := m.Extra.(*GenruleExtraProperties); ok {
if String(p.Sdk_version) != "" {
ctx.CreateVariations("", "sdk")
} else {
ctx.CreateVariations("")
}
ctx.AliasVariation("")
}
}
}

102
cc/sdk_test.go Normal file
View File

@ -0,0 +1,102 @@
// Copyright 2020 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cc
import (
"testing"
"android/soong/android"
)
func TestSdkMutator(t *testing.T) {
bp := `
cc_library {
name: "libsdk",
shared_libs: ["libsdkdep"],
sdk_version: "current",
stl: "c++_shared",
}
cc_library {
name: "libsdkdep",
sdk_version: "current",
stl: "c++_shared",
}
cc_library {
name: "libplatform",
shared_libs: ["libsdk"],
stl: "libc++",
}
cc_binary {
name: "platformbinary",
shared_libs: ["libplatform"],
stl: "libc++",
}
cc_binary {
name: "sdkbinary",
shared_libs: ["libsdk"],
sdk_version: "current",
stl: "libc++",
}
`
assertDep := func(t *testing.T, from, to android.TestingModule) {
t.Helper()
found := false
var toFile android.Path
m := to.Module().(*Module)
if toc := m.Toc(); toc.Valid() {
toFile = toc.Path()
} else {
toFile = m.outputFile.Path()
}
rule := from.Description("link")
for _, dep := range rule.Implicits {
if dep.String() == toFile.String() {
found = true
}
}
if !found {
t.Errorf("expected %q in %q", toFile.String(), rule.Implicits.Strings())
}
}
ctx := testCc(t, bp)
libsdkNDK := ctx.ModuleForTests("libsdk", "android_arm64_armv8-a_sdk_shared")
libsdkPlatform := ctx.ModuleForTests("libsdk", "android_arm64_armv8-a_shared")
libsdkdepNDK := ctx.ModuleForTests("libsdkdep", "android_arm64_armv8-a_sdk_shared")
libsdkdepPlatform := ctx.ModuleForTests("libsdkdep", "android_arm64_armv8-a_shared")
libplatform := ctx.ModuleForTests("libplatform", "android_arm64_armv8-a_shared")
platformbinary := ctx.ModuleForTests("platformbinary", "android_arm64_armv8-a")
sdkbinary := ctx.ModuleForTests("sdkbinary", "android_arm64_armv8-a_sdk")
libcxxNDK := ctx.ModuleForTests("ndk_libc++_shared", "android_arm64_armv8-a_sdk_shared")
libcxxPlatform := ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared")
assertDep(t, libsdkNDK, libsdkdepNDK)
assertDep(t, libsdkPlatform, libsdkdepPlatform)
assertDep(t, libplatform, libsdkPlatform)
assertDep(t, platformbinary, libplatform)
assertDep(t, sdkbinary, libsdkNDK)
assertDep(t, libsdkNDK, libcxxNDK)
assertDep(t, libsdkPlatform, libcxxPlatform)
}

View File

@ -115,9 +115,13 @@ func (stl *stl) begin(ctx BaseModuleContext) {
switch s {
case "libc++", "libc++_static":
return s
case "c++_shared":
return "libc++"
case "c++_static":
return "libc++_static"
case "none":
return ""
case "":
case "", "system":
if ctx.static() {
return "libc++_static"
} else {

View File

@ -138,6 +138,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
name: "libgcc_stripped",
vendor_available: true,
recovery_available: true,
sdk_version: "current",
src: "",
}
@ -155,6 +156,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
llndk_library {
name: "libc",
symbol_file: "",
sdk_version: "current",
}
cc_library {
name: "libm",
@ -174,6 +176,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
llndk_library {
name: "libm",
symbol_file: "",
sdk_version: "current",
}
cc_library {
name: "libdl",
@ -193,6 +196,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
llndk_library {
name: "libdl",
symbol_file: "",
sdk_version: "current",
}
cc_library {
name: "libft2",
@ -205,6 +209,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
name: "libft2",
symbol_file: "",
vendor_available: false,
sdk_version: "current",
}
cc_library {
name: "libc++_static",
@ -336,6 +341,16 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
sdk_version: "27",
}
ndk_prebuilt_object {
name: "ndk_crtbegin_dynamic.27",
sdk_version: "27",
}
ndk_prebuilt_object {
name: "ndk_crtend_android.27",
sdk_version: "27",
}
ndk_prebuilt_shared_stl {
name: "ndk_libc++_shared",
}

View File

@ -67,6 +67,7 @@ func ToolchainLibraryFactory() android.Module {
module.stl = nil
module.sanitize = nil
module.installer = nil
module.Properties.Sdk_version = StringPtr("current")
return module.Init()
}

View File

@ -204,6 +204,13 @@ func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
for _, jniTarget := range ctx.MultiTargets() {
variation := append(jniTarget.Variations(),
blueprint.Variation{Mutator: "link", Variation: "shared"})
// If the app builds against an Android SDK use the SDK variant of JNI dependencies
// unless jni_uses_platform_apis is set.
if a.sdkVersion().specified() && a.sdkVersion().kind != sdkCorePlatform &&
!Bool(a.appProperties.Jni_uses_platform_apis) {
variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
}
ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs...)
}

View File

@ -791,6 +791,7 @@ func TestJNIABI(t *testing.T) {
cc_library {
name: "libjni",
system_shared_libs: [],
sdk_version: "current",
stl: "none",
}
@ -928,26 +929,26 @@ func TestJNIPackaging(t *testing.T) {
android_test {
name: "test",
sdk_version: "core_platform",
sdk_version: "current",
jni_libs: ["libjni"],
}
android_test {
name: "test_noembed",
sdk_version: "core_platform",
sdk_version: "current",
jni_libs: ["libjni"],
use_embedded_native_libs: false,
}
android_test_helper_app {
name: "test_helper",
sdk_version: "core_platform",
sdk_version: "current",
jni_libs: ["libjni"],
}
android_test_helper_app {
name: "test_helper_noembed",
sdk_version: "core_platform",
sdk_version: "current",
jni_libs: ["libjni"],
use_embedded_native_libs: false,
}
@ -979,6 +980,10 @@ func TestJNIPackaging(t *testing.T) {
if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w {
t.Errorf("expected jni compressed %v, got %v", w, g)
}
if !strings.Contains(jniLibZip.Implicits[0].String(), "_sdk_") {
t.Errorf("expected input %q to use sdk variant", jniLibZip.Implicits[0].String())
}
}
})
}

View File

@ -164,6 +164,10 @@ func (mod *Module) OnlyInRecovery() bool {
return false
}
func (mod *Module) UseSdk() bool {
return false
}
func (mod *Module) UseVndk() bool {
return false
}
@ -184,6 +188,10 @@ func (mod *Module) SdkVersion() string {
return ""
}
func (mod *Module) AlwaysSdk() bool {
return false
}
func (mod *Module) ToolchainLibrary() bool {
return false
}