diff --git a/apex/apex.go b/apex/apex.go index 2d153e2c0..5294b6c17 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1545,7 +1545,7 @@ func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.Platform type javaModule interface { android.Module BaseModuleName() string - DexJarBuildPath() android.Path + DexJarBuildPath() java.OptionalDexJarPath JacocoReportClassesFile() android.Path LintDepSets() java.LintDepSets Stem() string @@ -1559,7 +1559,7 @@ var _ javaModule = (*java.SdkLibraryImport)(nil) // apexFileForJavaModule creates an apexFile for a java module's dex implementation jar. 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. diff --git a/apex/apex_test.go b/apex/apex_test.go index 2a2a1f45f..1f9bd5a2e 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -4799,9 +4799,10 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) { transform := android.NullFixturePreparer 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. p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency) - dexJarBuildPath := p.DexJarBuildPath() + dexJarBuildPath := p.DexJarBuildPath().PathOrNil() stem := android.RemoveOptionalPrebuiltPrefix(name) android.AssertStringEquals(t, "DexJarBuildPath should be apex-related path.", ".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) { + t.Helper() // Make sure the import has been given the correct path to the dex jar. p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency) dexJarBuildPath := p.DexJarInstallPath() @@ -4819,6 +4821,7 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) { } 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. android.AssertArrayString(t, "Check if there is no source variant", []string{"android_common"}, diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go index 3e19014a3..cb7d3d113 100644 --- a/apex/bootclasspath_fragment_test.go +++ b/apex/bootclasspath_fragment_test.go @@ -22,6 +22,7 @@ import ( "android/soong/android" "android/soong/java" + "github.com/google/blueprint/proptools" ) @@ -737,7 +738,7 @@ func TestBootclasspathFragmentContentsNoName(t *testing.T) { func getDexJarPath(result *android.TestResult, name string) string { 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 diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 4833a644b..d7be9a9e1 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -176,13 +176,15 @@ func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) { name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) if java.IsBootclasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag { // 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() - if path != nil { + path := child.(interface { + DexJarBuildPath() java.OptionalDexJarPath + }).DexJarBuildPath() + if path.IsSet() { af := apexFile{ module: child, moduleDir: ctx.OtherModuleDir(child), androidMkModuleName: name, - builtFile: path, + builtFile: path.Path(), class: javaSharedLib, } if module, ok := child.(java.DexpreopterInterface); ok { diff --git a/java/androidmk.go b/java/androidmk.go index 71370c9b1..1914595dc 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -29,8 +29,8 @@ func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries { if hostDexNeeded { var output android.Path - if library.dexJarFile != nil { - output = library.dexJarFile + if library.dexJarFile.IsSet() { + output = library.dexJarFile.Path() } else { output = library.implementationAndResourcesJar } @@ -44,8 +44,8 @@ func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries { func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { entries.SetBool("LOCAL_IS_HOST_MODULE", true) entries.SetPath("LOCAL_PREBUILT_MODULE_FILE", output) - if library.dexJarFile != nil { - entries.SetPath("LOCAL_SOONG_DEX_JAR", library.dexJarFile) + if library.dexJarFile.IsSet() { + entries.SetPath("LOCAL_SOONG_DEX_JAR", library.dexJarFile.Path()) } entries.SetPath("LOCAL_SOONG_HEADER_JAR", library.headerJarFile) entries.SetPath("LOCAL_SOONG_CLASSES_JAR", library.implementationAndResourcesJar) @@ -106,8 +106,8 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries { if library.installFile == nil { entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", true) } - if library.dexJarFile != nil { - entries.SetPath("LOCAL_SOONG_DEX_JAR", library.dexJarFile) + if library.dexJarFile.IsSet() { + entries.SetPath("LOCAL_SOONG_DEX_JAR", library.dexJarFile.Path()) } if len(library.dexpreopter.builtInstalled) > 0 { entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", library.dexpreopter.builtInstalled) @@ -207,8 +207,8 @@ func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries { ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !Bool(prebuilt.properties.Installable)) - if prebuilt.dexJarFile != nil { - entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile) + if prebuilt.dexJarFile.IsSet() { + entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile.Path()) } entries.SetPath("LOCAL_SOONG_HEADER_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{ Class: "JAVA_LIBRARIES", - OutputFile: android.OptionalPathForPath(prebuilt.dexJarFile), + OutputFile: android.OptionalPathForPath(prebuilt.dexJarFile.Path()), Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk", ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - if prebuilt.dexJarFile != nil { - entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile) + if prebuilt.dexJarFile.IsSet() { + entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile.Path()) } if len(prebuilt.dexpreopter.builtInstalled) > 0 { 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) { entries.SetPath("LOCAL_SOONG_HEADER_JAR", binary.headerJarFile) entries.SetPath("LOCAL_SOONG_CLASSES_JAR", binary.implementationAndResourcesJar) - if binary.dexJarFile != nil { - entries.SetPath("LOCAL_SOONG_DEX_JAR", binary.dexJarFile) + if binary.dexJarFile.IsSet() { + entries.SetPath("LOCAL_SOONG_DEX_JAR", binary.dexJarFile.Path()) } if len(binary.dexpreopter.builtInstalled) > 0 { 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.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", app.appProperties.PreventInstall) entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", app.exportPackage) - if app.dexJarFile != nil { - entries.SetPath("LOCAL_SOONG_DEX_JAR", app.dexJarFile) + if app.dexJarFile.IsSet() { + entries.SetPath("LOCAL_SOONG_DEX_JAR", app.dexJarFile.Path()) } if app.implementationAndResourcesJar != nil { entries.SetPath("LOCAL_SOONG_CLASSES_JAR", app.implementationAndResourcesJar) diff --git a/java/app.go b/java/app.go index a62e442ac..2fd646322 100755 --- a/java/app.go +++ b/java/app.go @@ -476,7 +476,7 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path { a.Module.compile(ctx, a.aaptSrcJar) } - return a.dexJarFile + return a.dexJarFile.PathOrNil() } 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) } 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() { ctx.AddMissingDependencies([]string{dep}) } else { diff --git a/java/base.go b/java/base.go index 78aaa19cf..579085b8a 100644 --- a/java/base.go +++ b/java/base.go @@ -276,6 +276,87 @@ func (e *embeddableInModuleAndImport) depIsInSameApex(ctx android.BaseModuleCont 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 "" + } + 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 type Module struct { android.ModuleBase @@ -310,7 +391,7 @@ type Module struct { implementationAndResourcesJar android.Path // output file containing classes.dex and resources - dexJarFile android.Path + dexJarFile OptionalDexJarPath // output file containing uninstrumented classes that will be instrumented by jacoco jacocoReportClassesFile android.Path @@ -1265,12 +1346,13 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { } // 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. dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile) - j.dexJarFile = dexOutputFile + j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) // Dexpreopting 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 // to the APK if this is an app. outputFile = implementationAndResourcesJar - j.dexJarFile = j.resourceJar + j.dexJarFile = makeDexJarPathFromPath(j.resourceJar) } if ctx.Failed() { @@ -1470,7 +1552,7 @@ func (j *Module) ImplementationJars() android.Paths { return android.Paths{j.implementationJarFile} } -func (j *Module) DexJarBuildPath() android.Path { +func (j *Module) DexJarBuildPath() OptionalDexJarPath { return j.dexJarFile } diff --git a/java/hiddenapi.go b/java/hiddenapi.go index 30683daa0..7c8be1e6e 100644 --- a/java/hiddenapi.go +++ b/java/hiddenapi.go @@ -30,14 +30,14 @@ type hiddenAPI struct { // that information encoded within it. 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 -hiddenapi modules that provide additional // annotations for the boot dex jar but which do not actually provide a boot dex jar // themselves. // // 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. - bootDexJarPath android.Path + bootDexJarPath OptionalDexJarPath // 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 @@ -49,7 +49,7 @@ type hiddenAPI struct { uncompressDexState *bool } -func (h *hiddenAPI) bootDexJar() android.Path { +func (h *hiddenAPI) bootDexJar() OptionalDexJarPath { return h.bootDexJarPath } @@ -68,7 +68,7 @@ type hiddenAPIModule interface { } type hiddenAPIIntf interface { - bootDexJar() android.Path + bootDexJar() OptionalDexJarPath classesJars() android.Paths 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 // 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 // processing. diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index 1c6fbac72..b9a1ca74d 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -19,6 +19,7 @@ import ( "strings" "android/soong/android" + "github.com/google/blueprint" ) @@ -277,7 +278,7 @@ func hiddenAPIAddStubLibDependencies(ctx android.BottomUpMutatorContext, apiScop // hiddenAPIRetrieveDexJarBuildPath retrieves the DexJarBuildPath from the specified module, if // available, or reports an error. 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 { dexJar = sdkLibrary.SdkApiStubDexJar(ctx, kind) } else if j, ok := module.(UsesLibraryDependency); ok { @@ -287,10 +288,11 @@ func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android. return nil } - if dexJar == nil { - ctx.ModuleErrorf("dependency %s does not provide a dex jar, consider setting compile_dex: true", module) + if !dexJar.Valid() { + 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. @@ -1159,18 +1161,17 @@ func extractBootDexInfoFromModules(ctx android.ModuleContext, contents []android // 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 -// create a fake path and either report an error immediately or defer reporting of the error until -// the path is actually used. +// If the module does not provide a boot dex jar, i.e. the returned boot dex jar is unset or +// invalid, then create a fake path and either report an error immediately or defer reporting of the +// error until the path is actually used. func retrieveBootDexJarFromHiddenAPIModule(ctx android.ModuleContext, module hiddenAPIModule) android.Path { bootDexJar := module.bootDexJar() - if bootDexJar == nil { + if !bootDexJar.Valid() { fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/boot-dex/%s.jar", module.Name())) - bootDexJar = fake - - handleMissingDexBootFile(ctx, module, fake) + handleMissingDexBootFile(ctx, module, fake, bootDexJar.InvalidReason()) + return fake } - return bootDexJar + return bootDexJar.Path() } // 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 // 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) { // Create an error rule that pretends to create the output file but will actually fail if it // is run. @@ -1272,11 +1273,11 @@ func handleMissingDexBootFile(ctx android.ModuleContext, module android.Module, Rule: android.ErrorRule, Output: fake, 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 { - 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 // a path to a fake file. func retrieveEncodedBootDexJarFromModule(ctx android.ModuleContext, module android.Module) android.Path { - bootDexJar := module.(interface{ DexJarBuildPath() android.Path }).DexJarBuildPath() - if bootDexJar == nil { + bootDexJar := module.(interface{ DexJarBuildPath() OptionalDexJarPath }).DexJarBuildPath() + if !bootDexJar.Valid() { fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/encoded-dex/%s.jar", module.Name())) - bootDexJar = fake - - handleMissingDexBootFile(ctx, module, fake) + handleMissingDexBootFile(ctx, module, fake, bootDexJar.InvalidReason()) + return fake } - return bootDexJar + return bootDexJar.Path() } // extractEncodedDexJarsFromModules extracts the encoded dex jars from the supplied modules. diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go index dcd363c2c..75b7bb7c8 100644 --- a/java/hiddenapi_singleton_test.go +++ b/java/hiddenapi_singleton_test.go @@ -20,6 +20,7 @@ import ( "testing" "android/soong/android" + "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()) // 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) } diff --git a/java/java.go b/java/java.go index 4a4486658..cfed1c893 100644 --- a/java/java.go +++ b/java/java.go @@ -219,7 +219,7 @@ type ApexDependency interface { // Provides build path and install path to DEX jars. type UsesLibraryDependency interface { - DexJarBuildPath() android.Path + DexJarBuildPath() OptionalDexJarPath DexJarInstallPath() android.Path ClassLoaderContexts() dexpreopt.ClassLoaderContextMap } @@ -1215,7 +1215,7 @@ type Import struct { properties ImportProperties // output file containing classes.dex and resources - dexJarFile android.Path + dexJarFile OptionalDexJarPath dexJarInstallFile android.Path combinedClasspathFile android.Path @@ -1370,11 +1370,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Get the path of the dex implementation jar from the `deapexer` module. di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) 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())) // Initialize the hiddenapi structure. - j.initHiddenAPI(ctx, dexOutputPath, outputFile, nil) + j.initHiddenAPI(ctx, dexJarFile, outputFile, nil) } else { // 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. @@ -1407,12 +1408,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { } // 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. dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile) - j.dexJarFile = dexOutputFile + j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) j.dexJarInstallFile = android.PathForModuleInstall(ctx, "framework", jarName) } } @@ -1450,7 +1451,7 @@ func (j *Import) ImplementationAndResourcesJars() android.Paths { return android.Paths{j.combinedClasspathFile} } -func (j *Import) DexJarBuildPath() android.Path { +func (j *Import) DexJarBuildPath() OptionalDexJarPath { return j.dexJarFile } @@ -1595,7 +1596,7 @@ type DexImport struct { properties DexImportProperties - dexJarFile android.Path + dexJarFile OptionalDexJarPath dexpreopter @@ -1686,7 +1687,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { }) } - j.dexJarFile = dexOutputFile + j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) j.dexpreopt(ctx, dexOutputFile) @@ -1696,7 +1697,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } -func (j *DexImport) DexJarBuildPath() android.Path { +func (j *DexImport) DexJarBuildPath() OptionalDexJarPath { return j.dexJarFile } @@ -1865,7 +1866,7 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, // from its CLC should be added to the current CLC. if sdkLib != nil { clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false, true, - dep.DexJarBuildPath(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) + dep.DexJarBuildPath().PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) } else { clcMap.AddContextMap(dep.ClassLoaderContexts(), depName) } diff --git a/java/java_test.go b/java/java_test.go index 8bb017f0b..bc9b40964 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -600,8 +600,8 @@ func TestPrebuilts(t *testing.T) { } barDexJar := barModule.Module().(*Import).DexJarBuildPath() - if barDexJar != nil { - t.Errorf("bar dex jar build path expected to be nil, got %q", barDexJar) + if barDexJar.IsSet() { + t.Errorf("bar dex jar build path expected to be set, got %s", barDexJar) } 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()) } - bazDexJar := bazModule.Module().(*Import).DexJarBuildPath() + bazDexJar := bazModule.Module().(*Import).DexJarBuildPath().Path() expectedDexJar := "out/soong/.intermediates/baz/android_common/dex/baz.jar" android.AssertPathRelativeToTopEquals(t, "baz dex jar build path", expectedDexJar, bazDexJar) diff --git a/java/sdk_library.go b/java/sdk_library.go index 2d8aef74c..0fcce1752 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -540,7 +540,7 @@ type scopePaths struct { // The dex jar for the 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. currentApiFilePath android.OptionalPath @@ -906,10 +906,10 @@ func sdkKindToApiScope(kind android.SdkKind) *apiScope { } // 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) if paths == nil { - return nil + return makeUnsetDexJarPath() } return paths.stubsDexJarPath @@ -1035,7 +1035,7 @@ type SdkLibraryDependency interface { // SdkApiStubDexJar returns the dex jar for the stubs. It is needed by the hiddenapi processing // 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(ctx android.BaseModuleContext, kind android.SdkKind) android.OptionalPath @@ -1929,7 +1929,7 @@ type SdkLibraryImport struct { xmlPermissionsFileModule *sdkLibraryXml // 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) // or dex implementation jar obtained from the prebuilt_apex, if any. @@ -2220,11 +2220,12 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo // Get the path of the dex implementation jar from the `deapexer` module. di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(module.BaseModuleName())); dexOutputPath != nil { - module.dexJarFile = dexOutputPath + dexJarFile := makeDexJarPathFromPath(dexOutputPath) + module.dexJarFile = dexJarFile installPath := android.PathForModuleInPartitionInstall( ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(module.BaseModuleName())) module.installFile = installPath - module.initHiddenAPI(ctx, dexOutputPath, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil) + module.initHiddenAPI(ctx, dexJarFile, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil) // Dexpreopting. module.dexpreopter.installPath = module.dexpreopter.getInstallPath(ctx, installPath) @@ -2269,14 +2270,14 @@ func (module *SdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleCont } // 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 // source. - if module.dexJarFile != nil { + if module.dexJarFile.IsSet() { return module.dexJarFile } if module.implLibraryModule == nil { - return nil + return makeUnsetDexJarPath() } else { return module.implLibraryModule.DexJarBuildPath() } diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go index 9efb3a49a..73ef7ea89 100644 --- a/sdk/java_sdk_test.go +++ b/sdk/java_sdk_test.go @@ -1258,7 +1258,7 @@ java_sdk_library_import { ctx := android.ModuleInstallPathContextForTesting(result.Config) dexJarBuildPath := func(name string, kind android.SdkKind) string { dep := result.Module(name, "android_common").(java.SdkLibraryDependency) - path := dep.SdkApiStubDexJar(ctx, kind) + path := dep.SdkApiStubDexJar(ctx, kind).Path() return path.RelativeToTop().String() }