You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
5.8 KiB
144 lines
5.8 KiB
/* |
|
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
|
*/ |
|
|
|
package org.jetbrains.compose.desktop.application.tasks |
|
|
|
import org.gradle.api.file.ConfigurableFileCollection |
|
import org.gradle.api.file.RegularFile |
|
import org.gradle.api.provider.Property |
|
import org.gradle.api.provider.Provider |
|
import org.gradle.api.tasks.* |
|
import org.jetbrains.compose.desktop.application.internal.ComposeProperties |
|
import org.jetbrains.compose.desktop.application.internal.JvmRuntimeProperties |
|
import org.jetbrains.compose.desktop.application.internal.ExternalToolRunner |
|
import org.jetbrains.compose.desktop.application.internal.JdkVersionProbe |
|
import org.jetbrains.compose.desktop.tasks.AbstractComposeDesktopTask |
|
import org.jetbrains.compose.internal.utils.OS |
|
import org.jetbrains.compose.internal.utils.currentOS |
|
import org.jetbrains.compose.internal.utils.executableName |
|
import org.jetbrains.compose.internal.utils.ioFile |
|
import org.jetbrains.compose.internal.utils.notNullProperty |
|
import java.io.ByteArrayInputStream |
|
import java.io.File |
|
import java.util.* |
|
|
|
// __COMPOSE_NATIVE_DISTRIBUTIONS_MIN_JAVA_VERSION__ |
|
internal const val MIN_JAVA_RUNTIME_VERSION = 17 |
|
|
|
@CacheableTask |
|
abstract class AbstractCheckNativeDistributionRuntime : AbstractComposeDesktopTask() { |
|
@get:Classpath |
|
val jdkVersionProbeJar: ConfigurableFileCollection = objects.fileCollection() |
|
|
|
@get:PathSensitive(PathSensitivity.ABSOLUTE) |
|
@get:InputDirectory |
|
val jdkHome: Property<String> = objects.notNullProperty() |
|
|
|
@get:Input |
|
abstract val checkJdkVendor: Property<Boolean> |
|
|
|
private val taskDir = project.layout.buildDirectory.dir("compose/tmp/$name") |
|
|
|
@get:OutputFile |
|
val javaRuntimePropertiesFile: Provider<RegularFile> = taskDir.map { it.file("properties.bin") } |
|
|
|
private val jdkHomeFile: File |
|
get() = File(jdkHome.orNull ?: error("Missing jdkHome value")) |
|
|
|
private fun File.getJdkTool(toolName: String): File = |
|
resolve("bin/${executableName(toolName)}") |
|
|
|
private fun ensureToolsExist(vararg tools: File) { |
|
val missingTools = tools.filter { !it.exists() }.map { "'${it.name}'" } |
|
|
|
if (missingTools.isEmpty()) return |
|
|
|
if (missingTools.size == 1) jdkDistributionProbingError("${missingTools.single()} is missing") |
|
|
|
jdkDistributionProbingError("${missingTools.joinToString(", ")} are missing") |
|
} |
|
|
|
private fun jdkDistributionProbingError(errorMessage: String): Nothing { |
|
val fullErrorMessage = buildString { |
|
appendLine("Failed to check JDK distribution: $errorMessage") |
|
appendLine("JDK distribution path: ${jdkHomeFile.absolutePath}") |
|
} |
|
error(fullErrorMessage) |
|
} |
|
|
|
@TaskAction |
|
fun run() { |
|
taskDir.ioFile.mkdirs() |
|
|
|
val jdkHome = jdkHomeFile |
|
val javaExecutable = jdkHome.getJdkTool("java") |
|
val jlinkExecutable = jdkHome.getJdkTool("jlink") |
|
val jpackageExecutabke = jdkHome.getJdkTool("jpackage") |
|
ensureToolsExist(javaExecutable, jlinkExecutable, jpackageExecutabke) |
|
|
|
val jdkRuntimeProperties = getJDKRuntimeProperties(javaExecutable) |
|
|
|
val jdkMajorVersionString = jdkRuntimeProperties.getProperty(JdkVersionProbe.JDK_MAJOR_VERSION_KEY) |
|
val jdkMajorVersion = jdkMajorVersionString?.toIntOrNull() |
|
?: jdkDistributionProbingError("JDK version '$jdkMajorVersionString' has unexpected format") |
|
|
|
check(jdkMajorVersion >= MIN_JAVA_RUNTIME_VERSION) { |
|
jdkDistributionProbingError( |
|
"minimum required JDK version is '$MIN_JAVA_RUNTIME_VERSION', " + |
|
"but actual version is '$jdkMajorVersion'" |
|
) |
|
} |
|
|
|
if (checkJdkVendor.get()) { |
|
val vendor = jdkRuntimeProperties.getProperty(JdkVersionProbe.JDK_VENDOR_KEY) |
|
if (vendor == null) { |
|
logger.warn("JDK vendor probe failed: $jdkHome") |
|
} else { |
|
if (currentOS == OS.MacOS && vendor.equals("homebrew", ignoreCase = true)) { |
|
error( |
|
""" |
|
|Homebrew's JDK distribution may cause issues with packaging. |
|
|See: https://github.com/JetBrains/compose-multiplatform/issues/3107 |
|
|Possible solutions: |
|
|* Use other vendor's JDK distribution, such as Amazon Corretto; |
|
|* To continue using Homebrew distribution for packaging on your own risk, add "${ComposeProperties.CHECK_JDK_VENDOR}=false" to your gradle.properties |
|
""".trimMargin()) |
|
} |
|
} |
|
} |
|
|
|
val modules = arrayListOf<String>() |
|
runExternalTool( |
|
tool = javaExecutable, |
|
args = listOf("--list-modules"), |
|
logToConsole = ExternalToolRunner.LogToConsole.Never, |
|
processStdout = { stdout -> |
|
stdout.lineSequence().forEach { line -> |
|
val moduleName = line.trim().substringBefore("@") |
|
if (moduleName.isNotBlank()) { |
|
modules.add(moduleName) |
|
} |
|
} |
|
} |
|
) |
|
|
|
val properties = JvmRuntimeProperties(jdkMajorVersion, modules) |
|
JvmRuntimeProperties.writeToFile(properties, javaRuntimePropertiesFile.ioFile) |
|
} |
|
|
|
private fun getJDKRuntimeProperties(javaExecutable: File): Properties { |
|
val jdkProperties = Properties() |
|
runExternalTool( |
|
tool = javaExecutable, |
|
args = listOf("-jar", jdkVersionProbeJar.files.single().absolutePath), |
|
processStdout = { stdout -> |
|
ByteArrayInputStream(stdout.trim().toByteArray()).use { |
|
jdkProperties.loadFromXML(it) |
|
} |
|
} |
|
) |
|
return jdkProperties |
|
} |
|
}
|
|
|