From 791cb363b77332e3abdf4039102dfcdb863ce6c3 Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Mon, 2 May 2016 05:19:07 -0700 Subject: Use macro annotation to load native library This also removes the need for third projects to depend on a "loader library". --- plugin/src/sbt-test/sbt-jni/multiclasses/README.md | 1 + plugin/src/sbt-test/sbt-jni/multiclasses/build.sbt | 16 ++++++ .../core/src/main/scala/multiclasses/Adder.scala | 18 +++++++ .../core/src/main/scala/multiclasses/Main.scala | 30 +++++++++++ .../src/main/scala/multiclasses/Multiplier.scala | 12 +++++ .../multiclasses/native1/src/CMakeLists.txt | 61 ++++++++++++++++++++++ .../sbt-jni/multiclasses/native1/src/library.c | 28 ++++++++++ .../multiclasses/native2/src/CMakeLists.txt | 61 ++++++++++++++++++++++ .../sbt-jni/multiclasses/native2/src/library.c | 16 ++++++ .../multiclasses/project/ScriptedHelper.scala | 1 + .../sbt-jni/multiclasses/project/plugins.sbt | 1 + plugin/src/sbt-test/sbt-jni/multiclasses/test | 2 + 12 files changed, 247 insertions(+) create mode 100644 plugin/src/sbt-test/sbt-jni/multiclasses/README.md create mode 100644 plugin/src/sbt-test/sbt-jni/multiclasses/build.sbt create mode 100644 plugin/src/sbt-test/sbt-jni/multiclasses/core/src/main/scala/multiclasses/Adder.scala create mode 100644 plugin/src/sbt-test/sbt-jni/multiclasses/core/src/main/scala/multiclasses/Main.scala create mode 100644 plugin/src/sbt-test/sbt-jni/multiclasses/core/src/main/scala/multiclasses/Multiplier.scala create mode 100644 plugin/src/sbt-test/sbt-jni/multiclasses/native1/src/CMakeLists.txt create mode 100644 plugin/src/sbt-test/sbt-jni/multiclasses/native1/src/library.c create mode 100644 plugin/src/sbt-test/sbt-jni/multiclasses/native2/src/CMakeLists.txt create mode 100644 plugin/src/sbt-test/sbt-jni/multiclasses/native2/src/library.c create mode 120000 plugin/src/sbt-test/sbt-jni/multiclasses/project/ScriptedHelper.scala create mode 120000 plugin/src/sbt-test/sbt-jni/multiclasses/project/plugins.sbt create mode 100644 plugin/src/sbt-test/sbt-jni/multiclasses/test (limited to 'plugin/src/sbt-test/sbt-jni/multiclasses') diff --git a/plugin/src/sbt-test/sbt-jni/multiclasses/README.md b/plugin/src/sbt-test/sbt-jni/multiclasses/README.md new file mode 100644 index 0000000..b039e7a --- /dev/null +++ b/plugin/src/sbt-test/sbt-jni/multiclasses/README.md @@ -0,0 +1 @@ +Tests multiple native projects and native loading for classes. diff --git a/plugin/src/sbt-test/sbt-jni/multiclasses/build.sbt b/plugin/src/sbt-test/sbt-jni/multiclasses/build.sbt new file mode 100644 index 0000000..d12a711 --- /dev/null +++ b/plugin/src/sbt-test/sbt-jni/multiclasses/build.sbt @@ -0,0 +1,16 @@ +ivyLoggingLevel := UpdateLogging.Quiet + +lazy val root = (project in file(".")). + aggregate(core, native1, native2) + +lazy val core = (project in file("core")). + dependsOn(native1 % Runtime). + dependsOn(native2 % Runtime) + +lazy val native1 = (project in file("native1")). + settings(sourceDirectory in nativeCompile := sourceDirectory.value). + enablePlugins(JniNative) + +lazy val native2 = (project in file("native2")). + settings(sourceDirectory in nativeCompile := sourceDirectory.value). + enablePlugins(JniNative) diff --git a/plugin/src/sbt-test/sbt-jni/multiclasses/core/src/main/scala/multiclasses/Adder.scala b/plugin/src/sbt-test/sbt-jni/multiclasses/core/src/main/scala/multiclasses/Adder.scala new file mode 100644 index 0000000..91d5683 --- /dev/null +++ b/plugin/src/sbt-test/sbt-jni/multiclasses/core/src/main/scala/multiclasses/Adder.scala @@ -0,0 +1,18 @@ +package multiclasses + +import ch.jodersky.jni.nativeLoader + +@nativeLoader("demo0") +class Adder(base0: Int) { + + final private val base = base0 + + @native def plus(term: Int): Int + +} + +object Adder { + + @native def sum(term1: Int, term2: Int): Int + +} diff --git a/plugin/src/sbt-test/sbt-jni/multiclasses/core/src/main/scala/multiclasses/Main.scala b/plugin/src/sbt-test/sbt-jni/multiclasses/core/src/main/scala/multiclasses/Main.scala new file mode 100644 index 0000000..6734ae9 --- /dev/null +++ b/plugin/src/sbt-test/sbt-jni/multiclasses/core/src/main/scala/multiclasses/Main.scala @@ -0,0 +1,30 @@ +package multiclasses + +object Main { + + def addition(): Unit = { + val zero = new Adder(0) + val one = new Adder(1) + assert((zero plus 1) == 1) + assert((one plus 1) == 2) + assert(Adder.sum(0,1) == 1) + } + + def multiplication(): Unit = { + val zero = new Multiplier { + override def base = 0 + } + + val one = new Multiplier { + override def base = 1 + } + assert((zero times 1) == 0) + assert((one times 1) == 1) + } + + def main(args: Array[String]): Unit = { + addition() + multiplication() + } + +} diff --git a/plugin/src/sbt-test/sbt-jni/multiclasses/core/src/main/scala/multiclasses/Multiplier.scala b/plugin/src/sbt-test/sbt-jni/multiclasses/core/src/main/scala/multiclasses/Multiplier.scala new file mode 100644 index 0000000..19cd25f --- /dev/null +++ b/plugin/src/sbt-test/sbt-jni/multiclasses/core/src/main/scala/multiclasses/Multiplier.scala @@ -0,0 +1,12 @@ +package multiclasses + +import ch.jodersky.jni.nativeLoader + +@nativeLoader("multiplier1") +abstract class Multiplier { + + def base: Int = 1 + + @native def times(factor: Int): Int + +} diff --git a/plugin/src/sbt-test/sbt-jni/multiclasses/native1/src/CMakeLists.txt b/plugin/src/sbt-test/sbt-jni/multiclasses/native1/src/CMakeLists.txt new file mode 100644 index 0000000..1539ec2 --- /dev/null +++ b/plugin/src/sbt-test/sbt-jni/multiclasses/native1/src/CMakeLists.txt @@ -0,0 +1,61 @@ +################################################################ +# A minimal CMake file that is compatible with sbt-jni # +# # +# All settings required by sbt-jni have been marked so, please # +# add/modify/remove settings to build your specific library. # +################################################################ + +cmake_minimum_required(VERSION 2.6) + +# Define project and related variables +# +project (demo) + +# Set versions and library name +# (required by sbt-jni) please use semantic versioning +# +set (VERSION_MAJOR 0) +set (VERSION_MINOR 0) +set (VERSION_PATCH 0) +# (required by sbt-jni) major version will always be appended to library name +set (LIB_NAME ${CMAKE_PROJECT_NAME}${VERSION_MAJOR}) + +# Command-line options +# +# (set by sbt-jni) +set (LIB_INSTALL_DIR lib CACHE PATH "Path in which to install libraries (equivalent to Autoconf --libdir).") +# (set by sbt-jni) +set (LIB_ENABLE_MINOR_VERSIONS ON CACHE BOOLEAN "Build libraries with minor and patch versions appended.") + +# Setup JNI +find_package(JNI REQUIRED) +if (JNI_FOUND) + message (STATUS "JNI include directories: ${JNI_INCLUDE_DIRS}") +endif() + +# Include directories +include_directories(.) +include_directories(../../core/target/native/include) +include_directories(${JNI_INCLUDE_DIRS}) + +# Setup main shared library +file(GLOB LIB_SRC + "*.c" + "*.cpp" +) +add_library(${LIB_NAME} SHARED ${LIB_SRC}) + +# By default, in a regular build, minor and patch versions are added to the generated files. +# When built through sbt-jni however, LIB_ENABLE_MINOR_VERSIONS is deactivated and only a +# major-versioned library file is built. +if (LIB_ENABLE_MINOR_VERSIONS) + set_target_properties( + ${LIB_NAME} + PROPERTIES + VERSION 0.${VERSION_MINOR}.${VERSION_PATCH} # major version always 0, it is included in library name + SOVERSION 0 + ) +endif() + +# Installation targets +install(TARGETS ${LIB_NAME} LIBRARY DESTINATION ${LIB_INSTALL_DIR}) diff --git a/plugin/src/sbt-test/sbt-jni/multiclasses/native1/src/library.c b/plugin/src/sbt-test/sbt-jni/multiclasses/native1/src/library.c new file mode 100644 index 0000000..8b45660 --- /dev/null +++ b/plugin/src/sbt-test/sbt-jni/multiclasses/native1/src/library.c @@ -0,0 +1,28 @@ +#include +#include "multiclasses_Adder.h" +#include "multiclasses_Adder__.h" + +/* + * Class: multiclasses_Adder + * Method: plus + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_multiclasses_Adder_plus + (JNIEnv* env, jobject instance, jint term) +{ + jclass clazz = (*env)->GetObjectClass(env, instance); + jfieldID field = (*env)->GetFieldID(env, clazz, "base", "I"); + jint base = (*env)->GetIntField(env, instance, field); + return base + term; +} + +/* + * Class: multiclasses_Adder__ + * Method: sum + * Signature: (II)I + */ +JNIEXPORT jint JNICALL Java_multiclasses_Adder_00024_sum + (JNIEnv* env, jobject instance, jint term1, jint term2) +{ + return term1 + term2; +} diff --git a/plugin/src/sbt-test/sbt-jni/multiclasses/native2/src/CMakeLists.txt b/plugin/src/sbt-test/sbt-jni/multiclasses/native2/src/CMakeLists.txt new file mode 100644 index 0000000..feeab89 --- /dev/null +++ b/plugin/src/sbt-test/sbt-jni/multiclasses/native2/src/CMakeLists.txt @@ -0,0 +1,61 @@ +################################################################ +# A minimal CMake file that is compatible with sbt-jni # +# # +# All settings required by sbt-jni have been marked so, please # +# add/modify/remove settings to build your specific library. # +################################################################ + +cmake_minimum_required(VERSION 2.6) + +# Define project and related variables +# +project (multiplier) + +# Set versions and library name +# (required by sbt-jni) please use semantic versioning +# +set (VERSION_MAJOR 1) +set (VERSION_MINOR 2) +set (VERSION_PATCH 3) +# (required by sbt-jni) major version will always be appended to library name +set (LIB_NAME ${CMAKE_PROJECT_NAME}${VERSION_MAJOR}) + +# Command-line options +# +# (set by sbt-jni) +set (LIB_INSTALL_DIR lib CACHE PATH "Path in which to install libraries (equivalent to Autoconf --libdir).") +# (set by sbt-jni) +set (LIB_ENABLE_MINOR_VERSIONS ON CACHE BOOLEAN "Build libraries with minor and patch versions appended.") + +# Setup JNI +find_package(JNI REQUIRED) +if (JNI_FOUND) + message (STATUS "JNI include directories: ${JNI_INCLUDE_DIRS}") +endif() + +# Include directories +include_directories(.) +include_directories(../../core/target/native/include) +include_directories(${JNI_INCLUDE_DIRS}) + +# Setup main shared library +file(GLOB LIB_SRC + "*.c" + "*.cpp" +) +add_library(${LIB_NAME} SHARED ${LIB_SRC}) + +# By default, in a regular build, minor and patch versions are added to the generated files. +# When built through sbt-jni however, LIB_ENABLE_MINOR_VERSIONS is deactivated and only a +# major-versioned library file is built. +if (LIB_ENABLE_MINOR_VERSIONS) + set_target_properties( + ${LIB_NAME} + PROPERTIES + VERSION 0.${VERSION_MINOR}.${VERSION_PATCH} # major version always 0, it is included in library name + SOVERSION 0 + ) +endif() + +# Installation targets +install(TARGETS ${LIB_NAME} LIBRARY DESTINATION ${LIB_INSTALL_DIR}) diff --git a/plugin/src/sbt-test/sbt-jni/multiclasses/native2/src/library.c b/plugin/src/sbt-test/sbt-jni/multiclasses/native2/src/library.c new file mode 100644 index 0000000..5fe817e --- /dev/null +++ b/plugin/src/sbt-test/sbt-jni/multiclasses/native2/src/library.c @@ -0,0 +1,16 @@ +#include +#include "multiclasses_Multiplier.h" + +/* + * Class: multiclasses_Multiplier + * Method: times + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_multiclasses_Multiplier_times + (JNIEnv* env, jobject instance, jint factor) +{ + jclass clazz = (*env)->GetObjectClass(env, instance); + jmethodID method = (*env)->GetMethodID(env, clazz, "base", "()I"); + jint base = (*env)->CallIntMethod(env, instance, method); + return base * factor; +} diff --git a/plugin/src/sbt-test/sbt-jni/multiclasses/project/ScriptedHelper.scala b/plugin/src/sbt-test/sbt-jni/multiclasses/project/ScriptedHelper.scala new file mode 120000 index 0000000..aeaba9d --- /dev/null +++ b/plugin/src/sbt-test/sbt-jni/multiclasses/project/ScriptedHelper.scala @@ -0,0 +1 @@ +../../simple/project/ScriptedHelper.scala \ No newline at end of file diff --git a/plugin/src/sbt-test/sbt-jni/multiclasses/project/plugins.sbt b/plugin/src/sbt-test/sbt-jni/multiclasses/project/plugins.sbt new file mode 120000 index 0000000..1c60ea7 --- /dev/null +++ b/plugin/src/sbt-test/sbt-jni/multiclasses/project/plugins.sbt @@ -0,0 +1 @@ +../../simple/project/plugins.sbt \ No newline at end of file diff --git a/plugin/src/sbt-test/sbt-jni/multiclasses/test b/plugin/src/sbt-test/sbt-jni/multiclasses/test new file mode 100644 index 0000000..e9e0d97 --- /dev/null +++ b/plugin/src/sbt-test/sbt-jni/multiclasses/test @@ -0,0 +1,2 @@ +> javah +> core/run \ No newline at end of file -- cgit v1.2.3