Merge changes I957f3df8,I68986dcc
* changes: Consolidate the code to resolve a deapexer module dependency. Propagate the dex jar path as an OptionalPath which is either valid or invalid with a message.
This commit is contained in:
@@ -69,6 +69,8 @@ import (
|
|||||||
|
|
||||||
// The information exported by the `deapexer` module, access it using `DeapxerInfoProvider`.
|
// The information exported by the `deapexer` module, access it using `DeapxerInfoProvider`.
|
||||||
type DeapexerInfo struct {
|
type DeapexerInfo struct {
|
||||||
|
apexModuleName string
|
||||||
|
|
||||||
// map from the name of an exported file from a prebuilt_apex to the path to that file. The
|
// map from the name of an exported file from a prebuilt_apex to the path to that file. The
|
||||||
// exported file name is the apex relative path, e.g. javalib/core-libart.jar.
|
// exported file name is the apex relative path, e.g. javalib/core-libart.jar.
|
||||||
//
|
//
|
||||||
@@ -76,6 +78,11 @@ type DeapexerInfo struct {
|
|||||||
exports map[string]WritablePath
|
exports map[string]WritablePath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ApexModuleName returns the name of the APEX module that provided the info.
|
||||||
|
func (i DeapexerInfo) ApexModuleName() string {
|
||||||
|
return i.apexModuleName
|
||||||
|
}
|
||||||
|
|
||||||
// PrebuiltExportPath provides the path, or nil if not available, of a file exported from the
|
// PrebuiltExportPath provides the path, or nil if not available, of a file exported from the
|
||||||
// prebuilt_apex that created this ApexInfo.
|
// prebuilt_apex that created this ApexInfo.
|
||||||
//
|
//
|
||||||
@@ -95,9 +102,10 @@ var DeapexerProvider = blueprint.NewProvider(DeapexerInfo{})
|
|||||||
// for use with a prebuilt_apex module.
|
// for use with a prebuilt_apex module.
|
||||||
//
|
//
|
||||||
// See apex/deapexer.go for more information.
|
// See apex/deapexer.go for more information.
|
||||||
func NewDeapexerInfo(exports map[string]WritablePath) DeapexerInfo {
|
func NewDeapexerInfo(apexModuleName string, exports map[string]WritablePath) DeapexerInfo {
|
||||||
return DeapexerInfo{
|
return DeapexerInfo{
|
||||||
exports: exports,
|
apexModuleName: apexModuleName,
|
||||||
|
exports: exports,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,3 +141,20 @@ type RequiresFilesFromPrebuiltApexTag interface {
|
|||||||
// Method that differentiates this interface from others.
|
// Method that differentiates this interface from others.
|
||||||
RequiresFilesFromPrebuiltApex()
|
RequiresFilesFromPrebuiltApex()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindDeapexerProviderForModule searches through the direct dependencies of the current context
|
||||||
|
// module for a DeapexerTag dependency and returns its DeapexerInfo. If there is an error then it is
|
||||||
|
// reported with ctx.ModuleErrorf and nil is returned.
|
||||||
|
func FindDeapexerProviderForModule(ctx ModuleContext) *DeapexerInfo {
|
||||||
|
var di *DeapexerInfo
|
||||||
|
ctx.VisitDirectDepsWithTag(DeapexerTag, func(m Module) {
|
||||||
|
p := ctx.OtherModuleProvider(m, DeapexerProvider).(DeapexerInfo)
|
||||||
|
di = &p
|
||||||
|
})
|
||||||
|
if di != nil {
|
||||||
|
return di
|
||||||
|
}
|
||||||
|
ai := ctx.Provider(ApexInfoProvider).(ApexInfo)
|
||||||
|
ctx.ModuleErrorf("No prebuilt APEX provides a deapexer module for APEX variant %s", ai.ApexVariationName)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@@ -1545,7 +1545,7 @@ func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.Platform
|
|||||||
type javaModule interface {
|
type javaModule interface {
|
||||||
android.Module
|
android.Module
|
||||||
BaseModuleName() string
|
BaseModuleName() string
|
||||||
DexJarBuildPath() android.Path
|
DexJarBuildPath() java.OptionalDexJarPath
|
||||||
JacocoReportClassesFile() android.Path
|
JacocoReportClassesFile() android.Path
|
||||||
LintDepSets() java.LintDepSets
|
LintDepSets() java.LintDepSets
|
||||||
Stem() string
|
Stem() string
|
||||||
@@ -1559,7 +1559,7 @@ var _ javaModule = (*java.SdkLibraryImport)(nil)
|
|||||||
|
|
||||||
// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
|
// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
|
||||||
func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
|
func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
|
||||||
return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath())
|
return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath().PathOrNil())
|
||||||
}
|
}
|
||||||
|
|
||||||
// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
|
// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
|
||||||
|
@@ -4799,9 +4799,10 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) {
|
|||||||
transform := android.NullFixturePreparer
|
transform := android.NullFixturePreparer
|
||||||
|
|
||||||
checkDexJarBuildPath := func(t *testing.T, ctx *android.TestContext, name string) {
|
checkDexJarBuildPath := func(t *testing.T, ctx *android.TestContext, name string) {
|
||||||
|
t.Helper()
|
||||||
// Make sure the import has been given the correct path to the dex jar.
|
// Make sure the import has been given the correct path to the dex jar.
|
||||||
p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
|
p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
|
||||||
dexJarBuildPath := p.DexJarBuildPath()
|
dexJarBuildPath := p.DexJarBuildPath().PathOrNil()
|
||||||
stem := android.RemoveOptionalPrebuiltPrefix(name)
|
stem := android.RemoveOptionalPrebuiltPrefix(name)
|
||||||
android.AssertStringEquals(t, "DexJarBuildPath should be apex-related path.",
|
android.AssertStringEquals(t, "DexJarBuildPath should be apex-related path.",
|
||||||
".intermediates/myapex.deapexer/android_common/deapexer/javalib/"+stem+".jar",
|
".intermediates/myapex.deapexer/android_common/deapexer/javalib/"+stem+".jar",
|
||||||
@@ -4809,6 +4810,7 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkDexJarInstallPath := func(t *testing.T, ctx *android.TestContext, name string) {
|
checkDexJarInstallPath := func(t *testing.T, ctx *android.TestContext, name string) {
|
||||||
|
t.Helper()
|
||||||
// Make sure the import has been given the correct path to the dex jar.
|
// Make sure the import has been given the correct path to the dex jar.
|
||||||
p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
|
p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
|
||||||
dexJarBuildPath := p.DexJarInstallPath()
|
dexJarBuildPath := p.DexJarInstallPath()
|
||||||
@@ -4819,6 +4821,7 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ensureNoSourceVariant := func(t *testing.T, ctx *android.TestContext, name string) {
|
ensureNoSourceVariant := func(t *testing.T, ctx *android.TestContext, name string) {
|
||||||
|
t.Helper()
|
||||||
// Make sure that an apex variant is not created for the source module.
|
// Make sure that an apex variant is not created for the source module.
|
||||||
android.AssertArrayString(t, "Check if there is no source variant",
|
android.AssertArrayString(t, "Check if there is no source variant",
|
||||||
[]string{"android_common"},
|
[]string{"android_common"},
|
||||||
@@ -4856,8 +4859,11 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) {
|
|||||||
// Make sure that dexpreopt can access dex implementation files from the prebuilt.
|
// Make sure that dexpreopt can access dex implementation files from the prebuilt.
|
||||||
ctx := testDexpreoptWithApexes(t, bp, "", transform)
|
ctx := testDexpreoptWithApexes(t, bp, "", transform)
|
||||||
|
|
||||||
|
deapexerName := deapexerModuleName("myapex")
|
||||||
|
android.AssertStringEquals(t, "APEX module name from deapexer name", "myapex", apexModuleName(deapexerName))
|
||||||
|
|
||||||
// Make sure that the deapexer has the correct input APEX.
|
// Make sure that the deapexer has the correct input APEX.
|
||||||
deapexer := ctx.ModuleForTests("myapex.deapexer", "android_common")
|
deapexer := ctx.ModuleForTests(deapexerName, "android_common")
|
||||||
rule := deapexer.Rule("deapexer")
|
rule := deapexer.Rule("deapexer")
|
||||||
if expected, actual := []string{"myapex-arm64.apex"}, android.NormalizePathsForTesting(rule.Implicits); !reflect.DeepEqual(expected, actual) {
|
if expected, actual := []string{"myapex-arm64.apex"}, android.NormalizePathsForTesting(rule.Implicits); !reflect.DeepEqual(expected, actual) {
|
||||||
t.Errorf("expected: %q, found: %q", expected, actual)
|
t.Errorf("expected: %q, found: %q", expected, actual)
|
||||||
|
@@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
"android/soong/java"
|
"android/soong/java"
|
||||||
|
|
||||||
"github.com/google/blueprint/proptools"
|
"github.com/google/blueprint/proptools"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -737,7 +738,7 @@ func TestBootclasspathFragmentContentsNoName(t *testing.T) {
|
|||||||
|
|
||||||
func getDexJarPath(result *android.TestResult, name string) string {
|
func getDexJarPath(result *android.TestResult, name string) string {
|
||||||
module := result.Module(name, "android_common")
|
module := result.Module(name, "android_common")
|
||||||
return module.(java.UsesLibraryDependency).DexJarBuildPath().RelativeToTop().String()
|
return module.(java.UsesLibraryDependency).DexJarBuildPath().Path().RelativeToTop().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestBootclasspathFragment_HiddenAPIList checks to make sure that the correct parameters are
|
// TestBootclasspathFragment_HiddenAPIList checks to make sure that the correct parameters are
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
package apex
|
package apex
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -75,6 +77,17 @@ type Deapexer struct {
|
|||||||
inputApex android.Path
|
inputApex android.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the name of the deapexer module corresponding to an APEX module with the given name.
|
||||||
|
func deapexerModuleName(apexModuleName string) string {
|
||||||
|
return apexModuleName + ".deapexer"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the name of the APEX module corresponding to an deapexer module with
|
||||||
|
// the given name. This reverses deapexerModuleName.
|
||||||
|
func apexModuleName(deapexerModuleName string) string {
|
||||||
|
return strings.TrimSuffix(deapexerModuleName, ".deapexer")
|
||||||
|
}
|
||||||
|
|
||||||
func privateDeapexerFactory() android.Module {
|
func privateDeapexerFactory() android.Module {
|
||||||
module := &Deapexer{}
|
module := &Deapexer{}
|
||||||
module.AddProperties(&module.properties, &module.selectedApexProperties)
|
module.AddProperties(&module.properties, &module.selectedApexProperties)
|
||||||
@@ -113,7 +126,8 @@ func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
// apex relative path to extracted file path available for other modules.
|
// apex relative path to extracted file path available for other modules.
|
||||||
if len(exports) > 0 {
|
if len(exports) > 0 {
|
||||||
// Make the information available for other modules.
|
// Make the information available for other modules.
|
||||||
ctx.SetProvider(android.DeapexerProvider, android.NewDeapexerInfo(exports))
|
di := android.NewDeapexerInfo(apexModuleName(ctx.ModuleName()), exports)
|
||||||
|
ctx.SetProvider(android.DeapexerProvider, di)
|
||||||
|
|
||||||
// Create a sorted list of the files that this exports.
|
// Create a sorted list of the files that this exports.
|
||||||
exportedPaths = android.SortedUniquePaths(exportedPaths)
|
exportedPaths = android.SortedUniquePaths(exportedPaths)
|
||||||
@@ -131,6 +145,6 @@ func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
for _, p := range exportedPaths {
|
for _, p := range exportedPaths {
|
||||||
command.Output(p.(android.WritablePath))
|
command.Output(p.(android.WritablePath))
|
||||||
}
|
}
|
||||||
builder.Build("deapexer", "deapex "+ctx.ModuleName())
|
builder.Build("deapexer", "deapex "+apexModuleName(ctx.ModuleName()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -176,13 +176,15 @@ func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) {
|
|||||||
name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child))
|
name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child))
|
||||||
if java.IsBootclasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag {
|
if java.IsBootclasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag {
|
||||||
// If the exported java module provides a dex jar path then add it to the list of apexFiles.
|
// If the exported java module provides a dex jar path then add it to the list of apexFiles.
|
||||||
path := child.(interface{ DexJarBuildPath() android.Path }).DexJarBuildPath()
|
path := child.(interface {
|
||||||
if path != nil {
|
DexJarBuildPath() java.OptionalDexJarPath
|
||||||
|
}).DexJarBuildPath()
|
||||||
|
if path.IsSet() {
|
||||||
af := apexFile{
|
af := apexFile{
|
||||||
module: child,
|
module: child,
|
||||||
moduleDir: ctx.OtherModuleDir(child),
|
moduleDir: ctx.OtherModuleDir(child),
|
||||||
androidMkModuleName: name,
|
androidMkModuleName: name,
|
||||||
builtFile: path,
|
builtFile: path.Path(),
|
||||||
class: javaSharedLib,
|
class: javaSharedLib,
|
||||||
}
|
}
|
||||||
if module, ok := child.(java.DexpreopterInterface); ok {
|
if module, ok := child.(java.DexpreopterInterface); ok {
|
||||||
@@ -629,10 +631,6 @@ func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerNam
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deapexerModuleName(baseModuleName string) string {
|
|
||||||
return baseModuleName + ".deapexer"
|
|
||||||
}
|
|
||||||
|
|
||||||
func apexSelectorModuleName(baseModuleName string) string {
|
func apexSelectorModuleName(baseModuleName string) string {
|
||||||
return baseModuleName + ".apex.selector"
|
return baseModuleName + ".apex.selector"
|
||||||
}
|
}
|
||||||
|
@@ -29,8 +29,8 @@ func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries {
|
|||||||
|
|
||||||
if hostDexNeeded {
|
if hostDexNeeded {
|
||||||
var output android.Path
|
var output android.Path
|
||||||
if library.dexJarFile != nil {
|
if library.dexJarFile.IsSet() {
|
||||||
output = library.dexJarFile
|
output = library.dexJarFile.Path()
|
||||||
} else {
|
} else {
|
||||||
output = library.implementationAndResourcesJar
|
output = library.implementationAndResourcesJar
|
||||||
}
|
}
|
||||||
@@ -44,8 +44,8 @@ func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries {
|
|||||||
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
||||||
entries.SetBool("LOCAL_IS_HOST_MODULE", true)
|
entries.SetBool("LOCAL_IS_HOST_MODULE", true)
|
||||||
entries.SetPath("LOCAL_PREBUILT_MODULE_FILE", output)
|
entries.SetPath("LOCAL_PREBUILT_MODULE_FILE", output)
|
||||||
if library.dexJarFile != nil {
|
if library.dexJarFile.IsSet() {
|
||||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", library.dexJarFile)
|
entries.SetPath("LOCAL_SOONG_DEX_JAR", library.dexJarFile.Path())
|
||||||
}
|
}
|
||||||
entries.SetPath("LOCAL_SOONG_HEADER_JAR", library.headerJarFile)
|
entries.SetPath("LOCAL_SOONG_HEADER_JAR", library.headerJarFile)
|
||||||
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", library.implementationAndResourcesJar)
|
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", library.implementationAndResourcesJar)
|
||||||
@@ -106,8 +106,8 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
|
|||||||
if library.installFile == nil {
|
if library.installFile == nil {
|
||||||
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", true)
|
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", true)
|
||||||
}
|
}
|
||||||
if library.dexJarFile != nil {
|
if library.dexJarFile.IsSet() {
|
||||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", library.dexJarFile)
|
entries.SetPath("LOCAL_SOONG_DEX_JAR", library.dexJarFile.Path())
|
||||||
}
|
}
|
||||||
if len(library.dexpreopter.builtInstalled) > 0 {
|
if len(library.dexpreopter.builtInstalled) > 0 {
|
||||||
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", library.dexpreopter.builtInstalled)
|
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", library.dexpreopter.builtInstalled)
|
||||||
@@ -207,8 +207,8 @@ func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries {
|
|||||||
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
|
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
|
||||||
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
||||||
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !Bool(prebuilt.properties.Installable))
|
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !Bool(prebuilt.properties.Installable))
|
||||||
if prebuilt.dexJarFile != nil {
|
if prebuilt.dexJarFile.IsSet() {
|
||||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile)
|
entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile.Path())
|
||||||
}
|
}
|
||||||
entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.combinedClasspathFile)
|
entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.combinedClasspathFile)
|
||||||
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.combinedClasspathFile)
|
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.combinedClasspathFile)
|
||||||
@@ -227,12 +227,12 @@ func (prebuilt *DexImport) AndroidMkEntries() []android.AndroidMkEntries {
|
|||||||
}
|
}
|
||||||
return []android.AndroidMkEntries{android.AndroidMkEntries{
|
return []android.AndroidMkEntries{android.AndroidMkEntries{
|
||||||
Class: "JAVA_LIBRARIES",
|
Class: "JAVA_LIBRARIES",
|
||||||
OutputFile: android.OptionalPathForPath(prebuilt.dexJarFile),
|
OutputFile: android.OptionalPathForPath(prebuilt.dexJarFile.Path()),
|
||||||
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
|
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
|
||||||
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
|
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
|
||||||
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
||||||
if prebuilt.dexJarFile != nil {
|
if prebuilt.dexJarFile.IsSet() {
|
||||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile)
|
entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile.Path())
|
||||||
}
|
}
|
||||||
if len(prebuilt.dexpreopter.builtInstalled) > 0 {
|
if len(prebuilt.dexpreopter.builtInstalled) > 0 {
|
||||||
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", prebuilt.dexpreopter.builtInstalled)
|
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", prebuilt.dexpreopter.builtInstalled)
|
||||||
@@ -279,8 +279,8 @@ func (binary *Binary) AndroidMkEntries() []android.AndroidMkEntries {
|
|||||||
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
||||||
entries.SetPath("LOCAL_SOONG_HEADER_JAR", binary.headerJarFile)
|
entries.SetPath("LOCAL_SOONG_HEADER_JAR", binary.headerJarFile)
|
||||||
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", binary.implementationAndResourcesJar)
|
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", binary.implementationAndResourcesJar)
|
||||||
if binary.dexJarFile != nil {
|
if binary.dexJarFile.IsSet() {
|
||||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", binary.dexJarFile)
|
entries.SetPath("LOCAL_SOONG_DEX_JAR", binary.dexJarFile.Path())
|
||||||
}
|
}
|
||||||
if len(binary.dexpreopter.builtInstalled) > 0 {
|
if len(binary.dexpreopter.builtInstalled) > 0 {
|
||||||
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", binary.dexpreopter.builtInstalled)
|
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", binary.dexpreopter.builtInstalled)
|
||||||
@@ -336,8 +336,8 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
|
|||||||
entries.SetString("LOCAL_MODULE", app.installApkName)
|
entries.SetString("LOCAL_MODULE", app.installApkName)
|
||||||
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", app.appProperties.PreventInstall)
|
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", app.appProperties.PreventInstall)
|
||||||
entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", app.exportPackage)
|
entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", app.exportPackage)
|
||||||
if app.dexJarFile != nil {
|
if app.dexJarFile.IsSet() {
|
||||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", app.dexJarFile)
|
entries.SetPath("LOCAL_SOONG_DEX_JAR", app.dexJarFile.Path())
|
||||||
}
|
}
|
||||||
if app.implementationAndResourcesJar != nil {
|
if app.implementationAndResourcesJar != nil {
|
||||||
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", app.implementationAndResourcesJar)
|
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", app.implementationAndResourcesJar)
|
||||||
|
@@ -476,7 +476,7 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
|
|||||||
a.Module.compile(ctx, a.aaptSrcJar)
|
a.Module.compile(ctx, a.aaptSrcJar)
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.dexJarFile
|
return a.dexJarFile.PathOrNil()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, ctx android.ModuleContext) android.WritablePath {
|
func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, ctx android.ModuleContext) android.WritablePath {
|
||||||
@@ -1305,7 +1305,8 @@ func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext
|
|||||||
replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName)
|
replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName)
|
||||||
}
|
}
|
||||||
clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, tag.implicit,
|
clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, tag.implicit,
|
||||||
lib.DexJarBuildPath(), lib.DexJarInstallPath(), lib.ClassLoaderContexts())
|
lib.DexJarBuildPath().PathOrNil(), lib.DexJarInstallPath(),
|
||||||
|
lib.ClassLoaderContexts())
|
||||||
} else if ctx.Config().AllowMissingDependencies() {
|
} else if ctx.Config().AllowMissingDependencies() {
|
||||||
ctx.AddMissingDependencies([]string{dep})
|
ctx.AddMissingDependencies([]string{dep})
|
||||||
} else {
|
} else {
|
||||||
|
92
java/base.go
92
java/base.go
@@ -276,6 +276,87 @@ func (e *embeddableInModuleAndImport) depIsInSameApex(ctx android.BaseModuleCont
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OptionalDexJarPath can be either unset, hold a valid path to a dex jar file,
|
||||||
|
// or an invalid path describing the reason it is invalid.
|
||||||
|
//
|
||||||
|
// It is unset if a dex jar isn't applicable, i.e. no build rule has been
|
||||||
|
// requested to create one.
|
||||||
|
//
|
||||||
|
// If a dex jar has been requested to be built then it is set, and it may be
|
||||||
|
// either a valid android.Path, or invalid with a reason message. The latter
|
||||||
|
// happens if the source that should produce the dex file isn't able to.
|
||||||
|
//
|
||||||
|
// E.g. it is invalid with a reason message if there is a prebuilt APEX that
|
||||||
|
// could produce the dex jar through a deapexer module, but the APEX isn't
|
||||||
|
// installable so doing so wouldn't be safe.
|
||||||
|
type OptionalDexJarPath struct {
|
||||||
|
isSet bool
|
||||||
|
path android.OptionalPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSet returns true if a path has been set, either invalid or valid.
|
||||||
|
func (o OptionalDexJarPath) IsSet() bool {
|
||||||
|
return o.isSet
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid returns true if there is a path that is valid.
|
||||||
|
func (o OptionalDexJarPath) Valid() bool {
|
||||||
|
return o.isSet && o.path.Valid()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path returns the valid path, or panics if it's either not set or is invalid.
|
||||||
|
func (o OptionalDexJarPath) Path() android.Path {
|
||||||
|
if !o.isSet {
|
||||||
|
panic("path isn't set")
|
||||||
|
}
|
||||||
|
return o.path.Path()
|
||||||
|
}
|
||||||
|
|
||||||
|
// PathOrNil returns the path if it's set and valid, or else nil.
|
||||||
|
func (o OptionalDexJarPath) PathOrNil() android.Path {
|
||||||
|
if o.Valid() {
|
||||||
|
return o.Path()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// InvalidReason returns the reason for an invalid path, which is never "". It
|
||||||
|
// returns "" for an unset or valid path.
|
||||||
|
func (o OptionalDexJarPath) InvalidReason() string {
|
||||||
|
if !o.isSet {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return o.path.InvalidReason()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o OptionalDexJarPath) String() string {
|
||||||
|
if !o.isSet {
|
||||||
|
return "<unset>"
|
||||||
|
}
|
||||||
|
return o.path.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// makeUnsetDexJarPath returns an unset OptionalDexJarPath.
|
||||||
|
func makeUnsetDexJarPath() OptionalDexJarPath {
|
||||||
|
return OptionalDexJarPath{isSet: false}
|
||||||
|
}
|
||||||
|
|
||||||
|
// makeDexJarPathFromOptionalPath returns an OptionalDexJarPath that is set with
|
||||||
|
// the given OptionalPath, which may be valid or invalid.
|
||||||
|
func makeDexJarPathFromOptionalPath(path android.OptionalPath) OptionalDexJarPath {
|
||||||
|
return OptionalDexJarPath{isSet: true, path: path}
|
||||||
|
}
|
||||||
|
|
||||||
|
// makeDexJarPathFromPath returns an OptionalDexJarPath that is set with the
|
||||||
|
// valid given path. It returns an unset OptionalDexJarPath if the given path is
|
||||||
|
// nil.
|
||||||
|
func makeDexJarPathFromPath(path android.Path) OptionalDexJarPath {
|
||||||
|
if path == nil {
|
||||||
|
return makeUnsetDexJarPath()
|
||||||
|
}
|
||||||
|
return makeDexJarPathFromOptionalPath(android.OptionalPathForPath(path))
|
||||||
|
}
|
||||||
|
|
||||||
// Module contains the properties and members used by all java module types
|
// Module contains the properties and members used by all java module types
|
||||||
type Module struct {
|
type Module struct {
|
||||||
android.ModuleBase
|
android.ModuleBase
|
||||||
@@ -310,7 +391,7 @@ type Module struct {
|
|||||||
implementationAndResourcesJar android.Path
|
implementationAndResourcesJar android.Path
|
||||||
|
|
||||||
// output file containing classes.dex and resources
|
// output file containing classes.dex and resources
|
||||||
dexJarFile android.Path
|
dexJarFile OptionalDexJarPath
|
||||||
|
|
||||||
// output file containing uninstrumented classes that will be instrumented by jacoco
|
// output file containing uninstrumented classes that will be instrumented by jacoco
|
||||||
jacocoReportClassesFile android.Path
|
jacocoReportClassesFile android.Path
|
||||||
@@ -1265,12 +1346,13 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the hiddenapi structure.
|
// Initialize the hiddenapi structure.
|
||||||
j.initHiddenAPI(ctx, dexOutputFile, j.implementationJarFile, j.dexProperties.Uncompress_dex)
|
|
||||||
|
j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), j.implementationJarFile, j.dexProperties.Uncompress_dex)
|
||||||
|
|
||||||
// Encode hidden API flags in dex file, if needed.
|
// Encode hidden API flags in dex file, if needed.
|
||||||
dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)
|
dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)
|
||||||
|
|
||||||
j.dexJarFile = dexOutputFile
|
j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
|
||||||
|
|
||||||
// Dexpreopting
|
// Dexpreopting
|
||||||
j.dexpreopt(ctx, dexOutputFile)
|
j.dexpreopt(ctx, dexOutputFile)
|
||||||
@@ -1280,7 +1362,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
|
|||||||
// There is no code to compile into a dex jar, make sure the resources are propagated
|
// There is no code to compile into a dex jar, make sure the resources are propagated
|
||||||
// to the APK if this is an app.
|
// to the APK if this is an app.
|
||||||
outputFile = implementationAndResourcesJar
|
outputFile = implementationAndResourcesJar
|
||||||
j.dexJarFile = j.resourceJar
|
j.dexJarFile = makeDexJarPathFromPath(j.resourceJar)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Failed() {
|
if ctx.Failed() {
|
||||||
@@ -1470,7 +1552,7 @@ func (j *Module) ImplementationJars() android.Paths {
|
|||||||
return android.Paths{j.implementationJarFile}
|
return android.Paths{j.implementationJarFile}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *Module) DexJarBuildPath() android.Path {
|
func (j *Module) DexJarBuildPath() OptionalDexJarPath {
|
||||||
return j.dexJarFile
|
return j.dexJarFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -954,23 +954,11 @@ func (module *prebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx and
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var deapexerModule android.Module
|
di := android.FindDeapexerProviderForModule(ctx)
|
||||||
ctx.VisitDirectDeps(func(module android.Module) {
|
if di == nil {
|
||||||
tag := ctx.OtherModuleDependencyTag(module)
|
return nil // An error has been reported by FindDeapexerProviderForModule.
|
||||||
// Save away the `deapexer` module on which this depends, if any.
|
|
||||||
if tag == android.DeapexerTag {
|
|
||||||
deapexerModule = module
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if deapexerModule == nil {
|
|
||||||
// This should never happen as a variant for a prebuilt_apex is only created if the
|
|
||||||
// deapexer module has been configured to export the dex implementation jar for this module.
|
|
||||||
ctx.ModuleErrorf("internal error: module does not depend on a `deapexer` module")
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo)
|
|
||||||
files := bootImageFilesByArch{}
|
files := bootImageFilesByArch{}
|
||||||
for _, variant := range imageConfig.apexVariants() {
|
for _, variant := range imageConfig.apexVariants() {
|
||||||
arch := variant.target.Arch.ArchType
|
arch := variant.target.Arch.ArchType
|
||||||
|
@@ -30,14 +30,14 @@ type hiddenAPI struct {
|
|||||||
// that information encoded within it.
|
// that information encoded within it.
|
||||||
active bool
|
active bool
|
||||||
|
|
||||||
// The path to the dex jar that is in the boot class path. If this is nil then the associated
|
// The path to the dex jar that is in the boot class path. If this is unset then the associated
|
||||||
// module is not a boot jar, but could be one of the <x>-hiddenapi modules that provide additional
|
// module is not a boot jar, but could be one of the <x>-hiddenapi modules that provide additional
|
||||||
// annotations for the <x> boot dex jar but which do not actually provide a boot dex jar
|
// annotations for the <x> boot dex jar but which do not actually provide a boot dex jar
|
||||||
// themselves.
|
// themselves.
|
||||||
//
|
//
|
||||||
// This must be the path to the unencoded dex jar as the encoded dex jar indirectly depends on
|
// This must be the path to the unencoded dex jar as the encoded dex jar indirectly depends on
|
||||||
// this file so using the encoded dex jar here would result in a cycle in the ninja rules.
|
// this file so using the encoded dex jar here would result in a cycle in the ninja rules.
|
||||||
bootDexJarPath android.Path
|
bootDexJarPath OptionalDexJarPath
|
||||||
|
|
||||||
// The paths to the classes jars that contain classes and class members annotated with
|
// The paths to the classes jars that contain classes and class members annotated with
|
||||||
// the UnsupportedAppUsage annotation that need to be extracted as part of the hidden API
|
// the UnsupportedAppUsage annotation that need to be extracted as part of the hidden API
|
||||||
@@ -49,7 +49,7 @@ type hiddenAPI struct {
|
|||||||
uncompressDexState *bool
|
uncompressDexState *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *hiddenAPI) bootDexJar() android.Path {
|
func (h *hiddenAPI) bootDexJar() OptionalDexJarPath {
|
||||||
return h.bootDexJarPath
|
return h.bootDexJarPath
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ type hiddenAPIModule interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type hiddenAPIIntf interface {
|
type hiddenAPIIntf interface {
|
||||||
bootDexJar() android.Path
|
bootDexJar() OptionalDexJarPath
|
||||||
classesJars() android.Paths
|
classesJars() android.Paths
|
||||||
uncompressDex() *bool
|
uncompressDex() *bool
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,7 @@ var _ hiddenAPIIntf = (*hiddenAPI)(nil)
|
|||||||
//
|
//
|
||||||
// uncompressedDexState should be nil when the module is a prebuilt and so does not require hidden
|
// uncompressedDexState should be nil when the module is a prebuilt and so does not require hidden
|
||||||
// API encoding.
|
// API encoding.
|
||||||
func (h *hiddenAPI) initHiddenAPI(ctx android.ModuleContext, dexJar, classesJar android.Path, uncompressedDexState *bool) {
|
func (h *hiddenAPI) initHiddenAPI(ctx android.ModuleContext, dexJar OptionalDexJarPath, classesJar android.Path, uncompressedDexState *bool) {
|
||||||
|
|
||||||
// Save the classes jars even if this is not active as they may be used by modular hidden API
|
// Save the classes jars even if this is not active as they may be used by modular hidden API
|
||||||
// processing.
|
// processing.
|
||||||
|
@@ -19,6 +19,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
|
|
||||||
"github.com/google/blueprint"
|
"github.com/google/blueprint"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -277,7 +278,7 @@ func hiddenAPIAddStubLibDependencies(ctx android.BottomUpMutatorContext, apiScop
|
|||||||
// hiddenAPIRetrieveDexJarBuildPath retrieves the DexJarBuildPath from the specified module, if
|
// hiddenAPIRetrieveDexJarBuildPath retrieves the DexJarBuildPath from the specified module, if
|
||||||
// available, or reports an error.
|
// available, or reports an error.
|
||||||
func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module, kind android.SdkKind) android.Path {
|
func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module, kind android.SdkKind) android.Path {
|
||||||
var dexJar android.Path
|
var dexJar OptionalDexJarPath
|
||||||
if sdkLibrary, ok := module.(SdkLibraryDependency); ok {
|
if sdkLibrary, ok := module.(SdkLibraryDependency); ok {
|
||||||
dexJar = sdkLibrary.SdkApiStubDexJar(ctx, kind)
|
dexJar = sdkLibrary.SdkApiStubDexJar(ctx, kind)
|
||||||
} else if j, ok := module.(UsesLibraryDependency); ok {
|
} else if j, ok := module.(UsesLibraryDependency); ok {
|
||||||
@@ -287,10 +288,11 @@ func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if dexJar == nil {
|
if !dexJar.Valid() {
|
||||||
ctx.ModuleErrorf("dependency %s does not provide a dex jar, consider setting compile_dex: true", module)
|
ctx.ModuleErrorf("dependency %s does not provide a dex jar: %s", module, dexJar.InvalidReason())
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return dexJar
|
return dexJar.Path()
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildRuleToGenerateHiddenAPIStubFlagsFile creates a rule to create a hidden API stub flags file.
|
// buildRuleToGenerateHiddenAPIStubFlagsFile creates a rule to create a hidden API stub flags file.
|
||||||
@@ -1159,18 +1161,17 @@ func extractBootDexInfoFromModules(ctx android.ModuleContext, contents []android
|
|||||||
|
|
||||||
// retrieveBootDexJarFromHiddenAPIModule retrieves the boot dex jar from the hiddenAPIModule.
|
// retrieveBootDexJarFromHiddenAPIModule retrieves the boot dex jar from the hiddenAPIModule.
|
||||||
//
|
//
|
||||||
// If the module does not provide a boot dex jar, i.e. the returned boot dex jar is nil, then that
|
// If the module does not provide a boot dex jar, i.e. the returned boot dex jar is unset or
|
||||||
// create a fake path and either report an error immediately or defer reporting of the error until
|
// invalid, then create a fake path and either report an error immediately or defer reporting of the
|
||||||
// the path is actually used.
|
// error until the path is actually used.
|
||||||
func retrieveBootDexJarFromHiddenAPIModule(ctx android.ModuleContext, module hiddenAPIModule) android.Path {
|
func retrieveBootDexJarFromHiddenAPIModule(ctx android.ModuleContext, module hiddenAPIModule) android.Path {
|
||||||
bootDexJar := module.bootDexJar()
|
bootDexJar := module.bootDexJar()
|
||||||
if bootDexJar == nil {
|
if !bootDexJar.Valid() {
|
||||||
fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/boot-dex/%s.jar", module.Name()))
|
fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/boot-dex/%s.jar", module.Name()))
|
||||||
bootDexJar = fake
|
handleMissingDexBootFile(ctx, module, fake, bootDexJar.InvalidReason())
|
||||||
|
return fake
|
||||||
handleMissingDexBootFile(ctx, module, fake)
|
|
||||||
}
|
}
|
||||||
return bootDexJar
|
return bootDexJar.Path()
|
||||||
}
|
}
|
||||||
|
|
||||||
// extractClassesJarsFromModules extracts the class jars from the supplied modules.
|
// extractClassesJarsFromModules extracts the class jars from the supplied modules.
|
||||||
@@ -1264,7 +1265,7 @@ func deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.M
|
|||||||
|
|
||||||
// handleMissingDexBootFile will either log a warning or create an error rule to create the fake
|
// handleMissingDexBootFile will either log a warning or create an error rule to create the fake
|
||||||
// file depending on the value returned from deferReportingMissingBootDexJar.
|
// file depending on the value returned from deferReportingMissingBootDexJar.
|
||||||
func handleMissingDexBootFile(ctx android.ModuleContext, module android.Module, fake android.WritablePath) {
|
func handleMissingDexBootFile(ctx android.ModuleContext, module android.Module, fake android.WritablePath, reason string) {
|
||||||
if deferReportingMissingBootDexJar(ctx, module) {
|
if deferReportingMissingBootDexJar(ctx, module) {
|
||||||
// Create an error rule that pretends to create the output file but will actually fail if it
|
// Create an error rule that pretends to create the output file but will actually fail if it
|
||||||
// is run.
|
// is run.
|
||||||
@@ -1272,11 +1273,11 @@ func handleMissingDexBootFile(ctx android.ModuleContext, module android.Module,
|
|||||||
Rule: android.ErrorRule,
|
Rule: android.ErrorRule,
|
||||||
Output: fake,
|
Output: fake,
|
||||||
Args: map[string]string{
|
Args: map[string]string{
|
||||||
"error": fmt.Sprintf("missing dependencies: boot dex jar for %s", module),
|
"error": fmt.Sprintf("missing boot dex jar dependency for %s: %s", module, reason),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
ctx.ModuleErrorf("module %s does not provide a dex jar", module)
|
ctx.ModuleErrorf("module %s does not provide a dex jar: %s", module, reason)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1287,14 +1288,13 @@ func handleMissingDexBootFile(ctx android.ModuleContext, module android.Module,
|
|||||||
// However, under certain conditions, e.g. errors, or special build configurations it will return
|
// However, under certain conditions, e.g. errors, or special build configurations it will return
|
||||||
// a path to a fake file.
|
// a path to a fake file.
|
||||||
func retrieveEncodedBootDexJarFromModule(ctx android.ModuleContext, module android.Module) android.Path {
|
func retrieveEncodedBootDexJarFromModule(ctx android.ModuleContext, module android.Module) android.Path {
|
||||||
bootDexJar := module.(interface{ DexJarBuildPath() android.Path }).DexJarBuildPath()
|
bootDexJar := module.(interface{ DexJarBuildPath() OptionalDexJarPath }).DexJarBuildPath()
|
||||||
if bootDexJar == nil {
|
if !bootDexJar.Valid() {
|
||||||
fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/encoded-dex/%s.jar", module.Name()))
|
fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/encoded-dex/%s.jar", module.Name()))
|
||||||
bootDexJar = fake
|
handleMissingDexBootFile(ctx, module, fake, bootDexJar.InvalidReason())
|
||||||
|
return fake
|
||||||
handleMissingDexBootFile(ctx, module, fake)
|
|
||||||
}
|
}
|
||||||
return bootDexJar
|
return bootDexJar.Path()
|
||||||
}
|
}
|
||||||
|
|
||||||
// extractEncodedDexJarsFromModules extracts the encoded dex jars from the supplied modules.
|
// extractEncodedDexJarsFromModules extracts the encoded dex jars from the supplied modules.
|
||||||
|
@@ -20,6 +20,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
|
|
||||||
"github.com/google/blueprint/proptools"
|
"github.com/google/blueprint/proptools"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -306,7 +307,7 @@ func TestHiddenAPIEncoding_JavaSdkLibrary(t *testing.T) {
|
|||||||
android.AssertStringEquals(t, "encode embedded java_library", unencodedDexJar, actualUnencodedDexJar.String())
|
android.AssertStringEquals(t, "encode embedded java_library", unencodedDexJar, actualUnencodedDexJar.String())
|
||||||
|
|
||||||
// Make sure that the encoded dex jar is the exported one.
|
// Make sure that the encoded dex jar is the exported one.
|
||||||
exportedDexJar := moduleForTests.Module().(UsesLibraryDependency).DexJarBuildPath()
|
exportedDexJar := moduleForTests.Module().(UsesLibraryDependency).DexJarBuildPath().Path()
|
||||||
android.AssertPathRelativeToTopEquals(t, "encode embedded java_library", encodedDexJar, exportedDexJar)
|
android.AssertPathRelativeToTopEquals(t, "encode embedded java_library", encodedDexJar, exportedDexJar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
44
java/java.go
44
java/java.go
@@ -219,7 +219,7 @@ type ApexDependency interface {
|
|||||||
|
|
||||||
// Provides build path and install path to DEX jars.
|
// Provides build path and install path to DEX jars.
|
||||||
type UsesLibraryDependency interface {
|
type UsesLibraryDependency interface {
|
||||||
DexJarBuildPath() android.Path
|
DexJarBuildPath() OptionalDexJarPath
|
||||||
DexJarInstallPath() android.Path
|
DexJarInstallPath() android.Path
|
||||||
ClassLoaderContexts() dexpreopt.ClassLoaderContextMap
|
ClassLoaderContexts() dexpreopt.ClassLoaderContextMap
|
||||||
}
|
}
|
||||||
@@ -1215,7 +1215,7 @@ type Import struct {
|
|||||||
properties ImportProperties
|
properties ImportProperties
|
||||||
|
|
||||||
// output file containing classes.dex and resources
|
// output file containing classes.dex and resources
|
||||||
dexJarFile android.Path
|
dexJarFile OptionalDexJarPath
|
||||||
dexJarInstallFile android.Path
|
dexJarInstallFile android.Path
|
||||||
|
|
||||||
combinedClasspathFile android.Path
|
combinedClasspathFile android.Path
|
||||||
@@ -1319,7 +1319,6 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
|
j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
|
||||||
|
|
||||||
var flags javaBuilderFlags
|
var flags javaBuilderFlags
|
||||||
var deapexerModule android.Module
|
|
||||||
|
|
||||||
ctx.VisitDirectDeps(func(module android.Module) {
|
ctx.VisitDirectDeps(func(module android.Module) {
|
||||||
tag := ctx.OtherModuleDependencyTag(module)
|
tag := ctx.OtherModuleDependencyTag(module)
|
||||||
@@ -1340,11 +1339,6 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addCLCFromDep(ctx, module, j.classLoaderContexts)
|
addCLCFromDep(ctx, module, j.classLoaderContexts)
|
||||||
|
|
||||||
// Save away the `deapexer` module on which this depends, if any.
|
|
||||||
if tag == android.DeapexerTag {
|
|
||||||
deapexerModule = module
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if Bool(j.properties.Installable) {
|
if Bool(j.properties.Installable) {
|
||||||
@@ -1359,26 +1353,22 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
// obtained from the associated deapexer module.
|
// obtained from the associated deapexer module.
|
||||||
ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
||||||
if ai.ForPrebuiltApex {
|
if ai.ForPrebuiltApex {
|
||||||
if deapexerModule == nil {
|
|
||||||
// This should never happen as a variant for a prebuilt_apex is only created if the
|
|
||||||
// deapexer module has been configured to export the dex implementation jar for this module.
|
|
||||||
ctx.ModuleErrorf("internal error: module %q does not depend on a `deapexer` module for prebuilt_apex %q",
|
|
||||||
j.Name(), ai.ApexVariationName)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the path of the dex implementation jar from the `deapexer` module.
|
// Get the path of the dex implementation jar from the `deapexer` module.
|
||||||
di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo)
|
di := android.FindDeapexerProviderForModule(ctx)
|
||||||
|
if di == nil {
|
||||||
|
return // An error has been reported by FindDeapexerProviderForModule.
|
||||||
|
}
|
||||||
if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil {
|
if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil {
|
||||||
j.dexJarFile = dexOutputPath
|
dexJarFile := makeDexJarPathFromPath(dexOutputPath)
|
||||||
|
j.dexJarFile = dexJarFile
|
||||||
j.dexJarInstallFile = android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName()))
|
j.dexJarInstallFile = android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName()))
|
||||||
|
|
||||||
// Initialize the hiddenapi structure.
|
// Initialize the hiddenapi structure.
|
||||||
j.initHiddenAPI(ctx, dexOutputPath, outputFile, nil)
|
j.initHiddenAPI(ctx, dexJarFile, outputFile, nil)
|
||||||
} else {
|
} else {
|
||||||
// This should never happen as a variant for a prebuilt_apex is only created if the
|
// This should never happen as a variant for a prebuilt_apex is only created if the
|
||||||
// prebuilt_apex has been configured to export the java library dex file.
|
// prebuilt_apex has been configured to export the java library dex file.
|
||||||
ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt_apex %q", deapexerModule.Name())
|
ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt APEX %s", di.ApexModuleName())
|
||||||
}
|
}
|
||||||
} else if Bool(j.dexProperties.Compile_dex) {
|
} else if Bool(j.dexProperties.Compile_dex) {
|
||||||
sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
|
sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
|
||||||
@@ -1407,12 +1397,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the hiddenapi structure.
|
// Initialize the hiddenapi structure.
|
||||||
j.initHiddenAPI(ctx, dexOutputFile, outputFile, j.dexProperties.Uncompress_dex)
|
j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), outputFile, j.dexProperties.Uncompress_dex)
|
||||||
|
|
||||||
// Encode hidden API flags in dex file.
|
// Encode hidden API flags in dex file.
|
||||||
dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)
|
dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)
|
||||||
|
|
||||||
j.dexJarFile = dexOutputFile
|
j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
|
||||||
j.dexJarInstallFile = android.PathForModuleInstall(ctx, "framework", jarName)
|
j.dexJarInstallFile = android.PathForModuleInstall(ctx, "framework", jarName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1450,7 +1440,7 @@ func (j *Import) ImplementationAndResourcesJars() android.Paths {
|
|||||||
return android.Paths{j.combinedClasspathFile}
|
return android.Paths{j.combinedClasspathFile}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *Import) DexJarBuildPath() android.Path {
|
func (j *Import) DexJarBuildPath() OptionalDexJarPath {
|
||||||
return j.dexJarFile
|
return j.dexJarFile
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1595,7 +1585,7 @@ type DexImport struct {
|
|||||||
|
|
||||||
properties DexImportProperties
|
properties DexImportProperties
|
||||||
|
|
||||||
dexJarFile android.Path
|
dexJarFile OptionalDexJarPath
|
||||||
|
|
||||||
dexpreopter
|
dexpreopter
|
||||||
|
|
||||||
@@ -1686,7 +1676,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
j.dexJarFile = dexOutputFile
|
j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
|
||||||
|
|
||||||
j.dexpreopt(ctx, dexOutputFile)
|
j.dexpreopt(ctx, dexOutputFile)
|
||||||
|
|
||||||
@@ -1696,7 +1686,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *DexImport) DexJarBuildPath() android.Path {
|
func (j *DexImport) DexJarBuildPath() OptionalDexJarPath {
|
||||||
return j.dexJarFile
|
return j.dexJarFile
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1865,7 +1855,7 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module,
|
|||||||
// from its CLC should be added to the current CLC.
|
// from its CLC should be added to the current CLC.
|
||||||
if sdkLib != nil {
|
if sdkLib != nil {
|
||||||
clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false, true,
|
clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false, true,
|
||||||
dep.DexJarBuildPath(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
|
dep.DexJarBuildPath().PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
|
||||||
} else {
|
} else {
|
||||||
clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
|
clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
|
||||||
}
|
}
|
||||||
|
@@ -600,8 +600,8 @@ func TestPrebuilts(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
barDexJar := barModule.Module().(*Import).DexJarBuildPath()
|
barDexJar := barModule.Module().(*Import).DexJarBuildPath()
|
||||||
if barDexJar != nil {
|
if barDexJar.IsSet() {
|
||||||
t.Errorf("bar dex jar build path expected to be nil, got %q", barDexJar)
|
t.Errorf("bar dex jar build path expected to be set, got %s", barDexJar)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) {
|
if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) {
|
||||||
@@ -612,7 +612,7 @@ func TestPrebuilts(t *testing.T) {
|
|||||||
t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, bazJar.String())
|
t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, bazJar.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
bazDexJar := bazModule.Module().(*Import).DexJarBuildPath()
|
bazDexJar := bazModule.Module().(*Import).DexJarBuildPath().Path()
|
||||||
expectedDexJar := "out/soong/.intermediates/baz/android_common/dex/baz.jar"
|
expectedDexJar := "out/soong/.intermediates/baz/android_common/dex/baz.jar"
|
||||||
android.AssertPathRelativeToTopEquals(t, "baz dex jar build path", expectedDexJar, bazDexJar)
|
android.AssertPathRelativeToTopEquals(t, "baz dex jar build path", expectedDexJar, bazDexJar)
|
||||||
|
|
||||||
|
@@ -540,7 +540,7 @@ type scopePaths struct {
|
|||||||
// The dex jar for the stubs.
|
// The dex jar for the stubs.
|
||||||
//
|
//
|
||||||
// This is not the implementation jar, it still only contains stubs.
|
// This is not the implementation jar, it still only contains stubs.
|
||||||
stubsDexJarPath android.Path
|
stubsDexJarPath OptionalDexJarPath
|
||||||
|
|
||||||
// The API specification file, e.g. system_current.txt.
|
// The API specification file, e.g. system_current.txt.
|
||||||
currentApiFilePath android.OptionalPath
|
currentApiFilePath android.OptionalPath
|
||||||
@@ -915,10 +915,10 @@ func sdkKindToApiScope(kind android.SdkKind) *apiScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// to satisfy SdkLibraryDependency interface
|
// to satisfy SdkLibraryDependency interface
|
||||||
func (c *commonToSdkLibraryAndImport) SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) android.Path {
|
func (c *commonToSdkLibraryAndImport) SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath {
|
||||||
paths := c.selectScopePaths(ctx, kind)
|
paths := c.selectScopePaths(ctx, kind)
|
||||||
if paths == nil {
|
if paths == nil {
|
||||||
return nil
|
return makeUnsetDexJarPath()
|
||||||
}
|
}
|
||||||
|
|
||||||
return paths.stubsDexJarPath
|
return paths.stubsDexJarPath
|
||||||
@@ -1044,7 +1044,7 @@ type SdkLibraryDependency interface {
|
|||||||
|
|
||||||
// SdkApiStubDexJar returns the dex jar for the stubs. It is needed by the hiddenapi processing
|
// SdkApiStubDexJar returns the dex jar for the stubs. It is needed by the hiddenapi processing
|
||||||
// tool which processes dex files.
|
// tool which processes dex files.
|
||||||
SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) android.Path
|
SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath
|
||||||
|
|
||||||
// SdkRemovedTxtFile returns the optional path to the removed.txt file for the specified sdk kind.
|
// SdkRemovedTxtFile returns the optional path to the removed.txt file for the specified sdk kind.
|
||||||
SdkRemovedTxtFile(ctx android.BaseModuleContext, kind android.SdkKind) android.OptionalPath
|
SdkRemovedTxtFile(ctx android.BaseModuleContext, kind android.SdkKind) android.OptionalPath
|
||||||
@@ -1941,7 +1941,7 @@ type SdkLibraryImport struct {
|
|||||||
xmlPermissionsFileModule *sdkLibraryXml
|
xmlPermissionsFileModule *sdkLibraryXml
|
||||||
|
|
||||||
// Build path to the dex implementation jar obtained from the prebuilt_apex, if any.
|
// Build path to the dex implementation jar obtained from the prebuilt_apex, if any.
|
||||||
dexJarFile android.Path
|
dexJarFile OptionalDexJarPath
|
||||||
|
|
||||||
// Expected install file path of the source module(sdk_library)
|
// Expected install file path of the source module(sdk_library)
|
||||||
// or dex implementation jar obtained from the prebuilt_apex, if any.
|
// or dex implementation jar obtained from the prebuilt_apex, if any.
|
||||||
@@ -2169,8 +2169,6 @@ func (module *SdkLibraryImport) OutputFiles(tag string) (android.Paths, error) {
|
|||||||
func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
module.generateCommonBuildActions(ctx)
|
module.generateCommonBuildActions(ctx)
|
||||||
|
|
||||||
var deapexerModule android.Module
|
|
||||||
|
|
||||||
// Assume that source module(sdk_library) is installed in /<sdk_library partition>/framework
|
// Assume that source module(sdk_library) is installed in /<sdk_library partition>/framework
|
||||||
module.installFile = android.PathForModuleInstall(ctx, "framework", module.Stem()+".jar")
|
module.installFile = android.PathForModuleInstall(ctx, "framework", module.Stem()+".jar")
|
||||||
|
|
||||||
@@ -2199,11 +2197,6 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
|
|||||||
ctx.ModuleErrorf("xml permissions file module must be of type *sdkLibraryXml but was %T", to)
|
ctx.ModuleErrorf("xml permissions file module must be of type *sdkLibraryXml but was %T", to)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save away the `deapexer` module on which this depends, if any.
|
|
||||||
if tag == android.DeapexerTag {
|
|
||||||
deapexerModule = to
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Populate the scope paths with information from the properties.
|
// Populate the scope paths with information from the properties.
|
||||||
@@ -2223,21 +2216,18 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
|
|||||||
// obtained from the associated deapexer module.
|
// obtained from the associated deapexer module.
|
||||||
ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
||||||
if ai.ForPrebuiltApex {
|
if ai.ForPrebuiltApex {
|
||||||
if deapexerModule == nil {
|
|
||||||
// This should never happen as a variant for a prebuilt_apex is only created if the
|
|
||||||
// deapxer module has been configured to export the dex implementation jar for this module.
|
|
||||||
ctx.ModuleErrorf("internal error: module %q does not depend on a `deapexer` module for prebuilt_apex %q",
|
|
||||||
module.Name(), ai.ApexVariationName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the path of the dex implementation jar from the `deapexer` module.
|
// Get the path of the dex implementation jar from the `deapexer` module.
|
||||||
di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo)
|
di := android.FindDeapexerProviderForModule(ctx)
|
||||||
|
if di == nil {
|
||||||
|
return // An error has been reported by FindDeapexerProviderForModule.
|
||||||
|
}
|
||||||
if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(module.BaseModuleName())); dexOutputPath != nil {
|
if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(module.BaseModuleName())); dexOutputPath != nil {
|
||||||
module.dexJarFile = dexOutputPath
|
dexJarFile := makeDexJarPathFromPath(dexOutputPath)
|
||||||
|
module.dexJarFile = dexJarFile
|
||||||
installPath := android.PathForModuleInPartitionInstall(
|
installPath := android.PathForModuleInPartitionInstall(
|
||||||
ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(module.BaseModuleName()))
|
ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(module.BaseModuleName()))
|
||||||
module.installFile = installPath
|
module.installFile = installPath
|
||||||
module.initHiddenAPI(ctx, dexOutputPath, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil)
|
module.initHiddenAPI(ctx, dexJarFile, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil)
|
||||||
|
|
||||||
// Dexpreopting.
|
// Dexpreopting.
|
||||||
module.dexpreopter.installPath = module.dexpreopter.getInstallPath(ctx, installPath)
|
module.dexpreopter.installPath = module.dexpreopter.getInstallPath(ctx, installPath)
|
||||||
@@ -2247,7 +2237,7 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
|
|||||||
} else {
|
} else {
|
||||||
// This should never happen as a variant for a prebuilt_apex is only created if the
|
// This should never happen as a variant for a prebuilt_apex is only created if the
|
||||||
// prebuilt_apex has been configured to export the java library dex file.
|
// prebuilt_apex has been configured to export the java library dex file.
|
||||||
ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt_apex %q", deapexerModule.Name())
|
ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt APEX %s", di.ApexModuleName())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2282,14 +2272,14 @@ func (module *SdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
// to satisfy UsesLibraryDependency interface
|
// to satisfy UsesLibraryDependency interface
|
||||||
func (module *SdkLibraryImport) DexJarBuildPath() android.Path {
|
func (module *SdkLibraryImport) DexJarBuildPath() OptionalDexJarPath {
|
||||||
// The dex implementation jar extracted from the .apex file should be used in preference to the
|
// The dex implementation jar extracted from the .apex file should be used in preference to the
|
||||||
// source.
|
// source.
|
||||||
if module.dexJarFile != nil {
|
if module.dexJarFile.IsSet() {
|
||||||
return module.dexJarFile
|
return module.dexJarFile
|
||||||
}
|
}
|
||||||
if module.implLibraryModule == nil {
|
if module.implLibraryModule == nil {
|
||||||
return nil
|
return makeUnsetDexJarPath()
|
||||||
} else {
|
} else {
|
||||||
return module.implLibraryModule.DexJarBuildPath()
|
return module.implLibraryModule.DexJarBuildPath()
|
||||||
}
|
}
|
||||||
|
@@ -1307,7 +1307,7 @@ java_sdk_library_import {
|
|||||||
ctx := android.ModuleInstallPathContextForTesting(result.Config)
|
ctx := android.ModuleInstallPathContextForTesting(result.Config)
|
||||||
dexJarBuildPath := func(name string, kind android.SdkKind) string {
|
dexJarBuildPath := func(name string, kind android.SdkKind) string {
|
||||||
dep := result.Module(name, "android_common").(java.SdkLibraryDependency)
|
dep := result.Module(name, "android_common").(java.SdkLibraryDependency)
|
||||||
path := dep.SdkApiStubDexJar(ctx, kind)
|
path := dep.SdkApiStubDexJar(ctx, kind).Path()
|
||||||
return path.RelativeToTop().String()
|
return path.RelativeToTop().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user