All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmMain.app.cash.zipline.QuickJsNativeLoader.kt Maven / Gradle / Ivy

/*
 * Copyright (C) 2021 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package app.cash.zipline

import java.io.IOException
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardCopyOption.REPLACE_EXISTING
import java.util.Locale.US

@Suppress("UnsafeDynamicallyLoadedCode") // Only loading from our own JAR contents.
internal actual fun loadNativeLibrary() {
  val osName = System.getProperty("os.name").lowercase(US)
  val osArch = System.getProperty("os.arch").lowercase(US)

  val targetOs = when {
    osName.startsWith("linux") -> "linux"
    osName.startsWith("mac") -> "macos"
    osName.startsWith("win") -> "windows"
    else -> throw IllegalStateException("Unsupported OS: $osName ($osArch)")
  }

  val targetArch = when (osArch) {
    "x86_64", "amd64" -> "x64"
    "aarch64", "arm64" -> "arm64"
    else -> throw IllegalStateException("Unsupported Arch: $osName ($osArch)")
  }

  val file = when {
    osName.startsWith("mac") -> "libquickjs.dylib"
    osName.startsWith("win") -> "libquickjs.dll"
    else -> "libquickjs.so"
  }

  val nativeLibraryJarPath = "/jni/$targetOs/$targetArch/$file"
  val nativeLibraryUrl = QuickJs::class.java.getResource(nativeLibraryJarPath)
    ?: throw IllegalStateException("Unable to read $nativeLibraryJarPath from JAR")
  val nativeLibraryFile: Path
  try {
    nativeLibraryFile = Files.createTempFile("quickjs", null)

    // File-based deleteOnExit() uses a special internal shutdown hook that always runs last.
    nativeLibraryFile.toFile().deleteOnExit()
    nativeLibraryUrl.openStream().use { nativeLibrary ->
      Files.copy(nativeLibrary, nativeLibraryFile, REPLACE_EXISTING)
    }
  } catch (e: IOException) {
    throw RuntimeException("Unable to extract native library from JAR", e)
  }
  System.load(nativeLibraryFile.toAbsolutePath().toString())
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy