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
|
package ch.jodersky.sbt.jni
import build._
import ch.jodersky.jni.{NativeLoader, Platform}
import sbt._
import sbt.Keys._
object JniPackager extends AutoPlugin {
override def requires = Jni
override def trigger = allRequirements
object autoImport {
//Main task, inspect this first
//val packageNative = taskKey[File]("Packages native libraries in a jar.")
//val packageNativeMappings = taskKey[Seq[(File, String)]]("")
val nativeLibraryPath = settingKey[String](
"String that is prepended to the path of a native library when packaged.")
val enableNativeCompilation = settingKey[Boolean](
"Determines if native compilation is enabled in a scoped key (typically for packaging).")
val unmanagedNativeDirectories = settingKey[Seq[File]](
"""|Unmanaged directories containing native libraries. The libraries must be regular files
|contained in a subdirectory corresponding to a platform.""".stripMargin)
val unmanagedNativeLibraries = taskKey[Map[Platform, File]]("")
val managedNativeLibraries = taskKey[Map[Platform, File]]("")
}
import autoImport._
import Jni.autoImport._
lazy val settings: Seq[Setting[_]] = Seq(
nativeLibraryPath := {
val orgPath = organization.value.replaceAll("\\.", "/")
s"/${orgPath}/${name.value}/native"
},
//Make NativeLoader available to project
libraryDependencies += "ch.jodersky" %% "jni-library" % Version.PluginVersion,
name in packageNative := {
name.value + "-native-" + version.value + ".jar"
},
enableNativeCompilation := true,
unmanagedNativeDirectories := Seq(baseDirectory.value / "lib_native"),
unmanagedNativeLibraries := {
val dirs: Seq[File] = unmanagedNativeDirectories.value
val seq: Seq[(Platform, File)] = for (
dir <- dirs;
platformDir <- dir.listFiles();
if platformDir.isDirectory;
platform = Platform.fromId(platformDir.name);
library <- platformDir.listFiles();
if library.isFile
) yield {
platform -> library.getCanonicalFile()
}
seq.toMap
},
managedNativeLibraries := Def.taskDyn[Map[Platform, File]]{
val enableManaged = (enableNativeCompilation).value
if (enableManaged) Def.task {
val library: File = (nativeCompile in Compile).value
val platform = (nativePlatform in Compile).value
Map(platform -> library)
} else Def.task{
Map()
}
}.value,
resourceGenerators in Compile += Def.task {
val libraries: Seq[(Patform, File)] = (managedNativeLibraries.value ++ unmanagedNativeLibraries.value).toSeq
val resources: Seq[File] = for ((plat, file) <- libraries) yield {
//native library as a managed resource file
val resource = (resourceManaged in Compile).value /
NativeLoader.fullLibraryPath(
(nativeLibraryPath).value,
plat)
//copy native library to a managed resource (so it can also be loaded when not packaged as a jar)
IO.copyFile(file, resource)
resource
}
resources
}.taskValue,
//don't add scala version to native jars
crossPaths := false
)
override lazy val projectSettings = settings
/*
name in packageNative := name,
//this is file name of the artifact
artifactName in packageNative := { (sv: ScalaVersion, module: ModuleID, artifact: Artifact) =>
artifact.name + "-native." + module.revision + "." + artifact.extension
}
packageNative := {
val log = streams.value.log
val mappings: Seq[(File, String)] = {
val libs = unmanagedNativeLibraries.value.toSeq ++ managedNativeLibraries.value.toSeq
libs.map{ case (platform, file) =>
file -> NativeLoader.fullLibraryPath(
(nativeLibraryPath in Compile).value,
platform)
}
}
val manifest = new java.util.jar.Manifest
val namer = (artifactName in packageNative).value
val jar: File = (target in nativeCompile).value / namer(
scalaVersion,
(artifactName in packageNative).value
)
Package.makeJar(mappings, jar, manifest, log)
jar
},
*/
//Add native jar to runtime classpath. Note that it is not added as a resource (this would cause
//the native library to included in the main jar).
//unmanagedClasspath in Runtime += Attributed.blank(packageNative.value),
//Fork new JVM when running locally, since native libraries can only be loaded once
//fork in run := true
/*
override lazy val projectSettings =
Defaults.packageTaskSettings(packageNative, packageNativeMappings) ++
addArtifact(artifact in packageNative, packageNative) ++
inConfig(Compile)(settings) ++ Seq(
packageNativeMappings := {
val libs = (unmanagedNativeLibraries in Compile).value.toSeq ++
(managedNativeLibraries in Compile).value.toSeq
libs.map{ case (platform, file) =>
file -> NativeLoader.fullLibraryPath(
(nativeLibraryPath in Compile).value,
platform)
}
},
artifactClassifier in packageNative := Some("native"),
//this is file name of the artifact
artifactName := { (sv: ScalaVersion, module: ModuleID, artifact: Artifact) =>
artifact.name + "-foso" + module.revision + "." + artifact.extension
},
artifact in packageNative := {
Artifact("foo", "jar", "jar", Some("native"), Nil, None, Map("platform" -> "all"))
},
crossVersion in packageNative := CrossVersion.Disabled
// projectID in packageNative := { projectID.value.copy(crossVersion = CrossVersion.Disabled) }
)
*/
}
|