summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/base.go45
-rw-r--r--java/bootclasspath_fragment.go20
-rw-r--r--java/builder.go17
-rw-r--r--java/dexpreopt_bootjars.go95
-rw-r--r--java/dexpreopt_config.go8
-rw-r--r--java/hiddenapi.go1
-rw-r--r--java/hiddenapi_modular.go209
-rw-r--r--java/hiddenapi_monolithic.go2
-rw-r--r--java/java_test.go28
-rw-r--r--java/kotlin_test.go1
-rw-r--r--java/lint.go5
-rw-r--r--java/platform_bootclasspath.go15
-rw-r--r--java/platform_bootclasspath_test.go112
13 files changed, 304 insertions, 254 deletions
diff --git a/java/base.go b/java/base.go
index 440b00478..1daa10876 100644
--- a/java/base.go
+++ b/java/base.go
@@ -155,6 +155,11 @@ type CommonProperties struct {
// List of java_plugin modules that provide extra errorprone checks.
Extra_check_modules []string
+
+ // Whether to run errorprone on a normal build. If this is false, errorprone
+ // will still be run if the RUN_ERROR_PRONE environment variable is true.
+ // Default false.
+ Enabled *bool
}
Proto struct {
@@ -701,7 +706,7 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
// javaVersion flag.
flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), android.SdkContext(j))
- if ctx.Config().RunErrorProne() {
+ if ctx.Config().RunErrorProne() || Bool(j.properties.Errorprone.Enabled) {
if config.ErrorProneClasspath == nil && ctx.Config().TestProductVariables == nil {
ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
}
@@ -972,14 +977,23 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
}
if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 {
var extraJarDeps android.Paths
- if ctx.Config().RunErrorProne() {
- // If error-prone is enabled, add an additional rule to compile the java files into
- // a separate set of classes (so that they don't overwrite the normal ones and require
- // a rebuild when error-prone is turned off).
- // TODO(ccross): Once we always compile with javac9 we may be able to conditionally
- // enable error-prone without affecting the output class files.
+ if Bool(j.properties.Errorprone.Enabled) {
+ // If error-prone is enabled, enable errorprone flags on the regular
+ // build.
+ flags = enableErrorproneFlags(flags)
+ } else if ctx.Config().RunErrorProne() {
+ // Otherwise, if the RUN_ERROR_PRONE environment variable is set, create
+ // a new jar file just for compiling with the errorprone compiler to.
+ // This is because we don't want to cause the java files to get completely
+ // rebuilt every time the state of the RUN_ERROR_PRONE variable changes.
+ // We also don't want to run this if errorprone is enabled by default for
+ // this module, or else we could have duplicated errorprone messages.
+ errorproneFlags := enableErrorproneFlags(flags)
errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
- RunErrorProne(ctx, errorprone, uniqueSrcFiles, srcJars, flags)
+
+ transformJavaToClasses(ctx, errorprone, -1, uniqueSrcFiles, srcJars, errorproneFlags, nil,
+ "errorprone", "errorprone")
+
extraJarDeps = append(extraJarDeps, errorprone)
}
@@ -1303,6 +1317,21 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
j.outputFile = outputFile.WithoutRel()
}
+// Returns a copy of the supplied flags, but with all the errorprone-related
+// fields copied to the regular build's fields.
+func enableErrorproneFlags(flags javaBuilderFlags) javaBuilderFlags {
+ flags.processorPath = append(flags.errorProneProcessorPath, flags.processorPath...)
+
+ if len(flags.errorProneExtraJavacFlags) > 0 {
+ if len(flags.javacFlags) > 0 {
+ flags.javacFlags += " " + flags.errorProneExtraJavacFlags
+ } else {
+ flags.javacFlags = flags.errorProneExtraJavacFlags
+ }
+ }
+ return flags
+}
+
func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, idx int,
srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.WritablePath {
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 1c7ad78ec..fc8f5571e 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -140,7 +140,7 @@ type commonBootclasspathFragment interface {
// produceHiddenAPIAllFlagsFile produces the all-flags.csv and intermediate files.
//
// Updates the supplied hiddenAPIInfo with the paths to the generated files set.
- produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, input HiddenAPIFlagInput) *HiddenAPIFlagOutput
+ produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIFlagOutput
}
var _ commonBootclasspathFragment = (*BootclasspathFragmentModule)(nil)
@@ -465,7 +465,7 @@ func (b *BootclasspathFragmentModule) populateApexContentInfoDexJars(ctx android
if unencodedDex == nil {
// This is an error. Sometimes Soong will report the error directly, other times it will
// defer the error reporting to happen only when trying to use the missing file in ninja.
- // Either way it is handled by extractBootDexJarsFromHiddenAPIModules which must have been
+ // Either way it is handled by extractBootDexJarsFromModules which must have been
// called before this as it generates the flags that are used to encode these files.
continue
}
@@ -561,12 +561,9 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.
// TODO(b/179354495): Stop hidden API processing being conditional once all bootclasspath_fragment
// modules have been updated to support it.
if input.canPerformHiddenAPIProcessing(ctx, b.properties) {
- // Get the content modules that contribute to the hidden API processing.
- hiddenAPIModules := gatherHiddenAPIModuleFromContents(ctx, contents)
-
// Delegate the production of the hidden API all-flags.csv file to a module type specific method.
common := ctx.Module().(commonBootclasspathFragment)
- output = common.produceHiddenAPIAllFlagsFile(ctx, hiddenAPIModules, input)
+ output = common.produceHiddenAPIAllFlagsFile(ctx, contents, input)
}
// Initialize a HiddenAPIInfo structure.
@@ -620,7 +617,7 @@ func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.Modul
// produceHiddenAPIAllFlagsFile produces the hidden API all-flags.csv file (and supporting files)
// for the fragment.
-func (b *BootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, input HiddenAPIFlagInput) *HiddenAPIFlagOutput {
+func (b *BootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIFlagOutput {
// Generate the rules to create the hidden API flags and update the supplied hiddenAPIInfo with the
// paths to the created files.
return hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx, contents, input)
@@ -648,7 +645,8 @@ func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.
}
// Copy the dex jars of this fragment's content modules to their predefined locations.
- copyBootJarsToPredefinedLocations(ctx, contents, imageConfig.modules, imageConfig.dexPaths)
+ bootDexJarByModule := extractEncodedDexJarsFromModules(ctx, contents)
+ copyBootJarsToPredefinedLocations(ctx, bootDexJarByModule, imageConfig.dexPathsByModule)
// Build a profile for the image config and then use that to build the boot image.
profile := bootImageProfileRule(ctx, imageConfig)
@@ -763,7 +761,7 @@ func (b *bootclasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.
// Copy manually curated flag files specified on the bootclasspath_fragment.
if b.Flag_files_by_category != nil {
- for _, category := range hiddenAPIFlagFileCategories {
+ for _, category := range HiddenAPIFlagFileCategories {
paths := b.Flag_files_by_category[category]
if len(paths) > 0 {
dests := []string{}
@@ -772,7 +770,7 @@ func (b *bootclasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.
builder.CopyToSnapshot(p, dest)
dests = append(dests, dest)
}
- hiddenAPISet.AddProperty(category.propertyName, dests)
+ hiddenAPISet.AddProperty(category.PropertyName, dests)
}
}
}
@@ -840,7 +838,7 @@ func (module *prebuiltBootclasspathFragmentModule) Name() string {
// produceHiddenAPIAllFlagsFile returns a path to the prebuilt all-flags.csv or nil if none is
// specified.
-func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, _ HiddenAPIFlagInput) *HiddenAPIFlagOutput {
+func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []android.Module, _ HiddenAPIFlagInput) *HiddenAPIFlagOutput {
pathForOptionalSrc := func(src *string) android.Path {
if src == nil {
// TODO(b/179354495): Fail if this is not provided once prebuilts have been updated.
diff --git a/java/builder.go b/java/builder.go
index cde87310f..ea011b8e1 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -279,23 +279,6 @@ func TransformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab
transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, flags, deps, "javac", desc)
}
-func RunErrorProne(ctx android.ModuleContext, outputFile android.WritablePath,
- srcFiles, srcJars android.Paths, flags javaBuilderFlags) {
-
- flags.processorPath = append(flags.errorProneProcessorPath, flags.processorPath...)
-
- if len(flags.errorProneExtraJavacFlags) > 0 {
- if len(flags.javacFlags) > 0 {
- flags.javacFlags += " " + flags.errorProneExtraJavacFlags
- } else {
- flags.javacFlags = flags.errorProneExtraJavacFlags
- }
- }
-
- transformJavaToClasses(ctx, outputFile, -1, srcFiles, srcJars, flags, nil,
- "errorprone", "errorprone")
-}
-
// Emits the rule to generate Xref input file (.kzip file) for the given set of source files and source jars
// to compile with given set of builder flags, etc.
func emitXrefRule(ctx android.ModuleContext, xrefFile android.WritablePath, idx int,
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index e1a36507a..dc8df5ec1 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -15,7 +15,6 @@
package java
import (
- "fmt"
"path/filepath"
"sort"
"strings"
@@ -254,6 +253,9 @@ type bootImageConfig struct {
dexPaths android.WritablePaths // for this image
dexPathsDeps android.WritablePaths // for the dependency images and in this image
+ // Map from module name (without prebuilt_ prefix) to the predefined build path.
+ dexPathsByModule map[string]android.WritablePath
+
// File path to a zip archive with all image files (or nil, if not needed).
zip android.WritablePath
@@ -276,13 +278,24 @@ type bootImageVariant struct {
dexLocationsDeps []string // for the dependency images and in this image
// Paths to image files.
- imagePathOnHost android.OutputPath // first image file path on host
- imagePathOnDevice string // first image file path on device
- imagesDeps android.OutputPaths // all files
+ imagePathOnHost android.OutputPath // first image file path on host
+ imagePathOnDevice string // first image file path on device
+
+ // All the files that constitute this image variant, i.e. .art, .oat and .vdex files.
+ imagesDeps android.OutputPaths
- // Only for extensions, paths to the primary boot images.
+ // The path to the primary image variant's imagePathOnHost field, where primary image variant
+ // means the image variant that this extends.
+ //
+ // This is only set for a variant of an image that extends another image.
primaryImages android.OutputPath
+ // The paths to the primary image variant's imagesDeps field, where primary image variant
+ // means the image variant that this extends.
+ //
+ // This is only set for a variant of an image that extends another image.
+ primaryImagesDeps android.Paths
+
// Rules which should be used in make to install the outputs.
installs android.RuleBuilderInstalls
vdexInstalls android.RuleBuilderInstalls
@@ -450,53 +463,27 @@ func shouldBuildBootImages(config android.Config, global *dexpreopt.GlobalConfig
return true
}
-// copyBootJarsToPredefinedLocations generates commands that will copy boot jars to
-// predefined paths in the global config.
-func copyBootJarsToPredefinedLocations(ctx android.ModuleContext, bootModules []android.Module, bootjars android.ConfiguredJarList, jarPathsPredefined android.WritablePaths) {
- jarPaths := make(android.Paths, bootjars.Len())
- for i, module := range bootModules {
- if module != nil {
- bootDexJar := module.(interface{ DexJarBuildPath() android.Path }).DexJarBuildPath()
- jarPaths[i] = bootDexJar
-
- name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(module))
- if bootjars.Jar(i) != name {
- ctx.ModuleErrorf("expected module %s at position %d but found %s", bootjars.Jar(i), i, name)
- }
- }
- }
-
- // The paths to bootclasspath DEX files need to be known at module GenerateAndroidBuildAction
- // time, before the boot images are built (these paths are used in dexpreopt rule generation for
- // Java libraries and apps). Generate rules that copy bootclasspath DEX jars to the predefined
- // paths.
- for i := range jarPaths {
- input := jarPaths[i]
- output := jarPathsPredefined[i]
- module := bootjars.Jar(i)
- if input == nil {
- if ctx.Config().AllowMissingDependencies() {
- apex := bootjars.Apex(i)
-
- // Create an error rule that pretends to create the output file but will actually fail if it
- // is run.
- ctx.Build(pctx, android.BuildParams{
- Rule: android.ErrorRule,
- Output: output,
- Args: map[string]string{
- "error": fmt.Sprintf("missing dependencies: dex jar for %s:%s", module, apex),
- },
- })
- } else {
- ctx.ModuleErrorf("failed to find a dex jar path for module '%s'"+
- ", note that some jars may be filtered out by module constraints", module)
- }
-
+// copyBootJarsToPredefinedLocations generates commands that will copy boot jars to predefined
+// paths in the global config.
+func copyBootJarsToPredefinedLocations(ctx android.ModuleContext, srcBootDexJarsByModule bootDexJarByModule, dstBootJarsByModule map[string]android.WritablePath) {
+ // Create the super set of module names.
+ names := []string{}
+ names = append(names, android.SortedStringKeys(srcBootDexJarsByModule)...)
+ names = append(names, android.SortedStringKeys(dstBootJarsByModule)...)
+ names = android.SortedUniqueStrings(names)
+ for _, name := range names {
+ src := srcBootDexJarsByModule[name]
+ dst := dstBootJarsByModule[name]
+
+ if src == nil {
+ ctx.ModuleErrorf("module %s does not provide a dex boot jar", name)
+ } else if dst == nil {
+ ctx.ModuleErrorf("module %s is not part of the boot configuration", name)
} else {
ctx.Build(pctx, android.BuildParams{
Rule: android.Cp,
- Input: input,
- Output: output,
+ Input: src,
+ Output: dst,
})
}
}
@@ -588,7 +575,15 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
cmd.
Flag("--runtime-arg").FlagWithInputList("-Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", image.dexLocationsDeps, ":").
- FlagWithArg("--boot-image=", dexpreopt.PathToLocation(artImage, arch)).Implicit(artImage)
+ // Add the path to the first file in the boot image with the arch specific directory removed,
+ // dex2oat will reconstruct the path to the actual file when it needs it. As the actual path
+ // to the file cannot be passed to the command make sure to add the actual path as an Implicit
+ // dependency to ensure that it is built before the command runs.
+ FlagWithArg("--boot-image=", dexpreopt.PathToLocation(artImage, arch)).Implicit(artImage).
+ // Similarly, the dex2oat tool will automatically find the paths to other files in the base
+ // boot image so make sure to add them as implicit dependencies to ensure that they are built
+ // before this command is run.
+ Implicits(image.primaryImagesDeps)
} else {
// It is a primary image, so it needs a base address.
cmd.FlagWithArg("--base=", ctx.Config().LibartImgDeviceBaseAddress())
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 39a3e11a5..b13955fba 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -100,6 +100,7 @@ func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig {
// TODO(b/143682396): use module dependencies instead
inputDir := deviceDir.Join(ctx, "dex_"+c.name+"jars_input")
c.dexPaths = c.modules.BuildPaths(ctx, inputDir)
+ c.dexPathsByModule = c.modules.BuildPathsByModule(ctx, inputDir)
c.dexPathsDeps = c.dexPaths
// Create target-specific variants.
@@ -125,6 +126,7 @@ func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig {
frameworkCfg.dexPathsDeps = append(artCfg.dexPathsDeps, frameworkCfg.dexPathsDeps...)
for i := range targets {
frameworkCfg.variants[i].primaryImages = artCfg.variants[i].imagePathOnHost
+ frameworkCfg.variants[i].primaryImagesDeps = artCfg.variants[i].imagesDeps.Paths()
frameworkCfg.variants[i].dexLocationsDeps = append(artCfg.variants[i].dexLocations, frameworkCfg.variants[i].dexLocationsDeps...)
}
@@ -152,6 +154,9 @@ type updatableBootConfig struct {
// later on a singleton adds commands to copy actual jars to the predefined paths.
dexPaths android.WritablePaths
+ // Map from module name (without prebuilt_ prefix) to the predefined build path.
+ dexPathsByModule map[string]android.WritablePath
+
// A list of dex locations (a.k.a. on-device paths) to the boot jars.
dexLocations []string
}
@@ -165,10 +170,11 @@ func GetUpdatableBootConfig(ctx android.PathContext) updatableBootConfig {
dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "updatable_bootjars")
dexPaths := updatableBootJars.BuildPaths(ctx, dir)
+ dexPathsByModuleName := updatableBootJars.BuildPathsByModule(ctx, dir)
dexLocations := updatableBootJars.DevicePaths(ctx.Config(), android.Android)
- return updatableBootConfig{updatableBootJars, dexPaths, dexLocations}
+ return updatableBootConfig{updatableBootJars, dexPaths, dexPathsByModuleName, dexLocations}
}).(updatableBootConfig)
}
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index e9693c68e..f901434a0 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -219,7 +219,6 @@ func buildRuleToGenerateIndex(ctx android.ModuleContext, desc string, classesJar
BuiltTool("merge_csv").
Flag("--zip_input").
Flag("--key_field signature").
- FlagWithArg("--header=", "signature,file,startline,startcol,endline,endcol,properties").
FlagWithOutput("--output=", indexCSV).
Inputs(classesJars)
rule.Build(desc, desc)
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index f2649d3c0..643c5cba2 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -248,8 +248,8 @@ type HiddenAPIFlagFileProperties struct {
}
type hiddenAPIFlagFileCategory struct {
- // propertyName is the name of the property for this category.
- propertyName string
+ // PropertyName is the name of the property for this category.
+ PropertyName string
// propertyValueReader retrieves the value of the property for this category from the set of
// properties.
@@ -262,12 +262,12 @@ type hiddenAPIFlagFileCategory struct {
// The flag file category for removed members of the API.
//
-// This is extracted from hiddenAPIFlagFileCategories as it is needed to add the dex signatures
+// This is extracted from HiddenAPIFlagFileCategories as it is needed to add the dex signatures
// list of removed API members that are generated automatically from the removed.txt files provided
// by API stubs.
var hiddenAPIRemovedFlagFileCategory = &hiddenAPIFlagFileCategory{
// See HiddenAPIFlagFileProperties.Removed
- propertyName: "removed",
+ PropertyName: "removed",
propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
return properties.Removed
},
@@ -276,10 +276,10 @@ var hiddenAPIRemovedFlagFileCategory = &hiddenAPIFlagFileCategory{
},
}
-var hiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
+var HiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
// See HiddenAPIFlagFileProperties.Unsupported
{
- propertyName: "unsupported",
+ PropertyName: "unsupported",
propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
return properties.Unsupported
},
@@ -290,7 +290,7 @@ var hiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
hiddenAPIRemovedFlagFileCategory,
// See HiddenAPIFlagFileProperties.Max_target_r_low_priority
{
- propertyName: "max_target_r_low_priority",
+ PropertyName: "max_target_r_low_priority",
propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
return properties.Max_target_r_low_priority
},
@@ -300,7 +300,7 @@ var hiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
},
// See HiddenAPIFlagFileProperties.Max_target_q
{
- propertyName: "max_target_q",
+ PropertyName: "max_target_q",
propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
return properties.Max_target_q
},
@@ -310,7 +310,7 @@ var hiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
},
// See HiddenAPIFlagFileProperties.Max_target_p
{
- propertyName: "max_target_p",
+ PropertyName: "max_target_p",
propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
return properties.Max_target_p
},
@@ -320,7 +320,7 @@ var hiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
},
// See HiddenAPIFlagFileProperties.Max_target_o_low_priority
{
- propertyName: "max_target_o_low_priority",
+ PropertyName: "max_target_o_low_priority",
propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
return properties.Max_target_o_low_priority
},
@@ -330,7 +330,7 @@ var hiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
},
// See HiddenAPIFlagFileProperties.Blocked
{
- propertyName: "blocked",
+ PropertyName: "blocked",
propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
return properties.Blocked
},
@@ -340,7 +340,7 @@ var hiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
},
// See HiddenAPIFlagFileProperties.Unsupported_packages
{
- propertyName: "unsupported_packages",
+ PropertyName: "unsupported_packages",
propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
return properties.Unsupported_packages
},
@@ -355,7 +355,7 @@ type FlagFilesByCategory map[*hiddenAPIFlagFileCategory]android.Paths
// append appends the supplied flags files to the corresponding category in this map.
func (s FlagFilesByCategory) append(other FlagFilesByCategory) {
- for _, category := range hiddenAPIFlagFileCategories {
+ for _, category := range HiddenAPIFlagFileCategories {
s[category] = append(s[category], other[category]...)
}
}
@@ -540,7 +540,7 @@ func (i *HiddenAPIFlagInput) gatherStubLibInfo(ctx android.ModuleContext, conten
// extractFlagFilesFromProperties extracts the paths to flag files that are specified in the
// supplied properties and stores them in this struct.
func (i *HiddenAPIFlagInput) extractFlagFilesFromProperties(ctx android.ModuleContext, p *HiddenAPIFlagFileProperties) {
- for _, category := range hiddenAPIFlagFileCategories {
+ for _, category := range HiddenAPIFlagFileCategories {
paths := android.PathsForModuleSrc(ctx, category.propertyValueReader(p))
i.FlagFilesByCategory[category] = paths
}
@@ -571,6 +571,15 @@ type HiddenAPIFlagOutput struct {
AllFlagsPath android.Path
}
+// bootDexJarByModule is a map from base module name (without prebuilt_ prefix) to the boot dex
+// path.
+type bootDexJarByModule map[string]android.Path
+
+// addPath adds the path for a module to the map.
+func (b bootDexJarByModule) addPath(module android.Module, path android.Path) {
+ b[android.RemoveOptionalPrebuiltPrefix(module.Name())] = path
+}
+
// pathForValidation creates a path of the same type as the supplied type but with a name of
// <path>.valid.
//
@@ -630,7 +639,7 @@ func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc st
FlagWithOutput("--output ", tempPath)
// Add the options for the different categories of flag files.
- for _, category := range hiddenAPIFlagFileCategories {
+ for _, category := range HiddenAPIFlagFileCategories {
paths := flagFilesByCategory[category]
for _, path := range paths {
category.commandMutator(command, path)
@@ -670,11 +679,11 @@ func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc st
// * metadata.csv
// * index.csv
// * all-flags.csv
-func hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx android.ModuleContext, contents []hiddenAPIModule, input HiddenAPIFlagInput) *HiddenAPIFlagOutput {
+func hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIFlagOutput {
hiddenApiSubDir := "modular-hiddenapi"
// Gather the dex files for the boot libraries provided by this fragment.
- bootDexJars := extractBootDexJarsFromHiddenAPIModules(ctx, contents)
+ bootDexJars := extractBootDexJarsFromModules(ctx, contents)
// Generate the stub-flags.csv.
stubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "stub-flags.csv")
@@ -682,7 +691,7 @@ func hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx android.ModuleContext
rule.Build("modularHiddenAPIStubFlagsFile", "modular hiddenapi stub flags")
// Extract the classes jars from the contents.
- classesJars := extractClassJarsFromHiddenAPIModules(ctx, contents)
+ classesJars := extractClassesJarsFromModules(contents)
// Generate the set of flags from the annotations in the source code.
annotationFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "annotation-flags.csv")
@@ -737,29 +746,18 @@ func buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, removedT
return android.OptionalPathForPath(output)
}
-// gatherHiddenAPIModuleFromContents gathers the hiddenAPIModule from the supplied contents.
-func gatherHiddenAPIModuleFromContents(ctx android.ModuleContext, contents []android.Module) []hiddenAPIModule {
- hiddenAPIModules := []hiddenAPIModule{}
- for _, module := range contents {
- if hiddenAPI, ok := module.(hiddenAPIModule); ok {
- hiddenAPIModules = append(hiddenAPIModules, hiddenAPI)
- } else if _, ok := module.(*DexImport); ok {
- // Ignore this for the purposes of hidden API processing
- } else {
- ctx.ModuleErrorf("module %s does not implement hiddenAPIModule", module)
- }
- }
- return hiddenAPIModules
-}
-
-// extractBootDexJarsFromHiddenAPIModules extracts the boot dex jars from the supplied modules.
-func extractBootDexJarsFromHiddenAPIModules(ctx android.ModuleContext, contents []hiddenAPIModule) android.Paths {
+// extractBootDexJarsFromModules extracts the boot dex jars from the supplied modules.
+func extractBootDexJarsFromModules(ctx android.ModuleContext, contents []android.Module) android.Paths {
bootDexJars := android.Paths{}
for _, module := range contents {
- bootDexJar := module.bootDexJar()
+ hiddenAPIModule := hiddenAPIModuleFromModule(ctx, module)
+ if hiddenAPIModule == nil {
+ continue
+ }
+ bootDexJar := hiddenAPIModule.bootDexJar()
if bootDexJar == nil {
if ctx.Config().AlwaysUsePrebuiltSdks() {
- // TODO(b/179354495): Remove this work around when it is unnecessary.
+ // TODO(b/179354495): Remove this workaround when it is unnecessary.
// Prebuilt modules like framework-wifi do not yet provide dex implementation jars. So,
// create a fake one that will cause a build error only if it is used.
fake := android.PathForModuleOut(ctx, "fake/boot-dex/%s.jar", module.Name())
@@ -784,11 +782,142 @@ func extractBootDexJarsFromHiddenAPIModules(ctx android.ModuleContext, contents
return bootDexJars
}
-// extractClassJarsFromHiddenAPIModules extracts the class jars from the supplied modules.
-func extractClassJarsFromHiddenAPIModules(ctx android.ModuleContext, contents []hiddenAPIModule) android.Paths {
+func hiddenAPIModuleFromModule(ctx android.BaseModuleContext, module android.Module) hiddenAPIModule {
+ if hiddenAPIModule, ok := module.(hiddenAPIModule); ok {
+ return hiddenAPIModule
+ } else if _, ok := module.(*DexImport); ok {
+ // Ignore this for the purposes of hidden API processing
+ } else {
+ ctx.ModuleErrorf("module %s does not implement hiddenAPIModule", module)
+ }
+
+ return nil
+}
+
+// extractClassesJarsFromModules extracts the class jars from the supplied modules.
+func extractClassesJarsFromModules(contents []android.Module) android.Paths {
classesJars := android.Paths{}
for _, module := range contents {
- classesJars = append(classesJars, module.classesJars()...)
+ classesJars = append(classesJars, retrieveClassesJarsFromModule(module)...)
}
return classesJars
}
+
+// retrieveClassesJarsFromModule retrieves the classes jars from the supplied module.
+func retrieveClassesJarsFromModule(module android.Module) android.Paths {
+ if hiddenAPIModule, ok := module.(hiddenAPIModule); ok {
+ return hiddenAPIModule.classesJars()
+ }
+
+ return nil
+}
+
+// deferReportingMissingBootDexJar returns true if a missing boot dex jar should not be reported by
+// Soong but should instead only be reported in ninja if the file is actually built.
+func deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.Module) bool {
+ // TODO(b/179354495): Remove this workaround when it is unnecessary.
+ // Prebuilt modules like framework-wifi do not yet provide dex implementation jars. So,
+ // create a fake one that will cause a build error only if it is used.
+ if ctx.Config().AlwaysUsePrebuiltSdks() {
+ return true
+ }
+
+ // This is called for both platform_bootclasspath and bootclasspath_fragment modules.
+ //
+ // A bootclasspath_fragment module should only use the APEX variant of source or prebuilt modules.
+ // Ideally, a bootclasspath_fragment module should never have a platform variant created for it
+ // but unfortunately, due to b/187910671 it does.
+ //
+ // That causes issues when obtaining a boot dex jar for a prebuilt module as a prebuilt module
+ // used by a bootclasspath_fragment can only provide a boot dex jar when it is part of APEX, i.e.
+ // has an APEX variant not a platform variant.
+ //
+ // There are some other situations when a prebuilt module used by a bootclasspath_fragment cannot
+ // provide a boot dex jar:
+ // 1. If the bootclasspath_fragment is not exported by the prebuilt_apex/apex_set module then it
+ // does not have an APEX variant and only has a platform variant and neither do its content
+ // modules.
+ // 2. Some build configurations, e.g. setting TARGET_BUILD_USE_PREBUILT_SDKS causes all
+ // java_sdk_library_import modules to be treated as preferred and as many of them are not part
+ // of an apex they cannot provide a boot dex jar.
+ //
+ // The first case causes problems when the affected prebuilt modules are preferred but that is an
+ // invalid configuration and it is ok for it to fail as the work to enable that is not yet
+ // complete. The second case is used for building targets that do not use boot dex jars and so
+ // deferring error reporting to ninja is fine as the affected ninja targets should never be built.
+ // That is handled above.
+ //
+ // A platform_bootclasspath module can use libraries from both platform and APEX variants. Unlike
+ // the bootclasspath_fragment it supports dex_import modules which provides the dex file. So, it
+ // can obtain a boot dex jar from a prebuilt that is not part of an APEX. However, it is assumed
+ // that if the library can be part of an APEX then it is the APEX variant that is used.
+ //
+ // This check handles the slightly different requirements of the bootclasspath_fragment and
+ // platform_bootclasspath modules by only deferring error reporting for the platform variant of
+ // a prebuilt modules that has other variants which are part of an APEX.
+ //
+ // TODO(b/187910671): Remove this once platform variants are no longer created unnecessarily.
+ if android.IsModulePrebuilt(module) {
+ if am, ok := module.(android.ApexModule); ok && am.InAnyApex() {
+ apexInfo := ctx.OtherModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
+ if apexInfo.IsForPlatform() {
+ return true
+ }
+ }
+ }
+
+ // A bootclasspath module that is part of a versioned sdk never provides a boot dex jar as there
+ // is no equivalently versioned prebuilt APEX file from which it can be obtained. However,
+ // versioned bootclasspath modules are processed by Soong so in order to avoid them causing build
+ // failures missing boot dex jars need to be deferred.
+ if android.IsModuleInVersionedSdk(ctx.Module()) {
+ return true
+ }
+
+ return false
+}
+
+// handleMissingDexBootFile will either log a warning or create an error rule to create the fake
+// file depending on the value returned from deferReportingMissingBootDexJar.
+func handleMissingDexBootFile(ctx android.ModuleContext, module android.Module, fake android.WritablePath) {
+ if deferReportingMissingBootDexJar(ctx, module) {
+ // Create an error rule that pretends to create the output file but will actually fail if it
+ // is run.
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.ErrorRule,
+ Output: fake,
+ Args: map[string]string{
+ "error": fmt.Sprintf("missing dependencies: boot dex jar for %s", module),
+ },
+ })
+ } else {
+ ctx.ModuleErrorf("module %s does not provide a dex jar", module)
+ }
+}
+
+// retrieveEncodedBootDexJarFromModule returns a path to the boot dex jar from the supplied module's
+// DexJarBuildPath() method.
+//
+// The returned path will usually be to a dex jar file that has been encoded with hidden API flags.
+// However, under certain conditions, e.g. errors, or special build configurations it will return
+// a path to a fake file.
+func retrieveEncodedBootDexJarFromModule(ctx android.ModuleContext, module android.Module) android.Path {
+ bootDexJar := module.(interface{ DexJarBuildPath() android.Path }).DexJarBuildPath()
+ if bootDexJar == nil {
+ fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/encoded-dex/%s.jar", module.Name()))
+ bootDexJar = fake
+
+ handleMissingDexBootFile(ctx, module, fake)
+ }
+ return bootDexJar
+}
+
+// extractEncodedDexJarsFromModules extracts the encoded dex jars from the supplied modules.
+func extractEncodedDexJarsFromModules(ctx android.ModuleContext, contents []android.Module) bootDexJarByModule {
+ encodedDexJarsByModuleName := bootDexJarByModule{}
+ for _, module := range contents {
+ path := retrieveEncodedBootDexJarFromModule(ctx, module)
+ encodedDexJarsByModuleName.addPath(module, path)
+ }
+ return encodedDexJarsByModuleName
+}
diff --git a/java/hiddenapi_monolithic.go b/java/hiddenapi_monolithic.go
index a6bf8c705..edf42351f 100644
--- a/java/hiddenapi_monolithic.go
+++ b/java/hiddenapi_monolithic.go
@@ -99,4 +99,4 @@ func (i *MonolithicHiddenAPIInfo) dedup() {
i.AllFlagsPaths = android.FirstUniquePaths(i.AllFlagsPaths)
}
-var monolithicHiddenAPIInfoProvider = blueprint.NewProvider(MonolithicHiddenAPIInfo{})
+var MonolithicHiddenAPIInfoProvider = blueprint.NewProvider(MonolithicHiddenAPIInfo{})
diff --git a/java/java_test.go b/java/java_test.go
index bd373c177..78d9ab4c7 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1392,3 +1392,31 @@ func TestDefaultInstallable(t *testing.T) {
assertDeepEquals(t, "Default installable value should be true.", proptools.BoolPtr(true),
module.properties.Installable)
}
+
+func TestErrorproneEnabled(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ errorprone: {
+ enabled: true,
+ },
+ }
+ `)
+
+ javac := ctx.ModuleForTests("foo", "android_common").Description("javac")
+
+ // Test that the errorprone plugins are passed to javac
+ expectedSubstring := "-Xplugin:ErrorProne"
+ if !strings.Contains(javac.Args["javacFlags"], expectedSubstring) {
+ t.Errorf("expected javacFlags to conain %q, got %q", expectedSubstring, javac.Args["javacFlags"])
+ }
+
+ // Modules with errorprone { enabled: true } will include errorprone checks
+ // in the main javac build rule. Only when RUN_ERROR_PRONE is true will
+ // the explicit errorprone build rule be created.
+ errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone")
+ if errorprone.RuleParams.Description != "" {
+ t.Errorf("expected errorprone build rule to not exist, but it did")
+ }
+}
diff --git a/java/kotlin_test.go b/java/kotlin_test.go
index 1c146a192..fd2f3ca61 100644
--- a/java/kotlin_test.go
+++ b/java/kotlin_test.go
@@ -185,7 +185,6 @@ func TestKapt(t *testing.T) {
buildOS := android.BuildOs.String()
kapt := result.ModuleForTests("foo", "android_common").Rule("kapt")
- //kotlinc := ctx.ModuleForTests("foo", "android_common").Rule("kotlinc")
javac := result.ModuleForTests("foo", "android_common").Description("javac")
errorprone := result.ModuleForTests("foo", "android_common").Description("errorprone")
diff --git a/java/lint.go b/java/lint.go
index 9f769dfe3..1511cfe26 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -361,10 +361,7 @@ func (l *linter) lint(ctx android.ModuleContext) {
Labels: map[string]string{"type": "tool", "name": "lint"},
ExecStrategy: lintRBEExecStrategy(ctx),
ToolchainInputs: []string{config.JavaCmd(ctx).String()},
- EnvironmentVariables: []string{
- "LANG",
- },
- Platform: map[string]string{remoteexec.PoolKey: pool},
+ Platform: map[string]string{remoteexec.PoolKey: pool},
})
}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 87c695cb5..fba73d0c1 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -280,7 +280,6 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.
}
monolithicInfo := b.createAndProvideMonolithicHiddenAPIInfo(ctx, fragments)
-
// Create the input to pass to ruleToGenerateHiddenAPIStubFlagsFile
input := newHiddenAPIFlagInput()
@@ -291,16 +290,14 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.
// Use the flag files from this module and all the fragments.
input.FlagFilesByCategory = monolithicInfo.FlagsFilesByCategory
- hiddenAPIModules := gatherHiddenAPIModuleFromContents(ctx, modules)
-
// Generate the monolithic stub-flags.csv file.
- bootDexJars := extractBootDexJarsFromHiddenAPIModules(ctx, hiddenAPIModules)
+ bootDexJars := extractBootDexJarsFromModules(ctx, modules)
stubFlags := hiddenAPISingletonPaths(ctx).stubFlags
rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlags, bootDexJars, input)
rule.Build("platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags")
// Extract the classes jars from the contents.
- classesJars := extractClassJarsFromHiddenAPIModules(ctx, hiddenAPIModules)
+ classesJars := extractClassesJarsFromModules(modules)
// Generate the annotation-flags.csv file from all the module annotations.
annotationFlags := android.PathForModuleOut(ctx, "hiddenapi-monolithic", "annotation-flags.csv")
@@ -342,7 +339,7 @@ func (b *platformBootclasspathModule) createAndProvideMonolithicHiddenAPIInfo(ct
monolithicInfo := newMonolithicHiddenAPIInfo(ctx, temporaryInput.FlagFilesByCategory, fragments)
// Store the information for testing.
- ctx.SetProvider(monolithicHiddenAPIInfoProvider, monolithicInfo)
+ ctx.SetProvider(MonolithicHiddenAPIInfoProvider, monolithicInfo)
return monolithicInfo
}
@@ -390,11 +387,13 @@ func (b *platformBootclasspathModule) generateBootImageBuildActions(ctx android.
generateUpdatableBcpPackagesRule(ctx, imageConfig, updatableModules)
// Copy non-updatable module dex jars to their predefined locations.
- copyBootJarsToPredefinedLocations(ctx, nonUpdatableModules, imageConfig.modules, imageConfig.dexPaths)
+ nonUpdatableBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, nonUpdatableModules)
+ copyBootJarsToPredefinedLocations(ctx, nonUpdatableBootDexJarsByModule, imageConfig.dexPathsByModule)
// Copy updatable module dex jars to their predefined locations.
config := GetUpdatableBootConfig(ctx)
- copyBootJarsToPredefinedLocations(ctx, updatableModules, config.modules, config.dexPaths)
+ updatableBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, updatableModules)
+ copyBootJarsToPredefinedLocations(ctx, updatableBootDexJarsByModule, config.dexPathsByModule)
// Build a profile for the image config and then use that to build the boot image.
profile := bootImageProfileRule(ctx, imageConfig)
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
index ed5549d35..0318a07d4 100644
--- a/java/platform_bootclasspath_test.go
+++ b/java/platform_bootclasspath_test.go
@@ -15,8 +15,6 @@
package java
import (
- "fmt"
- "strings"
"testing"
"android/soong/android"
@@ -152,116 +150,6 @@ func TestPlatformBootclasspath(t *testing.T) {
})
}
-func TestPlatformBootclasspath_Fragments(t *testing.T) {
- result := android.GroupFixturePreparers(
- prepareForTestWithPlatformBootclasspath,
- PrepareForTestWithJavaSdkLibraryFiles,
- FixtureWithLastReleaseApis("foo"),
- android.FixtureWithRootAndroidBp(`
- platform_bootclasspath {
- name: "platform-bootclasspath",
- fragments: [
- {module:"bar-fragment"},
- ],
- hidden_api: {
- unsupported: [
- "unsupported.txt",
- ],
- removed: [
- "removed.txt",
- ],
- max_target_r_low_priority: [
- "max-target-r-low-priority.txt",
- ],
- max_target_q: [
- "max-target-q.txt",
- ],
- max_target_p: [
- "max-target-p.txt",
- ],
- max_target_o_low_priority: [
- "max-target-o-low-priority.txt",
- ],
- blocked: [
- "blocked.txt",
- ],
- unsupported_packages: [
- "unsupported-packages.txt",
- ],
- },
- }
-
- bootclasspath_fragment {
- name: "bar-fragment",
- contents: ["bar"],
- api: {
- stub_libs: ["foo"],
- },
- hidden_api: {
- unsupported: [
- "bar-unsupported.txt",
- ],
- removed: [
- "bar-removed.txt",
- ],
- max_target_r_low_priority: [
- "bar-max-target-r-low-priority.txt",
- ],
- max_target_q: [
- "bar-max-target-q.txt",
- ],
- max_target_p: [
- "bar-max-target-p.txt",
- ],
- max_target_o_low_priority: [
- "bar-max-target-o-low-priority.txt",
- ],
- blocked: [
- "bar-blocked.txt",
- ],
- unsupported_packages: [
- "bar-unsupported-packages.txt",
- ],
- },
- }
-
- java_library {
- name: "bar",
- srcs: ["a.java"],
- system_modules: "none",
- sdk_version: "none",
- compile_dex: true,
- }
-
- java_sdk_library {
- name: "foo",
- srcs: ["a.java"],
- public: {
- enabled: true,
- },
- compile_dex: true,
- }
- `),
- ).RunTest(t)
-
- pbcp := result.Module("platform-bootclasspath", "android_common")
- info := result.ModuleProvider(pbcp, monolithicHiddenAPIInfoProvider).(MonolithicHiddenAPIInfo)
-
- for _, category := range hiddenAPIFlagFileCategories {
- name := category.propertyName
- message := fmt.Sprintf("category %s", name)
- filename := strings.ReplaceAll(name, "_", "-")
- expected := []string{fmt.Sprintf("%s.txt", filename), fmt.Sprintf("bar-%s.txt", filename)}
- android.AssertPathsRelativeToTopEquals(t, message, expected, info.FlagsFilesByCategory[category])
- }
-
- android.AssertPathsRelativeToTopEquals(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common/modular-hiddenapi/stub-flags.csv"}, info.StubFlagsPaths)
- android.AssertPathsRelativeToTopEquals(t, "annotation flags", []string{"out/soong/.intermediates/bar-fragment/android_common/modular-hiddenapi/annotation-flags.csv"}, info.AnnotationFlagsPaths)
- android.AssertPathsRelativeToTopEquals(t, "metadata flags", []string{"out/soong/.intermediates/bar-fragment/android_common/modular-hiddenapi/metadata.csv"}, info.MetadataPaths)
- android.AssertPathsRelativeToTopEquals(t, "index flags", []string{"out/soong/.intermediates/bar-fragment/android_common/modular-hiddenapi/index.csv"}, info.IndexPaths)
- android.AssertPathsRelativeToTopEquals(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common/modular-hiddenapi/all-flags.csv"}, info.AllFlagsPaths)
-}
-
func TestPlatformBootclasspathVariant(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,