1616import javax.inject.Inject
1717import org.gradle.api.DefaultTask
1818import org.gradle.api.file.ConfigurableFileCollection
19+ import org.gradle.api.file.ProjectLayout
1920import org.gradle.api.provider.ListProperty
2021import org.gradle.api.provider.Property
21- import org.gradle.api.provider.Provider
2222import org.gradle.api.services.BuildService
2323import org.gradle.api.services.BuildServiceParameters
24+ import org.gradle.api.services.ServiceReference
2425import org.gradle.api.tasks.ClasspathNormalizer
2526import org.gradle.api.tasks.Input
2627import org.gradle.api.tasks.InputFiles
2728import org.gradle.api.tasks.OutputFile
2829import org.gradle.api.tasks.PathSensitivity
2930import org.gradle.api.tasks.TaskAction
30- import org.gradle.kotlin.dsl.registerIfAbsent
3131import org.gradle.kotlin.dsl.withNormalizer
3232import org.gradle.process.ExecOperations
3333
@@ -49,45 +49,39 @@ abstract class NativeImageBuild : DefaultTask() {
4949
5050 @get:InputFiles abstract val classpath: ConfigurableFileCollection
5151
52- private val outputDir = project.layout.buildDirectory.dir(" executable" )
52+ /* * Path to the `native-image` binary (e.g. `<graalVmBaseDir>/bin/native-image`). */
53+ @get:Input abstract val nativeImageExecutable: Property <String >
5354
54- @get:OutputFile val outputFile = outputDir.flatMap { it.file(imageName) }
55+ @get:Input abstract val graalSdkLibraryName: Property <String >
56+
57+ @get:Input abstract val releaseBuild: Property <Boolean >
58+
59+ @get:Input abstract val nativeArch: Property <Boolean >
60+
61+ /* * Divisor applied to `availableProcessors` to throttle native-image CPU usage. */
62+ @get:Input abstract val processorDivisor: Property <Int >
5563
5664 @get:Inject protected abstract val execOperations: ExecOperations
5765
58- private val graalVm: Provider <BuildInfo .GraalVm > = arch.map { a ->
59- when (a) {
60- Architecture .AMD64 -> buildInfo.graalVmAmd64
61- Architecture .AARCH64 -> buildInfo.graalVmAarch64
62- }
63- }
66+ @get:Inject protected abstract val layout: ProjectLayout
6467
65- private val buildInfo: BuildInfo = project.extensions.getByType(BuildInfo ::class .java)
68+ private val outputDir
69+ get() = layout.buildDirectory.dir(" executable" )
6670
67- private val nativeImageCommandName =
68- if (buildInfo.os.isWindows) " native-image.cmd" else " native-image"
71+ @get:OutputFile
72+ val outputFile
73+ get() = outputDir.flatMap { it.file(imageName) }
6974
70- private val nativeImageExecutable = graalVm.map { " ${it.baseDir} /bin/$nativeImageCommandName " }
75+ @get:ServiceReference(" nativeImageBuildService" )
76+ abstract val buildService: Property <NativeImageBuildService >
7177
7278 private val extraArgsFromProperties by lazy {
7379 System .getProperties()
7480 .filter { it.key.toString().startsWith(" pkl.native" ) }
7581 .map { " ${it.key} =${it.value} " .substring(" pkl.native" .length) }
7682 }
7783
78- private val buildService =
79- project.gradle.sharedServices.registerIfAbsent(
80- " nativeImageBuildService" ,
81- NativeImageBuildService ::class ,
82- ) {
83- maxParallelUsages.set(1 )
84- }
85-
8684 init {
87- // ensure native-image builds run in serial (prevent `gw buildNative` from consuming all host
88- // CPU resources).
89- usesService(buildService)
90-
9185 group = " build"
9286
9387 inputs
@@ -104,8 +98,7 @@ abstract class NativeImageBuild : DefaultTask() {
10498 @Suppress(" unused" )
10599 protected fun run () {
106100 execOperations.exec {
107- val exclusions =
108- listOf (buildInfo.libs.findLibrary(" graalSdk" ).get()).map { it.get().module.name }
101+ val exclusions = listOf (graalSdkLibraryName.get())
109102
110103 executable = nativeImageExecutable.get()
111104 workingDir(outputDir)
@@ -140,10 +133,10 @@ abstract class NativeImageBuild : DefaultTask() {
140133 add(" -H:-ParseRuntimeOptions" )
141134 // quick build mode: 40% faster compilation, 20% smaller (but presumably also slower)
142135 // executable
143- if (! buildInfo.isReleaseBuild ) {
136+ if (! releaseBuild.get() ) {
144137 add(" -Ob" )
145138 }
146- if (buildInfo.isNativeArch ) {
139+ if (nativeArch.get() ) {
147140 add(" -march=native" )
148141 } else {
149142 add(" -march=compatibility" )
@@ -155,9 +148,7 @@ abstract class NativeImageBuild : DefaultTask() {
155148 }
156149 add(pathInput.asPath)
157150 // make sure dev machine stays responsive (15% slowdown on my laptop)
158- val processors =
159- Runtime .getRuntime().availableProcessors() /
160- if (buildInfo.os.isMacOsX && ! buildInfo.isCiBuild) 4 else 1
151+ val processors = Runtime .getRuntime().availableProcessors() / processorDivisor.get()
161152 add(" -J-XX:ActiveProcessorCount=${processors} " )
162153 // Pass through all `HOMEBREW_` prefixed environment variables to allow build with shimmed
163154 // tools.
0 commit comments