summaryrefslogblamecommitdiff
path: root/project/build/BasicLayer.scala
blob: a28b593c1a66fa60933e54344334efc6b13556d3 (plain) (tree)









































































































































































































































































                                                                                                                                                 
import sbt._
import xsbt.{ScalaInstance}
import BasicLayer._
import scala.collection.immutable.{EmptyMap}

/**
 * Basic tasks and configuration shared by all layers. This class regroups the configuration and behaviour
 * shared by all layers.
 * @author Grégory Moix
 */
abstract class BasicLayer(val info:ProjectInfo,val versionNumber:String, previousLayer:Option[BasicLayer]) extends Project with ReflectiveProject
        with AdditionalResources with Compilation{
  override def dependencies = info.dependencies
  lazy val projectRoot = info.projectPath

  lazy val copyright = property[String]
  lazy val partestVersionNumber = property[Version]


  /**
   * Before compiling the layer, we need to check that the previous layer
   * was created correctly and compile it if necessary
   */
  lazy val startLayer = previousLayer match {
    case Some(previous) => task{
      None
    }.dependsOn(previous.finishLayer)
    case None => task{None}
  }

  lazy val build= task{
    None
  }.dependsOn(externalCompilation,copyAdditionalFiles,writeProperties)

  /**
   * Finish the compilation and ressources copy and generation
   * It does nothing in itself. As sbt doesn't support conditional dependencies,
   * it permit locker to override it in order to lock the layer when the compilation
   * is finished.
   */
  lazy val finishLayer = task{None}.dependsOn(build)

  def instanceScope[A](action: ScalaInstance => A):A={
    val instance = ScalaInstance(instantiationLibraryJar.asFile, instantiationCompilerJar.asFile, info.launcher, msilJar.asFile, fjbgJar.asFile)
    log.debug("Compiler will be instantiated by :" +instance.compilerJar +" and :" +instance.libraryJar )
    action(instance)
  }

  // All path values must be lazy in order to avoid initialization issues (sbt way of doing things)
  lazy val layerOutput = outputRootPath / name
  lazy val pathLayout = new PathLayout(projectRoot, layerOutput)
  lazy val manifestPath = projectRoot/"META-INF"/"MANIFEST.MF"

  // Utility methods (for quick access)
  def libraryOutput = libraryConfig.outputDirectory
  def actorsOutput = actorsConfig.outputDirectory
  def dbcOutput = dbcConfig.outputDirectory
  def swingOutput = swingConfig.outputDirectory
  def scalapOutput = scalapConfig.outputDirectory
  def librarySrcDir = libraryConfig.srcDir
  def compilerOutput = compilerConfig.outputDirectory
  def compilerSrcDir = compilerConfig.srcDir
  def actorsSrcDir = actorsConfig.srcDir
  def swingSrcDir = swingConfig.srcDir
  def outputLibraryJar = libraryWS.jarDestination
  def outputCompilerJar = compilerConfig.jarDestination
  def outputPartestJar = partestConfig.jarDestination
  def outputScalapJar = scalapConfig.jarDestination

  // CONFIGURATION OF THE COMPILTATION STEPS

 /**
   *  Configuration of the core library compilation
   */
  lazy val libraryConfig = new CompilationStep("library", pathLayout ,log) with ResourcesToCopy with PropertiesToWrite{
    def label = "["+name+"] library"
    def options: Seq[String] = Seq("-sourcepath", pathConfig.sources.absolutePath.toString)
    def dependencies = Nil
    override def classpath = super.classpath +++ forkJoinJar

    def copyDestination = outputDirectory
    def filesToCopy = getResources(srcDir)

    def propertyDestination = outputDirectory / "library.properties"
    def propertyList = ("version.number",versionNumber)::("copyright.string",copyright.value)::Nil
  }

  /**
   * Configuration of the compiler
   */
  lazy val compilerConfig = new CompilationStep("compiler", pathLayout, log) with ResourcesToCopy with PropertiesToWrite with Packaging{
    def label = "["+name+"] compiler"
    private def bootClassPath : String = {
      System.getProperty("sun.boot.class.path")
    }
    override def classpath: PathFinder = super.classpath +++ fjbgJar +++ msilJar +++ jlineJar +++ antJar +++ forkJoinJar
    def options  = Seq("-bootclasspath",bootClassPath)
    def dependencies = if (minimalCompilation) libraryConfig::Nil else libraryConfig::actorsConfig::dbcConfig::swingConfig::Nil

    def copyDestination = outputDirectory
    def filesToCopy = getResources(srcDir)

    def propertyDestination = outputDirectory / "compiler.properties"
    def propertyList = ("version.number",versionNumber)::("copyright.string",copyright.value)::Nil

    def packagingDestination:Path = packingDestination
    def jarName:String = compilerJarName
    override def jarsToInclude = compilerAdditionalJars
    override def manifest = {
      import java.util.jar.Manifest
      import java.io.FileInputStream
      new Manifest(new FileInputStream(manifestPath.asFile))
    }
    override def jarContent = List(outputDirectory ##)

  }

  /**
   * Config of the actors library
   */
  lazy val actorsConfig = new CompilationStep ("actors", pathLayout,log){
    def label = "["+name+"] actors library"
    override def classpath: PathFinder = super.classpath +++ forkJoinJar
    def options: Seq[String] = Seq()
    def dependencies = libraryConfig::Nil
  }

  /**
   * Config of the dbc library
   */
  lazy val dbcConfig = new CompilationStep("dbc", pathLayout, log) with Packaging{
    def label = "["+name+"] dbc library"
    def options: Seq[String] = Seq()
    def dependencies = libraryConfig::Nil

    def packagingDestination=packingDestination
    def jarName = dbcJarName
    def jarContent = List(outputDirectory ##)

  }

  /**
   * Config of the swing library
   */
  lazy val swingConfig = new CompilationStep("swing", pathLayout, log) with Packaging{
    def label = "["+name+"] swing library"
    def options: Seq[String] = Seq()
    def dependencies = libraryConfig::actorsConfig::Nil

    def packagingDestination=packingDestination
    def jarName = swingJarName
    def jarContent = List(outputDirectory ##)

  }


  /**
   *  Configuration of scalap tool
   */
  lazy val scalapConfig  = new CompilationStep("scalap", pathLayout,log) with Packaging{
    def label = "["+name+"] scalap"
    def options: Seq[String] = Seq()
    def dependencies = libraryConfig::compilerConfig::Nil

    def packagingDestination=packingDestination
    def jarName = scalapJarName
    def jarContent = {
      val decoderProperties = (srcDir ## )/ "decoder.properties"

      List(outputDirectory ##, decoderProperties)
   }
  }

  /**
   * Configuration of the partest tool
   */
  lazy val partestConfig = new CompilationStep("partest", pathLayout,log) with ResourcesToCopy with PropertiesToWrite with Packaging{
    def label = "["+name+"] partest"
    override def classpath: PathFinder = super.classpath +++ antJar +++ forkJoinJar
    def options: Seq[String] = Seq()
    def dependencies = libraryConfig::compilerConfig::scalapConfig::actorsConfig::Nil

    def copyDestination = outputDirectory
    def filesToCopy = getResources(srcDir)

    def propertyDestination = outputDirectory / "partest.properties"
    def propertyList = ("version.number",partestVersionNumber.value.toString)::("copyright.string",copyright.value)::Nil

    def packagingDestination=packingDestination
    def jarName = partestJarName
    def jarContent = List(outputDirectory ##)
  }

  // Grouping compilation steps
  def minimalCompilation = false // It must be true for locker because we do not nedd to compile everything

  def libraryWS:WrapperStep with Packaging
  def toolsWS:WrapperStep


  lazy val allSteps = new WrapperStep(libraryWS::compilerConfig::toolsWS::Nil)





  //Needed Libraries
  //TODO Check if not possible to manage some of them with the sbt dependency management (ivy)
  lazy val lib = projectRoot / "lib"
  lazy val forkJoinJar = lib / forkJoinJarName
  lazy val jlineJar = lib / jlineJarName
  lazy val antJar = lib / "ant" / "ant.jar"
  lazy val fjbgJar = lib / fjbgJarName
  lazy val msilJar = lib /  msilJarName




  //Paths location that must be defined layer by layer
  /*
   * We must define which are the libraries used to instantiate the compiler
   * that will be used to compile this layer.
   */
  def instantiationCompilerJar:Path
  def instantiationLibraryJar:Path
  def packingDestination :Path = layerOutput / "pack"
  def compilerAdditionalJars: List[Path] = Nil
  def libraryAdditionalJars: List[Path] = Nil


  /**
   * Environment for storing properties that
   * 1) need to be saved across sbt session
   * 2) Are local to a layer
   * Used to save the last version of the compiler used to build the layer (for discarding it's product if necessary)
   */
  lazy val layerEnvironment = new BasicEnvironment {
    // use the project's Logger for any properties-related logging
    def log = BasicLayer.this.log

    // the properties file will be read from/stored to project/extra.properties
    def envBackingPath = outputRootPath / ("build-"+name+".properties")

    // define some properties that will go in project/extra.properties
    lazy val lastCompilerVersion:Property[String] = propertyOptional[String]("")
  }
}

object BasicLayer{
  // Some path definitions related strings
  val compilerJarName = "scala-compiler.jar"
  val libraryJarName = "scala-library.jar"
  val scalapJarName = "scalap.jar"
  val dbcJarName = "scala-dbc.jar"
  val swingJarName = "scala-swing.jar"
  val partestJarName = "scala-partest.jar"
  val fjbgJarName = "fjbg.jar"
  val msilJarName = "msil.jar"
  val jlineJarName = "jline.jar"
  val forkJoinJarName = "forkjoin.jar"

  implicit def stringToGlob(s:String):NameFilter=GlobFilter(s)



}