1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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)
}
|