Skip to content

Commit

Permalink
Fix library loading on windows
Browse files Browse the repository at this point in the history
  • Loading branch information
Him188 committed Dec 23, 2024
1 parent b6f6435 commit 0918522
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 21 deletions.
1 change: 0 additions & 1 deletion app/desktop/test-sandbox/libanitorrent.dylib

This file was deleted.

74 changes: 54 additions & 20 deletions torrent/anitorrent/src/jvmMain/kotlin/AnitorrentLibraryLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,25 @@
package me.him188.ani.app.torrent.anitorrent

import me.him188.ani.app.torrent.api.TorrentLibraryLoader
import me.him188.ani.utils.logging.info
import me.him188.ani.utils.logging.logger
import me.him188.ani.utils.logging.*
import me.him188.ani.utils.platform.Platform
import me.him188.ani.utils.platform.currentPlatform
import me.him188.ani.utils.platform.isAndroid
import java.io.File
import java.io.IOException
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.concurrent.Volatile
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.absolutePathString
import kotlin.io.path.deleteRecursively
import kotlin.io.path.outputStream
import kotlin.math.absoluteValue
import kotlin.random.Random

object AnitorrentLibraryLoader : TorrentLibraryLoader {
private val logger = logger<AnitorrentLibraryLoader>()
private val platform = currentPlatform()

@Volatile
private var libraryLoaded = false
Expand All @@ -38,39 +44,67 @@ object AnitorrentLibraryLoader : TorrentLibraryLoader {
// anitorrent.install_signal_handlers()
}

@Suppress("UnsafeDynamicallyLoadedCode")
@kotlin.jvm.Throws(IOException::class)
private fun loadDependencies() {
val platform = currentPlatform()
if (platform.isAndroid()) {
System.loadLibrary("anitorrent")
return
}
logger.info { "Loading anitorrent library" }
try {
System.loadLibrary("anitorrent")
logger.info { "Loading anitorrent library: success (from system library path)" }
logger.info { "Loading anitorrent library: success (from java.library.path)" }
} catch (e: UnsatisfiedLinkError) {
// 可能是调试状态, 从 resources 加载
logger.info { "Failed to load anitorrent directly from native path, trying resources instead" }
val filename = when (platform as Platform.Desktop) {
is Platform.Linux -> "libanitorrent.so"
is Platform.Windows -> "anitorrent.dll"
is Platform.MacOS -> "libanitorrent.dylib"
}
this::class.java.classLoader?.getResourceAsStream(filename)?.use {
val tempFile = File.createTempFile(Random.nextInt().absoluteValue.toString() + filename, null).apply {
deleteOnExit()
}
tempFile.outputStream().use { output ->
it.copyTo(output)
}
System.load(tempFile.absolutePath)
logger.info { "Failed to load anitorrent directly from java.library.path, trying resources instead" }
val temp = getTempDirForPlatform()
logger.info { "Temp dir: ${temp.absolutePathString()}" }
if (platform is Platform.Windows) {
loadLibraryFromResources("torrent-rasterbar", temp)
}
loadLibraryFromResources("anitorrent", temp)
logger.info { "Loading anitorrent library: success (from resources)" }
}
}

@OptIn(ExperimentalPathApi::class)
private fun getTempDirForPlatform(): Path {
return if (platform is Platform.Windows) {
Paths.get(System.getProperty("user.dir"))
} else {
Files.createTempDirectory("libanitorrent${Random.nextInt().absoluteValue}").apply {
Runtime.getRuntime().addShutdownHook(
Thread {
try {
deleteRecursively()
} catch (e: IOException) {
logger.error(e) { "Failed to delete temp directory $this" }
}
},
)
}
}
}

@Suppress("UnsafeDynamicallyLoadedCode")
private fun loadLibraryFromResources(
name: String,
tempDir: Path
) {
val filename = when (platform as Platform.Desktop) {
is Platform.Linux -> "lib$name.so"
is Platform.Windows -> "$name.dll"
is Platform.MacOS -> "lib$name.dylib"
}
this::class.java.classLoader?.getResourceAsStream(filename)?.use {
val tempFile = tempDir.resolve(filename)
tempFile.outputStream().use { output ->
it.copyTo(output)
}
System.load(tempFile.absolutePathString())
}
}

@Synchronized
@Throws(UnsatisfiedLinkError::class)
override fun loadLibraries() {
Expand Down

0 comments on commit 0918522

Please sign in to comment.