diff --git a/build.gradle.kts b/build.gradle.kts index 96371791..ec68f9f9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,3 @@ - import org.gradle.plugins.ide.idea.model.IdeaModel plugins { @@ -75,7 +74,7 @@ artifactNameMap.forEach { (subprojectName, artifactName) -> tasks.named("jar") { manifestContentCharset = "utf-8" - setMetadataCharset("utf-8") + metadataCharset = "utf-8" manifest.attributes( "Specification-Title" to projName, "Specification-Vendor" to "Overrun Organization", @@ -118,7 +117,6 @@ artifactNameMap.forEach { (subprojectName, artifactName) -> allprojects { tasks.withType { options { - verbose() if (this is CoreJavadocOptions) { if (jdkEnablePreview.toBoolean()) { addBooleanOption("-enable-preview", true) @@ -160,6 +158,47 @@ allprojects { } } +Artifact.values().forEach { + project(it.subprojectName) { + val javaComponent = components.findByName("java") as AdhocComponentWithVariants + // Add a different runtime variant for each platform + it.nativeBinding?.platforms?.forEach { platform -> + val nativeFileName = it.nativeFileName(platform) + val file = File("${rootProject.projectDir}/natives/$nativeFileName") + + if (file.exists()) { + val archiveTaskName = "${it.nativeBinding?.bindingName}${platform.classifier}Jar" + + val nativeJar = tasks.register(archiveTaskName) { + archiveBaseName.set(it.artifactName) + archiveClassifier.set(platform.classifier) + from(file) { into(File(nativeFileName).parent) } + } + + val nativeRuntimeElements = configurations.create(platform.classifier + "RuntimeElements") { + isCanBeConsumed = true; isCanBeResolved = false + attributes { + attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) + attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL)) + attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, targetJavaVersion) + attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR)) + attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME)) + attributes.attribute( + OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTE, + objects.named(platform.osFamilyName) + ) + attributes.attribute(MachineArchitecture.ARCHITECTURE_ATTRIBUTE, objects.named(platform.osArch)) + } + outgoing.artifact(tasks.named("jar")) + outgoing.artifact(nativeJar) + extendsFrom(configurations["runtimeElements"]) + } + javaComponent.addVariantsFromConfiguration(nativeRuntimeElements) {} + } + } + } +} + publishing.publications { fun MavenPom.setupPom(pomName: String, pomDescription: String, pomPackaging: String) { name.set(pomName) @@ -192,26 +231,12 @@ publishing.publications { } Artifact.values().forEach { module -> - create("maven${module.mavenName}") { + create("maven${module.name}") { groupId = projGroupId artifactId = module.artifactName version = projVersion description = module.projectDescription - project(module.subprojectName) { - from(components["java"]) - } - module.nativeBinding?.platforms?.forEach { - val nativeName = module.nativeFileName(it)!! - val file = File("${rootProject.projectDir}/natives/$nativeName") - if (file.exists()) { - val nativeParent = File(nativeName).parent - artifact(tasks.register("nativeJar${module.mavenName}${it.taskSuffix}") { - archiveBaseName.set(module.artifactName) - archiveClassifier.set(it.classifier) - from(file) { into(nativeParent) } - }) - } - } + from(project(module.subprojectName).components["java"]) pom { setupPom(module.projectName, module.projectDescription, "jar") } diff --git a/buildSrc/src/main/kotlin/myproject.java-conventions.gradle.kt b/buildSrc/src/main/kotlin/myproject.java-conventions.gradle.kt index 797bc1f5..741d2509 100644 --- a/buildSrc/src/main/kotlin/myproject.java-conventions.gradle.kt +++ b/buildSrc/src/main/kotlin/myproject.java-conventions.gradle.kt @@ -17,18 +17,20 @@ enum class NativePlatform( val osFamilyName: String, val osArch: String, - classifier: String, - val nativeLibPrefix: String, - val nativeLibSuffix: String, - val taskSuffix: String + classifier: String = "$osFamilyName-$osArch", + val nativeLibPrefix: String = "lib", + val nativeLibSuffix: String = ".so" ) { - WIN_64("windows", "x64", "windows", "", ".dll", "Win64"), - WIN_ARM64("windows", "arm64", "windows-arm64", "", ".dll", "WinArm64"), - LINUX_64("linux", "x64", "linux", "lib", ".so", "Linux64"), - LINUX_ARM32("linux", "arm32", "linux-arm32", "lib", ".so", "LinuxArm32"), - LINUX_ARM64("linux", "arm64", "linux-arm64", "lib", ".so", "LinuxArm64"), - MACOS("macos", "x64", "macos", "lib", ".dylib", "Macos"), - MACOS_ARM64("macos", "arm64", "macos-arm64", "lib", ".dylib", "MacosArm64"); + FREEBSD_X64("freebsd", "x64", classifier = "freebsd"), + LINUX_64("linux", "x64", classifier = "linux"), + LINUX_ARM32("linux", "arm32"), + LINUX_ARM64("linux", "arm64"), + LINUX_PPC64LE("linux", "ppc64le"), + LINUX_RISCV64("linux", "riscv64"), + MACOS("macos", "x64", classifier = "macos", nativeLibSuffix = ".dylib"), + MACOS_ARM64("macos", "arm64", nativeLibSuffix = ".dylib"), + WIN_64("windows", "x64", classifier = "windows", nativeLibPrefix = "", nativeLibSuffix = ".dll"), + WIN_ARM64("windows", "arm64", nativeLibPrefix = "", nativeLibSuffix = ".dll"); companion object { val ALL = values() @@ -42,12 +44,7 @@ enum class NativeBinding( val basename: String, vararg val platforms: NativePlatform ) { - GLFW( - "glfw", "glfw3", - NativePlatform.WIN_64, - NativePlatform.LINUX_64, NativePlatform.LINUX_ARM64, - NativePlatform.MACOS, NativePlatform.MACOS_ARM64 - ), + GLFW("glfw", "glfw", *NativePlatform.ALL), NFD("nfd", "nfd", *NativePlatform.ALL), STB("stb", "stb", *NativePlatform.ALL) } @@ -57,38 +54,37 @@ enum class Artifact( val projectName: String, val projectDescription: String, val subprojectName: String, - val mavenName: String, val nativeBinding: NativeBinding? = null ) { CORE( "overrungl", "OverrunGL", "The OverrunGL core library.", - ":core", "Core" + ":core" ), GLFW( "overrungl-glfw", "OverrunGL - GLFW bindings", "A multi-platform library for OpenGL, OpenGL ES and Vulkan development on the desktop. It provides a simple API for creating windows, contexts and surfaces, receiving input and events.", - ":glfw", "Glfw", NativeBinding.GLFW + ":glfw", NativeBinding.GLFW ), JOML( "overrungl-joml", "OverrunGL - JOML native access", "A Java math library for OpenGL rendering calculations", - ":joml", "Joml" + ":joml" ), NFD( "overrungl-nfd", "OverrunGL - Native File Dialog", "A tiny, neat C library that portably invokes native file open and save dialogs.", - ":nfd", "Nfd", NativeBinding.NFD + ":nfd", NativeBinding.NFD ), OPENGL( "overrungl-opengl", "OverrunGL - OpenGL bindings", "The most widely adopted 2D and 3D graphics API in the industry, bringing thousands of applications to a wide variety of computer platforms.", - ":opengl", "Opengl" + ":opengl" ), STB( "overrungl-stb", "OverrunGL - stb bindings", "Single-file public domain libraries for fonts, images, ogg vorbis files and more.", - ":stb", "Stb", NativeBinding.STB + ":stb", NativeBinding.STB ), // VULKAN("overrungl-vulkan", "OverrunGL - Vulkan bindings", // "A new generation graphics and compute API that provides high-efficiency, cross-platform access to modern GPUs used in a wide variety of devices from PCs and consoles to mobile phones and embedded platforms.", @@ -97,6 +93,6 @@ enum class Artifact( fun nativeFileName(platform: NativePlatform): String? { return if (nativeBinding == null) null - else "${nativeBinding.bindingName}/${platform.osFamilyName}/${platform.osArch}/${platform.nativeLibPrefix}${nativeBinding.basename}${platform.nativeLibSuffix}" + else "${nativeBinding.bindingName}/${platform.osFamilyName}-${platform.osArch}/${platform.nativeLibPrefix}${nativeBinding.basename}${platform.nativeLibSuffix}" } } diff --git a/doc/internal/README.md b/doc/internal/README.md index a3e4cd99..dd32b061 100644 --- a/doc/internal/README.md +++ b/doc/internal/README.md @@ -4,6 +4,12 @@ To publish this library, you need a GPG key and the write permission of Maven Central. +### CI + +- [glfw](https://github.com/Over-Run/glfw-ci) +- [nfd](https://github.com/Over-Run/nfd-ci) +- [stb](https://github.com/Over-Run/stb-ci) + ### Packing Natives The build script packs the native libraries into jars. @@ -12,56 +18,27 @@ The tree structure of the native libraries is: ```text natives -├─ glfw -│ ├─ linux -│ │ ├─ arm64 -│ │ │ └─ libglfw3.so -│ │ └─ x64 -│ │ └─ libglfw3.so -│ ├─ macos -│ │ ├─ arm64 -│ │ │ └─ libglfw3.dylib -│ │ └─ x64 -│ │ └─ libglfw3.dylib -│ └─ windows -│ └─ x64 -│ └─ glfw3.dll -├─ nfd https://github.com/Over-Run/nfd-ci -│ ├─ linux -│ │ ├─ arm32 -│ │ │ └─ libnfd.so -│ │ ├─ arm64 -│ │ │ └─ libnfd.so -│ │ └─ x64 -│ │ └─ libnfd.so -│ ├─ macos -│ │ ├─ arm64 -│ │ │ └─ libnfd.dylib -│ │ └─ x64 -│ │ └─ libnfd.dylib -│ └─ windows -│ ├─ arm64 -│ │ └─ nfd.dll -│ └─ x64 -│ └─ nfd.dll -└─ stb https://github.com/Over-Run/stb-ci - ├─ linux - │ ├─ arm32 - │ │ └─ libstb.so - │ ├─ arm64 - │ │ └─ libstb.so - │ └─ x64 - │ └─ libstb.so - ├─ macos - │ ├─ arm64 - │ │ └─ libstb.dylib - │ └─ x64 - │ └─ libstb.dylib - └─ windows - ├─ arm64 - │ └─ stb.dll - └─ x64 - └─ stb.dll +└─ + ├─ freebsd-x64 + │ └─ lib.so + ├─ linux-arm32 + │ └─ lib.so + ├─ linux-arm64 + │ └─ lib.so + ├─ linux-ppc64le + │ └─ lib.so + ├─ linux-riscv64 + │ └─ lib.so + ├─ linux-x64 + │ └─ lib.so + ├─ macos-arm64 + │ └─ lib.dylib + ├─ macos-x64 + │ └─ lib.dylib + ├─ windows-arm64 + │ └─ .dll + └─ windows-x64 + └─ .dll ``` -The `natives` directory is in the project directory. +The `natives` directory is in the root project directory. diff --git a/modules/overrungl.core/src/main/java/overrungl/OverrunGL.java b/modules/overrungl.core/src/main/java/overrungl/OverrunGL.java index b0ff75bb..dbdefdf4 100644 --- a/modules/overrungl.core/src/main/java/overrungl/OverrunGL.java +++ b/modules/overrungl.core/src/main/java/overrungl/OverrunGL.java @@ -37,15 +37,15 @@ public final class OverrunGL { /** * The version of GLFW native libraries. */ - public static final String GLFW_VERSION = "3.4.0.0"; + public static final String GLFW_VERSION = "3.5.0.0"; /** * The version of NFD native libraries. */ - public static final String NFD_VERSION = "0.1.0.0"; + public static final String NFD_VERSION = "1.1.1.0"; /** * The version of STB native libraries. */ - public static final String STB_VERSION = "0.1.0.3"; + public static final String STB_VERSION = "0.1.0.4"; private static final Consumer DEFAULT_LOGGER = System.err::println; private static Consumer apiLogger = DEFAULT_LOGGER; diff --git a/modules/overrungl.core/src/main/java/overrungl/internal/RuntimeHelper.java b/modules/overrungl.core/src/main/java/overrungl/internal/RuntimeHelper.java index 4685cf39..24785d6a 100644 --- a/modules/overrungl.core/src/main/java/overrungl/internal/RuntimeHelper.java +++ b/modules/overrungl.core/src/main/java/overrungl/internal/RuntimeHelper.java @@ -39,7 +39,8 @@ public final class RuntimeHelper { * The native linker. */ private static final Linker LINKER = Linker.nativeLinker(); - private static final Path tmpdir = Path.of(System.getProperty("java.io.tmpdir")); + private static final Path tmpdir = Path.of(System.getProperty("java.io.tmpdir")) + .resolve(STR."overrungl\{System.getProperty("user.name")}"); private static final StackWalker STACK_WALKER = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); private static final Map CANONICAL_LAYOUTS = LINKER.canonicalLayouts(); /** @@ -102,24 +103,23 @@ public static SymbolLookup load(String module, String basename, String version) uri = localFile; } else { // 2. Load from classpath - var file = tmpdir.resolve(STR."overrungl\{System.getProperty("user.name")}"); try { - if (!Files.exists(file)) { + if (!Files.exists(tmpdir)) { // Create directory - Files.createDirectories(file); - } else if (!Files.isDirectory(file)) { + Files.createDirectories(tmpdir); + } else if (!Files.isDirectory(tmpdir)) { // Remove - Files.delete(file); + Files.delete(tmpdir); // Create directory - Files.createDirectories(file); + Files.createDirectories(tmpdir); } } catch (IOException e) { - throw new IllegalStateException(STR."Couldn't create directory: \{file}; try setting -Doverrungl.natives to a valid path", e); + throw new IllegalStateException(STR."Couldn't create directory: \{tmpdir}; try setting -Doverrungl.natives to a valid path", e); } - var libFile = file.resolve(STR."\{basename}-\{version}\{suffix}"); + var libFile = tmpdir.resolve(STR."\{basename}-\{version}\{suffix}"); if (!Files.exists(libFile)) { // Extract - final String fromPath = STR."\{module}/\{os.familyName()}/\{Architecture.current()}/\{path}"; + final String fromPath = STR."\{module}/\{os.familyName()}-\{Architecture.current()}/\{path}"; try (var is = STACK_WALKER.getCallerClass().getClassLoader().getResourceAsStream(fromPath)) { Files.copy(Objects.requireNonNull(is, STR."File not found in classpath: \{fromPath}"), libFile); } catch (Exception e) { diff --git a/modules/overrungl.glfw/src/main/java/overrungl/glfw/Handles.java b/modules/overrungl.glfw/src/main/java/overrungl/glfw/Handles.java index f1745d71..7b059bea 100644 --- a/modules/overrungl.glfw/src/main/java/overrungl/glfw/Handles.java +++ b/modules/overrungl.glfw/src/main/java/overrungl/glfw/Handles.java @@ -33,7 +33,7 @@ final class Handles { static final SymbolLookup lookup; static { - final Supplier lib = () -> RuntimeHelper.load("glfw", "glfw3", OverrunGL.GLFW_VERSION); + final Supplier lib = () -> RuntimeHelper.load("glfw", "glfw", OverrunGL.GLFW_VERSION); final var function = Configurations.GLFW_SYMBOL_LOOKUP.get(); lookup = function != null ? function.apply(lib) : lib.get(); } diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 2c71cf89..00000000 --- a/pom.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - 4.0.0 - - io.github.over-run - overrungl - 0.1.0-SNAPSHOT - - OverrunGL - Overrun Game Library is a high-performance library, which enables cross-platform access to a set of C/C++ library bindings, and provides some useful utilities. - https://github.com/Over-Run/overrungl - - - - MIT - https://raw.githubusercontent.com/Over-Run/overrungl/main/LICENSE - repo - - - - - - squid233 - https://github.com/squid233 - - - - - scm:git:https://github.com/Over-Run/overrungl.git - scm:git:https://github.com/Over-Run/overrungl.git - https://github.com/Over-Run/overrungl.git - -