Merge changes I5645ddb9,Ib3d50f15,Ib4c5815a,If3b63706 into main am: e8cb9178ec am: 5312102ca0

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/3086468

Change-Id: Ieb2e4fa051e1886c613c7071c40175bebe221ab5
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot
2024-05-14 20:43:26 +00:00
committed by Automerger Merge Worker
10 changed files with 200 additions and 173 deletions

View File

@@ -17,6 +17,7 @@ package java
import (
"fmt"
"io"
"strings"
"android/soong/android"
@@ -412,6 +413,23 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
if app.embeddedJniLibs {
jniSymbols := app.JNISymbolsInstalls(app.installPathForJNISymbols.String())
entries.SetString("LOCAL_SOONG_JNI_LIBS_SYMBOLS", jniSymbols.String())
} else {
for _, jniLib := range app.jniLibs {
entries.AddStrings("LOCAL_SOONG_JNI_LIBS_"+jniLib.target.Arch.ArchType.String(), jniLib.name)
var partitionTag string
// Mimic the creation of partition_tag in build/make,
// which defaults to an empty string when the partition is system.
// Otherwise, capitalize with a leading _
if jniLib.partition == "system" {
partitionTag = ""
} else {
split := strings.Split(jniLib.partition, "/")
partitionTag = "_" + strings.ToUpper(split[len(split)-1])
}
entries.AddStrings("LOCAL_SOONG_JNI_LIBS_PARTITION_"+jniLib.target.Arch.ArchType.String(),
jniLib.name+":"+partitionTag)
}
}
if len(app.jniCoverageOutputs) > 0 {

View File

@@ -19,6 +19,9 @@ import (
"testing"
"android/soong/android"
"android/soong/cc"
"github.com/google/blueprint/proptools"
)
func TestRequired(t *testing.T) {
@@ -252,3 +255,149 @@ func TestGetOverriddenPackages(t *testing.T) {
android.AssertDeepEquals(t, "overrides property", expected.overrides, actual)
}
}
func TestJniPartition(t *testing.T) {
bp := `
cc_library {
name: "libjni_system",
system_shared_libs: [],
sdk_version: "current",
stl: "none",
}
cc_library {
name: "libjni_system_ext",
system_shared_libs: [],
sdk_version: "current",
stl: "none",
system_ext_specific: true,
}
cc_library {
name: "libjni_odm",
system_shared_libs: [],
sdk_version: "current",
stl: "none",
device_specific: true,
}
cc_library {
name: "libjni_product",
system_shared_libs: [],
sdk_version: "current",
stl: "none",
product_specific: true,
}
cc_library {
name: "libjni_vendor",
system_shared_libs: [],
sdk_version: "current",
stl: "none",
soc_specific: true,
}
android_app {
name: "test_app_system_jni_system",
privileged: true,
platform_apis: true,
certificate: "platform",
jni_libs: ["libjni_system"],
}
android_app {
name: "test_app_system_jni_system_ext",
privileged: true,
platform_apis: true,
certificate: "platform",
jni_libs: ["libjni_system_ext"],
}
android_app {
name: "test_app_system_ext_jni_system",
privileged: true,
platform_apis: true,
certificate: "platform",
jni_libs: ["libjni_system"],
system_ext_specific: true
}
android_app {
name: "test_app_system_ext_jni_system_ext",
sdk_version: "core_platform",
jni_libs: ["libjni_system_ext"],
system_ext_specific: true
}
android_app {
name: "test_app_product_jni_product",
sdk_version: "core_platform",
jni_libs: ["libjni_product"],
product_specific: true
}
android_app {
name: "test_app_vendor_jni_odm",
sdk_version: "core_platform",
jni_libs: ["libjni_odm"],
soc_specific: true
}
android_app {
name: "test_app_odm_jni_vendor",
sdk_version: "core_platform",
jni_libs: ["libjni_vendor"],
device_specific: true
}
android_app {
name: "test_app_system_jni_multiple",
privileged: true,
platform_apis: true,
certificate: "platform",
jni_libs: ["libjni_system", "libjni_system_ext"],
}
android_app {
name: "test_app_vendor_jni_multiple",
sdk_version: "core_platform",
jni_libs: ["libjni_odm", "libjni_vendor"],
soc_specific: true
}
`
arch := "arm64"
ctx := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
cc.PrepareForTestWithCcDefaultModules,
android.PrepareForTestWithAndroidMk,
android.FixtureModifyConfig(func(config android.Config) {
config.TestProductVariables.DeviceArch = proptools.StringPtr(arch)
}),
).
RunTestWithBp(t, bp)
testCases := []struct {
name string
partitionNames []string
partitionTags []string
}{
{"test_app_system_jni_system", []string{"libjni_system"}, []string{""}},
{"test_app_system_jni_system_ext", []string{"libjni_system_ext"}, []string{"_SYSTEM_EXT"}},
{"test_app_system_ext_jni_system", []string{"libjni_system"}, []string{""}},
{"test_app_system_ext_jni_system_ext", []string{"libjni_system_ext"}, []string{"_SYSTEM_EXT"}},
{"test_app_product_jni_product", []string{"libjni_product"}, []string{"_PRODUCT"}},
{"test_app_vendor_jni_odm", []string{"libjni_odm"}, []string{"_ODM"}},
{"test_app_odm_jni_vendor", []string{"libjni_vendor"}, []string{"_VENDOR"}},
{"test_app_system_jni_multiple", []string{"libjni_system", "libjni_system_ext"}, []string{"", "_SYSTEM_EXT"}},
{"test_app_vendor_jni_multiple", []string{"libjni_odm", "libjni_vendor"}, []string{"_ODM", "_VENDOR"}},
}
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
mod := ctx.ModuleForTests(test.name, "android_common").Module()
entry := android.AndroidMkEntriesForTest(t, ctx.TestContext, mod)[0]
for i := range test.partitionNames {
actual := entry.EntryMap["LOCAL_SOONG_JNI_LIBS_PARTITION_"+arch][i]
expected := test.partitionNames[i] + ":" + test.partitionTags[i]
android.AssertStringEquals(t, "Expected and actual differ", expected, actual)
}
})
}
}

