by Anonymous » 09 Sep 2025, 15:32
Ich stecke meine Gradle -App für native Android mit Gluon Toolkit zusammen. Ich habe genau, dass NativeBuild unter Linux einwandfrei funktioniert. Hier ist meine Build.gradle -App -Datei, in der Sie die verschiedenen Paketversionen überprüfen können, die verwendet werden: < /p>
Code: Select all
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.1.0'
id 'com.gluonhq.gluonfx-gradle-plugin' version '1.0.27'
id 'com.github.johnrengelman.shadow' version '8.1.1'
}
tasks.named('shadowJar') {
mergeServiceFiles() // ensures META-INF/services entries are included
}
def isAndroid = (project.findProperty("target") ?: "host") == "android"
def JFX_VERSION = '21.0.1' // JavaFX
def ATTACH_VERSION = '4.0.23' // Gluon Attach services (if you use them)
repositories {
mavenCentral()
// Optional but harmless for some Gluon artifacts:
maven { url 'https://nexus.gluonhq.com/nexus/content/repositories/releases' }
}
javafx {
version = JFX_VERSION
modules = isAndroid
? ['javafx.controls','javafx.fxml']
: ['javafx.controls','javafx.fxml','javafx.web']
}
dependencies {
// JavaFX (Linux x64)
implementation "org.openjfx:javafx-base:${JFX_VERSION}:linux"
implementation "org.openjfx:javafx-graphics:${JFX_VERSION}:linux"
implementation "org.openjfx:javafx-controls:${JFX_VERSION}:linux"
implementation "org.openjfx:javafx-fxml:${JFX_VERSION}:linux"
implementation "org.gillius:jfxutils:1.0"
implementation("com.github.kerner1000:javafx-chart-zooming:0.0.8")
// Gluon Attach and GListen
implementation "com.gluonhq:charm-glisten:6.2.3"
implementation "com.gluonhq.attach:util:$ATTACH_VERSION"
implementation "com.gluonhq.attach:display:$ATTACH_VERSION"
implementation "com.gluonhq.attach:local-notifications:$ATTACH_VERSION"
implementation "com.gluonhq.attach:lifecycle:$ATTACH_VERSION"
implementation "com.gluonhq.attach:statusbar:$ATTACH_VERSION"
implementation "com.gluonhq.attach:storage:$ATTACH_VERSION"
}
import org.gradle.api.tasks.JavaExec
tasks.register("printGluonfxExtension") {
doLast {
println "gluonfx extension class: " + project.extensions.getByName("gluonfx").getClass().getName()
}
}
tasks.register('runAgentCustom', JavaExec) {
group = 'gluonfx'
description = 'Run app with GraalVM native-image agent (records reflection/resources).'
// Use GraalVM's java for the agent:
def gvm = System.getenv('GRAALVM_HOME')
if (!gvm) throw new GradleException("Set GRAALVM_HOME to your GraalVM install")
executable = "${gvm}/bin/java"
// Your main class (ensure this matches your application {} block)
mainClass.set(project.hasProperty('mainClass') ? project.property('mainClass').toString()
: (project.extensions.findByName('application')?.mainClass ?: 'com.gluonapplication.Launcher'))
// Make sure all runtime deps are visible:
classpath = sourceSets.main.runtimeClasspath
// Turn on the agent and explicitly add JavaFX modules so Graal's java sees them:
jvmArgs += [
"-agentlib:native-image-agent=config-merge-dir=${projectDir}/src/main/resources/META-INF/native-image",
"--module-path", configurations.runtimeClasspath.asPath,
"--add-modules", "javafx.controls,javafx.fxml,javafx.web"
]
}
application {
mainClass = 'com.gluonapplication.Launcher'
}
gluonfx {
// This extension is ClientExtension_*; it **does** support mainClassName
mainClassName = 'com.gluonapplication.Launcher'
target = project.findProperty("target") ?: "host"
// Use compilerArgs for native-image options (not 'graalvmArgs')
compilerArgs = [
"-H:Name=com.gluonapplication.launcher" // ensures com.gluonapplication.launcher.o
]
// Optional SDK hints:
graalvmHome = System.getenv('GRAALVM_HOME') ?: ''
javafxStaticSdkVersion = JFX_VERSION
attachConfig {
version = ATTACH_VERSION
services 'display','local-notifications','statusbar'
}
resourcesList = [
".*[.]fxml",
".*[.]properties",
".*[.](png|jpg|jpeg|gif|css)"
]
release {
appLabel = "Vacuum Supervisor"
versionCode = "1"
versionName = "1.0.0"
// signing fields here if needed...
}
}
tasks.register("printAndroidToolchains") {
doLast {
def env = System.getenv()
def sdk = env.ANDROID_SDK_ROOT ?: env.ANDROID_HOME ?: env.ANDROID_SDK
def ndk = env.ANDROID_NDK_ROOT ?: env.ANDROID_NDK
if (!ndk && sdk) {
def ndkBundle = new File(sdk, "ndk-bundle")
if (ndkBundle.exists()) ndk = ndkBundle.absolutePath
}
println "ANDROID_SDK = ${sdk ?: '(not set)'}"
println "ANDROID_NDK = ${ndk ?: '(not set)'}"
// Try to read NDK version
if (ndk) {
def sp = new File(ndk, "source.properties")
if (sp.exists()) {
def ver = sp.readLines().find { it.startsWith("Pkg.Revision") }?.split('=')?.last()?.trim()
println "NDK Pkg.Revision = ${ver ?: '(unknown)'}"
} else {
println "NDK source.properties not found at: $sp"
}
}
// List installed side-by-side NDKs (if any)
if (sdk) {
def ndkRoot = new File(sdk, "ndk")
if (ndkRoot.exists()) {
println "Side-by-side NDKs under ${ndkRoot}:"
ndkRoot.listFiles()?.findAll { it.isDirectory() }?.each { println " - ${it.name}" }
}
}
}
tasks.register('ensureAndroidLauncherObj') {
doLast {
def gvmDir = file("$buildDir/gluonfx/aarch64-android/gvm")
def subDir = file("$gvmDir/MainApp")
def expected = new File(gvmDir, "com.gluonapplication.launcher.o")
if (expected.exists()) {
println "Found expected object: ${expected.name}"
return
}
// Prefer com.gluonapplication.launcher.o if native-image put it elsewhere,
// otherwise fall back to the launcher.o under the MainApp subdir.
def candidates = []
if (gvmDir.exists()) candidates += gvmDir.listFiles()?.findAll { it.name.endsWith(".o") } ?: []
if (subDir.exists()) candidates += subDir.listFiles()?.findAll { it.name.endsWith(".o") } ?: []
if (candidates.isEmpty()) {
println "No .o files found under $gvmDir"
return
}
def cand = candidates.find { it.name.equalsIgnoreCase("com.gluonapplication.launcher.o") } ?:
candidates.find { it.name.equalsIgnoreCase("launcher.o") } ?:
candidates[0]
copy {
from cand
into gvmDir
rename { "com.gluonapplication.launcher.o" }
}
println "Copied ${cand.name} -> ${expected.name}"
}
}
tasks.named('nativeCompile') { finalizedBy(tasks.named('ensureAndroidLauncherObj')) }
tasks.named('nativeLink') { dependsOn(tasks.named('ensureAndroidLauncherObj')) }
// (Optional) pick a JDK toolchain for JVM runs; native-image uses GraalVM from GRAALVM_HOME
java {
toolchain { languageVersion = JavaLanguageVersion.of(22) } // good match with current Gluon GraalVM
}
./gradlew -v liest:
Code: Select all
------------------------------------------------------------
Gradle 8.14.3
------------------------------------------------------------
Build time: 2025-07-04 13:15:44 UTC
Revision: e5ee1df3d88b8ca3a8074787a94f373e3090e1db
Kotlin: 2.0.21
Groovy: 3.0.24
Ant: Apache Ant(TM) version 1.10.15 compiled on August 25 2024
Launcher JVM: 23.0.2 (GraalVM Community 23.0.2+7-jvmci-b01)
Daemon JVM: /usr/lib/jvm/jdk-22-oracle-x64 (from org.gradle.java.home)
OS: Linux 5.17.6-300.fc36.x86_64 amd64
< /code>
Mein Toolchain liest:
./gradlew -q: mainApp: printandroidtoolChains < /p>
ANDROID_SDK = /home/sentenac/Downloads/android-sdk-linux
ANDROID_NDK = /home/sentenac/Downloads/android-sdk-linux/ndk/28.2.13676358
NDK Pkg.Revision = 28.2.13676358
Side-by-side NDKs under /home/sentenac/Downloads/android-sdk-linux/ndk:
- 28.2.13676358
- 27.1.12297006
- 22.1.7171670
./gradlew -ptarget = Android: mainApp: nativecompile ---info -stacktrace gibt den Blockierungsfehler:
[SUB] Error: Could not find option 'ForceNoROSectionRelocations' from 'user'. Use -H:PrintFlags= to list all available options.
< /code>
Es scheint, dass ich nicht die richtige Kombination von Paketen zum Zusammenbruch der Kompilierungszeit verwende. Irgendwelche Hilfe?
Ich stecke meine Gradle -App für native Android mit Gluon Toolkit zusammen. Ich habe genau, dass NativeBuild unter Linux einwandfrei funktioniert. Hier ist meine Build.gradle -App -Datei, in der Sie die verschiedenen Paketversionen überprüfen können, die verwendet werden: < /p>
[code]plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.1.0'
id 'com.gluonhq.gluonfx-gradle-plugin' version '1.0.27'
id 'com.github.johnrengelman.shadow' version '8.1.1'
}
tasks.named('shadowJar') {
mergeServiceFiles() // ensures META-INF/services entries are included
}
def isAndroid = (project.findProperty("target") ?: "host") == "android"
def JFX_VERSION = '21.0.1' // JavaFX
def ATTACH_VERSION = '4.0.23' // Gluon Attach services (if you use them)
repositories {
mavenCentral()
// Optional but harmless for some Gluon artifacts:
maven { url 'https://nexus.gluonhq.com/nexus/content/repositories/releases' }
}
javafx {
version = JFX_VERSION
modules = isAndroid
? ['javafx.controls','javafx.fxml']
: ['javafx.controls','javafx.fxml','javafx.web']
}
dependencies {
// JavaFX (Linux x64)
implementation "org.openjfx:javafx-base:${JFX_VERSION}:linux"
implementation "org.openjfx:javafx-graphics:${JFX_VERSION}:linux"
implementation "org.openjfx:javafx-controls:${JFX_VERSION}:linux"
implementation "org.openjfx:javafx-fxml:${JFX_VERSION}:linux"
implementation "org.gillius:jfxutils:1.0"
implementation("com.github.kerner1000:javafx-chart-zooming:0.0.8")
// Gluon Attach and GListen
implementation "com.gluonhq:charm-glisten:6.2.3"
implementation "com.gluonhq.attach:util:$ATTACH_VERSION"
implementation "com.gluonhq.attach:display:$ATTACH_VERSION"
implementation "com.gluonhq.attach:local-notifications:$ATTACH_VERSION"
implementation "com.gluonhq.attach:lifecycle:$ATTACH_VERSION"
implementation "com.gluonhq.attach:statusbar:$ATTACH_VERSION"
implementation "com.gluonhq.attach:storage:$ATTACH_VERSION"
}
import org.gradle.api.tasks.JavaExec
tasks.register("printGluonfxExtension") {
doLast {
println "gluonfx extension class: " + project.extensions.getByName("gluonfx").getClass().getName()
}
}
tasks.register('runAgentCustom', JavaExec) {
group = 'gluonfx'
description = 'Run app with GraalVM native-image agent (records reflection/resources).'
// Use GraalVM's java for the agent:
def gvm = System.getenv('GRAALVM_HOME')
if (!gvm) throw new GradleException("Set GRAALVM_HOME to your GraalVM install")
executable = "${gvm}/bin/java"
// Your main class (ensure this matches your application {} block)
mainClass.set(project.hasProperty('mainClass') ? project.property('mainClass').toString()
: (project.extensions.findByName('application')?.mainClass ?: 'com.gluonapplication.Launcher'))
// Make sure all runtime deps are visible:
classpath = sourceSets.main.runtimeClasspath
// Turn on the agent and explicitly add JavaFX modules so Graal's java sees them:
jvmArgs += [
"-agentlib:native-image-agent=config-merge-dir=${projectDir}/src/main/resources/META-INF/native-image",
"--module-path", configurations.runtimeClasspath.asPath,
"--add-modules", "javafx.controls,javafx.fxml,javafx.web"
]
}
application {
mainClass = 'com.gluonapplication.Launcher'
}
gluonfx {
// This extension is ClientExtension_*; it **does** support mainClassName
mainClassName = 'com.gluonapplication.Launcher'
target = project.findProperty("target") ?: "host"
// Use compilerArgs for native-image options (not 'graalvmArgs')
compilerArgs = [
"-H:Name=com.gluonapplication.launcher" // ensures com.gluonapplication.launcher.o
]
// Optional SDK hints:
graalvmHome = System.getenv('GRAALVM_HOME') ?: ''
javafxStaticSdkVersion = JFX_VERSION
attachConfig {
version = ATTACH_VERSION
services 'display','local-notifications','statusbar'
}
resourcesList = [
".*[.]fxml",
".*[.]properties",
".*[.](png|jpg|jpeg|gif|css)"
]
release {
appLabel = "Vacuum Supervisor"
versionCode = "1"
versionName = "1.0.0"
// signing fields here if needed...
}
}
tasks.register("printAndroidToolchains") {
doLast {
def env = System.getenv()
def sdk = env.ANDROID_SDK_ROOT ?: env.ANDROID_HOME ?: env.ANDROID_SDK
def ndk = env.ANDROID_NDK_ROOT ?: env.ANDROID_NDK
if (!ndk && sdk) {
def ndkBundle = new File(sdk, "ndk-bundle")
if (ndkBundle.exists()) ndk = ndkBundle.absolutePath
}
println "ANDROID_SDK = ${sdk ?: '(not set)'}"
println "ANDROID_NDK = ${ndk ?: '(not set)'}"
// Try to read NDK version
if (ndk) {
def sp = new File(ndk, "source.properties")
if (sp.exists()) {
def ver = sp.readLines().find { it.startsWith("Pkg.Revision") }?.split('=')?.last()?.trim()
println "NDK Pkg.Revision = ${ver ?: '(unknown)'}"
} else {
println "NDK source.properties not found at: $sp"
}
}
// List installed side-by-side NDKs (if any)
if (sdk) {
def ndkRoot = new File(sdk, "ndk")
if (ndkRoot.exists()) {
println "Side-by-side NDKs under ${ndkRoot}:"
ndkRoot.listFiles()?.findAll { it.isDirectory() }?.each { println " - ${it.name}" }
}
}
}
tasks.register('ensureAndroidLauncherObj') {
doLast {
def gvmDir = file("$buildDir/gluonfx/aarch64-android/gvm")
def subDir = file("$gvmDir/MainApp")
def expected = new File(gvmDir, "com.gluonapplication.launcher.o")
if (expected.exists()) {
println "Found expected object: ${expected.name}"
return
}
// Prefer com.gluonapplication.launcher.o if native-image put it elsewhere,
// otherwise fall back to the launcher.o under the MainApp subdir.
def candidates = []
if (gvmDir.exists()) candidates += gvmDir.listFiles()?.findAll { it.name.endsWith(".o") } ?: []
if (subDir.exists()) candidates += subDir.listFiles()?.findAll { it.name.endsWith(".o") } ?: []
if (candidates.isEmpty()) {
println "No .o files found under $gvmDir"
return
}
def cand = candidates.find { it.name.equalsIgnoreCase("com.gluonapplication.launcher.o") } ?:
candidates.find { it.name.equalsIgnoreCase("launcher.o") } ?:
candidates[0]
copy {
from cand
into gvmDir
rename { "com.gluonapplication.launcher.o" }
}
println "Copied ${cand.name} -> ${expected.name}"
}
}
tasks.named('nativeCompile') { finalizedBy(tasks.named('ensureAndroidLauncherObj')) }
tasks.named('nativeLink') { dependsOn(tasks.named('ensureAndroidLauncherObj')) }
// (Optional) pick a JDK toolchain for JVM runs; native-image uses GraalVM from GRAALVM_HOME
java {
toolchain { languageVersion = JavaLanguageVersion.of(22) } // good match with current Gluon GraalVM
}
[/code]
./gradlew -v liest:
[code]------------------------------------------------------------
Gradle 8.14.3
------------------------------------------------------------
Build time: 2025-07-04 13:15:44 UTC
Revision: e5ee1df3d88b8ca3a8074787a94f373e3090e1db
Kotlin: 2.0.21
Groovy: 3.0.24
Ant: Apache Ant(TM) version 1.10.15 compiled on August 25 2024
Launcher JVM: 23.0.2 (GraalVM Community 23.0.2+7-jvmci-b01)
Daemon JVM: /usr/lib/jvm/jdk-22-oracle-x64 (from org.gradle.java.home)
OS: Linux 5.17.6-300.fc36.x86_64 amd64
< /code>
Mein Toolchain liest:
./gradlew -q: mainApp: printandroidtoolChains < /p>
ANDROID_SDK = /home/sentenac/Downloads/android-sdk-linux
ANDROID_NDK = /home/sentenac/Downloads/android-sdk-linux/ndk/28.2.13676358
NDK Pkg.Revision = 28.2.13676358
Side-by-side NDKs under /home/sentenac/Downloads/android-sdk-linux/ndk:
- 28.2.13676358
- 27.1.12297006
- 22.1.7171670
[/code]
./gradlew -ptarget = Android: mainApp: nativecompile ---info -stacktrace gibt den Blockierungsfehler:
[SUB] Error: Could not find option 'ForceNoROSectionRelocations' from 'user'. Use -H:PrintFlags= to list all available options.
< /code>
Es scheint, dass ich nicht die richtige Kombination von Paketen zum Zusammenbruch der Kompilierungszeit verwende. Irgendwelche Hilfe?