diff --git a/java/base.go b/java/base.go index 8a4c64d71..070d35538 100644 --- a/java/base.go +++ b/java/base.go @@ -875,9 +875,12 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { if j.hasSrcExt(".kt") { // TODO(ccross): move this to a mutator pass that can tell if generated sources contain // Kotlin files - ctx.AddVariationDependencies(nil, kotlinStdlibTag, - "kotlin-stdlib", "kotlin-stdlib-jdk7", "kotlin-stdlib-jdk8") - ctx.AddVariationDependencies(nil, kotlinAnnotationsTag, "kotlin-annotations") + tag := staticLibTag + if !BoolDefault(j.properties.Static_kotlin_stdlib, true) { + tag = libTag + } + ctx.AddVariationDependencies(nil, tag, + "kotlin-stdlib", "kotlin-stdlib-jdk7", "kotlin-stdlib-jdk8", "kotlin-annotations") } // Framework libraries need special handling in static coverage builds: they should not have @@ -1211,7 +1214,6 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath var kotlinJars android.Paths var kotlinHeaderJars android.Paths - var kotlinExtraJars android.Paths // Prepend extraClasspathJars to classpath so that the resource processor R.jar comes before // any dependencies so that it can override any non-final R classes from dependencies with the @@ -1290,9 +1292,6 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath // Collect common .kt files for AIDEGen j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...) - flags.classpath = append(flags.classpath, deps.kotlinStdlib...) - flags.classpath = append(flags.classpath, deps.kotlinAnnotations...) - flags.kotlincClasspath = append(flags.kotlincClasspath, flags.bootClasspath...) flags.kotlincClasspath = append(flags.kotlincClasspath, flags.classpath...) @@ -1322,8 +1321,6 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath kotlinJars = append(kotlinJars, kotlinJarPath) kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar) - kotlinExtraJars = append(kotlinExtraJars, deps.kotlinStdlib...) - kotlinExtraJars = append(kotlinExtraJars, deps.kotlinAnnotations...) } jars := slices.Clone(kotlinJars) @@ -1342,9 +1339,6 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath // with sharding enabled. See: b/77284273. } extraJars := slices.Clone(kotlinHeaderJars) - if BoolDefault(j.properties.Static_kotlin_stdlib, true) { - extraJars = append(extraJars, kotlinExtraJars...) - } extraJars = append(extraJars, extraCombinedJars...) var combinedHeaderJarFile android.Path headerJarFileWithoutDepsOrJarjar, combinedHeaderJarFile = @@ -1423,13 +1417,6 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath } } - // Jar kotlin classes into the final jar after javac - if BoolDefault(j.properties.Static_kotlin_stdlib, true) { - jars = append(jars, kotlinExtraJars...) - } else { - flags.dexClasspath = append(flags.dexClasspath, kotlinExtraJars...) - } - jars = append(jars, extraCombinedJars...) j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles @@ -2343,10 +2330,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { } else { ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName) } - case kotlinStdlibTag: - deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars...) - case kotlinAnnotationsTag: - deps.kotlinAnnotations = dep.HeaderJars case kotlinPluginTag: deps.kotlinPlugins = append(deps.kotlinPlugins, dep.ImplementationAndResourcesJars...) case syspropPublicStubDepTag: @@ -2570,8 +2553,6 @@ func collectDirectDepsProviders(ctx android.ModuleContext) (result *JarJarProvid return RenameUseInclude, "tagswitch" case exportedPluginTag: return RenameUseInclude, "tagswitch" - case kotlinStdlibTag, kotlinAnnotationsTag: - return RenameUseExclude, "tagswitch" case kotlinPluginTag: return RenameUseInclude, "tagswitch" default: diff --git a/java/java.go b/java/java.go index 126d8f3a4..0d2704d24 100644 --- a/java/java.go +++ b/java/java.go @@ -421,8 +421,6 @@ var ( bootClasspathTag = dependencyTag{name: "bootclasspath", runtimeLinked: true} systemModulesTag = dependencyTag{name: "system modules", runtimeLinked: true} frameworkResTag = dependencyTag{name: "framework-res"} - kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib", runtimeLinked: true} - kotlinAnnotationsTag = dependencyTag{name: "kotlin-annotations", runtimeLinked: true} kotlinPluginTag = dependencyTag{name: "kotlin-plugin", toolchain: true} proguardRaiseTag = dependencyTag{name: "proguard-raise"} certificateTag = dependencyTag{name: "certificate"} @@ -458,8 +456,6 @@ var ( bootClasspathTag, systemModulesTag, java9LibTag, - kotlinStdlibTag, - kotlinAnnotationsTag, kotlinPluginTag, syspropPublicStubDepTag, instrumentationForTag, @@ -568,8 +564,6 @@ type deps struct { srcJars android.Paths systemModules *systemModules aidlPreprocess android.OptionalPath - kotlinStdlib android.Paths - kotlinAnnotations android.Paths kotlinPlugins android.Paths aconfigProtoFiles android.Paths diff --git a/java/kotlin_test.go b/java/kotlin_test.go index 933fc5187..844e974a4 100644 --- a/java/kotlin_test.go +++ b/java/kotlin_test.go @@ -15,6 +15,7 @@ package java import ( + "slices" "strconv" "strings" "testing" @@ -23,10 +24,11 @@ import ( ) func TestKotlin(t *testing.T) { - ctx, _ := testJava(t, ` + bp := ` java_library { name: "foo", srcs: ["a.java", "b.kt"], + static_libs: ["quz"], } java_library { @@ -39,85 +41,156 @@ func TestKotlin(t *testing.T) { java_library { name: "baz", srcs: ["c.java"], + static_libs: ["quz"], } - `) - kotlinStdlib := ctx.ModuleForTests("kotlin-stdlib", "android_common"). - Output("turbine-combined/kotlin-stdlib.jar").Output - kotlinStdlibJdk7 := ctx.ModuleForTests("kotlin-stdlib-jdk7", "android_common"). - Output("turbine-combined/kotlin-stdlib-jdk7.jar").Output - kotlinStdlibJdk8 := ctx.ModuleForTests("kotlin-stdlib-jdk8", "android_common"). - Output("turbine-combined/kotlin-stdlib-jdk8.jar").Output - kotlinAnnotations := ctx.ModuleForTests("kotlin-annotations", "android_common"). - Output("turbine-combined/kotlin-annotations.jar").Output + java_library { + name: "quz", + srcs: ["d.kt"], + }` - 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" { - t.Errorf(`foo kotlinc inputs %v != ["a.java", "b.kt"]`, fooKotlinc.Inputs) + kotlinStdlibTurbineCombinedJars := []string{ + "out/soong/.intermediates/default/java/kotlin-stdlib/android_common/turbine-combined/kotlin-stdlib.jar", + "out/soong/.intermediates/default/java/kotlin-stdlib-jdk7/android_common/turbine-combined/kotlin-stdlib-jdk7.jar", + "out/soong/.intermediates/default/java/kotlin-stdlib-jdk8/android_common/turbine-combined/kotlin-stdlib-jdk8.jar", + "out/soong/.intermediates/default/java/kotlin-annotations/android_common/turbine-combined/kotlin-annotations.jar", } - if len(fooJavac.Inputs) != 1 || fooJavac.Inputs[0].String() != "a.java" { - t.Errorf(`foo inputs %v != ["a.java"]`, fooJavac.Inputs) + kotlinStdlibJavacJars := []string{ + "out/soong/.intermediates/default/java/kotlin-stdlib/android_common/javac/kotlin-stdlib.jar", + "out/soong/.intermediates/default/java/kotlin-stdlib-jdk7/android_common/javac/kotlin-stdlib-jdk7.jar", + "out/soong/.intermediates/default/java/kotlin-stdlib-jdk8/android_common/javac/kotlin-stdlib-jdk8.jar", + "out/soong/.intermediates/default/java/kotlin-annotations/android_common/javac/kotlin-annotations.jar", } - if !strings.Contains(fooJavac.Args["classpath"], fooKotlincHeaderClasses.String()) { - t.Errorf("foo classpath %v does not contain %q", - fooJavac.Args["classpath"], fooKotlincHeaderClasses.String()) + bootclasspathTurbineCombinedJars := []string{ + "out/soong/.intermediates/default/java/stable.core.platform.api.stubs/android_common/turbine-combined/stable.core.platform.api.stubs.jar", + "out/soong/.intermediates/default/java/core-lambda-stubs/android_common/turbine-combined/core-lambda-stubs.jar", } - if !inList(fooKotlincClasses.String(), fooJar.Inputs.Strings()) { - t.Errorf("foo jar inputs %v does not contain %q", - fooJar.Inputs.Strings(), fooKotlincClasses.String()) + frameworkTurbineCombinedJars := []string{ + "out/soong/.intermediates/default/java/ext/android_common/turbine-combined/ext.jar", + "out/soong/.intermediates/default/java/framework/android_common/turbine-combined/framework.jar", } - if !inList(kotlinStdlib.String(), fooJar.Inputs.Strings()) { - t.Errorf("foo jar inputs %v does not contain %v", - fooJar.Inputs.Strings(), kotlinStdlib.String()) + testCases := []struct { + name string + + preparer android.FixturePreparer + + fooKotlincInputs []string + fooJavacInputs []string + fooKotlincClasspath []string + fooJavacClasspath []string + fooCombinedInputs []string + fooHeaderCombinedInputs []string + + barKotlincInputs []string + barKotlincClasspath []string + barCombinedInputs []string + barHeaderCombinedInputs []string + }{ + { + name: "normal", + preparer: android.NullFixturePreparer, + fooKotlincInputs: []string{"a.java", "b.kt"}, + fooJavacInputs: []string{"a.java"}, + fooKotlincClasspath: slices.Concat( + bootclasspathTurbineCombinedJars, + frameworkTurbineCombinedJars, + []string{"out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar"}, + kotlinStdlibTurbineCombinedJars, + ), + fooJavacClasspath: slices.Concat( + []string{"out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar"}, + frameworkTurbineCombinedJars, + []string{"out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar"}, + kotlinStdlibTurbineCombinedJars, + ), + fooCombinedInputs: slices.Concat( + []string{ + "out/soong/.intermediates/foo/android_common/kotlin/foo.jar", + "out/soong/.intermediates/foo/android_common/javac/foo.jar", + "out/soong/.intermediates/quz/android_common/combined/quz.jar", + }, + kotlinStdlibJavacJars, + ), + fooHeaderCombinedInputs: slices.Concat( + []string{ + "out/soong/.intermediates/foo/android_common/turbine/foo.jar", + "out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar", + "out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar", + }, + kotlinStdlibTurbineCombinedJars, + ), + + barKotlincInputs: []string{"b.kt"}, + barKotlincClasspath: slices.Concat( + bootclasspathTurbineCombinedJars, + frameworkTurbineCombinedJars, + []string{ + "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar", + "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar", + }, + kotlinStdlibTurbineCombinedJars, + ), + barCombinedInputs: slices.Concat( + []string{ + "out/soong/.intermediates/bar/android_common/kotlin/bar.jar", + "out/soong/.intermediates/baz/android_common/combined/baz.jar", + }, + kotlinStdlibJavacJars, + []string{}, + ), + barHeaderCombinedInputs: slices.Concat( + []string{ + "out/soong/.intermediates/bar/android_common/kotlin_headers/bar.jar", + "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar", + }, + kotlinStdlibTurbineCombinedJars, + ), + }, } - if !inList(kotlinStdlibJdk7.String(), fooJar.Inputs.Strings()) { - t.Errorf("foo jar inputs %v does not contain %v", - fooJar.Inputs.Strings(), kotlinStdlibJdk7.String()) - } + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + result := android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + tt.preparer, + ).RunTestWithBp(t, bp) + foo := result.ModuleForTests("foo", "android_common") + fooKotlinc := foo.Rule("kotlinc") + android.AssertPathsRelativeToTopEquals(t, "foo kotlinc inputs", tt.fooKotlincInputs, fooKotlinc.Inputs) - if !inList(kotlinStdlibJdk8.String(), fooJar.Inputs.Strings()) { - t.Errorf("foo jar inputs %v does not contain %v", - fooJar.Inputs.Strings(), kotlinStdlibJdk8.String()) - } + fooKotlincClasspath := android.ContentFromFileRuleForTests(t, result.TestContext, foo.Output("kotlinc/classpath.rsp")) + android.AssertStringPathsRelativeToTopEquals(t, "foo kotlinc classpath", result.Config, tt.fooKotlincClasspath, strings.Fields(fooKotlincClasspath)) - if !inList(kotlinAnnotations.String(), fooJar.Inputs.Strings()) { - t.Errorf("foo jar inputs %v does not contain %v", - fooJar.Inputs.Strings(), kotlinAnnotations.String()) - } + fooJavac := foo.Rule("javac") + android.AssertPathsRelativeToTopEquals(t, "foo javac inputs", tt.fooJavacInputs, fooJavac.Inputs) - if !inList(fooKotlincHeaderClasses.String(), fooHeaderJar.Inputs.Strings()) { - t.Errorf("foo header jar inputs %v does not contain %q", - fooHeaderJar.Inputs.Strings(), fooKotlincHeaderClasses.String()) - } + fooJavacClasspath := fooJavac.Args["classpath"] + android.AssertStringPathsRelativeToTopEquals(t, "foo javac classpath", result.Config, tt.fooJavacClasspath, + strings.Split(strings.TrimPrefix(fooJavacClasspath, "-classpath "), ":")) - bazHeaderJar := ctx.ModuleForTests("baz", "android_common").Output("turbine-combined/baz.jar") - barKotlinc := ctx.ModuleForTests("bar", "android_common").Rule("kotlinc") + fooCombinedJar := foo.Output("combined/foo.jar") + android.AssertPathsRelativeToTopEquals(t, "foo combined inputs", tt.fooCombinedInputs, fooCombinedJar.Inputs) - if len(barKotlinc.Inputs) != 1 || barKotlinc.Inputs[0].String() != "b.kt" { - t.Errorf(`bar kotlinc inputs %v != ["b.kt"]`, barKotlinc.Inputs) - } + fooCombinedHeaderJar := foo.Output("turbine-combined/foo.jar") + android.AssertPathsRelativeToTopEquals(t, "foo header combined inputs", tt.fooHeaderCombinedInputs, fooCombinedHeaderJar.Inputs) - if !inList(fooHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) { - t.Errorf(`expected %q in bar implicits %v`, - fooHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) - } + bar := result.ModuleForTests("bar", "android_common") + barKotlinc := bar.Rule("kotlinc") + android.AssertPathsRelativeToTopEquals(t, "bar kotlinc inputs", tt.barKotlincInputs, barKotlinc.Inputs) - if !inList(bazHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) { - t.Errorf(`expected %q in bar implicits %v`, - bazHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) + barKotlincClasspath := android.ContentFromFileRuleForTests(t, result.TestContext, bar.Output("kotlinc/classpath.rsp")) + android.AssertStringPathsRelativeToTopEquals(t, "bar kotlinc classpath", result.Config, tt.barKotlincClasspath, strings.Fields(barKotlincClasspath)) + + barCombinedJar := bar.Output("combined/bar.jar") + android.AssertPathsRelativeToTopEquals(t, "bar combined inputs", tt.barCombinedInputs, barCombinedJar.Inputs) + + barCombinedHeaderJar := bar.Output("turbine-combined/bar.jar") + android.AssertPathsRelativeToTopEquals(t, "bar header combined inputs", tt.barHeaderCombinedInputs, barCombinedHeaderJar.Inputs) + }) } }