gradle-plugin: Allow 'manual' dependency downloading
This patch adds an ability to download native dependencies (clang, sysroots etc) during execution of the `downloadKonanCompiler` task. The feature can by enabled by setting the `downloadDependencies` property of the `downloadKonanCompiler` task to true. Targets for these dependencies may be specified as a string list using `targets` property of the `downloadKonanCompiler` task.
This commit is contained in:
@@ -14,10 +14,15 @@ konanArtifacts {
|
||||
}
|
||||
|
||||
task compileCpp(type: Exec) {
|
||||
dependsOn 'downloadKonanCompiler'
|
||||
workingDir project.getProjectDir()
|
||||
commandLine './buildCpp.sh'
|
||||
}
|
||||
|
||||
compileKonanMessageChannel {
|
||||
dependsOn 'compileCpp'
|
||||
}
|
||||
|
||||
downloadKonanCompiler {
|
||||
downloadDependencies = true
|
||||
}
|
||||
+1
-15
@@ -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<String>
|
||||
@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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+28
-20
@@ -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<String> = mutableSetOf<String>()
|
||||
|
||||
/** 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) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-22
@@ -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<String>
|
||||
@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<String>().apply {
|
||||
|
||||
-6
@@ -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<KonanCompileConfig>
|
||||
get() = extensions.getByName(KonanPlugin.ARTIFACTS_CONTAINER_NAME) as NamedDomainObjectContainer<KonanCompileConfig>
|
||||
|
||||
+72
@@ -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<String>
|
||||
val environment: Map<String, Any>
|
||||
|
||||
fun run(args: List<String>)
|
||||
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<String>
|
||||
get() = listOf("-Dkonan.home=${project.konanHome}", "-Djava.library.path=${project.konanHome}/konan/nativelib")
|
||||
|
||||
override val environment: Map<String, Any>
|
||||
get() = emptyMap()
|
||||
|
||||
override fun run(args: List<String>) {
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user