aboutsummaryrefslogtreecommitdiff
path: root/plugin/src/main/scala/ch/jodersky/sbt/jni/plugins/JniPackage.scala
blob: fe627a94ff9612501a59506fd6f1f8271f1d5862 (plain) (blame)
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
package ch.jodersky.sbt.jni
package plugins

import sbt._
import sbt.Keys._
import java.io.File

/** Packages libraries built with JniNative. */
object JniPackage extends AutoPlugin {

  // JvmPlugin is required or else it will override resource generators when first included
  override def requires = JniNative && plugins.JvmPlugin
  override def trigger = allRequirements

  object autoImport {

    val enableNativeCompilation = settingKey[Boolean](
      "Determines if native compilation is enabled. If not enabled, only pre-compiled libraries in " +
        "`unmanagedNativeDirectories` will be packaged."
    )

    val unmanagedNativeDirectories = settingKey[Seq[File]](
      "Unmanaged directories containing native libraries. The libraries must be regular files " +
        "contained in a subdirectory corresponding to a platform. For example " +
        "`<unmanagedNativeDirectory>/x86_64-linux/libfoo.so` is an unmanaged library for machines having " +
        "the x86_64 architecture and running the Linux kernel."
    )

    val unmanagedNativeLibraries = taskKey[Seq[(File, String)]](
      "Reads `unmanagedNativeDirectories` and maps libraries to their locations on the classpath " +
        "(i.e. their path in a fat jar)."
    )

    val managedNativeLibraries = taskKey[Seq[(File, String)]](
      "Maps locally built, platform-dependant libraries to their locations on the classpath."
    )

    val nativeLibraries = taskKey[Seq[(File, String)]](
      "All native libraries, managed and unmanaged."
    )

  }
  import autoImport._
  import JniNative.autoImport._

  lazy val settings: Seq[Setting[_]] = Seq(

    enableNativeCompilation := true,

    unmanagedNativeDirectories := Seq(baseDirectory.value / "lib_native"),

    unmanagedNativeLibraries := {
      val baseDirs: Seq[File] = unmanagedNativeDirectories.value
      val mappings: Seq[(File, String)] = unmanagedNativeDirectories.value.flatMap { dir =>
        val files: Seq[File] = (dir ** "*").get.filter(_.isFile)
        files pair rebase(dir, "/native")
      }
      mappings
    },

    managedNativeLibraries := Def.taskDyn[Seq[(File, String)]] {
      val enableManaged = (enableNativeCompilation).value
      if (enableManaged) Def.task {
        val library: File = nativeCompile.value
        val platform = nativePlatform.value

        Seq(library -> s"/native/$platform/${library.name}")
      }
      else Def.task {
        Seq.empty
      }
    }.value,

    nativeLibraries := unmanagedNativeLibraries.value ++ managedNativeLibraries.value,

    resourceGenerators += Def.task {
      val libraries: Seq[(File, String)] = nativeLibraries.value
      val resources: Seq[File] = for ((file, path) <- libraries) yield {

        // native library as a managed resource file
        val resource = resourceManaged.value / path

        // copy native library to a managed resource, so that it is always available
        // on the classpath, even when not packaged as a jar
        IO.copyFile(file, resource)
        resource
      }
      resources
    }.taskValue

  )

  override lazy val projectSettings = inConfig(Compile)(settings) ++ inConfig(Test)(settings) ++
    Seq(crossPaths := false) // don't add scala version to native jars

}