Merge changes Ifbe123d1,Ie2e738a6 into main
* changes:
Support min_sdk_version overrides in apexes
Support min_sdk_version overrides in apps
diff --git a/android/module.go b/android/module.go
index d4e4c2d..c17f315 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2161,9 +2161,19 @@
}
return proptools.ConfigurableValueUndefined()
case "product_variable":
- // TODO(b/323382414): Might add these on a case-by-case basis
- ctx.OtherModulePropertyErrorf(m, property, "TODO(b/323382414): Product variables are not yet supported in selects")
- return proptools.ConfigurableValueUndefined()
+ if condition.NumArgs() != 1 {
+ ctx.OtherModulePropertyErrorf(m, property, "product_variable requires 1 argument, found %d", condition.NumArgs())
+ return proptools.ConfigurableValueUndefined()
+ }
+ variable := condition.Arg(0)
+ switch variable {
+ case "debuggable":
+ return proptools.ConfigurableValueBool(ctx.Config().Debuggable())
+ default:
+ // TODO(b/323382414): Might add these on a case-by-case basis
+ ctx.OtherModulePropertyErrorf(m, property, fmt.Sprintf("TODO(b/323382414): Product variable %q is not yet supported in selects", variable))
+ return proptools.ConfigurableValueUndefined()
+ }
case "soong_config_variable":
if condition.NumArgs() != 2 {
ctx.OtherModulePropertyErrorf(m, property, "soong_config_variable requires 2 arguments, found %d", condition.NumArgs())
diff --git a/android/packaging.go b/android/packaging.go
index 080dcfe..a2b8755 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -20,6 +20,7 @@
"strings"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
)
// PackagingSpec abstracts a request to place a built artifact at a certain path in a package. A
@@ -150,7 +151,7 @@
type depsProperty struct {
// Modules to include in this package
- Deps []string `android:"arch_variant"`
+ Deps proptools.Configurable[[]string] `android:"arch_variant"`
}
type packagingMultilibProperties struct {
@@ -169,8 +170,8 @@
}
type PackagingProperties struct {
- Deps []string `android:"arch_variant"`
- Multilib packagingMultilibProperties `android:"arch_variant"`
+ Deps proptools.Configurable[[]string] `android:"arch_variant"`
+ Multilib packagingMultilibProperties `android:"arch_variant"`
Arch packagingArchProperties
}
@@ -188,38 +189,42 @@
// multi target, deps is selected for each of the targets and is NOT selected for the current
// architecture which would be Common.
func (p *PackagingBase) getDepsForArch(ctx BaseModuleContext, arch ArchType) []string {
+ get := func(prop proptools.Configurable[[]string]) []string {
+ return prop.GetOrDefault(ctx, nil)
+ }
+
var ret []string
if arch == ctx.Target().Arch.ArchType && len(ctx.MultiTargets()) == 0 {
- ret = append(ret, p.properties.Deps...)
+ ret = append(ret, get(p.properties.Deps)...)
} else if arch.Multilib == "lib32" {
- ret = append(ret, p.properties.Multilib.Lib32.Deps...)
+ ret = append(ret, get(p.properties.Multilib.Lib32.Deps)...)
} else if arch.Multilib == "lib64" {
- ret = append(ret, p.properties.Multilib.Lib64.Deps...)
+ ret = append(ret, get(p.properties.Multilib.Lib64.Deps)...)
} else if arch == Common {
- ret = append(ret, p.properties.Multilib.Common.Deps...)
+ ret = append(ret, get(p.properties.Multilib.Common.Deps)...)
}
if p.DepsCollectFirstTargetOnly {
- if len(p.properties.Multilib.First.Deps) > 0 {
+ if len(get(p.properties.Multilib.First.Deps)) > 0 {
ctx.PropertyErrorf("multilib.first.deps", "not supported. use \"deps\" instead")
}
for i, t := range ctx.MultiTargets() {
if t.Arch.ArchType == arch {
- ret = append(ret, p.properties.Multilib.Both.Deps...)
+ ret = append(ret, get(p.properties.Multilib.Both.Deps)...)
if i == 0 {
- ret = append(ret, p.properties.Deps...)
+ ret = append(ret, get(p.properties.Deps)...)
}
}
}
} else {
- if len(p.properties.Multilib.Both.Deps) > 0 {
+ if len(get(p.properties.Multilib.Both.Deps)) > 0 {
ctx.PropertyErrorf("multilib.both.deps", "not supported. use \"deps\" instead")
}
for i, t := range ctx.MultiTargets() {
if t.Arch.ArchType == arch {
- ret = append(ret, p.properties.Deps...)
+ ret = append(ret, get(p.properties.Deps)...)
if i == 0 {
- ret = append(ret, p.properties.Multilib.First.Deps...)
+ ret = append(ret, get(p.properties.Multilib.First.Deps)...)
}
}
}
@@ -228,13 +233,13 @@
if ctx.Arch().ArchType == Common {
switch arch {
case Arm64:
- ret = append(ret, p.properties.Arch.Arm64.Deps...)
+ ret = append(ret, get(p.properties.Arch.Arm64.Deps)...)
case Arm:
- ret = append(ret, p.properties.Arch.Arm.Deps...)
+ ret = append(ret, get(p.properties.Arch.Arm.Deps)...)
case X86_64:
- ret = append(ret, p.properties.Arch.X86_64.Deps...)
+ ret = append(ret, get(p.properties.Arch.X86_64.Deps)...)
case X86:
- ret = append(ret, p.properties.Arch.X86.Deps...)
+ ret = append(ret, get(p.properties.Arch.X86.Deps)...)
}
}
diff --git a/android/packaging_test.go b/android/packaging_test.go
index f99bb91..0570ec5 100644
--- a/android/packaging_test.go
+++ b/android/packaging_test.go
@@ -95,12 +95,13 @@
m.entries = m.CopyDepsToZip(ctx, m.GatherPackagingSpecs(ctx), zipFile)
}
-type packageTestModuleConfig struct {
+type testConfig struct {
multiTarget bool
depsCollectFirstTargetOnly bool
+ debuggable bool
}
-func runPackagingTest(t *testing.T, config packageTestModuleConfig, bp string, expected []string) {
+func runPackagingTest(t *testing.T, config testConfig, bp string, expected []string) {
t.Helper()
var archVariant string
@@ -120,6 +121,9 @@
ctx.RegisterModuleType("component", componentTestModuleFactory)
ctx.RegisterModuleType("package_module", moduleFactory)
}),
+ FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+ variables.Debuggable = proptools.BoolPtr(config.debuggable)
+ }),
FixtureWithRootAndroidBp(bp),
).RunTest(t)
@@ -131,7 +135,7 @@
}
func TestPackagingBaseMultiTarget(t *testing.T) {
- config := packageTestModuleConfig{
+ config := testConfig{
multiTarget: true,
depsCollectFirstTargetOnly: false,
}
@@ -258,7 +262,7 @@
}
func TestPackagingBaseSingleTarget(t *testing.T) {
- config := packageTestModuleConfig{
+ config := testConfig{
multiTarget: false,
depsCollectFirstTargetOnly: false,
}
@@ -383,7 +387,7 @@
func TestPackagingWithSkipInstallDeps(t *testing.T) {
// package -[dep]-> foo -[dep]-> bar -[dep]-> baz
// Packaging should continue transitively through modules that are not installed.
- config := packageTestModuleConfig{
+ config := testConfig{
multiTarget: false,
depsCollectFirstTargetOnly: false,
}
@@ -412,7 +416,7 @@
}
func TestPackagingWithDepsCollectFirstTargetOnly(t *testing.T) {
- config := packageTestModuleConfig{
+ config := testConfig{
multiTarget: true,
depsCollectFirstTargetOnly: true,
}
@@ -537,3 +541,46 @@
}
`, []string{"lib64/foo", "lib64/bar"})
}
+
+func TestDebuggableDeps(t *testing.T) {
+ bp := `
+ component {
+ name: "foo",
+ }
+
+ component {
+ name: "bar",
+ deps: ["baz"],
+ }
+
+ component {
+ name: "baz",
+ }
+
+ package_module {
+ name: "package",
+ deps: ["foo"] + select(product_variable("debuggable"), {
+ true: ["bar"],
+ default: [],
+ }),
+ }`
+ testcases := []struct {
+ debuggable bool
+ expected []string
+ }{
+ {
+ debuggable: true,
+ expected: []string{"lib64/foo", "lib64/bar", "lib64/baz"},
+ },
+ {
+ debuggable: false,
+ expected: []string{"lib64/foo"},
+ },
+ }
+ for _, tc := range testcases {
+ config := testConfig{
+ debuggable: tc.debuggable,
+ }
+ runPackagingTest(t, config, bp, tc.expected)
+ }
+}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index b9c2f92..a2c8896 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -5049,6 +5049,20 @@
// Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
// is disabled.
android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
+
+ // Make sure that we have atleast one platform library so that we can check the monolithic hiddenapi
+ // file creation.
+ java.FixtureConfigureBootJars("platform:foo"),
+ android.FixtureModifyMockFS(func(fs android.MockFS) {
+ fs["platform/Android.bp"] = []byte(`
+ java_library {
+ name: "foo",
+ srcs: ["Test.java"],
+ compile_dex: true,
+ }
+ `)
+ fs["platform/Test.java"] = nil
+ }),
)
checkBootDexJarPath := func(t *testing.T, ctx *android.TestContext, stem string, bootDexJarPath string) {
@@ -5143,7 +5157,7 @@
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
+ checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
my-bootclasspath-fragment/index.csv
out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
@@ -5221,7 +5235,7 @@
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
+ checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
my-bootclasspath-fragment/index.csv
out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
@@ -5410,7 +5424,7 @@
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
+ checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
my-bootclasspath-fragment/index.csv
out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
@@ -5507,7 +5521,7 @@
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/my-bootclasspath-fragment/android_common_myapex/hiddenapi-modular/encoded/libbar.jar")
// Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
+ checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
out/soong/.intermediates/my-bootclasspath-fragment/android_common_myapex/modular-hiddenapi/index.csv
@@ -5620,7 +5634,7 @@
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
+ checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
my-bootclasspath-fragment/index.csv
out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
@@ -5908,7 +5922,6 @@
srcs: ["foo/bar/MyClass.java"],
sdk_version: "current",
system_modules: "none",
- use_embedded_native_libs: true,
jni_libs: ["libjni"],
stl: "none",
apex_available: [ "myapex" ],
@@ -11239,6 +11252,20 @@
android.FixtureMergeMockFs(map[string][]byte{
"system/sepolicy/apex/com.android.foo-file_contexts": nil,
}),
+ // Make sure that we have atleast one platform library so that we can check the monolithic hiddenapi
+ // file creation.
+ java.FixtureConfigureBootJars("platform:foo"),
+ android.FixtureModifyMockFS(func(fs android.MockFS) {
+ fs["platform/Android.bp"] = []byte(`
+ java_library {
+ name: "foo",
+ srcs: ["Test.java"],
+ compile_dex: true,
+ }
+ `)
+ fs["platform/Test.java"] = nil
+ }),
+
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.BuildFlags = map[string]string{
"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": tc.selectedApexContributions,
diff --git a/cc/config/global.go b/cc/config/global.go
index 16b5e09..290a27d 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -136,6 +136,11 @@
// displaying logs in web browsers.
"-fmessage-length=0",
+ // Disable C++17 "relaxed template template argument matching" as a workaround for
+ // our out-dated libcxx.
+ // http://b/341084395
+ "-fno-relaxed-template-template-args",
+
// Using simple template names reduces the size of debug builds.
"-gsimple-template-names",
diff --git a/java/androidmk.go b/java/androidmk.go
index 4316074..4f740b2 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -17,6 +17,7 @@
import (
"fmt"
"io"
+ "strings"
"android/soong/android"
@@ -412,6 +413,23 @@
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 {
diff --git a/java/androidmk_test.go b/java/androidmk_test.go
index 875e06f..2978a40 100644
--- a/java/androidmk_test.go
+++ b/java/androidmk_test.go
@@ -19,6 +19,9 @@
"testing"
"android/soong/android"
+ "android/soong/cc"
+
+ "github.com/google/blueprint/proptools"
)
func TestRequired(t *testing.T) {
@@ -252,3 +255,149 @@
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)
+ }
+ })
+ }
+}
diff --git a/java/app.go b/java/app.go
index ea72157..bab4130 100644
--- a/java/app.go
+++ b/java/app.go
@@ -274,37 +274,16 @@
variation := append(jniTarget.Variations(),
blueprint.Variation{Mutator: "link", Variation: "shared"})
- // Test whether to use the SDK variant or the non-SDK variant of JNI dependencies.
- // Many factors are considered here.
- // 1. Basically, the selection follows whether the app has sdk_version set or not.
- jniUsesSdkVariant := usesSDK
- // 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it
- if Bool(a.appProperties.Jni_uses_sdk_apis) {
- jniUsesSdkVariant = true
- }
- if Bool(a.appProperties.Jni_uses_platform_apis) {
- jniUsesSdkVariant = false
- }
- // 3. Then the use of SDK variant is again prohibited for the following cases:
- // 3.1. the app is shipped on unbundled partitions like vendor. Since the entire
- // partition (not only the app) is considered unbudled, there's no need to use the
- // SDK variant.
- // 3.2. the app doesn't support embedding the JNI libs
- if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) {
- jniUsesSdkVariant = false
- }
- if jniUsesSdkVariant {
+ // If the app builds against an Android SDK use the SDK variant of JNI dependencies
+ // unless jni_uses_platform_apis is set.
+ // Don't require the SDK variant for apps that are shipped on vendor, etc., as they already
+ // have stable APIs through the VNDK.
+ if (usesSDK && !a.RequiresStableAPIs(ctx) &&
+ !Bool(a.appProperties.Jni_uses_platform_apis)) ||
+ Bool(a.appProperties.Jni_uses_sdk_apis) {
variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
}
-
- // Use the installable dep tag when the JNIs are not embedded
- var tag dependencyTag
- if a.shouldEmbedJnis(ctx) {
- tag = jniLibTag
- } else {
- tag = jniInstallTag
- }
- ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs...)
+ ctx.AddFarVariationDependencies(variation, jniLibTag, a.appProperties.Jni_libs...)
}
for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
@@ -355,7 +334,6 @@
func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.checkAppSdkVersions(ctx)
- a.checkEmbedJnis(ctx)
a.generateAndroidBuildActions(ctx)
a.generateJavaUsedByApex(ctx)
}
@@ -389,17 +367,6 @@
a.checkSdkVersions(ctx)
}
-// Ensures that use_embedded_native_libs are set for apk-in-apex
-func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) {
- apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
- apkInApex := !apexInfo.IsForPlatform()
- hasJnis := len(a.appProperties.Jni_libs) > 0
-
- if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) {
- ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true")
- }
-}
-
// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
// This check is enforced for "updatable" APKs (including APK-in-APEX).
func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
@@ -455,9 +422,9 @@
}
func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
+ apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
- Bool(a.appProperties.Updatable) ||
- a.appProperties.AlwaysPackageNativeLibs
+ !apexInfo.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs
}
func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
@@ -851,9 +818,7 @@
dexJarFile, packageResources := a.dexBuildActions(ctx)
- // No need to check the SDK version of the JNI deps unless we embed them
- checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
- jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
+ 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() {
@@ -935,22 +900,6 @@
installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
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 itself
- symlinkName := installedLib.Base()
- symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
- ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
- }
- }
- }
ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
}
@@ -1038,7 +987,6 @@
coverageFile: dep.CoverageOutputFile(),
unstrippedFile: dep.UnstrippedOutputFile(),
partition: dep.Partition(),
- installPaths: dep.FilesToInstall(),
})
} else if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{otherName})
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index 330013e..6229797 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -198,13 +198,22 @@
hiddenApiFixtureFactory,
tc.preparer,
prepareForTestWithDefaultPlatformBootclasspath,
+ // Make sure that we have atleast one platform library so that we can check the monolithic hiddenapi
+ // file creation.
+ FixtureConfigureBootJars("platform:foo"),
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.Always_use_prebuilt_sdks = proptools.BoolPtr(tc.unbundledBuild)
variables.BuildFlags = map[string]string{
"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
}
}),
- ).RunTest(t)
+ ).RunTestWithBp(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ compile_dex: true,
+ }
+ `)
hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
diff --git a/java/java.go b/java/java.go
index e3f4824..f038f63 100644
--- a/java/java.go
+++ b/java/java.go
@@ -366,14 +366,14 @@
toolchain bool
static bool
-
- installable bool
}
-var _ android.InstallNeededDependencyTag = (*dependencyTag)(nil)
-
-func (d dependencyTag) InstallDepNeeded() bool {
- return d.installable
+// 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 {
+ blueprint.BaseDependencyTag
+ android.InstallAlwaysNeededDependencyTag
+ name string
}
func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation {
@@ -405,7 +405,7 @@
}
func IsJniDepTag(depTag blueprint.DependencyTag) bool {
- return depTag == jniLibTag || depTag == jniInstallTag
+ return depTag == jniLibTag
}
var (
@@ -434,8 +434,8 @@
javaApiContributionTag = dependencyTag{name: "java-api-contribution"}
depApiSrcsTag = dependencyTag{name: "dep-api-srcs"}
aconfigDeclarationTag = dependencyTag{name: "aconfig-declaration"}
- jniInstallTag = dependencyTag{name: "jni install", runtimeLinked: true, installable: true}
- binaryInstallTag = dependencyTag{name: "binary install", runtimeLinked: true, installable: true}
+ jniInstallTag = installDependencyTag{name: "jni install"}
+ binaryInstallTag = installDependencyTag{name: "binary install"}
usesLibReqTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false)
usesLibOptTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true)
usesLibCompat28OptTag = makeUsesLibraryDependencyTag(28, true)
@@ -491,7 +491,6 @@
coverageFile android.OptionalPath
unstrippedFile android.Path
partition string
- installPaths android.InstallPaths
}
func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) {
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index b3c9ce5..0f87b27 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -325,6 +325,11 @@
// the fragments will have already provided the flags that are needed.
classesJars := monolithicInfo.ClassesJars
+ if len(classesJars) == 0 {
+ // This product does not include any monolithic jars. Monolithic hiddenapi flag generation is not required.
+ return bootDexJarByModule
+ }
+
// Create the input to pass to buildRuleToGenerateHiddenAPIStubFlagsFile
input := newHiddenAPIFlagInput()
diff --git a/rust/builder.go b/rust/builder.go
index abbf90d..1ce92f4 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -158,7 +158,9 @@
func TransformSrcToBinary(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
+ if ctx.RustModule().compiler.Thinlto() {
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
+ }
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "bin"))
}
@@ -212,20 +214,28 @@
func TransformSrctoDylib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
+ if ctx.RustModule().compiler.Thinlto() {
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
+ }
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "dylib"))
}
func TransformSrctoStatic(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
+ if ctx.RustModule().compiler.Thinlto() {
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
+ }
+
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "staticlib"))
}
func TransformSrctoShared(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
+ if ctx.RustModule().compiler.Thinlto() {
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
+ }
+
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "cdylib"))
}
diff --git a/rust/compiler.go b/rust/compiler.go
index 5033fba..efc3dee 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -47,6 +47,7 @@
edition() string
features() []string
rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath
+ Thinlto() bool
// Output directory in which source-generated code from dependencies is
// copied. This is equivalent to Cargo's OUT_DIR variable.
@@ -231,6 +232,15 @@
// If cargo_env_compat is true, sets the CARGO_PKG_VERSION env var to this value.
Cargo_pkg_version *string
+
+ // Control whether LTO is used for the final (Rust) linkage. This does not impact
+ // cross-language LTO.
+ Lto struct {
+ // Whether thin LTO should be enabled. By default this is true.
+ // LTO provides such a large code size benefit for Rust, this should always
+ // be enabled for production builds unless there's a clear need to disable it.
+ Thin *bool `android:"arch_variant"`
+ } `android:"arch_variant"`
}
type baseCompiler struct {
@@ -273,6 +283,11 @@
return false
}
+// Thin LTO is enabled by default.
+func (compiler *baseCompiler) Thinlto() bool {
+ return BoolDefault(compiler.Properties.Lto.Thin, true)
+}
+
func (compiler *baseCompiler) SetDisabled() {
panic("baseCompiler does not implement SetDisabled()")
}
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index 89f4d1a..4caa12b 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -63,6 +63,35 @@
}
}
+func TestLtoFlag(t *testing.T) {
+ ctx := testRust(t, `
+ rust_library_host {
+ name: "libfoo",
+ srcs: ["foo.rs"],
+ crate_name: "foo",
+ lto: {
+ thin: false,
+ }
+ }
+
+ rust_library_host {
+ name: "libfoo_lto",
+ srcs: ["foo.rs"],
+ crate_name: "foo",
+ }
+ `)
+
+ libfoo := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
+ libfooLto := ctx.ModuleForTests("libfoo_lto", "linux_glibc_x86_64_dylib").Rule("rustc")
+
+ if strings.Contains(libfoo.Args["rustcFlags"], "-C lto=thin") {
+ t.Fatalf("libfoo expected to disable lto -- rustcFlags: %#v", libfoo.Args["rustcFlags"])
+ }
+ if !strings.Contains(libfooLto.Args["rustcFlags"], "-C lto=thin") {
+ t.Fatalf("libfoo expected to enable lto by default -- rustcFlags: %#v", libfooLto.Args["rustcFlags"])
+ }
+}
+
// Test that we reject multiple source files.
func TestEnforceSingleSourceFile(t *testing.T) {
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index 6e25122..7048a15 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -281,6 +281,19 @@
"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
}
}),
+ // Make sure that we have atleast one platform library so that we can check the monolithic hiddenapi
+ // file creation.
+ java.FixtureConfigureBootJars("platform:foo"),
+ android.FixtureModifyMockFS(func(fs android.MockFS) {
+ fs["platform/Android.bp"] = []byte(`
+ java_library {
+ name: "foo",
+ srcs: ["Test.java"],
+ compile_dex: true,
+ }
+ `)
+ fs["platform/Test.java"] = nil
+ }),
android.FixtureWithRootAndroidBp(sdk+`
apex {