diff --git a/android/module.go b/android/module.go index 66f6e1bcd..2fe822f26 100644 --- a/android/module.go +++ b/android/module.go @@ -2491,6 +2491,8 @@ func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet { return outputFilesFromProvider, err } + // TODO: add error when outputFilesFromProvider and err are both nil after + // OutputFileProducer and SourceFileProducer are deprecated. if outputFileProducer, ok := module.(OutputFileProducer); ok { paths, err := outputFileProducer.OutputFiles(tag) if err != nil { @@ -2505,7 +2507,7 @@ func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) paths := sourceFileProducer.Srcs() return paths, nil } else { - return nil, fmt.Errorf("module %q is not an OutputFileProducer or SourceFileProducer", pathContextName(ctx, module)) + return nil, fmt.Errorf("module %q is not an SourceFileProducer or having valid output file for tag %q", pathContextName(ctx, module), tag) } } diff --git a/java/aar.go b/java/aar.go index 4aae62a45..2f49a959d 100644 --- a/java/aar.go +++ b/java/aar.go @@ -798,18 +798,6 @@ type AndroidLibrary struct { aarFile android.WritablePath } -var _ android.OutputFileProducer = (*AndroidLibrary)(nil) - -// For OutputFileProducer interface -func (a *AndroidLibrary) OutputFiles(tag string) (android.Paths, error) { - switch tag { - case ".aar": - return []android.Path{a.aarFile}, nil - default: - return a.Library.OutputFiles(tag) - } -} - var _ AndroidLibraryDependency = (*AndroidLibrary)(nil) func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { @@ -911,6 +899,13 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{ AconfigTextFiles: aconfigTextFilePaths, }) + + a.setOutputFiles(ctx) +} + +func (a *AndroidLibrary) setOutputFiles(ctx android.ModuleContext) { + ctx.SetOutputFiles([]android.Path{a.aarFile}, ".aar") + setOutputFiles(ctx, a.Library.Module) } func (a *AndroidLibrary) IDEInfo(dpInfo *android.IdeInfo) { diff --git a/java/aar_test.go b/java/aar_test.go index 1ab1f9c90..ebad310ab 100644 --- a/java/aar_test.go +++ b/java/aar_test.go @@ -159,19 +159,19 @@ func TestAndroidLibraryOutputFilesRel(t *testing.T) { bar := result.ModuleForTests("bar", "android_common") baz := result.ModuleForTests("baz", "android_common") - fooOutputPath := android.OutputFileForModule(android.PathContext(nil), foo.Module(), "") + fooOutputPaths := foo.OutputFiles(t, "") barOutputPaths := bar.OutputFiles(t, "") bazOutputPaths := baz.OutputFiles(t, "") - android.AssertPathRelativeToTopEquals(t, "foo output path", - "out/soong/.intermediates/foo/android_common/withres/foo.jar", fooOutputPath) + android.AssertPathsRelativeToTopEquals(t, "foo output path", + []string{"out/soong/.intermediates/foo/android_common/withres/foo.jar"}, fooOutputPaths) android.AssertPathsRelativeToTopEquals(t, "bar output path", []string{"out/soong/.intermediates/bar/android_common/aar/bar.jar"}, barOutputPaths) android.AssertPathsRelativeToTopEquals(t, "baz output path", []string{"out/soong/.intermediates/baz/android_common/withres/baz.jar"}, bazOutputPaths) android.AssertStringEquals(t, "foo relative output path", - "foo.jar", fooOutputPath.Rel()) + "foo.jar", fooOutputPaths[0].Rel()) android.AssertStringEquals(t, "bar relative output path", "bar.jar", barOutputPaths[0].Rel()) android.AssertStringEquals(t, "baz relative output path", diff --git a/java/app.go b/java/app.go index e8c9bfe5a..fc2294c24 100644 --- a/java/app.go +++ b/java/app.go @@ -1017,6 +1017,22 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { isPrebuilt: false, }, ) + + a.setOutputFiles(ctx) +} + +func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) { + ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile") + if a.aaptSrcJar != nil { + ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar") + } + if a.rJar != nil { + ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar") + } + ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk") + ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk") + ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml") + setOutputFiles(ctx, a.Library.Module) } type appDepsInterface interface { @@ -1207,31 +1223,6 @@ func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android. return a.Library.DepIsInSameApex(ctx, dep) } -// For OutputFileProducer interface -func (a *AndroidApp) OutputFiles(tag string) (android.Paths, error) { - switch tag { - // In some instances, it can be useful to reference the aapt-generated flags from another - // target, e.g., system server implements services declared in the framework-res manifest. - case ".aapt.proguardOptionsFile": - return []android.Path{a.proguardOptionsFile}, nil - case ".aapt.srcjar": - if a.aaptSrcJar != nil { - return []android.Path{a.aaptSrcJar}, nil - } - case ".aapt.jar": - if a.rJar != nil { - return []android.Path{a.rJar}, nil - } - case ".apk": - return []android.Path{a.outputFile}, nil - case ".export-package.apk": - return []android.Path{a.exportPackage}, nil - case ".manifest.xml": - return []android.Path{a.aapt.manifestPath}, nil - } - return a.Library.OutputFiles(tag) -} - func (a *AndroidApp) Privileged() bool { return Bool(a.appProperties.Privileged) } diff --git a/java/app_test.go b/java/app_test.go index 5770ab45e..e878ccf6d 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -119,10 +119,7 @@ func TestAppSplits(t *testing.T) { foo.Output(expectedOutput) } - outputFiles, err := foo.Module().(*AndroidApp).OutputFiles("") - if err != nil { - t.Fatal(err) - } + outputFiles := foo.OutputFiles(t, "") android.AssertPathsRelativeToTopEquals(t, `OutputFiles("")`, expectedOutputs, outputFiles) } diff --git a/java/base.go b/java/base.go index ee8df3e76..fc68d2018 100644 --- a/java/base.go +++ b/java/base.go @@ -652,35 +652,21 @@ func (j *Module) provideHiddenAPIPropertyInfo(ctx android.ModuleContext) { android.SetProvider(ctx, hiddenAPIPropertyInfoProvider, hiddenAPIInfo) } -func (j *Module) OutputFiles(tag string) (android.Paths, error) { - switch tag { - case "": - return append(android.Paths{j.outputFile}, j.extraOutputFiles...), nil - case android.DefaultDistTag: - return android.Paths{j.outputFile}, nil - case ".jar": - return android.Paths{j.implementationAndResourcesJar}, nil - case ".hjar": - return android.Paths{j.headerJarFile}, nil - case ".proguard_map": - if j.dexer.proguardDictionary.Valid() { - return android.Paths{j.dexer.proguardDictionary.Path()}, nil - } - return nil, fmt.Errorf("%q was requested, but no output file was found.", tag) - case ".generated_srcjars": - return j.properties.Generated_srcjars, nil - case ".lint": - if j.linter.outputs.xml != nil { - return android.Paths{j.linter.outputs.xml}, nil - } - return nil, fmt.Errorf("%q was requested, but no output file was found.", tag) - default: - return nil, fmt.Errorf("unsupported module reference tag %q", tag) +// helper method for java modules to set OutputFilesProvider +func setOutputFiles(ctx android.ModuleContext, m Module) { + ctx.SetOutputFiles(append(android.Paths{m.outputFile}, m.extraOutputFiles...), "") + ctx.SetOutputFiles(android.Paths{m.outputFile}, android.DefaultDistTag) + ctx.SetOutputFiles(android.Paths{m.implementationAndResourcesJar}, ".jar") + ctx.SetOutputFiles(android.Paths{m.headerJarFile}, ".hjar") + if m.dexer.proguardDictionary.Valid() { + ctx.SetOutputFiles(android.Paths{m.dexer.proguardDictionary.Path()}, ".proguard_map") + } + ctx.SetOutputFiles(m.properties.Generated_srcjars, ".generated_srcjars") + if m.linter.outputs.xml != nil { + ctx.SetOutputFiles(android.Paths{m.linter.outputs.xml}, ".lint") } } -var _ android.OutputFileProducer = (*Module)(nil) - func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) { initJavaModule(module, hod, false) } diff --git a/java/java.go b/java/java.go index e4abbcd28..5fdb4b871 100644 --- a/java/java.go +++ b/java/java.go @@ -977,6 +977,8 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { TestOnly: Bool(j.sourceProperties.Test_only), TopLevelTarget: j.sourceProperties.Top_level_test_target, }) + + setOutputFiles(ctx, j.Module) } func (j *Library) setInstallRules(ctx android.ModuleContext, installModuleName string) { @@ -1836,6 +1838,8 @@ func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { // libraries. This is verified by TestBinary. j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"), ctx.ModuleName()+ext, j.wrapperFile) + + setOutputFiles(ctx, j.Library.Module) } } diff --git a/java/java_test.go b/java/java_test.go index 51c969e77..33079f381 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -2993,19 +2993,19 @@ func TestJavaLibraryOutputFilesRel(t *testing.T) { bar := result.ModuleForTests("bar", "android_common") baz := result.ModuleForTests("baz", "android_common") - fooOutputPath := android.OutputFileForModule(android.PathContext(nil), foo.Module(), "") + fooOutputPaths := foo.OutputFiles(t, "") barOutputPaths := bar.OutputFiles(t, "") bazOutputPaths := baz.OutputFiles(t, "") - android.AssertPathRelativeToTopEquals(t, "foo output path", - "out/soong/.intermediates/foo/android_common/javac/foo.jar", fooOutputPath) + android.AssertPathsRelativeToTopEquals(t, "foo output path", + []string{"out/soong/.intermediates/foo/android_common/javac/foo.jar"}, fooOutputPaths) android.AssertPathsRelativeToTopEquals(t, "bar output path", []string{"out/soong/.intermediates/bar/android_common/combined/bar.jar"}, barOutputPaths) android.AssertPathsRelativeToTopEquals(t, "baz output path", []string{"out/soong/.intermediates/baz/android_common/combined/baz.jar"}, bazOutputPaths) android.AssertStringEquals(t, "foo relative output path", - "foo.jar", fooOutputPath.Rel()) + "foo.jar", fooOutputPaths[0].Rel()) android.AssertStringEquals(t, "bar relative output path", "bar.jar", barOutputPaths[0].Rel()) android.AssertStringEquals(t, "baz relative output path", diff --git a/java/sdk_library.go b/java/sdk_library.go index e6cb6c49b..031bde3c8 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1086,57 +1086,26 @@ var tagSplitter = func() *regexp.Regexp { return regexp.MustCompile(fmt.Sprintf(`^\.(%s)\.(%s)$`, scopesRegexp, componentsRegexp)) }() -// For OutputFileProducer interface -// -// .., for all ComponentNames (for example: .public.removed-api.txt) -func (c *commonToSdkLibraryAndImport) commonOutputFiles(tag string) (android.Paths, error) { - if groups := tagSplitter.FindStringSubmatch(tag); groups != nil { - scopeName := groups[1] - component := groups[2] - - if scope, ok := scopeByName[scopeName]; ok { - paths := c.findScopePaths(scope) - if paths == nil { - return nil, fmt.Errorf("%q does not provide api scope %s", c.module.RootLibraryName(), scopeName) - } - - switch component { - case stubsSourceComponentName: - if paths.stubsSrcJar.Valid() { - return android.Paths{paths.stubsSrcJar.Path()}, nil - } - - case apiTxtComponentName: - if paths.currentApiFilePath.Valid() { - return android.Paths{paths.currentApiFilePath.Path()}, nil - } - - case removedApiTxtComponentName: - if paths.removedApiFilePath.Valid() { - return android.Paths{paths.removedApiFilePath.Path()}, nil - } - - case annotationsComponentName: - if paths.annotationsZip.Valid() { - return android.Paths{paths.annotationsZip.Path()}, nil - } - } - - return nil, fmt.Errorf("%s not available for api scope %s", component, scopeName) - } else { - return nil, fmt.Errorf("unknown scope %s in %s", scope, tag) +func (module *commonToSdkLibraryAndImport) setOutputFiles(ctx android.ModuleContext) { + if module.doctagPaths != nil { + ctx.SetOutputFiles(module.doctagPaths, ".doctags") + } + for _, scopeName := range android.SortedKeys(scopeByName) { + paths := module.findScopePaths(scopeByName[scopeName]) + if paths == nil { + continue } - - } else { - switch tag { - case ".doctags": - if c.doctagPaths != nil { - return c.doctagPaths, nil - } else { - return nil, fmt.Errorf("no doctag_files specified on %s", c.module.RootLibraryName()) + componentToOutput := map[string]android.OptionalPath{ + stubsSourceComponentName: paths.stubsSrcJar, + apiTxtComponentName: paths.currentApiFilePath, + removedApiTxtComponentName: paths.removedApiFilePath, + annotationsComponentName: paths.annotationsZip, + } + for _, component := range android.SortedKeys(componentToOutput) { + if componentToOutput[component].Valid() { + ctx.SetOutputFiles(android.Paths{componentToOutput[component].Path()}, "."+scopeName+"."+component) } } - return nil, nil } } @@ -1579,20 +1548,6 @@ func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { } } -func (module *SdkLibrary) OutputFiles(tag string) (android.Paths, error) { - paths, err := module.commonOutputFiles(tag) - if paths != nil || err != nil { - return paths, err - } - if module.requiresRuntimeImplementationLibrary() { - return module.implLibraryModule.OutputFiles(tag) - } - if tag == "" { - return nil, nil - } - return nil, fmt.Errorf("unsupported module reference tag %q", tag) -} - func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { if disableSourceApexVariant(ctx) { // Prebuilts are active, do not create the installation rules for the source javalib. @@ -1702,6 +1657,10 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) } } android.SetProvider(ctx, android.AdditionalSdkInfoProvider, android.AdditionalSdkInfo{additionalSdkInfo}) + module.setOutputFiles(ctx) + if module.requiresRuntimeImplementationLibrary() && module.implLibraryModule != nil { + setOutputFiles(ctx, module.implLibraryModule.Module) + } } func (module *SdkLibrary) BuiltInstalledForApex() []dexpreopterInstall { @@ -2937,18 +2896,6 @@ func (module *SdkLibraryImport) MinSdkVersion(ctx android.EarlyModuleContext) an var _ hiddenAPIModule = (*SdkLibraryImport)(nil) -func (module *SdkLibraryImport) OutputFiles(tag string) (android.Paths, error) { - paths, err := module.commonOutputFiles(tag) - if paths != nil || err != nil { - return paths, err - } - if module.implLibraryModule != nil { - return module.implLibraryModule.OutputFiles(tag) - } else { - return nil, nil - } -} - func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { module.generateCommonBuildActions(ctx) @@ -3031,6 +2978,11 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo } } } + + module.setOutputFiles(ctx) + if module.implLibraryModule != nil { + setOutputFiles(ctx, module.implLibraryModule.Module) + } } func (module *SdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec, headerJars bool) android.Paths { diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index 39f8c760b..cf1a6e1e3 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -492,7 +492,7 @@ func TestJavaSdkLibrary_AccessOutputFiles_NoAnnotations(t *testing.T) { PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("foo"), ). - ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": failed to get output file from module "foo" at tag ".public.annotations.zip": annotations.zip not available for api scope public`)). + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": unsupported module reference tag ".public.annotations.zip"`)). RunTestWithBp(t, ` java_sdk_library { name: "foo", @@ -517,7 +517,7 @@ func TestJavaSdkLibrary_AccessOutputFiles_MissingScope(t *testing.T) { PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("foo"), ). - ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`"foo" does not provide api scope system`)). + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": unsupported module reference tag ".system.stubs.source"`)). RunTestWithBp(t, ` java_sdk_library { name: "foo", @@ -606,7 +606,7 @@ func TestJavaSdkLibraryImport_AccessOutputFiles_Invalid(t *testing.T) { t.Run("stubs.source", func(t *testing.T) { prepareForJavaTest. - ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`stubs.source not available for api scope public`)). + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not an SourceFileProducer or having valid output file for tag ".public.stubs.source"`)). RunTestWithBp(t, bp+` java_library { name: "bar", @@ -621,7 +621,7 @@ func TestJavaSdkLibraryImport_AccessOutputFiles_Invalid(t *testing.T) { t.Run("api.txt", func(t *testing.T) { prepareForJavaTest. - ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`api.txt not available for api scope public`)). + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not an SourceFileProducer or having valid output file for tag ".public.api.txt"`)). RunTestWithBp(t, bp+` java_library { name: "bar", @@ -635,7 +635,7 @@ func TestJavaSdkLibraryImport_AccessOutputFiles_Invalid(t *testing.T) { t.Run("removed-api.txt", func(t *testing.T) { prepareForJavaTest. - ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`removed-api.txt not available for api scope public`)). + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not an SourceFileProducer or having valid output file for tag ".public.removed-api.txt"`)). RunTestWithBp(t, bp+` java_library { name: "bar",