diff --git a/android/deapexer.go b/android/deapexer.go index de933d1a4..fb2073dcd 100644 --- a/android/deapexer.go +++ b/android/deapexer.go @@ -15,6 +15,7 @@ package android import ( + "fmt" "strings" "github.com/google/blueprint" @@ -146,10 +147,16 @@ type RequiresFilesFromPrebuiltApexTag interface { // FindDeapexerProviderForModule searches through the direct dependencies of the current context // module for a DeapexerTag dependency and returns its DeapexerInfo. If a single nonambiguous -// deapexer module isn't found then errors are reported with ctx.ModuleErrorf and nil is returned. -func FindDeapexerProviderForModule(ctx ModuleContext) *DeapexerInfo { +// deapexer module isn't found then it returns it an error +// clients should check the value of error and call ctx.ModuleErrof if a non nil error is received +func FindDeapexerProviderForModule(ctx ModuleContext) (*DeapexerInfo, error) { var di *DeapexerInfo + var err error ctx.VisitDirectDepsWithTag(DeapexerTag, func(m Module) { + if err != nil { + // An err has been found. Do not visit further. + return + } c, _ := OtherModuleProvider(ctx, m, DeapexerProvider) p := &c if di != nil { @@ -159,17 +166,18 @@ func FindDeapexerProviderForModule(ctx ModuleContext) *DeapexerInfo { di = selected return } - ctx.ModuleErrorf("Multiple installable prebuilt APEXes provide ambiguous deapexers: %s and %s", - di.ApexModuleName(), p.ApexModuleName()) + err = fmt.Errorf("Multiple installable prebuilt APEXes provide ambiguous deapexers: %s and %s", di.ApexModuleName(), p.ApexModuleName()) } di = p }) + if err != nil { + return nil, err + } if di != nil { - return di + return di, nil } ai, _ := ModuleProvider(ctx, ApexInfoProvider) - ctx.ModuleErrorf("No prebuilt APEX provides a deapexer module for APEX variant %s", ai.ApexVariationName) - return nil + return nil, fmt.Errorf("No prebuilt APEX provides a deapexer module for APEX variant %s", ai.ApexVariationName) } // removeCompressedApexSuffix removes the _compressed suffix from the name if present. diff --git a/apex/apex_test.go b/apex/apex_test.go index 1ced39364..6c7dabccb 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -8432,6 +8432,13 @@ func TestDuplicateDeapexersFromPrebuiltApexes(t *testing.T) { prebuilt_bootclasspath_fragment { name: "my-bootclasspath-fragment", apex_available: ["com.android.myapex"], + hidden_api: { + annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", + metadata: "my-bootclasspath-fragment/metadata.csv", + index: "my-bootclasspath-fragment/index.csv", + stub_flags: "my-bootclasspath-fragment/stub-flags.csv", + all_flags: "my-bootclasspath-fragment/all-flags.csv", + }, %s } ` @@ -8453,6 +8460,7 @@ func TestDuplicateDeapexersFromPrebuiltApexes(t *testing.T) { public: { jars: ["libbar.jar"], }, + shared_library: false, apex_available: ["com.android.myapex"], } `) @@ -8468,6 +8476,7 @@ func TestDuplicateDeapexersFromPrebuiltApexes(t *testing.T) { public: { jars: ["libbar.jar"], }, + shared_library: false, apex_available: ["com.android.myapex"], } `) diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 4c44678e7..b13ecc2fd 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -193,7 +193,10 @@ func (p *prebuiltCommon) dexpreoptSystemServerJars(ctx android.ModuleContext) { } // Use apex_name to determine the api domain of this prebuilt apex apexName := p.ApexVariationName() - di := android.FindDeapexerProviderForModule(ctx) + di, err := android.FindDeapexerProviderForModule(ctx) + if err != nil { + ctx.ModuleErrorf(err.Error()) + } dc := dexpreopt.GetGlobalConfig(ctx) systemServerJarList := dc.AllApexSystemServerJars(ctx) diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index d2bb52315..83030b51e 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -240,7 +240,8 @@ type BootclasspathFragmentModule struct { sourceOnlyProperties SourceOnlyBootclasspathProperties // Path to the boot image profile. - profilePath android.WritablePath + profilePath android.WritablePath + profilePathErr error } // commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt @@ -1065,8 +1066,11 @@ func (module *PrebuiltBootclasspathFragmentModule) produceBootImageProfile(ctx a return nil } - di := android.FindDeapexerProviderForModule(ctx) - if di == nil { + di, err := android.FindDeapexerProviderForModule(ctx) + if err != nil { + // An error was found, possibly due to multiple apexes in the tree that export this library + // Defer the error till a client tries to call getProfilePath + module.profilePathErr = err return nil // An error has been reported by FindDeapexerProviderForModule. } @@ -1074,6 +1078,9 @@ func (module *PrebuiltBootclasspathFragmentModule) produceBootImageProfile(ctx a } func (b *PrebuiltBootclasspathFragmentModule) getProfilePath() android.Path { + if b.profilePathErr != nil { + panic(b.profilePathErr.Error()) + } return b.profilePath } diff --git a/java/java.go b/java/java.go index 630318e6d..51e8c344c 100644 --- a/java/java.go +++ b/java/java.go @@ -2100,6 +2100,7 @@ type Import struct { // output file containing classes.dex and resources dexJarFile OptionalDexJarPath + dexJarFileErr error dexJarInstallFile android.Path combinedClasspathFile android.Path @@ -2250,9 +2251,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) if ai.ForPrebuiltApex { // Get the path of the dex implementation jar from the `deapexer` module. - di := android.FindDeapexerProviderForModule(ctx) - if di == nil { - return // An error has been reported by FindDeapexerProviderForModule. + di, err := android.FindDeapexerProviderForModule(ctx) + if err != nil { + // An error was found, possibly due to multiple apexes in the tree that export this library + // Defer the error till a client tries to call DexJarBuildPath + j.dexJarFileErr = err + return } dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(j.BaseModuleName()) if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil { @@ -2375,6 +2379,9 @@ func (j *Import) ImplementationAndResourcesJars() android.Paths { } func (j *Import) DexJarBuildPath() OptionalDexJarPath { + if j.dexJarFileErr != nil { + panic(j.dexJarFileErr.Error()) + } return j.dexJarFile } diff --git a/java/sdk_library.go b/java/sdk_library.go index a634b1749..38bd301f4 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -2378,7 +2378,8 @@ type SdkLibraryImport struct { xmlPermissionsFileModule *sdkLibraryXml // Build path to the dex implementation jar obtained from the prebuilt_apex, if any. - dexJarFile OptionalDexJarPath + dexJarFile OptionalDexJarPath + dexJarFileErr error // Expected install file path of the source module(sdk_library) // or dex implementation jar obtained from the prebuilt_apex, if any. @@ -2687,9 +2688,12 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) if ai.ForPrebuiltApex { // Get the path of the dex implementation jar from the `deapexer` module. - di := android.FindDeapexerProviderForModule(ctx) - if di == nil { - return // An error has been reported by FindDeapexerProviderForModule. + di, err := android.FindDeapexerProviderForModule(ctx) + if err != nil { + // An error was found, possibly due to multiple apexes in the tree that export this library + // Defer the error till a client tries to call DexJarBuildPath + module.dexJarFileErr = err + return } dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(module.BaseModuleName()) if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil { @@ -2751,6 +2755,9 @@ func (module *SdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleCont func (module *SdkLibraryImport) DexJarBuildPath() OptionalDexJarPath { // The dex implementation jar extracted from the .apex file should be used in preference to the // source. + if module.dexJarFileErr != nil { + panic(module.dexJarFileErr.Error()) + } if module.dexJarFile.IsSet() { return module.dexJarFile }