Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ nativeBuildTool := Meson.make(Nil)
|--------------------------------|---------------|
| automatic, when JniNative enabled | [JniPackage.scala](plugin/src/main/scala/com/github/sbt/jni/plugins/JniPackage.scala) |

This plugin packages native libraries produced by JniNative in a way that they can be transparently loaded with JniLoad. It uses the notion of a native "platform", defined as the architecture-kernel values returned by `uname -sm`. A native binary of a given platform is assumed to be executable on any machines of the same platform.
This plugin packages native libraries produced by JniNative in a way that they can be transparently loaded with JniLoad. It uses the notion of a native "platform", defined as the architecture-kernel values returned by `uname -sm`, or using the `os.name` and `os.arch` properties if the `uname` command is not available. A native binary of a given platform is assumed to be executable on any machines of the same platform.

## Canonical Use

Expand Down Expand Up @@ -325,7 +325,7 @@ Real-world use-cases of sbt-jni include:

- projects using `JniLoad` must use Scala versions 2.11, 2.12, 2.13 or 3.2
- projects using `JniLoad` with Scala 3 should use it with the `sbtJniCoreScope := Compile` SBT key set
- only POSIX platforms are supported (actually, any platform that has the `uname` command available)
- only POSIX platforms are supported

The goal of sbt-jni is to be the least intrusive possible. No transitive dependencies are added to projects using any plugin (some dependencies are added to the `provided` configuration, however these do not affect any downstream projects).

Expand Down
48 changes: 35 additions & 13 deletions core/src/main/scala-2/com/github/sbt/jni/annotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,8 @@ class nativeLoaderAnnotationMacro(val c: Context) {

val tmp: Path = Files.createTempDirectory("jni-")
val plat: String = {
val line = try {
scala.sys.process.Process("uname -sm").!!.linesIterator.next()
} catch {
case _: Exception => sys.error("Error running `uname` command")
}
val parts = line.split(" ")
if (parts.length != 2) {
sys.error("Could not determine platform: 'uname -sm' returned unexpected string: " + line)
} else {
val arch = parts(1).toLowerCase.replaceAll("\\s", "")
val kernel = parts(0).toLowerCase.replaceAll("\\s", "")
arch + "-" + kernel
}
val (kernel, arch) = determinePlatform()
arch + "-" + kernel
}

val resourcePath: String = "/native/" + plat + "/" + lib
Expand Down Expand Up @@ -83,6 +72,39 @@ class nativeLoaderAnnotationMacro(val c: Context) {
case _: UnsatisfiedLinkError => loadPackaged()
}

def determinePlatform(): (String, String) = {
try {
val line =
try {
scala.io.Source.fromString(scala.sys.process.Process("uname -sm").!!).getLines().next()
} catch {
case _: Exception => sys.error("Error running `uname` command")
}
val parts = line.split(" ")
if (parts.length != 2) {
sys.error("Could not determine platform: 'uname -sm' returned unexpected string: " + line)
} else {
val arch = parts(1).toLowerCase.replaceAll("\\s", "")
val kernel = parts(0).toLowerCase.replaceAll("\\s", "")
(arch, kernel)
}
} catch {
case _: Exception =>
val os = System.getProperty("os.name").toLowerCase match {
case s if s.contains("win") => "windows"
case s if s.contains("mac") => "darwin"
case _ => "linux"
}

val arch = System.getProperty("os.arch").toLowerCase match {
case "arm64" | "aarch64" => "arm64"
case _ => "x86_64"
}

(os, arch)
}
}

load()
}
"""
Expand Down
49 changes: 35 additions & 14 deletions core/src/main/scala/com/github/sbt/jni/syntax/NativeLoader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,8 @@ object NativeLoader {

val tmp: Path = Files.createTempDirectory("jni-")
val plat: String = {
val line =
try {
scala.io.Source.fromString(scala.sys.process.Process("uname -sm").!!).getLines().next()
} catch {
case _: Exception => sys.error("Error running `uname` command")
}
val parts = line.split(" ")
if (parts.length != 2) {
sys.error("Could not determine platform: 'uname -sm' returned unexpected string: " + line)
} else {
val arch = parts(1).toLowerCase.replaceAll("\\s", "")
val kernel = parts(0).toLowerCase.replaceAll("\\s", "")
arch + "-" + kernel
}
val (kernel, arch) = determinePlatform()
arch + "-" + kernel
}

val resourcePath: String = "/native/" + plat + "/" + lib
Expand Down Expand Up @@ -56,6 +44,39 @@ object NativeLoader {
case _: UnsatisfiedLinkError => loadPackaged()
}

def determinePlatform(): (String, String) = {
try {
val line =
try {
scala.io.Source.fromString(scala.sys.process.Process("uname -sm").!!).getLines().next()
} catch {
case _: Exception => sys.error("Error running `uname` command")
}
val parts = line.split(" ")
if (parts.length != 2) {
sys.error("Could not determine platform: 'uname -sm' returned unexpected string: " + line)
} else {
val arch = parts(1).toLowerCase.replaceAll("\\s", "")
val kernel = parts(0).toLowerCase.replaceAll("\\s", "")
(arch, kernel)
}
} catch {
case _: Exception =>
val os = System.getProperty("os.name").toLowerCase match {
case s if s.contains("win") => "windows"
case s if s.contains("mac") => "darwin"
case _ => "linux"
}

val arch = System.getProperty("os.arch").toLowerCase match {
case "arm64" | "aarch64" => "arm64"
case _ => "x86_64"
}

(os, arch)
}
}

load()
}
}
48 changes: 35 additions & 13 deletions plugin/src/main/scala/com/github/sbt/jni/plugins/JniNative.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,8 @@ object JniNative extends AutoPlugin {
// the value retruned must match that of `com.github.sbt.jni.PlatformMacros#current()` of project `macros`
nativePlatform := {
try {
val lines = Process("uname -sm").lineStream
if (lines.isEmpty) {
sys.error("Error occured trying to run `uname`")
}
// uname -sm returns "<kernel> <hardware name>"
val parts = lines.head.split(" ")
if (parts.length != 2) {
sys.error("'uname -sm' returned unexpected string: " + lines.head)
} else {
val arch = parts(1).toLowerCase.replaceAll("\\s", "")
val kernel = parts(0).toLowerCase.replaceAll("\\s", "")
arch + "-" + kernel
}
val (kernel, arch) = determinePlatform()
arch + "-" + kernel
} catch {
case _: Exception =>
sLog.value.error("Error trying to determine platform.")
Expand Down Expand Up @@ -155,6 +144,39 @@ object JniNative extends AutoPlugin {
}
)

private def determinePlatform(): (String, String) = {
try {
val line =
try {
scala.io.Source.fromString(scala.sys.process.Process("uname -sm").!!).getLines().next()
} catch {
case _: Exception => sys.error("Error running `uname` command")
}
val parts = line.split(" ")
if (parts.length != 2) {
sys.error("Could not determine platform: 'uname -sm' returned unexpected string: " + line)
} else {
val arch = parts(1).toLowerCase.replaceAll("\\s", "")
val kernel = parts(0).toLowerCase.replaceAll("\\s", "")
(arch, kernel)
}
} catch {
case _: Exception =>
val os = System.getProperty("os.name").toLowerCase match {
case s if s.contains("win") => "windows"
case s if s.contains("mac") => "darwin"
case _ => "linux"
}

val arch = System.getProperty("os.arch").toLowerCase match {
case "arm64" | "aarch64" => "arm64"
case _ => "x86_64"
}

(os, arch)
}
}

override lazy val projectSettings = settings

}
Loading