Revert^2 "Install jni symlinks in Soong"
b7646e4d4f
This is a relanding of I0930cb1ebb8ca8a6efd64b1ce2cdfd1c47fe19ef plus
some forward fix described below:
Export non-embedded JNI lib names via LOCAL_REQUIRED_MODULES
The non-embedded JNI libs are installed as the dependencies of the APK.
However, that dependency is not revealed to the Make world and as a
result, the JNI libs are dropped from the file_list.txt file which Make
uses to filter files to include in the image file.
Adding the lib names to LOCAL_REQUIRED_MODULES fixes it.
Bug: 341335305
Bug: 330276359
Test: m out/target/product/vsoc_x86_64_only/obj/PACKAGING/system_intermediates/file_list.txt
and check if libcarservicejni.so is there
Test: go test ./... under soong/java
Change-Id: If915a05909129c92fab7a6cbbd0c4c55f5ced598
This commit is contained in:
@@ -17,7 +17,6 @@ package java
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
|
|
||||||
@@ -414,22 +413,11 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
|
|||||||
jniSymbols := app.JNISymbolsInstalls(app.installPathForJNISymbols.String())
|
jniSymbols := app.JNISymbolsInstalls(app.installPathForJNISymbols.String())
|
||||||
entries.SetString("LOCAL_SOONG_JNI_LIBS_SYMBOLS", jniSymbols.String())
|
entries.SetString("LOCAL_SOONG_JNI_LIBS_SYMBOLS", jniSymbols.String())
|
||||||
} else {
|
} else {
|
||||||
|
var names []string
|
||||||
for _, jniLib := range app.jniLibs {
|
for _, jniLib := range app.jniLibs {
|
||||||
entries.AddStrings("LOCAL_SOONG_JNI_LIBS_"+jniLib.target.Arch.ArchType.String(), jniLib.name)
|
names = append(names, 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)
|
|
||||||
}
|
}
|
||||||
|
entries.AddStrings("LOCAL_REQUIRED_MODULES", names...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(app.jniCoverageOutputs) > 0 {
|
if len(app.jniCoverageOutputs) > 0 {
|
||||||
|
@@ -20,8 +20,6 @@ import (
|
|||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
"android/soong/cc"
|
"android/soong/cc"
|
||||||
|
|
||||||
"github.com/google/blueprint/proptools"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRequired(t *testing.T) {
|
func TestRequired(t *testing.T) {
|
||||||
@@ -256,148 +254,50 @@ func TestGetOverriddenPackages(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJniPartition(t *testing.T) {
|
func TestJniAsRequiredDeps(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(
|
ctx := android.GroupFixturePreparers(
|
||||||
PrepareForTestWithJavaDefaultModules,
|
PrepareForTestWithJavaDefaultModules,
|
||||||
cc.PrepareForTestWithCcDefaultModules,
|
cc.PrepareForTestWithCcDefaultModules,
|
||||||
android.PrepareForTestWithAndroidMk,
|
android.PrepareForTestWithAndroidMk,
|
||||||
android.FixtureModifyConfig(func(config android.Config) {
|
).RunTestWithBp(t, `
|
||||||
config.TestProductVariables.DeviceArch = proptools.StringPtr(arch)
|
android_app {
|
||||||
}),
|
name: "app",
|
||||||
).
|
jni_libs: ["libjni"],
|
||||||
RunTestWithBp(t, bp)
|
platform_apis: true,
|
||||||
testCases := []struct {
|
}
|
||||||
name string
|
|
||||||
partitionNames []string
|
android_app {
|
||||||
partitionTags []string
|
name: "app_embedded",
|
||||||
|
jni_libs: ["libjni"],
|
||||||
|
platform_apis: true,
|
||||||
|
use_embedded_native_libs: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libjni",
|
||||||
|
system_shared_libs: [],
|
||||||
|
stl: "none",
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
testcases := []struct {
|
||||||
|
name string
|
||||||
|
expected []string
|
||||||
}{
|
}{
|
||||||
{"test_app_system_jni_system", []string{"libjni_system"}, []string{""}},
|
{
|
||||||
{"test_app_system_jni_system_ext", []string{"libjni_system_ext"}, []string{"_SYSTEM_EXT"}},
|
name: "app",
|
||||||
{"test_app_system_ext_jni_system", []string{"libjni_system"}, []string{""}},
|
expected: []string{"libjni"},
|
||||||
{"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"}},
|
name: "app_embedded",
|
||||||
{"test_app_odm_jni_vendor", []string{"libjni_vendor"}, []string{"_VENDOR"}},
|
expected: nil,
|
||||||
{"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 {
|
for _, tc := range testcases {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
mod := ctx.ModuleForTests(tc.name, "android_common").Module()
|
||||||
mod := ctx.ModuleForTests(test.name, "android_common").Module()
|
entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, mod)[0]
|
||||||
entry := android.AndroidMkEntriesForTest(t, ctx.TestContext, mod)[0]
|
required := entries.EntryMap["LOCAL_REQUIRED_MODULES"]
|
||||||
for i := range test.partitionNames {
|
android.AssertDeepEquals(t, "unexpected required deps", tc.expected, required)
|
||||||
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)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
java/app.go
21
java/app.go
@@ -911,6 +911,26 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
|
installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
|
||||||
extraInstalledPaths = append(extraInstalledPaths, installed)
|
extraInstalledPaths = append(extraInstalledPaths, installed)
|
||||||
}
|
}
|
||||||
|
// If we don't embed jni libs, make sure that those are installed along with the
|
||||||
|
// app, and also place symlinks to the installed paths under the lib/<arch>
|
||||||
|
// directory of the app installation directory. ex:
|
||||||
|
// /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
|
||||||
|
if !a.embeddedJniLibs {
|
||||||
|
for _, jniLib := range jniLibs {
|
||||||
|
archStr := jniLib.target.Arch.ArchType.String()
|
||||||
|
symlinkDir := a.installDir.Join(ctx, "lib", archStr)
|
||||||
|
for _, installedLib := range jniLib.installPaths {
|
||||||
|
// install the symlink target along with the app
|
||||||
|
extraInstalledPaths = append(extraInstalledPaths, installedLib)
|
||||||
|
ctx.PackageFile(installedLib, "", jniLib.path)
|
||||||
|
|
||||||
|
// install the symlink itself
|
||||||
|
symlinkName := installedLib.Base()
|
||||||
|
symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
|
||||||
|
ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
|
ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -998,6 +1018,7 @@ func collectJniDeps(ctx android.ModuleContext,
|
|||||||
coverageFile: dep.CoverageOutputFile(),
|
coverageFile: dep.CoverageOutputFile(),
|
||||||
unstrippedFile: dep.UnstrippedOutputFile(),
|
unstrippedFile: dep.UnstrippedOutputFile(),
|
||||||
partition: dep.Partition(),
|
partition: dep.Partition(),
|
||||||
|
installPaths: dep.FilesToInstall(),
|
||||||
})
|
})
|
||||||
} else if ctx.Config().AllowMissingDependencies() {
|
} else if ctx.Config().AllowMissingDependencies() {
|
||||||
ctx.AddMissingDependencies([]string{otherName})
|
ctx.AddMissingDependencies([]string{otherName})
|
||||||
|
@@ -491,6 +491,7 @@ type jniLib struct {
|
|||||||
coverageFile android.OptionalPath
|
coverageFile android.OptionalPath
|
||||||
unstrippedFile android.Path
|
unstrippedFile android.Path
|
||||||
partition string
|
partition string
|
||||||
|
installPaths android.InstallPaths
|
||||||
}
|
}
|
||||||
|
|
||||||
func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) {
|
func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) {
|
||||||
|
Reference in New Issue
Block a user