Skip to content

Commit

Permalink
Builder supports building abis on request.
Browse files Browse the repository at this point in the history
  • Loading branch information
Corbin Smith committed Feb 28, 2020
1 parent 86c62f7 commit 7bb0d1e
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 72 deletions.
3 changes: 2 additions & 1 deletion kotlin/internal/jvm/android.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ def _kt_android_artifact(name, srcs = [], deps = [], plugins = [], **kwargs):
"""
base_name = name + "_base"
kt_name = name + "_kt"

# TODO(bazelbuild/rules_kotlin/issues/273): This should be retrieved from a provider.
base_deps = deps + [ "@io_bazel_rules_kotlin//third_party:android_sdk" ]
base_deps = deps + ["@io_bazel_rules_kotlin//third_party:android_sdk"]

native.android_library(
name = base_name,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
/*
* Copyright 2018 The Bazel Authors. All rights reserved.
* Copyright 2020 The Bazel Authors. 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
* 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.
*
* 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 io.bazel.kotlin.builder.tasks.jvm

Expand All @@ -34,7 +35,8 @@ class KotlinJvmTaskExecutor @Inject internal constructor(
private val compiler: KotlinToolchain.KotlincInvoker,
private val pluginArgsEncoder: KotlinCompilerPluginArgsEncoder,
private val javaCompiler: JavaCompiler,
private val jDepsGenerator: JDepsGenerator
private val jDepsGenerator: JDepsGenerator,
private val abiPlugins: KtAbiPluginArgs
) {
fun execute(context: CompilationTaskContext, task: JvmCompilationTask) {
val preprocessedTask = task
Expand All @@ -44,12 +46,24 @@ class KotlinJvmTaskExecutor @Inject internal constructor(
context.execute("compile classes") {
preprocessedTask.apply {
var kotlinError: CompilationStatusException? = null
var result: List<String> = listOf()
var result: List<String> = emptyList()
// skip compilation if there are no kt files.
if (inputs.kotlinSourcesCount > 0) {
context.execute("kotlinc") {
result = try {
compileKotlin(context, compiler, printOnFail = false)
val args = commonArgs().plus(
outputs.jar.takeIf(String::isNotEmpty)?.let {
argsForCompile()
} ?: emptyList()
).plus(
outputs.abijar.takeIf(String::isNotEmpty)?.let {
abiPlugins.args(directories.classes, generateCode = outputs.jar.isNotEmpty())
} ?: emptyList()
)
compileKotlin(context,
compiler,
compilerArguments = args,
printOnFail = false)
} catch (ex: CompilationStatusException) {
kotlinError = ex
ex.lines
Expand All @@ -62,13 +76,17 @@ class KotlinJvmTaskExecutor @Inject internal constructor(
result.apply(context::printCompilerOutput)
kotlinError?.also { throw it }
}
if (outputs.jar.isNotEmpty()) {
context.execute("create jar", ::createOutputJar)
context.execute("produce src jar", ::produceSourceJar)
}
if (outputs.abijar.isNotEmpty()) {
context.execute("create abi jar", ::createAbiJar)
}
if (outputs.jdeps.isNotEmpty()) {
context.execute("generate jdeps") { jDepsGenerator.generateJDeps(this) }
}
}
}

context.execute("create jar") { preprocessedTask.createOutputJar() }
context.execute("produce src jar") { preprocessedTask.produceSourceJar() }
if (preprocessedTask.outputs.jdeps.isNotEmpty()) {
context.execute("generate jdeps") { jDepsGenerator.generateJDeps(preprocessedTask) }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2020 The Bazel Authors. 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 io.bazel.kotlin.builder.tasks.jvm

import io.bazel.kotlin.builder.toolchain.KotlinToolchain
import javax.inject.Inject

class KtAbiPluginArgs @Inject constructor(
val toolchain: KotlinToolchain
) {
fun args(outputDir: String, generateCode: Boolean): List<String> {
return listOf(
"-Xplugin=${toolchain.jvmAbiGen.jarPath}",
"-P",
"plugin:${toolchain.jvmAbiGen.id}:outputDir=${outputDir}"
) + if (!generateCode) {
listOf("-Xplugin=${toolchain.skipCodeGen.jarPath}")
} else {
emptyList()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,28 @@ import io.bazel.kotlin.builder.utils.joinedClasspath
import io.bazel.kotlin.builder.utils.partitionJvmSources
import io.bazel.kotlin.model.JvmCompilationTask
import java.io.File
import java.nio.file.FileSystems
import java.nio.file.Files
import java.nio.file.Paths

/**
* Return a list with the common arguments.
*/
internal fun JvmCompilationTask.getCommonArgs(): MutableList<String> {
val friendPaths = info.friendPathsList.map { Paths.get(it).toAbsolutePath() }
val args = mutableListOf<String>()
args.addAll(baseArgs() + listOf(
"-Xfriend-paths=${friendPaths.joinToString(X_FRIENDS_PATH_SEPARATOR)}",
"-d", directories.classes))
info.passthroughFlags?.takeIf { it.isNotBlank() }?.let { args.addAll(it.split(" ")) }
return args
internal fun JvmCompilationTask.argsForCompile(): List<String> {
val fs = FileSystems.getDefault()
return (
info.friendPathsList.takeIf { it.isNotEmpty() }
?.map { fs.getPath(it).toAbsolutePath() }
?.let { listOf("-Xfriend-paths=${it.joinToString(X_FRIENDS_PATH_SEPARATOR)}") }
?: emptyList()
) + (
info.passthroughFlags.takeIf { it.isNotEmpty() }
?.split(" ")
?: emptyList()
) + listOf("-d", directories.classes)
}

internal fun JvmCompilationTask.baseArgs(): List<String> {
internal fun JvmCompilationTask.commonArgs(): List<String> {
return listOf(
"-cp", inputs.joinedClasspath
.split(File.pathSeparator)
Expand Down Expand Up @@ -103,12 +108,12 @@ internal fun JvmCompilationTask.runAnnotationProcessors(
} else {
return context.execute("kapt (${inputs.processorsList.joinToString(", ")})")
{
getCommonArgs().let { args ->
commonArgs().toMutableList().let { args ->
args.addAll(pluginArgsEncoder.encode(context,
this))
args.addAll(inputs.kotlinSourcesList)
args.addAll(inputs.javaSourcesList)
context.executeCompilerTask(
return@let context.executeCompilerTask(
args,
compiler::compile,
printOnSuccess = context.whenTracing { false } ?: true)
Expand All @@ -118,7 +123,7 @@ internal fun JvmCompilationTask.runAnnotationProcessors(
context.whenTracing {
printLines("kapt output", outputLines)
}
expandWithGeneratedSources()
return@let expandWithGeneratedSources()
}
}
}
Expand Down Expand Up @@ -160,13 +165,12 @@ internal fun JvmCompilationTask.createAbiJar() =
internal fun JvmCompilationTask.compileKotlin(
context: CompilationTaskContext,
compiler: KotlinToolchain.KotlincInvoker,
compilerArguments: List<String> = getCommonArgs(),
compilerArguments: List<String>,
printOnFail: Boolean = true
) = compilerArguments.toMutableList().let { args ->
args.addAll(inputs.javaSourcesList)
args.addAll(inputs.kotlinSourcesList)
context.executeCompilerTask(args.toList(), compiler::compile, printOnFail = printOnFail)
}
): List<String> = context.executeCompilerTask(
compilerArguments + inputs.kotlinSourcesList + inputs.javaSourcesList,
compiler::compile,
printOnFail = printOnFail)

/**
* If any srcjars were provided expand the jars sources and create a new [JvmCompilationTask] with the
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
/*
* Copyright 2018 The Bazel Authors. All rights reserved.
* Copyright 2020 The Bazel Authors. 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
* 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.
*
* 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 io.bazel.kotlin.builder.toolchain

Expand Down Expand Up @@ -109,19 +110,22 @@ class CompilationTaskContext(val info: CompilationTaskInfo, private val out: Pri
printOnFail: Boolean = true,
printOnSuccess: Boolean = true
): List<String> {
val outputStream = ByteArrayOutputStream()
val ps = PrintStream(outputStream)
val result = compile(args.toTypedArray(), ps)
val output = ByteArrayInputStream(outputStream.toByteArray()).bufferedReader().readLines()
if (result != 0) {
if (printOnFail) {
printCompilerOutput(output)
}
throw CompilationStatusException("compile phase failed", result, output)
} else if (printOnSuccess) {
printCompilerOutput(output)
val outputStream = ByteArrayOutputStream()
val ps = PrintStream(outputStream)
val result = compile(args.toTypedArray(), ps)
val output = ByteArrayInputStream(outputStream
.toByteArray())
.bufferedReader()
.readLines()
if (result != 0) {
if (printOnFail) {
printCompilerOutput(output)
}
return output
throw CompilationStatusException("compile phase failed", result, output)
} else if (printOnSuccess) {
printCompilerOutput(output)
}
return output
}

/**
Expand Down
15 changes: 8 additions & 7 deletions src/main/kotlin/io/bazel/kotlin/builder/utils/ArgMap.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
/*
* Copyright 2018 The Bazel Authors. All rights reserved.
* Copyright 2020 The Bazel Authors. 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
* 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.
*
* 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 io.bazel.kotlin.builder.utils
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
/*
* Copyright 2018 The Bazel Authors. All rights reserved.
* Copyright 2020 The Bazel Authors. 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
* 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.
*
* 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 io.bazel.kotlin.builder.tasks.jvm;

Expand Down Expand Up @@ -44,8 +45,16 @@ public class KotlinBuilderJvmBasicTest {
public void testSimpleMixedModeCompile() {
ctx.runCompileTask(
c -> {
c.addSource("AClass.kt", "package something;" + "class AClass{}");
c.addSource("AnotherClass.java", "package something;", "", "class AnotherClass{}");
c.addSource(
"AClass.kt",
"package something;" + "class AClass{}"
);
c.addSource(
"AnotherClass.java",
"package something;",
"",
"class AnotherClass{}"
);
c.outputJar().outputSrcJar();
});
ctx.assertFilesExist(
Expand All @@ -58,11 +67,44 @@ public void testGeneratesJDeps() {
c -> {
c.addSource("AClass.kt", "package something;" + "class AClass{}");
c.addSource("AnotherClass.java", "package something;", "", "class AnotherClass{}");
// declaring outputJdeps also asserts existance after compile.
// declaring outputJdeps also asserts existence after compile.
c.outputJar().outputSrcJar().outputJdeps();
});
}

@Test
public void testGeneratesAbiOnly() {
Deps.Dep d = ctx.runCompileTask(
c -> {
c.addSource("AClass.kt", "package something;" + "class AClass{}");
c.addSource("AnotherClass.java", "package something;", "", "class AnotherClass{}");
c.outputAbiJar();
});
ctx.runCompileTask(
c -> {
c.addDirectDependencies(d);
c.addSource("Dependent.kt",
"package dep;",
"import something.AClass",
"class Dependent{}");
c.outputJar().outputSrcJar().outputJdeps();
});
}

@Test
public void testGeneratesAbiJarSource() {
ctx.runCompileTask(
c -> {
c.addSource("AClass.kt", "package something;" + "class AClass{}");
c.addSource("AnotherClass.java", "package something;", "", "class AnotherClass{}");
// declaring outputJdeps also asserts existance after compile.
c.outputJar();
c.outputSrcJar();
c.outputJdeps();
c.outputAbiJar();
});
}

@Test
public void testKotlinErrorRendering() {
ctx.runFailingCompileTaskAndValidateOutput(
Expand Down
Loading

0 comments on commit 7bb0d1e

Please sign in to comment.