diff --git a/java/base.go b/java/base.go index 2f425cd83..8b258d6c8 100644 --- a/java/base.go +++ b/java/base.go @@ -1052,6 +1052,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...) var kotlinJars android.Paths + var kotlinHeaderJars android.Paths if srcFiles.HasExt(".kt") { // user defined kotlin flags. @@ -1109,18 +1110,22 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { } kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName) - kotlinCompile(ctx, kotlinJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags) + kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName) + kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags) if ctx.Failed() { return } // Make javac rule depend on the kotlinc rule - flags.classpath = append(flags.classpath, kotlinJar) + flags.classpath = append(classpath{kotlinHeaderJar}, flags.classpath...) kotlinJars = append(kotlinJars, kotlinJar) + kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar) + // Jar kotlin classes into the final jar after javac if BoolDefault(j.properties.Static_kotlin_stdlib, true) { kotlinJars = append(kotlinJars, deps.kotlinStdlib...) + kotlinHeaderJars = append(kotlinHeaderJars, deps.kotlinStdlib...) } else { flags.dexClasspath = append(flags.dexClasspath, deps.kotlinStdlib...) } @@ -1144,7 +1149,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { // with sharding enabled. See: b/77284273. } headerJarFileWithoutDepsOrJarjar, j.headerJarFile = - j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinJars) + j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinHeaderJars) if ctx.Failed() { return } diff --git a/java/config/kotlin.go b/java/config/kotlin.go index a83f87fb3..fc63f4dfb 100644 --- a/java/config/kotlin.go +++ b/java/config/kotlin.go @@ -34,6 +34,7 @@ func init() { pctx.SourcePathVariable("KotlinKaptJar", "external/kotlinc/lib/kotlin-annotation-processing.jar") pctx.SourcePathVariable("KotlinAnnotationJar", "external/kotlinc/lib/annotations-13.0.jar") pctx.SourcePathVariable("KotlinStdlibJar", KotlinStdlibJar) + pctx.SourcePathVariable("KotlinAbiGenPluginJar", "external/kotlinc/lib/jvm-abi-gen.jar") // These flags silence "Illegal reflective access" warnings when running kapt in OpenJDK9+ pctx.StaticVariable("KaptSuppressJDK9Warnings", strings.Join([]string{ diff --git a/java/kotlin.go b/java/kotlin.go index ce79bae16..eff5bb53f 100644 --- a/java/kotlin.go +++ b/java/kotlin.go @@ -28,17 +28,20 @@ import ( var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports{Goma: true}, blueprint.RuleParams{ - Command: `rm -rf "$classesDir" "$srcJarDir" "$kotlinBuildFile" "$emptyDir" && ` + - `mkdir -p "$classesDir" "$srcJarDir" "$emptyDir" && ` + + Command: `rm -rf "$classesDir" "$headerClassesDir" "$srcJarDir" "$kotlinBuildFile" "$emptyDir" && ` + + `mkdir -p "$classesDir" "$headerClassesDir" "$srcJarDir" "$emptyDir" && ` + `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` + `${config.GenKotlinBuildFileCmd} --classpath "$classpath" --name "$name"` + ` --out_dir "$classesDir" --srcs "$out.rsp" --srcs "$srcJarDir/list"` + ` $commonSrcFilesArg --out "$kotlinBuildFile" && ` + `${config.KotlincCmd} ${config.KotlincGlobalFlags} ` + - `${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} ` + - `$kotlincFlags -jvm-target $kotlinJvmTarget -Xbuild-file=$kotlinBuildFile ` + - `-kotlin-home $emptyDir && ` + - `${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir && ` + + ` ${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} ` + + ` $kotlincFlags -jvm-target $kotlinJvmTarget -Xbuild-file=$kotlinBuildFile ` + + ` -kotlin-home $emptyDir ` + + ` -Xplugin=${config.KotlinAbiGenPluginJar} ` + + ` -P plugin:org.jetbrains.kotlin.jvm.abi:outputDir=$headerClassesDir && ` + + `${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir -write_if_changed && ` + + `${config.SoongZipCmd} -jar -o $headerJar -C $headerClassesDir -D $headerClassesDir -write_if_changed && ` + `rm -rf "$srcJarDir"`, CommandDeps: []string{ "${config.KotlincCmd}", @@ -49,15 +52,17 @@ var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports "${config.KotlinStdlibJar}", "${config.KotlinTrove4jJar}", "${config.KotlinAnnotationJar}", + "${config.KotlinAbiGenPluginJar}", "${config.GenKotlinBuildFileCmd}", "${config.SoongZipCmd}", "${config.ZipSyncCmd}", }, Rspfile: "$out.rsp", RspfileContent: `$in`, + Restat: true, }, "kotlincFlags", "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "classesDir", - "kotlinJvmTarget", "kotlinBuildFile", "emptyDir", "name") + "headerClassesDir", "headerJar", "kotlinJvmTarget", "kotlinBuildFile", "emptyDir", "name") func kotlinCommonSrcsList(ctx android.ModuleContext, commonSrcFiles android.Paths) android.OptionalPath { if len(commonSrcFiles) > 0 { @@ -76,7 +81,7 @@ func kotlinCommonSrcsList(ctx android.ModuleContext, commonSrcFiles android.Path } // kotlinCompile takes .java and .kt sources and srcJars, and compiles the .kt sources into a classes jar in outputFile. -func kotlinCompile(ctx android.ModuleContext, outputFile android.WritablePath, +func kotlinCompile(ctx android.ModuleContext, outputFile, headerOutputFile android.WritablePath, srcFiles, commonSrcFiles, srcJars android.Paths, flags javaBuilderFlags) { @@ -97,17 +102,20 @@ func kotlinCompile(ctx android.ModuleContext, outputFile android.WritablePath, } ctx.Build(pctx, android.BuildParams{ - Rule: kotlinc, - Description: "kotlinc", - Output: outputFile, - Inputs: srcFiles, - Implicits: deps, + Rule: kotlinc, + Description: "kotlinc", + Output: outputFile, + ImplicitOutput: headerOutputFile, + Inputs: srcFiles, + Implicits: deps, Args: map[string]string{ "classpath": flags.kotlincClasspath.FormJavaClassPath(""), "kotlincFlags": flags.kotlincFlags, "commonSrcFilesArg": commonSrcFilesArg, "srcJars": strings.Join(srcJars.Strings(), " "), "classesDir": android.PathForModuleOut(ctx, "kotlinc", "classes").String(), + "headerClassesDir": android.PathForModuleOut(ctx, "kotlinc", "header_classes").String(), + "headerJar": headerOutputFile.String(), "srcJarDir": android.PathForModuleOut(ctx, "kotlinc", "srcJars").String(), "kotlinBuildFile": android.PathForModuleOut(ctx, "kotlinc-build.xml").String(), "emptyDir": android.PathForModuleOut(ctx, "kotlinc", "empty").String(), diff --git a/java/kotlin_test.go b/java/kotlin_test.go index d51bc041d..f9ff98229 100644 --- a/java/kotlin_test.go +++ b/java/kotlin_test.go @@ -45,6 +45,10 @@ func TestKotlin(t *testing.T) { fooKotlinc := ctx.ModuleForTests("foo", "android_common").Rule("kotlinc") fooJavac := ctx.ModuleForTests("foo", "android_common").Rule("javac") fooJar := ctx.ModuleForTests("foo", "android_common").Output("combined/foo.jar") + fooHeaderJar := ctx.ModuleForTests("foo", "android_common").Output("turbine-combined/foo.jar") + + fooKotlincClasses := fooKotlinc.Output + fooKotlincHeaderClasses := fooKotlinc.ImplicitOutput if len(fooKotlinc.Inputs) != 2 || fooKotlinc.Inputs[0].String() != "a.java" || fooKotlinc.Inputs[1].String() != "b.kt" { @@ -55,17 +59,21 @@ func TestKotlin(t *testing.T) { t.Errorf(`foo inputs %v != ["a.java"]`, fooJavac.Inputs) } - if !strings.Contains(fooJavac.Args["classpath"], fooKotlinc.Output.String()) { + if !strings.Contains(fooJavac.Args["classpath"], fooKotlincHeaderClasses.String()) { t.Errorf("foo classpath %v does not contain %q", - fooJavac.Args["classpath"], fooKotlinc.Output.String()) + fooJavac.Args["classpath"], fooKotlincHeaderClasses.String()) } - if !inList(fooKotlinc.Output.String(), fooJar.Inputs.Strings()) { + if !inList(fooKotlincClasses.String(), fooJar.Inputs.Strings()) { t.Errorf("foo jar inputs %v does not contain %q", - fooJar.Inputs.Strings(), fooKotlinc.Output.String()) + fooJar.Inputs.Strings(), fooKotlincClasses.String()) + } + + if !inList(fooKotlincHeaderClasses.String(), fooHeaderJar.Inputs.Strings()) { + t.Errorf("foo header jar inputs %v does not contain %q", + fooHeaderJar.Inputs.Strings(), fooKotlincHeaderClasses.String()) } - fooHeaderJar := ctx.ModuleForTests("foo", "android_common").Output("turbine-combined/foo.jar") bazHeaderJar := ctx.ModuleForTests("baz", "android_common").Output("turbine-combined/baz.jar") barKotlinc := ctx.ModuleForTests("bar", "android_common").Rule("kotlinc")