diff --git a/docs/src/docs/asciidoc/gradle-plugin.adoc b/docs/src/docs/asciidoc/gradle-plugin.adoc index 35878df90..7a3d615a4 100644 --- a/docs/src/docs/asciidoc/gradle-plugin.adoc +++ b/docs/src/docs/asciidoc/gradle-plugin.adoc @@ -90,8 +90,9 @@ Follow the <> to install it properly Eventually, you also have the options to: -1. Run Gradle itself with a GraalVM SDK -2. Setup a `GRAALVM_HOME` environment variable pointing to your GraalVM installation +1. <> +2. Run Gradle itself with a GraalVM SDK +3. Setup a `GRAALVM_HOME` environment variable pointing to your GraalVM installation Note that none of those options are recommended as they are more fragile. @@ -119,7 +120,7 @@ The link:javadocs/native-gradle-plugin/org/graalvm/buildtools/gradle/dsl/NativeI ==== Selecting the GraalVM toolchain By default, the plugin will select a Java 11 GraalVM toolchain. -If you want to use a different toolchain, for example a GraalVM Enterprise Edition for Java 8, you can configure the toolchain like this: +If you want to use a different toolchain, for example a GraalVM Community Edition for Java 8, you can configure the toolchain like this: .Selecting the GraalVM toolchain [role="multi-language-sample"] @@ -132,6 +133,29 @@ include::../snippets/gradle/groovy/build.gradle[tags=select-toolchain] include::../snippets/gradle/kotlin/build.gradle.kts[tags=select-toolchain] ``` +[[disabling-toolchains]] +==== Disabling toolchain detection + +Because of limitations in Gradle, the plugin may not be able to properly detect the toolchain. +This is the case if, for example, you want to use GraalVM Enterprise or that you want to be able to select a particular version of GraalVM. + +To workaround this problem, you can disable toolchain detection: + +.Disabling toolchain detection +[role="multi-language-sample"] +```groovy +include::../snippets/gradle/groovy/build.gradle[tags=disabling-toolchain, indent=0] +``` + +[role="multi-language-sample"] +```kotlin +include::../snippets/gradle/kotlin/build.gradle.kts[tags=disabling-toolchain, indent=0] +``` + +If you do this, the plugin will search for 2 environment variables: `GRAALVM_HOME` and `JAVA_HOME` _in that order_. +If one of them is set, it will assume that it points to a valid GraalVM installation and completely bypass toolchain selection. +Therefore, it becomes your responsibility to make sure that the JDK pointing at this environment variable matches your build script requirements (in particular, the language version). + ==== Configuration options The following configuration options are available for building images: @@ -139,12 +163,12 @@ The following configuration options are available for building images: .NativeImageOption configuration [role="multi-language-sample"] ```groovy -include::../snippets/gradle/groovy/build.gradle[tags=all-plugin-options] +include::../snippets/gradle/groovy/build.gradle[tags=all-config-options] ``` [role="multi-language-sample"] ```kotlin -include::../snippets/gradle/kotlin/build.gradle.kts[tags=all-plugin-options] +include::../snippets/gradle/kotlin/build.gradle.kts[tags=all-config-options] ``` NOTE: For options that can be set using command-line, if both DSL and command-line options are present, command-line options take precedence. diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 2dcc52e26..b04e2b0b9 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -15,6 +15,17 @@ If you are interested in contributing, please refer to our https://github.com/gr [[changelog]] == Changelog +=== Release 0.9.8 + +==== Gradle plugin + +* Add an option to disable toolchain support altogether, which can be useful to use GraalVM Enterprise Edition, for example. +* Fixed a bug when using a _fat jar_ which assumed that all entries to be repackaged were jars. + +==== JUnit Platform Native + +* Fixed builds failing when tests were aborted + === Release 0.9.7.1 ==== Bugfixes diff --git a/docs/src/docs/snippets/gradle/groovy/build.gradle b/docs/src/docs/snippets/gradle/groovy/build.gradle index e4c29c3ea..3ee5a950c 100644 --- a/docs/src/docs/snippets/gradle/groovy/build.gradle +++ b/docs/src/docs/snippets/gradle/groovy/build.gradle @@ -50,14 +50,22 @@ graalvmNative { main { javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(8) - vendor = JvmVendorSpec.matching("GraalVM Enterprise") + vendor = JvmVendorSpec.matching("GraalVM Community") } } } } -// end:select-toolchain[] +// end::select-toolchain[] -// tag:all-config-options[] +if (providers.environmentVariable("DISABLE_TOOLCHAIN").isPresent()) { +// tag::disabling-toolchain[] + tasks.withType(org.graalvm.buildtools.gradle.tasks.BuildNativeImageTask).configureEach { + disableToolchainDetection = true + } +// end::disabling-toolchain[] +} + +// tag::all-config-options[] graalvmNative { binaries { main { diff --git a/docs/src/docs/snippets/gradle/kotlin/build.gradle.kts b/docs/src/docs/snippets/gradle/kotlin/build.gradle.kts index fe07854c1..fe3255569 100644 --- a/docs/src/docs/snippets/gradle/kotlin/build.gradle.kts +++ b/docs/src/docs/snippets/gradle/kotlin/build.gradle.kts @@ -51,13 +51,21 @@ graalvmNative { named("main") { javaLauncher.set(javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(8)) - vendor.set(JvmVendorSpec.matching("GraalVM Enterprise")) + vendor.set(JvmVendorSpec.matching("GraalVM Community")) }) } } } // end::select-toolchain[] +if (providers.environmentVariable("DISABLE_TOOLCHAIN").isPresent()) { +// tag::disabling-toolchain[] + tasks.withType().configureEach { + disableToolchainDetection.set(true) + } +// end::disabling-toolchain[] +} + // tag::all-config-options[] graalvmNative { binaries { diff --git a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationFunctionalTest.groovy b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationFunctionalTest.groovy index 2027c6d9f..b8dc041ca 100644 --- a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationFunctionalTest.groovy +++ b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationFunctionalTest.groovy @@ -42,13 +42,15 @@ package org.graalvm.buildtools.gradle import org.graalvm.buildtools.gradle.fixtures.AbstractFunctionalTest +import org.gradle.util.GradleVersion import spock.lang.Issue +import spock.lang.Requires class JavaApplicationFunctionalTest extends AbstractFunctionalTest { def "can build a native image for a simple application"() { gradleVersion = version def nativeApp = file("build/native/nativeCompile/java-application") - debug = true + debug = true given: withSample("java-application") @@ -113,4 +115,53 @@ class JavaApplicationFunctionalTest extends AbstractFunctionalTest { where: version << TESTED_GRADLE_VERSIONS } + + @Requires({ + def graalvmHome = System.getenv("GRAALVM_HOME") + graalvmHome != null + }) + def "can override toolchain selection"() { + gradleVersion = version + def nativeApp = file("build/native/nativeCompile/java-application") + boolean dummyToolchain = GradleVersion.version(gradleVersion).compareTo(GradleVersion.version("7.0")) >= 0 + + given: + withSample("java-application") + + if (dummyToolchain) { + buildFile << """graalvmNative.binaries.configureEach { + javaLauncher.set(javaToolchains.launcherFor { + vendor.set(JvmVendorSpec.matching("non existing vendor")) + }) + }""" + } + + buildFile << """ + tasks.withType(org.graalvm.buildtools.gradle.tasks.BuildNativeImageTask).configureEach { + disableToolchainDetection = true + } + """.stripIndent() + + when: + run 'nativeCompile', '-i' + + then: + tasks { + succeeded ':jar', ':nativeCompile' + doesNotContain ':build', ':run' + } + + and: + nativeApp.exists() + + when: + def process = execute(nativeApp) + + then: + process.output.contains "Hello, native!" + + where: + version << TESTED_GRADLE_VERSIONS + } + } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeImageOptions.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeImageOptions.java index 4c844b203..2b7b41075 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeImageOptions.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeImageOptions.java @@ -174,6 +174,7 @@ public interface NativeImageOptions extends Named { * to a Java launcher due to Gradle limitations. */ @Nested + @Optional Property getJavaLauncher(); /** diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/BuildNativeImageTask.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/BuildNativeImageTask.java index 7491f21ee..4ff6cebdf 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/BuildNativeImageTask.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/BuildNativeImageTask.java @@ -111,6 +111,9 @@ public Provider getOutputFile() { @Input public abstract Property getAgentEnabled(); + @Input + public abstract Property getDisableToolchainDetection(); + @Inject protected abstract ProviderFactory getProviders(); @@ -125,7 +128,11 @@ public BuildNativeImageTask() { setDescription("Builds a native image."); setGroup(JavaBasePlugin.VERIFICATION_GROUP); getOutputDirectory().convention(outputDir); - this.graalvmHomeProvider = getProject().getProviders().environmentVariable("GRAALVM_HOME"); + ProviderFactory providers = getProject().getProviders(); + this.graalvmHomeProvider = providers.environmentVariable("GRAALVM_HOME") + .forUseAtConfigurationTime() + .orElse(providers.environmentVariable("JAVA_HOME").forUseAtConfigurationTime()); + getDisableToolchainDetection().convention(false); } private List buildActualCommandLineArgs() { @@ -155,10 +162,20 @@ public void exec() { if (options.getVerbose().get()) { logger.lifecycle("Args are: " + args); } - JavaInstallationMetadata metadata = options.getJavaLauncher().get().getMetadata(); - File executablePath = metadata.getInstallationPath().file("bin/" + NATIVE_IMAGE_EXE).getAsFile(); - if (!executablePath.exists() && getGraalVMHome().isPresent()) { - executablePath = Paths.get(getGraalVMHome().get()).resolve("bin").resolve(NATIVE_IMAGE_EXE).toFile(); + File executablePath = null; + if (getDisableToolchainDetection().get()) { + if (getGraalVMHome().isPresent()) { + String graalvmHome = getGraalVMHome().get(); + getLogger().lifecycle("Toolchain detection is disabled, will use GraalVM from {}.", graalvmHome); + executablePath = Paths.get(graalvmHome).resolve("bin/" + NATIVE_IMAGE_EXE).toFile(); + } + } + if (executablePath == null) { + JavaInstallationMetadata metadata = options.getJavaLauncher().get().getMetadata(); + executablePath = metadata.getInstallationPath().file("bin/" + NATIVE_IMAGE_EXE).getAsFile(); + if (!executablePath.exists() && getGraalVMHome().isPresent()) { + executablePath = Paths.get(getGraalVMHome().get()).resolve("bin").resolve(NATIVE_IMAGE_EXE).toFile(); + } } try {