import sbt._
import Keys._
import com.jsuereth.git.GitKeys.gitRunner
/** This trait stores all the helper methods to generate layers in Scala's layered build. */
trait Layers extends Build {
// TODO - Clean this up or use a self-type.
/** Default SBT overrides needed for layered compilation. */
def settingOverrides: Seq[Setting[_]]
/** Reference to the jline project */
def jline: Project
/** Reference to forkjoin library */
def forkjoin: Project
/** Reference to Fast-Java-Bytecode-Generator library */
def fjbg: Project
/** A setting that adds some external dependencies. */
def externalDeps: Setting[_]
/** The root project. */
def aaa_root: Project
/** Creates a reference Scala version that can be used to build other projects. This takes in the raw
* library, compiler and fjbg libraries as well as a string representing the layer name (used for compiling the compile-interface).
*/
def makeScalaReference(layer : String, library: Project, compiler: Project, fjbg: Project) =
scalaInstance <<= (appConfiguration in library,
version in library,
(exportedProducts in library in Compile),
(exportedProducts in compiler in Compile),
(exportedProducts in fjbg in Compile),
(fullClasspath in jline in Runtime)) map {
(app, version: String, lib: Classpath, comp: Classpath, fjbg: Classpath, jline: Classpath) =>
val launcher = app.provider.scalaProvider.launcher
(lib,comp) match {
case (Seq(libraryJar), Seq(compilerJar)) =>
ScalaInstance(
version + "-" + layer + "-",
libraryJar.data,
compilerJar.data,
launcher,
((fjbg.files++jline.files):_*))
case _ => error("Cannot build a ScalaReference with more than one classpath element")
}
}
/** Creates a "layer" of Scala compilation. That is, this will build the next version of Scala from a previous version.
* Returns the library project and compiler project from the next layer.
* Note: The library and compiler are not *complete* in the sense that they are missing things like "actors" and "fjbg".
*/
def makeLayer(layer: String, referenceScala: Setting[Task[ScalaInstance]]) : (Project, Project) = {
val library = Project(layer + "-library", file(".")) settings(settingOverrides: _*) settings(
version := layer,
// TODO - use depends on.
unmanagedClasspath in Compile <<= (exportedProducts in forkjoin in Compile).identity,
managedClasspath in Compile := Seq(),
scalaSource in Compile <<= (baseDirectory) apply (_ / "src" / "library"),
resourceDirectory in Compile <<= baseDirectory apply (_ / "src" / "library"),
defaultExcludes in unmanagedResources := ("*.scala" | "*.java" | "*.disabled"),
// TODO - Allow other scalac option settings.
scalacOptions in Compile <++= (scalaSource in Compile) map (src => Seq("-sourcepath", src.getAbsolutePath)),
classpathOptions := ClasspathOptions.manual,
resourceGenerators in Compile <+= (resourceManaged, Versions.scalaVersions, streams) map Versions.generateVersionPropertiesFile("library.properties"),
referenceScala
)
// Define the compiler
val compiler = Project(layer + "-compiler", file(".")) settings(settingOverrides:_*) settings(
version := layer,
scalaSource in Compile <<= (baseDirectory) apply (_ / "src" / "compiler"),
resourceDirectory in Compile <<= baseDirectory apply (_ / "src" / "compiler"),
unmanagedSourceDirectories in Compile <+= (baseDirectory) apply (_ / "src" / "msil"),
defaultExcludes := ("tests"),
javacOptions ++= Seq("-source", "1.4"),
defaultExcludes in unmanagedResources := "*.scala",
resourceGenerators in Compile <+= (resourceManaged, Versions.scalaVersions, streams) map Versions.generateVersionPropertiesFile("compiler.properties"),
// Note, we might be able to use the default task, but for some reason ant was filtering files out. Not sure what's up, but we'll
// stick with that for now.
unmanagedResources in Compile <<= (baseDirectory) map {
(bd) =>
val dirs = Seq(bd / "src" / "compiler")
dirs.descendentsExcept( ("*.xml" | "*.html" | "*.gif" | "*.png" | "*.js" | "*.css" | "*.tmpl" | "*.swf" | "*.properties" | "*.txt"),"*.scala").get
},
// TODO - Use depends on *and* SBT's magic dependency mechanisms...
unmanagedClasspath in Compile <<= Seq(forkjoin, library, fjbg, jline).map(exportedProducts in Compile in _).join.map(_.flatten),
classpathOptions := ClasspathOptions.manual,
externalDeps,
referenceScala
)
// Return the generated projects.
(library, compiler)
}
}