diff --git a/Android.bp b/Android.bp index 97f786edc..2c400cf4a 100644 --- a/Android.bp +++ b/Android.bp @@ -248,6 +248,7 @@ bootstrap_go_package { "java/java.go", "java/jdeps.go", "java/java_resources.go", + "java/kotlin.go", "java/prebuilt_apis.go", "java/proto.go", "java/sdk.go", @@ -260,6 +261,7 @@ bootstrap_go_package { "java/dexpreopt_test.go", "java/java_test.go", "java/jdeps_test.go", + "java/kotlin_test.go", "java/sdk_test.go", ], pluginFor: ["soong_build"], diff --git a/java/builder.go b/java/builder.go index 861566495..f1a6ead02 100644 --- a/java/builder.go +++ b/java/builder.go @@ -60,26 +60,6 @@ var ( "javacFlags", "bootClasspath", "classpath", "processorpath", "srcJars", "srcJarDir", "outDir", "annoDir", "javaVersion") - kotlinc = pctx.AndroidGomaStaticRule("kotlinc", - blueprint.RuleParams{ - Command: `rm -rf "$classesDir" "$srcJarDir" "$kotlinBuildFile" && mkdir -p "$classesDir" "$srcJarDir" && ` + - `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` + - `${config.GenKotlinBuildFileCmd} $classpath $classesDir $out.rsp $srcJarDir/list > $kotlinBuildFile &&` + - `${config.KotlincCmd} $kotlincFlags ` + - `-jvm-target $kotlinJvmTarget -Xbuild-file=$kotlinBuildFile && ` + - `${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir`, - CommandDeps: []string{ - "${config.KotlincCmd}", - "${config.KotlinCompilerJar}", - "${config.GenKotlinBuildFileCmd}", - "${config.SoongZipCmd}", - "${config.ZipSyncCmd}", - }, - Rspfile: "$out.rsp", - RspfileContent: `$in`, - }, - "kotlincFlags", "classpath", "srcJars", "srcJarDir", "classesDir", "kotlinJvmTarget", "kotlinBuildFile") - turbine = pctx.AndroidStaticRule("turbine", blueprint.RuleParams{ Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + @@ -177,35 +157,6 @@ type javaBuilderFlags struct { protoRoot bool } -func TransformKotlinToClasses(ctx android.ModuleContext, outputFile android.WritablePath, - srcFiles, srcJars android.Paths, - flags javaBuilderFlags) { - - inputs := append(android.Paths(nil), srcFiles...) - - var deps android.Paths - deps = append(deps, flags.kotlincClasspath...) - deps = append(deps, srcJars...) - - ctx.Build(pctx, android.BuildParams{ - Rule: kotlinc, - Description: "kotlinc", - Output: outputFile, - Inputs: inputs, - Implicits: deps, - Args: map[string]string{ - "classpath": flags.kotlincClasspath.FormJavaClassPath("-classpath"), - "kotlincFlags": flags.kotlincFlags, - "srcJars": strings.Join(srcJars.Strings(), " "), - "classesDir": android.PathForModuleOut(ctx, "kotlinc", "classes").String(), - "srcJarDir": android.PathForModuleOut(ctx, "kotlinc", "srcJars").String(), - "kotlinBuildFile": android.PathForModuleOut(ctx, "kotlinc-build.xml").String(), - // http://b/69160377 kotlinc only supports -jvm-target 1.6 and 1.8 - "kotlinJvmTarget": "1.8", - }, - }) -} - func TransformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath, shardIdx int, srcFiles, srcJars android.Paths, flags javaBuilderFlags, deps android.Paths) { diff --git a/java/java.go b/java/java.go index 7e82c59d6..d2710a805 100644 --- a/java/java.go +++ b/java/java.go @@ -974,7 +974,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path flags.kotlincClasspath = append(flags.kotlincClasspath, deps.classpath...) kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName) - TransformKotlinToClasses(ctx, kotlinJar, kotlinSrcFiles, srcJars, flags) + kotlinCompile(ctx, kotlinJar, kotlinSrcFiles, srcJars, flags) if ctx.Failed() { return } diff --git a/java/java_test.go b/java/java_test.go index 6437c0c7a..e16ae355c 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -571,68 +571,6 @@ func TestGeneratedSources(t *testing.T) { } } -func TestKotlin(t *testing.T) { - ctx := testJava(t, ` - java_library { - name: "foo", - srcs: ["a.java", "b.kt"], - } - - java_library { - name: "bar", - srcs: ["b.kt"], - libs: ["foo"], - static_libs: ["baz"], - } - - java_library { - name: "baz", - srcs: ["c.java"], - } - `) - - 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") - - if len(fooKotlinc.Inputs) != 2 || fooKotlinc.Inputs[0].String() != "a.java" || - fooKotlinc.Inputs[1].String() != "b.kt" { - t.Errorf(`foo kotlinc inputs %v != ["a.java", "b.kt"]`, fooKotlinc.Inputs) - } - - if len(fooJavac.Inputs) != 1 || fooJavac.Inputs[0].String() != "a.java" { - t.Errorf(`foo inputs %v != ["a.java"]`, fooJavac.Inputs) - } - - if !strings.Contains(fooJavac.Args["classpath"], fooKotlinc.Output.String()) { - t.Errorf("foo classpath %v does not contain %q", - fooJavac.Args["classpath"], fooKotlinc.Output.String()) - } - - if !inList(fooKotlinc.Output.String(), fooJar.Inputs.Strings()) { - t.Errorf("foo jar inputs %v does not contain %q", - fooJar.Inputs.Strings(), fooKotlinc.Output.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") - - if len(barKotlinc.Inputs) != 1 || barKotlinc.Inputs[0].String() != "b.kt" { - t.Errorf(`bar kotlinc inputs %v != ["b.kt"]`, barKotlinc.Inputs) - } - - if !inList(fooHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) { - t.Errorf(`expected %q in bar implicits %v`, - fooHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) - } - - if !inList(bazHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) { - t.Errorf(`expected %q in bar implicits %v`, - bazHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) - } -} - func TestTurbine(t *testing.T) { ctx := testJava(t, ` java_library { diff --git a/java/kotlin.go b/java/kotlin.go new file mode 100644 index 000000000..5bc7441c8 --- /dev/null +++ b/java/kotlin.go @@ -0,0 +1,71 @@ +// 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" + "strings" + + "github.com/google/blueprint" +) + +var kotlinc = pctx.AndroidGomaStaticRule("kotlinc", + blueprint.RuleParams{ + Command: `rm -rf "$classesDir" "$srcJarDir" "$kotlinBuildFile" && mkdir -p "$classesDir" "$srcJarDir" && ` + + `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` + + `${config.GenKotlinBuildFileCmd} $classpath $classesDir $out.rsp $srcJarDir/list > $kotlinBuildFile &&` + + `${config.KotlincCmd} $kotlincFlags ` + + `-jvm-target $kotlinJvmTarget -Xbuild-file=$kotlinBuildFile && ` + + `${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir`, + CommandDeps: []string{ + "${config.KotlincCmd}", + "${config.KotlinCompilerJar}", + "${config.GenKotlinBuildFileCmd}", + "${config.SoongZipCmd}", + "${config.ZipSyncCmd}", + }, + Rspfile: "$out.rsp", + RspfileContent: `$in`, + }, + "kotlincFlags", "classpath", "srcJars", "srcJarDir", "classesDir", "kotlinJvmTarget", "kotlinBuildFile") + +func kotlinCompile(ctx android.ModuleContext, outputFile android.WritablePath, + srcFiles, srcJars android.Paths, + flags javaBuilderFlags) { + + inputs := append(android.Paths(nil), srcFiles...) + + var deps android.Paths + deps = append(deps, flags.kotlincClasspath...) + deps = append(deps, srcJars...) + + ctx.Build(pctx, android.BuildParams{ + Rule: kotlinc, + Description: "kotlinc", + Output: outputFile, + Inputs: inputs, + Implicits: deps, + Args: map[string]string{ + "classpath": flags.kotlincClasspath.FormJavaClassPath("-classpath"), + "kotlincFlags": flags.kotlincFlags, + "srcJars": strings.Join(srcJars.Strings(), " "), + "classesDir": android.PathForModuleOut(ctx, "kotlinc", "classes").String(), + "srcJarDir": android.PathForModuleOut(ctx, "kotlinc", "srcJars").String(), + "kotlinBuildFile": android.PathForModuleOut(ctx, "kotlinc-build.xml").String(), + // http://b/69160377 kotlinc only supports -jvm-target 1.6 and 1.8 + "kotlinJvmTarget": "1.8", + }, + }) +} diff --git a/java/kotlin_test.go b/java/kotlin_test.go new file mode 100644 index 000000000..08a308515 --- /dev/null +++ b/java/kotlin_test.go @@ -0,0 +1,82 @@ +// Copyright 2017 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 ( + "strings" + "testing" +) + +func TestKotlin(t *testing.T) { + ctx := testJava(t, ` + java_library { + name: "foo", + srcs: ["a.java", "b.kt"], + } + + java_library { + name: "bar", + srcs: ["b.kt"], + libs: ["foo"], + static_libs: ["baz"], + } + + java_library { + name: "baz", + srcs: ["c.java"], + } + `) + + 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") + + if len(fooKotlinc.Inputs) != 2 || fooKotlinc.Inputs[0].String() != "a.java" || + fooKotlinc.Inputs[1].String() != "b.kt" { + t.Errorf(`foo kotlinc inputs %v != ["a.java", "b.kt"]`, fooKotlinc.Inputs) + } + + if len(fooJavac.Inputs) != 1 || fooJavac.Inputs[0].String() != "a.java" { + t.Errorf(`foo inputs %v != ["a.java"]`, fooJavac.Inputs) + } + + if !strings.Contains(fooJavac.Args["classpath"], fooKotlinc.Output.String()) { + t.Errorf("foo classpath %v does not contain %q", + fooJavac.Args["classpath"], fooKotlinc.Output.String()) + } + + if !inList(fooKotlinc.Output.String(), fooJar.Inputs.Strings()) { + t.Errorf("foo jar inputs %v does not contain %q", + fooJar.Inputs.Strings(), fooKotlinc.Output.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") + + if len(barKotlinc.Inputs) != 1 || barKotlinc.Inputs[0].String() != "b.kt" { + t.Errorf(`bar kotlinc inputs %v != ["b.kt"]`, barKotlinc.Inputs) + } + + if !inList(fooHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) { + t.Errorf(`expected %q in bar implicits %v`, + fooHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) + } + + if !inList(bazHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) { + t.Errorf(`expected %q in bar implicits %v`, + bazHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) + } +}