FS-native-tasks: Gradle native-image tasks build and run Native Image outputs
August 10, 2026 · View on GitHub
Native image tasks are the user-facing Gradle commands for building, running, and experimenting with native executables. They adapt §root/FS-native-builds to Gradle task inputs and outputs.
1. Compile tasks
nativeCompile builds the main binary. It consumes the binary classpath, main class or
shared-library setting, build arguments, configuration directories, generated resources,
reachability metadata, optional classpath JAR, argument-file setting, layer and PGO options,
environment variables, system properties, and JVM arguments.
nativeTestCompile builds the native test binary described by §root/FS-native-tests.
It uses compiled test classes, test resources, the test runtime classpath, JUnit native support,
selected test identifiers, and the test binary options.
Every custom binary must receive a derived native<Binary>Compile task. All compile tasks must
declare Gradle inputs and outputs for the selected options and generated files, including the
binary's classpath and reachability-metadata exclusions, so Gradle can skip, cache, or rerun them
consistently.
Every named layer receives a derived native<Layer>Layer task with an output under
build/native/layers/<layer>/<layer>.nil. Its inputs are the explicit selection and, only when
packages require it, the configured application classpath. Consuming compile and run tasks are
wired to that output through providers. The layer task creates and executes from its declared
output directory before invoking Native Image. It uses the logical layer name for the .nil
bundle and the platform's native shared-library naming derived from lib<layer> for the companion
library consumed by later image builds.
2. Run tasks
nativeRun executes the output of nativeCompile for the main binary and passes runtime
arguments from the binary configuration. When layered Native Image output is used, it sets up layer
library paths lazily from the produced layer files while remaining compatible with Gradle's
configuration cache. Custom runnable binaries receive derived run tasks that execute their own
compile-task output.
nativeTest executes the output of nativeTestCompile unless native test execution is skipped.
A failing native test executable must fail the Gradle build.
3. Deprecated task aliases
The plugin must keep compatibility aliases for deprecated task names where they still exist. An alias should depend on the replacement task and warn users to use the current name, protecting §REQ-task-surface.
4. Command-line overrides
Compile tasks must expose task options for image name, main class, debug, verbose, fallback, quick build, rich output, PGO instrumentation, build args, forced build args, fat JAR mode, system properties, environment variables, JVM args, and forced JVM args. These one-off overrides feed the same option objects as the DSL, keeping command-line experimentation aligned with §root/FS-option-precedence.
The fallback option is deprecated because Native Image removed fallback support in GraalVM 25.1.
It remains available for compatibility: disabling fallback produces --no-fallback before 25.1
and when the GraalVM release cannot be identified, while 25.1 and later omit the generated flag.
./gradlew nativeCompile --quick-build-native --verbose --image-name demo-dev
./gradlew nativeCompile --build-args=--initialize-at-build-time=com.example
./gradlew nativeCompile --force-build-args=--no-fallback
5. Override precedence
Command-line task options and -P controls override DSL configuration for a single invocation
rather than merging with it. A setter such as --image-name calls set(...) on the same property
the DSL populates, so the command-line value replaces the DSL value for that build.
Build arguments are the documented exception: --build-args appends to configured arguments,
while --force-build-args replaces them. The -Pagent property overrides the configured agent
default mode as in §FS-tracing-agent.1. Because every source writes to one option object,
behavior depends on the final value, not on whether the value came from DSL or the command line.
6. Task surface examples
The primary task surface is nativeCompile, nativeRun, nativeTestCompile, nativeTest,
generateResourcesConfigFile, collectReachabilityMetadata, listLibrariesMissingMetadata, and
metadataCopy. These tasks should be discoverable through normal Gradle task listing and keep
generated Native Image state under build/native/.
./gradlew nativeCompile
./gradlew nativeRun
./gradlew nativeTestCompile
./gradlew nativeTest
./gradlew generateResourcesConfigFile
./gradlew collectReachabilityMetadata
./gradlew listLibrariesMissingMetadata
./gradlew metadataCopy