Skip to content

Include natives for all platforms in generated build files #88

@knokko

Description

@knokko

When using the build configurator to create a gradle build file with only the core of LWJGL, it will generate the following file:

import org.gradle.internal.os.OperatingSystem

project.ext.lwjglVersion = "3.2.3"

switch (OperatingSystem.current()) {
	case OperatingSystem.LINUX:
		def osArch = System.getProperty("os.arch")
		project.ext.lwjglNatives = osArch.startsWith("arm") || osArch.startsWith("aarch64")
			? "natives-linux-${osArch.contains("64") || osArch.startsWith("armv8") ? "arm64" : "arm32"}"
			: "natives-linux"
		break
	case OperatingSystem.MAC_OS:
		project.ext.lwjglNatives = "natives-macos"
		break
	case OperatingSystem.WINDOWS:
		project.ext.lwjglNatives = System.getProperty("os.arch").contains("64") ? "natives-windows" : "natives-windows-x86"
		break
}

repositories {
	mavenCentral()
}

dependencies {
	implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion")

	implementation "org.lwjgl:lwjgl"
	runtimeOnly "org.lwjgl:lwjgl::$lwjglNatives"
}

This uses a big switch statement to pick the natives for the current operating system. This is nice for development runs, but horrible when distributing with something like shadowJar: it will generate a fat jar file containing only the natives of the operating system that built it. This would cause the jar to work very well on the machine of the developer, but fail on any machine with a different operating system or architecture due to missing natives. If the developer doesn't open it up with an archive manager or tests on a different machine, he wouldn't even find out.

I would instead generate a file like this:

project.ext.lwjglVersion = "3.2.3"

repositories {
	mavenCentral()
}

dependencies {
	implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion")

	implementation "org.lwjgl:lwjgl"
	runtimeOnly "org.lwjgl:lwjgl::natives-windows"
	runtimeOnly "org.lwjgl:lwjgl::natives-windows-x86"
	runtimeOnly "org.lwjgl:lwjgl::natives-linux"
	runtimeOnly "org.lwjgl:lwjgl::natives-linux-arm32"
	runtimeOnly "org.lwjgl:lwjgl::natives-linux-arm64"
	runtimeOnly "org.lwjgl:lwjgl::natives-macos"
}

With this file, the natives for all operating systems will always be included, regardless on which operating system it is built. If shadowJar would be used on such a build file, the produced jar file will contain all natives and therefor work on all supported platforms. I would consider this more the Java way to do things.

This example was just for gradle, but similar arguments should hold for the other supported build systems as well. Note: If there is a better than way than shadowJar to distribute lwjgl applications, please let me know!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions