Skip to content

Commit c46a9bb

Browse files
Run windows examples in linux (#2747)
* add task to run tests in proton * Update jme3-examples/build.gradle Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update jme3-examples/build.gradle Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update jme3-examples/build.gradle Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update jme3-examples/build.gradle Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent f629be3 commit c46a9bb

1 file changed

Lines changed: 141 additions & 0 deletions

File tree

jme3-examples/build.gradle

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,147 @@ task runExamples(dependsOn: 'build', type: JavaExec) {
3737
}
3838
}
3939

40+
def umuLauncherDownloadUrl = 'https://github.com/Open-Wine-Components/umu-launcher/releases/download/1.4.0/umu-launcher-1.4.0-zipapp.tar'
41+
def umuLauncherArchive = layout.buildDirectory.file('tmp/umu-launcher-1.4.0-zipapp.tar')
42+
def umuLauncherExtractDir = layout.buildDirectory.dir('tools/umu-launcher')
43+
def protonToolchainVersion = java.toolchain.languageVersion.get().asInt()
44+
def protonJdkDownloadUrl = "https://api.adoptium.net/v3/binary/latest/${protonToolchainVersion}/ga/windows/x64/jdk/hotspot/normal/eclipse?project=jdk"
45+
def protonJdkArchive = layout.buildDirectory.file("tmp/proton-jdk-${protonToolchainVersion}-windows.zip")
46+
def protonJdkExtractDir = layout.buildDirectory.dir('tools/proton-jdk')
47+
48+
task downloadProtonRuntime {
49+
description = 'Download and extract Proton runtime launcher into jme3-examples/build/tools/umu-launcher.'
50+
outputs.dir(umuLauncherExtractDir)
51+
inputs.property("url", umuLauncherDownloadUrl)
52+
53+
doLast {
54+
def archiveFile = umuLauncherArchive.get().asFile
55+
archiveFile.parentFile.mkdirs()
56+
57+
logger.lifecycle("Downloading umu-launcher from ${umuLauncherDownloadUrl}")
58+
59+
new URL(umuLauncherDownloadUrl).withInputStream { input ->
60+
archiveFile.withOutputStream { output ->
61+
output << input
62+
}
63+
}
64+
65+
def extractRoot = umuLauncherExtractDir.get().asFile
66+
extractRoot.deleteDir()
67+
extractRoot.mkdirs()
68+
69+
copy {
70+
from tarTree(archiveFile)
71+
into extractRoot
72+
}
73+
74+
def extractedEntries = extractRoot.listFiles()
75+
if (extractedEntries == null || extractedEntries.length == 0) {
76+
throw new GradleException('umu-launcher archive extraction failed: build/tools/umu-launcher is empty')
77+
}
78+
79+
logger.lifecycle("umu-launcher extracted to ${extractRoot.absolutePath}")
80+
}
81+
}
82+
83+
task downloadProtonJdk {
84+
description = "Download and extract the Adoptium Java ${protonToolchainVersion} Windows JDK used to bootstrap Gradle inside Proton."
85+
outputs.dir(protonJdkExtractDir)
86+
inputs.property("url", protonJdkDownloadUrl)
87+
88+
doLast {
89+
def archiveFile = protonJdkArchive.get().asFile
90+
archiveFile.parentFile.mkdirs()
91+
92+
logger.lifecycle("Downloading Windows JDK from ${protonJdkDownloadUrl}")
93+
94+
new URL(protonJdkDownloadUrl).withInputStream { input ->
95+
archiveFile.withOutputStream { output ->
96+
output << input
97+
}
98+
}
99+
100+
def extractRoot = protonJdkExtractDir.get().asFile
101+
extractRoot.deleteDir()
102+
extractRoot.mkdirs()
103+
104+
copy {
105+
from zipTree(archiveFile)
106+
into extractRoot
107+
}
108+
109+
def extractedEntries = extractRoot.listFiles()
110+
if (extractedEntries == null || extractedEntries.length == 0) {
111+
throw new GradleException('Windows JDK extraction failed: build/tools/proton-jdk is empty')
112+
}
113+
114+
logger.lifecycle("Windows JDK extracted to ${extractRoot.absolutePath}")
115+
}
116+
}
117+
118+
task runExamplesWithProton(dependsOn: ['build', 'downloadProtonRuntime', 'downloadProtonJdk'], type: Exec) {
119+
description = 'Run jme3 examples under Proton using the downloaded runtime launcher and Windows JDK.'
120+
workingDir = rootProject.projectDir
121+
122+
doFirst {
123+
def extractRoot = umuLauncherExtractDir.get().asFile
124+
def umuRunScript = new File(extractRoot, 'umu-run')
125+
if (!umuRunScript.exists()) {
126+
def nestedUmuRun = extractRoot.listFiles()?.find { it.isDirectory() }?.toPath()?.resolve('umu-run')?.toFile()
127+
if (nestedUmuRun != null && nestedUmuRun.exists()) {
128+
umuRunScript = nestedUmuRun
129+
}
130+
}
131+
if (!umuRunScript.exists()) {
132+
throw new GradleException("Could not find umu-run script at ${umuRunScript.absolutePath}")
133+
}
134+
135+
def protonJdkRoot = protonJdkExtractDir.get().asFile
136+
def protonJdkDir = fileTree(protonJdkRoot).find { it.name == 'java.exe' }?.parentFile?.parentFile
137+
138+
def winePrefix = "${buildDir}/umu/wineprefix"
139+
def gameId = 'jme3-examples'
140+
def store = 'none'
141+
def protonJavaHome = "Z:${protonJdkDir.absolutePath.replace('/', '\\\\')}"
142+
def protonJavaExe = "${protonJavaHome}\\\\bin\\\\java.exe"
143+
def exampleClass = project.findProperty('example')?.toString() ?: mainClassName
144+
def runtimeClasspathFiles = sourceSets.main.runtimeClasspath.files as LinkedHashSet
145+
def relevantRuntimeEntries = runtimeClasspathFiles.findAll { file ->
146+
def name = file.name.toLowerCase()
147+
name.contains('angle') || name.contains('saferalloc')
148+
}
149+
logger.lifecycle("Proton runtime entries: ${relevantRuntimeEntries*.name}")
150+
151+
def runtimeClasspath = runtimeClasspathFiles.collect { file ->
152+
"Z:${file.absolutePath.replace('/', '\\\\')}"
153+
}.join(';')
154+
def jvmArgs = []
155+
156+
if (assertions == 'true') {
157+
jvmArgs << '-ea'
158+
}
159+
160+
if (System.properties['java.util.logging.config.file'] != null) {
161+
def loggingConfig = System.properties['java.util.logging.config.file'].replace('/', '\\\\')
162+
jvmArgs << "-Djava.util.logging.config.file=Z:${loggingConfig}"
163+
}
164+
165+
executable = umuRunScript.absolutePath
166+
args protonJavaExe
167+
args jvmArgs
168+
args '-cp', runtimeClasspath, exampleClass
169+
170+
environment 'WINEPREFIX', winePrefix
171+
environment 'GAMEID', gameId
172+
environment 'STORE', store
173+
environment 'JAVA_HOME', protonJavaHome
174+
environment 'JDK_HOME', protonJavaHome
175+
environment 'PROTON_VERB', 'waitforexitandrun'
176+
177+
logger.lifecycle("Running ${exampleClass} with Proton via ${protonJavaExe}")
178+
}
179+
}
180+
40181
dependencies {
41182
implementation project(':jme3-core')
42183
implementation project(':jme3-desktop')

0 commit comments

Comments
 (0)