From 9ca38d22a49127901dadb14ffa093e29a2942f2d Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 18 Jun 2020 15:46:32 -0700 Subject: [PATCH 1/3] Fix annotation processors in kotlin modules that generate resources The kapt rule was only keeping the generated sources, and not the generated classes directory. The generated classes directory will contain resources generated by the annotation processor and needs to be added to the final jar. Test: m ApiFinder Bug: 153485543 Change-Id: I89197d0afcb1eee011c01aa400f9977e66f43768 --- java/java.go | 4 +++- java/kotlin.go | 21 +++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/java/java.go b/java/java.go index 97a674745..3ce25759a 100644 --- a/java/java.go +++ b/java/java.go @@ -1350,8 +1350,10 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { if len(flags.processorPath) > 0 { // Use kapt for annotation processing kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar") - kotlinKapt(ctx, kaptSrcJar, kotlinSrcFiles, srcJars, flags) + kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar") + kotlinKapt(ctx, kaptSrcJar, kaptResJar, kotlinSrcFiles, srcJars, flags) srcJars = append(srcJars, kaptSrcJar) + kotlinJars = append(kotlinJars, kaptResJar) // Disable annotation processing in javac, it's already been handled by kapt flags.processorPath = nil flags.processors = nil diff --git a/java/kotlin.go b/java/kotlin.go index 9b160a082..673970b9c 100644 --- a/java/kotlin.go +++ b/java/kotlin.go @@ -90,7 +90,8 @@ func kotlinCompile(ctx android.ModuleContext, outputFile android.WritablePath, var kapt = pctx.AndroidRemoteStaticRule("kapt", android.RemoteRuleSupports{Goma: true}, blueprint.RuleParams{ - Command: `rm -rf "$srcJarDir" "$kotlinBuildFile" "$kaptDir" && mkdir -p "$srcJarDir" "$kaptDir" && ` + + Command: `rm -rf "$srcJarDir" "$kotlinBuildFile" "$kaptDir" && ` + + `mkdir -p "$srcJarDir" "$kaptDir/sources" "$kaptDir/classes" && ` + `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` + `${config.GenKotlinBuildFileCmd} $classpath "$name" "" $out.rsp $srcJarDir/list > $kotlinBuildFile &&` + `${config.KotlincCmd} ${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} $kotlincFlags ` + @@ -105,6 +106,7 @@ var kapt = pctx.AndroidRemoteStaticRule("kapt", android.RemoteRuleSupports{Goma: `$kaptProcessor ` + `-Xbuild-file=$kotlinBuildFile && ` + `${config.SoongZipCmd} -jar -o $out -C $kaptDir/sources -D $kaptDir/sources && ` + + `${config.SoongZipCmd} -jar -o $classesJarOut -C $kaptDir/classes -D $kaptDir/classes && ` + `rm -rf "$srcJarDir"`, CommandDeps: []string{ "${config.KotlincCmd}", @@ -118,13 +120,14 @@ var kapt = pctx.AndroidRemoteStaticRule("kapt", android.RemoteRuleSupports{Goma: RspfileContent: `$in`, }, "kotlincFlags", "encodedJavacFlags", "kaptProcessorPath", "kaptProcessor", - "classpath", "srcJars", "srcJarDir", "kaptDir", "kotlinJvmTarget", "kotlinBuildFile", "name") + "classpath", "srcJars", "srcJarDir", "kaptDir", "kotlinJvmTarget", "kotlinBuildFile", "name", + "classesJarOut") // 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 // added as an additional input to kotlinc and javac rules, and the javac rule should have annotation processing // disabled. -func kotlinKapt(ctx android.ModuleContext, outputFile android.WritablePath, +func kotlinKapt(ctx android.ModuleContext, srcJarOutputFile, resJarOutputFile android.WritablePath, srcFiles, srcJars android.Paths, flags javaBuilderFlags) { @@ -152,11 +155,12 @@ func kotlinKapt(ctx android.ModuleContext, outputFile android.WritablePath, kotlinName = strings.ReplaceAll(kotlinName, "/", "__") ctx.Build(pctx, android.BuildParams{ - Rule: kapt, - Description: "kapt", - Output: outputFile, - Inputs: srcFiles, - Implicits: deps, + Rule: kapt, + Description: "kapt", + Output: srcJarOutputFile, + ImplicitOutput: resJarOutputFile, + Inputs: srcFiles, + Implicits: deps, Args: map[string]string{ "classpath": flags.kotlincClasspath.FormJavaClassPath("-classpath"), "kotlincFlags": flags.kotlincFlags, @@ -168,6 +172,7 @@ func kotlinKapt(ctx android.ModuleContext, outputFile android.WritablePath, "kaptDir": android.PathForModuleOut(ctx, "kapt/gen").String(), "encodedJavacFlags": encodedJavacFlags, "name": kotlinName, + "classesJarOut": resJarOutputFile.String(), }, }) } From 0b67a8bd0fc87c7c584d165abfeeb9314ce22f18 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 18 Jun 2020 15:52:01 -0700 Subject: [PATCH 2/3] Allow kotlin modules to skip packaging the kotlin stdlib Host tools like lint may package their own version of the kotlin stdlib, and any jars loaded by them shouldn't contain the platform version. Add a static_kotlin_stdlib property that defaults to true to allow building the module without staticalling including the kotlin stdlib. Bug: 153485543 Test: m ApiFinder Change-Id: I7da78ef493806ce4ab0050e4ee9e8d330b0509c8 --- java/java.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/java/java.go b/java/java.go index 3ce25759a..7ef55c97e 100644 --- a/java/java.go +++ b/java/java.go @@ -253,6 +253,9 @@ type CompilerProperties struct { // List of files to include in the META-INF/services folder of the resulting jar. Services []string `android:"path,arch_variant"` + + // If true, package the kotlin stdlib into the jar. Defaults to true. + Static_kotlin_stdlib *bool `android:"arch_variant"` } type CompilerDeviceProperties struct { @@ -1368,9 +1371,11 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { // Make javac rule depend on the kotlinc rule flags.classpath = append(flags.classpath, kotlinJar) - // Jar kotlin classes into the final jar after javac kotlinJars = append(kotlinJars, kotlinJar) - kotlinJars = append(kotlinJars, deps.kotlinStdlib...) + // Jar kotlin classes into the final jar after javac + if BoolDefault(j.properties.Static_kotlin_stdlib, true) { + kotlinJars = append(kotlinJars, deps.kotlinStdlib...) + } } jars := append(android.Paths(nil), kotlinJars...) From 92e4b46af561503506b54f9e4c925615bd03a069 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 18 Jun 2020 15:56:48 -0700 Subject: [PATCH 3/3] Support adding extra lint checks Add a lint.extra_check_modules property to list modules to use as plugins to Lint. Bug: 153485543 Test: m checkbuild Change-Id: I25c7799438cfec43163e757637c65b8657488d36 --- java/java.go | 3 +++ java/lint.go | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/java/java.go b/java/java.go index 7ef55c97e..7a4255745 100644 --- a/java/java.go +++ b/java/java.go @@ -579,6 +579,7 @@ var ( certificateTag = dependencyTag{name: "certificate"} instrumentationForTag = dependencyTag{name: "instrumentation_for"} usesLibTag = dependencyTag{name: "uses-library"} + extraLintCheckTag = dependencyTag{name: "extra-lint-check"} ) func IsLibDepTag(depTag blueprint.DependencyTag) bool { @@ -690,6 +691,8 @@ func (j *Module) AvailableFor(what string) bool { func (j *Module) deps(ctx android.BottomUpMutatorContext) { if ctx.Device() { + j.linter.deps(ctx) + sdkDep := decodeSdkDep(ctx, sdkContext(j)) if sdkDep.useDefaultLibs { ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...) diff --git a/java/lint.go b/java/lint.go index 441e110cd..fac9a1983 100644 --- a/java/lint.go +++ b/java/lint.go @@ -42,6 +42,9 @@ type LintProperties struct { // Checks that should be skipped. Disabled_checks []string + + // Modules that provide extra lint checks + Extra_check_modules []string } } @@ -76,6 +79,14 @@ func (l *linter) enabled() bool { return BoolDefault(l.properties.Lint.Enabled, true) } +func (l *linter) deps(ctx android.BottomUpMutatorContext) { + if !l.enabled() { + return + } + + ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), extraLintCheckTag, l.properties.Lint.Extra_check_modules...) +} + func (l *linter) writeLintProjectXML(ctx android.ModuleContext, rule *android.RuleBuilder) (projectXMLPath, configXMLPath, cacheDir android.WritablePath, deps android.Paths) { @@ -179,6 +190,16 @@ func (l *linter) lint(ctx android.ModuleContext) { return } + extraLintCheckModules := ctx.GetDirectDepsWithTag(extraLintCheckTag) + for _, extraLintCheckModule := range extraLintCheckModules { + if dep, ok := extraLintCheckModule.(Dependency); ok { + l.extraLintCheckJars = append(l.extraLintCheckJars, dep.ImplementationAndResourcesJars()...) + } else { + ctx.PropertyErrorf("lint.extra_check_modules", + "%s is not a java module", ctx.OtherModuleName(extraLintCheckModule)) + } + } + rule := android.NewRuleBuilder() if l.manifest == nil {