aboutsummaryrefslogtreecommitdiff
path: root/project/Build.scala
blob: bd31c1b158ad2eb29e091afb44c508a6f37df6e1 (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
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
import sbt._
import Keys._

import NativeKeys._
import NativeDefaults._
import JniKeys._

object FlowBuild extends Build {
  val Organization = "com.github.jodersky"
  val Version = "1.0-SNAPSHOT" //version of flow library
  val BinaryMajorVersion = 2 //binary major version used to select so's and dlls when publishing (needs to be incremented if API changes are made to flow.h or NativeSerial.java)
  val ScalaVersion = "2.10.2"
  //see native settings down below
  
  lazy val commonSettings: Seq[Setting[_]] = Seq(
    organization := Organization,
    version := Version,
    scalaVersion := ScalaVersion,
    resolvers += "Typesafe Repo" at "http://repo.typesafe.com/typesafe/releases/",
    scalacOptions ++= Seq("-deprecation", "-unchecked", "-feature"))
  
  lazy val runSettings: Seq[Setting[_]] = Seq(
    fork := true,
    connectInput in run := true,
    outputStrategy := Some(StdoutOutput)
  )
  
  lazy val main: Project = (
    Project("flow", file("flow-main"))
    settings (commonSettings: _*)
    settings (
      libraryDependencies ++= Seq(
        Dependencies.akkaActor,
        Dependencies.ioCore,
        Dependencies.ioFile), 
      compileOrder in Compile := CompileOrder.Mixed,
      resourceGenerators in Compile <+= (resourceManaged in Compile, binariesDirectory in ThisBuild) map { (resDir, binDir) =>
        val binaries: Seq[(File, File)] = getLatestBinaries(binDir, BinaryMajorVersion)
        val resources = for (binary <- binaries) yield {
          val versionedBinary = binary._1
          val unversionedBinary = binary._2
          
          val relative = (unversionedBinary relativeTo binDir).get.getPath
          
          val resource = resDir / "native" / relative
          IO.copyFile(versionedBinary, resource)
          resource
        }
        resources
      }
    )
  )
  
  def getLatestBinaries(base: File, majorVersion: Int): Seq[(File, File)] = {
    def latest(platform: File) = {
      val Pattern = "(.+)\\.(\\d+)\\.(\\d+)".r
      val MajorVersion = majorVersion.toString
      val majorCompatible = platform.listFiles.map(_.getAbsolutePath) collect {
        case path @ Pattern(strippedPath, MajorVersion, minorVersion) => (path, strippedPath, minorVersion)
      }
      val latestMinor = majorCompatible.sortBy(_._3).lastOption
      latestMinor map { case (path, strippedPath, _) =>
        (file(path), file(strippedPath))
      }
    }
    
    val oSs = IO.listFiles(base).filter(file => !file.name.startsWith("."))
    val platforms = oSs.flatMap(_.listFiles)
    
    platforms.flatMap(latest(_))
  }
  
  lazy val terminal = (
    Project("flow-samples-terminal", file("flow-samples") / "terminal")
    settings(commonSettings: _*)
    settings(runSettings: _*)
    dependsOn(main)
  )
  
 
  //--- native settings --------------------------------------------------
  
  val binariesDirectory = settingKey[File]("Directory containing published native binaries.")
  override lazy val settings = super.settings ++ Seq(
    (binariesDirectory in ThisBuild) := (baseDirectory in ThisBuild).value / "flow-binaries"
  )
    
  def canonicalBinaryPath(base: File, binaryName: String) = {
	base / sys.props("os.name").toLowerCase.filter(_ != ' ') / sys.props("os.arch").toLowerCase / binaryName    
  }
  val publishNative = taskKey[File]("Publish native binary compiled on current OS to flow-binaries project so that it may be packaged in a distribution of flow.")
  val publishNativeImpl = Def.task{
    val in = (link in Native).value
    val out = canonicalBinaryPath((binariesDirectory in ThisBuild).value, in.getName)
    IO.copyFile(in, out)
    out
  }

  lazy val commonNativeSettings: Seq[Setting[_]] = Seq(
    nativeSource in Native := baseDirectory.value / "src",
    includeDirectories in Native += file("flow-native") / "shared" / "include",
    nativeCompile in Native := ((nativeCompile in Native) dependsOn (compile in Compile in main)).value,
    publishNative := publishNativeImpl.value,
    javahClasspath := Seq((classDirectory in Compile in main).value),
    javahClasses := Seq("com.github.jodersky.flow.internal.NativeSerial")) ++ JniDefaults.defaultSettings

    
  //--- native unix-like settings ----------------------------------------
  
  val UnixBinaryMinorVersion = 1
  
  lazy val unixNativeSettings: Seq[Setting[_]] = commonNativeSettings ++ Seq(
    flags in Native := Seq("-fPIC", "-O2")
    )

  lazy val nativeLinux = (
    NativeProject("flow-native-linux", file("flow-native") / "unix")
    settings (unixNativeSettings: _*)
    settings (
      target := baseDirectory.value / "target" / "linux",
      includeDirectories in Native ++= jdkHome.value.map(jdk => jdk / "include" / "linux").toSeq,
      linkFlags in Native ++= Seq("-shared", s"-Wl,-soname,libflow.so.${BinaryMajorVersion}"),
      binaryName in Native := s"libflow.so.${BinaryMajorVersion}.${UnixBinaryMinorVersion}"
    )
    dependsOn(main)
  )
  
  lazy val nativeMacOSX = (
    NativeProject("flow-native-macosx", file("flow-native") / "unix")
    settings (unixNativeSettings: _*)
    settings (
      target := baseDirectory.value / "target" / "macosx",
      includeDirectories in Native += file("/System/Library/Frameworks/JavaVM.framework/Headers/jni.h"),
      includeDirectories in Native += file("/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers"),
      linkFlags in Native ++= Seq("-dynamiclib"),
      binaryName in Native := s"libflow.jnilib.${BinaryMajorVersion}.${UnixBinaryMinorVersion}"
    )
    dependsOn (main)
  )
  
  
  /* stub for native project on windows, I don't know if this would actually work...
   * 
   * val WindowsBinaryMinorVersion = 0
   * 
  lazy val nativeWindows = (
    NativeProject("flow-native-windows", file("flow-native") / "windows") //note: change from unix to windows
    settings (
      //windows is not a unix-like OS, several default settings need to be changed
      cCompiler in Native := "???",
      flags in Native := Seq("-fPIC", "-O2"),
      linkFlags in Native ++= ???,
      binaryName in Native := s"flow.dll.${BinaryMajorVersion}.${WindowsBinaryMinorVersion}"
      includeDirectories in Native += jdkHome.value / "include" / "windows"
    )
    dependsOn (main)
  )*/
  
}