From b0c32f5325702dd7f7ef3d5ccc0eb9a2b972cf7a Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Tue, 18 Jun 2013 18:05:20 +0200 Subject: use sbt-native and jni plugin --- project/Build.scala | 41 +++++++++++-------------- project/JNIBuild.scala | 22 -------------- project/Jni.scala | 37 +++++++++++++++++++++++ project/NativeBuild.scala | 75 ---------------------------------------------- project/NativeSettings.foo | 56 ---------------------------------- project/build.properties | 1 + project/plugins.sbt | 1 + 7 files changed, 57 insertions(+), 176 deletions(-) delete mode 100644 project/JNIBuild.scala create mode 100644 project/Jni.scala delete mode 100644 project/NativeBuild.scala delete mode 100644 project/NativeSettings.foo create mode 100644 project/build.properties create mode 100644 project/plugins.sbt (limited to 'project') diff --git a/project/Build.scala b/project/Build.scala index ccee261..5b157a7 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1,22 +1,33 @@ import sbt._ import Keys._ -import NativeBuild._ -import JNIBuild._ + +import com.github.jodersky.build.NativeKeys._ +import com.github.jodersky.build.NativePlugin._ +import Jni._ object FlowBuild extends Build { val Organization = "com.github.jodersky" val Version = "1.0-SNAPSHOT" val ScalaVersion = "2.10.1" - lazy val root = Project( - id = "flow", - base = file("main"), - settings = buildSettings ++ jniSettings ++ Seq(libraryDependencies ++= Dependencies.all)) + lazy val main = Project("flow-main", file("flow-main")).settings( + buildSettings ++ Seq(libraryDependencies ++= Dependencies.all): _* + ) + + lazy val native = NativeProject("flow-native", file("flow-native")).settings((Seq( + javahClasses := Seq("com.github.jodersky.flow.low.NativeSerial"), + includeDirectories in Native += jdkHome.value / "include" / "linux", + nativeSource in Native := baseDirectory.value / "src", + binaryType in Native := SharedLibrary, + binaryName in Native := "flow", + options in Native := Seq("-fPIC", "-O2"), + linkOptions in Native := Seq("-Wl,-soname,libflow.so.1") + ) ++ Jni.defaultSettings): _*).dependsOn(main) lazy val example = Project( id = "flow-example", base = file("example"), - settings = buildSettings ++ runSettings ++ Seq(libraryDependencies ++= Dependencies.all)).dependsOn(root) + settings = buildSettings ++ runSettings ++ Seq(libraryDependencies ++= Dependencies.all)) lazy val buildSettings = Defaults.defaultSettings ++ Seq( organization := Organization, @@ -26,22 +37,6 @@ object FlowBuild extends Build { scalacOptions ++= Seq("-deprecation", "-unchecked", "-feature"), compileOrder in Compile := CompileOrder.Mixed) - lazy val jniSettings = JNIBuild.defaults ++ Seq( - jdkHome := file(System.getProperty("java.home")) / "..", - javaClass := "com.github.jodersky.flow.low.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"), - Keys.packageBin in Compile <<= (Keys.packageBin in Compile).dependsOn(NativeBuild.link), - mappings in (Compile, packageBin) <+= linkerOutput map { out => - out -> ("native/" + System.getProperty("os.name").toLowerCase + "/" + System.getProperty("os.arch").toLowerCase + "/libflow.so") - }, - exportJars := true - ) - lazy val runSettings = Seq( fork := true, connectInput in run := true, diff --git a/project/JNIBuild.scala b/project/JNIBuild.scala deleted file mode 100644 index ed0d05e..0000000 --- a/project/JNIBuild.scala +++ /dev/null @@ -1,22 +0,0 @@ -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: Seq[Setting[_]] = NativeBuild.defaults ++ Seq( - javahTask, - NativeBuild.compile <<= NativeBuild.compile.dependsOn(javah) - ) - -} - diff --git a/project/Jni.scala b/project/Jni.scala new file mode 100644 index 0000000..0263786 --- /dev/null +++ b/project/Jni.scala @@ -0,0 +1,37 @@ +import sbt._ +import Keys._ +import com.github.jodersky.build.NativeKeys._ + +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 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 := { + + val cp = (fullClasspath in Compile).value.map(_.data.getAbsolutePath).mkString(":") + for (clazz <- javahClasses.value) { + val parts = Seq( + "javah", + "-d", javahHeaderDirectory.value, + "-classpath", cp, + clazz) + val cmd = parts.mkString(" ") + val ev = Process(cmd) ! streams.value.log + if (ev != 0) throw new RuntimeException("Error occured running javah.") + } + IO.listFiles(javahHeaderDirectory.value) + }, + sourceGenerators in Native <+= javah map {headers => + headers + }, + includeDirectories in Native += javahHeaderDirectory.value, + javah <<= (javah dependsOn (compile in Compile)), + includeDirectories in Native += jdkHome.value / "include" + ) +} + diff --git a/project/NativeBuild.scala b/project/NativeBuild.scala deleted file mode 100644 index a77e8f8..0000000 --- a/project/NativeBuild.scala +++ /dev/null @@ -1,75 +0,0 @@ -import sbt._ -import Keys._ - -object NativeBuild { - - //settings - val sourceDirectory = SettingKey[File]("native-source-directory", "Native source directory containing files to compile.") - val compiler = SettingKey[String]("native-compiler", "Native compiler.") - val options = SettingKey[Seq[String]]("native-options", "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 linker = SettingKey[String]("native-linker", "Native linker.") - val linkerOutput = SettingKey[File]("native-linker-output", "Name of linker output.") - val linkerOptions = SettingKey[Seq[String]]("native-linker-options", "Native linker options.") - val linkerLibraries = SettingKey[Seq[String]]("native-linker-libraries", "Libraries against which to link.") - - //tasks - val outputFromSource = TaskKey[File => File]("native-output-from-source", "Get name of native binary from source file.") - val sources = TaskKey[Seq[File]]("native-source", "Native source files to compile.") - val makeOutputDirectory = TaskKey[Unit]("native-make-output-directory", "Make native output directory.") - val compile = TaskKey[Unit]("native-compile", "Compiles native sources.") - val link = TaskKey[Unit]("native-link", "Link native sources.") - - //task implementations - val outputFromSourceTask = outputFromSource <<= (outputDirectory) map { - outputDir => - ((src: File) => {file((outputDir / src.base).absolutePath + ".o")}) - } - - val makeOutputDirectoryTask = makeOutputDirectory <<= (outputDirectory) map {o => o.mkdirs(); {}} - - def compileSingleFile(compiler: String, options: Seq[String], includeDirectories: Seq[File], source: File, s2o: File => File): Unit = { - val cmdParts = - List(compiler) ++ - options ++ - includeDirectories.map(i => "-I" + i.absolutePath) ++ - List("-c", source.absolutePath) ++ - List("-o", s2o(source)) - - val cmd = cmdParts.mkString(" ") - cmd ! - } - - val compileTask = compile <<= (compiler, options, includeDirectories, sources, outputFromSource) map { - (c, f, i, srcs, out) => for (s <- srcs) compileSingleFile(c,f,i,s,out) - } dependsOn(makeOutputDirectory) - - val linkTask = link <<= (linker, linkerOptions, linkerLibraries, linkerOutput, sources, outputFromSource) map { (l, opts, libs, out, srcs, s2o) => - val outs = srcs.map(s2o(_)) - val cmd: Seq[String] = Seq(l) ++ opts ++ Seq("-o", out.absolutePath) ++ outs.map(_.absolutePath) ++ libs.map(lib => "-l" + lib) - cmd !; - {} - } dependsOn(compile) - - - - lazy val defaults = Seq( - compiler := "gcc", - options := Seq(), - sourceDirectory <<= Keys.sourceDirectory(_ / "main" / "c"), - sources <<= sourceDirectory map (dir => (dir ** "*.c").get), - includeDirectories <<= sourceDirectory(dir => Seq(dir)), - outputDirectory <<= target(_ / "c"), - linker := "gcc", - linkerOutput <<= outputDirectory(_ / "a.out"), - linkerOptions := Seq(), - linkerLibraries := Seq(), - - outputFromSourceTask, - makeOutputDirectoryTask, - compileTask, - linkTask - ) - -} \ No newline at end of file diff --git a/project/NativeSettings.foo b/project/NativeSettings.foo deleted file mode 100644 index 5a544c1..0000000 --- a/project/NativeSettings.foo +++ /dev/null @@ -1,56 +0,0 @@ -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 diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 0000000..15f8ffd --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=0.13.0-Beta2 diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..6eb2159 --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("com.github.jodersky" % "sbt-native" % "1.0-SNAPSHOT") -- cgit v1.2.3