Replace annotation_processors with plugins
Follow bazel's modules for annotation processors by introducing a java_plugin module type that can contain extra metadata about the annotation processor, the processor class and a flag to specify if the annotation processor is compatible with the turbine optimization. Deprecate the annotation_processors property, which took a list of java_library_host modules, in favor of the plugins property, which takes a list of java_plugin modules. The annotation_processors property will be removed once all uses have been replaced with plugins. Bug: 77284273 Test: plugin_test.go Test: m caliper Change-Id: I37c1e80eba71ae2d6a06199fb102194a51994989
This commit is contained in:
parent
c4efd9cb55
commit
be9cdb8d64
|
@ -249,6 +249,7 @@ bootstrap_go_package {
|
|||
"java/jdeps.go",
|
||||
"java/java_resources.go",
|
||||
"java/kotlin.go",
|
||||
"java/plugin.go",
|
||||
"java/prebuilt_apis.go",
|
||||
"java/proto.go",
|
||||
"java/sdk.go",
|
||||
|
@ -262,6 +263,7 @@ bootstrap_go_package {
|
|||
"java/java_test.go",
|
||||
"java/jdeps_test.go",
|
||||
"java/kotlin_test.go",
|
||||
"java/plugin_test.go",
|
||||
"java/sdk_test.go",
|
||||
],
|
||||
pluginFor: ["soong_build"],
|
||||
|
|
|
@ -44,7 +44,7 @@ var (
|
|||
`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
|
||||
`(if [ -s $srcJarDir/list ] || [ -s $out.rsp ] ; then ` +
|
||||
`${config.SoongJavacWrapper} ${config.JavacWrapper}${config.JavacCmd} ${config.JavacHeapFlags} ${config.CommonJdkFlags} ` +
|
||||
`$processorpath $javacFlags $bootClasspath $classpath ` +
|
||||
`$processorpath $processor $javacFlags $bootClasspath $classpath ` +
|
||||
`-source $javaVersion -target $javaVersion ` +
|
||||
`-d $outDir -s $annoDir @$out.rsp @$srcJarDir/list ; fi ) && ` +
|
||||
`${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir`,
|
||||
|
@ -57,7 +57,7 @@ var (
|
|||
Rspfile: "$out.rsp",
|
||||
RspfileContent: "$in",
|
||||
},
|
||||
"javacFlags", "bootClasspath", "classpath", "processorpath", "srcJars", "srcJarDir",
|
||||
"javacFlags", "bootClasspath", "classpath", "processorpath", "processor", "srcJars", "srcJarDir",
|
||||
"outDir", "annoDir", "javaVersion")
|
||||
|
||||
turbine = pctx.AndroidStaticRule("turbine",
|
||||
|
@ -141,6 +141,7 @@ type javaBuilderFlags struct {
|
|||
bootClasspath classpath
|
||||
classpath classpath
|
||||
processorPath classpath
|
||||
processor string
|
||||
systemModules classpath
|
||||
aidlFlags string
|
||||
javaVersion string
|
||||
|
@ -254,6 +255,12 @@ func transformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab
|
|||
deps = append(deps, flags.classpath...)
|
||||
deps = append(deps, flags.processorPath...)
|
||||
|
||||
// TODO(b/77284273): pass -processor:none if no plugins are listed
|
||||
processor := ""
|
||||
if flags.processor != "" {
|
||||
processor = "-processor " + flags.processor
|
||||
}
|
||||
|
||||
srcJarDir := "srcjars"
|
||||
outDir := "classes"
|
||||
annoDir := "anno"
|
||||
|
@ -274,6 +281,7 @@ func transformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab
|
|||
"bootClasspath": bootClasspath,
|
||||
"classpath": flags.classpath.FormJavaClassPath("-classpath"),
|
||||
"processorpath": flags.processorPath.FormJavaClassPath("-processorpath"),
|
||||
"processor": processor,
|
||||
"srcJars": strings.Join(srcJars.Strings(), " "),
|
||||
"srcJarDir": android.PathForModuleOut(ctx, intermediatesDir, srcJarDir).String(),
|
||||
"outDir": android.PathForModuleOut(ctx, intermediatesDir, outDir).String(),
|
||||
|
|
28
java/java.go
28
java/java.go
|
@ -114,11 +114,11 @@ type CompilerProperties struct {
|
|||
// If set to true, include sources used to compile the module in to the final jar
|
||||
Include_srcs *bool
|
||||
|
||||
// List of modules to use as annotation processors
|
||||
// List of modules to use as annotation processors. Deprecated, use plugins instead.
|
||||
Annotation_processors []string
|
||||
|
||||
// List of classes to pass to javac to use as annotation processors
|
||||
Annotation_processor_classes []string
|
||||
// List of modules to use as annotation processors
|
||||
Plugins []string
|
||||
|
||||
// The number of Java source entries each Javac instance can process
|
||||
Javac_shard_size *int64
|
||||
|
@ -377,6 +377,7 @@ var (
|
|||
staticLibTag = dependencyTag{name: "staticlib"}
|
||||
libTag = dependencyTag{name: "javalib"}
|
||||
annoTag = dependencyTag{name: "annotation processor"}
|
||||
pluginTag = dependencyTag{name: "plugin"}
|
||||
bootClasspathTag = dependencyTag{name: "bootclasspath"}
|
||||
systemModulesTag = dependencyTag{name: "system modules"}
|
||||
frameworkResTag = dependencyTag{name: "framework-res"}
|
||||
|
@ -474,6 +475,10 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {
|
|||
{Mutator: "arch", Variation: ctx.Config().BuildOsCommonVariant},
|
||||
}, annoTag, j.properties.Annotation_processors...)
|
||||
|
||||
ctx.AddFarVariationDependencies([]blueprint.Variation{
|
||||
{Mutator: "arch", Variation: ctx.Config().BuildOsCommonVariant},
|
||||
}, pluginTag, j.properties.Plugins...)
|
||||
|
||||
android.ExtractSourcesDeps(ctx, j.properties.Srcs)
|
||||
android.ExtractSourcesDeps(ctx, j.properties.Exclude_srcs)
|
||||
android.ExtractSourcesDeps(ctx, j.properties.Java_resources)
|
||||
|
@ -563,6 +568,7 @@ type deps struct {
|
|||
classpath classpath
|
||||
bootClasspath classpath
|
||||
processorPath classpath
|
||||
processorClasses []string
|
||||
staticJars android.Paths
|
||||
staticHeaderJars android.Paths
|
||||
staticResourceJars android.Paths
|
||||
|
@ -573,6 +579,8 @@ type deps struct {
|
|||
aidlPreprocess android.OptionalPath
|
||||
kotlinStdlib android.Paths
|
||||
kotlinAnnotations android.Paths
|
||||
|
||||
disableTurbine bool
|
||||
}
|
||||
|
||||
func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) {
|
||||
|
@ -712,6 +720,16 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
|
|||
j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
|
||||
case annoTag:
|
||||
deps.processorPath = append(deps.processorPath, dep.ImplementationAndResourcesJars()...)
|
||||
case pluginTag:
|
||||
if plugin, ok := dep.(*Plugin); ok {
|
||||
deps.processorPath = append(deps.processorPath, dep.ImplementationAndResourcesJars()...)
|
||||
if plugin.pluginProperties.Processor_class != nil {
|
||||
deps.processorClasses = append(deps.processorClasses, *plugin.pluginProperties.Processor_class)
|
||||
}
|
||||
deps.disableTurbine = deps.disableTurbine || Bool(plugin.pluginProperties.Generates_api)
|
||||
} else {
|
||||
ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
|
||||
}
|
||||
case frameworkResTag:
|
||||
if (ctx.ModuleName() == "framework") || (ctx.ModuleName() == "framework-annotation-proc") {
|
||||
// framework.jar has a one-off dependency on the R.java and Manifest.java files
|
||||
|
@ -859,6 +877,8 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
|
|||
flags.classpath = append(flags.classpath, deps.classpath...)
|
||||
flags.processorPath = append(flags.processorPath, deps.processorPath...)
|
||||
|
||||
flags.processor = strings.Join(deps.processorClasses, ",")
|
||||
|
||||
if len(flags.bootClasspath) == 0 && ctx.Host() && flags.javaVersion != "1.9" &&
|
||||
!Bool(j.properties.No_standard_libs) &&
|
||||
inList(flags.javaVersion, []string{"1.6", "1.7", "1.8"}) {
|
||||
|
@ -1020,7 +1040,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
|
|||
j.compiledSrcJars = srcJars
|
||||
|
||||
enable_sharding := false
|
||||
if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") {
|
||||
if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !deps.disableTurbine {
|
||||
if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
|
||||
enable_sharding = true
|
||||
// Formerly, there was a check here that prevented annotation processors
|
||||
|
|
|
@ -83,6 +83,7 @@ func testContext(config android.Config, bp string,
|
|||
ctx.RegisterModuleType("java_defaults", android.ModuleFactoryAdaptor(defaultsFactory))
|
||||
ctx.RegisterModuleType("java_system_modules", android.ModuleFactoryAdaptor(SystemModulesFactory))
|
||||
ctx.RegisterModuleType("java_genrule", android.ModuleFactoryAdaptor(genRuleFactory))
|
||||
ctx.RegisterModuleType("java_plugin", android.ModuleFactoryAdaptor(PluginFactory))
|
||||
ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
|
||||
ctx.RegisterModuleType("genrule", android.ModuleFactoryAdaptor(genrule.GenRuleFactory))
|
||||
ctx.RegisterModuleType("droiddoc", android.ModuleFactoryAdaptor(DroiddocFactory))
|
||||
|
|
|
@ -87,6 +87,7 @@ var kapt = pctx.AndroidGomaStaticRule("kapt",
|
|||
`-P plugin:org.jetbrains.kotlin.kapt3:aptMode=stubsAndApt ` +
|
||||
`-P plugin:org.jetbrains.kotlin.kapt3:javacArguments=$encodedJavacFlags ` +
|
||||
`$kaptProcessorPath ` +
|
||||
`$kaptProcessor ` +
|
||||
`-Xbuild-file=$kotlinBuildFile && ` +
|
||||
`${config.SoongZipCmd} -jar -o $out -C $kaptDir/sources -D $kaptDir/sources`,
|
||||
CommandDeps: []string{
|
||||
|
@ -100,7 +101,8 @@ var kapt = pctx.AndroidGomaStaticRule("kapt",
|
|||
Rspfile: "$out.rsp",
|
||||
RspfileContent: `$in`,
|
||||
},
|
||||
"kotlincFlags", "encodedJavacFlags", "kaptProcessorPath", "classpath", "srcJars", "srcJarDir", "kaptDir", "kotlinJvmTarget", "kotlinBuildFile")
|
||||
"kotlincFlags", "encodedJavacFlags", "kaptProcessorPath", "kaptProcessor",
|
||||
"classpath", "srcJars", "srcJarDir", "kaptDir", "kotlinJvmTarget", "kotlinBuildFile")
|
||||
|
||||
// kotlinKapt performs Kotlin-compatible annotation processing. It takes .kt and .java sources and srcjars, and runs
|
||||
// annotation processors over all of them, producing a srcjar of generated code in outputFile. The srcjar should be
|
||||
|
@ -117,6 +119,11 @@ func kotlinKapt(ctx android.ModuleContext, outputFile android.WritablePath,
|
|||
|
||||
kaptProcessorPath := flags.processorPath.FormTurbineClasspath("-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=")
|
||||
|
||||
kaptProcessor := ""
|
||||
if flags.processor != "" {
|
||||
kaptProcessor = "-P plugin:org.jetbrains.kotlin.kapt3:processor=" + flags.processor
|
||||
}
|
||||
|
||||
encodedJavacFlags := kaptEncodeFlags([][2]string{
|
||||
{"-source", flags.javaVersion},
|
||||
{"-target", flags.javaVersion},
|
||||
|
@ -135,6 +142,7 @@ func kotlinKapt(ctx android.ModuleContext, outputFile android.WritablePath,
|
|||
"srcJarDir": android.PathForModuleOut(ctx, "kapt", "srcJars").String(),
|
||||
"kotlinBuildFile": android.PathForModuleOut(ctx, "kapt", "build.xml").String(),
|
||||
"kaptProcessorPath": strings.Join(kaptProcessorPath, " "),
|
||||
"kaptProcessor": kaptProcessor,
|
||||
"kaptDir": android.PathForModuleOut(ctx, "kapt/gen").String(),
|
||||
"encodedJavacFlags": encodedJavacFlags,
|
||||
},
|
||||
|
|
|
@ -87,10 +87,10 @@ func TestKapt(t *testing.T) {
|
|||
java_library {
|
||||
name: "foo",
|
||||
srcs: ["a.java", "b.kt"],
|
||||
annotation_processors: ["bar"],
|
||||
plugins: ["bar"],
|
||||
}
|
||||
|
||||
java_library_host {
|
||||
java_plugin {
|
||||
name: "bar",
|
||||
}
|
||||
`)
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright 2019 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 "android/soong/android"
|
||||
|
||||
func init() {
|
||||
android.RegisterModuleType("java_plugin", PluginFactory)
|
||||
}
|
||||
|
||||
// A java_plugin module describes a host java library that will be used by javac as an annotation processor.
|
||||
func PluginFactory() android.Module {
|
||||
module := &Plugin{}
|
||||
|
||||
module.AddProperties(
|
||||
&module.Module.properties,
|
||||
&module.Module.protoProperties,
|
||||
&module.pluginProperties)
|
||||
|
||||
InitJavaModule(module, android.HostSupported)
|
||||
return module
|
||||
}
|
||||
|
||||
type Plugin struct {
|
||||
Library
|
||||
|
||||
pluginProperties PluginProperties
|
||||
}
|
||||
|
||||
type PluginProperties struct {
|
||||
// The optional name of the class that javac will use to run the annotation processor.
|
||||
Processor_class *string
|
||||
|
||||
// If true, assume the annotation processor will generate classes that are referenced from outside the module.
|
||||
// This necessitates disabling the turbine optimization on modules that use this plugin, which will reduce
|
||||
// parallelism and cause more recompilation for modules that depend on modules that use this plugin.
|
||||
Generates_api *bool
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
// Copyright 2019 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 (
|
||||
"android/soong/android"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNoPlugin(t *testing.T) {
|
||||
ctx := testJava(t, `
|
||||
java_library {
|
||||
name: "foo",
|
||||
srcs: ["a.java"],
|
||||
}
|
||||
`)
|
||||
|
||||
javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
|
||||
turbine := ctx.ModuleForTests("foo", "android_common").MaybeRule("turbine")
|
||||
|
||||
if turbine.Rule == nil {
|
||||
t.Errorf("expected turbine to be enabled")
|
||||
}
|
||||
|
||||
if javac.Args["processsorpath"] != "" {
|
||||
t.Errorf("want empty processorpath, got %q", javac.Args["processorpath"])
|
||||
}
|
||||
|
||||
// TODO(b/77284273): test for -processor:none if no plugins are enabled
|
||||
if javac.Args["processor"] != "" {
|
||||
t.Errorf("want no -processor argument, got %q", javac.Args["processor"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlugin(t *testing.T) {
|
||||
ctx := testJava(t, `
|
||||
java_library {
|
||||
name: "foo",
|
||||
srcs: ["a.java"],
|
||||
plugins: ["bar"],
|
||||
}
|
||||
|
||||
java_plugin {
|
||||
name: "bar",
|
||||
processor_class: "com.bar",
|
||||
srcs: ["b.java"],
|
||||
}
|
||||
`)
|
||||
|
||||
buildOS := android.BuildOs.String()
|
||||
|
||||
javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
|
||||
turbine := ctx.ModuleForTests("foo", "android_common").MaybeRule("turbine")
|
||||
|
||||
if turbine.Rule == nil {
|
||||
t.Errorf("expected turbine to be enabled")
|
||||
}
|
||||
|
||||
bar := ctx.ModuleForTests("bar", buildOS+"_common").Rule("javac").Output.String()
|
||||
|
||||
if !inList(bar, javac.Implicits.Strings()) {
|
||||
t.Errorf("foo implicits %v does not contain %q", javac.Implicits.Strings(), bar)
|
||||
}
|
||||
|
||||
if javac.Args["processorpath"] != "-processorpath "+bar {
|
||||
t.Errorf("foo processorpath %q != '-processorpath %s'", javac.Args["processorpath"], bar)
|
||||
}
|
||||
|
||||
if javac.Args["processor"] != "-processor com.bar" {
|
||||
t.Errorf("foo processor %q != '-processor com.bar'", javac.Args["processor"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestPluginGeneratesApi(t *testing.T) {
|
||||
ctx := testJava(t, `
|
||||
java_library {
|
||||
name: "foo",
|
||||
srcs: ["a.java"],
|
||||
plugins: ["bar"],
|
||||
}
|
||||
|
||||
java_plugin {
|
||||
name: "bar",
|
||||
processor_class: "com.bar",
|
||||
generates_api: true,
|
||||
srcs: ["b.java"],
|
||||
}
|
||||
`)
|
||||
|
||||
buildOS := android.BuildOs.String()
|
||||
|
||||
javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
|
||||
turbine := ctx.ModuleForTests("foo", "android_common").MaybeRule("turbine")
|
||||
|
||||
if turbine.Rule != nil {
|
||||
t.Errorf("expected turbine to be disabled")
|
||||
}
|
||||
|
||||
bar := ctx.ModuleForTests("bar", buildOS+"_common").Rule("javac").Output.String()
|
||||
|
||||
if !inList(bar, javac.Implicits.Strings()) {
|
||||
t.Errorf("foo implicits %v does not contain %q", javac.Implicits.Strings(), bar)
|
||||
}
|
||||
|
||||
if javac.Args["processorpath"] != "-processorpath "+bar {
|
||||
t.Errorf("foo processorpath %q != '-processorpath %s'", javac.Args["processorpath"], bar)
|
||||
}
|
||||
|
||||
if javac.Args["processor"] != "-processor com.bar" {
|
||||
t.Errorf("foo processor %q != '-processor com.bar'", javac.Args["processor"])
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue