diff --git a/samples/concurrent/build.gradle b/samples/concurrent/build.gradle index fa7a7ba3f4e..ef492aff51b 100644 --- a/samples/concurrent/build.gradle +++ b/samples/concurrent/build.gradle @@ -14,10 +14,15 @@ konanArtifacts { } task compileCpp(type: Exec) { + dependsOn 'downloadKonanCompiler' workingDir project.getProjectDir() commandLine './buildCpp.sh' } compileKonanMessageChannel { dependsOn 'compileCpp' +} + +downloadKonanCompiler { + downloadDependencies = true } \ No newline at end of file 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 81c4e99c1dc..1d5fb3ccc6b 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 @@ -29,13 +29,6 @@ import java.io.File */ open class KonanCompileTask: KonanTargetableTask() { - companion object { - const val COMPILER_MAIN = "org.jetbrains.kotlin.cli.bc.K2NativeKt" - } - - val COMPILER_JVM_ARGS: List - @Internal get() = listOf("-Dkonan.home=${project.konanHome}", "-Djava.library.path=${project.konanHome}/konan/nativelib") - // Output artifact -------------------------------------------------------- internal lateinit var artifactName: String @@ -146,14 +139,7 @@ open class KonanCompileTask: KonanTargetableTask() { if (dumpParameters) dumpProperties(this@KonanCompileTask) // TODO: Use compiler service. - project.javaexec { - with(it) { - main = COMPILER_MAIN - classpath = project.konanCompilerClasspath - jvmArgs(COMPILER_JVM_ARGS) - args(buildArgs().apply { logger.info("Compiler args: ${this.joinToString(separator = " ")}") }) - } - } + KonanCompilerRunner(project).run(buildArgs()) } } 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 b78ddcccd0f..42ffb726584 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 @@ -18,9 +18,10 @@ package org.jetbrains.kotlin.gradle.plugin import org.gradle.api.DefaultTask import org.gradle.api.GradleScriptException -import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.* import org.jetbrains.kotlin.konan.util.DependencyProcessor import java.io.File +import java.io.IOException open class KonanCompilerDownloadTask : DefaultTask() { @@ -30,32 +31,39 @@ open class KonanCompilerDownloadTask : DefaultTask() { internal val KONAN_PARENT_DIR = "${System.getProperty("user.home")}/.konan" } + /** + * A list of tasks used to download dependencies. If empty then dependencies will be downloaded for the host. + * Isn't used if [downloadDependencies] is false. + */ + @Internal var targets: MutableCollection = mutableSetOf() + + /** If true the task will also download dependencies for targets specified by [targets] property. */ + @Internal var downloadDependencies: Boolean = false + @TaskAction fun downloadAndExtract() { 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.") + } else { + try { + val konanCompiler = project.konanCompilerName() + logger.info("Downloading Kotlin/Native compiler from $DOWNLOAD_URL/$konanCompiler into $KONAN_PARENT_DIR") + DependencyProcessor(File(KONAN_PARENT_DIR), DOWNLOAD_URL, listOf(konanCompiler)).run() + } catch (e: IOException) { + throw GradleScriptException("Cannot download Kotlin/Native compiler", e) } - - 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") - DependencyProcessor(File(KONAN_PARENT_DIR), DOWNLOAD_URL, listOf(konanCompiler)).run() - } catch (e: RuntimeException) { - throw GradleScriptException("Cannot download Kotlin/Native compiler", e) + + // Download dependencies if a user said so. + if (downloadDependencies) { + val runner = KonanCompilerRunner(project) + if (targets.isEmpty()) { + // Download for the host. + runner.run("--check_dependencies") + } else { + targets.forEach { runner.run("--check_dependencies", "-target", it) } + } } } } 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 4c677632282..863c04be14f 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 @@ -29,19 +29,12 @@ import java.io.File */ open class KonanInteropTask: KonanTargetableTask() { - internal companion object { - const val INTEROP_MAIN = "org.jetbrains.kotlin.native.interop.gen.jvm.MainKt" - } - internal fun init(libName: String) { dependsOn(project.konanCompilerDownloadTask) this.libName = libName this.defFile = project.konanDefaultDefFile(libName) } - internal val INTEROP_JVM_ARGS: List - @Internal get() = listOf("-Dkonan.home=${project.konanHome}", "-Djava.library.path=${project.konanHome}/konan/nativelib") - // Output directories ----------------------------------------------------- /** Directory with autogenerated interop stubs (*.kt) */ @@ -82,21 +75,7 @@ open class KonanInteropTask: KonanTargetableTask() { @TaskAction fun exec() { if (dumpParameters) dumpProperties(this@KonanInteropTask) - - project.javaexec { - with(it) { - main = INTEROP_MAIN - classpath = project.konanInteropClasspath - jvmArgs(INTEROP_JVM_ARGS) - environment("LIBCLANG_DISABLE_CRASH_RECOVERY", "1") - // TODO: remove this hack. - if (project.host == "mingw") { - environment("PATH", "${project.konanHome}\\dependencies\\msys2-mingw-w64-x86_64-gcc-6.3.0-clang-llvm-3.9.1-windows-x86-64\\bin;${System.getenv("PATH")}") - } - - args(buildArgs().apply { logger.info("Interop args: ${this.joinToString(separator = " ")}") }) - } - } + KonanInteropRunner(project).run(buildArgs()) } protected fun buildArgs() = mutableListOf().apply { 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 03741d58b85..36de6b7e124 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,12 +60,6 @@ internal val Project.konanDefaultSrcFiles get() = fileTree("${projectDir internal fun Project.konanDefaultDefFile(libName: String) = file("${projectDir.canonicalPath}/src/main/c_interop/$libName.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/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanToolRunner.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanToolRunner.kt new file mode 100644 index 00000000000..b2549bbaad0 --- /dev/null +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanToolRunner.kt @@ -0,0 +1,72 @@ +package org.jetbrains.kotlin.gradle.plugin + +import org.gradle.api.Project +import org.gradle.api.file.FileCollection + +// Consider using JavaExecSPec +internal interface KonanToolRunner { + val mainClass: String + val classpath: FileCollection + val jvmArgs: List + val environment: Map + + fun run(args: List) + fun run(vararg args: String) = run(args.toList()) +} + +internal abstract class KonanBaseRunner(val project: Project): KonanToolRunner { + abstract val toolName: String + + override val classpath: FileCollection + get() = project.fileTree("${project.konanHome}/konan/lib/").apply { include("*.jar") } + + override val jvmArgs: List + get() = listOf("-Dkonan.home=${project.konanHome}", "-Djava.library.path=${project.konanHome}/konan/nativelib") + + override val environment: Map + get() = emptyMap() + + override fun run(args: List) { + if (classpath.isEmpty) { + throw IllegalStateException("Classpath if the tool is empty: $toolName\n" + + "Probably the 'konan.home' project property contains an incorrect path.\n" + + "Please change it to the compiler root directory and rerun the build.") + } + + project.javaexec { + it.main = mainClass + it.classpath = classpath + it.jvmArgs(jvmArgs) + it.args(args.apply { + project.logger.info("Run tool: $toolName with args: ${this.joinToString(separator = " ")}") + }) + it.environment(environment) + } + } +} + +internal class KonanInteropRunner(project: Project) : KonanBaseRunner(project){ + internal companion object { + const val INTEROP_MAIN = "org.jetbrains.kotlin.native.interop.gen.jvm.MainKt" + } + + override val toolName get() = "Kotlin/Native cinterop tool" + override val mainClass get() = INTEROP_MAIN + + override val environment = mutableMapOf("LIBCLANG_DISABLE_CRASH_RECOVERY" to "1").apply { + if (project.host == "mingw") { + put("PATH", "${project.konanHome}\\dependencies" + + "\\msys2-mingw-w64-x86_64-gcc-6.3.0-clang-llvm-3.9.1-windows-x86-64" + + "\\bin;${System.getenv("PATH")}") + } + } +} + +internal class KonanCompilerRunner(project: Project) : KonanBaseRunner(project) { + internal companion object { + const val COMPILER_MAIN = "org.jetbrains.kotlin.cli.bc.K2NativeKt" + } + + override val toolName get() = "Kotlin/Native compiler" + override val mainClass get() = COMPILER_MAIN +}