View File

@@ -90,17 +90,20 @@ type appProperties struct {
Stl *string `android:"arch_variant"`
// Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
// flag so that they are used from inside the APK at runtime. This property is respected only for
// APKs built using android_test or android_test_helper_app. For other APKs, this property is ignored
// and native libraries are always embedded compressed.
// flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless
// sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
// android_app modules that are embedded to APEXes, defaults to false for other module types where the native
// libraries are generally preinstalled outside the APK.
Use_embedded_native_libs *bool
// Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
// they are used from inside the APK at runtime.
Use_embedded_dex *bool
// Allows compressing of embedded native libs. Only for android_test and android_test_helper_app.
AllowCompressingNativeLibs bool `blueprint:"mutated"`
// Forces native libraries to always be packaged into the APK,
// Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
// True for android_test* modules.
AlwaysPackageNativeLibs bool `blueprint:"mutated"`
// If set, find and merge all NOTICE files that this module and its dependencies have and store
// it in the APK as an asset.
@@ -400,20 +403,14 @@ func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVer
// Returns true if the native libraries should be stored in the APK uncompressed and the
// extractNativeLibs application flag should be set to false in the manifest.
func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
var useEmbedded bool
if a.appProperties.AllowCompressingNativeLibs {
useEmbedded = BoolDefault(a.appProperties.Use_embedded_native_libs, true)
} else {
useEmbedded = true // always uncompress for non-test apps
}
minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
if err != nil {
ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
}
supported := minSdkVersion.FinalOrFutureInt() >= 23
return useEmbedded && supported
apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
!apexInfo.IsForPlatform()
}
// Returns whether this module should have the dex file stored uncompressed in the APK.
@@ -436,23 +433,9 @@ func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
}
func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
// Always!
return true
}
func (a *AndroidApp) shouldCollectRecursiveNativeDeps(ctx android.ModuleContext) bool {
// JNI libs are always embedded, but whether to embed their transitive dependencies as well
// or not is determined here. For most of the apps built here (using the platform build
// system), we don't need to collect the transitive deps because they will anyway be
// available in the partition image where the app will be installed to.
//
// Collecting transitive dependencies is required only for unbundled apps.
apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
apkInApex := !apexInfo.IsForPlatform()
testApp := a.appProperties.AllowCompressingNativeLibs
unbundledApp := ctx.Config().UnbundledBuild() || apkInApex || testApp
return a.shouldEmbedJnis(ctx) && unbundledApp
return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
!apexInfo.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs
}
func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
@@ -846,7 +829,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
dexJarFile, packageResources := a.dexBuildActions(ctx)
jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldCollectRecursiveNativeDeps(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
if ctx.Failed() {
@@ -1417,7 +1400,8 @@ func AndroidTestFactory() android.Module {
module.Module.properties.Instrument = true
module.Module.properties.Supports_static_instrumentation = true
module.Module.properties.Installable = proptools.BoolPtr(true)
module.appProperties.AllowCompressingNativeLibs = true
module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
module.appProperties.AlwaysPackageNativeLibs = true
module.Module.dexpreopter.isTest = true
module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
@@ -1472,7 +1456,8 @@ func AndroidTestHelperAppFactory() android.Module {
module.Module.dexProperties.Optimize.EnabledByDefault = true
module.Module.properties.Installable = proptools.BoolPtr(true)
module.appProperties.AllowCompressingNativeLibs = true
module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
module.appProperties.AlwaysPackageNativeLibs = true
module.Module.dexpreopter.isTest = true
module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)

View File

@@ -2013,8 +2013,8 @@ func TestJNIPackaging(t *testing.T) {
packaged bool
compressed bool
}{
{"app", true, false},
{"app_noembed", true, false},
{"app", false, false},
{"app_noembed", false, false},
{"app_embed", true, false},
{"test", true, false},
{"test_noembed", true, true},
@@ -2043,44 +2043,6 @@ func TestJNIPackaging(t *testing.T) {
}
}
func TestJNITranstiveDepsInstallation(t *testing.T) {
ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
android_app {
name: "app",
jni_libs: ["libjni"],
platform_apis: true,
}
cc_library {
name: "libjni",
shared_libs: ["libplatform"],
system_shared_libs: [],
stl: "none",
required: ["librequired"],
}
cc_library {
name: "libplatform",
system_shared_libs: [],
stl: "none",
}
cc_library {
name: "librequired",
system_shared_libs: [],
stl: "none",
}
`)
app := ctx.ModuleForTests("app", "android_common")
jniLibZip := app.Output("jnilibs.zip")
android.AssertPathsEndWith(t, "embedd jni lib mismatch", []string{"libjni.so"}, jniLibZip.Implicits)
install := app.Rule("Cp")
android.AssertPathsEndWith(t, "install dep mismatch", []string{"libplatform.so", "librequired.so"}, install.OrderOnly)
}
func TestJNISDK(t *testing.T) {
ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
@@ -3357,7 +3319,8 @@ func TestUsesLibraries(t *testing.T) {
// These also include explicit `uses_libs`/`optional_uses_libs` entries, as they may be
// propagated from dependencies.
actualManifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
expectManifestFixerArgs := `--uses-library foo ` +
expectManifestFixerArgs := `--extract-native-libs=true ` +
`--uses-library foo ` +
`--uses-library com.non.sdk.lib ` +
`--uses-library qux ` +
`--uses-library quuz ` +
@@ -4147,7 +4110,7 @@ func TestAppIncludesJniPackages(t *testing.T) {
},
{
name: "aary-no-use-embedded",
hasPackage: true,
hasPackage: false,
},
}

View File

@@ -368,17 +368,6 @@ type dependencyTag struct {
static bool
}
var _ android.SkipToTransitiveDepsTag = (*dependencyTag)(nil)
func (depTag dependencyTag) SkipToTransitiveDeps() bool {
// jni_libs are not installed because they are always embedded into the app. However,
// transitive deps of jni_libs themselves should be installed along with the app.
if IsJniDepTag(depTag) {
return true
}
return false
}
// installDependencyTag is a dependency tag that is annotated to cause the installed files of the
// dependency to be installed when the parent module is installed.
type installDependencyTag struct {