Download native compiler in configuration stage
This commit is contained in:
committed by
Ilya Matveev
parent
5a64067601
commit
80bec0898f
+18
@@ -17,6 +17,7 @@ import org.junit.Test
|
||||
import java.util.jar.JarFile
|
||||
import java.util.zip.ZipFile
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class NewMultiplatformIT : BaseGradleIT() {
|
||||
@@ -607,4 +608,21 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
assertTrue(output.contains("Dependent: Published print"), "No test output found")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNativeCompilerDownloading() {
|
||||
// The plugin shouldn't download the K/N compiler if there is no corresponding targets in the project.
|
||||
with(Project("new-mpp-lib-with-tests", gradleVersion)) {
|
||||
build("tasks") {
|
||||
assertSuccessful()
|
||||
assertFalse(output.contains("Kotlin/Native distribution: "))
|
||||
}
|
||||
}
|
||||
with(Project("new-mpp-native-libraries", gradleVersion)) {
|
||||
build("tasks") {
|
||||
assertSuccessful()
|
||||
assertTrue(output.contains("Kotlin/Native distribution: "))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-8
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.compilerRunner
|
||||
import org.gradle.api.Named
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.konan.util.DependencyDirectories
|
||||
@@ -26,10 +27,9 @@ import org.jetbrains.kotlin.konan.util.DependencyDirectories
|
||||
/** Copied from Kotlin/Native repository. */
|
||||
|
||||
internal enum class KotlinNativeProjectProperty(val propertyName: String) {
|
||||
KONAN_HOME ("org.jetbrains.kotlin.native.home"),
|
||||
KONAN_HOME_OVERRIDE ("org.jetbrains.kotlin.native.home"),
|
||||
KONAN_JVM_ARGS ("org.jetbrains.kotlin.native.jvmArgs"),
|
||||
KONAN_USE_ENVIRONMENT_VARIABLES("org.jetbrains.kotlin.native.useEnvironmentVariables"),
|
||||
DOWNLOAD_COMPILER ("org.jetbrains.kotlin.native.download.compiler"),
|
||||
KONAN_USE_ENVIRONMENT_VARIABLES("org.jetbrains.kotlin.native.useEnvironmentVariables")
|
||||
}
|
||||
|
||||
internal fun Project.hasProperty(property: KotlinNativeProjectProperty) = hasProperty(property.propertyName)
|
||||
@@ -44,12 +44,10 @@ internal fun Project.getProperty(property: KotlinNativeProjectProperty) = findPr
|
||||
internal val Project.jvmArgs
|
||||
get() = (findProperty(KotlinNativeProjectProperty.KONAN_JVM_ARGS) as String?)?.split("\\s+".toRegex()).orEmpty()
|
||||
|
||||
// konanHome extension is set by downloadKonanCompiler task.
|
||||
internal val Project.konanHome: String
|
||||
get() {
|
||||
assert(hasProperty(KotlinNativeProjectProperty.KONAN_HOME))
|
||||
return project.file(getProperty(KotlinNativeProjectProperty.KONAN_HOME)).canonicalPath
|
||||
}
|
||||
get() = findProperty(KotlinNativeProjectProperty.KONAN_HOME_OVERRIDE)?.let {
|
||||
file(it).absolutePath
|
||||
} ?: NativeCompilerDownloader(project).compilerDirectory.absolutePath
|
||||
|
||||
internal interface KonanToolRunner: Named {
|
||||
val mainClass: String
|
||||
|
||||
-8
@@ -36,7 +36,6 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.getSourceSetHierarchy
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
|
||||
import org.jetbrains.kotlin.gradle.tasks.KonanCompilerDownloadTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
|
||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
@@ -412,7 +411,6 @@ open class KotlinNativeTargetConfigurator(
|
||||
onlyIf { testExecutableProperty.get().exists() }
|
||||
inputs.file(testExecutableProperty)
|
||||
dependsOn(testExecutableLinkTask)
|
||||
dependsOnCompilerDownloading()
|
||||
}
|
||||
tasks.maybeCreate(LifecycleBasePlugin.CHECK_TASK_NAME).apply {
|
||||
dependsOn(testTask)
|
||||
@@ -507,7 +505,6 @@ open class KotlinNativeTargetConfigurator(
|
||||
addCompilerPlugins()
|
||||
|
||||
dependsOn(compilation.compileKotlinTaskName)
|
||||
dependsOnCompilerDownloading()
|
||||
linkAll.dependsOn(this)
|
||||
}
|
||||
|
||||
@@ -577,7 +574,6 @@ open class KotlinNativeTargetConfigurator(
|
||||
|
||||
registerOutputFiles(klibOutputDirectory(compilation))
|
||||
addCompilerPlugins()
|
||||
dependsOnCompilerDownloading()
|
||||
compilation.output.tryAddClassesDir {
|
||||
project.files(this.outputFile).builtBy(this)
|
||||
}
|
||||
@@ -609,7 +605,6 @@ open class KotlinNativeTargetConfigurator(
|
||||
"of target '${konanTarget.name}'."
|
||||
enabled = compilation.target.konanTarget.enabledOnCurrentHost
|
||||
|
||||
dependsOnCompilerDownloading()
|
||||
val interopOutput = project.files(outputFileProvider).builtBy(this)
|
||||
with(compilation) {
|
||||
project.dependencies.add(compileDependencyConfigurationName, interopOutput)
|
||||
@@ -655,9 +650,6 @@ open class KotlinNativeTargetConfigurator(
|
||||
configureCInterops(target)
|
||||
}
|
||||
|
||||
private fun Task.dependsOnCompilerDownloading() =
|
||||
dependsOn(KonanCompilerDownloadTask.KONAN_DOWNLOAD_TASK_NAME)
|
||||
|
||||
object NativeArtifactFormat {
|
||||
const val KLIB = "org.jetbrains.kotlin.klib"
|
||||
}
|
||||
|
||||
+1
-1
@@ -290,7 +290,7 @@ class KotlinNativeCompilation(
|
||||
internal val binaryTasks = mutableMapOf<Pair<NativeOutputKind, NativeBuildType>, KotlinNativeCompile>()
|
||||
|
||||
// Native-specific DSL.
|
||||
val extraOpts = mutableListOf<String>()
|
||||
var extraOpts = mutableListOf<String>()
|
||||
|
||||
fun extraOpts(vararg values: Any) = extraOpts(values.toList())
|
||||
fun extraOpts(values: List<Any>) {
|
||||
|
||||
+11
-11
@@ -20,9 +20,8 @@ import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.AndroidTasksProvider
|
||||
import org.jetbrains.kotlin.gradle.tasks.KonanCompilerDownloadTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.KonanCompilerDownloadTask.Companion.KONAN_DOWNLOAD_TASK_NAME
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
@@ -245,26 +244,27 @@ class KotlinNativeTargetPreset(
|
||||
|
||||
override fun getName(): String = name
|
||||
|
||||
private fun createCompilerDownloadingTask() = with(project) {
|
||||
if (!hasProperty(KotlinNativeProjectProperty.KONAN_HOME)) {
|
||||
setProperty(KotlinNativeProjectProperty.KONAN_HOME, KonanCompilerDownloadTask.compilerDirectory)
|
||||
setProperty(KotlinNativeProjectProperty.DOWNLOAD_COMPILER, true)
|
||||
private fun setupNativeCompiler() = with(project) {
|
||||
if (!hasProperty(KotlinNativeProjectProperty.KONAN_HOME_OVERRIDE)) {
|
||||
NativeCompilerDownloader(this).downloadIfNeeded()
|
||||
logger.info("Kotlin/Native distribution: $konanHome")
|
||||
} else {
|
||||
logger.info("User-provided Kotlin/Native distribution: $konanHome")
|
||||
}
|
||||
tasks.maybeCreate(KONAN_DOWNLOAD_TASK_NAME, KonanCompilerDownloadTask::class.java)
|
||||
}
|
||||
|
||||
private fun stdlib(target: KonanTarget): FileCollection = with(project) {
|
||||
files("${konanHome}/klib/common/stdlib").builtBy(createCompilerDownloadingTask())
|
||||
files("${konanHome}/klib/common/stdlib")
|
||||
}
|
||||
|
||||
private fun platformLibs(target: KonanTarget): FileCollection = with(project) {
|
||||
files(provider {
|
||||
file("${project.konanHome}/klib/platform/${target.name}").listFiles { file -> file.isDirectory } ?: emptyArray()
|
||||
}).builtBy(createCompilerDownloadingTask())
|
||||
file("${konanHome}/klib/platform/${target.name}").listFiles { file -> file.isDirectory } ?: emptyArray()
|
||||
})
|
||||
}
|
||||
|
||||
override fun createTarget(name: String): KotlinNativeTarget {
|
||||
createCompilerDownloadingTask()
|
||||
setupNativeCompiler()
|
||||
|
||||
val result = KotlinNativeTarget(project, konanTarget).apply {
|
||||
targetName = name
|
||||
|
||||
+2
-100
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultCInteropSettings
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.defaultSourceSetName
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.isMainCompilation
|
||||
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
|
||||
import org.jetbrains.kotlin.konan.KonanVersion
|
||||
import org.jetbrains.kotlin.konan.KonanVersionImpl
|
||||
import org.jetbrains.kotlin.konan.MetaVersion
|
||||
@@ -77,8 +78,6 @@ private fun File.providedByCompiler(project: Project): Boolean =
|
||||
open class KotlinNativeCompile : AbstractCompile() {
|
||||
|
||||
init {
|
||||
dependsOn(KonanCompilerDownloadTask.KONAN_DOWNLOAD_TASK_NAME)
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
setDestinationDir(project.provider {
|
||||
val output = outputFile.get()
|
||||
@@ -155,7 +154,7 @@ open class KotlinNativeCompile : AbstractCompile() {
|
||||
// endregion.
|
||||
|
||||
val kotlinNativeVersion: String
|
||||
@Input get() = KonanCompilerDownloadTask.compilerVersion.toString()
|
||||
@Input get() = NativeCompilerDownloader(project).compilerVersion.toString()
|
||||
|
||||
// We manually register this property as output file or directory depending on output kind.
|
||||
@Internal
|
||||
@@ -333,100 +332,3 @@ open class CInteropProcess: DefaultTask() {
|
||||
KonanInteropRunner(project).run(args)
|
||||
}
|
||||
}
|
||||
|
||||
open class KonanCompilerDownloadTask : DefaultTask() {
|
||||
|
||||
internal companion object {
|
||||
|
||||
val simpleOsName: String = HostManager.simpleOsName()
|
||||
|
||||
val compilerDirectory: File
|
||||
get() = DependencyDirectories.localKonanDir.resolve("kotlin-native-$simpleOsName-$compilerVersion")
|
||||
|
||||
// TODO: Support project property for Kotlin/Native compiler version
|
||||
val compilerVersion: KonanVersion = KonanVersionImpl(MetaVersion.RELEASE, 0, 9, 0)
|
||||
|
||||
internal const val BASE_DOWNLOAD_URL = "https://download.jetbrains.com/kotlin/native/builds"
|
||||
const val KONAN_DOWNLOAD_TASK_NAME = "checkNativeCompiler"
|
||||
}
|
||||
|
||||
private val useZip = HostManager.hostIsMingw
|
||||
|
||||
private val archiveExtension
|
||||
get() = if (useZip) {
|
||||
"zip"
|
||||
} else {
|
||||
"tar.gz"
|
||||
}
|
||||
|
||||
private fun archiveFileTree(archive: File): FileTree =
|
||||
if (useZip) {
|
||||
project.zipTree(archive)
|
||||
} else {
|
||||
project.tarTree(archive)
|
||||
}
|
||||
|
||||
private fun setupRepo(url: String): ArtifactRepository {
|
||||
return project.repositories.ivy { repo ->
|
||||
repo.setUrl(url)
|
||||
repo.layout("pattern") {
|
||||
val layout = it as IvyPatternRepositoryLayout
|
||||
layout.artifact("[artifact]-[revision].[ext]")
|
||||
}
|
||||
repo.metadataSources {
|
||||
it.artifact()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeRepo(repo: ArtifactRepository) {
|
||||
project.repositories.remove(repo)
|
||||
}
|
||||
|
||||
private fun downloadAndExtract() {
|
||||
val versionString = compilerVersion.toString()
|
||||
|
||||
val url = buildString {
|
||||
append("$BASE_DOWNLOAD_URL/")
|
||||
append(if (compilerVersion.meta == MetaVersion.DEV) "dev/" else "releases/")
|
||||
append("$versionString/")
|
||||
append(simpleOsName)
|
||||
}
|
||||
|
||||
val repo = setupRepo(url)
|
||||
|
||||
val compilerDependency = project.dependencies.create(
|
||||
mapOf(
|
||||
"name" to "kotlin-native-$simpleOsName",
|
||||
"version" to versionString,
|
||||
"ext" to archiveExtension
|
||||
)
|
||||
)
|
||||
|
||||
val configuration = project.configurations.detachedConfiguration(compilerDependency)
|
||||
val archive = configuration.files.single()
|
||||
|
||||
logger.info("Use Kotlin/Native compiler archive: ${archive.absolutePath}")
|
||||
logger.lifecycle("Unpacking Kotlin/Native compiler (version $versionString)...")
|
||||
project.copy {
|
||||
it.from(archiveFileTree(archive))
|
||||
it.into(DependencyDirectories.localKonanDir)
|
||||
}
|
||||
|
||||
removeRepo(repo)
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun checkCompiler() {
|
||||
if (!project.hasProperty(KotlinNativeProjectProperty.DOWNLOAD_COMPILER)) {
|
||||
val konanHome = project.getProperty(KotlinNativeProjectProperty.KONAN_HOME)
|
||||
logger.info("Use a user-defined compiler path: $konanHome")
|
||||
} else {
|
||||
// TODO: Move Kotlin/Native Distribution class in the Big Kotlin repo and use it here.
|
||||
if (KonanCompilerRunner(project).classpath.isEmpty) {
|
||||
downloadAndExtract()
|
||||
}
|
||||
logger.info("Use Kotlin/Native distribution: $compilerDirectory")
|
||||
}
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.utils
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.repositories.ArtifactRepository
|
||||
import org.gradle.api.artifacts.repositories.IvyPatternRepositoryLayout
|
||||
import org.gradle.api.file.FileTree
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.jetbrains.kotlin.compilerRunner.KonanCompilerRunner
|
||||
import org.jetbrains.kotlin.konan.KonanVersion
|
||||
import org.jetbrains.kotlin.konan.KonanVersionImpl
|
||||
import org.jetbrains.kotlin.konan.MetaVersion
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.util.DependencyDirectories
|
||||
import java.io.File
|
||||
|
||||
class NativeCompilerDownloader(val project: Project) {
|
||||
|
||||
internal companion object {
|
||||
const val BASE_DOWNLOAD_URL = "https://download.jetbrains.com/kotlin/native/builds"
|
||||
}
|
||||
|
||||
private val logger: Logger
|
||||
get() = project.logger
|
||||
|
||||
private val simpleOsName: String
|
||||
get() = HostManager.simpleOsName()
|
||||
|
||||
private val useZip
|
||||
get() = HostManager.hostIsMingw
|
||||
|
||||
private val archiveExtension
|
||||
get() = if (useZip) {
|
||||
"zip"
|
||||
} else {
|
||||
"tar.gz"
|
||||
}
|
||||
|
||||
private fun archiveFileTree(archive: File): FileTree =
|
||||
if (useZip) {
|
||||
project.zipTree(archive)
|
||||
} else {
|
||||
project.tarTree(archive)
|
||||
}
|
||||
|
||||
private fun setupRepo(url: String): ArtifactRepository {
|
||||
return project.repositories.ivy { repo ->
|
||||
repo.setUrl(url)
|
||||
repo.layout("pattern") {
|
||||
val layout = it as IvyPatternRepositoryLayout
|
||||
layout.artifact("[artifact]-[revision].[ext]")
|
||||
}
|
||||
repo.metadataSources {
|
||||
it.artifact()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeRepo(repo: ArtifactRepository) {
|
||||
project.repositories.remove(repo)
|
||||
}
|
||||
|
||||
private fun downloadAndExtract() {
|
||||
val versionString = compilerVersion.toString()
|
||||
|
||||
val url = buildString {
|
||||
append("$BASE_DOWNLOAD_URL/")
|
||||
append(if (compilerVersion.meta == MetaVersion.DEV) "dev/" else "releases/")
|
||||
append("$versionString/")
|
||||
append(simpleOsName)
|
||||
}
|
||||
|
||||
val repo = setupRepo(url)
|
||||
|
||||
val compilerDependency = project.dependencies.create(
|
||||
mapOf(
|
||||
"name" to "kotlin-native-$simpleOsName",
|
||||
"version" to versionString,
|
||||
"ext" to archiveExtension
|
||||
)
|
||||
)
|
||||
|
||||
val configuration = project.configurations.detachedConfiguration(compilerDependency)
|
||||
val archive = configuration.files.single()
|
||||
|
||||
logger.info("Use Kotlin/Native compiler archive: ${archive.absolutePath}")
|
||||
logger.lifecycle("Unpacking Kotlin/Native compiler (version $versionString)...")
|
||||
project.copy {
|
||||
it.from(archiveFileTree(archive))
|
||||
it.into(DependencyDirectories.localKonanDir)
|
||||
}
|
||||
|
||||
removeRepo(repo)
|
||||
}
|
||||
|
||||
val compilerDirectory: File
|
||||
get() = DependencyDirectories.localKonanDir.resolve("kotlin-native-$simpleOsName-$compilerVersion")
|
||||
|
||||
// TODO: Support project property for Kotlin/Native compiler version
|
||||
val compilerVersion: KonanVersion = KonanVersionImpl(MetaVersion.RELEASE, 0, 9, 0)
|
||||
|
||||
fun downloadIfNeeded() {
|
||||
if (KonanCompilerRunner(project).classpath.isEmpty) {
|
||||
downloadAndExtract()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user