From bc625cd942bb218cc35250f9050d05b3caf5720a Mon Sep 17 00:00:00 2001 From: Jaewoong Jung Date: Mon, 6 May 2019 15:48:44 -0700 Subject: [PATCH] Add stl property to android_app. The flag is a Soong version of LOCAL_NDK_STL_VARIANT in apps and app tests. Unlike in the case of cc_library and its siblings, the only meaningful value for the make var when it's used in apps is 'c++_shared', in which case we add additional dependency to libc++. Fixes: 130891985 Test: app_test.go + CtsNdkBinderTestCases Change-Id: I83f45d375742164fff7f160a734b0686e56b5c38 --- java/app.go | 22 ++++++++++++++--- java/app_test.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/java/app.go b/java/app.go index 9f37836a3..f7f08a88d 100644 --- a/java/app.go +++ b/java/app.go @@ -85,6 +85,9 @@ type appProperties struct { // list of native libraries that will be provided in or alongside the resulting jar Jni_libs []string `android:"arch_variant"` + // STL library to use for JNI libraries. + 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. 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 false for other @@ -149,10 +152,15 @@ type Certificate struct { func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { a.Module.deps(ctx) + if String(a.appProperties.Stl) == "c++_shared" && a.sdkVersion() == "" { + ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared") + } + if !Bool(a.properties.No_framework_libs) && !Bool(a.properties.No_standard_libs) { a.aapt.deps(ctx, sdkContext(a)) } + embedJni := a.shouldEmbedJnis(ctx) for _, jniTarget := range ctx.MultiTargets() { variation := []blueprint.Variation{ {Mutator: "arch", Variation: jniTarget.String()}, @@ -162,6 +170,11 @@ func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { target: jniTarget, } ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs...) + if String(a.appProperties.Stl) == "c++_shared" { + if embedJni { + ctx.AddFarVariationDependencies(variation, tag, "libc++") + } + } } } @@ -217,6 +230,11 @@ func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool { return shouldUncompressDex(ctx, &a.dexpreopter) } +func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool { + return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) || + a.appProperties.AlwaysPackageNativeLibs +} + func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) { a.aapt.usesNonSdkApis = Bool(a.Module.deviceProperties.Platform_apis) @@ -305,9 +323,7 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path { func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, ctx android.ModuleContext) android.WritablePath { var jniJarFile android.WritablePath if len(jniLibs) > 0 { - embedJni := ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) || - a.appProperties.AlwaysPackageNativeLibs - if embedJni { + if a.shouldEmbedJnis(ctx) { jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip") TransformJniLibsToJar(ctx, jniJarFile, jniLibs, a.useEmbeddedNativeLibs(ctx)) } else { diff --git a/java/app_test.go b/java/app_test.go index 347139e15..40a64af8c 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -1178,3 +1178,64 @@ func TestAndroidAppImport_DpiVariants(t *testing.T) { } } } + +func TestStl(t *testing.T) { + ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` + cc_library { + name: "libjni", + } + + android_test { + name: "stl", + jni_libs: ["libjni"], + compile_multilib: "both", + sdk_version: "current", + stl: "c++_shared", + } + + android_test { + name: "system", + jni_libs: ["libjni"], + compile_multilib: "both", + sdk_version: "current", + } + `) + + testCases := []struct { + name string + jnis []string + }{ + {"stl", + []string{ + "libjni.so", + "libc++.so", + }, + }, + {"system", + []string{ + "libjni.so", + }, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + app := ctx.ModuleForTests(test.name, "android_common") + jniLibZip := app.Output("jnilibs.zip") + var jnis []string + args := strings.Fields(jniLibZip.Args["jarArgs"]) + for i := 0; i < len(args); i++ { + if args[i] == "-f" { + jnis = append(jnis, args[i+1]) + i += 1 + } + } + jnisJoined := strings.Join(jnis, " ") + for _, jni := range test.jnis { + if !strings.Contains(jnisJoined, jni) { + t.Errorf("missing jni %q in %q", jni, jnis) + } + } + }) + } +}