mirror of
https://github.com/apple/pkl.git
synced 2026-06-11 08:12:50 +02:00
Enable Gradle configuration cache (#1646)
Enable the configuration cache feature in Gradle, and adjust various pieces of build logic that aren't configuration cache compatible.
This commit is contained in:
@@ -288,7 +288,12 @@ open class BuildInfo(private val project: Project) {
|
||||
classpath = template.classpath
|
||||
testClassesDirs = template.testClassesDirs
|
||||
jvmArgs.addAll(template.jvmArgs)
|
||||
jvmArgumentProviders.addAll(template.jvmArgumentProviders)
|
||||
// jvmArgumentProviders are NOT copied: providers added by plugins (e.g.
|
||||
// java-gradle-plugin's GradleJvmCommandLineArgumentProvider) hold a direct
|
||||
// reference to the task they were registered on. Copying them to derived tasks
|
||||
// causes those tasks to capture a foreign task reference, which the
|
||||
// configuration cache cannot serialize. Each derived task receives its own
|
||||
// providers via withType<Test>().configureEach in the subproject.
|
||||
forkEvery = template.forkEvery
|
||||
maxParallelForks = template.maxParallelForks
|
||||
minHeapSize = template.minHeapSize
|
||||
@@ -372,35 +377,33 @@ open class BuildInfo(private val project: Project) {
|
||||
org.gradle.internal.os.OperatingSystem.current()
|
||||
}
|
||||
|
||||
// could be `commitId: Provider<String> = project.provider { ... }`
|
||||
val commitId: String by lazy {
|
||||
// allow -DcommitId=abc123 for build environments that don't have git.
|
||||
System.getProperty("commitId").let { if (it != null) return@lazy it }
|
||||
private val computedCommitId: Provider<String> =
|
||||
// only run command once per build invocation
|
||||
if (project.path == project.rootProject.path) {
|
||||
val process =
|
||||
ProcessBuilder()
|
||||
.command("git", "rev-parse", "--short", "HEAD")
|
||||
.directory(project.rootDir)
|
||||
.start()
|
||||
process.waitFor().also { exitCode ->
|
||||
if (exitCode == -1) throw RuntimeException(process.errorStream.reader().readText())
|
||||
}
|
||||
process.inputStream.reader().readText().trim()
|
||||
project.providers
|
||||
.exec { commandLine("git", "rev-parse", "--short", "HEAD") }
|
||||
.standardOutput
|
||||
.asText
|
||||
.map { it.trim() }
|
||||
} else {
|
||||
project.rootProject.extensions.getByType(BuildInfo::class.java).commitId
|
||||
}
|
||||
}
|
||||
|
||||
val commitish: String by lazy { if (isReleaseBuild) project.version.toString() else commitId }
|
||||
val commitId: Provider<String> =
|
||||
// allow -DcommitId=abc123 for build environments that don't have git.
|
||||
System.getProperty("commitId")?.let { project.providers.provider { it } } ?: computedCommitId
|
||||
|
||||
val pklVersion: String by lazy {
|
||||
val commitish: Provider<String> =
|
||||
if (isReleaseBuild) project.providers.provider { project.version.toString() } else commitId
|
||||
|
||||
val pklVersion: Provider<String> =
|
||||
if (isReleaseBuild) {
|
||||
project.version.toString()
|
||||
project.providers.provider { project.version.toString() }
|
||||
} else {
|
||||
project.version.toString().replace("-SNAPSHOT", "-dev+$commitId")
|
||||
project.providers
|
||||
.provider { project.version.toString() }
|
||||
.zip(commitId) { version, id -> version.replace("-SNAPSHOT", "-dev+$id") }
|
||||
}
|
||||
}
|
||||
|
||||
val pklVersionNonUnique: String by lazy {
|
||||
if (isReleaseBuild) {
|
||||
|
||||
@@ -20,9 +20,13 @@ import java.util.*
|
||||
import javax.inject.Inject
|
||||
import kotlin.io.path.createDirectories
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.internal.file.FileOperations
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.process.ExecOperations
|
||||
|
||||
@@ -32,25 +36,32 @@ constructor(
|
||||
private val fileOperations: FileOperations,
|
||||
private val execOperations: ExecOperations,
|
||||
) : DefaultTask() {
|
||||
@get:Input abstract val graalVm: Property<BuildInfo.GraalVm>
|
||||
@get:Input abstract val homeDir: Property<String>
|
||||
|
||||
@get:InputFile abstract val downloadFile: RegularFileProperty
|
||||
|
||||
@get:Input abstract val version: Property<String>
|
||||
|
||||
@get:Input abstract val graalVmJdkVersion: Property<String>
|
||||
|
||||
@get:Internal abstract val installDir: DirectoryProperty
|
||||
|
||||
init {
|
||||
@Suppress("LeakingThis") onlyIf("GraalVM not installed") { !graalVm.get().installDir.exists() }
|
||||
@Suppress("LeakingThis") onlyIf("GraalVM not installed") { !installDir.get().asFile.exists() }
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
@Suppress("unused")
|
||||
fun run() {
|
||||
// minimize chance of corruption by extract-to-random-dir-and-flip-symlink
|
||||
val distroDir = Paths.get(graalVm.get().homeDir, UUID.randomUUID().toString())
|
||||
val distroDir = Paths.get(homeDir.get(), UUID.randomUUID().toString())
|
||||
try {
|
||||
distroDir.createDirectories()
|
||||
println("Extracting ${graalVm.get().downloadFile} into $distroDir")
|
||||
println("Extracting ${downloadFile.get().asFile} into $distroDir")
|
||||
// faster and more reliable than Gradle's `copy { from tarTree() }`
|
||||
execOperations.exec {
|
||||
workingDir = distroDir.toFile()
|
||||
executable = "tar"
|
||||
args("--strip-components=1", "-xzf", graalVm.get().downloadFile)
|
||||
args("--strip-components=1", "-xzf", downloadFile.get().asFile)
|
||||
}
|
||||
|
||||
val os = org.gradle.internal.os.OperatingSystem.current()
|
||||
@@ -59,8 +70,8 @@ constructor(
|
||||
|
||||
println("Installing native-image into $distroDir")
|
||||
val gvmVersionMajor =
|
||||
requireNotNull(graalVm.get().version.split(".").first().toIntOrNull()) {
|
||||
"Invalid GraalVM JDK version: ${graalVm.get().graalVmJdkVersion}"
|
||||
requireNotNull(version.get().split(".").first().toIntOrNull()) {
|
||||
"Invalid GraalVM JDK version: ${graalVmJdkVersion.get()}"
|
||||
}
|
||||
if (gvmVersionMajor < 24) {
|
||||
execOperations.exec {
|
||||
@@ -70,11 +81,11 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
println("Creating symlink ${graalVm.get().installDir} for $distroDir")
|
||||
val tempLink = Paths.get(graalVm.get().homeDir, UUID.randomUUID().toString())
|
||||
println("Creating symlink ${installDir.get().asFile} for $distroDir")
|
||||
val tempLink = Paths.get(homeDir.get(), UUID.randomUUID().toString())
|
||||
Files.createSymbolicLink(tempLink, distroDir)
|
||||
try {
|
||||
Files.move(tempLink, graalVm.get().installDir.toPath(), StandardCopyOption.ATOMIC_MOVE)
|
||||
Files.move(tempLink, installDir.get().asFile.toPath(), StandardCopyOption.ATOMIC_MOVE)
|
||||
} catch (e: Exception) {
|
||||
try {
|
||||
fileOperations.delete(tempLink.toFile())
|
||||
|
||||
@@ -16,18 +16,18 @@
|
||||
import javax.inject.Inject
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.ProjectLayout
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.services.BuildService
|
||||
import org.gradle.api.services.BuildServiceParameters
|
||||
import org.gradle.api.services.ServiceReference
|
||||
import org.gradle.api.tasks.ClasspathNormalizer
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.PathSensitivity
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.registerIfAbsent
|
||||
import org.gradle.kotlin.dsl.withNormalizer
|
||||
import org.gradle.process.ExecOperations
|
||||
|
||||
@@ -49,25 +49,31 @@ abstract class NativeImageBuild : DefaultTask() {
|
||||
|
||||
@get:InputFiles abstract val classpath: ConfigurableFileCollection
|
||||
|
||||
private val outputDir = project.layout.buildDirectory.dir("executable")
|
||||
/** Path to the `native-image` binary (e.g. `<graalVmBaseDir>/bin/native-image`). */
|
||||
@get:Input abstract val nativeImageExecutable: Property<String>
|
||||
|
||||
@get:OutputFile val outputFile = outputDir.flatMap { it.file(imageName) }
|
||||
@get:Input abstract val graalSdkLibraryName: Property<String>
|
||||
|
||||
@get:Input abstract val releaseBuild: Property<Boolean>
|
||||
|
||||
@get:Input abstract val nativeArch: Property<Boolean>
|
||||
|
||||
/** Divisor applied to `availableProcessors` to throttle native-image CPU usage. */
|
||||
@get:Input abstract val processorDivisor: Property<Int>
|
||||
|
||||
@get:Inject protected abstract val execOperations: ExecOperations
|
||||
|
||||
private val graalVm: Provider<BuildInfo.GraalVm> = arch.map { a ->
|
||||
when (a) {
|
||||
Architecture.AMD64 -> buildInfo.graalVmAmd64
|
||||
Architecture.AARCH64 -> buildInfo.graalVmAarch64
|
||||
}
|
||||
}
|
||||
@get:Inject protected abstract val layout: ProjectLayout
|
||||
|
||||
private val buildInfo: BuildInfo = project.extensions.getByType(BuildInfo::class.java)
|
||||
private val outputDir
|
||||
get() = layout.buildDirectory.dir("executable")
|
||||
|
||||
private val nativeImageCommandName =
|
||||
if (buildInfo.os.isWindows) "native-image.cmd" else "native-image"
|
||||
@get:OutputFile
|
||||
val outputFile
|
||||
get() = outputDir.flatMap { it.file(imageName) }
|
||||
|
||||
private val nativeImageExecutable = graalVm.map { "${it.baseDir}/bin/$nativeImageCommandName" }
|
||||
@get:ServiceReference("nativeImageBuildService")
|
||||
abstract val buildService: Property<NativeImageBuildService>
|
||||
|
||||
private val extraArgsFromProperties by lazy {
|
||||
System.getProperties()
|
||||
@@ -75,19 +81,7 @@ abstract class NativeImageBuild : DefaultTask() {
|
||||
.map { "${it.key}=${it.value}".substring("pkl.native".length) }
|
||||
}
|
||||
|
||||
private val buildService =
|
||||
project.gradle.sharedServices.registerIfAbsent(
|
||||
"nativeImageBuildService",
|
||||
NativeImageBuildService::class,
|
||||
) {
|
||||
maxParallelUsages.set(1)
|
||||
}
|
||||
|
||||
init {
|
||||
// ensure native-image builds run in serial (prevent `gw buildNative` from consuming all host
|
||||
// CPU resources).
|
||||
usesService(buildService)
|
||||
|
||||
group = "build"
|
||||
|
||||
inputs
|
||||
@@ -104,8 +98,7 @@ abstract class NativeImageBuild : DefaultTask() {
|
||||
@Suppress("unused")
|
||||
protected fun run() {
|
||||
execOperations.exec {
|
||||
val exclusions =
|
||||
listOf(buildInfo.libs.findLibrary("graalSdk").get()).map { it.get().module.name }
|
||||
val exclusions = listOf(graalSdkLibraryName.get())
|
||||
|
||||
executable = nativeImageExecutable.get()
|
||||
workingDir(outputDir)
|
||||
@@ -140,10 +133,10 @@ abstract class NativeImageBuild : DefaultTask() {
|
||||
add("-H:-ParseRuntimeOptions")
|
||||
// quick build mode: 40% faster compilation, 20% smaller (but presumably also slower)
|
||||
// executable
|
||||
if (!buildInfo.isReleaseBuild) {
|
||||
if (!releaseBuild.get()) {
|
||||
add("-Ob")
|
||||
}
|
||||
if (buildInfo.isNativeArch) {
|
||||
if (nativeArch.get()) {
|
||||
add("-march=native")
|
||||
} else {
|
||||
add("-march=compatibility")
|
||||
@@ -155,9 +148,7 @@ abstract class NativeImageBuild : DefaultTask() {
|
||||
}
|
||||
add(pathInput.asPath)
|
||||
// make sure dev machine stays responsive (15% slowdown on my laptop)
|
||||
val processors =
|
||||
Runtime.getRuntime().availableProcessors() /
|
||||
if (buildInfo.os.isMacOsX && !buildInfo.isCiBuild) 4 else 1
|
||||
val processors = Runtime.getRuntime().availableProcessors() / processorDivisor.get()
|
||||
add("-J-XX:ActiveProcessorCount=${processors}")
|
||||
// Pass through all `HOMEBREW_` prefixed environment variables to allow build with shimmed
|
||||
// tools.
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
*/
|
||||
import com.diffplug.spotless.FormatterFunc
|
||||
import com.diffplug.spotless.FormatterStep
|
||||
import java.io.File
|
||||
import java.io.Serial
|
||||
import java.io.Serializable
|
||||
import java.lang.reflect.Method
|
||||
import java.net.URLClassLoader
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
|
||||
@@ -26,31 +28,45 @@ class PklFormatterStep(@Transient private val configuration: Configuration) : Se
|
||||
}
|
||||
|
||||
fun create(): FormatterStep {
|
||||
val files = configuration.files.toList()
|
||||
return FormatterStep.createLazy(
|
||||
"pkl",
|
||||
{ PklFormatterStep(configuration) },
|
||||
{ PklFormatterFunc(configuration) },
|
||||
{ PklFormatterState(files) },
|
||||
{ PklFormatterFunc(it.files) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class PklFormatterFunc(@Transient private val configuration: Configuration) :
|
||||
FormatterFunc, Serializable {
|
||||
data class PklFormatterState(val files: List<File>) : Serializable {
|
||||
companion object {
|
||||
@Serial private const val serialVersionUID: Long = 1L
|
||||
}
|
||||
}
|
||||
|
||||
class PklFormatterFunc(private val files: List<File>) : FormatterFunc, Serializable {
|
||||
companion object {
|
||||
@Serial private const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
private val classLoader by lazy {
|
||||
val urls = configuration.files.map { it.toURI().toURL() }
|
||||
@delegate:Transient
|
||||
private val classLoader: URLClassLoader by lazy {
|
||||
val urls = files.map { it.toURI().toURL() }
|
||||
// Use the platform classloader as parent to isolate from Gradle's classloader
|
||||
URLClassLoader(urls.toTypedArray(), ClassLoader.getPlatformClassLoader())
|
||||
}
|
||||
|
||||
private val formatterClass by lazy { classLoader.loadClass("org.pkl.formatter.Formatter") }
|
||||
@delegate:Transient
|
||||
private val formatterClass: Class<*> by lazy {
|
||||
classLoader.loadClass("org.pkl.formatter.Formatter")
|
||||
}
|
||||
|
||||
private val formatMethod by lazy { formatterClass.getMethod("format", String::class.java) }
|
||||
@delegate:Transient
|
||||
private val formatMethod: Method by lazy {
|
||||
formatterClass.getMethod("format", String::class.java)
|
||||
}
|
||||
|
||||
private val formatterInstance by lazy { formatterClass.getConstructor().newInstance() }
|
||||
@delegate:Transient
|
||||
private val formatterInstance: Any by lazy { formatterClass.getConstructor().newInstance() }
|
||||
|
||||
override fun apply(input: String): String {
|
||||
return formatMethod(formatterInstance, input) as String
|
||||
|
||||
@@ -46,7 +46,7 @@ fun Project.configurePklPomMetadata() {
|
||||
connection.set("scm:git:git://github.com/apple/pkl.git")
|
||||
developerConnection.set("scm:git:ssh://github.com/apple/pkl.git")
|
||||
val buildInfo = extensions.getByType<BuildInfo>()
|
||||
url.set("https://github.com/apple/pkl/tree/${buildInfo.commitish}")
|
||||
url.set(buildInfo.commitish.map { "https://github.com/apple/pkl/tree/$it" })
|
||||
}
|
||||
issueManagement {
|
||||
system.set("GitHub Issues")
|
||||
|
||||
@@ -15,10 +15,12 @@
|
||||
*/
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.file.ArchiveOperations
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
import org.gradle.api.tasks.testing.Test
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import org.gradle.kotlin.dsl.support.serviceOf
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
@@ -150,17 +152,19 @@ tasks.check { dependsOn(testFatJar) }
|
||||
|
||||
val validateFatJar by tasks.registering {
|
||||
val outputFile = layout.buildDirectory.file("validateFatJar/result.txt")
|
||||
inputs.files(tasks.shadowJar)
|
||||
val shadowJarFile = tasks.shadowJar.flatMap { it.archiveFile }
|
||||
val archiveOps = serviceOf<ArchiveOperations>()
|
||||
inputs.file(shadowJarFile)
|
||||
inputs.property("nonRelocations", nonRelocations)
|
||||
outputs.file(outputFile)
|
||||
val nonRelocations = nonRelocations
|
||||
|
||||
doLast {
|
||||
val unshadowedFiles = mutableListOf<String>()
|
||||
zipTree(tasks.shadowJar.get().outputs.files.singleFile).visit {
|
||||
val fileDetails = this
|
||||
val path = fileDetails.relativePath.pathString
|
||||
archiveOps.zipTree(shadowJarFile.get().asFile).visit {
|
||||
val path = relativePath.pathString
|
||||
if (
|
||||
!(fileDetails.isDirectory ||
|
||||
!(isDirectory ||
|
||||
path.startsWith("org/pkl/") ||
|
||||
path.startsWith("META-INF/") ||
|
||||
nonRelocations.any { path.startsWith(it) })
|
||||
|
||||
@@ -28,11 +28,13 @@ val downloadGraalVmAmd64 by
|
||||
tasks.registering(Download::class) { configureDownloadGraalVm(buildInfo.graalVmAmd64) }
|
||||
|
||||
fun Download.configureDownloadGraalVm(graalvm: BuildInfo.GraalVm) {
|
||||
onlyIf { !graalvm.installDir.exists() }
|
||||
doLast { println("Downloaded GraalVm to ${graalvm.downloadFile}") }
|
||||
val installDir = graalvm.installDir
|
||||
val downloadFile = graalvm.downloadFile
|
||||
onlyIf { !installDir.exists() }
|
||||
doLast { println("Downloaded GraalVm to $downloadFile") }
|
||||
|
||||
src(graalvm.downloadUrl)
|
||||
dest(graalvm.downloadFile)
|
||||
dest(downloadFile)
|
||||
overwrite(false)
|
||||
tempAndMove(true)
|
||||
}
|
||||
@@ -50,7 +52,8 @@ val verifyGraalVmAmd64 by
|
||||
}
|
||||
|
||||
fun Verify.configureVerifyGraalVm(graalvm: BuildInfo.GraalVm) {
|
||||
onlyIf { !graalvm.installDir.exists() }
|
||||
val installDir = graalvm.installDir
|
||||
onlyIf { !installDir.exists() }
|
||||
|
||||
src(graalvm.downloadFile)
|
||||
checksum(
|
||||
@@ -59,16 +62,26 @@ fun Verify.configureVerifyGraalVm(graalvm: BuildInfo.GraalVm) {
|
||||
algorithm("SHA-256")
|
||||
}
|
||||
|
||||
// incorrect diagnostic
|
||||
@Suppress("UnusedReceiverParameter")
|
||||
fun InstallGraalVm.configureInstallGraalVm(graalVm: BuildInfo.GraalVm) {
|
||||
homeDir = graalVm.homeDir
|
||||
downloadFile = graalVm.downloadFile
|
||||
version = graalVm.version
|
||||
graalVmJdkVersion = graalVm.graalVmJdkVersion
|
||||
installDir = graalVm.installDir
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
val installGraalVmAarch64 by
|
||||
tasks.registering(InstallGraalVm::class) {
|
||||
dependsOn(verifyGraalVmAarch64)
|
||||
graalVm = buildInfo.graalVmAarch64
|
||||
configureInstallGraalVm(buildInfo.graalVmAarch64)
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
val installGraalVmAmd64 by
|
||||
tasks.registering(InstallGraalVm::class) {
|
||||
dependsOn(verifyGraalVmAmd64)
|
||||
graalVm = buildInfo.graalVmAmd64
|
||||
configureInstallGraalVm(buildInfo.graalVmAmd64)
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ val validateHtml by
|
||||
// write a basic result file s.t. gradle can consider task up-to-date
|
||||
// writing a result file in case validation fails is not easily possible with JavaExec, but also
|
||||
// not strictly necessary
|
||||
doFirst { project.delete(resultFile) }
|
||||
doFirst { resultFile.get().asFile.delete() }
|
||||
doLast { resultFile.get().asFile.writeText("Success.") }
|
||||
}
|
||||
|
||||
|
||||
@@ -47,8 +47,10 @@ fun Task.setupTestStartJavaExecutable(launcher: Provider<JavaLauncher>? = null)
|
||||
val outputFile = layout.buildDirectory.file("testStartJavaExecutable/$name")
|
||||
outputs.file(outputFile)
|
||||
|
||||
val executableFile = javaExecutable.flatMap { it.outJar }
|
||||
val pklVersion = buildInfo.pklVersionNonUnique
|
||||
val execOutput = providers.exec {
|
||||
val executablePath = javaExecutable.get().outputs.files.singleFile
|
||||
val executablePath = executableFile.get().asFile
|
||||
if (launcher?.isPresent == true) {
|
||||
commandLine(
|
||||
launcher.get().executablePath.asFile.absolutePath,
|
||||
@@ -63,9 +65,9 @@ fun Task.setupTestStartJavaExecutable(launcher: Provider<JavaLauncher>? = null)
|
||||
|
||||
doLast {
|
||||
val outputText = execOutput.standardOutput.asText.get()
|
||||
if (!outputText.contains(buildInfo.pklVersionNonUnique)) {
|
||||
if (!outputText.contains(pklVersion)) {
|
||||
throw GradleException(
|
||||
"Expected version output to contain current version (${buildInfo.pklVersionNonUnique}), but got '$outputText'"
|
||||
"Expected version output to contain current version ($pklVersion), but got '$outputText'"
|
||||
)
|
||||
}
|
||||
outputFile.get().asFile.toPath().apply {
|
||||
|
||||
@@ -67,13 +67,35 @@ dependencies {
|
||||
stagedWindowsAmd64Executable(executableFile("windows-amd64.exe"))
|
||||
}
|
||||
|
||||
val nativeImageBuildService =
|
||||
gradle.sharedServices.registerIfAbsent(
|
||||
"nativeImageBuildService",
|
||||
NativeImageBuildService::class,
|
||||
) {
|
||||
maxParallelUsages = 1
|
||||
}
|
||||
|
||||
private val nativeImageCommandName =
|
||||
if (buildInfo.os.isWindows) "native-image.cmd" else "native-image"
|
||||
|
||||
private fun NativeImageBuild.configure() {
|
||||
graalSdkLibraryName = buildInfo.libs.findLibrary("graalSdk").get().map { it.module.name }
|
||||
releaseBuild = buildInfo.isReleaseBuild
|
||||
nativeArch = buildInfo.isNativeArch
|
||||
processorDivisor = if (buildInfo.os.isMacOsX && !buildInfo.isCiBuild) 4 else 1
|
||||
buildService = nativeImageBuildService
|
||||
usesService(nativeImageBuildService)
|
||||
}
|
||||
|
||||
private fun NativeImageBuild.amd64() {
|
||||
arch = Architecture.AMD64
|
||||
nativeImageExecutable = "${buildInfo.graalVmAmd64.baseDir}/bin/$nativeImageCommandName"
|
||||
dependsOn(":installGraalVmAmd64")
|
||||
}
|
||||
|
||||
private fun NativeImageBuild.aarch64() {
|
||||
arch = Architecture.AARCH64
|
||||
nativeImageExecutable = "${buildInfo.graalVmAarch64.baseDir}/bin/$nativeImageCommandName"
|
||||
dependsOn(":installGraalVmAarch64")
|
||||
}
|
||||
|
||||
@@ -91,6 +113,7 @@ val macExecutableAmd64 by
|
||||
mainClass = executableSpec.mainClass
|
||||
amd64()
|
||||
setClasspath()
|
||||
configure()
|
||||
}
|
||||
|
||||
val macExecutableAarch64 by
|
||||
@@ -99,6 +122,7 @@ val macExecutableAarch64 by
|
||||
mainClass = executableSpec.mainClass
|
||||
aarch64()
|
||||
setClasspath()
|
||||
configure()
|
||||
}
|
||||
|
||||
val linuxExecutableAmd64 by
|
||||
@@ -107,6 +131,7 @@ val linuxExecutableAmd64 by
|
||||
mainClass = executableSpec.mainClass
|
||||
amd64()
|
||||
setClasspath()
|
||||
configure()
|
||||
}
|
||||
|
||||
val linuxExecutableAarch64 by
|
||||
@@ -115,6 +140,7 @@ val linuxExecutableAarch64 by
|
||||
mainClass = executableSpec.mainClass
|
||||
aarch64()
|
||||
setClasspath()
|
||||
configure()
|
||||
// Ensure compatibility for kernels with page size set to 4k, 16k and 64k
|
||||
// (e.g. Raspberry Pi 5, Asahi Linux)
|
||||
extraNativeImageArgs.add("-H:PageSize=65536")
|
||||
@@ -126,6 +152,7 @@ val alpineExecutableAmd64 by
|
||||
mainClass = executableSpec.mainClass
|
||||
amd64()
|
||||
setClasspath()
|
||||
configure()
|
||||
extraNativeImageArgs.addAll(listOf("--static", "--libc=musl"))
|
||||
}
|
||||
|
||||
@@ -135,6 +162,7 @@ val windowsExecutableAmd64 by
|
||||
mainClass = executableSpec.mainClass
|
||||
amd64()
|
||||
setClasspath()
|
||||
configure()
|
||||
}
|
||||
|
||||
val assembleNative by tasks.existing
|
||||
@@ -143,18 +171,18 @@ val testStartNativeExecutable by tasks.registering {
|
||||
dependsOn(assembleNative)
|
||||
|
||||
// dummy file for up-to-date checking
|
||||
val outputFile = project.layout.buildDirectory.file("testStartNativeExecutable/output.txt")
|
||||
val outputFile = layout.buildDirectory.file("testStartNativeExecutable/output.txt")
|
||||
outputs.file(outputFile)
|
||||
|
||||
val execOutput = providers.exec {
|
||||
commandLine(assembleNative.get().outputs.files.singleFile, "--version")
|
||||
}
|
||||
val nativeExecutableFile = assembleNative.map { it.outputs.files.singleFile }
|
||||
val execOutput = providers.exec { commandLine(nativeExecutableFile.get(), "--version") }
|
||||
val pklVersion = buildInfo.pklVersionNonUnique
|
||||
|
||||
doLast {
|
||||
val outputText = execOutput.standardOutput.asText.get()
|
||||
if (!outputText.contains(buildInfo.pklVersionNonUnique)) {
|
||||
if (!outputText.contains(pklVersion)) {
|
||||
throw GradleException(
|
||||
"Expected version output to contain current version (${buildInfo.pklVersionNonUnique}), but got '$outputText'"
|
||||
"Expected version output to contain current version ($pklVersion), but got '$outputText'"
|
||||
)
|
||||
}
|
||||
outputFile.get().asFile.toPath().apply {
|
||||
@@ -171,10 +199,10 @@ val requiredGlibcVersion: Version = Version.parse("2.17")
|
||||
val checkGlibc by tasks.registering {
|
||||
enabled = buildInfo.os.isLinux && !buildInfo.musl
|
||||
dependsOn(assembleNative)
|
||||
val nativeExecutableFile = assembleNative.map { it.outputs.files.singleFile }
|
||||
val requiredGlibcVersion = requiredGlibcVersion
|
||||
val exec = providers.exec { commandLine("objdump", "-T", nativeExecutableFile.get()) }
|
||||
doLast {
|
||||
val exec = providers.exec {
|
||||
commandLine("objdump", "-T", assembleNative.get().outputs.files.singleFile)
|
||||
}
|
||||
val output = exec.standardOutput.asText.get()
|
||||
val minimumGlibcVersion =
|
||||
output
|
||||
|
||||
Reference in New Issue
Block a user