diff --git a/GRADLE_PLUGIN.md b/GRADLE_PLUGIN.md index d127982f10a..5b8fdd498ef 100644 --- a/GRADLE_PLUGIN.md +++ b/GRADLE_PLUGIN.md @@ -24,10 +24,10 @@ project property: konan.version=0.3 -If you already downloaded the compiler manually you may specify the path to it using `konan.home` project property (e.g. - in `gradle.properties`). Note: the plugin ignores the `konan.version` property in this case. +If you already downloaded the compiler manually you may specify the path to its root directory using `konan.home` +project property (e.g. in `gradle.properties`). Note: the plugin ignores the `konan.version` property in this case. - konan.home=/path/to/already/downloaded/compiler + konan.home=/home/user/kotlin-native-0.3 In this case the compiler will not be downloaded by the plugin. diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt index 1cbbc9ab731..d3026834873 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt @@ -75,8 +75,6 @@ open class KonanCompileTask: KonanTargetableTask() { val COMPILER_JVM_ARGS: List @Internal get() = listOf("-Dkonan.home=${project.konanHome}", "-Djava.library.path=${project.konanHome}/konan/nativelib") - val COMPILER_CLASSPATH: String - @Internal get() = "${project.konanHome}/konan/lib/" // Output artifact -------------------------------------------------------- @@ -175,7 +173,7 @@ open class KonanCompileTask: KonanTargetableTask() { project.javaexec { with(it) { main = COMPILER_MAIN - classpath = project.fileTree(COMPILER_CLASSPATH).apply { include("*.jar") } + classpath = project.konanCompilerClasspath jvmArgs(COMPILER_JVM_ARGS) args(buildArgs().apply { logger.info("Compiler args: ${this.joinToString(separator = " ")}") }) } diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompilerDownloadTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompilerDownloadTask.kt index 09edb52a001..9201c9d0e47 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompilerDownloadTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompilerDownloadTask.kt @@ -35,14 +35,27 @@ open class KonanCompilerDownloadTask : DefaultTask() { if (!project.hasProperty(KonanPlugin.ProjectProperty.DOWNLOAD_COMPILER)) { val konanHome = project.getProperty(KonanPlugin.ProjectProperty.KONAN_HOME) logger.info("Use a user-defined compiler path: $konanHome") + + val interopClasspath = project.konanInteropClasspath + if (interopClasspath.isEmpty) { + throw IllegalStateException("Stub generator classpath is empty: ${interopClasspath.dir}\n" + + "Probably the 'konan.home' project property contains an incorrect path. Please change it to the compiler root directory and rerun the build.") + } + + val compilerClasspath = project.konanCompilerClasspath + if (compilerClasspath.isEmpty) { + throw IllegalStateException("Kotlin/Native compiler classpath is empty: ${compilerClasspath.dir}\n" + + "Probably the 'konan.home' project property contains an incorrect path. Please change it to the compiler root directory and rerun the build.") + } + return } try { val konanCompiler = project.konanCompilerName() - logger.info("Downloading Kotlin Native compiler from $DOWNLOAD_URL/$konanCompiler into $KONAN_PARENT_DIR") + logger.info("Downloading Kotlin/Native compiler from $DOWNLOAD_URL/$konanCompiler into $KONAN_PARENT_DIR") DependencyDownloader(File(KONAN_PARENT_DIR), DOWNLOAD_URL, listOf(konanCompiler)).run() } catch (e: RuntimeException) { - throw GradleScriptException("Cannot download Kotlin Native compiler", e) + throw GradleScriptException("Cannot download Kotlin/Native compiler", e) } } } diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt index bdcc3269b1e..51faaa202ad 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt @@ -56,8 +56,6 @@ open class KonanInteropTask: KonanTargetableTask() { internal val INTEROP_JVM_ARGS: List @Internal get() = listOf("-Dkonan.home=${project.konanHome}", "-Djava.library.path=${project.konanHome}/konan/nativelib") - internal val INTEROP_CLASSPATH: String - @Internal get() = "${project.konanHome}/konan/lib/" // Output directories ----------------------------------------------------- @@ -100,7 +98,7 @@ open class KonanInteropTask: KonanTargetableTask() { project.javaexec { with(it) { main = INTEROP_MAIN - classpath = project.fileTree(INTEROP_CLASSPATH).apply { include("*.jar") } + classpath = project.konanInteropClasspath jvmArgs(INTEROP_JVM_ARGS) environment("LIBCLANG_DISABLE_CRASH_RECOVERY", "1") // TODO: remove this hack. diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt index 4225ce23b8c..41f90bc4b46 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt @@ -60,6 +60,12 @@ internal val Project.konanDefaultSrcDir get() = file("${projectDir.can internal fun Project.konanDefaultDefFile(interopName: String) = file("${projectDir.canonicalPath}/src/main/c_interop/$interopName.def") +internal val Project.konanInteropClasspath + get() = project.fileTree("${project.konanHome}/konan/lib/").apply { include("*.jar") } + +internal val Project.konanCompilerClasspath + get() = project.fileTree("${project.konanHome}/konan/lib/").apply { include("*.jar") } + @Suppress("UNCHECKED_CAST") internal val Project.konanArtifactsContainer: NamedDomainObjectContainer get() = extensions.getByName(KonanPlugin.ARTIFACTS_CONTAINER_NAME) as NamedDomainObjectContainer diff --git a/tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/PathSpecifiaction.groovy b/tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/PathSpecification.groovy similarity index 58% rename from tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/PathSpecifiaction.groovy rename to tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/PathSpecification.groovy index a13b1ee39ca..969cb44fa9d 100644 --- a/tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/PathSpecifiaction.groovy +++ b/tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/PathSpecification.groovy @@ -1,5 +1,6 @@ package org.jetbrains.kotlin.gradle.plugin.test +import org.gradle.testkit.runner.TaskOutcome import org.junit.Rule import org.junit.rules.TemporaryFolder import spock.lang.Specification @@ -29,4 +30,24 @@ class PathSpecification extends Specification { nativeLib.exists() && nativeLib.file } + def 'Plugin should stop building if the compiler classpath is empty'() { + when: + def project = KonanProject.createEmpty(tmpFolder) + project.propertiesFile.write("konan.home=${tmpFolder.root.canonicalPath}}") + def result = project.createRunner().withArguments('build').buildAndFail() + + then: + result.task(project.downloadTask).outcome == TaskOutcome.FAILED + } + + def 'Plugin should stop building if the stub generator classpath is empty'() { + when: + def project = KonanInteropProject.createEmpty(tmpFolder) + project.propertiesFile.write("konan.home=${tmpFolder.root.canonicalPath}}") + def result = project.createRunner().withArguments('build').buildAndFail() + + then: + result.task(project.downloadTask).outcome == TaskOutcome.FAILED + } + }