aboutsummaryrefslogtreecommitdiff
path: root/plugin/src/main/scala/ch/jodersky/sbt/jni/build/BuildTool.scala
blob: 931ee583a9395b896994f6a2468c3eb2c06b4805 (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
package ch.jodersky.sbt.jni
package build

import java.io.File
import java.nio.file.Files

import scala.io.Source

import sbt.Logger

trait BuildTool {

  /** Name of this build tool. */
  def name: String

  /** Detect if this build tool is configured in the given directory.
    * E.g. for the Make build tool, this would return true if a Makefile is present
    * in the given directory.
    */
  def detect(baseDirectory: File): Boolean

  protected def templateMappings: Seq[(String, String)]

  /** Initialize the given directory with a minimal, functioning configuration for
    * this build tool. E.g. for the Make build tool, this would create a Makefile in
    * the given directory that is compatible with sbt-jni.
    * @return all created files
    */
  def initTemplate(baseDirectory: File, projectName: String): Seq[File] =
    for ((resource, name) <- templateMappings) yield {
      val resourceStream = this.getClass.getResourceAsStream(resource)

      if (resourceStream == null) sys.error(s"Template for $name not found.")

      val raw = Source.fromInputStream(resourceStream).mkString("")
      val replaced = raw.replaceAll("\\{\\{project\\}\\}", projectName)

      baseDirectory.mkdir()
      val out = baseDirectory.toPath().resolve(name)
      Files.write(out, replaced.getBytes)
      out.toFile()
    }

  /** Actual tasks that can be perfomed on a specific configuration, such as
    * configured in a Makefile.
    */
  trait Instance {

    /** Invokes the native build tool's clean task */
    def clean(): Unit

    /** Invokes the native build tool's main task, resulting in a single shared
      * library file.
      * @param baseDirectory the directory where the native project is located
      * @param buildDirectory a directory from where the build is called, it may be used
      * to store temporary files
      * @param targetDirectory the directory into which the native library is copied
      * @return the native library file
      */
    def library(
      targetDirectory: File
    ): File

  }

  /** Get an instance (build configuration) of this tool, in the specified directory. */
  def getInstance(baseDirectory: File, buildDirectory: File, logger: Logger): Instance

}