added documentation of NativeImage plugin
This commit is contained in:
132
graalvm/REAMDE.md
Normal file
132
graalvm/REAMDE.md
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
## Overview
|
||||||
|
This project contains 2 Gradle plugin:
|
||||||
|
- NativeImage allows you to create a native executable file from a Gradle project using GraalVM's `native-image` tool
|
||||||
|
- Jlink allows you to create a native distribution of a Gradle project using GraalVM `jlink` tool
|
||||||
|
|
||||||
|
### Native Image plugin
|
||||||
|
|
||||||
|
Declare the plugin in your build's `settings.gradle` like this
|
||||||
|
```groovy
|
||||||
|
|
||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url = 'https://woggioni.net/mvn/'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id "net.woggioni.gradle.graalvm.native-image" version "2023.10.23"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then add it to a project's `build.gradle`
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
plugins {
|
||||||
|
id 'net.woggioni.gradle.graalvm.native-image'
|
||||||
|
}
|
||||||
|
|
||||||
|
configureNativeImage {
|
||||||
|
args = [ 'your', 'command', 'line', 'arguments']
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainClass = 'your.main.Class'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Mind that if your project also uses the built-in Gradle `application` plugin, that must be applied before the `net.woggioni.gradle.graalvm.native-image`.
|
||||||
|
|
||||||
|
The plugin adds 2 tasks to your project:
|
||||||
|
|
||||||
|
- `configureNativeImage` of type `net.woggioni.gradle.graalvm.NativeImageConfigurationTask` which launches
|
||||||
|
your application with the [native-image-agent](https://www.graalvm.org/latest/reference-manual/native-image/metadata/AutomaticMetadataCollection/)
|
||||||
|
to generate the native image configuration files in `${project.projectDir}/native-image`
|
||||||
|
- `nativeImage` of type `net.woggioni.gradle.graalvm.NativeImageTask` that creates the native executable the project's
|
||||||
|
libraries folder (`${project.buildDir}/libs`)
|
||||||
|
|
||||||
|
#### Configuration for `NativeImageConfigurationTask`
|
||||||
|
|
||||||
|
###### mergeConfiguration
|
||||||
|
|
||||||
|
This boolean property decides whether to create a new set of configuration files or simply append to the existing ones
|
||||||
|
|
||||||
|
#### Configuration for `NativeImageTask`
|
||||||
|
|
||||||
|
###### mainClass
|
||||||
|
|
||||||
|
The name of the main class the native executable will launch, defaults to the value set in
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
application {
|
||||||
|
mainClass = 'my.main.class'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
###### mainModule
|
||||||
|
|
||||||
|
The name of the main JPMS module the native executable will launch, defaults to the value set in
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
application {
|
||||||
|
mainModule = 'my.main.module'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Only applicable when `useJpms` is true
|
||||||
|
|
||||||
|
###### useJpms
|
||||||
|
|
||||||
|
Whether or not enable JPMS in the generated executable
|
||||||
|
(dependencies that support JPMS will be forwarded to `native-image` using the `-p` instead of the `-cp` option)
|
||||||
|
|
||||||
|
###### useMusl
|
||||||
|
|
||||||
|
This boolean property allows to link the generated executable to musl libc,
|
||||||
|
note that in order to do that a valid (linked to musl-libc) compiler toolchain must be available
|
||||||
|
on the `PATH`, for example if building x86_64 executables on Linux, GraalVM will look for
|
||||||
|
`x86_64-linux-musl-gcc`
|
||||||
|
|
||||||
|
###### buildStaticImage
|
||||||
|
|
||||||
|
This boolean property allows to create a statically linked executable for maximum portability
|
||||||
|
(a static executable only depends on the kernel and can be moved freely to
|
||||||
|
another different machine with the same operating system and CPU architecture).
|
||||||
|
Beware that this requires the libc to support static linking
|
||||||
|
(most notably, the glibc does not support static linking, the only way to build static executables
|
||||||
|
on linux is to link to a different libc implementation like musl libc).
|
||||||
|
|
||||||
|
###### enableFallback
|
||||||
|
|
||||||
|
Whether or not to allow the creation of the [fallback image](https://www.graalvm.org/22.0/reference-manual/native-image/Limitations/)
|
||||||
|
when native-image configuration is missing.
|
||||||
|
|
||||||
|
###### graalVmHome
|
||||||
|
|
||||||
|
This points to the installation folder of GraalVM, defaults to the installation directory
|
||||||
|
of the selected Gradle toolchain (if any) or the installation directory
|
||||||
|
of the JVM Gradle is running on otherwise.
|
||||||
|
|
||||||
|
#### Customize native-image command line
|
||||||
|
A [native-image.properties](https://www.graalvm.org/22.0/reference-manual/native-image/BuildConfiguration/)
|
||||||
|
file can be added to `${project.projectDir}/native-image` to add custom parameters:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
-H:Optimize=3 --initialize-at-run-time=your.main.class --gc=G1
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Limitations
|
||||||
|
|
||||||
|
GraalVM with the [native-image](https://www.graalvm.org/22.0/reference-manual/native-image/) plugin is required in order
|
||||||
|
for these plugins to work, this can be achieved either running Gradle under GraalVM directly or using Gradle toolchains
|
||||||
|
support to request GraalVM at the project level
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
java {
|
||||||
|
toolchain {
|
||||||
|
languageVersion = JavaLanguageVersion.of(17)
|
||||||
|
vendor = JvmVendorSpec.GRAAL_VM
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
@@ -10,12 +10,14 @@ import org.gradle.api.plugins.JavaPlugin;
|
|||||||
import org.gradle.api.plugins.JavaPluginExtension;
|
import org.gradle.api.plugins.JavaPluginExtension;
|
||||||
import org.gradle.api.provider.Property;
|
import org.gradle.api.provider.Property;
|
||||||
import org.gradle.api.provider.Provider;
|
import org.gradle.api.provider.Provider;
|
||||||
|
import org.gradle.api.tasks.Input;
|
||||||
import org.gradle.api.tasks.JavaExec;
|
import org.gradle.api.tasks.JavaExec;
|
||||||
import org.gradle.api.tasks.OutputDirectory;
|
import org.gradle.api.tasks.OutputDirectory;
|
||||||
import org.gradle.api.tasks.TaskContainer;
|
import org.gradle.api.tasks.TaskContainer;
|
||||||
import org.gradle.api.tasks.bundling.Jar;
|
import org.gradle.api.tasks.bundling.Jar;
|
||||||
import org.gradle.jvm.toolchain.JavaLauncher;
|
import org.gradle.jvm.toolchain.JavaLauncher;
|
||||||
import org.gradle.jvm.toolchain.JavaToolchainService;
|
import org.gradle.jvm.toolchain.JavaToolchainService;
|
||||||
|
import org.gradle.process.CommandLineArgumentProvider;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -27,6 +29,8 @@ import static net.woggioni.gradle.graalvm.Constants.GRAALVM_TASK_GROUP;
|
|||||||
import static net.woggioni.gradle.graalvm.NativeImagePlugin.NATIVE_IMAGE_CONFIGURATION_FOLDER_NAME;
|
import static net.woggioni.gradle.graalvm.NativeImagePlugin.NATIVE_IMAGE_CONFIGURATION_FOLDER_NAME;
|
||||||
|
|
||||||
public abstract class NativeImageConfigurationTask extends JavaExec {
|
public abstract class NativeImageConfigurationTask extends JavaExec {
|
||||||
|
@Input
|
||||||
|
public abstract Property<Boolean> getMergeConfiguration();
|
||||||
|
|
||||||
@OutputDirectory
|
@OutputDirectory
|
||||||
public abstract DirectoryProperty getConfigurationDir();
|
public abstract DirectoryProperty getConfigurationDir();
|
||||||
@@ -50,6 +54,7 @@ public abstract class NativeImageConfigurationTask extends JavaExec {
|
|||||||
}
|
}
|
||||||
getConfigurationDir().convention(layout.getProjectDirectory()
|
getConfigurationDir().convention(layout.getProjectDirectory()
|
||||||
.dir(NATIVE_IMAGE_CONFIGURATION_FOLDER_NAME));
|
.dir(NATIVE_IMAGE_CONFIGURATION_FOLDER_NAME));
|
||||||
|
getMergeConfiguration().convention(true);
|
||||||
ConfigurationContainer cc = getProject().getConfigurations();
|
ConfigurationContainer cc = getProject().getConfigurations();
|
||||||
Configuration runtimeClasspath = cc.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME);
|
Configuration runtimeClasspath = cc.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME);
|
||||||
setClasspath(runtimeClasspath);
|
setClasspath(runtimeClasspath);
|
||||||
@@ -60,11 +65,20 @@ public abstract class NativeImageConfigurationTask extends JavaExec {
|
|||||||
runtimeClasspath
|
runtimeClasspath
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
List<String> jvmArgs = new ArrayList<>();
|
getJvmArgumentProviders().add(new CommandLineArgumentProvider() {
|
||||||
jvmArgs.add("-agentlib:native-image-agent=config-output-dir=" + getConfigurationDir().get());
|
@Override
|
||||||
for(String jvmArg : Optional.ofNullable(javaApplication.getApplicationDefaultJvmArgs()).orElse(Collections.emptyList())) {
|
public Iterable<String> asArguments() {
|
||||||
jvmArgs.add(jvmArg);
|
List<String> jvmArgs = new ArrayList<>();
|
||||||
}
|
if(getMergeConfiguration().get()) {
|
||||||
jvmArgs(jvmArgs);
|
jvmArgs.add("-agentlib:native-image-agent=config-merge-dir=" + getConfigurationDir().get());
|
||||||
|
} else {
|
||||||
|
jvmArgs.add("-agentlib:native-image-agent=config-output-dir=" + getConfigurationDir().get());
|
||||||
|
}
|
||||||
|
for(String jvmArg : Optional.ofNullable(javaApplication.getApplicationDefaultJvmArgs()).orElse(Collections.emptyList())) {
|
||||||
|
jvmArgs.add(jvmArg);
|
||||||
|
}
|
||||||
|
return jvmArgs;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -87,7 +87,7 @@ public abstract class NativeImageTask extends Exec {
|
|||||||
javaToolchainService.launcherFor(javaToolchainSpec)
|
javaToolchainService.launcherFor(javaToolchainSpec)
|
||||||
).map(javaLauncher ->
|
).map(javaLauncher ->
|
||||||
javaLauncher.map(JavaLauncher::getMetadata).map(JavaInstallationMetadata::getInstallationPath)
|
javaLauncher.map(JavaLauncher::getMetadata).map(JavaInstallationMetadata::getInstallationPath)
|
||||||
).orElseGet(() -> layout.dir(project.provider(() ->project.file(System.getProperty("java.home")))));
|
).orElseGet(() -> layout.dir(project.provider(() -> project.file(System.getProperty("java.home")))));
|
||||||
getGraalVmHome().convention(graalHomeDirectoryProvider);
|
getGraalVmHome().convention(graalHomeDirectoryProvider);
|
||||||
|
|
||||||
BasePluginExtension basePluginExtension =
|
BasePluginExtension basePluginExtension =
|
||||||
|
@@ -2,7 +2,7 @@ woggioniMavenRepositoryUrl=https://mvn.woggioni.net/
|
|||||||
|
|
||||||
lys.catalog.version=2023.10.01
|
lys.catalog.version=2023.10.01
|
||||||
|
|
||||||
version.myGradlePlugins=2023.10.20
|
version.myGradlePlugins=2023.10.23
|
||||||
version.gradle=7.6
|
version.gradle=7.6
|
||||||
version.felix.config.admin=1.9.26
|
version.felix.config.admin=1.9.26
|
||||||
version.felix=7.0.5
|
version.felix=7.0.5
|
||||||
|
Reference in New Issue
Block a user