From 2d732e0070c8650f3dcbe06d52768d6a1cfa8b89 Mon Sep 17 00:00:00 2001 From: Aurimas Liutikas Date: Wed, 11 Mar 2020 16:28:05 -0700 Subject: Do not include any documentation when building stubs We only need documentation (javadocs) when building docs stubs, for regular stubs, we can drop printing out all the docs. Tested with: touch frameworks/base/core/java/android/view/View.java && time make -j framework Before (with just r.android.com/1254909) Run #1 2m4.779s Run #2 2m6.672s Run #3 2m4.179s Average: 125.2 seconds After (with this patch and r.android.com/1254909) Run #1 1m58.682s Run #2 1m58.820s Run #3 1m57.724s Average: 118.4 seconds Speedup ~6.8 seconds (5.4%) Bug: 151160048 Test: make checkapi Change-Id: I27eafb5a61bb9d26a74ca25f84c9daca17a8394f Merged-in: I27eafb5a61bb9d26a74ca25f84c9daca17a8394f --- java/droiddoc.go | 1 + 1 file changed, 1 insertion(+) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index fd4b90df3..70d997a43 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1344,6 +1344,7 @@ func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuil cmd.FlagWithArg("--doc-stubs ", stubsDir.String()) } else { cmd.FlagWithArg("--stubs ", stubsDir.String()) + cmd.Flag("--exclude-documentation-from-stubs") } } -- cgit v1.2.3-59-g8ed1b From 82f316b8dbc6c641be2cdc2795160df089e9da82 Mon Sep 17 00:00:00 2001 From: Automerger Merge Worker Date: Fri, 28 Feb 2020 21:26:56 +0000 Subject: Add support for order-only dependencies to RuleBuilder Test: TestRuleBuilder Change-Id: I1609a790dd4d0a03c8308b6e552622fe33fa2499 Bug: 153071808 Merged-In: Icfa98d6840b1dc2e273ba29c33011635d1cf93b1 --- android/config.go | 4 ++-- android/variable.go | 7 +++---- cc/linker.go | 8 +++++--- java/droiddoc.go | 3 ++- 4 files changed, 12 insertions(+), 10 deletions(-) (limited to 'java/droiddoc.go') diff --git a/android/config.go b/android/config.go index c9d7dabc4..a81b92849 100644 --- a/android/config.go +++ b/android/config.go @@ -570,8 +570,8 @@ func (c *config) BuildId() string { return String(c.productVariables.BuildId) } -func (c *config) BuildNumberFromFile() string { - return String(c.productVariables.BuildNumberFromFile) +func (c *config) BuildNumberFile(ctx PathContext) Path { + return PathForOutput(ctx, String(c.productVariables.BuildNumberFile)) } // DeviceName returns the name of the current device target diff --git a/android/variable.go b/android/variable.go index 06bd4ed8c..e4dd9fca9 100644 --- a/android/variable.go +++ b/android/variable.go @@ -140,9 +140,8 @@ type productVariables struct { // Suffix to add to generated Makefiles Make_suffix *string `json:",omitempty"` - BuildId *string `json:",omitempty"` - BuildNumberFromFile *string `json:",omitempty"` - DateFromFile *string `json:",omitempty"` + BuildId *string `json:",omitempty"` + BuildNumberFile *string `json:",omitempty"` Platform_version_name *string `json:",omitempty"` Platform_sdk_version *int `json:",omitempty"` @@ -347,7 +346,7 @@ func stringPtr(v string) *string { func (v *productVariables) SetDefaultConfig() { *v = productVariables{ - BuildNumberFromFile: stringPtr("123456789"), + BuildNumberFile: stringPtr("build_number.txt"), Platform_version_name: stringPtr("Q"), Platform_sdk_version: intPtr(28), diff --git a/cc/linker.go b/cc/linker.go index af4cbf333..a7b621a91 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -501,19 +501,21 @@ func init() { var injectVersionSymbol = pctx.AndroidStaticRule("injectVersionSymbol", blueprint.RuleParams{ Command: "$symbolInjectCmd -i $in -o $out -s soong_build_number " + - "-from 'SOONG BUILD NUMBER PLACEHOLDER' -v $buildNumberFromFile", + "-from 'SOONG BUILD NUMBER PLACEHOLDER' -v $$(cat $buildNumberFile)", CommandDeps: []string{"$symbolInjectCmd"}, }, - "buildNumberFromFile") + "buildNumberFile") func (linker *baseLinker) injectVersionSymbol(ctx ModuleContext, in android.Path, out android.WritablePath) { + buildNumberFile := ctx.Config().BuildNumberFile(ctx) ctx.Build(pctx, android.BuildParams{ Rule: injectVersionSymbol, Description: "inject version symbol", Input: in, Output: out, + OrderOnly: android.Paths{buildNumberFile}, Args: map[string]string{ - "buildNumberFromFile": proptools.NinjaEscape(ctx.Config().BuildNumberFromFile()), + "buildNumberFile": buildNumberFile.String(), }, }) } diff --git a/java/droiddoc.go b/java/droiddoc.go index 70d997a43..1ac7444a5 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -773,6 +773,7 @@ func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) { } func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) { + buildNumberFile := ctx.Config().BuildNumberFile(ctx) // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9 // sources, droiddoc will get sources produced by metalava which will have already stripped out the // 1.9 language features. @@ -782,7 +783,7 @@ func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.Rule Flag("-XDignore.symbol.file"). FlagWithArg("-doclet ", "com.google.doclava.Doclava"). FlagWithInputList("-docletpath ", docletPath.Paths(), ":"). - FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()). + FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-$(cat "+buildNumberFile.String()+")").OrderOnly(buildNumberFile). FlagWithArg("-hdf page.now ", `"$(date -d @$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `) if String(d.properties.Custom_template) == "" { -- cgit v1.2.3-59-g8ed1b From 93520edca20aba56c795ccd5ff317c45d57894bc Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Fri, 20 Mar 2020 13:35:40 +0000 Subject: Remove old SdkMemberType API for creating snapshot modules Migrates system modules and droid stubs over to use the new API for creating the snapshot modules and removes the old API. Bug: 153306490 Test: m nothing Merged-In: Ia825767f1f7ee77f68cfe00f53e09e6f6bfa027f Change-Id: Ia825767f1f7ee77f68cfe00f53e09e6f6bfa027f --- android/sdk.go | 28 ---------------------------- java/droiddoc.go | 39 +++++++++++++++++++++++++++------------ java/system_modules.go | 34 ++++++++++++++++++++++------------ sdk/update.go | 7 +------ 4 files changed, 50 insertions(+), 58 deletions(-) (limited to 'java/droiddoc.go') diff --git a/android/sdk.go b/android/sdk.go index fb469b0b6..78e88a0dd 100644 --- a/android/sdk.go +++ b/android/sdk.go @@ -145,10 +145,6 @@ func (s *SdkBase) RequiredSdks() SdkRefs { return s.properties.RequiredSdks } -func (s *SdkBase) BuildSnapshot(sdkModuleContext ModuleContext, builder SnapshotBuilder) { - sdkModuleContext.ModuleErrorf("module type " + sdkModuleContext.OtherModuleType(s.module) + " cannot be used in an sdk") -} - // InitSdkAwareModule initializes the SdkBase struct. This must be called by all modules including // SdkBase. func InitSdkAwareModule(m SdkAware) { @@ -319,17 +315,6 @@ type SdkMemberType interface { // the module is not allowed in whichever sdk property it was added. IsInstance(module Module) bool - // Build the snapshot for the SDK member - // - // The ModuleContext provided is for the SDK module, so information for - // variants in the supplied member can be accessed using the Other... methods. - // - // The SdkMember is guaranteed to contain variants for which the - // IsInstance(Module) method returned true. - // - // deprecated Use AddPrebuiltModule() instead. - BuildSnapshot(sdkModuleContext ModuleContext, builder SnapshotBuilder, member SdkMember) - // Add a prebuilt module that the sdk will populate. // // Returning nil from this will cause the sdk module type to use the deprecated BuildSnapshot @@ -381,19 +366,6 @@ func (b *SdkMemberTypeBase) HasTransitiveSdkMembers() bool { return b.TransitiveSdkMembers } -func (b *SdkMemberTypeBase) BuildSnapshot(sdkModuleContext ModuleContext, builder SnapshotBuilder, member SdkMember) { - panic("override AddPrebuiltModule") -} - -func (b *SdkMemberTypeBase) AddPrebuiltModule(ctx SdkMemberContext, member SdkMember) BpModule { - // Returning nil causes the legacy BuildSnapshot method to be used. - return nil -} - -func (b *SdkMemberTypeBase) CreateVariantPropertiesStruct() SdkMemberProperties { - panic("override me") -} - // Encapsulates the information about registered SdkMemberTypes. type SdkMemberTypesRegistry struct { // The list of types sorted by property name. diff --git a/java/droiddoc.go b/java/droiddoc.go index 1ac7444a5..b0efaa5bd 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -2041,18 +2041,33 @@ func (mt *droidStubsSdkMemberType) IsInstance(module android.Module) bool { return ok } -func (mt *droidStubsSdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) { - variants := member.Variants() - if len(variants) != 1 { - sdkModuleContext.ModuleErrorf("sdk contains %d variants of member %q but only one is allowed", len(variants), member.Name()) - } - variant := variants[0] - d, _ := variant.(*Droidstubs) - stubsSrcJar := d.stubsSrcJar +func (mt *droidStubsSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { + return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_stubs_sources") +} + +func (mt *droidStubsSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { + return &droidStubsInfoProperties{} +} + +type droidStubsInfoProperties struct { + android.SdkMemberPropertiesBase + + StubsSrcJar android.Path +} + +func (p *droidStubsInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { + droidstubs := variant.(*Droidstubs) + p.StubsSrcJar = droidstubs.stubsSrcJar +} - snapshotRelativeDir := filepath.Join("java", d.Name()+"_stubs_sources") - builder.UnzipToSnapshot(stubsSrcJar, snapshotRelativeDir) +func (p *droidStubsInfoProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { + if p.StubsSrcJar != nil { + builder := ctx.SnapshotBuilder() - pbm := builder.AddPrebuiltModule(member, "prebuilt_stubs_sources") - pbm.AddProperty("srcs", []string{snapshotRelativeDir}) + snapshotRelativeDir := filepath.Join("java", ctx.Name()+"_stubs_sources") + + builder.UnzipToSnapshot(p.StubsSrcJar, snapshotRelativeDir) + + propertySet.AddProperty("srcs", []string{snapshotRelativeDir}) + } } diff --git a/java/system_modules.go b/java/system_modules.go index 40031cb05..7394fd547 100644 --- a/java/system_modules.go +++ b/java/system_modules.go @@ -242,18 +242,28 @@ func (mt *systemModulesSdkMemberType) IsInstance(module android.Module) bool { return false } -func (mt *systemModulesSdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) { - variants := member.Variants() - if len(variants) != 1 { - sdkModuleContext.ModuleErrorf("sdk contains %d variants of member %q but only one is allowed", len(variants), member.Name()) - for _, variant := range variants { - sdkModuleContext.ModuleErrorf(" %q", variant) - } - } - variant := variants[0] +func (mt *systemModulesSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { + return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_system_modules_import") +} + +type systemModulesInfoProperties struct { + android.SdkMemberPropertiesBase + + Libs []string +} + +func (mt *systemModulesSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { + return &systemModulesInfoProperties{} +} + +func (p *systemModulesInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { systemModule := variant.(*SystemModules) + p.Libs = systemModule.properties.Libs +} - pbm := builder.AddPrebuiltModule(member, "java_system_modules_import") - // Add the references to the libraries that form the system module. - pbm.AddPropertyWithTag("libs", systemModule.properties.Libs, builder.SdkMemberReferencePropertyTag(true)) +func (p *systemModulesInfoProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { + if len(p.Libs) > 0 { + // Add the references to the libraries that form the system module. + propertySet.AddPropertyWithTag("libs", p.Libs, ctx.SnapshotBuilder().SdkMemberReferencePropertyTag(true)) + } } diff --git a/sdk/update.go b/sdk/update.go index 3ff0c1d1c..fef430d47 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -258,12 +258,7 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) andro memberCtx := &memberContext{ctx, builder, memberType, member.name} prebuiltModule := memberType.AddPrebuiltModule(memberCtx, member) - if prebuiltModule == nil { - // Fall back to legacy method of building a snapshot - memberType.BuildSnapshot(ctx, builder, member) - } else { - s.createMemberSnapshot(memberCtx, member, prebuiltModule) - } + s.createMemberSnapshot(memberCtx, member, prebuiltModule) } // Create a transformer that will transform an unversioned module into a versioned module. -- cgit v1.2.3-59-g8ed1b From 455b0bf92265057b28d816389d6cdadae005e158 Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Wed, 8 Apr 2020 18:18:03 +0100 Subject: Allow droidstubs to not generate any stubs Needed to optimize the handling of the module_lib API surface which currently has to be generated with two separate droidstubs instances, one to generate the stubs and another to generate the .txt file. This allows the module generating the .txt file to avoid also wasting time generating stubs that are not used. This change: * Adds a generate_stubs property that defaults to true to allow the behavior to be customized on a per module basis. * Uses either the stubs srcjar or the api .txt file as the OutputFile for the AndroidMkEntries to ensure that they get written out properly. * Rearranges the code for generating stubs to make it easier to turn it off. Bug: 146727827 Bug: 153306490 Test: m droid Check output dir of framework-sdkextensions-api-module_libs_api to make sure it does not contain any sources or srcjars. Merged-In: Ib8025019f8a7a8cf5fa8765d76b5ad470af20006 Change-Id: Ib8025019f8a7a8cf5fa8765d76b5ad470af20006 --- java/androidmk.go | 15 +++++++++++++-- java/droiddoc.go | 48 ++++++++++++++++++++++++++++++------------------ 2 files changed, 43 insertions(+), 20 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/androidmk.go b/java/androidmk.go index d8a38842f..7d575253b 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -517,10 +517,21 @@ func (ddoc *Droiddoc) AndroidMkEntries() []android.AndroidMkEntries { } func (dstubs *Droidstubs) AndroidMkEntries() []android.AndroidMkEntries { + // If the stubsSrcJar is not generated (because generate_stubs is false) then + // use the api file as the output file to ensure the relevant phony targets + // are created in make if only the api txt file is being generated. This is + // needed because an invalid output file would prevent the make entries from + // being written. + // TODO(b/146727827): Revert when we do not need to generate stubs and API separately. + distFile := android.OptionalPathForPath(dstubs.apiFile) + outputFile := android.OptionalPathForPath(dstubs.stubsSrcJar) + if !outputFile.Valid() { + outputFile = distFile + } return []android.AndroidMkEntries{android.AndroidMkEntries{ Class: "JAVA_LIBRARIES", - DistFile: android.OptionalPathForPath(dstubs.apiFile), - OutputFile: android.OptionalPathForPath(dstubs.stubsSrcJar), + DistFile: distFile, + OutputFile: outputFile, Include: "$(BUILD_SYSTEM)/soong_droiddoc_prebuilt.mk", ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(entries *android.AndroidMkEntries) { diff --git a/java/droiddoc.go b/java/droiddoc.go index b0efaa5bd..0947247b9 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -301,6 +301,11 @@ type DroidstubsProperties struct { // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false. Create_doc_stubs *bool + // if set to false then do not write out stubs. Defaults to true. + // + // TODO(b/146727827): Remove capability when we do not need to generate stubs and API separately. + Generate_stubs *bool + // is set to true, Metalava will allow framework SDK to contain API levels annotations. Api_levels_annotations_enabled *bool @@ -1285,7 +1290,7 @@ func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) { } } -func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) { +func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath) { if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") || apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") || String(d.properties.Api_filename) != "" { @@ -1341,11 +1346,13 @@ func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuil cmd.FlagWithArg("--sdk-values ", d.metadataDir.String()) } - if Bool(d.properties.Create_doc_stubs) { - cmd.FlagWithArg("--doc-stubs ", stubsDir.String()) - } else { - cmd.FlagWithArg("--stubs ", stubsDir.String()) - cmd.Flag("--exclude-documentation-from-stubs") + if stubsDir.Valid() { + if Bool(d.properties.Create_doc_stubs) { + cmd.FlagWithArg("--doc-stubs ", stubsDir.String()) + } else { + cmd.FlagWithArg("--stubs ", stubsDir.String()) + cmd.Flag("--exclude-documentation-from-stubs") + } } } @@ -1502,15 +1509,18 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Create rule for metalava - d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar") - srcJarDir := android.PathForModuleOut(ctx, "srcjars") - stubsDir := android.PathForModuleOut(ctx, "stubsDir") rule := android.NewRuleBuilder() - rule.Command().Text("rm -rf").Text(stubsDir.String()) - rule.Command().Text("mkdir -p").Text(stubsDir.String()) + generateStubs := BoolDefault(d.properties.Generate_stubs, true) + var stubsDir android.OptionalPath + if generateStubs { + d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar") + stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, "stubsDir")) + rule.Command().Text("rm -rf").Text(stubsDir.String()) + rule.Command().Text("mkdir -p").Text(stubsDir.String()) + } srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars) @@ -1536,13 +1546,15 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { cmd.ImplicitOutput(android.PathForModuleGen(ctx, o)) } - rule.Command(). - BuiltTool(ctx, "soong_zip"). - Flag("-write_if_changed"). - Flag("-jar"). - FlagWithOutput("-o ", d.Javadoc.stubsSrcJar). - FlagWithArg("-C ", stubsDir.String()). - FlagWithArg("-D ", stubsDir.String()) + if generateStubs { + rule.Command(). + BuiltTool(ctx, "soong_zip"). + Flag("-write_if_changed"). + Flag("-jar"). + FlagWithOutput("-o ", d.Javadoc.stubsSrcJar). + FlagWithArg("-C ", stubsDir.String()). + FlagWithArg("-D ", stubsDir.String()) + } if Bool(d.properties.Write_sdk_values) { d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip") -- cgit v1.2.3-59-g8ed1b From 0ee713aa0e2a79e4068ef24351643985e668b949 Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Fri, 17 Apr 2020 14:09:11 +0100 Subject: Remove unused arguments in droiddoc Nothing passes these arguments, so it's dead code. There is a lot of other cruft in this file that is effectively dead code, but required further cleanup. Bug: 152479829 Test: m Change-Id: Ib2630d4d49f21003b17e2331b0900e8df0a27e66 --- java/droiddoc.go | 114 ------------------------------------------------------- 1 file changed, 114 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 1ac7444a5..1c2c44736 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -177,37 +177,15 @@ type DroiddocProperties struct { // filegroup or genrule can be included within this property. Knowntags []string `android:"path"` - // the tag name used to distinguish if the API files belong to public/system/test. - Api_tag_name *string - // the generated public API filename by Doclava. Api_filename *string - // the generated public Dex API filename by Doclava. - Dex_api_filename *string - - // the generated private API filename by Doclava. - Private_api_filename *string - - // the generated private Dex API filename by Doclava. - Private_dex_api_filename *string - // the generated removed API filename by Doclava. Removed_api_filename *string // the generated removed Dex API filename by Doclava. Removed_dex_api_filename *string - // mapping of dex signatures to source file and line number. This is a temporary property and - // will be deleted; you probably shouldn't be using it. - Dex_mapping_filename *string - - // the generated exact API filename by Doclava. - Exact_api_filename *string - - // the generated proguard filename by Doclava. - Proguard_filename *string - // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true. Create_stubs *bool @@ -229,37 +207,15 @@ type DroiddocProperties struct { } type DroidstubsProperties struct { - // the tag name used to distinguish if the API files belong to public/system/test. - Api_tag_name *string - // the generated public API filename by Metalava. Api_filename *string - // the generated public Dex API filename by Metalava. - Dex_api_filename *string - - // the generated private API filename by Metalava. - Private_api_filename *string - - // the generated private Dex API filename by Metalava. - Private_dex_api_filename *string - // the generated removed API filename by Metalava. Removed_api_filename *string // the generated removed Dex API filename by Metalava. Removed_dex_api_filename *string - // mapping of dex signatures to source file and line number. This is a temporary property and - // will be deleted; you probably shouldn't be using it. - Dex_mapping_filename *string - - // the generated exact API filename by Metalava. - Exact_api_filename *string - - // the generated proguard filename by Metalava. - Proguard_filename *string - Check_api struct { Last_released ApiToCheck @@ -718,14 +674,9 @@ type Droiddoc struct { properties DroiddocProperties apiFile android.WritablePath - dexApiFile android.WritablePath privateApiFile android.WritablePath - privateDexApiFile android.WritablePath removedApiFile android.WritablePath removedDexApiFile android.WritablePath - exactApiFile android.WritablePath - apiMappingFile android.WritablePath - proguardFile android.WritablePath checkCurrentApiTimestamp android.WritablePath updateCurrentApiTimestamp android.WritablePath @@ -863,41 +814,11 @@ func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilde cmd.FlagWithOutput("-removedApi ", d.removedApiFile) } - if String(d.properties.Private_api_filename) != "" { - d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename)) - cmd.FlagWithOutput("-privateApi ", d.privateApiFile) - } - - if String(d.properties.Dex_api_filename) != "" { - d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename)) - cmd.FlagWithOutput("-dexApi ", d.dexApiFile) - } - - if String(d.properties.Private_dex_api_filename) != "" { - d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename)) - cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile) - } - if String(d.properties.Removed_dex_api_filename) != "" { d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename)) cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile) } - if String(d.properties.Exact_api_filename) != "" { - d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename)) - cmd.FlagWithOutput("-exactApi ", d.exactApiFile) - } - - if String(d.properties.Dex_mapping_filename) != "" { - d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename)) - cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile) - } - - if String(d.properties.Proguard_filename) != "" { - d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename)) - cmd.FlagWithOutput("-proguard ", d.proguardFile) - } - if BoolDefault(d.properties.Create_stubs, true) { cmd.FlagWithArg("-stubs ", stubsDir.String()) } @@ -1197,14 +1118,9 @@ type Droidstubs struct { apiFile android.WritablePath apiXmlFile android.WritablePath lastReleasedApiXmlFile android.WritablePath - dexApiFile android.WritablePath privateApiFile android.WritablePath - privateDexApiFile android.WritablePath removedApiFile android.WritablePath removedDexApiFile android.WritablePath - apiMappingFile android.WritablePath - exactApiFile android.WritablePath - proguardFile android.WritablePath nullabilityWarningsFile android.WritablePath checkCurrentApiTimestamp android.WritablePath @@ -1301,41 +1217,11 @@ func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuil cmd.FlagWithOutput("--removed-api ", d.removedApiFile) } - if String(d.properties.Private_api_filename) != "" { - d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename)) - cmd.FlagWithOutput("--private-api ", d.privateApiFile) - } - - if String(d.properties.Dex_api_filename) != "" { - d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename)) - cmd.FlagWithOutput("--dex-api ", d.dexApiFile) - } - - if String(d.properties.Private_dex_api_filename) != "" { - d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename)) - cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile) - } - if String(d.properties.Removed_dex_api_filename) != "" { d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename)) cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile) } - if String(d.properties.Exact_api_filename) != "" { - d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename)) - cmd.FlagWithOutput("--exact-api ", d.exactApiFile) - } - - if String(d.properties.Dex_mapping_filename) != "" { - d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename)) - cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile) - } - - if String(d.properties.Proguard_filename) != "" { - d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename)) - cmd.FlagWithOutput("--proguard ", d.proguardFile) - } - if Bool(d.properties.Write_sdk_values) { d.metadataDir = android.PathForModuleOut(ctx, "metadata") cmd.FlagWithArg("--sdk-values ", d.metadataDir.String()) -- cgit v1.2.3-59-g8ed1b From b52c8eafaa26e267f7abd298cc1036f1fdb37352 Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Thu, 16 Apr 2020 17:02:40 -0700 Subject: Don't use metalava for "check-current" Because we already generate the latest current.txt and removed.txt during the "main" metalava invocation (i.e. stub generation), we don't have to use metalava for current API check. Just use diff instead. Bug: 151160048 Test: Remove @hide from Intent.EXTRA_INSTALL_RESULT, and do `m out/soong/.intermediates/frameworks/base/api-stubs-docs/android_common/check_current_api.timestamp`. Result is: ``` FAILED: out/soong/.intermediates/frameworks/base/api-stubs-docs/android_common/check_current_api.timestamp ( true && diff -u -F '{ *$' frameworks/base/api/current.txt out/soong/.intermediates/frameworks/base/api-stubs-docs/android_common/api-stubs-docs_api.txt && diff -u -F '{ *$' frameworks/base/api/removed.txt out/soong/.intermediates/frameworks/base/api-stubs-docs/android_common/api-stubs-docs_removed.txt && touch out/soong/.intermediates/frameworks/base/api-stubs-docs/android_common/check_current_api.timestamp ) || ( echo -e "\n******************************\nYou have tried to change the API from what has been previously approved.\n\nTo make these errors go away, you have two choices:\n 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n to the new methods, etc. shown in the above diff.\n\n 2. You can update current.txt and/or removed.txt by executing the following command:\n make api-stubs-docs-update-current-api\n\n To submit the revised current.txt to the main Android repository,\n you will need approval.\n******************************\n" ; exit 38 ) Change-Id: Ib391ca2afb296b5c5174d755c7ffb66d3fa5810c --- frameworks/base/api/current.txt 2020-04-16 17:50:21.911899599 -0700 +++ out/soong/.intermediates/frameworks/base/api-stubs-docs/android_common/api-stubs-docs_api.txt 2020-04-16 17:51:35.211792638 -0700 @@ -10415,6 +10415,7 @@ public class Intent implements java.lang field public static final String EXTRA_INDEX = "android.intent.extra.INDEX"; field public static final String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS"; field public static final String EXTRA_INSTALLER_PACKAGE_NAME = "android.intent.extra.INSTALLER_PACKAGE_NAME"; + field public static final String EXTRA_INSTALL_RESULT = "android.intent.extra.INSTALL_RESULT"; field public static final String EXTRA_INTENT = "android.intent.extra.INTENT"; field public static final String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT"; field public static final String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY"; ****************************** You have tried to change the API from what has been previously approved. To make these errors go away, you have two choices: 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc) to the new methods, etc. shown in the above diff. 2. You can update current.txt and/or removed.txt by executing the following command: make api-stubs-docs-update-current-api To submit the revised current.txt to the main Android repository, you will need approval. ****************************** ninja: build stopped: subcommand failed. ``` Test: Remove @removed and @SystemApi from Intent.ACTION_MASTER_CLEAR, and do `m out/soong/.intermediates/frameworks/base/system-api-stubs-docs/android_common/check_current_api.timestamp` Result is: ``` ( true && diff -u -F '{ *$' frameworks/base/api/system-current.txt out/soong/.intermediates/frameworks/base/system-api-stubs-docs/android_common/system-api-stubs-docs_api.txt && diff -u -F '{ *$' frameworks/base/api/system-removed.txt out/soong/.intermediates/frameworks/base/system-api-stubs-docs/android_common/system-api-stubs-docs_removed.txt && touch out/soong/.intermediates/frameworks/base/system-api-stubs-docs/android_common/check_current_api.timestamp ) || ( echo -e "\n******************************\nYou have tried to change the API from what has been previously approved.\n\nTo make these errors go away, you have two choices:\n 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n to the new methods, etc. shown in the above diff.\n\n 2. You can update current.txt and/or removed.txt by executing the following command:\n make system-api-stubs-docs-update-current-api\n\n To submit the revised current.txt to the main Android repository,\n you will need approval.\n******************************\n" ; exit 38 ) --- frameworks/base/api/system-removed.txt 2020-04-16 17:50:21.911899599 -0700 +++ out/soong/.intermediates/frameworks/base/system-api-stubs-docs/android_common/system-api-stubs-docs_removed.txt 2020-04-16 17:53:45.319602905 -0700 @@ -55,7 +55,6 @@ package android.content { public class Intent implements java.lang.Cloneable android.os.Parcelable { field @Deprecated public static final String ACTION_DEVICE_INITIALIZATION_WIZARD = "android.intent.action.DEVICE_INITIALIZATION_WIZARD"; - field @Deprecated public static final String ACTION_MASTER_CLEAR = "android.intent.action.MASTER_CLEAR"; field @Deprecated public static final String ACTION_SERVICE_STATE = "android.intent.action.SERVICE_STATE"; field @Deprecated public static final String EXTRA_CDMA_DEFAULT_ROAMING_INDICATOR = "cdmaDefaultRoamingIndicator"; field @Deprecated public static final String EXTRA_CDMA_ROAMING_INDICATOR = "cdmaRoamingIndicator"; ****************************** You have tried to change the API from what has been previously approved. To make these errors go away, you have two choices: 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc) to the new methods, etc. shown in the above diff. 2. You can update current.txt and/or removed.txt by executing the following command: make system-api-stubs-docs-update-current-api To submit the revised current.txt to the main Android repository, you will need approval. ****************************** ``` Test: Add `baseline_file` to `check_api.current` and run `m` FAILED: out/soong/build.ninja out/soong/.bootstrap/bin/soong_build -t -l out/.module_paths/Android.bp.list -b out/soong -n out -d out/soong/build.ninja.d -globFile out/soong/.bootstrap/build-globs.ninja -o out/soong/build.ninja Android.bp error: frameworks/base/StubLibraries.bp:86:1: module "api-stubs-docs" variant "android_common": current API check can't have a baseline file. (module %s): api-stubs-docs ninja: build stopped: subcommand failed. Test: With the above changes, run "m api-stubs-docs-update-current-api system-api-stubs-docs-update-current-api", make sure the API files got updated, and then run "m" Merged-in: I47b146c6fe4caa65775ecf5425ab09b57f43f839 Change-Id: I3045bd8dc95d5f70893729ed65426d8cfc88c5ec --- java/droiddoc.go | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 8f08f1f89..7ac71a468 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1524,40 +1524,35 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file)) removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file)) baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file) - updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt") + + if baselineFile.Valid() { + ctx.PropertyErrorf("current API check can't have a baseline file. (module %s)", ctx.ModuleName()) + } d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp") rule := android.NewRuleBuilder() - rule.Command().Text("( true") + // Diff command line. + // -F matches the closest "opening" line, such as "package xxx{" + // and " public class Yyy {". + diff := `diff -u -F '{ *$'` - srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars") - srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars) - - cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList, - deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths) - - cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles). - FlagWithInput("--check-compatibility:api:current ", apiFile). - FlagWithInput("--check-compatibility:removed:current ", removedApiFile) - - d.inclusionAnnotationsFlags(ctx, cmd) - d.mergeAnnoDirFlags(ctx, cmd) - - if baselineFile.Valid() { - cmd.FlagWithInput("--baseline ", baselineFile.Path()) - cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput) - } + rule.Command().Text("( true") + rule.Command(). + Text(diff). + Input(apiFile).Input(d.apiFile) - zipSyncCleanupCmd(rule, srcJarDir) + rule.Command(). + Text(diff). + Input(removedApiFile).Input(d.removedApiFile) msg := fmt.Sprintf(`\n******************************\n`+ `You have tried to change the API from what has been previously approved.\n\n`+ `To make these errors go away, you have two choices:\n`+ - ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+ - ` errors above.\n\n`+ - ` 2. You can update current.txt by executing the following command:\n`+ + ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+ + ` to the new methods, etc. shown in the above diff.\n\n`+ + ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+ ` make %s-update-current-api\n\n`+ ` To submit the revised current.txt to the main Android repository,\n`+ ` you will need approval.\n`+ @@ -1570,7 +1565,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { Text("; exit 38"). Text(")") - rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API") + rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "check current API") d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp") -- cgit v1.2.3-59-g8ed1b From 34ced82d2a4eccdabe62e453e56d46ce68c62c64 Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Fri, 1 May 2020 17:08:54 +0100 Subject: Fix soong crashing when there's no baseline file Soong was referencing the baseline file regardless of whether it was valid or not. Also update the lint message to match the one metalava itself prints, which only suggests whitelisting the error if it's not possible to fix it properly. Bug: 154616909 Test: m (with lint error) Change-Id: I4c6ec327a59aefe74825b4c4719393dd267ba3aa --- java/droiddoc.go | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 7ac71a468..1e950c13c 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1489,20 +1489,37 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { updatedBaselineOutput := android.PathForModuleOut(ctx, "api_lint_baseline.txt") d.apiLintTimestamp = android.PathForModuleOut(ctx, "api_lint.timestamp") + msg := `` + + `************************************************************\n` + + `Your API changes are triggering API Lint warnings or errors.\n` + + `To make these errors go away, fix the code according to the\n` + + `error and/or warning messages above.\n` + + `\n` + + `If it's not possible to do so, there are workarounds:\n` + + `\n` + + `1. You can suppress the errors with @SuppressLint(\"\")\n` + if baselineFile.Valid() { cmd.FlagWithInput("--baseline ", baselineFile.Path()) cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput) + + msg += fmt.Sprintf(``+ + `2. You can update the baseline by executing the following\n`+ + ` command:\n`+ + ` cp \\ \n`+ + ` \"$PWD/%s\" \\ \n`+ + ` \"$PWD/%s\" \n`+ + ` To submit the revised baseline.txt to the main Android\n`+ + ` repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path()) + } else { + msg += fmt.Sprintf(``+ + `2. You can add a baseline file of existing lint failures\n`+ + ` to the build rule of %s.\n`, d.Name()) } + msg += `************************************************************\n` zipSyncCleanupCmd(rule, srcJarDir) - msg := fmt.Sprintf(`\n******************************\n`+ - `Your API changes are triggering API Lint warnings or errors.\n\n`+ - `To make these errors go away, you have two choices:\n`+ - ` 1. You can suppress the errors with @SuppressLint(\"\").\n\n`+ - ` 2. You can update the baseline by executing the following command:\n`+ - ` cp \"$PWD/%s\" \"$PWD/%s\"\n\n`+ - `******************************\n`, updatedBaselineOutput, baselineFile.Path()) rule.Command(). Text("touch").Output(d.apiLintTimestamp). Text(") || ("). -- cgit v1.2.3-59-g8ed1b From e714565ce8f090d8615381ce9df28ac8ff2c49f0 Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Mon, 4 May 2020 18:38:46 +0100 Subject: Treat lint warnings as errors Warnings get lost in the build spam and never get fixed. Right now is the best time to do this, because we only track the warnings/errors since the last released API. The API has just been frozen, so the number of warnings is at an all-time low. Whitelist the car lib and test stubs for now, which produce a lot of warnings. Bug: 154317059 Test: presubmit Change-Id: I9aa7cb1b947c6c664f15e2bd5835d76eaac1237a --- java/droiddoc.go | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 1e950c13c..62675c46a 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1471,6 +1471,15 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList, deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths) + // TODO(b/154317059): Clean up this whitelist by baselining and/or checking in last-released. + if d.Name() != "android.car-system-stubs-docs" && + d.Name() != "android.car-stubs-docs" && + d.Name() != "system-api-stubs-docs" && + d.Name() != "test-api-stubs-docs" { + cmd.Flag("--lints-as-errors") + cmd.Flag("--warnings-as-errors") // Most lints are actually warnings. + } + cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles) newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since) -- cgit v1.2.3-59-g8ed1b From 194c43f5a756236967e667b453aff0e2020fe861 Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Mon, 27 Apr 2020 17:22:16 -0700 Subject: Merge the "big 3" metalava invocations into one This CL merges the biggest three metalava invocations -- stub and signature file generation, api lint, and "check released" -- into one call. For each of the existing separate rules for api lint and check released this change: 1) Stopped creating a separate rule containing its own metalava invocation. 2) Moved the code for creating the rule earlier so it can add extra flags to the combined metalava command. 3) Moved the message handling into metalava, allowing the message to be passed in. 4) Added a flag to record whether the specific check was needed so that you can separate the timestamp file creation out to run after the merged metalava command. A couple of minor bug fixes and clarifications. Bug: 151160048 Test: "m" and treehugger Test: Apply https://android-review.googlesource.com/c/platform/frameworks/base/+/1295541 and run `NINJA_ARGS="-k 999" m checkapi` -> Make sure there are 4 kinds of lint failures ("AddedFinal" and "VisiblySynchronized") with the valid error messages, from: - api-stubs-docs - system-api-stubs-docs - test-api-stubs-docs - module-lib-api- Test: Run the 4 cp commands shown by lint -> Make sure the following 4 baseline files are updated: frameworks/base/api/lint-baseline.txt frameworks/base/api/module-lib-lint-baseline.txt frameworks/base/api/system-lint-baseline.txt frameworks/base/api/test-lint-baseline.txt Test: Then run `NINJA_ARGS="-k 999" m checkapi` again. -> Make sure the API lint errors are gone -> Make sure "api-stubs-docs" shows the "You have tried to change the API from what has been previously released in ..." error. (because of "AddedFinal") -> Make sure it the other 3 API surfaces show the "You have tried to change the API from what has been previously approved" error. Test: Remove "final" from Intent.java and run "NINJA_ARGS="-k 999" m checkapi" again. -> This time, all the 4 API surfaces say "You have tried to change the API from what has been previously approved" error." Test: Run the 4 "make *-update-current-api" commands shown in the above errors and "NINJA_ARGS="-k 999" m checkapi" -> The exact command is: $ make \ module-lib-api-update-current-api \ api-stubs-docs-update-current-api \ test-api-stubs-docs-update-current-api \ system-api-stubs-docs-update-current-api -> Make sure frameworks/base/api/*-current.txt are properly updated. Test: Run "m update-api" -> Make sure no text signature files get updated. Test: Run "m droid". -> Make sure everything builds fine. Change-Id: Ia1a5510b57d58748b4655473d4585636deb7f45e --- java/droiddoc.go | 219 +++++++++++++++++++++++++------------------------------ 1 file changed, 100 insertions(+), 119 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 9a522481d..6ae071eac 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1473,44 +1473,25 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { cmd.ImplicitOutput(android.PathForModuleGen(ctx, o)) } - if generateStubs { - rule.Command(). - BuiltTool(ctx, "soong_zip"). - Flag("-write_if_changed"). - Flag("-jar"). - FlagWithOutput("-o ", d.Javadoc.stubsSrcJar). - FlagWithArg("-C ", stubsDir.String()). - FlagWithArg("-D ", stubsDir.String()) - } + // Add options for the other optional tasks: API-lint and check-released. + // We generate separate timestamp files for them. - if Bool(d.properties.Write_sdk_values) { - d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip") - rule.Command(). - BuiltTool(ctx, "soong_zip"). - Flag("-write_if_changed"). - Flag("-d"). - FlagWithOutput("-o ", d.metadataZip). - FlagWithArg("-C ", d.metadataDir.String()). - FlagWithArg("-D ", d.metadataDir.String()) - } + doApiLint := false + doCheckReleased := false - rule.Restat() - - zipSyncCleanupCmd(rule, srcJarDir) - - rule.Build(pctx, ctx, "metalava", "metalava") - - // Create rule for apicheck + // Add API lint options. if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().IsPdkBuild() { - rule := android.NewRuleBuilder() - rule.Command().Text("( true") - - srcJarDir := android.PathForModuleOut(ctx, "api_lint", "srcjars") - srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars) + doApiLint = true - cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList, - deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths) + newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since) + if newSince.Valid() { + cmd.FlagWithInput("--api-lint ", newSince.Path()) + } else { + cmd.Flag("--api-lint") + } + d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt") + cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint" // TODO(b/154317059): Clean up this whitelist by baselining and/or checking in last-released. if d.Name() != "android.car-system-stubs-docs" && @@ -1521,44 +1502,37 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { cmd.Flag("--warnings-as-errors") // Most lints are actually warnings. } - cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles) - - newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since) - if newSince.Valid() { - cmd.FlagWithInput("--api-lint ", newSince.Path()) - } else { - cmd.Flag("--api-lint") - } - d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt") - cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) - - d.inclusionAnnotationsFlags(ctx, cmd) - d.mergeAnnoDirFlags(ctx, cmd) - baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file) updatedBaselineOutput := android.PathForModuleOut(ctx, "api_lint_baseline.txt") d.apiLintTimestamp = android.PathForModuleOut(ctx, "api_lint.timestamp") - msg := `` + + // Note this string includes a special shell quote $' ... ', which decodes the "\n"s. + // However, because $' ... ' doesn't expand environmental variables, we can't just embed + // $PWD, so we have to terminate $'...', use "$PWD", then start $' ... ' again, + // which is why we have '"$PWD"$' in it. + // + // TODO: metalava also has a slightly different message hardcoded. Should we unify this + // message and metalava's one? + msg := `$'` + // Enclose with $' ... ' `************************************************************\n` + `Your API changes are triggering API Lint warnings or errors.\n` + `To make these errors go away, fix the code according to the\n` + `error and/or warning messages above.\n` + `\n` + - `If it's not possible to do so, there are workarounds:\n` + + `If it is not possible to do so, there are workarounds:\n` + `\n` + - `1. You can suppress the errors with @SuppressLint(\"\")\n` + `1. You can suppress the errors with @SuppressLint("")\n` if baselineFile.Valid() { - cmd.FlagWithInput("--baseline ", baselineFile.Path()) - cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput) + cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path()) + cmd.FlagWithOutput("--update-baseline:api-lint ", updatedBaselineOutput) msg += fmt.Sprintf(``+ `2. You can update the baseline by executing the following\n`+ ` command:\n`+ ` cp \\ \n`+ - ` \"$PWD/%s\" \\ \n`+ - ` \"$PWD/%s\" \n`+ + ` "'"$PWD"$'/%s" \\ \n`+ + ` "'"$PWD"$'/%s" \n`+ ` To submit the revised baseline.txt to the main Android\n`+ ` repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path()) } else { @@ -1566,20 +1540,81 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { `2. You can add a baseline file of existing lint failures\n`+ ` to the build rule of %s.\n`, d.Name()) } - msg += `************************************************************\n` + // Note the message ends with a ' (single quote), to close the $' ... ' . + msg += `************************************************************\n'` - zipSyncCleanupCmd(rule, srcJarDir) + cmd.FlagWithArg("--error-message:api-lint ", msg) + } + + // Add "check released" options. (Detect incompatible API changes from the last public release) + + if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") && + !ctx.Config().IsPdkBuild() { + doCheckReleased = true + + if len(d.Javadoc.properties.Out) > 0 { + ctx.PropertyErrorf("out", "out property may not be combined with check_api") + } + + apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file)) + removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file)) + baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file) + updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt") + + d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp") + + cmd.FlagWithInput("--check-compatibility:api:released ", apiFile) + cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile) + + if baselineFile.Valid() { + cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path()) + cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput) + } + + // Note this string includes quote ($' ... '), which decodes the "\n"s. + msg := `$'\n******************************\n` + + `You have tried to change the API from what has been previously released in\n` + + `an SDK. Please fix the errors listed above.\n` + + `******************************\n'` + + cmd.FlagWithArg("--error-message:compatibility:released ", msg) + } + if generateStubs { rule.Command(). - Text("touch").Output(d.apiLintTimestamp). - Text(") || ("). - Text("echo").Flag("-e").Flag(`"` + msg + `"`). - Text("; exit 38"). - Text(")") + BuiltTool(ctx, "soong_zip"). + Flag("-write_if_changed"). + Flag("-jar"). + FlagWithOutput("-o ", d.Javadoc.stubsSrcJar). + FlagWithArg("-C ", stubsDir.String()). + FlagWithArg("-D ", stubsDir.String()) + } - rule.Build(pctx, ctx, "metalavaApiLint", "metalava API lint") + if Bool(d.properties.Write_sdk_values) { + d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip") + rule.Command(). + BuiltTool(ctx, "soong_zip"). + Flag("-write_if_changed"). + Flag("-d"). + FlagWithOutput("-o ", d.metadataZip). + FlagWithArg("-C ", d.metadataDir.String()). + FlagWithArg("-D ", d.metadataDir.String()) + } + // TODO: We don't really need two separate API files, but this is a reminiscence of how + // we used to run metalava separately for API lint and the "last_released" check. Unify them. + if doApiLint { + rule.Command().Text("touch").Output(d.apiLintTimestamp) } + if doCheckReleased { + rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp) + } + + rule.Restat() + + zipSyncCleanupCmd(rule, srcJarDir) + + rule.Build(pctx, ctx, "metalava", "metalava merged") if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") && !ctx.Config().IsPdkBuild() { @@ -1593,7 +1628,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file) if baselineFile.Valid() { - ctx.PropertyErrorf("current API check can't have a baseline file. (module %s)", ctx.ModuleName()) + ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName()) } d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp") @@ -1601,8 +1636,8 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { rule := android.NewRuleBuilder() // Diff command line. - // -F matches the closest "opening" line, such as "package xxx{" - // and " public class Yyy {". + // -F matches the closest "opening" line, such as "package android {" + // and " public class Intent {". diff := `diff -u -F '{ *$'` rule.Command().Text("( true") @@ -1661,60 +1696,6 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API") } - if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") && - !ctx.Config().IsPdkBuild() { - - if len(d.Javadoc.properties.Out) > 0 { - ctx.PropertyErrorf("out", "out property may not be combined with check_api") - } - - apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file)) - removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file)) - baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file) - updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt") - - d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp") - - rule := android.NewRuleBuilder() - - rule.Command().Text("( true") - - srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars") - srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars) - - cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList, - deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths) - - cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles). - FlagWithInput("--check-compatibility:api:released ", apiFile) - - d.inclusionAnnotationsFlags(ctx, cmd) - - cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile) - - d.mergeAnnoDirFlags(ctx, cmd) - - if baselineFile.Valid() { - cmd.FlagWithInput("--baseline ", baselineFile.Path()) - cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput) - } - - zipSyncCleanupCmd(rule, srcJarDir) - - msg := `\n******************************\n` + - `You have tried to change the API from what has been previously released in\n` + - `an SDK. Please fix the errors listed above.\n` + - `******************************\n` - rule.Command(). - Text("touch").Output(d.checkLastReleasedApiTimestamp). - Text(") || ("). - Text("echo").Flag("-e").Flag(`"` + msg + `"`). - Text("; exit 38"). - Text(")") - - rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API") - } - if String(d.properties.Check_nullability_warnings) != "" { if d.nullabilityWarningsFile == nil { ctx.PropertyErrorf("check_nullability_warnings", -- cgit v1.2.3-59-g8ed1b From b850a9deaa49b759c0fd9e308cf214353b0971bd Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Mon, 27 Apr 2020 17:22:16 -0700 Subject: Merge the "big 3" metalava invocations into one This CL merges the biggest three metalava invocations -- stub and signature file generation, api lint, and "check released" -- into one call. For each of the existing separate rules for api lint and check released this change: 1) Stopped creating a separate rule containing its own metalava invocation. 2) Moved the code for creating the rule earlier so it can add extra flags to the combined metalava command. 3) Moved the message handling into metalava, allowing the message to be passed in. 4) Added a flag to record whether the specific check was needed so that you can separate the timestamp file creation out to run after the merged metalava command. A couple of minor bug fixes and clarifications. Bug: 151160048 Test: "m" and treehugger Test: Apply https://android-review.googlesource.com/c/platform/frameworks/base/+/1295541 and run `NINJA_ARGS="-k 999" m checkapi` -> Make sure there are 4 kinds of lint failures ("AddedFinal" and "VisiblySynchronized") with the valid error messages, from: - api-stubs-docs - system-api-stubs-docs - test-api-stubs-docs - module-lib-api- Test: Run the 4 cp commands shown by lint -> Make sure the following 4 baseline files are updated: frameworks/base/api/lint-baseline.txt frameworks/base/api/module-lib-lint-baseline.txt frameworks/base/api/system-lint-baseline.txt frameworks/base/api/test-lint-baseline.txt Test: Then run `NINJA_ARGS="-k 999" m checkapi` again. -> Make sure the API lint errors are gone -> Make sure "api-stubs-docs" shows the "You have tried to change the API from what has been previously released in ..." error. (because of "AddedFinal") -> Make sure it the other 3 API surfaces show the "You have tried to change the API from what has been previously approved" error. Test: Remove "final" from Intent.java and run "NINJA_ARGS="-k 999" m checkapi" again. -> This time, all the 4 API surfaces say "You have tried to change the API from what has been previously approved" error." Test: Run the 4 "make *-update-current-api" commands shown in the above errors and "NINJA_ARGS="-k 999" m checkapi" -> The exact command is: $ make \ module-lib-api-update-current-api \ api-stubs-docs-update-current-api \ test-api-stubs-docs-update-current-api \ system-api-stubs-docs-update-current-api -> Make sure frameworks/base/api/*-current.txt are properly updated. Test: Run "m update-api" -> Make sure no text signature files get updated. Test: Run "m droid". -> Make sure everything builds fine. Change-Id: Ia1a5510b57d58748b4655473d4585636deb7f45e Merged-in: Ia1a5510b57d58748b4655473d4585636deb7f45e --- java/droiddoc.go | 219 +++++++++++++++++++++++++------------------------------ 1 file changed, 100 insertions(+), 119 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 62675c46a..07c626c4b 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1432,44 +1432,25 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { cmd.ImplicitOutput(android.PathForModuleGen(ctx, o)) } - if generateStubs { - rule.Command(). - BuiltTool(ctx, "soong_zip"). - Flag("-write_if_changed"). - Flag("-jar"). - FlagWithOutput("-o ", d.Javadoc.stubsSrcJar). - FlagWithArg("-C ", stubsDir.String()). - FlagWithArg("-D ", stubsDir.String()) - } + // Add options for the other optional tasks: API-lint and check-released. + // We generate separate timestamp files for them. - if Bool(d.properties.Write_sdk_values) { - d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip") - rule.Command(). - BuiltTool(ctx, "soong_zip"). - Flag("-write_if_changed"). - Flag("-d"). - FlagWithOutput("-o ", d.metadataZip). - FlagWithArg("-C ", d.metadataDir.String()). - FlagWithArg("-D ", d.metadataDir.String()) - } + doApiLint := false + doCheckReleased := false - rule.Restat() - - zipSyncCleanupCmd(rule, srcJarDir) - - rule.Build(pctx, ctx, "metalava", "metalava") - - // Create rule for apicheck + // Add API lint options. if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().IsPdkBuild() { - rule := android.NewRuleBuilder() - rule.Command().Text("( true") - - srcJarDir := android.PathForModuleOut(ctx, "api_lint", "srcjars") - srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars) + doApiLint = true - cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList, - deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths) + newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since) + if newSince.Valid() { + cmd.FlagWithInput("--api-lint ", newSince.Path()) + } else { + cmd.Flag("--api-lint") + } + d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt") + cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint" // TODO(b/154317059): Clean up this whitelist by baselining and/or checking in last-released. if d.Name() != "android.car-system-stubs-docs" && @@ -1480,44 +1461,37 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { cmd.Flag("--warnings-as-errors") // Most lints are actually warnings. } - cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles) - - newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since) - if newSince.Valid() { - cmd.FlagWithInput("--api-lint ", newSince.Path()) - } else { - cmd.Flag("--api-lint") - } - d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt") - cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) - - d.inclusionAnnotationsFlags(ctx, cmd) - d.mergeAnnoDirFlags(ctx, cmd) - baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file) updatedBaselineOutput := android.PathForModuleOut(ctx, "api_lint_baseline.txt") d.apiLintTimestamp = android.PathForModuleOut(ctx, "api_lint.timestamp") - msg := `` + + // Note this string includes a special shell quote $' ... ', which decodes the "\n"s. + // However, because $' ... ' doesn't expand environmental variables, we can't just embed + // $PWD, so we have to terminate $'...', use "$PWD", then start $' ... ' again, + // which is why we have '"$PWD"$' in it. + // + // TODO: metalava also has a slightly different message hardcoded. Should we unify this + // message and metalava's one? + msg := `$'` + // Enclose with $' ... ' `************************************************************\n` + `Your API changes are triggering API Lint warnings or errors.\n` + `To make these errors go away, fix the code according to the\n` + `error and/or warning messages above.\n` + `\n` + - `If it's not possible to do so, there are workarounds:\n` + + `If it is not possible to do so, there are workarounds:\n` + `\n` + - `1. You can suppress the errors with @SuppressLint(\"\")\n` + `1. You can suppress the errors with @SuppressLint("")\n` if baselineFile.Valid() { - cmd.FlagWithInput("--baseline ", baselineFile.Path()) - cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput) + cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path()) + cmd.FlagWithOutput("--update-baseline:api-lint ", updatedBaselineOutput) msg += fmt.Sprintf(``+ `2. You can update the baseline by executing the following\n`+ ` command:\n`+ ` cp \\ \n`+ - ` \"$PWD/%s\" \\ \n`+ - ` \"$PWD/%s\" \n`+ + ` "'"$PWD"$'/%s" \\ \n`+ + ` "'"$PWD"$'/%s" \n`+ ` To submit the revised baseline.txt to the main Android\n`+ ` repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path()) } else { @@ -1525,20 +1499,81 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { `2. You can add a baseline file of existing lint failures\n`+ ` to the build rule of %s.\n`, d.Name()) } - msg += `************************************************************\n` + // Note the message ends with a ' (single quote), to close the $' ... ' . + msg += `************************************************************\n'` - zipSyncCleanupCmd(rule, srcJarDir) + cmd.FlagWithArg("--error-message:api-lint ", msg) + } + + // Add "check released" options. (Detect incompatible API changes from the last public release) + + if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") && + !ctx.Config().IsPdkBuild() { + doCheckReleased = true + + if len(d.Javadoc.properties.Out) > 0 { + ctx.PropertyErrorf("out", "out property may not be combined with check_api") + } + + apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file)) + removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file)) + baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file) + updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt") + + d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp") + + cmd.FlagWithInput("--check-compatibility:api:released ", apiFile) + cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile) + + if baselineFile.Valid() { + cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path()) + cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput) + } + + // Note this string includes quote ($' ... '), which decodes the "\n"s. + msg := `$'\n******************************\n` + + `You have tried to change the API from what has been previously released in\n` + + `an SDK. Please fix the errors listed above.\n` + + `******************************\n'` + + cmd.FlagWithArg("--error-message:compatibility:released ", msg) + } + if generateStubs { rule.Command(). - Text("touch").Output(d.apiLintTimestamp). - Text(") || ("). - Text("echo").Flag("-e").Flag(`"` + msg + `"`). - Text("; exit 38"). - Text(")") + BuiltTool(ctx, "soong_zip"). + Flag("-write_if_changed"). + Flag("-jar"). + FlagWithOutput("-o ", d.Javadoc.stubsSrcJar). + FlagWithArg("-C ", stubsDir.String()). + FlagWithArg("-D ", stubsDir.String()) + } - rule.Build(pctx, ctx, "metalavaApiLint", "metalava API lint") + if Bool(d.properties.Write_sdk_values) { + d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip") + rule.Command(). + BuiltTool(ctx, "soong_zip"). + Flag("-write_if_changed"). + Flag("-d"). + FlagWithOutput("-o ", d.metadataZip). + FlagWithArg("-C ", d.metadataDir.String()). + FlagWithArg("-D ", d.metadataDir.String()) + } + // TODO: We don't really need two separate API files, but this is a reminiscence of how + // we used to run metalava separately for API lint and the "last_released" check. Unify them. + if doApiLint { + rule.Command().Text("touch").Output(d.apiLintTimestamp) } + if doCheckReleased { + rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp) + } + + rule.Restat() + + zipSyncCleanupCmd(rule, srcJarDir) + + rule.Build(pctx, ctx, "metalava", "metalava merged") if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") && !ctx.Config().IsPdkBuild() { @@ -1552,7 +1587,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file) if baselineFile.Valid() { - ctx.PropertyErrorf("current API check can't have a baseline file. (module %s)", ctx.ModuleName()) + ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName()) } d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp") @@ -1560,8 +1595,8 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { rule := android.NewRuleBuilder() // Diff command line. - // -F matches the closest "opening" line, such as "package xxx{" - // and " public class Yyy {". + // -F matches the closest "opening" line, such as "package android {" + // and " public class Intent {". diff := `diff -u -F '{ *$'` rule.Command().Text("( true") @@ -1620,60 +1655,6 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API") } - if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") && - !ctx.Config().IsPdkBuild() { - - if len(d.Javadoc.properties.Out) > 0 { - ctx.PropertyErrorf("out", "out property may not be combined with check_api") - } - - apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file)) - removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file)) - baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file) - updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt") - - d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp") - - rule := android.NewRuleBuilder() - - rule.Command().Text("( true") - - srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars") - srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars) - - cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList, - deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths) - - cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles). - FlagWithInput("--check-compatibility:api:released ", apiFile) - - d.inclusionAnnotationsFlags(ctx, cmd) - - cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile) - - d.mergeAnnoDirFlags(ctx, cmd) - - if baselineFile.Valid() { - cmd.FlagWithInput("--baseline ", baselineFile.Path()) - cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput) - } - - zipSyncCleanupCmd(rule, srcJarDir) - - msg := `\n******************************\n` + - `You have tried to change the API from what has been previously released in\n` + - `an SDK. Please fix the errors listed above.\n` + - `******************************\n` - rule.Command(). - Text("touch").Output(d.checkLastReleasedApiTimestamp). - Text(") || ("). - Text("echo").Flag("-e").Flag(`"` + msg + `"`). - Text("; exit 38"). - Text(")") - - rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API") - } - if String(d.properties.Check_nullability_warnings) != "" { if d.nullabilityWarningsFile == nil { ctx.PropertyErrorf("check_nullability_warnings", -- cgit v1.2.3-59-g8ed1b From f488ef2a3cbe60f2edd0201f8f84ff6fbab4dc2f Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Thu, 9 Apr 2020 00:10:17 +0100 Subject: Export stub sources as part of the java_sdk_library Minor refactoring of checkMergeZip(string) -> checkMergeZips(...string) to allow testing of multiple merge zips. Bug: 153443117 Test: m nothing Merged-In: I8db00f611ced15f8476ba16f2834a72e8c913596 Change-Id: I8db00f611ced15f8476ba16f2834a72e8c913596 (cherry picked from commit 3d1248ceb6d8c1ce7d2f3f2e62f98700f668e4dc) --- java/droiddoc.go | 11 +++++++++++ java/sdk_library.go | 38 ++++++++++++++++++++++++++++++++++---- sdk/java_sdk_test.go | 14 ++++++++++++-- sdk/testing.go | 7 ++++--- 4 files changed, 61 insertions(+), 9 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 62675c46a..90f143a7a 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -331,10 +331,17 @@ func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToC apiToCheck.Removed_api_file = nil } +// Used by xsd_config type ApiFilePath interface { ApiFilePath() android.Path } +// Provider of information about API stubs, used by java_sdk_library. +type ApiStubsProvider interface { + ApiFilePath + StubsSrcJar() android.Path +} + // // Javadoc // @@ -1180,6 +1187,10 @@ func (d *Droidstubs) ApiFilePath() android.Path { return d.apiFilePath } +func (d *Droidstubs) StubsSrcJar() android.Path { + return d.stubsSrcJar +} + func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) { d.Javadoc.addDeps(ctx) diff --git a/java/sdk_library.go b/java/sdk_library.go index 1ad5132c4..85d5bd3b7 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -243,6 +243,7 @@ type scopePaths struct { stubsHeaderPath android.Paths stubsImplPath android.Paths apiFilePath android.Path + stubsSrcJar android.Path } // Common code between sdk library and sdk library import @@ -329,11 +330,12 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) scopePaths.stubsImplPath = lib.ImplementationJars() } } - if doc, ok := to.(ApiFilePath); ok { + if doc, ok := to.(ApiStubsProvider); ok { if scopeTag, ok := tag.(scopeDependencyTag); ok { apiScope := scopeTag.apiScope scopePaths := module.getScopePaths(apiScope) scopePaths.apiFilePath = doc.ApiFilePath() + scopePaths.stubsSrcJar = doc.StubsSrcJar() } else { ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag) } @@ -821,6 +823,9 @@ type sdkLibraryScopeProperties struct { // List of shared java libs that this module has dependencies to Libs []string + + // The stub sources. + Stub_srcs []string `android:"path"` } type sdkLibraryImportProperties struct { @@ -922,6 +927,8 @@ func (module *sdkLibraryImport) createInternalModules(mctx android.LoadHookConte } module.createJavaImportForStubs(mctx, apiScope, scopeProperties) + + module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties) } javaSdkLibraries := javaSdkLibraries(mctx.Config()) @@ -966,6 +973,16 @@ func (module *sdkLibraryImport) createJavaImportForStubs(mctx android.LoadHookCo mctx.CreateModule(ImportFactory, &props) } +func (module *sdkLibraryImport) createPrebuiltStubsSources(mctx android.LoadHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) { + props := struct { + Name *string + Srcs []string + }{} + props.Name = proptools.StringPtr(apiScope.docsModuleName(module.BaseModuleName())) + props.Srcs = scopeProperties.Stub_srcs + mctx.CreateModule(PrebuiltStubsSourcesFactory, &props) +} + func (module *sdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) { for apiScope, scopeProperties := range module.scopeProperties { if len(scopeProperties.Jars) == 0 { @@ -1164,11 +1181,15 @@ type sdkLibrarySdkMemberProperties struct { // Additional libraries that the exported stubs libraries depend upon. Libs []string + + // The Java stubs source files. + Stub_srcs []string } type scopeProperties struct { - Jars android.Paths - SdkVersion string + Jars android.Paths + StubsSrcJar android.Path + SdkVersion string } func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { @@ -1182,6 +1203,7 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe properties := scopeProperties{} properties.Jars = jars properties.SdkVersion = apiScope.sdkVersion + properties.StubsSrcJar = paths.stubsSrcJar s.Scopes[apiScope] = properties } } @@ -1194,14 +1216,22 @@ func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberCo if properties, ok := s.Scopes[apiScope]; ok { scopeSet := propertySet.AddPropertySet(apiScope.name) + scopeDir := filepath.Join("sdk_library", s.OsPrefix(), apiScope.name) + var jars []string for _, p := range properties.Jars { - dest := filepath.Join("sdk_library", s.OsPrefix(), apiScope.name, ctx.Name()+"-stubs.jar") + dest := filepath.Join(scopeDir, ctx.Name()+"-stubs.jar") ctx.SnapshotBuilder().CopyToSnapshot(p, dest) jars = append(jars, dest) } scopeSet.AddProperty("jars", jars) + // Merge the stubs source jar into the snapshot zip so that when it is unpacked + // the source files are also unpacked. + snapshotRelativeDir := filepath.Join(scopeDir, ctx.Name()+"_stub_sources") + ctx.SnapshotBuilder().UnzipToSnapshot(properties.StubsSrcJar, snapshotRelativeDir) + scopeSet.AddProperty("stub_srcs", []string{snapshotRelativeDir}) + if properties.SdkVersion != "" { scopeSet.AddProperty("sdk_version", properties.SdkVersion) } diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go index a844a5313..415f60b3b 100644 --- a/sdk/java_sdk_test.go +++ b/sdk/java_sdk_test.go @@ -624,7 +624,7 @@ module_exports_snapshot { `), checkAllCopyRules(""), - checkMergeZip(".intermediates/myexports/common_os/tmp/java/myjavaapistubs_stubs_sources.zip"), + checkMergeZips(".intermediates/myexports/common_os/tmp/java/myjavaapistubs_stubs_sources.zip"), ) } @@ -678,7 +678,7 @@ module_exports_snapshot { } `), checkAllCopyRules(""), - checkMergeZip(".intermediates/myexports/common_os/tmp/java/myjavaapistubs_stubs_sources.zip"), + checkMergeZips(".intermediates/myexports/common_os/tmp/java/myjavaapistubs_stubs_sources.zip"), ) } @@ -997,14 +997,17 @@ java_sdk_library_import { apex_available: ["//apex_available:anyapex"], public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], + stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], sdk_version: "current", }, system: { jars: ["sdk_library/system/myjavalib-stubs.jar"], + stub_srcs: ["sdk_library/system/myjavalib_stub_sources"], sdk_version: "system_current", }, test: { jars: ["sdk_library/test/myjavalib-stubs.jar"], + stub_srcs: ["sdk_library/test/myjavalib_stub_sources"], sdk_version: "test_current", }, } @@ -1015,14 +1018,17 @@ java_sdk_library_import { apex_available: ["//apex_available:anyapex"], public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], + stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], sdk_version: "current", }, system: { jars: ["sdk_library/system/myjavalib-stubs.jar"], + stub_srcs: ["sdk_library/system/myjavalib_stub_sources"], sdk_version: "system_current", }, test: { jars: ["sdk_library/test/myjavalib-stubs.jar"], + stub_srcs: ["sdk_library/test/myjavalib_stub_sources"], sdk_version: "test_current", }, } @@ -1037,5 +1043,9 @@ sdk_snapshot { .intermediates/myjavalib.stubs.system/android_common/javac/myjavalib.stubs.system.jar -> sdk_library/system/myjavalib-stubs.jar .intermediates/myjavalib.stubs.test/android_common/javac/myjavalib.stubs.test.jar -> sdk_library/test/myjavalib-stubs.jar `), + checkMergeZips( + ".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip", + ".intermediates/mysdk/common_os/tmp/sdk_library/system/myjavalib_stub_sources.zip", + ".intermediates/mysdk/common_os/tmp/sdk_library/test/myjavalib_stub_sources.zip"), ) } diff --git a/sdk/testing.go b/sdk/testing.go index 362a352d8..14a397c68 100644 --- a/sdk/testing.go +++ b/sdk/testing.go @@ -348,14 +348,15 @@ func checkAllOtherCopyRules(expected string) snapshotBuildInfoChecker { } } -// Check that the specified path is in the list of zips to merge with the intermediate zip. -func checkMergeZip(expected string) snapshotBuildInfoChecker { +// Check that the specified paths match the list of zips to merge with the intermediate zip. +func checkMergeZips(expected ...string) snapshotBuildInfoChecker { return func(info *snapshotBuildInfo) { info.r.t.Helper() if info.intermediateZip == "" { info.r.t.Errorf("No intermediate zip file was created") } - ensureListContains(info.r.t, info.mergeZips, expected) + + info.r.AssertDeepEquals("mismatching merge zip files", expected, info.mergeZips) } } -- cgit v1.2.3-59-g8ed1b From 75dcc80396bcd0e6562c3f4d8e209648bcb52d7b Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Thu, 9 Apr 2020 01:08:11 +0100 Subject: Export API files as part of the java_sdk_library Bug: 153443117 Test: m nothing Merged-In: I9d6f5b91a7cc25019e2eb9e3c138f0874d2831de Change-Id: I9d6f5b91a7cc25019e2eb9e3c138f0874d2831de (cherry picked from commit 1fd005d5b30ce24593d7fe2e7dba43855d6f6466) --- java/droiddoc.go | 5 +++++ java/sdk_library.go | 40 ++++++++++++++++++++++++++++++++-------- sdk/java_sdk_test.go | 18 ++++++++++++++++++ 3 files changed, 55 insertions(+), 8 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 90f143a7a..e0ea515ed 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -339,6 +339,7 @@ type ApiFilePath interface { // Provider of information about API stubs, used by java_sdk_library. type ApiStubsProvider interface { ApiFilePath + RemovedApiFilePath() android.Path StubsSrcJar() android.Path } @@ -1187,6 +1188,10 @@ func (d *Droidstubs) ApiFilePath() android.Path { return d.apiFilePath } +func (d *Droidstubs) RemovedApiFilePath() android.Path { + return d.removedApiFile +} + func (d *Droidstubs) StubsSrcJar() android.Path { return d.stubsSrcJar } diff --git a/java/sdk_library.go b/java/sdk_library.go index 85d5bd3b7..39c118d34 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -240,10 +240,11 @@ type sdkLibraryProperties struct { } type scopePaths struct { - stubsHeaderPath android.Paths - stubsImplPath android.Paths - apiFilePath android.Path - stubsSrcJar android.Path + stubsHeaderPath android.Paths + stubsImplPath android.Paths + currentApiFilePath android.Path + removedApiFilePath android.Path + stubsSrcJar android.Path } // Common code between sdk library and sdk library import @@ -334,7 +335,8 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) if scopeTag, ok := tag.(scopeDependencyTag); ok { apiScope := scopeTag.apiScope scopePaths := module.getScopePaths(apiScope) - scopePaths.apiFilePath = doc.ApiFilePath() + scopePaths.currentApiFilePath = doc.ApiFilePath() + scopePaths.removedApiFilePath = doc.RemovedApiFilePath() scopePaths.stubsSrcJar = doc.StubsSrcJar() } else { ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag) @@ -826,6 +828,12 @@ type sdkLibraryScopeProperties struct { // The stub sources. Stub_srcs []string `android:"path"` + + // The current.txt + Current_api string `android:"path"` + + // The removed.txt + Removed_api string `android:"path"` } type sdkLibraryImportProperties struct { @@ -1187,9 +1195,11 @@ type sdkLibrarySdkMemberProperties struct { } type scopeProperties struct { - Jars android.Paths - StubsSrcJar android.Path - SdkVersion string + Jars android.Paths + StubsSrcJar android.Path + CurrentApiFile android.Path + RemovedApiFile android.Path + SdkVersion string } func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { @@ -1204,6 +1214,8 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe properties.Jars = jars properties.SdkVersion = apiScope.sdkVersion properties.StubsSrcJar = paths.stubsSrcJar + properties.CurrentApiFile = paths.currentApiFilePath + properties.RemovedApiFile = paths.removedApiFilePath s.Scopes[apiScope] = properties } } @@ -1232,6 +1244,18 @@ func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberCo ctx.SnapshotBuilder().UnzipToSnapshot(properties.StubsSrcJar, snapshotRelativeDir) scopeSet.AddProperty("stub_srcs", []string{snapshotRelativeDir}) + if properties.CurrentApiFile != nil { + currentApiSnapshotPath := filepath.Join(scopeDir, ctx.Name()+".txt") + ctx.SnapshotBuilder().CopyToSnapshot(properties.CurrentApiFile, currentApiSnapshotPath) + scopeSet.AddProperty("current_api", currentApiSnapshotPath) + } + + if properties.RemovedApiFile != nil { + removedApiSnapshotPath := filepath.Join(scopeDir, ctx.Name()+"-removed.txt") + ctx.SnapshotBuilder().CopyToSnapshot(properties.CurrentApiFile, removedApiSnapshotPath) + scopeSet.AddProperty("removed_api", removedApiSnapshotPath) + } + if properties.SdkVersion != "" { scopeSet.AddProperty("sdk_version", properties.SdkVersion) } diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go index 415f60b3b..788d0166e 100644 --- a/sdk/java_sdk_test.go +++ b/sdk/java_sdk_test.go @@ -998,16 +998,22 @@ java_sdk_library_import { public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], + current_api: "sdk_library/public/myjavalib.txt", + removed_api: "sdk_library/public/myjavalib-removed.txt", sdk_version: "current", }, system: { jars: ["sdk_library/system/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/system/myjavalib_stub_sources"], + current_api: "sdk_library/system/myjavalib.txt", + removed_api: "sdk_library/system/myjavalib-removed.txt", sdk_version: "system_current", }, test: { jars: ["sdk_library/test/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/test/myjavalib_stub_sources"], + current_api: "sdk_library/test/myjavalib.txt", + removed_api: "sdk_library/test/myjavalib-removed.txt", sdk_version: "test_current", }, } @@ -1019,16 +1025,22 @@ java_sdk_library_import { public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], + current_api: "sdk_library/public/myjavalib.txt", + removed_api: "sdk_library/public/myjavalib-removed.txt", sdk_version: "current", }, system: { jars: ["sdk_library/system/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/system/myjavalib_stub_sources"], + current_api: "sdk_library/system/myjavalib.txt", + removed_api: "sdk_library/system/myjavalib-removed.txt", sdk_version: "system_current", }, test: { jars: ["sdk_library/test/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/test/myjavalib_stub_sources"], + current_api: "sdk_library/test/myjavalib.txt", + removed_api: "sdk_library/test/myjavalib-removed.txt", sdk_version: "test_current", }, } @@ -1040,8 +1052,14 @@ sdk_snapshot { `), checkAllCopyRules(` .intermediates/myjavalib.stubs/android_common/javac/myjavalib.stubs.jar -> sdk_library/public/myjavalib-stubs.jar +.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt +.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib-removed.txt .intermediates/myjavalib.stubs.system/android_common/javac/myjavalib.stubs.system.jar -> sdk_library/system/myjavalib-stubs.jar +.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib.txt +.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib-removed.txt .intermediates/myjavalib.stubs.test/android_common/javac/myjavalib.stubs.test.jar -> sdk_library/test/myjavalib-stubs.jar +.intermediates/myjavalib.stubs.source.test/android_common/myjavalib.stubs.source.test_api.txt -> sdk_library/test/myjavalib.txt +.intermediates/myjavalib.stubs.source.test/android_common/myjavalib.stubs.source.test_api.txt -> sdk_library/test/myjavalib-removed.txt `), checkMergeZips( ".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip", -- cgit v1.2.3-59-g8ed1b From 8986cc947cae0cb150e1e5e72940fe078b349140 Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Sun, 10 May 2020 19:32:20 +0100 Subject: Enable api_lint in java_sdk_library Adds api_lint.enabled property to control whether API linting should be performed. Test: m checkapi Bug: 156126315 Merged-In: I87ca5a942228cf6af1a9939f0334d6fc46c39a63 Change-Id: I87ca5a942228cf6af1a9939f0334d6fc46c39a63 (cherry picked from commit 160fe41c39c8e84acffce8180fed0031b2244638) --- java/droiddoc.go | 28 ++++++++++++++++++++++++++-- java/sdk_library.go | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 4 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 5cd104809..3ca68cfe1 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -221,8 +221,22 @@ type DroidstubsProperties struct { Current ApiToCheck - // do not perform API check against Last_released, in the case that both two specified API - // files by Last_released are modules which don't exist. + // The java_sdk_library module generates references to modules (i.e. filegroups) + // from which information about the latest API version can be obtained. As those + // modules may not exist (e.g. because a previous version has not been released) it + // sets ignore_missing_latest_api=true on the droidstubs modules it creates so + // that droidstubs can ignore those references if the modules do not yet exist. + // + // If true then this will ignore module references for modules that do not exist + // in properties that supply the previous version of the API. + // + // There are two sets of those: + // * Api_file, Removed_api_file in check_api.last_released + // * New_since in check_api.api_lint.new_since + // + // The first two must be set as a pair, so either they should both exist or neither + // should exist - in which case when this property is true they are ignored. If one + // exists and the other does not then it is an error. Ignore_missing_latest_api *bool `blueprint:"mutated"` Api_lint struct { @@ -1199,8 +1213,18 @@ func (d *Droidstubs) StubsSrcJar() android.Path { func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) { d.Javadoc.addDeps(ctx) + // If requested clear any properties that provide information about the latest version + // of an API and which reference non-existent modules. if Bool(d.properties.Check_api.Ignore_missing_latest_api) { ignoreMissingModules(ctx, &d.properties.Check_api.Last_released) + + // If the new_since references a module, e.g. :module-latest-api and the module + // does not exist then clear it. + newSinceSrc := d.properties.Check_api.Api_lint.New_since + newSinceSrcModule := android.SrcIsModule(proptools.String(newSinceSrc)) + if newSinceSrcModule != "" && !ctx.OtherModuleExists(newSinceSrcModule) { + d.properties.Check_api.Api_lint.New_since = nil + } } if len(d.properties.Merge_annotations_dirs) != 0 { diff --git a/java/sdk_library.go b/java/sdk_library.go index 2c85c8c09..8956e8be4 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -351,6 +351,12 @@ type sdkLibraryProperties struct { // disabled by default. Module_lib ApiScopeProperties + // Properties related to api linting. + Api_lint struct { + // Enable api linting. + Enabled *bool + } + // TODO: determines whether to create HTML doc or not //Html_doc *bool } @@ -677,6 +683,12 @@ func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookC Current ApiToCheck Last_released ApiToCheck Ignore_missing_latest_api *bool + + Api_lint struct { + Enabled *bool + New_since *string + Baseline_file *string + } } Aidl struct { Include_dirs []string @@ -759,11 +771,30 @@ func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookC if !apiScope.unstable { // check against the latest released API - props.Check_api.Last_released.Api_file = proptools.StringPtr( - module.latestApiFilegroupName(apiScope)) + latestApiFilegroupName := proptools.StringPtr(module.latestApiFilegroupName(apiScope)) + props.Check_api.Last_released.Api_file = latestApiFilegroupName props.Check_api.Last_released.Removed_api_file = proptools.StringPtr( module.latestRemovedApiFilegroupName(apiScope)) props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true) + + if proptools.Bool(module.sdkLibraryProperties.Api_lint.Enabled) { + // Enable api lint. + props.Check_api.Api_lint.Enabled = proptools.BoolPtr(true) + props.Check_api.Api_lint.New_since = latestApiFilegroupName + + // If it exists then pass a lint-baseline.txt through to droidstubs. + baselinePath := path.Join(apiDir, apiScope.apiFilePrefix+"lint-baseline.txt") + baselinePathRelativeToRoot := path.Join(mctx.ModuleDir(), baselinePath) + paths, err := mctx.GlobWithDeps(baselinePathRelativeToRoot, nil) + if err != nil { + mctx.ModuleErrorf("error checking for presence of %s: %s", baselinePathRelativeToRoot, err) + } + if len(paths) == 1 { + props.Check_api.Api_lint.Baseline_file = proptools.StringPtr(baselinePath) + } else if len(paths) != 0 { + mctx.ModuleErrorf("error checking for presence of %s: expected one path, found: %v", baselinePathRelativeToRoot, paths) + } + } } // Dist the api txt artifact for sdk builds. -- cgit v1.2.3-59-g8ed1b From 18a289560d6e5a4019ebc0bc03b5853406606a33 Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Mon, 11 May 2020 15:38:31 +0100 Subject: Fix API lint copy command The space after the backtick prevents it working when copy-pasting it into the shell. Test: create lint error => m => cp/pasted command runs successfully Merged-In: I42b8b60d01dcaed34dbde0390eb1691d656a32cf Change-Id: I42b8b60d01dcaed34dbde0390eb1691d656a32cf (cherry picked from commit 3361a294c0b0919d663b7a355b46548f5c520bb4) // Added for rvc-dev. Used this bug as it is the bug that needs all the build changes. Bug: 155164730 Change-Id: I42b8b60d01dcaed34dbde0390eb1691d656a32cf --- java/droiddoc.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 3ca68cfe1..62a66618d 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1529,9 +1529,9 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { msg += fmt.Sprintf(``+ `2. You can update the baseline by executing the following\n`+ ` command:\n`+ - ` cp \\ \n`+ - ` "'"$PWD"$'/%s" \\ \n`+ - ` "'"$PWD"$'/%s" \n`+ + ` cp \\\n`+ + ` "'"$PWD"$'/%s" \\\n`+ + ` "'"$PWD"$'/%s"\n`+ ` To submit the revised baseline.txt to the main Android\n`+ ` repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path()) } else { -- cgit v1.2.3-59-g8ed1b From c5e13279ad9d146e12d97f937afc45c958c1e3af Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Thu, 21 May 2020 10:11:31 +0100 Subject: Don't require merge_annotations_dir for annotations_enabled As far as I can tell, annotations_enabled does not require use of merge_annotations_dir (although it may have done in the past). Bug: 157010342 Test: m Change-Id: I6705522774203b4566f58679bbc2f0c17422c1dd --- java/droiddoc.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 62a66618d..4b4a245e7 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1308,13 +1308,10 @@ func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.Ru d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip") cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip) - if len(d.properties.Merge_annotations_dirs) == 0 { - ctx.PropertyErrorf("merge_annotations_dirs", - "has to be non-empty if annotations was enabled!") + if len(d.properties.Merge_annotations_dirs) != 0 { + d.mergeAnnoDirFlags(ctx, cmd) } - d.mergeAnnoDirFlags(ctx, cmd) - // TODO(tnorbye): find owners to fix these warnings when annotation was enabled. cmd.FlagWithArg("--hide ", "HiddenTypedefConstant"). FlagWithArg("--hide ", "SuperfluousPrefix"). -- cgit v1.2.3-59-g8ed1b From dce3fe78f0d864e77fbad6b8ea31489a2d6e855d Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Wed, 20 May 2020 16:18:00 +0100 Subject: java_sdk_library: Improve consistency with ..._import The scopePaths struct is used by both java_sdk_library and its prebuilt but was not populated in the same way. This change addresses those discrepancies in preparation for a follow up change which will allow access to some of those fields through OutputFileProvider. Changes: * Document the scopePaths field and struct. * Switch those fields that may not be fully populated from Paths to OptionalPath to make that 100% clear and protect against unchecked use. * Switch java_sdk_library_import to use the dependency extraction mechanism driven by the dependency tag. This should actually have been part of the change that added that mechanism. * Only create prebuilt_stubs_sources if sources have been provided. * Add dependencies from java_sdk_library_import on its stubs source child modules if sources have been provided. That will ensure the stubsSrcJar field is updated. * Updates current/removedApiFilePath if provided for the scope in java_sdk_library_import. * Extracts ApiStubsSrcProvider from ApiStubsProvider to allow it to be implemented by PrebuiltStubsSources so that it can provide access to the stubs src jar that it creates. Test: m nothing Bug: 148080325 Bug: 155164730 Merged-In: Ic5bf884b2b1e79841843e7c3b4642796ecd49f5d Change-Id: Ic5bf884b2b1e79841843e7c3b4642796ecd49f5d (cherry picked from commit 0f8faffdc0e039bb73305d2a53a2d17029cdb469) --- java/droiddoc.go | 11 ++++++- java/java_test.go | 1 + java/sdk_library.go | 93 ++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 81 insertions(+), 24 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 62a66618d..a637349c8 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -350,11 +350,16 @@ type ApiFilePath interface { ApiFilePath() android.Path } +type ApiStubsSrcProvider interface { + StubsSrcJar() android.Path +} + // Provider of information about API stubs, used by java_sdk_library. type ApiStubsProvider interface { ApiFilePath RemovedApiFilePath() android.Path - StubsSrcJar() android.Path + + ApiStubsSrcProvider } // @@ -1915,6 +1920,10 @@ func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) { } } +func (d *PrebuiltStubsSources) StubsSrcJar() android.Path { + return d.stubsSrcJar +} + func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) { p.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar") diff --git a/java/java_test.go b/java/java_test.go index b8abacb59..16200119e 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -575,6 +575,7 @@ func TestJavaSdkLibraryImport(t *testing.T) { }, test: { jars: ["c.jar"], + stub_srcs: ["c.java"], }, } `) diff --git a/java/sdk_library.go b/java/sdk_library.go index cae0ff52d..432598edb 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -433,12 +433,30 @@ type sdkLibraryProperties struct { //Html_doc *bool } +// Paths to outputs from java_sdk_library and java_sdk_library_import. +// +// Fields that are android.Paths are always set (during GenerateAndroidBuildActions). +// OptionalPaths are always set by java_sdk_library but may not be set by +// java_sdk_library_import as not all instances provide that information. type scopePaths struct { - stubsHeaderPath android.Paths - stubsImplPath android.Paths - currentApiFilePath android.Path - removedApiFilePath android.Path - stubsSrcJar android.Path + // The path (represented as Paths for convenience when returning) to the stubs header jar. + // + // That is the jar that is created by turbine. + stubsHeaderPath android.Paths + + // The path (represented as Paths for convenience when returning) to the stubs implementation jar. + // + // This is not the implementation jar, it still only contains stubs. + stubsImplPath android.Paths + + // The API specification file, e.g. system_current.txt. + currentApiFilePath android.OptionalPath + + // The specification of API elements removed since the last release. + removedApiFilePath android.OptionalPath + + // The stubs source jar. + stubsSrcJar android.OptionalPath } func (paths *scopePaths) extractStubsLibraryInfoFromDependency(dep android.Module) error { @@ -460,9 +478,18 @@ func (paths *scopePaths) treatDepAsApiStubsProvider(dep android.Module, action f } } +func (paths *scopePaths) treatDepAsApiStubsSrcProvider(dep android.Module, action func(provider ApiStubsSrcProvider)) error { + if apiStubsProvider, ok := dep.(ApiStubsSrcProvider); ok { + action(apiStubsProvider) + return nil + } else { + return fmt.Errorf("expected module that implements ApiStubsSrcProvider, e.g. droidstubs") + } +} + func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider ApiStubsProvider) { - paths.currentApiFilePath = provider.ApiFilePath() - paths.removedApiFilePath = provider.RemovedApiFilePath() + paths.currentApiFilePath = android.OptionalPathForPath(provider.ApiFilePath()) + paths.removedApiFilePath = android.OptionalPathForPath(provider.RemovedApiFilePath()) } func (paths *scopePaths) extractApiInfoFromDep(dep android.Module) error { @@ -471,12 +498,12 @@ func (paths *scopePaths) extractApiInfoFromDep(dep android.Module) error { }) } -func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsProvider) { - paths.stubsSrcJar = provider.StubsSrcJar() +func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsSrcProvider) { + paths.stubsSrcJar = android.OptionalPathForPath(provider.StubsSrcJar()) } func (paths *scopePaths) extractStubsSourceInfoFromDep(dep android.Module) error { - return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) { + return paths.treatDepAsApiStubsSrcProvider(dep, func(provider ApiStubsSrcProvider) { paths.extractStubsSourceInfoFromApiStubsProviders(provider) }) } @@ -1314,10 +1341,10 @@ type sdkLibraryScopeProperties struct { Stub_srcs []string `android:"path"` // The current.txt - Current_api string `android:"path"` + Current_api *string `android:"path"` // The removed.txt - Removed_api string `android:"path"` + Removed_api *string `android:"path"` } type sdkLibraryImportProperties struct { @@ -1427,7 +1454,9 @@ func (module *sdkLibraryImport) createInternalModules(mctx android.DefaultableHo module.createJavaImportForStubs(mctx, apiScope, scopeProperties) - module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties) + if len(scopeProperties.Stub_srcs) > 0 { + module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties) + } } javaSdkLibraries := javaSdkLibraries(mctx.Config()) @@ -1479,22 +1508,40 @@ func (module *sdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) // Add dependencies to the prebuilt stubs library ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsLibraryModuleName(apiScope)) + + if len(scopeProperties.Stub_srcs) > 0 { + // Add dependencies to the prebuilt stubs source library + ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, module.stubsSourceModuleName(apiScope)) + } } } func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { - // Record the paths to the prebuilt stubs library. + // Record the paths to the prebuilt stubs library and stubs source. ctx.VisitDirectDeps(func(to android.Module) { tag := ctx.OtherModuleDependencyTag(to) - if lib, ok := to.(Dependency); ok { - if scopeTag, ok := tag.(scopeDependencyTag); ok { - apiScope := scopeTag.apiScope - scopePaths := module.getScopePathsCreateIfNeeded(apiScope) - scopePaths.stubsHeaderPath = lib.HeaderJars() - } + // Extract information from any of the scope specific dependencies. + if scopeTag, ok := tag.(scopeDependencyTag); ok { + apiScope := scopeTag.apiScope + scopePaths := module.getScopePathsCreateIfNeeded(apiScope) + + // Extract information from the dependency. The exact information extracted + // is determined by the nature of the dependency which is determined by the tag. + scopeTag.extractDepInfo(ctx, to, scopePaths) } }) + + // Populate the scope paths with information from the properties. + for apiScope, scopeProperties := range module.scopeProperties { + if len(scopeProperties.Jars) == 0 { + continue + } + + paths := module.getScopePathsCreateIfNeeded(apiScope) + paths.currentApiFilePath = android.OptionalPathForModuleSrc(ctx, scopeProperties.Current_api) + paths.removedApiFilePath = android.OptionalPathForModuleSrc(ctx, scopeProperties.Removed_api) + } } func (module *sdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths { @@ -1685,9 +1732,9 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe properties := scopeProperties{} properties.Jars = jars properties.SdkVersion = sdk.sdkVersionForStubsLibrary(ctx.SdkModuleContext(), apiScope) - properties.StubsSrcJar = paths.stubsSrcJar - properties.CurrentApiFile = paths.currentApiFilePath - properties.RemovedApiFile = paths.removedApiFilePath + properties.StubsSrcJar = paths.stubsSrcJar.Path() + properties.CurrentApiFile = paths.currentApiFilePath.Path() + properties.RemovedApiFile = paths.removedApiFilePath.Path() s.Scopes[apiScope] = properties } } -- cgit v1.2.3-59-g8ed1b From 2ee93a5de958262fd1a2d1db08063acd2b0c3e03 Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Mon, 25 May 2020 01:56:32 +0000 Subject: Revert "java_sdk_library: Improve consistency with ..._import" This reverts commit dce3fe78f0d864e77fbad6b8ea31489a2d6e855d. Reason for revert: Broke presubmit: b/157231582 Change-Id: I638e0e090f3242ed5a9a3134cbe380e872411247 --- java/droiddoc.go | 11 +------ java/java_test.go | 1 - java/sdk_library.go | 93 +++++++++++++---------------------------------------- 3 files changed, 24 insertions(+), 81 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index a637349c8..62a66618d 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -350,16 +350,11 @@ type ApiFilePath interface { ApiFilePath() android.Path } -type ApiStubsSrcProvider interface { - StubsSrcJar() android.Path -} - // Provider of information about API stubs, used by java_sdk_library. type ApiStubsProvider interface { ApiFilePath RemovedApiFilePath() android.Path - - ApiStubsSrcProvider + StubsSrcJar() android.Path } // @@ -1920,10 +1915,6 @@ func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) { } } -func (d *PrebuiltStubsSources) StubsSrcJar() android.Path { - return d.stubsSrcJar -} - func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) { p.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar") diff --git a/java/java_test.go b/java/java_test.go index 16200119e..b8abacb59 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -575,7 +575,6 @@ func TestJavaSdkLibraryImport(t *testing.T) { }, test: { jars: ["c.jar"], - stub_srcs: ["c.java"], }, } `) diff --git a/java/sdk_library.go b/java/sdk_library.go index 432598edb..cae0ff52d 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -433,30 +433,12 @@ type sdkLibraryProperties struct { //Html_doc *bool } -// Paths to outputs from java_sdk_library and java_sdk_library_import. -// -// Fields that are android.Paths are always set (during GenerateAndroidBuildActions). -// OptionalPaths are always set by java_sdk_library but may not be set by -// java_sdk_library_import as not all instances provide that information. type scopePaths struct { - // The path (represented as Paths for convenience when returning) to the stubs header jar. - // - // That is the jar that is created by turbine. - stubsHeaderPath android.Paths - - // The path (represented as Paths for convenience when returning) to the stubs implementation jar. - // - // This is not the implementation jar, it still only contains stubs. - stubsImplPath android.Paths - - // The API specification file, e.g. system_current.txt. - currentApiFilePath android.OptionalPath - - // The specification of API elements removed since the last release. - removedApiFilePath android.OptionalPath - - // The stubs source jar. - stubsSrcJar android.OptionalPath + stubsHeaderPath android.Paths + stubsImplPath android.Paths + currentApiFilePath android.Path + removedApiFilePath android.Path + stubsSrcJar android.Path } func (paths *scopePaths) extractStubsLibraryInfoFromDependency(dep android.Module) error { @@ -478,18 +460,9 @@ func (paths *scopePaths) treatDepAsApiStubsProvider(dep android.Module, action f } } -func (paths *scopePaths) treatDepAsApiStubsSrcProvider(dep android.Module, action func(provider ApiStubsSrcProvider)) error { - if apiStubsProvider, ok := dep.(ApiStubsSrcProvider); ok { - action(apiStubsProvider) - return nil - } else { - return fmt.Errorf("expected module that implements ApiStubsSrcProvider, e.g. droidstubs") - } -} - func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider ApiStubsProvider) { - paths.currentApiFilePath = android.OptionalPathForPath(provider.ApiFilePath()) - paths.removedApiFilePath = android.OptionalPathForPath(provider.RemovedApiFilePath()) + paths.currentApiFilePath = provider.ApiFilePath() + paths.removedApiFilePath = provider.RemovedApiFilePath() } func (paths *scopePaths) extractApiInfoFromDep(dep android.Module) error { @@ -498,12 +471,12 @@ func (paths *scopePaths) extractApiInfoFromDep(dep android.Module) error { }) } -func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsSrcProvider) { - paths.stubsSrcJar = android.OptionalPathForPath(provider.StubsSrcJar()) +func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsProvider) { + paths.stubsSrcJar = provider.StubsSrcJar() } func (paths *scopePaths) extractStubsSourceInfoFromDep(dep android.Module) error { - return paths.treatDepAsApiStubsSrcProvider(dep, func(provider ApiStubsSrcProvider) { + return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) { paths.extractStubsSourceInfoFromApiStubsProviders(provider) }) } @@ -1341,10 +1314,10 @@ type sdkLibraryScopeProperties struct { Stub_srcs []string `android:"path"` // The current.txt - Current_api *string `android:"path"` + Current_api string `android:"path"` // The removed.txt - Removed_api *string `android:"path"` + Removed_api string `android:"path"` } type sdkLibraryImportProperties struct { @@ -1454,9 +1427,7 @@ func (module *sdkLibraryImport) createInternalModules(mctx android.DefaultableHo module.createJavaImportForStubs(mctx, apiScope, scopeProperties) - if len(scopeProperties.Stub_srcs) > 0 { - module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties) - } + module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties) } javaSdkLibraries := javaSdkLibraries(mctx.Config()) @@ -1508,40 +1479,22 @@ func (module *sdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) // Add dependencies to the prebuilt stubs library ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsLibraryModuleName(apiScope)) - - if len(scopeProperties.Stub_srcs) > 0 { - // Add dependencies to the prebuilt stubs source library - ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, module.stubsSourceModuleName(apiScope)) - } } } func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { - // Record the paths to the prebuilt stubs library and stubs source. + // Record the paths to the prebuilt stubs library. ctx.VisitDirectDeps(func(to android.Module) { tag := ctx.OtherModuleDependencyTag(to) - // Extract information from any of the scope specific dependencies. - if scopeTag, ok := tag.(scopeDependencyTag); ok { - apiScope := scopeTag.apiScope - scopePaths := module.getScopePathsCreateIfNeeded(apiScope) - - // Extract information from the dependency. The exact information extracted - // is determined by the nature of the dependency which is determined by the tag. - scopeTag.extractDepInfo(ctx, to, scopePaths) + if lib, ok := to.(Dependency); ok { + if scopeTag, ok := tag.(scopeDependencyTag); ok { + apiScope := scopeTag.apiScope + scopePaths := module.getScopePathsCreateIfNeeded(apiScope) + scopePaths.stubsHeaderPath = lib.HeaderJars() + } } }) - - // Populate the scope paths with information from the properties. - for apiScope, scopeProperties := range module.scopeProperties { - if len(scopeProperties.Jars) == 0 { - continue - } - - paths := module.getScopePathsCreateIfNeeded(apiScope) - paths.currentApiFilePath = android.OptionalPathForModuleSrc(ctx, scopeProperties.Current_api) - paths.removedApiFilePath = android.OptionalPathForModuleSrc(ctx, scopeProperties.Removed_api) - } } func (module *sdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths { @@ -1732,9 +1685,9 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe properties := scopeProperties{} properties.Jars = jars properties.SdkVersion = sdk.sdkVersionForStubsLibrary(ctx.SdkModuleContext(), apiScope) - properties.StubsSrcJar = paths.stubsSrcJar.Path() - properties.CurrentApiFile = paths.currentApiFilePath.Path() - properties.RemovedApiFile = paths.removedApiFilePath.Path() + properties.StubsSrcJar = paths.stubsSrcJar + properties.CurrentApiFile = paths.currentApiFilePath + properties.RemovedApiFile = paths.removedApiFilePath s.Scopes[apiScope] = properties } } -- cgit v1.2.3-59-g8ed1b From 533f9c78cd61c35859f8a9e194b799f46b1df90f Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Wed, 20 May 2020 16:18:00 +0100 Subject: Retry: "java_sdk_library: Improve consistency with ..._import" The scopePaths struct is used by both java_sdk_library and its prebuilt but was not populated in the same way. This change addresses those discrepancies in preparation for a follow up change which will allow access to some of those fields through OutputFileProvider. Changes: * Document the scopePaths field and struct. * Switch those fields that may not be fully populated from Paths to OptionalPath to make that 100% clear and protect against unchecked use. * Switch java_sdk_library_import to use the dependency extraction mechanism driven by the dependency tag. This should actually have been part of the change that added that mechanism. * Only create prebuilt_stubs_sources if sources have been provided. * Add dependencies from java_sdk_library_import on its stubs source child modules if sources have been provided. That will ensure the stubsSrcJar field is updated. * Updates current/removedApiFilePath if provided for the scope in java_sdk_library_import. * Extracts ApiStubsSrcProvider from ApiStubsProvider to allow it to be implemented by PrebuiltStubsSources so that it can provide access to the stubs src jar that it creates. Test: m nothing Bug: 148080325 Bug: 155164730 (cherry picked from commit 0f8faffdc0e039bb73305d2a53a2d17029cdb469) Change-Id: Ib56ca608d6fc1357d3d89e9c4cfed6ff8da11735 --- java/droiddoc.go | 11 ++++++- java/java_test.go | 1 + java/sdk_library.go | 93 ++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 81 insertions(+), 24 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 4b4a245e7..c1cecb64a 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -350,11 +350,16 @@ type ApiFilePath interface { ApiFilePath() android.Path } +type ApiStubsSrcProvider interface { + StubsSrcJar() android.Path +} + // Provider of information about API stubs, used by java_sdk_library. type ApiStubsProvider interface { ApiFilePath RemovedApiFilePath() android.Path - StubsSrcJar() android.Path + + ApiStubsSrcProvider } // @@ -1912,6 +1917,10 @@ func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) { } } +func (d *PrebuiltStubsSources) StubsSrcJar() android.Path { + return d.stubsSrcJar +} + func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) { p.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar") diff --git a/java/java_test.go b/java/java_test.go index b8abacb59..16200119e 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -575,6 +575,7 @@ func TestJavaSdkLibraryImport(t *testing.T) { }, test: { jars: ["c.jar"], + stub_srcs: ["c.java"], }, } `) diff --git a/java/sdk_library.go b/java/sdk_library.go index 1fff3ba34..c91091ffc 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -433,12 +433,30 @@ type sdkLibraryProperties struct { //Html_doc *bool } +// Paths to outputs from java_sdk_library and java_sdk_library_import. +// +// Fields that are android.Paths are always set (during GenerateAndroidBuildActions). +// OptionalPaths are always set by java_sdk_library but may not be set by +// java_sdk_library_import as not all instances provide that information. type scopePaths struct { - stubsHeaderPath android.Paths - stubsImplPath android.Paths - currentApiFilePath android.Path - removedApiFilePath android.Path - stubsSrcJar android.Path + // The path (represented as Paths for convenience when returning) to the stubs header jar. + // + // That is the jar that is created by turbine. + stubsHeaderPath android.Paths + + // The path (represented as Paths for convenience when returning) to the stubs implementation jar. + // + // This is not the implementation jar, it still only contains stubs. + stubsImplPath android.Paths + + // The API specification file, e.g. system_current.txt. + currentApiFilePath android.OptionalPath + + // The specification of API elements removed since the last release. + removedApiFilePath android.OptionalPath + + // The stubs source jar. + stubsSrcJar android.OptionalPath } func (paths *scopePaths) extractStubsLibraryInfoFromDependency(dep android.Module) error { @@ -460,9 +478,18 @@ func (paths *scopePaths) treatDepAsApiStubsProvider(dep android.Module, action f } } +func (paths *scopePaths) treatDepAsApiStubsSrcProvider(dep android.Module, action func(provider ApiStubsSrcProvider)) error { + if apiStubsProvider, ok := dep.(ApiStubsSrcProvider); ok { + action(apiStubsProvider) + return nil + } else { + return fmt.Errorf("expected module that implements ApiStubsSrcProvider, e.g. droidstubs") + } +} + func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider ApiStubsProvider) { - paths.currentApiFilePath = provider.ApiFilePath() - paths.removedApiFilePath = provider.RemovedApiFilePath() + paths.currentApiFilePath = android.OptionalPathForPath(provider.ApiFilePath()) + paths.removedApiFilePath = android.OptionalPathForPath(provider.RemovedApiFilePath()) } func (paths *scopePaths) extractApiInfoFromDep(dep android.Module) error { @@ -471,12 +498,12 @@ func (paths *scopePaths) extractApiInfoFromDep(dep android.Module) error { }) } -func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsProvider) { - paths.stubsSrcJar = provider.StubsSrcJar() +func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsSrcProvider) { + paths.stubsSrcJar = android.OptionalPathForPath(provider.StubsSrcJar()) } func (paths *scopePaths) extractStubsSourceInfoFromDep(dep android.Module) error { - return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) { + return paths.treatDepAsApiStubsSrcProvider(dep, func(provider ApiStubsSrcProvider) { paths.extractStubsSourceInfoFromApiStubsProviders(provider) }) } @@ -1319,10 +1346,10 @@ type sdkLibraryScopeProperties struct { Stub_srcs []string `android:"path"` // The current.txt - Current_api string `android:"path"` + Current_api *string `android:"path"` // The removed.txt - Removed_api string `android:"path"` + Removed_api *string `android:"path"` } type sdkLibraryImportProperties struct { @@ -1432,7 +1459,9 @@ func (module *sdkLibraryImport) createInternalModules(mctx android.DefaultableHo module.createJavaImportForStubs(mctx, apiScope, scopeProperties) - module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties) + if len(scopeProperties.Stub_srcs) > 0 { + module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties) + } } javaSdkLibraries := javaSdkLibraries(mctx.Config()) @@ -1484,22 +1513,40 @@ func (module *sdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) // Add dependencies to the prebuilt stubs library ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsLibraryModuleName(apiScope)) + + if len(scopeProperties.Stub_srcs) > 0 { + // Add dependencies to the prebuilt stubs source library + ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, module.stubsSourceModuleName(apiScope)) + } } } func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { - // Record the paths to the prebuilt stubs library. + // Record the paths to the prebuilt stubs library and stubs source. ctx.VisitDirectDeps(func(to android.Module) { tag := ctx.OtherModuleDependencyTag(to) - if lib, ok := to.(Dependency); ok { - if scopeTag, ok := tag.(scopeDependencyTag); ok { - apiScope := scopeTag.apiScope - scopePaths := module.getScopePathsCreateIfNeeded(apiScope) - scopePaths.stubsHeaderPath = lib.HeaderJars() - } + // Extract information from any of the scope specific dependencies. + if scopeTag, ok := tag.(scopeDependencyTag); ok { + apiScope := scopeTag.apiScope + scopePaths := module.getScopePathsCreateIfNeeded(apiScope) + + // Extract information from the dependency. The exact information extracted + // is determined by the nature of the dependency which is determined by the tag. + scopeTag.extractDepInfo(ctx, to, scopePaths) } }) + + // Populate the scope paths with information from the properties. + for apiScope, scopeProperties := range module.scopeProperties { + if len(scopeProperties.Jars) == 0 { + continue + } + + paths := module.getScopePathsCreateIfNeeded(apiScope) + paths.currentApiFilePath = android.OptionalPathForModuleSrc(ctx, scopeProperties.Current_api) + paths.removedApiFilePath = android.OptionalPathForModuleSrc(ctx, scopeProperties.Removed_api) + } } func (module *sdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths { @@ -1690,9 +1737,9 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe properties := scopeProperties{} properties.Jars = jars properties.SdkVersion = sdk.sdkVersionForStubsLibrary(ctx.SdkModuleContext(), apiScope) - properties.StubsSrcJar = paths.stubsSrcJar - properties.CurrentApiFile = paths.currentApiFilePath - properties.RemovedApiFile = paths.removedApiFilePath + properties.StubsSrcJar = paths.stubsSrcJar.Path() + properties.CurrentApiFile = paths.currentApiFilePath.Path() + properties.RemovedApiFile = paths.removedApiFilePath.Path() s.Scopes[apiScope] = properties } } -- cgit v1.2.3-59-g8ed1b From 174b26e7d3680919cda10a51adf01f20990eb396 Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Tue, 26 May 2020 11:42:13 +0100 Subject: Switch droiddoc to use SdkHeaderJars() Previously, droiddoc was using SdkImplementationJars() to get a JAR to add to the classpath in order to resolve unknown references in the source. Given that SdkHeaderJars() returns jars created by Turbine which are (for compilation at least) functionally identical to the implementation jars there is no point in using the implementation jars. Bug: 148080325 Test: m nothing Merged-In: I2b718cc1445c04e849dcb0b1f53bba2b0bd90c95 Change-Id: I2b718cc1445c04e849dcb0b1f53bba2b0bd90c95 (cherry picked from commit 649dadfb8759ef1fc4f9c9ddb9221a6c2f6a8cdf) --- java/droiddoc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index c1cecb64a..cf4c892f9 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -545,7 +545,7 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { case libTag: switch dep := module.(type) { case SdkLibraryDependency: - deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...) + deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...) case Dependency: deps.classpath = append(deps.classpath, dep.HeaderJars()...) deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...) -- cgit v1.2.3-59-g8ed1b From 1fb3cd84967bb0fbfa42466fd6afbe0d3bf7730f Mon Sep 17 00:00:00 2001 From: Ramy Medhat Date: Tue, 5 May 2020 22:50:09 +0000 Subject: Add support for the remote execution of metalava actions. Bug: b/156613606 Test: built aosp crosshatch userdebug with RBE_METALAVA=1 Change-Id: I3d42d75b4522f99ff95ce8c997ead782e4322f6e Merged-In: I3d42d75b4522f99ff95ce8c997ead782e4322f6e --- java/droiddoc.go | 27 +++++++++++++++++++++++++- remoteexec/remoteexec.go | 44 ++++++++++++++++++++++++++++--------------- remoteexec/remoteexec_test.go | 18 ++++++++++++++++++ 3 files changed, 73 insertions(+), 16 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index cf4c892f9..4d806baef 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -24,6 +24,7 @@ import ( "android/soong/android" "android/soong/java/config" + "android/soong/remoteexec" ) func init() { @@ -1401,7 +1402,31 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand { // Metalava uses lots of memory, restrict the number of metalava jobs that can run in parallel. rule.HighMem() - cmd := rule.Command().BuiltTool(ctx, "metalava"). + cmd := rule.Command() + if ctx.Config().IsEnvTrue("RBE_METALAVA") { + rule.Remoteable(android.RemoteRuleSupports{RBE: true}) + execStrategy := remoteexec.LocalExecStrategy + if v := ctx.Config().Getenv("RBE_METALAVA_EXEC_STRATEGY"); v != "" { + execStrategy = v + } + pool := "metalava" + if v := ctx.Config().Getenv("RBE_METALAVA_POOL"); v != "" { + pool = v + } + inputs := []string{android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "metalava.jar").String()} + if v := ctx.Config().Getenv("RBE_METALAVA_INPUTS"); v != "" { + inputs = append(inputs, strings.Split(v, ",")...) + } + cmd.Text((&remoteexec.REParams{ + Labels: map[string]string{"type": "compile", "lang": "java", "compiler": "metalava"}, + ExecStrategy: execStrategy, + Inputs: inputs, + ToolchainInputs: []string{config.JavaCmd(ctx).String()}, + Platform: map[string]string{remoteexec.PoolKey: pool}, + }).NoVarTemplate(ctx.Config())) + } + + cmd.BuiltTool(ctx, "metalava"). Flag(config.JavacVmFlags). FlagWithArg("-encoding ", "UTF-8"). FlagWithArg("-source ", javaVersion.String()). diff --git a/remoteexec/remoteexec.go b/remoteexec/remoteexec.go index c7d518eec..d69fe1cc0 100644 --- a/remoteexec/remoteexec.go +++ b/remoteexec/remoteexec.go @@ -85,17 +85,31 @@ type REParams struct { func init() { pctx.VariableFunc("Wrapper", func(ctx android.PackageVarContext) string { - if override := ctx.Config().Getenv("RBE_WRAPPER"); override != "" { - return override - } - return DefaultWrapperPath + return wrapper(ctx.Config()) }) } -// Generate the remote execution wrapper template to be added as a prefix to the rule's command. +func wrapper(cfg android.Config) string { + if override := cfg.Getenv("RBE_WRAPPER"); override != "" { + return override + } + return DefaultWrapperPath +} + +// Template generates the remote execution wrapper template to be added as a prefix to the rule's +// command. func (r *REParams) Template() string { - template := "${remoteexec.Wrapper}" + return "${remoteexec.Wrapper}" + r.wrapperArgs() +} + +// NoVarTemplate generate the remote execution wrapper template without variables, to be used in +// RuleBuilder. +func (r *REParams) NoVarTemplate(cfg android.Config) string { + return wrapper(cfg) + r.wrapperArgs() +} +func (r *REParams) wrapperArgs() string { + args := "" var kvs []string labels := r.Labels if len(labels) == 0 { @@ -105,7 +119,7 @@ func (r *REParams) Template() string { kvs = append(kvs, k+"="+v) } sort.Strings(kvs) - template += " --labels=" + strings.Join(kvs, ",") + args += " --labels=" + strings.Join(kvs, ",") var platform []string for k, v := range r.Platform { @@ -119,36 +133,36 @@ func (r *REParams) Template() string { } if platform != nil { sort.Strings(platform) - template += " --platform=\"" + strings.Join(platform, ",") + "\"" + args += " --platform=\"" + strings.Join(platform, ",") + "\"" } strategy := r.ExecStrategy if strategy == "" { strategy = defaultExecStrategy } - template += " --exec_strategy=" + strategy + args += " --exec_strategy=" + strategy if len(r.Inputs) > 0 { - template += " --inputs=" + strings.Join(r.Inputs, ",") + args += " --inputs=" + strings.Join(r.Inputs, ",") } if r.RSPFile != "" { - template += " --input_list_paths=" + r.RSPFile + args += " --input_list_paths=" + r.RSPFile } if len(r.OutputFiles) > 0 { - template += " --output_files=" + strings.Join(r.OutputFiles, ",") + args += " --output_files=" + strings.Join(r.OutputFiles, ",") } if len(r.OutputDirectories) > 0 { - template += " --output_directories=" + strings.Join(r.OutputDirectories, ",") + args += " --output_directories=" + strings.Join(r.OutputDirectories, ",") } if len(r.ToolchainInputs) > 0 { - template += " --toolchain_inputs=" + strings.Join(r.ToolchainInputs, ",") + args += " --toolchain_inputs=" + strings.Join(r.ToolchainInputs, ",") } - return template + " -- " + return args + " -- " } // StaticRules returns a pair of rules based on the given RuleParams, where the first rule is a diff --git a/remoteexec/remoteexec_test.go b/remoteexec/remoteexec_test.go index 30e891ced..56985d356 100644 --- a/remoteexec/remoteexec_test.go +++ b/remoteexec/remoteexec_test.go @@ -17,6 +17,8 @@ package remoteexec import ( "fmt" "testing" + + "android/soong/android" ) func TestTemplate(t *testing.T) { @@ -64,6 +66,22 @@ func TestTemplate(t *testing.T) { } } +func TestNoVarTemplate(t *testing.T) { + params := &REParams{ + Labels: map[string]string{"type": "compile", "lang": "cpp", "compiler": "clang"}, + Inputs: []string{"$in"}, + OutputFiles: []string{"$out"}, + Platform: map[string]string{ + ContainerImageKey: DefaultImage, + PoolKey: "default", + }, + } + want := fmt.Sprintf("prebuilts/remoteexecution-client/live/rewrapper --labels=compiler=clang,lang=cpp,type=compile --platform=\"Pool=default,container-image=%s\" --exec_strategy=local --inputs=$in --output_files=$out -- ", DefaultImage) + if got := params.NoVarTemplate(android.NullConfig("")); got != want { + t.Errorf("NoVarTemplate() returned\n%s\nwant\n%s", got, want) + } +} + func TestTemplateDeterminism(t *testing.T) { r := &REParams{ Labels: map[string]string{"type": "compile", "lang": "cpp", "compiler": "clang"}, -- cgit v1.2.3-59-g8ed1b From 46bad760ec1947e7695b7acfaaf20bc5bf83d311 Mon Sep 17 00:00:00 2001 From: Ramy Medhat Date: Mon, 11 May 2020 16:49:37 -0400 Subject: Add sourcepath to inputs of remoteable metalava action. Bug: b/156613606 Test: presubmit Change-Id: Idd77abddac0a676302226eb62883c74d5d7489af Merged-In: Idd77abddac0a676302226eb62883c74d5d7489af --- java/droiddoc.go | 1 + 1 file changed, 1 insertion(+) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 4d806baef..6d2a453e4 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1414,6 +1414,7 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi pool = v } inputs := []string{android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "metalava.jar").String()} + inputs = append(inputs, sourcepaths.Strings()...) if v := ctx.Config().Getenv("RBE_METALAVA_INPUTS"); v != "" { inputs = append(inputs, strings.Split(v, ",")...) } -- cgit v1.2.3-59-g8ed1b From 8e9b63b6ffaa2b38080a1500359ee18b31dd3999 Mon Sep 17 00:00:00 2001 From: Ramy Medhat Date: Thu, 30 Apr 2020 03:08:37 -0400 Subject: Add support for Metalava implicit dependencies for remote execution. Bug: b/156613606 Test: built aosp crosshatch userdebug with RBE_METALAVA=1 Change-Id: Ic64d98785e34717ef9bdad62b4885085f84f132a Merged-In: Ic64d98785e34717ef9bdad62b4885085f84f132a --- java/droiddoc.go | 41 +++++++++++++++++++++++++++++++++++++++-- java/java_test.go | 2 +- remoteexec/remoteexec.go | 6 +++--- 3 files changed, 43 insertions(+), 6 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 6d2a453e4..330a4a6f6 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -376,6 +376,7 @@ type Javadoc struct { srcFiles android.Paths sourcepaths android.Paths argFiles android.Paths + implicits android.Paths args string @@ -575,6 +576,7 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs // may contain filegroup or genrule. srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs) + j.implicits = append(j.implicits, srcFiles...) filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path { if filterPackages == nil { @@ -600,6 +602,24 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { } srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages) + // While metalava needs package html files, it does not need them to be explicit on the command + // line. More importantly, the metalava rsp file is also used by the subsequent jdiff action if + // jdiff_enabled=true. javadoc complains if it receives html files on the command line. The filter + // below excludes html files from the rsp file for both metalava and jdiff. Note that the html + // files are still included as implicit inputs for successful remote execution and correct + // incremental builds. + filterHtml := func(srcs []android.Path) []android.Path { + filtered := []android.Path{} + for _, src := range srcs { + if src.Ext() == ".html" { + continue + } + filtered = append(filtered, src) + } + return filtered + } + srcFiles = filterHtml(srcFiles) + flags := j.collectAidlFlags(ctx, deps) srcFiles = j.genSources(ctx, srcFiles, flags) @@ -1399,10 +1419,26 @@ func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleB } func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths, - srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand { + srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths, implicits android.Paths) *android.RuleBuilderCommand { // Metalava uses lots of memory, restrict the number of metalava jobs that can run in parallel. rule.HighMem() cmd := rule.Command() + + rspFile := "" + if len(implicits) > 0 { + implicitsRsp := android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"implicits.rsp") + rspFile = implicitsRsp.String() + impRule := android.NewRuleBuilder() + impCmd := impRule.Command() + // A dummy action that copies the ninja generated rsp file to a new location. This allows us to + // add a large number of inputs to a file without exceeding bash command length limits (which + // would happen if we use the WriteFile rule). The cp is needed because RuleBuilder sets the + // rsp file to be ${output}.rsp. + impCmd.Text("cp").FlagWithRspFileInputList("", implicits).Output(implicitsRsp) + impRule.Build(pctx, ctx, "implicitsGen", "implicits generation") + cmd.Implicits(implicits) + cmd.Implicit(implicitsRsp) + } if ctx.Config().IsEnvTrue("RBE_METALAVA") { rule.Remoteable(android.RemoteRuleSupports{RBE: true}) execStrategy := remoteexec.LocalExecStrategy @@ -1422,6 +1458,7 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi Labels: map[string]string{"type": "compile", "lang": "java", "compiler": "metalava"}, ExecStrategy: execStrategy, Inputs: inputs, + RSPFile: rspFile, ToolchainInputs: []string{config.JavaCmd(ctx).String()}, Platform: map[string]string{remoteexec.PoolKey: pool}, }).NoVarTemplate(ctx.Config())) @@ -1479,7 +1516,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars) cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList, - deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths) + deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths, d.Javadoc.implicits) d.stubsFlags(ctx, cmd, stubsDir) diff --git a/java/java_test.go b/java/java_test.go index bb3ecb60a..99f67ae74 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -1038,7 +1038,7 @@ func checkSystemModulesUseByDroidstubs(t *testing.T, ctx *android.TestContext, m for _, i := range metalavaRule.Implicits { systemJars = append(systemJars, i.Base()) } - if len(systemJars) != 1 || systemJars[0] != systemJar { + if len(systemJars) < 1 || systemJars[0] != systemJar { t.Errorf("inputs of %q must be []string{%q}, but was %#v.", moduleName, systemJar, systemJars) } } diff --git a/remoteexec/remoteexec.go b/remoteexec/remoteexec.go index d69fe1cc0..d6e2c0a75 100644 --- a/remoteexec/remoteexec.go +++ b/remoteexec/remoteexec.go @@ -75,8 +75,8 @@ type REParams struct { // OutputFiles is a list of output file paths or ninja variables as placeholders for rule // outputs. OutputFiles []string - // OutputDirectories is a list of output directory paths or ninja variables as placeholders - // for rule outputs. + // OutputDirectories is a list of output directories or ninja variables as placeholders for + // rule output directories. OutputDirectories []string // ToolchainInputs is a list of paths or ninja variables pointing to the location of // toolchain binaries used by the rule. @@ -102,7 +102,7 @@ func (r *REParams) Template() string { return "${remoteexec.Wrapper}" + r.wrapperArgs() } -// NoVarTemplate generate the remote execution wrapper template without variables, to be used in +// NoVarTemplate generates the remote execution wrapper template without variables, to be used in // RuleBuilder. func (r *REParams) NoVarTemplate(cfg android.Config) string { return wrapper(cfg) + r.wrapperArgs() -- cgit v1.2.3-59-g8ed1b From 7f2006c091fcc708f0952a4433de488ac3bc46c4 Mon Sep 17 00:00:00 2001 From: Ramy Medhat Date: Thu, 4 Jun 2020 01:54:07 -0400 Subject: Turn on metalava sandbox warning in all droiddoc metalava invocations. Bug: b/156613606 Test: built aosp crosshatch userdebug with RBE_METALAVA=1 and dependency file support. Change-Id: I5ca637984429df12fe05bb07f5db154be9b24f97 Merged-In: I5ca637984429df12fe05bb07f5db154be9b24f97 --- java/droiddoc.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 330a4a6f6..6e986505e 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1424,10 +1424,9 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi rule.HighMem() cmd := rule.Command() - rspFile := "" + var implicitsRsp android.WritablePath if len(implicits) > 0 { - implicitsRsp := android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"implicits.rsp") - rspFile = implicitsRsp.String() + implicitsRsp = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"implicits.rsp") impRule := android.NewRuleBuilder() impCmd := impRule.Command() // A dummy action that copies the ninja generated rsp file to a new location. This allows us to @@ -1455,10 +1454,10 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi inputs = append(inputs, strings.Split(v, ",")...) } cmd.Text((&remoteexec.REParams{ - Labels: map[string]string{"type": "compile", "lang": "java", "compiler": "metalava"}, + Labels: map[string]string{"type": "compile", "lang": "java", "compiler": "metalava", "shallow": "true"}, ExecStrategy: execStrategy, Inputs: inputs, - RSPFile: rspFile, + RSPFile: implicitsRsp.String(), ToolchainInputs: []string{config.JavaCmd(ctx).String()}, Platform: map[string]string{remoteexec.PoolKey: pool}, }).NoVarTemplate(ctx.Config())) @@ -1469,7 +1468,12 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi FlagWithArg("-encoding ", "UTF-8"). FlagWithArg("-source ", javaVersion.String()). FlagWithRspFileInputList("@", srcs). - FlagWithInput("@", srcJarList) + FlagWithInput("@", srcJarList). + FlagWithOutput("--strict-input-files:warn ", android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"violations.txt")) + + if implicitsRsp.String() != "" { + cmd.FlagWithArg("--strict-input-files-exempt ", "@"+implicitsRsp.String()) + } if len(bootclasspath) > 0 { cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":") -- cgit v1.2.3-59-g8ed1b From f5f663b0c392a0a0ed3b9872bb0b3d3b2bb47fba Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Sun, 7 Jun 2020 16:58:18 -0700 Subject: Remove most paths from java.TestConfig Now that tests don't need to specify every path passed to PathForSource or PathForModuleSrc, remove most of them from java.TestConfig. Leave a few that are globbed by lots of tests, and move a few that are globbed by a single test into the tests. Bug: 153485543 Test: all soong tests Change-Id: Ica91d7203a6a7dbca0fd4fed84c78f149b8699e1 Merged-In: Ica91d7203a6a7dbca0fd4fed84c78f149b8699e1 (cherry picked from commit 238c1f3903eef027c7f1f9448bb6bcc6d4c669cd) --- java/app_test.go | 9 +++++++-- java/droiddoc.go | 2 +- java/java_test.go | 46 +++++++++++++++++++++++++++++++----------- java/testing.go | 60 ------------------------------------------------------- 4 files changed, 42 insertions(+), 75 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/app_test.go b/java/app_test.go index 1123d84d9..4d47496d2 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -2719,7 +2719,7 @@ func TestCodelessApp(t *testing.T) { } func TestEmbedNotice(t *testing.T) { - ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` + ctx, _ := testJavaWithFS(t, cc.GatherRequiredDepsForTest(android.Android)+` android_app { name: "foo", srcs: ["a.java"], @@ -2775,7 +2775,12 @@ func TestEmbedNotice(t *testing.T) { srcs: ["b.java"], notice: "TOOL_NOTICE", } - `) + `, map[string][]byte{ + "APP_NOTICE": nil, + "GENRULE_NOTICE": nil, + "LIB_NOTICE": nil, + "TOOL_NOTICE": nil, + }) // foo has NOTICE files to process, and embed_notices is true. foo := ctx.ModuleForTests("foo", "android_common") diff --git a/java/droiddoc.go b/java/droiddoc.go index 6e986505e..8db688fec 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1471,7 +1471,7 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi FlagWithInput("@", srcJarList). FlagWithOutput("--strict-input-files:warn ", android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"violations.txt")) - if implicitsRsp.String() != "" { + if implicitsRsp != nil { cmd.FlagWithArg("--strict-input-files-exempt ", "@"+implicitsRsp.String()) } diff --git a/java/java_test.go b/java/java_test.go index 99f67ae74..f0de52fb9 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -142,9 +142,14 @@ func testJavaErrorWithConfig(t *testing.T, pattern string, config android.Config return ctx, config } +func testJavaWithFS(t *testing.T, bp string, fs map[string][]byte) (*android.TestContext, android.Config) { + t.Helper() + return testJavaWithConfig(t, testConfig(nil, bp, fs)) +} + func testJava(t *testing.T, bp string) (*android.TestContext, android.Config) { t.Helper() - return testJavaWithConfig(t, testConfig(nil, bp, nil)) + return testJavaWithFS(t, bp, nil) } func testJavaWithConfig(t *testing.T, config android.Config) (*android.TestContext, android.Config) { @@ -740,7 +745,7 @@ func TestResources(t *testing.T) { for _, test := range table { t.Run(test.name, func(t *testing.T) { - ctx, _ := testJava(t, ` + ctx, _ := testJavaWithFS(t, ` java_library { name: "foo", srcs: [ @@ -750,7 +755,13 @@ func TestResources(t *testing.T) { ], `+test.prop+`, } - `+test.extra) + `+test.extra, + map[string][]byte{ + "java-res/a/a": nil, + "java-res/b/b": nil, + "java-res2/a": nil, + }, + ) foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar") fooRes := ctx.ModuleForTests("foo", "android_common").Output("res/foo.jar") @@ -769,7 +780,7 @@ func TestResources(t *testing.T) { } func TestIncludeSrcs(t *testing.T) { - ctx, _ := testJava(t, ` + ctx, _ := testJavaWithFS(t, ` java_library { name: "foo", srcs: [ @@ -790,7 +801,11 @@ func TestIncludeSrcs(t *testing.T) { java_resource_dirs: ["java-res"], include_srcs: true, } - `) + `, map[string][]byte{ + "java-res/a/a": nil, + "java-res/b/b": nil, + "java-res2/a": nil, + }) // Test a library with include_srcs: true foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar") @@ -832,7 +847,7 @@ func TestIncludeSrcs(t *testing.T) { } func TestGeneratedSources(t *testing.T) { - ctx, _ := testJava(t, ` + ctx, _ := testJavaWithFS(t, ` java_library { name: "foo", srcs: [ @@ -847,7 +862,10 @@ func TestGeneratedSources(t *testing.T) { tool_files: ["java-res/a"], out: ["gen.java"], } - `) + `, map[string][]byte{ + "a.java": nil, + "b.java": nil, + }) javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") genrule := ctx.ModuleForTests("gen", "").Rule("generator") @@ -932,7 +950,7 @@ func TestSharding(t *testing.T) { } func TestDroiddoc(t *testing.T) { - ctx, _ := testJava(t, ` + ctx, _ := testJavaWithFS(t, ` droiddoc_exported_dir { name: "droiddoc-templates-sdk", path: ".", @@ -945,7 +963,7 @@ func TestDroiddoc(t *testing.T) { droiddoc { name: "bar-doc", srcs: [ - "bar-doc/*.java", + "bar-doc/a.java", "bar-doc/IFoo.aidl", ":bar-doc-aidl-srcs", ], @@ -963,7 +981,11 @@ func TestDroiddoc(t *testing.T) { todo_file: "libcore-docs-todo.html", args: "-offlinemode -title \"libcore\"", } - `) + `, + map[string][]byte{ + "bar-doc/a.java": nil, + "bar-doc/b.java": nil, + }) barDoc := ctx.ModuleForTests("bar-doc", "android_common").Rule("javadoc") var javaSrcs []string @@ -989,7 +1011,7 @@ func TestDroidstubsWithSystemModules(t *testing.T) { droidstubs { name: "stubs-source-system-modules", srcs: [ - "bar-doc/*.java", + "bar-doc/a.java", ], sdk_version: "none", system_modules: "source-system-modules", @@ -1010,7 +1032,7 @@ func TestDroidstubsWithSystemModules(t *testing.T) { droidstubs { name: "stubs-prebuilt-system-modules", srcs: [ - "bar-doc/*.java", + "bar-doc/a.java", ], sdk_version: "none", system_modules: "prebuilt-system-modules", diff --git a/java/testing.go b/java/testing.go index 552055efd..48e449f34 100644 --- a/java/testing.go +++ b/java/testing.go @@ -25,33 +25,12 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string bp += GatherRequiredDepsForTest() mockFS := map[string][]byte{ - "a.java": nil, - "b.java": nil, - "c.java": nil, - "b.kt": nil, - "a.jar": nil, - "b.jar": nil, - "c.jar": nil, - "APP_NOTICE": nil, - "GENRULE_NOTICE": nil, - "LIB_NOTICE": nil, - "TOOL_NOTICE": nil, - "AndroidTest.xml": nil, - "java-res/a/a": nil, - "java-res/b/b": nil, - "java-res2/a": nil, - "java-fg/a.java": nil, - "java-fg/b.java": nil, - "java-fg/c.java": nil, "api/current.txt": nil, "api/removed.txt": nil, "api/system-current.txt": nil, "api/system-removed.txt": nil, "api/test-current.txt": nil, "api/test-removed.txt": nil, - "framework/aidl/a.aidl": nil, - "assets_a/a": nil, - "assets_b/b": nil, "prebuilts/sdk/14/public/android.jar": nil, "prebuilts/sdk/14/public/framework.aidl": nil, @@ -102,45 +81,6 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string "prebuilts/sdk/tools/core-lambda-stubs.jar": nil, "prebuilts/sdk/Android.bp": []byte(`prebuilt_apis { name: "sdk", api_dirs: ["14", "28", "30", "current"],}`), - "prebuilts/apk/app.apk": nil, - "prebuilts/apk/app_arm.apk": nil, - "prebuilts/apk/app_arm64.apk": nil, - "prebuilts/apk/app_xhdpi.apk": nil, - "prebuilts/apk/app_xxhdpi.apk": nil, - - "prebuilts/apks/app.apks": nil, - - // For framework-res, which is an implicit dependency for framework - "AndroidManifest.xml": nil, - "build/make/target/product/security/testkey": nil, - - "build/soong/scripts/jar-wrapper.sh": nil, - - "build/make/core/verify_uses_libraries.sh": nil, - - "build/make/core/proguard.flags": nil, - "build/make/core/proguard_basic_keeps.flags": nil, - - "jdk8/jre/lib/jce.jar": nil, - "jdk8/jre/lib/rt.jar": nil, - "jdk8/lib/tools.jar": nil, - - "bar-doc/a.java": nil, - "bar-doc/b.java": nil, - "bar-doc/IFoo.aidl": nil, - "bar-doc/IBar.aidl": nil, - "bar-doc/known_oj_tags.txt": nil, - "external/doclava/templates-sdk": nil, - - "cert/new_cert.x509.pem": nil, - "cert/new_cert.pk8": nil, - "lineage.bin": nil, - - "testdata/data": nil, - - "stubs-sources/foo/Foo.java": nil, - "stubs/sources/foo/Foo.java": nil, - // For java_sdk_library "api/module-lib-current.txt": nil, "api/module-lib-removed.txt": nil, -- cgit v1.2.3-59-g8ed1b From 1e28e3c61593571db5ecea328d134ee50501104d Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 2 Jun 2020 20:09:13 -0700 Subject: Add support for running Android lint on java and android modules. Add a rule that runs Android lint on each java and android module and produces reports in xml, html and text formats. Bug: 153485543 Test: m out/soong/.intermediates/packages/apps/Settings/Settings-core/android_common/lint-report.html Change-Id: I5a530975b73ba767fef45b257d4f9ec901a19fcb Merged-In: I5a530975b73ba767fef45b257d4f9ec901a19fcb (cherry picked from commit 014489c1e6cbd2801970b88d5b608dc5c45b403c) --- java/Android.bp | 1 + java/aar.go | 7 + java/app.go | 6 + java/droiddoc.go | 15 ++ java/java.go | 27 ++++ java/lint.go | 355 ++++++++++++++++++++++++++++++++++++++++++++ java/lint_defaults.txt | 78 ++++++++++ java/robolectric.go | 1 + java/sdk_library.go | 1 + scripts/Android.bp | 6 + scripts/lint-project-xml.py | 213 ++++++++++++++++++++++++++ 11 files changed, 710 insertions(+) create mode 100644 java/lint.go create mode 100644 java/lint_defaults.txt create mode 100755 scripts/lint-project-xml.py (limited to 'java/droiddoc.go') diff --git a/java/Android.bp b/java/Android.bp index 2de1b8ea1..1fda7f71d 100644 --- a/java/Android.bp +++ b/java/Android.bp @@ -37,6 +37,7 @@ bootstrap_go_package { "jdeps.go", "java_resources.go", "kotlin.go", + "lint.go", "platform_compat_config.go", "plugin.go", "prebuilt_apis.go", diff --git a/java/aar.go b/java/aar.go index 66a1c53bf..53b50d60d 100644 --- a/java/aar.go +++ b/java/aar.go @@ -102,6 +102,7 @@ type aapt struct { sdkLibraries []string hasNoCode bool LoggingParent string + resourceFiles android.Paths splitNames []string splits []split @@ -275,6 +276,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex var compiledResDirs []android.Paths for _, dir := range resDirs { + a.resourceFiles = append(a.resourceFiles, dir.files...) compiledResDirs = append(compiledResDirs, aapt2Compile(ctx, dir.dir, dir.files, compileFlags).Paths()) } @@ -473,6 +475,10 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) // apps manifests are handled by aapt, don't let Module see them a.properties.Manifest = nil + a.linter.mergedManifest = a.aapt.mergedManifestFile + a.linter.manifest = a.aapt.manifestPath + a.linter.resources = a.aapt.resourceFiles + a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, a.proguardOptionsFile) @@ -512,6 +518,7 @@ func AndroidLibraryFactory() android.Module { &module.androidLibraryProperties) module.androidLibraryProperties.BuildAAR = true + module.Module.linter.library = true android.InitApexModule(module) InitJavaModule(module, android.DeviceSupported) diff --git a/java/app.go b/java/app.go index 6aaae0786..245c586e1 100755 --- a/java/app.go +++ b/java/app.go @@ -737,6 +737,10 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { a.proguardBuildActions(ctx) + a.linter.mergedManifest = a.aapt.mergedManifestFile + a.linter.manifest = a.aapt.manifestPath + a.linter.resources = a.aapt.resourceFiles + dexJarFile := a.dexBuildActions(ctx) jniLibs, certificateDeps := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis)) @@ -1089,6 +1093,7 @@ func AndroidTestFactory() android.Module { module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true) module.appProperties.AlwaysPackageNativeLibs = true module.Module.dexpreopter.isTest = true + module.Module.linter.test = true module.addHostAndDeviceProperties() module.AddProperties( @@ -1138,6 +1143,7 @@ func AndroidTestHelperAppFactory() android.Module { module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true) module.appProperties.AlwaysPackageNativeLibs = true module.Module.dexpreopter.isTest = true + module.Module.linter.test = true module.addHostAndDeviceProperties() module.AddProperties( diff --git a/java/droiddoc.go b/java/droiddoc.go index 8db688fec..39cadebf1 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1224,6 +1224,21 @@ func DroidstubsHostFactory() android.Module { return module } +func (d *Droidstubs) OutputFiles(tag string) (android.Paths, error) { + switch tag { + case "": + return android.Paths{d.stubsSrcJar}, nil + case ".docs.zip": + return android.Paths{d.docZip}, nil + case ".annotations.zip": + return android.Paths{d.annotationsZip}, nil + case ".api_versions.xml": + return android.Paths{d.apiVersionsXml}, nil + default: + return nil, fmt.Errorf("unsupported module reference tag %q", tag) + } +} + func (d *Droidstubs) ApiFilePath() android.Path { return d.apiFilePath } diff --git a/java/java.go b/java/java.go index c80eef97f..0c0c659e9 100644 --- a/java/java.go +++ b/java/java.go @@ -475,6 +475,7 @@ type Module struct { hiddenAPI dexpreopter + linter // list of the xref extraction files kytheFiles android.Paths @@ -494,6 +495,7 @@ func (j *Module) addHostAndDeviceProperties() { j.AddProperties( &j.deviceProperties, &j.dexpreoptProperties, + &j.linter.properties, ) } @@ -1635,6 +1637,28 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { outputFile = implementationAndResourcesJar } + if ctx.Device() { + lintSDKVersionString := func(sdkSpec sdkSpec) string { + if v := sdkSpec.version; v.isNumbered() { + return v.String() + } else { + return ctx.Config().DefaultAppTargetSdk() + } + } + + j.linter.name = ctx.ModuleName() + j.linter.srcs = srcFiles + j.linter.srcJars = srcJars + j.linter.classpath = append(append(android.Paths(nil), flags.bootClasspath...), flags.classpath...) + j.linter.classes = j.implementationJarFile + j.linter.minSdkVersion = lintSDKVersionString(j.minSdkVersion()) + j.linter.targetSdkVersion = lintSDKVersionString(j.targetSdkVersion()) + j.linter.compileSdkVersion = lintSDKVersionString(j.sdkVersion()) + j.linter.javaLanguageLevel = flags.javaVersion.String() + j.linter.kotlinLanguageLevel = "1.3" + j.linter.lint(ctx) + } + ctx.CheckbuildFile(outputFile) // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource @@ -2235,6 +2259,7 @@ func TestFactory() android.Module { module.Module.properties.Installable = proptools.BoolPtr(true) module.Module.dexpreopter.isTest = true + module.Module.linter.test = true InitJavaModule(module, android.HostAndDeviceSupported) return module @@ -2249,6 +2274,7 @@ func TestHelperLibraryFactory() android.Module { module.Module.properties.Installable = proptools.BoolPtr(true) module.Module.dexpreopter.isTest = true + module.Module.linter.test = true InitJavaModule(module, android.HostAndDeviceSupported) return module @@ -2823,6 +2849,7 @@ func DefaultsFactory() android.Module { &DexImportProperties{}, &android.ApexProperties{}, &RuntimeResourceOverlayProperties{}, + &LintProperties{}, ) android.InitDefaultsModule(module) diff --git a/java/lint.go b/java/lint.go new file mode 100644 index 000000000..441e110cd --- /dev/null +++ b/java/lint.go @@ -0,0 +1,355 @@ +// Copyright 2020 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package java + +import ( + "fmt" + "sort" + + "android/soong/android" +) + +type LintProperties struct { + // Controls for running Android Lint on the module. + Lint struct { + + // If true, run Android Lint on the module. Defaults to true. + Enabled *bool + + // Flags to pass to the Android Lint tool. + Flags []string + + // Checks that should be treated as fatal. + Fatal_checks []string + + // Checks that should be treated as errors. + Error_checks []string + + // Checks that should be treated as warnings. + Warning_checks []string + + // Checks that should be skipped. + Disabled_checks []string + } +} + +type linter struct { + name string + manifest android.Path + mergedManifest android.Path + srcs android.Paths + srcJars android.Paths + resources android.Paths + classpath android.Paths + classes android.Path + extraLintCheckJars android.Paths + test bool + library bool + minSdkVersion string + targetSdkVersion string + compileSdkVersion string + javaLanguageLevel string + kotlinLanguageLevel string + outputs lintOutputs + properties LintProperties +} + +type lintOutputs struct { + html android.ModuleOutPath + text android.ModuleOutPath + xml android.ModuleOutPath +} + +func (l *linter) enabled() bool { + return BoolDefault(l.properties.Lint.Enabled, true) +} + +func (l *linter) writeLintProjectXML(ctx android.ModuleContext, + rule *android.RuleBuilder) (projectXMLPath, configXMLPath, cacheDir android.WritablePath, deps android.Paths) { + + var resourcesList android.WritablePath + if len(l.resources) > 0 { + // The list of resources may be too long to put on the command line, but + // we can't use the rsp file because it is already being used for srcs. + // Insert a second rule to write out the list of resources to a file. + resourcesList = android.PathForModuleOut(ctx, "lint", "resources.list") + resListRule := android.NewRuleBuilder() + resListRule.Command().Text("cp").FlagWithRspFileInputList("", l.resources).Output(resourcesList) + resListRule.Build(pctx, ctx, "lint_resources_list", "lint resources list") + deps = append(deps, l.resources...) + } + + projectXMLPath = android.PathForModuleOut(ctx, "lint", "project.xml") + // Lint looks for a lint.xml file next to the project.xml file, give it one. + configXMLPath = android.PathForModuleOut(ctx, "lint", "lint.xml") + cacheDir = android.PathForModuleOut(ctx, "lint", "cache") + + srcJarDir := android.PathForModuleOut(ctx, "lint-srcjars") + srcJarList := zipSyncCmd(ctx, rule, srcJarDir, l.srcJars) + + cmd := rule.Command(). + BuiltTool(ctx, "lint-project-xml"). + FlagWithOutput("--project_out ", projectXMLPath). + FlagWithOutput("--config_out ", configXMLPath). + FlagWithArg("--name ", ctx.ModuleName()) + + if l.library { + cmd.Flag("--library") + } + if l.test { + cmd.Flag("--test") + } + if l.manifest != nil { + deps = append(deps, l.manifest) + cmd.FlagWithArg("--manifest ", l.manifest.String()) + } + if l.mergedManifest != nil { + deps = append(deps, l.mergedManifest) + cmd.FlagWithArg("--merged_manifest ", l.mergedManifest.String()) + } + + // TODO(ccross): some of the files in l.srcs are generated sources and should be passed to + // lint separately. + cmd.FlagWithRspFileInputList("--srcs ", l.srcs) + deps = append(deps, l.srcs...) + + cmd.FlagWithInput("--generated_srcs ", srcJarList) + deps = append(deps, l.srcJars...) + + if resourcesList != nil { + cmd.FlagWithInput("--resources ", resourcesList) + } + + if l.classes != nil { + deps = append(deps, l.classes) + cmd.FlagWithArg("--classes ", l.classes.String()) + } + + cmd.FlagForEachArg("--classpath ", l.classpath.Strings()) + deps = append(deps, l.classpath...) + + cmd.FlagForEachArg("--extra_checks_jar ", l.extraLintCheckJars.Strings()) + deps = append(deps, l.extraLintCheckJars...) + + // The cache tag in project.xml is relative to the project.xml file. + cmd.FlagWithArg("--cache_dir ", "cache") + + cmd.FlagWithInput("@", + android.PathForSource(ctx, "build/soong/java/lint_defaults.txt")) + + cmd.FlagForEachArg("--disable_check ", l.properties.Lint.Disabled_checks) + cmd.FlagForEachArg("--warning_check ", l.properties.Lint.Warning_checks) + cmd.FlagForEachArg("--error_check ", l.properties.Lint.Error_checks) + cmd.FlagForEachArg("--fatal_check ", l.properties.Lint.Fatal_checks) + + return projectXMLPath, configXMLPath, cacheDir, deps +} + +// generateManifest adds a command to the rule to write a dummy manifest cat contains the +// minSdkVersion and targetSdkVersion for modules (like java_library) that don't have a manifest. +func (l *linter) generateManifest(ctx android.ModuleContext, rule *android.RuleBuilder) android.Path { + manifestPath := android.PathForModuleOut(ctx, "lint", "AndroidManifest.xml") + + rule.Command().Text("("). + Text(`echo "" &&`). + Text(`echo "" &&`). + Textf(`echo " " &&`, + l.minSdkVersion, l.targetSdkVersion). + Text(`echo ""`). + Text(") >").Output(manifestPath) + + return manifestPath +} + +func (l *linter) lint(ctx android.ModuleContext) { + if !l.enabled() { + return + } + + rule := android.NewRuleBuilder() + + if l.manifest == nil { + manifest := l.generateManifest(ctx, rule) + l.manifest = manifest + } + + projectXML, lintXML, cacheDir, deps := l.writeLintProjectXML(ctx, rule) + + l.outputs.html = android.PathForModuleOut(ctx, "lint-report.html") + l.outputs.text = android.PathForModuleOut(ctx, "lint-report.txt") + l.outputs.xml = android.PathForModuleOut(ctx, "lint-report.xml") + + rule.Command().Text("rm -rf").Flag(cacheDir.String()) + rule.Command().Text("mkdir -p").Flag(cacheDir.String()) + + rule.Command(). + Text("("). + Flag("JAVA_OPTS=-Xmx2048m"). + FlagWithInput("SDK_ANNOTATIONS=", annotationsZipPath(ctx)). + FlagWithInput("LINT_OPTS=-DLINT_API_DATABASE=", apiVersionsXmlPath(ctx)). + Tool(android.PathForSource(ctx, "prebuilts/cmdline-tools/tools/bin/lint")). + Implicit(android.PathForSource(ctx, "prebuilts/cmdline-tools/tools/lib/lint-classpath.jar")). + Flag("--quiet"). + FlagWithInput("--project ", projectXML). + FlagWithInput("--config ", lintXML). + FlagWithOutput("--html ", l.outputs.html). + FlagWithOutput("--text ", l.outputs.text). + FlagWithOutput("--xml ", l.outputs.xml). + FlagWithArg("--compile-sdk-version ", l.compileSdkVersion). + FlagWithArg("--java-language-level ", l.javaLanguageLevel). + FlagWithArg("--kotlin-language-level ", l.kotlinLanguageLevel). + FlagWithArg("--url ", fmt.Sprintf(".=.,%s=out", android.PathForOutput(ctx).String())). + Flag("--exitcode"). + Flags(l.properties.Lint.Flags). + Implicits(deps). + Text("|| (").Text("cat").Input(l.outputs.text).Text("; exit 7)"). + Text(")") + + rule.Command().Text("rm -rf").Flag(cacheDir.String()) + + rule.Build(pctx, ctx, "lint", "lint") +} + +func (l *linter) lintOutputs() *lintOutputs { + return &l.outputs +} + +type lintOutputIntf interface { + lintOutputs() *lintOutputs +} + +var _ lintOutputIntf = (*linter)(nil) + +type lintSingleton struct { + htmlZip android.WritablePath + textZip android.WritablePath + xmlZip android.WritablePath +} + +func (l *lintSingleton) GenerateBuildActions(ctx android.SingletonContext) { + l.generateLintReportZips(ctx) + l.copyLintDependencies(ctx) +} + +func (l *lintSingleton) copyLintDependencies(ctx android.SingletonContext) { + if ctx.Config().UnbundledBuild() { + return + } + + var frameworkDocStubs android.Module + ctx.VisitAllModules(func(m android.Module) { + if ctx.ModuleName(m) == "framework-doc-stubs" { + if frameworkDocStubs == nil { + frameworkDocStubs = m + } else { + ctx.Errorf("lint: multiple framework-doc-stubs modules found: %s and %s", + ctx.ModuleSubDir(m), ctx.ModuleSubDir(frameworkDocStubs)) + } + } + }) + + if frameworkDocStubs == nil { + if !ctx.Config().AllowMissingDependencies() { + ctx.Errorf("lint: missing framework-doc-stubs") + } + return + } + + ctx.Build(pctx, android.BuildParams{ + Rule: android.Cp, + Input: android.OutputFileForModule(ctx, frameworkDocStubs, ".annotations.zip"), + Output: annotationsZipPath(ctx), + }) + + ctx.Build(pctx, android.BuildParams{ + Rule: android.Cp, + Input: android.OutputFileForModule(ctx, frameworkDocStubs, ".api_versions.xml"), + Output: apiVersionsXmlPath(ctx), + }) +} + +func annotationsZipPath(ctx android.PathContext) android.WritablePath { + return android.PathForOutput(ctx, "lint", "annotations.zip") +} + +func apiVersionsXmlPath(ctx android.PathContext) android.WritablePath { + return android.PathForOutput(ctx, "lint", "api_versions.xml") +} + +func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) { + var outputs []*lintOutputs + var dirs []string + ctx.VisitAllModules(func(m android.Module) { + if ctx.Config().EmbeddedInMake() && !m.ExportedToMake() { + return + } + + if apex, ok := m.(android.ApexModule); ok && apex.NotAvailableForPlatform() && apex.IsForPlatform() { + // There are stray platform variants of modules in apexes that are not available for + // the platform, and they sometimes can't be built. Don't depend on them. + return + } + + if l, ok := m.(lintOutputIntf); ok { + outputs = append(outputs, l.lintOutputs()) + } + }) + + dirs = android.SortedUniqueStrings(dirs) + + zip := func(outputPath android.WritablePath, get func(*lintOutputs) android.Path) { + var paths android.Paths + + for _, output := range outputs { + paths = append(paths, get(output)) + } + + sort.Slice(paths, func(i, j int) bool { + return paths[i].String() < paths[j].String() + }) + + rule := android.NewRuleBuilder() + + rule.Command().BuiltTool(ctx, "soong_zip"). + FlagWithOutput("-o ", outputPath). + FlagWithArg("-C ", android.PathForIntermediates(ctx).String()). + FlagWithRspFileInputList("-l ", paths) + + rule.Build(pctx, ctx, outputPath.Base(), outputPath.Base()) + } + + l.htmlZip = android.PathForOutput(ctx, "lint-report-html.zip") + zip(l.htmlZip, func(l *lintOutputs) android.Path { return l.html }) + + l.textZip = android.PathForOutput(ctx, "lint-report-text.zip") + zip(l.textZip, func(l *lintOutputs) android.Path { return l.text }) + + l.xmlZip = android.PathForOutput(ctx, "lint-report-xml.zip") + zip(l.xmlZip, func(l *lintOutputs) android.Path { return l.xml }) + + ctx.Phony("lint-check", l.htmlZip, l.textZip, l.xmlZip) +} + +func (l *lintSingleton) MakeVars(ctx android.MakeVarsContext) { + ctx.DistForGoal("lint-check", l.htmlZip, l.textZip, l.xmlZip) +} + +var _ android.SingletonMakeVarsProvider = (*lintSingleton)(nil) + +func init() { + android.RegisterSingletonType("lint", + func() android.Singleton { return &lintSingleton{} }) +} diff --git a/java/lint_defaults.txt b/java/lint_defaults.txt new file mode 100644 index 000000000..0786b7c00 --- /dev/null +++ b/java/lint_defaults.txt @@ -0,0 +1,78 @@ +# Treat LintError as fatal to catch invocation errors +--fatal_check LintError + +# Downgrade existing errors to warnings +--warning_check AppCompatResource # 55 occurences in 10 modules +--warning_check AppLinkUrlError # 111 occurences in 53 modules +--warning_check BlockedPrivateApi # 2 occurences in 2 modules +--warning_check ByteOrderMark # 2 occurences in 2 modules +--warning_check DuplicateActivity # 3 occurences in 3 modules +--warning_check DuplicateDefinition # 3623 occurences in 48 modules +--warning_check DuplicateIds # 207 occurences in 22 modules +--warning_check EllipsizeMaxLines # 12 occurences in 7 modules +--warning_check ExtraTranslation # 21276 occurences in 27 modules +--warning_check FontValidationError # 4 occurences in 1 modules +--warning_check FullBackupContent # 16 occurences in 1 modules +--warning_check GetContentDescriptionOverride # 3 occurences in 2 modules +--warning_check HalfFloat # 31 occurences in 1 modules +--warning_check HardcodedDebugMode # 99 occurences in 95 modules +--warning_check ImpliedQuantity # 703 occurences in 27 modules +--warning_check ImpliedTouchscreenHardware # 4 occurences in 4 modules +--warning_check IncludeLayoutParam # 11 occurences in 6 modules +--warning_check Instantiatable # 145 occurences in 19 modules +--warning_check InvalidPermission # 6 occurences in 4 modules +--warning_check InvalidUsesTagAttribute # 6 occurences in 2 modules +--warning_check InvalidWakeLockTag # 111 occurences in 37 modules +--warning_check JavascriptInterface # 3 occurences in 2 modules +--warning_check LibraryCustomView # 9 occurences in 4 modules +--warning_check LogTagMismatch # 81 occurences in 13 modules +--warning_check LongLogTag # 249 occurences in 12 modules +--warning_check MenuTitle # 5 occurences in 4 modules +--warning_check MissingClass # 537 occurences in 141 modules +--warning_check MissingConstraints # 39 occurences in 10 modules +--warning_check MissingDefaultResource # 1257 occurences in 40 modules +--warning_check MissingIntentFilterForMediaSearch # 1 occurences in 1 modules +--warning_check MissingLeanbackLauncher # 3 occurences in 3 modules +--warning_check MissingLeanbackSupport # 2 occurences in 2 modules +--warning_check MissingOnPlayFromSearch # 1 occurences in 1 modules +--warning_check MissingPermission # 2071 occurences in 150 modules +--warning_check MissingPrefix # 46 occurences in 41 modules +--warning_check MissingQuantity # 100 occurences in 1 modules +--warning_check MissingSuperCall # 121 occurences in 36 modules +--warning_check MissingTvBanner # 3 occurences in 3 modules +--warning_check NamespaceTypo # 3 occurences in 3 modules +--warning_check NetworkSecurityConfig # 46 occurences in 12 modules +--warning_check NewApi # 1996 occurences in 122 modules +--warning_check NotSibling # 15 occurences in 10 modules +--warning_check ObjectAnimatorBinding # 14 occurences in 5 modules +--warning_check OnClick # 49 occurences in 21 modules +--warning_check Orientation # 77 occurences in 19 modules +--warning_check Override # 385 occurences in 36 modules +--warning_check ParcelCreator # 23 occurences in 2 modules +--warning_check ProtectedPermissions # 2413 occurences in 381 modules +--warning_check Range # 80 occurences in 28 modules +--warning_check RecyclerView # 1 occurences in 1 modules +--warning_check ReferenceType # 4 occurences in 1 modules +--warning_check ResourceAsColor # 19 occurences in 14 modules +--warning_check RequiredSize # 52 occurences in 13 modules +--warning_check ResAuto # 3 occurences in 1 modules +--warning_check ResourceCycle # 37 occurences in 10 modules +--warning_check ResourceType # 137 occurences in 36 modules +--warning_check RestrictedApi # 28 occurences in 5 modules +--warning_check RtlCompat # 9 occurences in 6 modules +--warning_check ServiceCast # 3 occurences in 1 modules +--warning_check SoonBlockedPrivateApi # 5 occurences in 3 modules +--warning_check StringFormatInvalid # 148 occurences in 11 modules +--warning_check StringFormatMatches # 4800 occurences in 30 modules +--warning_check UnknownId # 8 occurences in 7 modules +--warning_check ValidFragment # 12 occurences in 5 modules +--warning_check ValidRestrictions # 5 occurences in 1 modules +--warning_check WebViewLayout # 3 occurences in 1 modules +--warning_check WrongCall # 21 occurences in 3 modules +--warning_check WrongConstant # 894 occurences in 126 modules +--warning_check WrongManifestParent # 10 occurences in 4 modules +--warning_check WrongThread # 14 occurences in 6 modules +--warning_check WrongViewCast # 1 occurences in 1 modules + +# TODO(b/158390965): remove this when lint doesn't crash +--disable_check HardcodedDebugMode diff --git a/java/robolectric.go b/java/robolectric.go index 64bd32570..c6b07a17e 100644 --- a/java/robolectric.go +++ b/java/robolectric.go @@ -221,6 +221,7 @@ func RobolectricTestFactory() android.Module { &module.robolectricProperties) module.Module.dexpreopter.isTest = true + module.Module.linter.test = true InitJavaModule(module, android.DeviceSupported) return module diff --git a/java/sdk_library.go b/java/sdk_library.go index a6549ea5f..8e9c0774e 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1101,6 +1101,7 @@ func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext) &module.protoProperties, &module.deviceProperties, &module.dexpreoptProperties, + &module.linter.properties, &props, module.sdkComponentPropertiesForChildLibrary(), } diff --git a/scripts/Android.bp b/scripts/Android.bp index e848b5019..1f5503051 100644 --- a/scripts/Android.bp +++ b/scripts/Android.bp @@ -148,3 +148,9 @@ python_test_host { ], test_suites: ["general-tests"], } + +python_binary_host { + name: "lint-project-xml", + main: "lint-project-xml.py", + srcs: ["lint-project-xml.py"], +} diff --git a/scripts/lint-project-xml.py b/scripts/lint-project-xml.py new file mode 100755 index 000000000..7ab4f0150 --- /dev/null +++ b/scripts/lint-project-xml.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2018 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +"""This file generates project.xml and lint.xml files used to drive the Android Lint CLI tool.""" + +import argparse + + +def check_action(check_type): + """ + Returns an action that appends a tuple of check_type and the argument to the dest. + """ + class CheckAction(argparse.Action): + def __init__(self, option_strings, dest, nargs=None, **kwargs): + if nargs is not None: + raise ValueError("nargs must be None, was %s" % nargs) + super(CheckAction, self).__init__(option_strings, dest, **kwargs) + def __call__(self, parser, namespace, values, option_string=None): + checks = getattr(namespace, self.dest, []) + checks.append((check_type, values)) + setattr(namespace, self.dest, checks) + return CheckAction + + +def parse_args(): + """Parse commandline arguments.""" + + def convert_arg_line_to_args(arg_line): + for arg in arg_line.split(): + if arg.startswith('#'): + return + if not arg.strip(): + continue + yield arg + + parser = argparse.ArgumentParser(fromfile_prefix_chars='@') + parser.convert_arg_line_to_args = convert_arg_line_to_args + parser.add_argument('--project_out', dest='project_out', + help='file to which the project.xml contents will be written.') + parser.add_argument('--config_out', dest='config_out', + help='file to which the lint.xml contents will be written.') + parser.add_argument('--name', dest='name', + help='name of the module.') + parser.add_argument('--srcs', dest='srcs', action='append', default=[], + help='file containing whitespace separated list of source files.') + parser.add_argument('--generated_srcs', dest='generated_srcs', action='append', default=[], + help='file containing whitespace separated list of generated source files.') + parser.add_argument('--resources', dest='resources', action='append', default=[], + help='file containing whitespace separated list of resource files.') + parser.add_argument('--classes', dest='classes', action='append', default=[], + help='file containing the module\'s classes.') + parser.add_argument('--classpath', dest='classpath', action='append', default=[], + help='file containing classes from dependencies.') + parser.add_argument('--extra_checks_jar', dest='extra_checks_jars', action='append', default=[], + help='file containing extra lint checks.') + parser.add_argument('--manifest', dest='manifest', + help='file containing the module\'s manifest.') + parser.add_argument('--merged_manifest', dest='merged_manifest', + help='file containing merged manifest for the module and its dependencies.') + parser.add_argument('--library', dest='library', action='store_true', + help='mark the module as a library.') + parser.add_argument('--test', dest='test', action='store_true', + help='mark the module as a test.') + parser.add_argument('--cache_dir', dest='cache_dir', + help='directory to use for cached file.') + group = parser.add_argument_group('check arguments', 'later arguments override earlier ones.') + group.add_argument('--fatal_check', dest='checks', action=check_action('fatal'), default=[], + help='treat a lint issue as a fatal error.') + group.add_argument('--error_check', dest='checks', action=check_action('error'), default=[], + help='treat a lint issue as an error.') + group.add_argument('--warning_check', dest='checks', action=check_action('warning'), default=[], + help='treat a lint issue as a warning.') + group.add_argument('--disable_check', dest='checks', action=check_action('ignore'), default=[], + help='disable a lint issue.') + return parser.parse_args() + + +class NinjaRspFileReader: + """ + Reads entries from a Ninja rsp file. Ninja escapes any entries in the file that contain a + non-standard character by surrounding the whole entry with single quotes, and then replacing + any single quotes in the entry with the escape sequence '\''. + """ + + def __init__(self, filename): + self.f = open(filename, 'r') + self.r = self.character_reader(self.f) + + def __iter__(self): + return self + + def character_reader(self, f): + """Turns a file into a generator that returns one character at a time.""" + while True: + c = f.read(1) + if c: + yield c + else: + return + + def __next__(self): + entry = self.read_entry() + if entry: + return entry + else: + raise StopIteration + + def read_entry(self): + c = next(self.r, "") + if not c: + return "" + elif c == "'": + return self.read_quoted_entry() + else: + entry = c + for c in self.r: + if c == " " or c == "\n": + break + entry += c + return entry + + def read_quoted_entry(self): + entry = "" + for c in self.r: + if c == "'": + # Either the end of the quoted entry, or the beginning of an escape sequence, read the next + # character to find out. + c = next(self.r) + if not c or c == " " or c == "\n": + # End of the item + return entry + elif c == "\\": + # Escape sequence, expect a ' + c = next(self.r) + if c != "'": + # Malformed escape sequence + raise "malformed escape sequence %s'\\%s" % (entry, c) + entry += "'" + else: + raise "malformed escape sequence %s'%s" % (entry, c) + else: + entry += c + raise "unterminated quoted entry %s" % entry + + +def write_project_xml(f, args): + test_attr = "test='true' " if args.test else "" + + f.write("\n") + f.write("\n") + f.write(" \n" % (args.name, "library='true' " if args.library else "")) + if args.manifest: + f.write(" \n" % (args.manifest, test_attr)) + if args.merged_manifest: + f.write(" \n" % (args.merged_manifest, test_attr)) + for src_file in args.srcs: + for src in NinjaRspFileReader(src_file): + f.write(" \n" % (src, test_attr)) + for src_file in args.generated_srcs: + for src in NinjaRspFileReader(src_file): + f.write(" \n" % (src, test_attr)) + for res_file in args.resources: + for res in NinjaRspFileReader(res_file): + f.write(" \n" % (res, test_attr)) + for classes in args.classes: + f.write(" \n" % classes) + for classpath in args.classpath: + f.write(" \n" % classpath) + for extra in args.extra_checks_jars: + f.write(" \n" % extra) + f.write(" \n") + if args.cache_dir: + f.write(" \n" % args.cache_dir) + f.write("\n") + + +def write_config_xml(f, args): + f.write("\n") + f.write("\n") + for check in args.checks: + f.write(" \n" % (check[1], check[0])) + f.write("\n") + + +def main(): + """Program entry point.""" + args = parse_args() + + if args.project_out: + with open(args.project_out, 'w') as f: + write_project_xml(f, args) + + if args.config_out: + with open(args.config_out, 'w') as f: + write_config_xml(f, args) + + +if __name__ == '__main__': + main() -- cgit v1.2.3-59-g8ed1b From 86672f6f4e7277f7d6b6a5c15021f4c00cf5baed Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Fri, 19 Jun 2020 18:39:55 +0100 Subject: Fix build breakages when WITHOUT_CHECK_API=true Bug: 158578354 Test: export WITHOUT_CHECK_API=true m checkbuild Change-Id: I7b5fff40b870c9d754f779ff1c3314bac7e42440 --- java/droiddoc.go | 22 ++++++++++++++-------- java/sdk_library.go | 8 ++++++-- 2 files changed, 20 insertions(+), 10 deletions(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 8db688fec..6a5f28910 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1399,7 +1399,7 @@ func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *a } func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) { - if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() { + if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() && d.apiFile != nil { if d.apiFile.String() == "" { ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.") } @@ -1830,13 +1830,19 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { Flag("-XDignore.symbol.file"). FlagWithArg("-doclet ", "jdiff.JDiff"). FlagWithInput("-docletpath ", jdiff). - Flag("-quiet"). - FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())). - FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())). - Implicit(d.apiXmlFile). - FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())). - FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())). - Implicit(d.lastReleasedApiXmlFile) + Flag("-quiet") + + if d.apiXmlFile != nil { + cmd.FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())). + FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())). + Implicit(d.apiXmlFile) + } + + if d.lastReleasedApiXmlFile != nil { + cmd.FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())). + FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())). + Implicit(d.lastReleasedApiXmlFile) + } rule.Command(). BuiltTool(ctx, "soong_zip"). diff --git a/java/sdk_library.go b/java/sdk_library.go index c97a04a5b..82888d1ab 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -2182,8 +2182,12 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe properties.Jars = jars properties.SdkVersion = sdk.sdkVersionForStubsLibrary(ctx.SdkModuleContext(), apiScope) properties.StubsSrcJar = paths.stubsSrcJar.Path() - properties.CurrentApiFile = paths.currentApiFilePath.Path() - properties.RemovedApiFile = paths.removedApiFilePath.Path() + if paths.currentApiFilePath.Valid() { + properties.CurrentApiFile = paths.currentApiFilePath.Path() + } + if paths.removedApiFilePath.Valid() { + properties.RemovedApiFile = paths.removedApiFilePath.Path() + } s.Scopes[apiScope] = properties } } -- cgit v1.2.3-59-g8ed1b From dbc0adad52a8eaa299a68355397a41bb030e8d3f Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Tue, 23 Jun 2020 10:52:58 -0700 Subject: Enable check for "try to expose APIs from hidden class" Exempt-From-Owner-Approval:Cherry-pick from goog/master Bug: 159121253 Test: treehugger (i.e. this shouldn't trigger "API has changed" error.) Merged-in: I6ca2d8e3967cdc41aa2a931972472174aae2a613 Change-Id: I6ca2d8e3967cdc41aa2a931972472174aae2a613 --- java/droiddoc.go | 1 - 1 file changed, 1 deletion(-) (limited to 'java/droiddoc.go') diff --git a/java/droiddoc.go b/java/droiddoc.go index 1f8f2fcea..8a6454b27 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1325,7 +1325,6 @@ func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuil cmd.Flag("--exclude-documentation-from-stubs") } } - cmd.FlagWithArg("--hide ", "ShowingMemberInHiddenClass") // b/159121253 -- remove it once all the violations are fixed. } func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) { -- cgit v1.2.3-59-g8ed1b