diff options
-rw-r--r-- | README.md | 10 | ||||
-rw-r--r-- | build.sbt | 0 | ||||
-rw-r--r-- | flow-main/src/main/scala/com/github/jodersky/flow/internal/NativeLoader.scala | 40 | ||||
-rw-r--r-- | flow-samples/rwc/README (renamed from samples/rwc/README) | 0 | ||||
-rw-r--r-- | flow-samples/rwc/src/main/scala/com/github/jodersky/flow/example/Main.scala (renamed from samples/rwc/src/main/scala/com/github/jodersky/flow/example/Main.scala) | 0 | ||||
-rw-r--r-- | flow-samples/rwc/src/main/scala/com/github/jodersky/flow/example/SerialHandler.scala (renamed from samples/rwc/src/main/scala/com/github/jodersky/flow/example/SerialHandler.scala) | 0 | ||||
-rw-r--r-- | project/Build.scala | 41 | ||||
-rw-r--r-- | project/Dependencies.scala | 5 | ||||
-rw-r--r-- | project/Jni.scala | 5 | ||||
-rw-r--r-- | samples/arduino/README | 1 |
10 files changed, 63 insertions, 39 deletions
@@ -14,6 +14,16 @@ To see an example, switch to project 'flow-rwc' and then type 'run'. Don't forge The build currently only works on Linux. +### Project structure +flow +├── flow-main //main scala/java sources +├── flow-native //native sources +│ ├── include //general headers +│ └── unix //source code for unix-like systems +├── flow-samples +├── project +└── README.md + ## License Copyright (c) 2013 by Jakob Odersky diff --git a/build.sbt b/build.sbt deleted file mode 100644 index e69de29..0000000 --- a/build.sbt +++ /dev/null diff --git a/flow-main/src/main/scala/com/github/jodersky/flow/internal/NativeLoader.scala b/flow-main/src/main/scala/com/github/jodersky/flow/internal/NativeLoader.scala index aebbe3f..23314f1 100644 --- a/flow-main/src/main/scala/com/github/jodersky/flow/internal/NativeLoader.scala +++ b/flow-main/src/main/scala/com/github/jodersky/flow/internal/NativeLoader.scala @@ -2,35 +2,37 @@ package com.github.jodersky.flow.internal import java.io.File import java.io.FileOutputStream +import scalax.file.Path +import scalax.io.Resource +import scala.util.Try /**Loads the current system's native library for flow. */ object NativeLoader { - def load = { + def extract(): Option[File] = { val os = System.getProperty("os.name").toLowerCase val arch = System.getProperty("os.arch").toLowerCase + val fqlib = System.mapLibraryName("flow") //fully qualified library name - val in = NativeLoader.getClass().getResourceAsStream("/native/" + os + "/" + arch + "/" + "libflow.so") - val temp = File.createTempFile("flow" + os + arch, ".so"); - temp.deleteOnExit() - val out = new FileOutputStream(temp); + val in = NativeLoader.getClass().getResourceAsStream(s"/native/${os}/${arch}/${fqlib}") + if (in == null) return None - try { - var read: Int = 0; ; - val buffer = new Array[Byte](4096); - do { - read = in.read(buffer) - if (read != -1) { - out.write(buffer, 0, read); - } - } while (read != -1) - } finally { - in.close() - out.close - } + val temp = Path.createTempFile() + Resource.fromInputStream(in).copyDataTo(temp) + temp.fileOption + } - System.load(temp.getAbsolutePath()) + def loadFromJar() = extract() match { + case Some(file) => System.load(file.getAbsolutePath) + case None => throw new UnsatisfiedLinkError("cannot extract native library, the native library may not exist for your specific system/architecture combination") + } + def load = { + try { + System.loadLibrary("flow") + } catch { + case ex: UnsatisfiedLinkError => loadFromJar() + } } }
\ No newline at end of file diff --git a/samples/rwc/README b/flow-samples/rwc/README index 843e38d..843e38d 100644 --- a/samples/rwc/README +++ b/flow-samples/rwc/README diff --git a/samples/rwc/src/main/scala/com/github/jodersky/flow/example/Main.scala b/flow-samples/rwc/src/main/scala/com/github/jodersky/flow/example/Main.scala index 518efc2..518efc2 100644 --- a/samples/rwc/src/main/scala/com/github/jodersky/flow/example/Main.scala +++ b/flow-samples/rwc/src/main/scala/com/github/jodersky/flow/example/Main.scala diff --git a/samples/rwc/src/main/scala/com/github/jodersky/flow/example/SerialHandler.scala b/flow-samples/rwc/src/main/scala/com/github/jodersky/flow/example/SerialHandler.scala index e616763..e616763 100644 --- a/samples/rwc/src/main/scala/com/github/jodersky/flow/example/SerialHandler.scala +++ b/flow-samples/rwc/src/main/scala/com/github/jodersky/flow/example/SerialHandler.scala diff --git a/project/Build.scala b/project/Build.scala index c08e766..55002d4 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -9,7 +9,7 @@ import Jni._ object FlowBuild extends Build { val Organization = "com.github.jodersky" val Version = "1.0-SNAPSHOT" //version of flow library - val BinaryMajorVersion = 1 //binary major (api-level) version used to select so's and dlls when publishing + val BinaryMajorVersion = 1 //binary major version used to select so's and dlls when publishing (needs to be incremented if API changes are made to flow.h or NativeSerial.java) val ScalaVersion = "2.10.1" lazy val commonSettings: Seq[Setting[_]] = Seq( @@ -22,32 +22,43 @@ object FlowBuild extends Build { lazy val runSettings: Seq[Setting[_]] = Seq( fork := true, connectInput in run := true) + lazy val main: Project = ( Project("flow-main", file("flow-main")) settings (commonSettings: _*) settings ( - libraryDependencies += Dependencies.akka, - compileOrder in Compile := CompileOrder.Mixed + libraryDependencies ++= Seq( + Dependencies.akkaActor, + Dependencies.ioCore, + Dependencies.ioFile), + compileOrder in Compile := CompileOrder.Mixed, + resourceGenerators in Compile <+= (resourceManaged in Compile, link in Native in LocalProject("flow-native-linux")) map { (resDir, binary) => + val file = resDir / "native" / sys.props("os.name").toLowerCase / sys.props("os.arch").toLowerCase / binary.getName + IO.copyFile(binary, file) + Seq(file) + } ) ) - lazy val samples = ( - Project("flow-samples-rwc", file("samples") / "rwc") + lazy val rwc = ( + Project("flow-samples-rwc", file("flow-samples") / "rwc") settings(commonSettings: _*) settings(runSettings: _*) dependsOn(main) ) - - //---native projects -------------------------------------------------- + + //--- native settings -------------------------------------------------- lazy val commonNativeSettings: Seq[Setting[_]] = Seq( includeDirectories in Native += file("flow-native") / "include", + nativeCompile in Native := ((nativeCompile in Native) dependsOn (compile in Compile in main)).value, + javahClasspath := Seq((classDirectory in Compile in main).value), javahClasses := Seq("com.github.jodersky.flow.internal.NativeSerial")) ++ Jni.defaultSettings - //---native unix like settings ---------------------------------------- + //--- native unix like settings ---------------------------------------- val UnixBinaryName = "flow" val UnixBinaryMinorVersion = 0 @@ -55,18 +66,20 @@ object FlowBuild extends Build { lazy val unixNativeSettings: Seq[Setting[_]] = commonNativeSettings ++ Seq( flags in Native := Seq("-fPIC", "-O2"), linkFlags in Native ++= Seq("-shared", s"-Wl,-soname,lib${UnixBinaryName}.so.${BinaryMajorVersion}"), - binaryName in Native := s"lib${UnixBinaryName}.so.${BinaryMajorVersion}.${UnixBinaryMinorVersion}") + binaryName in Native := s"lib${UnixBinaryName}.so.${BinaryMajorVersion}.${UnixBinaryMinorVersion}", + version := s"${BinaryMajorVersion}.${UnixBinaryMinorVersion}-${sys.props("os.name").toLowerCase}-${sys.props("os.arch").toLowerCase}", + nativeSource in Native := baseDirectory.value / "src") lazy val nativeLinux = ( NativeProject("flow-native-linux", file("flow-native") / "unix") settings (unixNativeSettings: _*) settings ( - nativeSource in Native := baseDirectory.value / "src", includeDirectories in Native += jdkHome.value / "include" / "linux" ) dependsOn (main) ) - + + /* Seq( libraryDependencies ++= Dependencies.all, @@ -76,11 +89,7 @@ object FlowBuild extends Build { binaryName in Native := "flow", options in Native := Seq("-fPIC", "-O2"), linkOptions in Native := Seq("-Wl,-soname,libflow.so.1"), - resourceGenerators in Compile <+= (resourceManaged in Compile, link in Native) map { (resDir, binary) => - val file = resDir / "native" / sys.props("os.name").toLowerCase / sys.props("os.arch").toLowerCase / binary.getName - IO.copyFile(binary, file) - Seq(file) - } + ) ++ Jni.defaultSettings * */ diff --git a/project/Dependencies.scala b/project/Dependencies.scala index a705cf3..aa3aa36 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,6 +2,9 @@ import sbt._ object Dependencies { - lazy val akka = "com.typesafe.akka" %% "akka-actor" % "2.2-M3" + lazy val akkaActor = "com.typesafe.akka" %% "akka-actor" % "2.2-M3" + + lazy val ioCore = "com.github.scala-incubator.io" %% "scala-io-core" % "0.4.2" + lazy val ioFile = "com.github.scala-incubator.io" %% "scala-io-file" % "0.4.2" }
\ No newline at end of file diff --git a/project/Jni.scala b/project/Jni.scala index d597269..db345e2 100644 --- a/project/Jni.scala +++ b/project/Jni.scala @@ -6,18 +6,19 @@ object Jni { val jdkHome = settingKey[File]("Home of JDK.") val javahHeaderDirectory = settingKey[File]("Directory where generated javah header files are placed.") val javahClasses = settingKey[Seq[String]]("Fully qualified names of classes containing native declarations.") + val javahClasspath = taskKey[Seq[File]]("Classpath to use in javah.") val javah = taskKey[Seq[File]]("Generate JNI headers.") val defaultSettings: Seq[Setting[_]] = Seq( jdkHome := file(sys.env("JAVA_HOME")), javahHeaderDirectory := (sourceManaged in Native).value / "javah", - javah := javahImpl.value, + javah := javahImpl.value, sourceGenerators in Native <+= javah map { headers => headers}, includeDirectories in Native += javahHeaderDirectory.value, includeDirectories in Native += jdkHome.value / "include") def javahImpl = Def.task { - val cps = (internalDependencyClasspath in Compile).value.map(_.data).map(_.getAbsolutePath) + val cps = javahClasspath.value val cp = cps.mkString(":") for (clazz <- javahClasses.value) { val parts = Seq( diff --git a/samples/arduino/README b/samples/arduino/README deleted file mode 100644 index 64c8a5c..0000000 --- a/samples/arduino/README +++ /dev/null @@ -1 +0,0 @@ -Code to run on an arduino for serial communication testing. |