Port uses-shared library verification and dexpreopting to Soong
Ports 09f3b97f4b488cd3a7b7d72038b173575b02c162 (Add support for preopt with uses-libraries) from Make to Soong to support verifying and preopting shared libraries. This reapplies Id25f55f07a55120bebe2a9b32c094209efc85c8b with fixes for unbundled builds and builds with ALLOW_MISSING_DEPENDENCIES=true set. Bug: 132357300 Test: app_test.go Test: m checkbuild Change-Id: I964309a68ec4ed081f3f3154879c71048ecb5455
This commit is contained in:
parent
7d06395f0c
commit
50ddcc4b69
|
@ -1103,6 +1103,10 @@ func (c *config) ProductCompatibleProperty() bool {
|
|||
return Bool(c.productVariables.ProductCompatibleProperty)
|
||||
}
|
||||
|
||||
func (c *config) MissingUsesLibraries() []string {
|
||||
return c.productVariables.MissingUsesLibraries
|
||||
}
|
||||
|
||||
func (c *deviceConfig) BoardVndkRuntimeDisable() bool {
|
||||
return Bool(c.config.productVariables.BoardVndkRuntimeDisable)
|
||||
}
|
||||
|
|
|
@ -306,6 +306,8 @@ type productVariables struct {
|
|||
ProductCompatibleProperty *bool `json:",omitempty"`
|
||||
|
||||
TargetFSConfigGen []string `json:",omitempty"`
|
||||
|
||||
MissingUsesLibraries []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
func boolPtr(v bool) *bool {
|
||||
|
|
|
@ -65,8 +65,6 @@ type GlobalConfig struct {
|
|||
AlwaysOtherDebugInfo bool // always generate mini debug info for non-system server modules (overrides NoDebugInfo=true)
|
||||
NeverOtherDebugInfo bool // never generate mini debug info for non-system server modules (overrides NoDebugInfo=true)
|
||||
|
||||
MissingUsesLibraries []string // libraries that may be listed in OptionalUsesLibraries but will not be installed by the product
|
||||
|
||||
IsEng bool // build is a eng variant
|
||||
SanitizeLite bool // build is the second phase of a SANITIZE_LITE build
|
||||
|
||||
|
@ -119,7 +117,7 @@ type ModuleConfig struct {
|
|||
ProfileIsTextListing bool
|
||||
|
||||
EnforceUsesLibraries bool
|
||||
OptionalUsesLibraries []string
|
||||
PresentOptionalUsesLibraries []string
|
||||
UsesLibraries []string
|
||||
LibraryPaths map[string]android.Path
|
||||
|
||||
|
@ -310,7 +308,6 @@ func GlobalConfigForTests(ctx android.PathContext) GlobalConfig {
|
|||
NeverSystemServerDebugInfo: false,
|
||||
AlwaysOtherDebugInfo: false,
|
||||
NeverOtherDebugInfo: false,
|
||||
MissingUsesLibraries: nil,
|
||||
IsEng: false,
|
||||
SanitizeLite: false,
|
||||
DefaultAppImages: false,
|
||||
|
|
|
@ -226,11 +226,6 @@ func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module Modul
|
|||
bootImageLocation = PathToLocation(bootImage, arch)
|
||||
}
|
||||
|
||||
// Lists of used and optional libraries from the build config, with optional libraries that are known to not
|
||||
// be present in the current product removed.
|
||||
var filteredUsesLibs []string
|
||||
var filteredOptionalUsesLibs []string
|
||||
|
||||
// The class loader context using paths in the build
|
||||
var classLoaderContextHost android.Paths
|
||||
|
||||
|
@ -248,11 +243,10 @@ func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module Modul
|
|||
var classLoaderContextHostString string
|
||||
|
||||
if module.EnforceUsesLibraries {
|
||||
filteredOptionalUsesLibs = filterOut(global.MissingUsesLibraries, module.OptionalUsesLibraries)
|
||||
filteredUsesLibs = append(copyOf(module.UsesLibraries), filteredOptionalUsesLibs...)
|
||||
usesLibs := append(copyOf(module.UsesLibraries), module.PresentOptionalUsesLibraries...)
|
||||
|
||||
// Create class loader context for dex2oat from uses libraries and filtered optional libraries
|
||||
for _, l := range filteredUsesLibs {
|
||||
for _, l := range usesLibs {
|
||||
|
||||
classLoaderContextHost = append(classLoaderContextHost,
|
||||
pathForLibrary(module, l))
|
||||
|
@ -267,7 +261,9 @@ func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module Modul
|
|||
// targetSdkVersion in the manifest or APK is < 28, and the module does not explicitly depend on
|
||||
// org.apache.http.legacy, then implicitly add the classes to the classpath for dexpreopt. One the
|
||||
// device the classes will be in a file called org.apache.http.legacy.impl.jar.
|
||||
if !contains(module.UsesLibraries, httpLegacy) && !contains(module.OptionalUsesLibraries, httpLegacy) {
|
||||
module.LibraryPaths[httpLegacyImpl] = module.LibraryPaths[httpLegacy]
|
||||
|
||||
if !contains(module.UsesLibraries, httpLegacy) && !contains(module.PresentOptionalUsesLibraries, httpLegacy) {
|
||||
conditionalClassLoaderContextHost28 = append(conditionalClassLoaderContextHost28,
|
||||
pathForLibrary(module, httpLegacyImpl))
|
||||
conditionalClassLoaderContextTarget28 = append(conditionalClassLoaderContextTarget28,
|
||||
|
|
|
@ -33,7 +33,7 @@ func testModuleConfig(ctx android.PathContext) ModuleConfig {
|
|||
ProfileClassListing: android.OptionalPath{},
|
||||
ProfileIsTextListing: false,
|
||||
EnforceUsesLibraries: false,
|
||||
OptionalUsesLibraries: nil,
|
||||
PresentOptionalUsesLibraries: nil,
|
||||
UsesLibraries: nil,
|
||||
LibraryPaths: nil,
|
||||
Archs: []android.ArchType{android.Arm},
|
||||
|
|
173
java/app.go
173
java/app.go
|
@ -17,12 +17,13 @@ package java
|
|||
// This file contains the module types for compiling Android apps.
|
||||
|
||||
import (
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/proptools"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/proptools"
|
||||
|
||||
"android/soong/android"
|
||||
"android/soong/cc"
|
||||
"android/soong/tradefed"
|
||||
|
@ -119,6 +120,8 @@ type AndroidApp struct {
|
|||
aapt
|
||||
android.OverridableModuleBase
|
||||
|
||||
usesLibrary usesLibrary
|
||||
|
||||
certificate Certificate
|
||||
|
||||
appProperties appProperties
|
||||
|
@ -176,6 +179,8 @@ func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
a.usesLibrary.deps(ctx, Bool(a.properties.No_framework_libs))
|
||||
}
|
||||
|
||||
func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
|
||||
|
@ -276,6 +281,7 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
|
|||
aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
|
||||
|
||||
a.aapt.splitNames = a.appProperties.Package_splits
|
||||
a.aapt.sdkLibraries = a.exportedSdkLibs
|
||||
|
||||
a.aapt.buildActions(ctx, sdkContext(a), aaptLinkFlags...)
|
||||
|
||||
|
@ -308,9 +314,17 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
|
|||
} else {
|
||||
installDir = filepath.Join("app", a.installApkName)
|
||||
}
|
||||
|
||||
a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
|
||||
a.dexpreopter.isInstallable = Bool(a.properties.Installable)
|
||||
a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
|
||||
|
||||
a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
|
||||
a.dexpreopter.usesLibs = a.usesLibrary.usesLibraryProperties.Uses_libs
|
||||
a.dexpreopter.optionalUsesLibs = a.usesLibrary.presentOptionalUsesLibs(ctx)
|
||||
a.dexpreopter.libraryPaths = a.usesLibrary.usesLibraryPaths(ctx)
|
||||
a.dexpreopter.manifestFile = a.mergedManifestFile
|
||||
|
||||
a.deviceProperties.UncompressDex = a.dexpreopter.uncompressedDex
|
||||
|
||||
if ctx.ModuleName() != "framework-res" {
|
||||
|
@ -368,12 +382,19 @@ func processMainCert(m android.ModuleBase, certPropValue string, certificates []
|
|||
}
|
||||
|
||||
func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
var apkDeps android.Paths
|
||||
|
||||
// Check if the install APK name needs to be overridden.
|
||||
a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(a.Name())
|
||||
|
||||
// Process all building blocks, from AAPT to certificates.
|
||||
a.aaptBuildActions(ctx)
|
||||
|
||||
if a.usesLibrary.enforceUsesLibraries() {
|
||||
manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(ctx, a.mergedManifestFile)
|
||||
apkDeps = append(apkDeps, manifestCheckFile)
|
||||
}
|
||||
|
||||
a.proguardBuildActions(ctx)
|
||||
|
||||
dexJarFile := a.dexBuildActions(ctx)
|
||||
|
@ -391,13 +412,13 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
// Build a final signed app package.
|
||||
// TODO(jungjw): Consider changing this to installApkName.
|
||||
packageFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".apk")
|
||||
CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates)
|
||||
CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps)
|
||||
a.outputFile = packageFile
|
||||
|
||||
for _, split := range a.aapt.splits {
|
||||
// Sign the split APKs
|
||||
packageFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"_"+split.suffix+".apk")
|
||||
CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates)
|
||||
CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps)
|
||||
a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
|
||||
}
|
||||
|
||||
|
@ -483,7 +504,8 @@ func AndroidAppFactory() android.Module {
|
|||
&module.Module.protoProperties,
|
||||
&module.aaptProperties,
|
||||
&module.appProperties,
|
||||
&module.overridableAppProperties)
|
||||
&module.overridableAppProperties,
|
||||
&module.usesLibrary.usesLibraryProperties)
|
||||
|
||||
module.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool {
|
||||
return class == android.Device && ctx.Config().DevicePrefer32BitApps()
|
||||
|
@ -559,6 +581,7 @@ func AndroidTestFactory() android.Module {
|
|||
&module.appProperties,
|
||||
&module.appTestProperties,
|
||||
&module.overridableAppProperties,
|
||||
&module.usesLibrary.usesLibraryProperties,
|
||||
&module.testProperties)
|
||||
|
||||
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
||||
|
@ -599,7 +622,8 @@ func AndroidTestHelperAppFactory() android.Module {
|
|||
&module.aaptProperties,
|
||||
&module.appProperties,
|
||||
&module.appTestHelperAppProperties,
|
||||
&module.overridableAppProperties)
|
||||
&module.overridableAppProperties,
|
||||
&module.usesLibrary.usesLibraryProperties)
|
||||
|
||||
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
||||
android.InitDefaultableModule(module)
|
||||
|
@ -666,6 +690,8 @@ type AndroidAppImport struct {
|
|||
certificate *Certificate
|
||||
|
||||
dexpreopter
|
||||
|
||||
usesLibrary usesLibrary
|
||||
}
|
||||
|
||||
type AndroidAppImportProperties struct {
|
||||
|
@ -753,6 +779,8 @@ func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|||
if cert != "" {
|
||||
ctx.AddDependency(ctx.Module(), certificateTag, cert)
|
||||
}
|
||||
|
||||
a.usesLibrary.deps(ctx, false)
|
||||
}
|
||||
|
||||
func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
|
||||
|
@ -808,7 +836,12 @@ func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext
|
|||
// TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK
|
||||
// TODO: LOCAL_PACKAGE_SPLITS
|
||||
|
||||
srcApk := android.PathForModuleSrc(ctx, a.getSrcApkPath(ctx))
|
||||
var srcApk android.Path
|
||||
srcApk = android.PathForModuleSrc(ctx, a.getSrcApkPath(ctx))
|
||||
|
||||
if a.usesLibrary.enforceUsesLibraries() {
|
||||
srcApk = a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk)
|
||||
}
|
||||
|
||||
// TODO: Install or embed JNI libraries
|
||||
|
||||
|
@ -821,6 +854,12 @@ func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext
|
|||
a.dexpreopter.isInstallable = true
|
||||
a.dexpreopter.isPresignedPrebuilt = Bool(a.properties.Presigned)
|
||||
a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
|
||||
|
||||
a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
|
||||
a.dexpreopter.usesLibs = a.usesLibrary.usesLibraryProperties.Uses_libs
|
||||
a.dexpreopter.optionalUsesLibs = a.usesLibrary.presentOptionalUsesLibs(ctx)
|
||||
a.dexpreopter.libraryPaths = a.usesLibrary.usesLibraryPaths(ctx)
|
||||
|
||||
dexOutput := a.dexpreopter.dexpreopt(ctx, jnisUncompressed)
|
||||
if a.dexpreopter.uncompressedDex {
|
||||
dexUncompressed := android.PathForModuleOut(ctx, "dex-uncompressed", ctx.ModuleName()+".apk")
|
||||
|
@ -866,9 +905,129 @@ func AndroidAppImportFactory() android.Module {
|
|||
module.properties.Dpi_variants = reflect.New(dpiVariantsStruct).Interface()
|
||||
module.AddProperties(&module.properties)
|
||||
module.AddProperties(&module.dexpreoptProperties)
|
||||
module.AddProperties(&module.usesLibrary.usesLibraryProperties)
|
||||
|
||||
InitJavaModule(module, android.DeviceSupported)
|
||||
android.InitSingleSourcePrebuiltModule(module, &module.properties.Apk)
|
||||
|
||||
return module
|
||||
}
|
||||
|
||||
type UsesLibraryProperties struct {
|
||||
// A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
|
||||
Uses_libs []string
|
||||
|
||||
// A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
|
||||
// required=false.
|
||||
Optional_uses_libs []string
|
||||
|
||||
// If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
|
||||
// to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
|
||||
Enforce_uses_libs *bool
|
||||
}
|
||||
|
||||
// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
|
||||
// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
|
||||
// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
|
||||
// with knowledge of their shared libraries.
|
||||
type usesLibrary struct {
|
||||
usesLibraryProperties UsesLibraryProperties
|
||||
}
|
||||
|
||||
func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, noFrameworkLibs bool) {
|
||||
ctx.AddVariationDependencies(nil, usesLibTag, u.usesLibraryProperties.Uses_libs...)
|
||||
ctx.AddVariationDependencies(nil, usesLibTag, u.presentOptionalUsesLibs(ctx)...)
|
||||
if !noFrameworkLibs {
|
||||
// dexpreopt/dexpreopt.go needs the paths to the dex jars of these libraries in case construct_context.sh needs
|
||||
// to pass them to dex2oat. Add them as a dependency so we can determine the path to the dex jar of each
|
||||
// library to dexpreopt.
|
||||
ctx.AddVariationDependencies(nil, usesLibTag,
|
||||
"org.apache.http.legacy",
|
||||
"android.hidl.base-V1.0-java",
|
||||
"android.hidl.manager-V1.0-java")
|
||||
}
|
||||
}
|
||||
|
||||
// presentOptionalUsesLibs returns optional_uses_libs after filtering out MissingUsesLibraries, which don't exist in the
|
||||
// build.
|
||||
func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
|
||||
optionalUsesLibs, _ := android.FilterList(u.usesLibraryProperties.Optional_uses_libs, ctx.Config().MissingUsesLibraries())
|
||||
return optionalUsesLibs
|
||||
}
|
||||
|
||||
// usesLibraryPaths returns a map of module names of shared library dependencies to the paths to their dex jars.
|
||||
func (u *usesLibrary) usesLibraryPaths(ctx android.ModuleContext) map[string]android.Path {
|
||||
usesLibPaths := make(map[string]android.Path)
|
||||
|
||||
if !ctx.Config().UnbundledBuild() {
|
||||
ctx.VisitDirectDepsWithTag(usesLibTag, func(m android.Module) {
|
||||
if lib, ok := m.(Dependency); ok {
|
||||
if dexJar := lib.DexJar(); dexJar != nil {
|
||||
usesLibPaths[ctx.OtherModuleName(m)] = dexJar
|
||||
} else {
|
||||
ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must produce a dex jar, does it have installable: true?",
|
||||
ctx.OtherModuleName(m))
|
||||
}
|
||||
} else if ctx.Config().AllowMissingDependencies() {
|
||||
ctx.AddMissingDependencies([]string{ctx.OtherModuleName(m)})
|
||||
} else {
|
||||
ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library",
|
||||
ctx.OtherModuleName(m))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return usesLibPaths
|
||||
}
|
||||
|
||||
// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
|
||||
// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
|
||||
// unconditionally in the future.
|
||||
func (u *usesLibrary) enforceUsesLibraries() bool {
|
||||
defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs) > 0 ||
|
||||
len(u.usesLibraryProperties.Optional_uses_libs) > 0
|
||||
return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, defaultEnforceUsesLibs)
|
||||
}
|
||||
|
||||
// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against the ones specified
|
||||
// in the uses_libs and optional_uses_libs properties. It returns the path to a copy of the manifest.
|
||||
func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path {
|
||||
outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
|
||||
|
||||
rule := android.NewRuleBuilder()
|
||||
cmd := rule.Command().Tool(ctx.Config().HostToolPath(ctx, "manifest_check")).
|
||||
Flag("--enforce-uses-libraries").
|
||||
Input(manifest).
|
||||
FlagWithOutput("-o ", outputFile)
|
||||
|
||||
for _, lib := range u.usesLibraryProperties.Uses_libs {
|
||||
cmd.FlagWithArg("--uses-library ", lib)
|
||||
}
|
||||
|
||||
for _, lib := range u.usesLibraryProperties.Optional_uses_libs {
|
||||
cmd.FlagWithArg("--optional-uses-library ", lib)
|
||||
}
|
||||
|
||||
rule.Build(pctx, ctx, "verify_uses_libraries", "verify <uses-library>")
|
||||
|
||||
return outputFile
|
||||
}
|
||||
|
||||
// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the ones specified
|
||||
// in the uses_libs and optional_uses_libs properties. It returns the path to a copy of the APK.
|
||||
func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) android.Path {
|
||||
outputFile := android.PathForModuleOut(ctx, "verify_uses_libraries", apk.Base())
|
||||
|
||||
rule := android.NewRuleBuilder()
|
||||
aapt := ctx.Config().HostToolPath(ctx, "aapt")
|
||||
rule.Command().
|
||||
Textf("aapt_binary=%s", aapt.String()).Implicit(aapt).
|
||||
Textf(`uses_library_names="%s"`, strings.Join(u.usesLibraryProperties.Uses_libs, " ")).
|
||||
Textf(`optional_uses_library_names="%s"`, strings.Join(u.usesLibraryProperties.Optional_uses_libs, " ")).
|
||||
Tool(android.PathForSource(ctx, "build/make/core/verify_uses_libraries.sh")).Input(apk)
|
||||
rule.Command().Text("cp -f").Input(apk).Output(outputFile)
|
||||
|
||||
rule.Build(pctx, ctx, "verify_uses_libraries", "verify <uses-library>")
|
||||
|
||||
return outputFile
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ var combineApk = pctx.AndroidStaticRule("combineApk",
|
|||
})
|
||||
|
||||
func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
|
||||
packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate) {
|
||||
packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths) {
|
||||
|
||||
unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk"
|
||||
unsignedApk := android.PathForModuleOut(ctx, unsignedApkName)
|
||||
|
@ -81,6 +81,7 @@ func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.Writa
|
|||
Rule: combineApk,
|
||||
Inputs: inputs,
|
||||
Output: unsignedApk,
|
||||
Implicits: deps,
|
||||
})
|
||||
|
||||
SignAppPackage(ctx, outputFile, unsignedApk, certificates)
|
||||
|
|
|
@ -1239,3 +1239,83 @@ func TestStl(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUsesLibraries(t *testing.T) {
|
||||
bp := `
|
||||
java_sdk_library {
|
||||
name: "foo",
|
||||
srcs: ["a.java"],
|
||||
api_packages: ["foo"],
|
||||
}
|
||||
|
||||
java_sdk_library {
|
||||
name: "bar",
|
||||
srcs: ["a.java"],
|
||||
api_packages: ["bar"],
|
||||
}
|
||||
|
||||
android_app {
|
||||
name: "app",
|
||||
srcs: ["a.java"],
|
||||
uses_libs: ["foo"],
|
||||
optional_uses_libs: [
|
||||
"bar",
|
||||
"baz",
|
||||
],
|
||||
}
|
||||
|
||||
android_app_import {
|
||||
name: "prebuilt",
|
||||
apk: "prebuilts/apk/app.apk",
|
||||
certificate: "platform",
|
||||
uses_libs: ["foo"],
|
||||
optional_uses_libs: [
|
||||
"bar",
|
||||
"baz",
|
||||
],
|
||||
}
|
||||
`
|
||||
|
||||
config := testConfig(nil)
|
||||
config.TestProductVariables.MissingUsesLibraries = []string{"baz"}
|
||||
|
||||
ctx := testAppContext(config, bp, nil)
|
||||
|
||||
run(t, ctx, config)
|
||||
|
||||
app := ctx.ModuleForTests("app", "android_common")
|
||||
prebuilt := ctx.ModuleForTests("prebuilt", "android_common")
|
||||
|
||||
// Test that all libraries are verified
|
||||
cmd := app.Rule("verify_uses_libraries").RuleParams.Command
|
||||
if w := "--uses-library foo"; !strings.Contains(cmd, w) {
|
||||
t.Errorf("wanted %q in %q", w, cmd)
|
||||
}
|
||||
|
||||
if w := "--optional-uses-library bar --optional-uses-library baz"; !strings.Contains(cmd, w) {
|
||||
t.Errorf("wanted %q in %q", w, cmd)
|
||||
}
|
||||
|
||||
cmd = prebuilt.Rule("verify_uses_libraries").RuleParams.Command
|
||||
|
||||
if w := `uses_library_names="foo"`; !strings.Contains(cmd, w) {
|
||||
t.Errorf("wanted %q in %q", w, cmd)
|
||||
}
|
||||
|
||||
if w := `optional_uses_library_names="bar baz"`; !strings.Contains(cmd, w) {
|
||||
t.Errorf("wanted %q in %q", w, cmd)
|
||||
}
|
||||
|
||||
// Test that only present libraries are preopted
|
||||
cmd = app.Rule("dexpreopt").RuleParams.Command
|
||||
|
||||
if w := `dex_preopt_target_libraries="/system/framework/foo.jar /system/framework/bar.jar"`; !strings.Contains(cmd, w) {
|
||||
t.Errorf("wanted %q in %q", w, cmd)
|
||||
}
|
||||
|
||||
cmd = prebuilt.Rule("dexpreopt").RuleParams.Command
|
||||
|
||||
if w := `dex_preopt_target_libraries="/system/framework/foo.jar /system/framework/bar.jar"`; !strings.Contains(cmd, w) {
|
||||
t.Errorf("wanted %q in %q", w, cmd)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,12 @@ type dexpreopter struct {
|
|||
isInstallable bool
|
||||
isPresignedPrebuilt bool
|
||||
|
||||
manifestFile android.Path
|
||||
usesLibs []string
|
||||
optionalUsesLibs []string
|
||||
enforceUsesLibs bool
|
||||
libraryPaths map[string]android.Path
|
||||
|
||||
builtInstalled string
|
||||
}
|
||||
|
||||
|
@ -154,6 +160,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
|
|||
DexLocation: dexLocation,
|
||||
BuildPath: android.PathForModuleOut(ctx, "dexpreopt", ctx.ModuleName()+".jar").OutputPath,
|
||||
DexPath: dexJarFile,
|
||||
ManifestPath: d.manifestFile,
|
||||
UncompressedDex: d.uncompressedDex,
|
||||
HasApkLibraries: false,
|
||||
PreoptFlags: nil,
|
||||
|
@ -161,10 +168,10 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
|
|||
ProfileClassListing: profileClassListing,
|
||||
ProfileIsTextListing: profileIsTextListing,
|
||||
|
||||
EnforceUsesLibraries: false,
|
||||
OptionalUsesLibraries: nil,
|
||||
UsesLibraries: nil,
|
||||
LibraryPaths: nil,
|
||||
EnforceUsesLibraries: d.enforceUsesLibs,
|
||||
PresentOptionalUsesLibraries: d.optionalUsesLibs,
|
||||
UsesLibraries: d.usesLibs,
|
||||
LibraryPaths: d.libraryPaths,
|
||||
|
||||
Archs: archs,
|
||||
DexPreoptImages: images,
|
||||
|
|
|
@ -420,6 +420,7 @@ var (
|
|||
proguardRaiseTag = dependencyTag{name: "proguard-raise"}
|
||||
certificateTag = dependencyTag{name: "certificate"}
|
||||
instrumentationForTag = dependencyTag{name: "instrumentation_for"}
|
||||
usesLibTag = dependencyTag{name: "uses-library"}
|
||||
)
|
||||
|
||||
type sdkDep struct {
|
||||
|
|
|
@ -174,6 +174,8 @@ func testContext(config android.Config, bp string,
|
|||
|
||||
"build/soong/scripts/jar-wrapper.sh": nil,
|
||||
|
||||
"build/make/core/verify_uses_libraries.sh": nil,
|
||||
|
||||
"build/make/core/proguard.flags": nil,
|
||||
"build/make/core/proguard_basic_keeps.flags": nil,
|
||||
|
||||
|
|
|
@ -77,6 +77,33 @@ func GatherRequiredDepsForTest() string {
|
|||
name: "framework-res",
|
||||
no_framework_libs: true,
|
||||
}
|
||||
|
||||
java_library {
|
||||
name: "android.hidl.base-V1.0-java",
|
||||
srcs: ["a.java"],
|
||||
no_standard_libs: true,
|
||||
sdk_version: "core_current",
|
||||
system_modules: "core-platform-api-stubs-system-modules",
|
||||
installable: true,
|
||||
}
|
||||
|
||||
java_library {
|
||||
name: "android.hidl.manager-V1.0-java",
|
||||
srcs: ["a.java"],
|
||||
no_standard_libs: true,
|
||||
sdk_version: "core_current",
|
||||
system_modules: "core-platform-api-stubs-system-modules",
|
||||
installable: true,
|
||||
}
|
||||
|
||||
java_library {
|
||||
name: "org.apache.http.legacy",
|
||||
srcs: ["a.java"],
|
||||
no_standard_libs: true,
|
||||
sdk_version: "core_current",
|
||||
system_modules: "core-platform-api-stubs-system-modules",
|
||||
installable: true,
|
||||
}
|
||||
`
|
||||
|
||||
systemModules := []string{
|
||||
|
|
Loading…
Reference in New Issue