aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jakob@odersky.com>2016-05-13 10:18:39 -0700
committerJakob Odersky <jakob@odersky.com>2016-05-13 12:14:14 -0700
commit83f5dfdf479012fd1d4a3e7006e58dc81528b8de (patch)
tree52a4e350e0df72b778f41413065f662d28fd769f
parent7613a55cc05a981736c25b431031efc0c6dd8278 (diff)
downloadsbt-jni-83f5dfdf479012fd1d4a3e7006e58dc81528b8de.tar.gz
sbt-jni-83f5dfdf479012fd1d4a3e7006e58dc81528b8de.tar.bz2
sbt-jni-83f5dfdf479012fd1d4a3e7006e58dc81528b8de.zip
Update README and formatting
-rw-r--r--README.md51
-rw-r--r--plugin/src/main/scala/ch/jodersky/sbt/jni/build/BuildTool.scala1
-rw-r--r--plugin/src/main/scala/ch/jodersky/sbt/jni/plugins/JniLoad.scala1
3 files changed, 30 insertions, 23 deletions
diff --git a/README.md b/README.md
index 57455aa..33ca3a2 100644
--- a/README.md
+++ b/README.md
@@ -23,17 +23,16 @@ The second point, portability, is inherent to JNI and thus unavoidable. However
| JniJavah | Adds support for generating headers from classfiles that have `@native` methods. |
| JniLoad | Makes `@nativeLoader` annotation available, that injects code to transparently load native libraries. |
| JniNative | Adds sbt wrapper tasks around native build tools to ease building and integrating native libraries. |
-| JniPackage | Packages native libraries into multi-platform fat jars. No more manual library path configuration! |
+| JniPackage | Packages native libraries into multi-platform fat jars. No more manual library installation! |
-All plugins are made available by adding
+All plugins are made available with the following sbt configuration
```scala
-resolvers += Resolver.jcenterRepo
addSbtPlugin("ch.jodersky" % "sbt-jni" % "1.0.0-RC1")
```
-to `project/plugins.sbt`.
+in `project/plugins.sbt`.
-Note that most plugins are enabled in projects by default. Disabling their functionality can be achieved by adding `disablePlugin(<plugin>)` to the corresponding project definition (for example, to disable packaging native libraries).
+Note that most plugins are enabled in projects by default. Disabling their functionality can be achieved by adding `disablePlugin(<plugin>)` to the corresponding project definition (for example, should you wish to disable packaging of native libraries).
## Plugin Details
@@ -78,7 +77,7 @@ Note that native methods declared both in Scala and Java are supported. Whereas
|--------------------------------|---------------|
| automatic, for all projects | [JniLoad.scala](plugin/src/main/scala/ch/jodersky/sbt/jni/plugins/JniLoad.scala) |
-This plugin enables loading native libraries in a safe and transparent manner to the developer (no more explicit, static `System.load("library")` calls required). It does so by providing a class annotation which injects native loading code to all its annottees. Furthermore, in case a native library is not available on the current `java.library.path`, the code injected by the annotation will fall back to loading native libraries packaged according to the rules of `JniPackage` and available on the classpath.
+This plugin enables loading native libraries in a safe and transparent manner to the developer (no more explicit, static `System.load("library")` calls required). It does so by providing a class annotation which injects native loading code to all its annottees. Furthermore, in case a native library is not available on the current `java.library.path`, the code injected by the annotation will fall back to loading native libraries packaged according to the rules of `JniPackage`.
Example use:
```scala
@@ -97,8 +96,7 @@ object Main extends App {
}
```
-Note: this plugin is just shorthand for adding `sbt-jni-macros` and `scala macros paradise` projects as provided dependencies.
-Projects must use Scala versions 2.11 or 2.12.0-M4.
+Note: this plugin is just a shorthand for adding `sbt-jni-macros` (the project in `macros/`) and the scala-macros-paradise projects as provided dependencies. Projects must use Scala versions 2.11 or 2.12.0-M4.
See the [annotation's implementation](macros/src/main/scala/ch/jodersky/sbt/jni/annotations.scala) for details about the injected code.
@@ -118,36 +116,42 @@ TODO: explanation
## Canonical Use
+*Keep in mind that sbt-jni is a _suite_ of plugins, there are many other use cases. This is a just a description of the most common one.*
+
1. Define separate sub-projects for JVM and native sources. In `myproject/build.sbt`:
```scala
- lazy val core = project in file("myproject-core"). // contains regular jvm sources and @native methods
+ lazy val core = project in file("myproject-core"). // regular scala code with @native methods
dependsOn(native % Runtime) // natives only required for running, compilation can be done without
- lazy val native = project in file("myproject-native"). // contains native sources
- enablePlugin(JniNative)
+ lazy val native = project in file("myproject-native"). // native code and build script
+ enablePlugin(JniNative) // JniNative needs to be explicitly enabled
```
- Note that separate projects are not strictly required. They are recommended nevertheless, as a portability-convenience tradeoff: programs
- written in a jvm language are expected to run anywhere without recompilation, but including native libraries in jars limits this portability
- to only platforms of the packaged libraries.
+ Note that separate projects are not strictly required. They are recommended nevertheless, as a portability-convenience tradeoff: programs written in a JVM language are expected to run anywhere without recompilation, but including native libraries in jars limits this portability to only platforms of the packaged libraries. Having a separate native project enables the users to easily swap out the native library with their own implementation.
+
+2. Initialize the native build tool from a template:
+
+ Run `sbt nativeInit cmake <libname>`
-2. Initialize the native build tool from a template: `sbt nativeInit cmake <libname>`
+3. Implement core project:
-3. Implement core project: *just a regular scala project*
+ This step is identical to building a regular scala project, with the addition that some classes will also contain `@native` methods.
-4. Generate native headers: `sbt javah`
+4. Generate native headers:
-5. Implement native headers in library: *project specific, see examples*
+ Run `sbt javah`
+
+5. Implement native headers:
+
+ The function prototypes in the header files must be implemented in native code (such as C, C++) and built into a shared library. Run `sbt nativeCompile` to call the native build tool and build a shared library.
6. Build/run/test:
- - Library: `publish`
- - Application: `core/run`
+ At this point, the project can be tested and run as any standard sbt project. For example, you can publish your project as a library (`sbt publish`), run it (`sbt core/run`) or simply run unit tests (`sbt test`). Packaging and recompiling of the native library will happen transparently.
7. Develop:
- - Re-run `javah` only if `@native` methods changed
- - Otherwise, go to 6
+ The usual iterative development process. Nothing speial needs to be done, except in case any `@native` methods are added/removed or their signature changed, then `sbt javah` needs to be run again.
## Examples
The [plugins' unit tests](plugin/src/sbt-test/sbt-jni) offer some simple examples. They can be run individually through these steps:
@@ -157,6 +161,7 @@ The [plugins' unit tests](plugin/src/sbt-test/sbt-jni) offer some simple example
3. Follow the instructions in the `test` file (only enter the lines that start with ">" into sbt).
Real-world use-cases of sbt-jni include:
+
- [serial communication library for scala](https://jodersky.github.io/flow)
## Building
@@ -167,7 +172,7 @@ Both the macro library (`sbt-jni-macros`) and the sbt plugins (`sbt-jni`) are pu
The differing Scala versions make it necessary to always cross-compile and cross-publish this project, i.e. append a "+" before every task.
-Run `+publishLocal` to build and use this plugin locally.
+Run `sbt +publishLocal` to build and use this plugin locally.
## Copying
This project is released under the terms of the 3-clause BSD license. See LICENSE for details.
diff --git a/plugin/src/main/scala/ch/jodersky/sbt/jni/build/BuildTool.scala b/plugin/src/main/scala/ch/jodersky/sbt/jni/build/BuildTool.scala
index 3d0deb1..e1163f1 100644
--- a/plugin/src/main/scala/ch/jodersky/sbt/jni/build/BuildTool.scala
+++ b/plugin/src/main/scala/ch/jodersky/sbt/jni/build/BuildTool.scala
@@ -5,6 +5,7 @@ import java.io.{ File, InputStream }
import java.nio.file.Files
import scala.io.Source
+
import sbt.Logger
trait BuildTool {
diff --git a/plugin/src/main/scala/ch/jodersky/sbt/jni/plugins/JniLoad.scala b/plugin/src/main/scala/ch/jodersky/sbt/jni/plugins/JniLoad.scala
index 51d9c7b..9f88dbb 100644
--- a/plugin/src/main/scala/ch/jodersky/sbt/jni/plugins/JniLoad.scala
+++ b/plugin/src/main/scala/ch/jodersky/sbt/jni/plugins/JniLoad.scala
@@ -16,6 +16,7 @@ object JniLoad extends AutoPlugin {
addCompilerPlugin(
"org.scalamacros" % "paradise" % ProjectVersion.MacrosParadise cross CrossVersion.full
),
+ resolvers += Resolver.jcenterRepo,
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value % Provided,
libraryDependencies += "ch.jodersky" %% "sbt-jni-macros" % ProjectVersion.Macros % Provided
)