From 60cac1f48d76329fa94034cea84499fb93337953 Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Tue, 21 May 2013 17:36:00 +0200 Subject: move JNI header generation to sbt --- project/Build.scala | 8 +++++-- project/JNIBuild.scala | 21 +++++++++++++++++ project/NativeSettings.foo | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 project/JNIBuild.scala create mode 100644 project/NativeSettings.foo diff --git a/project/Build.scala b/project/Build.scala index be1febc..714c9d0 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1,6 +1,7 @@ import sbt._ import Keys._ import NativeBuild._ +import JNIBuild._ object FlowBuild extends Build { val Organization = "com.github.jodersky" @@ -10,7 +11,7 @@ object FlowBuild extends Build { lazy val root = Project( id = "flow", base = file("."), - settings = buildSettings ++ nativeSettings ++ runSettings) + settings = buildSettings ++ jniSettings ++ runSettings) lazy val buildSettings = Defaults.defaultSettings ++ Seq( organization := Organization, @@ -20,9 +21,12 @@ object FlowBuild extends Build { scalacOptions ++= Seq("-deprecation", "-unchecked", "-feature"), compileOrder in Compile := CompileOrder.JavaThenScala) - lazy val nativeSettings = NativeBuild.defaults ++ Seq( + lazy val jniSettings = JNIBuild.defaults ++ Seq( + jdkHome := file(System.getProperty("java.home")) / "..", + javaClass := "com.github.jodersky.flow.NativeSerial", NativeBuild.compiler := "gcc", options := Seq("-fPIC"), + NativeBuild.includeDirectories <<= jdkHome apply (jdk => Seq(jdk / "include", jdk / "include" / "linux")), linker := "gcc", linkerOptions := Seq("-shared", "-Wl,-soname,libflow.so.1"), linkerOutput <<= NativeBuild.outputDirectory(_ / "libflow.so") diff --git a/project/JNIBuild.scala b/project/JNIBuild.scala new file mode 100644 index 0000000..95509fb --- /dev/null +++ b/project/JNIBuild.scala @@ -0,0 +1,21 @@ +import sbt._ +import Keys._ + +object JNIBuild { + val jdkHome = SettingKey[File]("jdk-home", "Home of JDK.") + val javaClass = SettingKey[String]("jni-class", "Fully qualified name of class containing native declarations.") + + val javah = TaskKey[Unit]("javah", "Generate JNI headers.") + + val javahTask = javah <<= (javaClass, NativeBuild.sourceDirectory, Keys.classDirectory in Compile) map { (j, src, cp) => + val cmd = "javah -d " + src.absolutePath + " -classpath " + cp.absolutePath + " " + j + cmd !; + {} + } dependsOn (Keys.compile in Compile) + + val defaults = NativeBuild.defaults ++ Seq( + javahTask, + NativeBuild.compile <<= NativeBuild.compile.dependsOn(javah)) + +} + diff --git a/project/NativeSettings.foo b/project/NativeSettings.foo new file mode 100644 index 0000000..5a544c1 --- /dev/null +++ b/project/NativeSettings.foo @@ -0,0 +1,56 @@ +import sbt._ +import Keys._ + +object NativeSettings { + + val jdkHome = SettingKey[File]("jdk-home", "Home of JDK.") + + val javaClass = SettingKey[String]("native-java-file", "Fully qualified name of class containing native declarations.") + val sourceDirectory = SettingKey[File]("native-source-directory", "Native source directory ontaining files to compile.") + val sources = SettingKey[File]("native-source", "Native source files to compile.") + + val compiler = SettingKey[String]("native-compiler", "Native compiler.") + val flags = SettingKey[Seq[String]]("native-flags", "Flags for native compiler.") + val includeDirectories = SettingKey[Seq[File]]("native-include-directories", "Include directories for native compiler.") + val outputDirectory = SettingKey[File]("native-output-directory", "Directory for native output.") + + val makeOutputDirectory = TaskKey[Unit]("native-make-output-directory", "Make native output directory.") + val compile = TaskKey[Unit]("native-compile", "Compiles native sources.") + val javah = TaskKey[Unit]("native-javah", "Generate JNI headers.") + + val javahTask = javah <<= (javaClass, sourceDirectory, Keys.classDirectory) map {(j, src, cp) => + val cmd = "javah -d " + source.absolutePath + " -cp " + cp.absolutePath + " " + javaClass + cmd ! + } + + def compileTask(compiler: String, flags: Seq[String], includeDirectories: Seq[File], source: File, outputDirectory: File): Unit = { + val cmdParts = + List(compiler) ++ + flags ++ + includeDirectories.map(i => "-I" + i.absolutePath) ++ + List("-c", source.absolutePath) ++ + List("-o", (outputDirectory / source.base).absolutePath + ".o") + + val cmd = cmdParts.mkString(" ") + println(cmd) + cmd ! + } + + def jdkHome = + + lazy val defaults = Seq( + jdkHome := file(System.getProperty("java.home")) / "..", + compiler := "gcc", + flags := Seq(), + source <<= sourceDirectory(_ / "main" / "c" / "flow.c"), + includeDirectories := Seq(jdkHome / "include", jdkHome / "include" / "linux"), + outputDirectory <<= target(_ / "c"), + makeOutputDirectory <<= (outputDirectory) map {o => o.mkdirs()}, + + + compile <<= ((compiler, flags, includeDirectories, source, outputDirectory) map { + (c, f, i, s, o) => compileTask(c, f, i, s, o) + }).dependsOn(makeOutputDirectory) + ) + +} \ No newline at end of file -- cgit v1.2.3