From 3e90312b3f2d912bf27e91b454a6ef21a81a2fc5 Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Fri, 4 Dec 2015 20:50:53 -0800 Subject: initial commit --- .../main/scala/ch/jodersky/sbt/jni/Defaults.scala | 192 +++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 jni-plugin/src/main/scala/ch/jodersky/sbt/jni/Defaults.scala (limited to 'jni-plugin/src/main/scala/ch/jodersky/sbt/jni/Defaults.scala') diff --git a/jni-plugin/src/main/scala/ch/jodersky/sbt/jni/Defaults.scala b/jni-plugin/src/main/scala/ch/jodersky/sbt/jni/Defaults.scala new file mode 100644 index 0000000..49f4a49 --- /dev/null +++ b/jni-plugin/src/main/scala/ch/jodersky/sbt/jni/Defaults.scala @@ -0,0 +1,192 @@ +package ch.jodersky.sbt.jni + +import sbt._ +import sbt.Keys._ +import Keys._ + +import build.CMake +import build.BuildTool + +import ch.jodersky.jni.Platform +import ch.jodersky.jni.NativeLoader + +object Defaults { + + lazy val buildSettings: Seq[Setting[_]] = Seq( + + baseDirectory in jni := (baseDirectory in ThisBuild).value / "native", + + target in jni := target.value / "native" / (jniPlatform in jni).value.id, + + jniPlatform in jni := Platform.current.getOrElse{ + sLog.value.warn("Warning: cannot determine platform! It will be set to 'unknown'.") + Platform.Unknown + }, + + jniBuildTool in jni := { + val tools = Seq(CMake) + + val base = (baseDirectory in jni).value + + val tool = if (base.exists && base.isDirectory) { + tools.find(t => t detect base) + } else { + None + } + tool.getOrElse( + sys.error("No supported native build tool detected. " + + s"Check that the setting 'baseDirectory in jni' (currently $base) " + + "points to a valid directory. Supported build tools are: " + + tools.map(_.name).mkString(",") + ) + ) + }, + + clean := { + val log = streams.value.log + val tool = try { + Some((jniBuildTool in jni).value) + } catch { + case _: Exception => None + } + tool foreach { t => + log.debug("Cleaning native build") + t.api.clean( + (baseDirectory in jni).value, + log + ) + } + clean.value + }, + + jni := { + val tool = (jniBuildTool in jni).value + val dir = (baseDirectory in jni).value + val targetDir = (target in jni).value / "lib" + val log = streams.value.log + + tool.api.library(dir, targetDir, log) + }, + + javahClasses in javah := Seq(), + + javahObjects in javah := Seq(), + + target in javah := (baseDirectory in jni).value, + + fullClasspath in javah := (fullClasspath in Compile).value, + + javah := { + val out = (target in javah).value + val jcp: Seq[File] = (fullClasspath in javah).value.map(_.data) + val cp = jcp.mkString(sys.props("path.separator")) + + val classes = (javahClasses in javah).value ++ + (javahObjects in javah).value.map(_ + "$") + + for (clazz <- classes) { + val parts = Seq( + "javah", + "-d", out.getAbsolutePath, + "-classpath", cp, + clazz) + val cmd = parts.mkString(" ") + val ev = Process(cmd) ! streams.value.log + if (ev != 0) sys.error(s"Error occured running javah. Exit code: ${ev}") + } + + out + } + + ) + + lazy val bundleSettings: Seq[Setting[_]] = Seq( + + jniLibraryPath in jni := { + "/" + (organization.value + "." + name.value).replaceAll("\\.|-", "/") + }, + + unmanagedResourceDirectories in jni := Seq( + (baseDirectory).value / "lib_native" + ), + + unmanagedClasspath ++= (unmanagedResourceDirectories in jni).value.map{ file => + Attributed.blank(file) + }, + + resourceManaged in jni := (target in jni).value / "lib_managed", + + managedResourceDirectories in jni := Seq( + (resourceManaged in jni).value + ), + + managedClasspath ++= { + + //build native library + val library = jni.value + + //native library as a managed resource file + val libraryResource = (resourceManaged in jni).value / + NativeLoader.fullLibraryPath( + (jniLibraryPath in jni).value, + (jniPlatform in jni).value + ) + + //copy native library to a managed resource (so it can also be loaded when not packages as a jar) + IO.copyFile(library, libraryResource) + + Seq(Attributed.blank((resourceManaged in jni).value)) + }, + + packageJni in Global := { + + val unmanagedMappings: Seq[(File, String)] = (unmanagedResourceDirectories in jni).value flatMap { dir => + val files = (dir ** "*").filter(_.isFile).get + files map { file => + println(file.getAbsolutePath) + file -> (file relativeTo dir).get.getPath + } + } + + managedClasspath.value //call this to generate files in resourceManaged + + val managedMappings: Seq[(File, String)] = (managedResourceDirectories in jni).value flatMap { dir => + val files = (dir ** "*").filter(_.isFile).get + files map { file => + println(file.getAbsolutePath) + file -> (file relativeTo dir).get.getPath + } + } + + val out = target.value / (name.value + "-native.jar") + + val manifest = new java.util.jar.Manifest + Package.makeJar( + unmanagedMappings ++ managedMappings, + out, + manifest, + streams.value.log + ) + out + } + + ) + + lazy val clientSettings: Seq[Setting[_]] = Seq( + libraryDependencies += "ch.jodersky" %% "jni-library" % "0.1-SNAPSHOT", + fork in run := true, + artifact in jni := { + Artifact( + name = name.value, + `type` = "jar", + extension = "jar", + classifier = Some("native"), + configurations = Seq(Runtime), + url = None + ) extra ( + "platform" -> "all" + ) + } + ) ++ addArtifact(artifact in jni, packageJni) + +} -- cgit v1.2.3