aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jodersky@gmail.com>2014-04-18 19:36:21 +0200
committerJakob Odersky <jodersky@gmail.com>2014-04-18 19:36:21 +0200
commit2b8d4feff9a342910192218a33fc9880abc1f33d (patch)
treeeb1f0484ccf44572ec5a2394a00bf299f46396bf
parent6f24c31168b2700504dd81bcd5aff278e3353fef (diff)
downloadakka-serial-2b8d4feff9a342910192218a33fc9880abc1f33d.tar.gz
akka-serial-2b8d4feff9a342910192218a33fc9880abc1f33d.tar.bz2
akka-serial-2b8d4feff9a342910192218a33fc9880abc1f33d.zip
reinstore native jars
-rw-r--r--flow/src/main/java/com/github/jodersky/flow/internal/NativeSerial.java2
-rw-r--r--flow/src/main/scala/com/github/jodersky/flow/internal/NativeLoader.scala40
-rw-r--r--project/Dependencies.scala3
-rw-r--r--project/FlowBuild.scala16
-rw-r--r--project/native.scala82
-rw-r--r--project/nativeFat.scala69
6 files changed, 135 insertions, 77 deletions
diff --git a/flow/src/main/java/com/github/jodersky/flow/internal/NativeSerial.java b/flow/src/main/java/com/github/jodersky/flow/internal/NativeSerial.java
index 22306e0..c159058 100644
--- a/flow/src/main/java/com/github/jodersky/flow/internal/NativeSerial.java
+++ b/flow/src/main/java/com/github/jodersky/flow/internal/NativeSerial.java
@@ -25,7 +25,7 @@ import com.github.jodersky.flow.PortInterruptedException;
final class NativeSerial {
static {
- System.loadLibrary("flow3");
+ NativeLoader.load("flow3");
}
final static int PARITY_NONE = 0;
diff --git a/flow/src/main/scala/com/github/jodersky/flow/internal/NativeLoader.scala b/flow/src/main/scala/com/github/jodersky/flow/internal/NativeLoader.scala
new file mode 100644
index 0000000..8fe1e3b
--- /dev/null
+++ b/flow/src/main/scala/com/github/jodersky/flow/internal/NativeLoader.scala
@@ -0,0 +1,40 @@
+package com.github.jodersky.flow.internal
+
+import java.io.File
+import scalax.file.Path
+import scalax.io.Resource
+import java.security.CodeSource
+import java.util.zip.ZipEntry
+import java.util.zip.ZipInputStream
+import java.net.URL
+
+/** Handles loading of the current platform's native library for flow. */
+object NativeLoader {
+
+ private def os = System.getProperty("os.name").toLowerCase.filter(_ != ' ')
+
+ private def arch = System.getProperty("os.arch").toLowerCase
+
+ private def extractNative(nativeLibrary: String): Option[File] = {
+ val fqlib = System.mapLibraryName(nativeLibrary) //fully qualified library name
+
+ val in = NativeLoader.getClass().getResourceAsStream(s"/native/${os}-${arch}/${fqlib}")
+ if (in == null) return None
+
+ val temp = Path.createTempFile(nativeLibrary)
+ Resource.fromInputStream(in).copyDataTo(temp)
+ temp.fileOption
+ }
+
+ private def loadFromJar(nativeLibrary: String) = extractNative(nativeLibrary) match {
+ case Some(file) => System.load(file.getAbsolutePath)
+ case None => throw new UnsatisfiedLinkError("Cannot extract flow's native library, the native library may not exist for your specific architecture/OS combination.")
+ }
+
+ def load(nativeLibrary: String) = try {
+ System.loadLibrary(nativeLibrary)
+ } catch {
+ case ex: UnsatisfiedLinkError => loadFromJar(nativeLibrary)
+ }
+
+} \ No newline at end of file
diff --git a/project/Dependencies.scala b/project/Dependencies.scala
index b9d5cb9..9590394 100644
--- a/project/Dependencies.scala
+++ b/project/Dependencies.scala
@@ -4,4 +4,7 @@ object Dependencies {
lazy val akkaActor = "com.typesafe.akka" %% "akka-actor" % "2.2.0"
+ lazy val ioCore = "com.github.scala-incubator.io" %% "scala-io-file" % "0.4.2"
+ lazy val ioFile = "com.github.scala-incubator.io" %% "scala-io-file" % "0.4.2"
+
}
diff --git a/project/FlowBuild.scala b/project/FlowBuild.scala
index e7a21d7..688743b 100644
--- a/project/FlowBuild.scala
+++ b/project/FlowBuild.scala
@@ -65,15 +65,15 @@ object FlowBuild extends Build {
settings (commonSettings: _*)
settings (publishSettings: _*)
settings (JniDefaults.settings: _*)
+ settings(NativeDefaults.settings: _*)
settings(
- javahHeaderDirectory := (baseDirectory in ThisBuild).value / "flow-native" / "include",
+ nativeBuildDirectory := (baseDirectory in ThisBuild).value / "flow-native",
+ javahHeaderDirectory := nativeBuildDirectory.value / "src",
javahClasses := Seq("com.github.jodersky.flow.internal.NativeSerial"),
compileOrder in Compile := CompileOrder.Mixed,
- libraryDependencies += Dependencies.akkaActor
- )
- settings(NativeDefaults.settings: _*)
- settings(
- nativeBuildDirectory := (baseDirectory in ThisBuild).value / "flow-native"
+ libraryDependencies += Dependencies.akkaActor,
+ libraryDependencies += Dependencies.ioCore,
+ libraryDependencies += Dependencies.ioFile
)
)
@@ -81,7 +81,9 @@ object FlowBuild extends Build {
Project("flow-samples-terminal", file("flow-samples") / "flow-samples-terminal")
settings(commonSettings: _*)
settings(runSettings: _*)
- //dependsOn(flowPack)
+ settings(
+ unmanagedJars in Compile += (nativePackage in flow).value
+ )
dependsOn(flow)
)
diff --git a/project/native.scala b/project/native.scala
new file mode 100644
index 0000000..84537a3
--- /dev/null
+++ b/project/native.scala
@@ -0,0 +1,82 @@
+import sbt._
+import Keys._
+import java.io.File
+import java.util.jar.Manifest
+
+object NativeKeys {
+
+ val nativeBuildDirectory = settingKey[File]("Directory containing native build scripts.")
+ val nativeTargetDirectory = settingKey[File]("Base directory to store native products.")
+ val nativeOutputDirectory = settingKey[File]("Actual directory where native products are stored.")
+ val nativePackageUnmanagedDirectory = settingKey[File]("Directory containing external products that will be copied to the native jar.")
+ val nativePackageArtifact = settingKey[Artifact]("Native artifact.")
+
+
+ val nativeBuild = taskKey[File]("Invoke native build.")
+ val nativePackage = taskKey[File]("Package native products into a jar.")
+
+}
+
+object NativeDefaults {
+ import NativeKeys._
+
+ val autoLib = Def.task {
+ val log = streams.value.log
+ val build = nativeBuildDirectory.value
+ val out = nativeOutputDirectory.value
+
+ val configure = Process(
+ "./configure " +
+ "--prefix=" + out.getAbsolutePath + " " +
+ "--libdir=" + out.getAbsolutePath + " " +
+ "--disable-versioned-lib",
+ build)
+
+ val make = Process("make", build)
+
+ val makeInstall = Process("make install", build)
+
+ val ev = configure #&& make #&& makeInstall ! log
+ if (ev != 0)
+ throw new RuntimeException(s"Building native library failed.")
+
+ (out ** ("*.la")).get.foreach(_.delete())
+
+ out
+ }
+
+ val nativePackageImpl = Def.task {
+ val managedDir = nativeTargetDirectory.value
+ val unmanagedDir = nativePackageUnmanagedDirectory.value
+
+ val managed = (nativeBuild.value ** "*").get
+ val unmanaged = (unmanagedDir ** "*").get
+
+ val jarFile = nativeTargetDirectory.value / (name.value + "-" + version.value + "-native.jar")
+
+ val managedMappings: Seq[(File, String)] = for (file <- managed; if file.isFile) yield {
+ file -> ("native/" + (file relativeTo managedDir).get.getPath)
+ }
+
+ val unmanagedMappings: Seq[(File, String)] = for (file <- unmanaged; if file.isFile) yield {
+ file -> ("native/" + (file relativeTo unmanagedDir).get.getPath)
+ }
+
+ IO.jar(managedMappings ++ unmanagedMappings, jarFile, new Manifest())
+ jarFile
+ }
+
+ def os = System.getProperty("os.name").toLowerCase.filter(_ != ' ')
+ def arch = System.getProperty("os.arch").toLowerCase
+
+ val settings: Seq[Setting[_]] = Seq(
+ nativeTargetDirectory := target.value / "native",
+ nativeOutputDirectory := nativeTargetDirectory.value / (os + "-" + arch),
+ nativeBuild := autoLib.value,
+ nativePackage := nativePackageImpl.value,
+ nativePackageArtifact := Artifact(name.value, "native"),
+ nativePackageUnmanagedDirectory := baseDirectory.value / "lib_native"
+ ) ++ addArtifact(nativePackageArtifact, nativePackage).settings
+
+}
+
diff --git a/project/nativeFat.scala b/project/nativeFat.scala
deleted file mode 100644
index 55df06d..0000000
--- a/project/nativeFat.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-import sbt._
-import Keys._
-import java.io.File
-
-object NativeKeys {
-
- val nativeBuildDirectory = settingKey[File]("Directory containing native build scripts.")
- val nativeTarget = settingKey[File]("Target directory to store native artifacts.")
-
- val nativeBuild = taskKey[File]("Invoke native build.")
-
- val nativePackUnmanaged = settingKey[File]("")
-}
-
-object NativeDefaults {
- import NativeKeys._
-
- val nativeBuildImpl = Def.task {
- val log = streams.value.log
- val build = nativeBuildDirectory.value
- val target = nativeTarget.value
-
- val configure = Process(
- "./configure " +
- "--prefix=" + target.getAbsolutePath + " " +
- "--libdir=" + target.getAbsolutePath,
- Some(build))
-
- val make = Process("make", build)
-
- val makeInstall = Process("make install", build)
-
- val ev = configure #&& make #&& makeInstall ! log
- if (ev != 0)
- throw new RuntimeException(s"Building native library failed.")
-
- (target ** ("*.la")).get.foreach(_.delete())
-
- target
- }
-
-
- val mappingsImpl = Def.task {
- val files = (nativeBuild.value ** "*").get
- val unamanagedDir = nativePackUnmanaged.value
-
- val managed: Seq[(File, String)] = for (file <- files; if file.isFile) yield {
- file -> ("native/" + (file relativeTo nativeTarget.value).get.getPath)
- }
-
- val unmanaged: Seq[(File, String)] = for (file <- (unamanagedDir ** "*").get; if file.isFile) yield {
- file -> ("native/" + (file relativeTo unamanagedDir).get.getPath)
- }
-
- managed ++ unmanaged
- }
-
- def os = System.getProperty("os.name").toLowerCase.filter(_ != ' ')
- def arch = System.getProperty("os.arch").toLowerCase
-
- val settings: Seq[Setting[_]] = Seq(
- nativeTarget := target.value / "native" / (os + "-" + arch),
- nativeBuild := nativeBuildImpl.value,
- nativePackUnmanaged := baseDirectory.value / "lib_native",
- mappings in (Compile, packageBin) ++= mappingsImpl.value
- )
-
-}
-