Add a way to customize compiler file in build.gradle

This commit is contained in:
Alexey Tsvetkov
2016-11-17 17:13:01 +03:00
parent 75133bdfb9
commit 5082e8f236
5 changed files with 53 additions and 58 deletions
@@ -308,6 +308,23 @@ class KotlinGradleIT: BaseGradleIT() {
}
}
@Test
fun testCustomCompilerFile() {
val project = Project("customCompilerFile", GRADLE_VERSION)
project.setupWorkingDir()
// copy compiler embeddable to project dir using custom name
val classpath = System.getProperty("java.class.path").split(File.pathSeparator)
val kotlinEmbeddableJar = File(classpath.find { it.contains("kotlin-compiler-embeddable") })
val compilerJar = File(project.projectDir, "compiler.jar")
kotlinEmbeddableJar.copyTo(compilerJar)
project.build("build") {
assertSuccessful()
assertContains("Using kotlin compiler jar: $compilerJar")
}
}
@Test
fun testMultiplatformCompile() {
@@ -0,0 +1,22 @@
buildscript {
repositories {
mavenLocal()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: "kotlin"
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
testCompile 'junit:junit:4.12'
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
compileKotlin.compilerJarFile = project.file("compiler.jar")
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.gradle.plugin.ParentLastURLClassLoader
import org.jetbrains.kotlin.gradle.plugin.kotlinInfo
import org.jetbrains.kotlin.incremental.classpathAsList
import org.jetbrains.kotlin.incremental.destinationAsFile
import org.jetbrains.kotlin.incremental.makeModuleFile
@@ -30,7 +29,6 @@ import java.io.ByteArrayOutputStream
import java.io.File
import java.io.PrintStream
import java.net.URL
import java.util.zip.ZipFile
import kotlin.concurrent.thread
internal const val KOTLIN_COMPILER_EXECUTION_STRATEGY_PROPERTY = "kotlin.compiler.execution.strategy"
@@ -38,8 +36,6 @@ internal const val DAEMON_EXECUTION_STRATEGY = "daemon"
internal const val IN_PROCESS_EXECUTION_STRATEGY = "in-process"
internal const val OUT_OF_PROCESS_EXECUTION_STRATEGY = "out-of-process"
internal const val KOTLIN_COMPILER_JAR_PATH_PROPERTY = "kotlin.compiler.jar.path"
internal class GradleCompilerRunner(private val project: Project) : KotlinCompilerRunner<GradleCompilerEnvironment>() {
override val log = GradleKotlinLogger(project.logger)
private val flagFile = run {
@@ -57,10 +53,13 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
javaSourceRoots: Iterable<File>,
args: K2JVMCompilerArguments,
messageCollector: MessageCollector,
outputItemsCollector: OutputItemsCollector
outputItemsCollector: OutputItemsCollector,
kotlinCompilerJar: File
): ExitCode {
val outputDir = args.destinationAsFile
log.debug("Removing all kotlin classes in $outputDir")
log.info("Using kotlin compiler jar: $kotlinCompilerJar")
// we're free to delete all classes since only we know about that directory
outputDir.deleteRecursively()
@@ -77,7 +76,7 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
val additionalArguments = ""
try {
return runCompiler(K2JVM_COMPILER, args, additionalArguments, messageCollector, outputItemsCollector, GradleCompilerEnvironment(project, K2JVM_COMPILER))
return runCompiler(K2JVM_COMPILER, args, additionalArguments, messageCollector, outputItemsCollector, GradleCompilerEnvironment(kotlinCompilerJar))
}
finally {
moduleFile.delete()
@@ -180,59 +179,11 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
}
internal class GradleCompilerEnvironment(
private val project: Project,
private val compilerClassName: String
val compilerJar: File
) : CompilerEnvironment(Services.EMPTY) {
val compilerJar: File by lazy {
val file = findKotlinCompilerJar(project, compilerClassName)
?: throw IllegalStateException("Could not found Kotlin compiler jar. " +
"As a workaround you may specify path to compiler jar using " +
"\"$KOTLIN_COMPILER_JAR_PATH_PROPERTY\" system property")
project.logger.kotlinInfo("Using kotlin compiler jar: $file")
file
}
val compilerClasspath: List<File>
get() = listOf(compilerJar).filterNotNull()
val compilerClasspathURLs: List<URL>
get() = compilerClasspath.map { it.toURI().toURL() }
}
fun findKotlinCompilerJar(project: Project, compilerClassName: String): File? {
fun Project.classpathJars(): Sequence<File> =
buildscript.configurations.findByName("classpath")?.files?.asSequence() ?: emptySequence()
val pathFromSysProperties = System.getProperty(KOTLIN_COMPILER_JAR_PATH_PROPERTY)
if (pathFromSysProperties != null) {
val fileFromSysProperties = File(pathFromSysProperties)
if (fileFromSysProperties.exists()) return fileFromSysProperties
}
val projectsToRoot = generateSequence(project) { if (it != it.rootProject) it.parent else null }
val classpathDeps = projectsToRoot.flatMap { it.classpathJars() }
val entryToFind = compilerClassName.replace(".", "/") + ".class"
val jarCandidate = classpathDeps.firstOrNull { it.hasEntry(entryToFind) }
System.setProperty(KOTLIN_COMPILER_JAR_PATH_PROPERTY, jarCandidate?.absolutePath)
return jarCandidate
}
private fun File.hasEntry(entryToFind: String): Boolean {
try {
val zip = ZipFile(this)
val enumeration = zip.entries()
while (enumeration.hasMoreElements()) {
val entry = enumeration.nextElement()
if (entry.name.equals(entryToFind, ignoreCase = true)) return true
}
}
catch (e: Exception) {
return false
}
return false
}
@@ -80,6 +80,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractCo
logger.kotlinDebug { "Set $this.coroutines=${value.compilerArgument}" }
}
var compilerJarFile: File? = null
internal var compilerCalled: Boolean = false
// TODO: consider more reliable approach (see usage)
internal var anyClassesCompiled: Boolean = false
@@ -198,10 +199,15 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
args.classpathAsList = compileClasspath.toList()
args.destinationAsFile = destinationDir
val outputItemCollector = OutputItemsCollectorImpl()
val compilerJar = compilerJarFile
?: findKotlinJvmCompilerJar(project)
?: throw IllegalStateException("Could not find Kotlin Compiler jar. Please specify $name.compilerJarFile")
if (!incremental) {
anyClassesCompiled = true
val exitCode = GradleCompilerRunner(project).runJvmCompiler(sourceRoots.kotlinSourceFiles, sourceRoots.javaSourceRoots, args, messageCollector, outputItemCollector)
val compilerRunner = GradleCompilerRunner(project)
val exitCode = compilerRunner.runJvmCompiler(sourceRoots.kotlinSourceFiles, sourceRoots.javaSourceRoots, args, messageCollector,
outputItemCollector, compilerJar)
processCompilerExitCode(exitCode)
return
}
@@ -314,8 +320,6 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(),
override val kotlinOptions: KotlinJsOptions
get() = kotlinOptionsImpl
var compilerJarFile: File? = null
private val defaultOutputFile: File
get() = File(destinationDir, "$moduleName.js")