buildscript { repositories { gradlePluginPortal() } dependencies { classpath "io.github.fourlastor:construo:2.1.0" if(enableGraalNative == 'true') { classpath "org.graalvm.buildtools.native:org.graalvm.buildtools.native.gradle.plugin:0.9.28" } } } plugins { id "application" } apply plugin: 'io.github.fourlastor.construo' import io.github.fourlastor.construo.Target sourceSets.main.resources.srcDirs += [ rootProject.file('assets').path ] application.mainClass = 'me.lethunderhawk.lwjgl3.Lwjgl3Launcher' application.applicationName = appName eclipse.project.name = appName + '-lwjgl3' java.sourceCompatibility = 21 java.targetCompatibility = 21 if (JavaVersion.current().isJava9Compatible()) { compileJava.options.release.set(21) } dependencies { implementation "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion" implementation "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop" implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" implementation project(':core') if(enableGraalNative == 'true') { implementation "io.github.berstanio:gdx-svmhelper-backend-lwjgl3:$graalHelperVersion" implementation "io.github.berstanio:gdx-svmhelper-extension-box2d:$graalHelperVersion" } // Forces LWJGL3 to use at least $lwjgl3Version, currently 3.4.1, to avoid problems on Java 25 and up. constraints{ implementation("org.lwjgl:lwjgl:$lwjgl3Version") implementation("org.lwjgl:lwjgl-glfw:$lwjgl3Version") implementation("org.lwjgl:lwjgl-jemalloc:$lwjgl3Version") implementation("org.lwjgl:lwjgl-openal:$lwjgl3Version") implementation("org.lwjgl:lwjgl-opengl:$lwjgl3Version") implementation("org.lwjgl:lwjgl-stb:$lwjgl3Version") } } def os = System.properties['os.name'].toLowerCase(Locale.ROOT) run { workingDir = rootProject.file('assets').path // You can uncomment the next line if your IDE claims a build failure even when the app closed properly. //setIgnoreExitValue(true) jvmArgs += "--enable-native-access=ALL-UNNAMED" if (os.contains('mac')) jvmArgs += "-XstartOnFirstThread" } jar { // sets the name of the .jar file this produces to the name of the game or app, with the version after. archiveFileName.set("${appName}-${projectVersion}.jar") // the duplicatesStrategy matters starting in Gradle 7.0; this setting works. duplicatesStrategy = DuplicatesStrategy.EXCLUDE dependsOn configurations.runtimeClasspath from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } // these "exclude" lines remove some unnecessary duplicate files in the output JAR. exclude('META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA') dependencies { exclude('META-INF/INDEX.LIST', 'META-INF/maven/**') } // setting the manifest makes the JAR runnable. // enabling native access helps avoid a warning when Java 24 or later runs the JAR. // setting Multi-Release to true allows LWJGL3 to use different classes on recent Java versions. manifest { attributes 'Main-Class': application.mainClass, 'Enable-Native-Access': 'ALL-UNNAMED', 'Multi-Release': 'true' } // this last step may help on some OSes that need extra instruction to make runnable JARs. doLast { file(archiveFile).setExecutable(true, false) } } // Builds a JAR that only includes the files needed to run on macOS, not Windows or Linux. // The file size for a Mac-only JAR is about 7MB smaller than a cross-platform JAR. tasks.register("jarMac") { dependsOn("jar") group("build") jar.archiveFileName.set("${appName}-${projectVersion}-mac.jar") jar.exclude("windows/x86/**", "windows/x64/**", "linux/arm32/**", "linux/arm64/**", "linux/x64/**", "**/*.dll", "**/*.so", 'META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA') dependencies { jar.exclude("windows/x86/**", "windows/x64/**", "linux/arm32/**", "linux/arm64/**", "linux/x64/**", 'META-INF/INDEX.LIST', 'META-INF/maven/**') } } // Builds a JAR that only includes the files needed to run on Linux, not Windows or macOS. // The file size for a Linux-only JAR is about 5MB smaller than a cross-platform JAR. tasks.register("jarLinux") { dependsOn("jar") group("build") jar.archiveFileName.set("${appName}-${projectVersion}-linux.jar") jar.exclude("windows/x86/**", "windows/x64/**", "macos/arm64/**", "macos/x64/**", "**/*.dll", "**/*.dylib", 'META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA') dependencies { jar.exclude("windows/x86/**", "windows/x64/**", "macos/arm64/**", "macos/x64/**", 'META-INF/INDEX.LIST', 'META-INF/maven/**') } } // Builds a JAR that only includes the files needed to run on Windows, not Linux or macOS. // The file size for a Windows-only JAR is about 6MB smaller than a cross-platform JAR. tasks.register("jarWin") { dependsOn("jar") group("build") jar.archiveFileName.set("${appName}-${projectVersion}-win.jar") jar.exclude("macos/arm64/**", "macos/x64/**", "linux/arm32/**", "linux/arm64/**", "linux/x64/**", "**/*.dylib", "**/*.so", 'META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA') dependencies { jar.exclude("macos/arm64/**", "macos/x64/**", "linux/arm32/**", "linux/arm64/**", "linux/x64/**", 'META-INF/INDEX.LIST', 'META-INF/maven/**') } } construo { // name of the executable name.set(appName) // human-readable name, used for example in the `.app` name for macOS humanName.set(appName) jlink { guessModulesFromJar.set(false) // You may need to add more modules, as needed. modules.addAll("java.base", "java.management", "java.desktop", "jdk.unsupported") } targets.configure { register("linuxX64", Target.Linux) { architecture.set(Target.Architecture.X86_64) jdkUrl.set("https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.10%2B7/OpenJDK21U-jdk_x64_linux_hotspot_21.0.10_7.tar.gz") // Linux does not currently have a way to set the icon on the executable } register("macM1", Target.MacOs) { architecture.set(Target.Architecture.AARCH64) jdkUrl.set("https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.10%2B7/OpenJDK21U-jdk_aarch64_mac_hotspot_21.0.10_7.tar.gz") // macOS needs an identifier identifier.set("me.lethunderhawk." + appName) // Optional: icon for macOS, as an ICNS file macIcon.set(project.file("icons/logo.icns")) } register("macX64", Target.MacOs) { architecture.set(Target.Architecture.X86_64) jdkUrl.set("https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.10%2B7/OpenJDK21U-jdk_x64_mac_hotspot_21.0.10_7.tar.gz") // macOS needs an identifier identifier.set("me.lethunderhawk." + appName) // Optional: icon for macOS, as an ICNS file macIcon.set(project.file("icons/logo.icns")) } register("winX64", Target.Windows) { architecture.set(Target.Architecture.X86_64) // Optional: icon for Windows, as a PNG icon.set(project.file("icons/logo.png")) jdkUrl.set("https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.10%2B7/OpenJDK21U-jdk_x64_windows_hotspot_21.0.10_7.zip") // Uncomment the next line to show a console when the game runs, to print messages. //useConsole.set(true) } } } // Equivalent to the jar task; here for compatibility with gdx-setup. tasks.register('dist') { dependsOn 'jar' } distributions { main { contents { into('libs') { project.configurations.runtimeClasspath.files.findAll { file -> file.getName() != project.tasks.jar.outputs.files.singleFile.name }.each { file -> exclude file.name } } } } } startScripts.dependsOn(':lwjgl3:jar') startScripts.classpath = project.tasks.jar.outputs.files // Helps if debugging on Linux with an Nvidia GPU. // This means StartupHelper won't try to restart the JVM, which can prevent debugging. // This only applies to Gradle tasks, not main methods debugged when launching a main() method directly. // As a more general solution, set the environment variable __GL_THREADED_OPTIMIZATIONS to 0 globally, on Linux // machines with Nvidia GPUs where you need to debug LWJGL3 apps and games. // You can also set __GL_THREADED_OPTIMIZATIONS to 0 in run configurations, which you would need per main() method. // StartupHelper will still restart the JVM to set this environment variable when run as a distributable JAR, which is // a good thing for end users. They won't need to ever set the debug-specific environment variable. tasks.withType(JavaExec.class).configureEach { environment("__GL_THREADED_OPTIMIZATIONS", 0) } if(enableGraalNative == 'true') { apply from: file("nativeimage.gradle") }