Make native library config options more flexible

This replaces the forceNativeLibWithName config option with two new ones: forceNativeLibPlatform and forceNativeLibPathFirst. forceNativeLibPlatform allows overriding the normally auto-detected platform string to a custom value, in case the user is on an unsupported platform. forceNativeLibPathFirst allows choosing a directory to check for natives in, instead of always searching in the jar for one. This allows custom natives to be used without packing them into the mod jar first, which should be much easier for end users.
This commit is contained in:
TheCodex6824 2022-09-24 20:27:44 -04:00
parent 00c5a9b3dd
commit b40b330e6f
No known key found for this signature in database
GPG Key ID: E9EBC39837469118
3 changed files with 160 additions and 117 deletions

View File

@ -1506,10 +1506,21 @@ opencomputers {
# to work.
logFullNativeLibLoadErrors: false
# Force loading one specific library, to avoid trying to load any
# others. Use this if you get warnings in the log or are told to do
# so for debugging purposes ;-)
forceNativeLibWithName: ""
# Force the platform name for the native libraries, instead of relying
# on auto-detecting it. Use this if your system is using an otherwise
# unsupported operating system or CPU architecture. If unsure, leave blank.
#
# Examples of platform strings include "solaris-x86_64" for 64-bit Solaris,
# or "windows-aarch64" for Windows on the aarch64 (64-bit arm) architecture.
forceNativeLibPlatform: ""
# Force the native library loader to check the specified directory for natives first,
# before trying to find libraries packaged with OpenComputers. Use this if you want to
# use custom native libraries, or are on an unsupported platform. If unsure, leave blank.
#
# This can be an absolute or relative path. If relative, the base directory will be the .minecraft
# directory of the running Minecraft instance.
forceNativeLibPathFirst: ""
# Used to suppress log spam for OpenGL errors on derpy drivers. I'm
# quite certain the code in the font render is valid, display list

View File

@ -438,7 +438,8 @@ class Settings(val config: Config) {
val limitMemory = !config.getBoolean("debug.disableMemoryLimit")
val forceCaseInsensitive = config.getBoolean("debug.forceCaseInsensitiveFS")
val logFullLibLoadErrors = config.getBoolean("debug.logFullNativeLibLoadErrors")
val forceNativeLib = config.getString("debug.forceNativeLibWithName")
val forceNativeLibPlatform = config.getString("debug.forceNativeLibPlatform")
val forceNativeLibPathFirst = config.getString("debug.forceNativeLibPathFirst")
val logOpenGLErrors = config.getBoolean("debug.logOpenGLErrors")
val logHexFontErrors = config.getBoolean("debug.logHexFontErrors")
val alwaysTryNative = config.getBoolean("debug.alwaysTryNative")

View File

@ -4,8 +4,8 @@ import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.nio.channels.Channels
import java.nio.file.Paths
import java.util.regex.Pattern
import com.google.common.base.Strings
import com.google.common.io.PatternFilenameFilter
import li.cil.oc.OpenComputers
@ -130,15 +130,15 @@ abstract class LuaStateFactory {
private var currentLib = ""
private val libraryName = {
if (!Strings.isNullOrEmpty(Settings.get.forceNativeLib)) Settings.get.forceNativeLib
else {
val libExtension = {
if (SystemUtils.IS_OS_MAC) ".dylib"
else if (SystemUtils.IS_OS_WINDOWS) ".dll"
else ".so"
}
val platformName = {
if (!Strings.isNullOrEmpty(Settings.get.forceNativeLibPlatform)) Settings.get.forceNativeLibPlatform
else {
val systemName = {
if (SystemUtils.IS_OS_FREE_BSD) "freebsd"
else if (SystemUtils.IS_OS_NET_BSD) "netbsd"
@ -158,10 +158,13 @@ abstract class LuaStateFactory {
else "unknown"
}
"libjnlua" + version + "-" + systemName + "-" + archName + libExtension
systemName + "-" + archName
}
}
"libjnlua" + version + "-" + platformName + libExtension
}
protected def create(maxMemory: Option[Int] = None): jnlua.LuaState
protected def openLibs(state: jnlua.LuaState): Unit
@ -170,13 +173,26 @@ abstract class LuaStateFactory {
def isAvailable = haveNativeLibrary
val is64Bit = Architecture.IS_OS_X64
val is64Bit = {
val dataModel = try System.getProperty("sun.arch.data.model") catch {
case ex: SecurityException => null
}
if (dataModel != null)
"64".equals(dataModel)
else {
// Best effort, will probably miss some esoteric architectures
// Examples this works for: x86_64, ppc64le, aarch64_be
SystemUtils.OS_ARCH.matches(".*64_?([bl]e)?")
}
}
// Since we use native libraries we have to do some work. This includes
// figuring out what we're running on, so that we can load the proper shared
// libraries compiled for that system. It also means we have to unpack the
// shared libraries somewhere so that we can load them, because we cannot
// load them directly from a JAR.
// load them directly from a JAR. Lastly, we need to handle library overrides in
// case the user wants to use custom libraries, or are not on a supported platform.
def init() {
if (libraryName == null) {
return
@ -194,9 +210,22 @@ abstract class LuaStateFactory {
}
}
var tmpLibFile: File = null
if (!Strings.isNullOrEmpty(Settings.get.forceNativeLibPathFirst)) {
val libraryTest = new File(Settings.get.forceNativeLibPathFirst, libraryName);
if (libraryTest.canRead) {
tmpLibFile = libraryTest
currentLib = libraryTest.getAbsolutePath
OpenComputers.log.info(s"Found forced-path filesystem library $currentLib.")
}
else
OpenComputers.log.warn(s"forceNativeLibPathFirst is set, but $currentLib was not found there. Falling back to checking the built-in libraries.")
}
if (currentLib.isEmpty) {
val libraryUrl = classOf[Machine].getResource(s"/assets/${Settings.resourceDomain}/lib/$libraryName")
if (libraryUrl == null) {
OpenComputers.log.warn(s"Native library with name '$version/$libraryName' not found.")
OpenComputers.log.warn(s"Native library with name '$libraryName' not found.")
return
}
@ -208,7 +237,7 @@ abstract class LuaStateFactory {
else path + "/"
}
else "./"
val tmpLibFile = new File(tmpBasePath + tmpLibName)
tmpLibFile = new File(tmpBasePath + tmpLibName)
// Clean up old library files when not in tmp dir.
if (!Settings.get.nativeInTmpDir) {
@ -296,6 +325,8 @@ abstract class LuaStateFactory {
}
// Try to load the lib.
currentLib = tmpLibFile.getAbsolutePath
}
try {
LuaStateFactory.synchronized {
System.load(currentLib)