Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove dependency on uname command #234

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
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
Next Next commit
remove dependency on uname command
Martomate committed Jan 1, 2025
commit 2ed343b115ceee0ad3aad7dd511c96685a015360
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -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 using the `os.name` and `os.arch` properties. A native binary of a given platform is assumed to be executable on any machines of the same platform.

## Canonical Use

@@ -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).

30 changes: 17 additions & 13 deletions core/src/main/scala-2/com/github/sbt/jni/annotations.scala
Original file line number Diff line number Diff line change
@@ -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
@@ -83,6 +72,21 @@ class nativeLoaderAnnotationMacro(val c: Context) {
case _: UnsatisfiedLinkError => loadPackaged()
}

def determinePlatform(): (String, String) = {
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()
}
"""
31 changes: 17 additions & 14 deletions core/src/main/scala/com/github/sbt/jni/syntax/NativeLoader.scala
Original file line number Diff line number Diff line change
@@ -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
@@ -56,6 +44,21 @@ object NativeLoader {
case _: UnsatisfiedLinkError => loadPackaged()
}

def determinePlatform(): (String, String) = {
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()
}
}
30 changes: 17 additions & 13 deletions plugin/src/main/scala/com/github/sbt/jni/plugins/JniNative.scala
Original file line number Diff line number Diff line change
@@ -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.")
@@ -155,6 +144,21 @@ object JniNative extends AutoPlugin {
}
)

private def determinePlatform(): (String, String) = {
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

}