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)
}