aboutsummaryrefslogtreecommitdiff
path: root/java/kotlin.go
diff options
context:
space:
mode:
Diffstat (limited to 'java/kotlin.go')
-rw-r--r--java/kotlin.go260
1 files changed, 219 insertions, 41 deletions
diff --git a/java/kotlin.go b/java/kotlin.go
index 308bb0305..68890bdda 100644
--- a/java/kotlin.go
+++ b/java/kotlin.go
@@ -26,25 +26,99 @@ import (
"github.com/google/blueprint"
)
-var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports{Goma: true},
+type KotlinCompileData struct {
+ pcStateFileNew android.OutputPath
+ pcStateFilePrior android.OutputPath
+ diffFile android.OutputPath
+}
+
+const inputDeltaCmd = `${config.FindInputDeltaCmd} --target "$out" ` +
+ `--inputs_file "$out.rsp" --new_state "$newStateFile" --prior_state "$priorStateFile" > $sourceDeltaFile`
+
+const nonIncKotlinCmd = `rm -rf "$classesDir" "$headerClassesDir" "$srcJarDir" "$kotlinBuildFile" "$emptyDir" && ` +
+ `mkdir -p "$classesDir" "$headerClassesDir" "$srcJarDir" "$emptyDir" && ` +
+ `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" -f "*.kt" $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 $composePluginFlag $kotlincPluginFlags -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" "$classesDir" "$headerClassesDir" `
+
+const moveDeltaStateFile = `mv $newStateFile $priorStateFile && rm $sourceDeltaFile`
+
+var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports{},
blueprint.RuleParams{
- Command: `rm -rf "$classesDir" "$headerClassesDir" "$srcJarDir" "$kotlinBuildFile" "$emptyDir" && ` +
- `mkdir -p "$classesDir" "$headerClassesDir" "$srcJarDir" "$emptyDir" && ` +
+ Command: inputDeltaCmd + ` && ` + nonIncKotlinCmd + ` && ` + moveDeltaStateFile,
+ CommandDeps: []string{
+ "${config.FindInputDeltaCmd}",
+ "${config.KotlincCmd}",
+ "${config.KotlinCompilerJar}",
+ "${config.KotlinPreloaderJar}",
+ "${config.KotlinReflectJar}",
+ "${config.KotlinScriptRuntimeJar}",
+ "${config.KotlinStdlibJar}",
+ "${config.KotlinTrove4jJar}",
+ "${config.KotlinAnnotationJar}",
+ "${config.KotlinAbiGenPluginJar}",
+ "${config.GenKotlinBuildFileCmd}",
+ "${config.SoongZipCmd}",
+ "${config.ZipSyncCmd}",
+ },
+ Rspfile: "$out.rsp",
+ RspfileContent: `$in`,
+ Restat: true,
+ },
+ "kotlincFlags", "composePluginFlag", "kotlincPluginFlags", "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir",
+ "classesDir", "headerClassesDir", "headerJar", "kotlinJvmTarget", "kotlinBuildFile", "emptyDir",
+ "newStateFile", "priorStateFile", "sourceDeltaFile", "name")
+
+// TODO: does incremental work with RBE?
+var kotlinIncremental = pctx.AndroidRemoteStaticRule("kotlin-incremental", android.RemoteRuleSupports{},
+ blueprint.RuleParams{
+ Command: // Incremental
+
+ inputDeltaCmd + ` && ` +
+
+ `if [ "$$SOONG_USE_PARTIAL_COMPILE" = "true" ]; then ` +
+ `rm -rf "$srcJarDir" "$kotlinBuildFile" "$emptyDir" && ` +
+ `mkdir -p "$headerClassesDir" "$srcJarDir" "$emptyDir" && ` +
`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" -f "*.kt" $srcJars && ` +
`${config.GenKotlinBuildFileCmd} --classpath "$classpath" --name "$name"` +
` --out_dir "$classesDir" --srcs "$out.rsp" --srcs "$srcJarDir/list"` +
` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
- `${config.KotlincCmd} ${config.KotlincGlobalFlags} ` +
+ `${config.KotlinIncrementalClientBinary} ${config.KotlincGlobalFlags} ` +
` ${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} ` +
- ` $kotlincFlags -jvm-target $kotlinJvmTarget -Xbuild-file=$kotlinBuildFile ` +
- ` -kotlin-home $emptyDir ` +
+ ` $kotlincFlags $composeEmbeddablePluginFlag $kotlincPluginFlags ` +
+ ` -jvm-target $kotlinJvmTarget -build-file=$kotlinBuildFile ` +
+ ` -source-delta-file=$sourceDeltaFile` +
+ ` -kotlin-home=$emptyDir ` +
+ ` -root-dir=$incrementalRootDir` +
+ ` -output-dir=$outputDir` +
+ ` -build-dir=$buildDir ` +
+ ` -working-dir=$workDir ` +
` -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" "$classesDir" "$headerClassesDir"`,
+ `rm -rf "$srcJarDir" ; ` +
+
+ // Else non incremental
+ `else ` +
+ nonIncKotlinCmd + ` ; ` +
+ `fi && ` +
+ moveDeltaStateFile,
+
CommandDeps: []string{
+ "${config.FindInputDeltaCmd}",
"${config.KotlincCmd}",
+ "${config.KotlinIncrementalClientBinary}",
"${config.KotlinCompilerJar}",
"${config.KotlinPreloaderJar}",
"${config.KotlinReflectJar}",
@@ -61,8 +135,9 @@ var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports
RspfileContent: `$in`,
Restat: true,
},
- "kotlincFlags", "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "classesDir",
- "headerClassesDir", "headerJar", "kotlinJvmTarget", "kotlinBuildFile", "emptyDir", "name")
+ "kotlincFlags", "composeEmbeddablePluginFlag", "composePluginFlag", "kotlincPluginFlags", "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "incrementalRootDir",
+ "classesDir", "headerClassesDir", "headerJar", "kotlinJvmTarget", "kotlinBuildFile", "emptyDir",
+ "name", "outputDir", "buildDir", "workDir", "newStateFile", "priorStateFile", "sourceDeltaFile")
var kotlinKytheExtract = pctx.AndroidStaticRule("kotlinKythe",
blueprint.RuleParams{
@@ -74,7 +149,7 @@ var kotlinKytheExtract = pctx.AndroidStaticRule("kotlinKythe",
// Skip header jars, those should not have an effect on kythe results.
` --args '${config.KotlincGlobalFlags} ` +
` ${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} ` +
- ` $kotlincFlags -jvm-target $kotlinJvmTarget ` +
+ ` $kotlincFlags $kotlincPluginFlags -jvm-target $kotlinJvmTarget ` +
`${config.KotlincKytheGlobalFlags}'`,
CommandDeps: []string{
"${config.KotlinKytheExtractor}",
@@ -83,7 +158,14 @@ var kotlinKytheExtract = pctx.AndroidStaticRule("kotlinKythe",
Rspfile: "$out.rsp",
RspfileContent: "$in",
},
- "classpath", "kotlincFlags", "commonSrcFilesList", "kotlinJvmTarget", "outJar", "srcJars", "srcJarDir",
+ "classpath", "kotlincFlags", "kotlincPluginFlags", "commonSrcFilesList", "kotlinJvmTarget", "outJar", "srcJars", "srcJarDir",
+)
+
+var kotlinIncrementalClean = pctx.AndroidStaticRule("kotlin-partialcompileclean",
+ blueprint.RuleParams{
+ Command: `rm -rf "$cpSnapshot" "$outDir" "$buildDir" "$workDir"`,
+ },
+ "cpSnapshot", "outDir", "buildDir", "workDir",
)
func kotlinCommonSrcsList(ctx android.ModuleContext, commonSrcFiles android.Paths) android.OptionalPath {
@@ -104,10 +186,10 @@ 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 (j *Module) kotlinCompile(ctx android.ModuleContext, outputFile, headerOutputFile android.WritablePath,
- srcFiles, commonSrcFiles, srcJars android.Paths,
- flags javaBuilderFlags) {
+ srcFiles, commonSrcFiles, srcJars android.Paths, flags javaBuilderFlags, compileData KotlinCompileData, incremental bool) {
var deps android.Paths
+ var orderOnlyDeps android.Paths
deps = append(deps, flags.kotlincClasspath...)
deps = append(deps, flags.kotlincDeps...)
deps = append(deps, srcJars...)
@@ -123,43 +205,97 @@ func (j *Module) kotlinCompile(ctx android.ModuleContext, outputFile, headerOutp
commonSrcFilesArg = "--common_srcs " + commonSrcsList.String()
}
+ associateJars := getAssociateJars(ctx, j.properties.Associates)
+ if len(associateJars) > 0 {
+ flags.kotlincFlags += " -Xfriend-paths=" + strings.Join(associateJars.Strings(), ",")
+ deps = append(deps, associateJars...)
+
+ // Prepend the associates classes jar in the classpath, so that they take priority over the other jars.
+ var newClasspath classpath
+ newClasspath = append(newClasspath, associateJars...)
+ newClasspath = append(newClasspath, flags.kotlincClasspath...)
+ flags.kotlincClasspath = newClasspath
+ }
+
classpathRspFile := android.PathForModuleOut(ctx, "kotlinc", "classpath.rsp")
android.WriteFileRule(ctx, classpathRspFile, strings.Join(flags.kotlincClasspath.Strings(), " "))
deps = append(deps, classpathRspFile)
+ rule := kotlinc
+ description := "kotlinc"
+ incrementalRootDir := android.PathForModuleOut(ctx, "kotlinc")
+ outputDir := "classes"
+ buildDir := "build"
+ workDir := "work"
+ args := map[string]string{
+ "classpath": classpathRspFile.String(),
+ "kotlincFlags": flags.kotlincFlags,
+ "kotlincPluginFlags": flags.kotlincPluginFlags,
+ "commonSrcFilesArg": commonSrcFilesArg,
+ "srcJars": strings.Join(srcJars.Strings(), " "),
+ "classesDir": android.PathForModuleOut(ctx, "kotlinc", outputDir).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(),
+ "kotlinJvmTarget": flags.javaVersion.StringForKotlinc(),
+ "name": kotlinName,
+ "newStateFile": compileData.pcStateFileNew.String(),
+ "priorStateFile": compileData.pcStateFilePrior.String(),
+ "sourceDeltaFile": compileData.diffFile.String(),
+ "composePluginFlag": flags.composePluginFlag,
+ }
+ if incremental {
+ rule = kotlinIncremental
+ description = "kotlin-incremental"
+ args["outputDir"] = outputDir
+ args["buildDir"] = buildDir
+ args["workDir"] = workDir
+ args["incrementalRootDir"] = incrementalRootDir.String()
+ args["sourceDeltaFile"] = compileData.diffFile.String()
+ args["composeEmbeddablePluginFlag"] = flags.composeEmbeddablePluginFlag
+ }
+
ctx.Build(pctx, android.BuildParams{
- Rule: kotlinc,
- Description: "kotlinc",
- Output: outputFile,
- ImplicitOutput: headerOutputFile,
- Inputs: srcFiles,
- Implicits: deps,
+ Rule: rule,
+ Description: description,
+ Inputs: srcFiles,
+ Implicits: deps,
+ OrderOnly: orderOnlyDeps,
+ Output: outputFile,
+ ImplicitOutputs: []android.WritablePath{headerOutputFile, compileData.pcStateFilePrior},
+ Args: args,
+ })
+
+ cleanPhonyPath := android.PathForModuleOut(ctx, "partialcompileclean", kotlinName)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: kotlinIncrementalClean,
+ Description: "kotlin-partialcompileclean",
+ Output: cleanPhonyPath,
+ Inputs: android.Paths{},
Args: map[string]string{
- "classpath": classpathRspFile.String(),
- "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(),
- "kotlinJvmTarget": flags.javaVersion.StringForKotlinc(),
- "name": kotlinName,
+ // TODO: add this cp snapshot as a param to the incremental compiler.
+ "cpSnapshot": incrementalRootDir.Join(ctx, "shrunk-classpath-snapshot.bin").String(),
+ "outDir": incrementalRootDir.Join(ctx, outputDir).String(),
+ "buildDir": incrementalRootDir.Join(ctx, buildDir).String(),
+ "workDir": incrementalRootDir.Join(ctx, workDir).String(),
},
+ PhonyOutput: true,
})
+ ctx.Phony("partialcompileclean", cleanPhonyPath)
// Emit kythe xref rule
if (ctx.Config().EmitXrefRules()) && ctx.Module() == ctx.PrimaryModule() {
extractionFile := outputFile.ReplaceExtension(ctx, "kzip")
args := map[string]string{
- "classpath": classpathRspFile.String(),
- "kotlincFlags": flags.kotlincFlags,
- "kotlinJvmTarget": flags.javaVersion.StringForKotlinc(),
- "outJar": outputFile.String(),
- "srcJars": strings.Join(srcJars.Strings(), " "),
- "srcJarDir": android.PathForModuleOut(ctx, "kotlinc", "srcJars.xref").String(),
+ "classpath": classpathRspFile.String(),
+ "kotlincFlags": flags.kotlincFlags,
+ "kotlincPluginFlags": flags.kotlincPluginFlags,
+ "kotlinJvmTarget": flags.javaVersion.StringForKotlinc(),
+ "outJar": outputFile.String(),
+ "srcJars": strings.Join(srcJars.Strings(), " "),
+ "srcJarDir": android.PathForModuleOut(ctx, "kotlinc", "srcJars.xref").String(),
}
if commonSrcsList.Valid() {
args["commonSrcFilesList"] = "--common_srcs @" + commonSrcsList.String()
@@ -176,7 +312,49 @@ func (j *Module) kotlinCompile(ctx android.ModuleContext, outputFile, headerOutp
}
}
-var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupports{Goma: true},
+func getAssociateJars(ctx android.ModuleContext, associates []string) android.Paths {
+ if len(associates) == 0 {
+ return nil
+ }
+
+ associatesFound := make(map[string]bool)
+ for _, name := range associates {
+ associatesFound[name] = false
+ }
+
+ var associateJars android.Paths
+ ctx.VisitDirectDepsProxy(func(depModule android.ModuleProxy) {
+ depName := ctx.OtherModuleName(depModule)
+ _, isAssociate := associatesFound[depName]
+ if !isAssociate {
+ return
+ }
+
+ associatesFound[depName] = true
+ depInfo, ok := android.OtherModuleProvider(ctx, depModule, JavaInfoProvider)
+ if !ok {
+ ctx.PropertyErrorf("Associates", "associate module '%s' is not a Java module", depName)
+ return
+ }
+
+ if len(depInfo.KotlinHeaderJars) == 0 {
+ ctx.PropertyErrorf("Associates", "associate module '%s' is not a Kotlin module", depName)
+ return
+ }
+
+ associateJars = append(associateJars, depInfo.KotlinHeaderJars...)
+ })
+
+ for name, found := range associatesFound {
+ if !found {
+ ctx.PropertyErrorf("Associates", "associate module '%s' must also be listed as a direct dependency (e.g. in static_libs or libs)", name)
+ }
+ }
+
+ return associateJars
+}
+
+var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupports{},
blueprint.RuleParams{
Command: `rm -rf "$srcJarDir" "$kotlinBuildFile" "$kaptDir" && ` +
`mkdir -p "$srcJarDir" "$kaptDir/sources" "$kaptDir/classes" && ` +
@@ -187,7 +365,8 @@ var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupp
` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
`${config.KotlincCmd} ${config.KotlincGlobalFlags} ` +
`${config.KaptSuppressJDK9Warnings} ${config.KotlincSuppressJDK9Warnings} ` +
- `${config.JavacHeapFlags} $kotlincFlags -Xplugin=${config.KotlinKaptJar} ` +
+ `${config.JavacHeapFlags} $kotlincFlags ` +
+ `-Xplugin=${config.KotlinKaptJar} ` +
`-P plugin:org.jetbrains.kotlin.kapt3:sources=$kaptDir/sources ` +
`-P plugin:org.jetbrains.kotlin.kapt3:classes=$kaptDir/classes ` +
`-P plugin:org.jetbrains.kotlin.kapt3:stubs=$kaptDir/stubs ` +
@@ -198,7 +377,6 @@ var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupp
`$kaptProcessor ` +
`-Xbuild-file=$kotlinBuildFile && ` +
`${config.SoongZipCmd} -jar -write_if_changed -o $out -C $kaptDir/stubs -D $kaptDir/stubs && ` +
- `if [ -f "$out.pc_state.new" ]; then mv "$out.pc_state.new" "$out.pc_state"; fi && ` +
`rm -rf "$srcJarDir"`,
CommandDeps: []string{
"${config.FindInputDeltaCmd}",
@@ -214,7 +392,7 @@ var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupp
Restat: true,
},
"kotlincFlags", "encodedJavacFlags", "kaptProcessorPath", "kaptProcessor",
- "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "kaptDir", "kotlinJvmTarget",
+ "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "kaptDir",
"kotlinBuildFile", "name", "classesJarOut")
// kotlinKapt performs Kotlin-compatible annotation processing. It takes .kt and .java sources and srcjars, and runs