diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinNativeToolRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinNativeToolRunner.kt index 6b64d0c41ba..1800bcf8ae9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinNativeToolRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinNativeToolRunner.kt @@ -27,7 +27,11 @@ import org.jetbrains.kotlin.konan.KonanVersion import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.util.DependencyDirectories +import java.io.File +import java.lang.reflect.InvocationTargetException +import java.net.URLClassLoader import java.util.* +import java.util.concurrent.ConcurrentHashMap /** Copied from Kotlin/Native repository. */ @@ -44,6 +48,9 @@ internal val Project.konanVersion: KonanVersion KonanVersion.fromString(it.toString()) } ?: NativeCompilerDownloader.DEFAULT_KONAN_VERSION +internal val Project.disableKonanDaemon: Boolean + get() = PropertiesProvider(this).nativeDisableCompilerDaemon == true + internal interface KonanToolRunner : Named { val mainClass: String val classpath: FileCollection @@ -123,25 +130,64 @@ internal abstract class KonanCliRunner( ) } - project.javaexec { spec -> - spec.main = mainClass - spec.classpath = classpath - spec.jvmArgs(jvmArgs) - spec.systemProperties( - System.getProperties().asSequence() - .map { (k, v) -> k.toString() to v.toString() } - .filter { (k, _) -> k !in blacklistProperties } - .escapeQuotesForWindows() - .toMap() - ) - spec.systemProperties(additionalSystemProperties) - spec.args(listOf(toolName) + transformArgs(args)) - blacklistEnvironment.forEach { spec.environment.remove(it) } - spec.environment(environment) + if (project.disableKonanDaemon || toolName == "cinterop") { + project.javaexec { spec -> + spec.main = mainClass + spec.classpath = classpath + spec.jvmArgs(jvmArgs) + spec.systemProperties( + System.getProperties().asSequence() + .map { (k, v) -> k.toString() to v.toString() } + .filter { (k, _) -> k !in blacklistProperties } + .escapeQuotesForWindows() + .toMap() + ) + spec.systemProperties(additionalSystemProperties) + spec.args(listOf(toolName) + transformArgs(args)) + blacklistEnvironment.forEach { spec.environment.remove(it) } + spec.environment(environment) + } + } else { + val oldProperties = mutableMapOf() + additionalSystemProperties.forEach { + oldProperties[it.key] = System.getProperty(it.key) + } + System.getProperties().toList() + .map { (k, v) -> k.toString() to v.toString() } + .filter { (k, _) -> k in blacklistProperties } + .forEach { (k, v) -> + oldProperties[k] = v + System.clearProperty(k) + } + + additionalSystemProperties.forEach { System.setProperty(it.key, it.value) } + + val konanCompilerClassLoader = konanCompilerClassLoadersMap.computeIfAbsent(project.konanHome) { + val arrayOfURLs = classpath.map { File(it.absolutePath).toURI().toURL() }.toTypedArray() + URLClassLoader(arrayOfURLs, null) + } + + val mainClass = konanCompilerClassLoader.loadClass(mainClass) + val mainMethod = mainClass.methods.single { it.name == "daemonMain" } + + try { + mainMethod.invoke(null, (listOf(toolName) + transformArgs(args)).toTypedArray()) + } catch (t: InvocationTargetException) { + throw t.targetException + } finally { + oldProperties.forEach { + val value = it.value + if (value == null) + System.clearProperty(it.key) + else System.setProperty(it.key, value) + } + } } } } +private val konanCompilerClassLoadersMap = ConcurrentHashMap() + internal class KonanInteropRunner(project: Project, additionalJvmArgs: List = emptyList()) : KonanCliRunner("cinterop", "Kotlin/Native cinterop tool", project, additionalJvmArgs) { init { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt index 5e56bde77c5..48b2a5f89e0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt @@ -140,6 +140,12 @@ internal class PropertiesProvider private constructor(private val project: Proje val nativeJvmArgs: String? get() = propertyWithDeprecatedVariant("kotlin.native.jvmArgs", "org.jetbrains.kotlin.native.jvmArgs") + /** + * Forces to run a compilation in a separate JVM. + */ + val nativeDisableCompilerDaemon: Boolean? + get() = booleanProperty("kotlin.native.disableCompilerDaemon") + /** * Generate kotlin/js external declarations from all .d.ts files found in npm modules */