From 5082e8f2362548054029d7cf146547b44ab3b0d4 Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Thu, 17 Nov 2016 17:13:01 +0300 Subject: [PATCH] Add a way to customize compiler file in build.gradle --- .../kotlin/gradle/KotlinGradlePluginIT.kt | 17 ++++++ .../customCompilerFile/build.gradle | 22 +++++++ .../src/main/kotlin/Dummy.kt | 1 + .../GradleKotlinCompilerRunner.kt | 61 ++----------------- .../jetbrains/kotlin/gradle/tasks/Tasks.kt | 10 ++- 5 files changed, 53 insertions(+), 58 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/customCompilerFile/build.gradle create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/customCompilerFile/src/main/kotlin/Dummy.kt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt index 874735c3ba7..8890ed4d9e7 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt @@ -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() { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/customCompilerFile/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/customCompilerFile/build.gradle new file mode 100644 index 00000000000..20ef0311fa6 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/customCompilerFile/build.gradle @@ -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") diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/customCompilerFile/src/main/kotlin/Dummy.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/customCompilerFile/src/main/kotlin/Dummy.kt new file mode 100644 index 00000000000..b5925573e5b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/customCompilerFile/src/main/kotlin/Dummy.kt @@ -0,0 +1 @@ +class Dummy diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt index 21d7489b5be..7f3b9e4d57e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt @@ -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() { override val log = GradleKotlinLogger(project.logger) private val flagFile = run { @@ -57,10 +53,13 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil javaSourceRoots: Iterable, 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 get() = listOf(compilerJar).filterNotNull() val compilerClasspathURLs: List get() = compilerClasspath.map { it.toURI().toURL() } -} - -fun findKotlinCompilerJar(project: Project, compilerClassName: String): File? { - fun Project.classpathJars(): Sequence = - 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 } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index f243c91e632..1dab5a43a2d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -80,6 +80,7 @@ abstract class AbstractKotlinCompile() : 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(), 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(), override val kotlinOptions: KotlinJsOptions get() = kotlinOptionsImpl - var compilerJarFile: File? = null - private val defaultOutputFile: File get() = File(destinationDir, "$moduleName.js")