diff options
Diffstat (limited to 'project/build')
-rw-r--r-- | project/build/AdditionalResources.scala | 10 | ||||
-rw-r--r-- | project/build/BasicLayer.scala | 192 | ||||
-rw-r--r-- | project/build/BuildInfoEnvironment.scala | 21 | ||||
-rw-r--r-- | project/build/Compilation.scala | 85 | ||||
-rw-r--r-- | project/build/CompilationStep.scala | 11 | ||||
-rw-r--r-- | project/build/Packer.scala | 94 | ||||
-rw-r--r-- | project/build/PathConfig.scala | 19 | ||||
-rw-r--r-- | project/build/ScalaBuildProject.scala | 37 | ||||
-rw-r--r-- | project/build/ScalaSBTBuilder.scala | 178 |
9 files changed, 473 insertions, 174 deletions
diff --git a/project/build/AdditionalResources.scala b/project/build/AdditionalResources.scala index 3db7fe6ed2..b1f727df6b 100644 --- a/project/build/AdditionalResources.scala +++ b/project/build/AdditionalResources.scala @@ -10,7 +10,7 @@ import AdditionalResources._ trait AdditionalResources { self : BasicLayer => - lazy val copyAdditionalFiles = task { + /* lazy val copyAdditionalFiles = task { def copy0(steps:List[Step]):Option[String]= steps match{ case x::xs => x match{ case c:ResourcesToCopy => { @@ -21,9 +21,9 @@ trait AdditionalResources { case Nil => None } copy0(allSteps.topologicalSort) - }.dependsOn(externalCompilation) + }.dependsOn(externalCompilation)*/ - lazy val writeProperties = task { + def writeProperties: Option[String] = { def write0(steps:List[Step]):Option[String]= steps match{ case x::xs => x match{ case c:PropertiesToWrite => { @@ -34,8 +34,7 @@ trait AdditionalResources { case Nil => None } write0(allSteps.topologicalSort) - }.dependsOn(externalCompilation) - + } @@ -59,6 +58,7 @@ trait ResourcesToCopy { def copyDestination:Path def filesToCopy:PathFinder def copy = { + log.info("Copying files for "+name) try{ FileUtilities.copy(filesToCopy.get,copyDestination,log) }catch{ diff --git a/project/build/BasicLayer.scala b/project/build/BasicLayer.scala index a28b593c1a..084fcf3072 100644 --- a/project/build/BasicLayer.scala +++ b/project/build/BasicLayer.scala @@ -1,6 +1,7 @@ import sbt._ import xsbt.{ScalaInstance} import BasicLayer._ +import ScalaBuildProject._ import scala.collection.immutable.{EmptyMap} /** @@ -8,14 +9,30 @@ import scala.collection.immutable.{EmptyMap} * 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{ +abstract class BasicLayer(val info:ProjectInfo,val versionNumber:String, previousLayer:Option[BasicLayer]) + extends ScalaBuildProject with ReflectiveProject + with AdditionalResources with LayerCompilation with BuildInfoEnvironment{ + + layer => + + // All path values must be lazy in order to avoid initialization issues (sbt way of doing things) + + def buildInfoEnvironmentLocation:Path=outputRootPath / ("build-"+name+".properties") + + override def dependencies = info.dependencies - lazy val projectRoot = info.projectPath lazy val copyright = property[String] lazy val partestVersionNumber = property[Version] + lazy val nextLayer:Option[BasicLayer]=None + lazy val libsDestination=packingDestination/"lib" + lazy val packedStarrOutput=outputRootPath / "pasta" + lazy val requiredPluginsDirForCompilation = layerOutput / "misc" / "scala-devel" / "plugins" + + + + // TASKS /** * Before compiling the layer, we need to check that the previous layer @@ -28,9 +45,15 @@ abstract class BasicLayer(val info:ProjectInfo,val versionNumber:String, previou case None => task{None} } + def buildLayer:Option[String] = { + externalCompilation orElse + writeProperties + } + lazy val build= task{ - None - }.dependsOn(externalCompilation,copyAdditionalFiles,writeProperties) + buildLayer + }.dependsOn(startLayer) + /** * Finish the compilation and ressources copy and generation @@ -38,18 +61,21 @@ abstract class BasicLayer(val info:ProjectInfo,val versionNumber:String, previou * it permit locker to override it in order to lock the layer when the compilation * is finished. */ - lazy val finishLayer = task{None}.dependsOn(build) + lazy val finishLayer:ManagedTask = task{None}.dependsOn(build) + + + def cleaningList=layerOutput::layerEnvironment.envBackingPath::packingDestination::Nil + + lazy val cleanFiles = FileUtilities.clean(cleaningList,true,log) + + lazy val clean:Task = nextLayer match { + case None => super.task{ cleanFiles}// We use super.task, so cleaning is done in every case, even when locked + case Some(next) => super.task{cleanFiles}.dependsOn{next.clean} - 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 @@ -62,10 +88,10 @@ abstract class BasicLayer(val info:ProjectInfo,val versionNumber:String, previou 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 + def outputLibraryJar = libraryWS.packagingConfig.jarDestination + def outputCompilerJar = compilerConfig.packagingConfig.jarDestination + def outputPartestJar = partestConfig.packagingConfig.jarDestination + def outputScalapJar = scalapConfig.packagingConfig.jarDestination // CONFIGURATION OF THE COMPILTATION STEPS @@ -73,7 +99,7 @@ abstract class BasicLayer(val info:ProjectInfo,val versionNumber:String, previou * Configuration of the core library compilation */ lazy val libraryConfig = new CompilationStep("library", pathLayout ,log) with ResourcesToCopy with PropertiesToWrite{ - def label = "["+name+"] library" + def label = "["+layer.name+"] library" def options: Seq[String] = Seq("-sourcepath", pathConfig.sources.absolutePath.toString) def dependencies = Nil override def classpath = super.classpath +++ forkJoinJar @@ -89,7 +115,7 @@ abstract class BasicLayer(val info:ProjectInfo,val versionNumber:String, previou * Configuration of the compiler */ lazy val compilerConfig = new CompilationStep("compiler", pathLayout, log) with ResourcesToCopy with PropertiesToWrite with Packaging{ - def label = "["+name+"] compiler" + def label = "["+layer.name+"] compiler" private def bootClassPath : String = { System.getProperty("sun.boot.class.path") } @@ -103,23 +129,23 @@ abstract class BasicLayer(val info:ProjectInfo,val versionNumber:String, previou 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 = { + lazy val packagingConfig = { import java.util.jar.Manifest import java.io.FileInputStream - new Manifest(new FileInputStream(manifestPath.asFile)) + val manifest = new Manifest(new FileInputStream(manifestPath.asFile)) + new PackagingConfiguration(libsDestination / compilerJarName, List(outputDirectory ##),manifest ,compilerAdditionalJars) } - override def jarContent = List(outputDirectory ##) + lazy val starrPackagingConfig = new PackagingConfiguration(packedStarrOutput/compilerJarName, List(outputDirectory ##)) } + //// ADDTIONNAL LIBRARIES //// + /** * Config of the actors library */ lazy val actorsConfig = new CompilationStep ("actors", pathLayout,log){ - def label = "["+name+"] actors library" + def label = "["+layer.name+"] actors library" override def classpath: PathFinder = super.classpath +++ forkJoinJar def options: Seq[String] = Seq() def dependencies = libraryConfig::Nil @@ -129,13 +155,11 @@ abstract class BasicLayer(val info:ProjectInfo,val versionNumber:String, previou * Config of the dbc library */ lazy val dbcConfig = new CompilationStep("dbc", pathLayout, log) with Packaging{ - def label = "["+name+"] dbc library" + def label = "["+layer.name+"] dbc library" def options: Seq[String] = Seq() def dependencies = libraryConfig::Nil - def packagingDestination=packingDestination - def jarName = dbcJarName - def jarContent = List(outputDirectory ##) + lazy val packagingConfig = new PackagingConfiguration(libsDestination / dbcJarName,List(outputDirectory ##)) } @@ -143,39 +167,35 @@ abstract class BasicLayer(val info:ProjectInfo,val versionNumber:String, previou * Config of the swing library */ lazy val swingConfig = new CompilationStep("swing", pathLayout, log) with Packaging{ - def label = "["+name+"] swing library" + def label = "["+layer.name+"] swing library" def options: Seq[String] = Seq() def dependencies = libraryConfig::actorsConfig::Nil - def packagingDestination=packingDestination - def jarName = swingJarName - def jarContent = List(outputDirectory ##) + lazy val packagingConfig = new PackagingConfiguration(libsDestination / swingJarName,List(outputDirectory ##)) + } + ///// TOOLS CONFIGURATION //////// /** * Configuration of scalap tool */ lazy val scalapConfig = new CompilationStep("scalap", pathLayout,log) with Packaging{ - def label = "["+name+"] scalap" + def label = "["+layer.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" + val decoderProperties = (srcDir ## )/ "decoder.properties" - List(outputDirectory ##, decoderProperties) - } + lazy val packagingConfig = new PackagingConfiguration(libsDestination / scalapJarName,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" + def label = "["+layer.name+"] partest" override def classpath: PathFinder = super.classpath +++ antJar +++ forkJoinJar def options: Seq[String] = Seq() def dependencies = libraryConfig::compilerConfig::scalapConfig::actorsConfig::Nil @@ -186,19 +206,59 @@ abstract class BasicLayer(val info:ProjectInfo,val versionNumber:String, previou def propertyDestination = outputDirectory / "partest.properties" def propertyList = ("version.number",partestVersionNumber.value.toString)::("copyright.string",copyright.value)::Nil - def packagingDestination=packingDestination - def jarName = partestJarName + lazy val packagingConfig = new PackagingConfiguration(libsDestination / partestJarName,List(outputDirectory ##)) + + } + + ///// PLUGINS CONFIGURATION //////// + + + lazy val continuationPluginConfig = new CompilationStep("continuation-plugin", + new PathConfig{ + def projectRoot:Path = pathLayout.projectRoot + def sources:Path = pathLayout.srcDir / "continuations" / "plugin" + def analysis:Path = pathLayout.analysisOutput / "continuations" / "plugin" + def output:Path = pathLayout.classesOutput / "continuations" / "plugin" + } , + log)with ResourcesToCopy with EarlyPackaging { + def label = "["+layer.name+"] continuation plugin" + def dependencies = libraryConfig::compilerConfig::Nil + override def classpath = super.classpath + def options = Seq() + + def filesToCopy = (sourceRoots##) / "scalac-plugin.xml" + def copyDestination = outputDirectory def jarContent = List(outputDirectory ##) + lazy val packagingConfig = new PackagingConfiguration(requiredPluginsDirForCompilation/"continuations.jar",List(outputDirectory ##)) + lazy val earlyPackagingConfig= new PackagingConfiguration(pathLayout.outputDir / "misc" / "scala-devel" / "plugins"/"continuations.jar",List(outputDirectory ##)) + + } + + lazy val continuationLibraryConfig = new CompilationStep("continuation-library", + new PathConfig{ + def projectRoot:Path = pathLayout.projectRoot + def sources:Path = pathLayout.srcDir / "continuations" / "library" + def analysis:Path = pathLayout.analysisOutput / "continuations" / "library" + def output:Path = pathLayout.classesOutput / "continuations" / "library" + }, + log) { + def label = "["+layer.name+"] continuation library" + def dependencies = libraryConfig::compilerConfig::continuationPluginConfig::Nil + def options = Seq("-Xpluginsdir",requiredPluginsDirForCompilation.absolutePath,"-Xplugin-require:continuations","-P:continuations:enable") + } + + + // 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 pluginsWS = new WrapperStep(continuationPluginConfig::continuationLibraryConfig::Nil) - - lazy val allSteps = new WrapperStep(libraryWS::compilerConfig::toolsWS::Nil) + lazy val allSteps = new WrapperStep(libraryWS::compilerConfig::pluginsWS::toolsWS::Nil) @@ -206,12 +266,6 @@ abstract class BasicLayer(val info:ProjectInfo,val versionNumber:String, previou //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 @@ -221,45 +275,15 @@ abstract class BasicLayer(val info:ProjectInfo,val versionNumber:String, previou * 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) + implicit def stringToGlob(s:String):NameFilter=GlobFilter(s) diff --git a/project/build/BuildInfoEnvironment.scala b/project/build/BuildInfoEnvironment.scala new file mode 100644 index 0000000000..682b8af5da --- /dev/null +++ b/project/build/BuildInfoEnvironment.scala @@ -0,0 +1,21 @@ +import sbt._ +trait BuildInfoEnvironment{ + self : Project => + def buildInfoEnvironmentLocation:Path + /** + * 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 = self.log + + // the properties file will be read/stored + def envBackingPath = buildInfoEnvironmentLocation + // define some properties + lazy val lastCompilerVersion:Property[String] = propertyOptional[String]("") + } + +} diff --git a/project/build/Compilation.scala b/project/build/Compilation.scala index 42e3c55902..f634cbc287 100644 --- a/project/build/Compilation.scala +++ b/project/build/Compilation.scala @@ -1,26 +1,33 @@ import sbt._ import xsbt.{AnalyzingCompiler,ScalaInstance} +import FileUtilities._ /** - * This trait define the compilation task. It is possible to configure what it actually compiles by - * overriding the compilationSteps methods (useful because locker does not compile everything) - * @author Grégory Moix + * This trait define the compilation task. +* @author Grégory Moix */ -trait Compilation{ - self : BasicLayer => +trait Compilation { + self : ScalaBuildProject with BuildInfoEnvironment => def lastUsedCompilerVersion = layerEnvironment.lastCompilerVersion - def cleanCompilation:Option[String]= { - log.info("Cleaning the products of the compilation.") - FileUtilities.clean(layerOutput::Nil,true,log) + def instantiationCompilerJar:Path + def instantiationLibraryJar:Path + + + 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) } + def compile(stepList:Step,clean:()=>Option[String]):Option[String]=compile(stepList,Some(clean)) + def compile(stepList:Step):Option[String]=compile(stepList,None) /** * Execute the different compilation parts one after the others. */ - def compile:Option[String]={ + def compile(stepsList:Step,clean:Option[()=>Option[String]]):Option[String]={ instanceScope[Option[String]]{ scala => lazy val analyzing = new AnalyzingCompiler(scala,componentManager,xsbt.ClasspathOptions.manual,log) @@ -31,12 +38,12 @@ trait Compilation{ } - def checkAndClean:Option[String]={ + def checkAndClean(cleanFunction:()=>Option[String]):Option[String]={ if (compilerVersionHasChanged){ - log.info("The compiler version used to build this layer has changed since last time.") + log.info("The compiler version used to build this layer has changed since last time or this is a clean build.") lastUsedCompilerVersion.update(scala.actualVersion) layerEnvironment.saveEnvironment - cleanCompilation + cleanFunction() }else{ log.debug("The compiler version is unchanged. No need for cleaning.") None @@ -48,39 +55,59 @@ trait Compilation{ case c:CompilationStep => { val conditional = new CompileConditional(c, analyzing) log.info("") - conditional.run orElse compile0(xs) + conditional.run orElse copy(c) orElse earlyPackaging(c) orElse compile0(xs) } case _ => compile0(xs) } case Nil => None } + /** + * When we finishe to compile a step we want to jar if necessary in order to + * be able to load plugins for the associated library + */ + def earlyPackaging(step:CompilationStep):Option[String]= step match { + case s:EarlyPackaging => { + val c = s.earlyPackagingConfig + log.debug("Creating jar for plugin") + jar(c.content.flatMap(Packer.jarPattern(_)),c.jarDestination,c.manifest, false, log) + } + case _ => None + } - checkAndClean orElse compile0(allSteps.topologicalSort) + def copy(step:CompilationStep):Option[String]= step match { + case s:ResourcesToCopy => s.copy + case _ => None + } + + def cleanIfNecessary:Option[String] = clean match{ + case None => None + case Some(f) => checkAndClean(f) + } + cleanIfNecessary orElse compile0(stepsList.topologicalSort) } } + +} + +trait LayerCompilation extends Compilation{ + self : BasicLayer => + + protected def cleanCompilation:Option[String]= { + log.info("Cleaning the products of the compilation.") + FileUtilities.clean(layerOutput::Nil,true,log) + } + /** * Run the actual compilation. Should not be called directly because it is executed on the same jvm and that * it could lead to memory issues. It is used only when launching a new sbt process to do the compilation. */ - lazy val compilation = task{compile} + lazy val compilation = task{compile(allSteps,cleanCompilation _)} - /** - * Runs the compilation in another process in order to circumvent memory issues that - * arises when compiling every layer on the same jvm. - */ - lazy val externalCompilation:ManagedTask=task{ + def externalCompilation:Option[String] = { val runner = new ExternalTaskRunner(projectRoot,this.name,compilation.name, log) runner.runTask - }.dependsOn(startLayer) - - /** - * This method permits to specify what are the different steps of the compilation process, - * meaning that you can customize exactly what is compiled by overriding it. It is overriden by - * the locker layer that doesn't compile actors, sbc, scalap, partest - */ - def compilationSteps:List[CompileConfiguration] = - libraryConfig::actorsConfig::dbcConfig::swingConfig::compilerConfig::scalapConfig::partestConfig::Nil + } } diff --git a/project/build/CompilationStep.scala b/project/build/CompilationStep.scala index 02d76b9a54..be587de564 100644 --- a/project/build/CompilationStep.scala +++ b/project/build/CompilationStep.scala @@ -1,5 +1,6 @@ import sbt._ import BasicLayer._ + trait Step extends Dag[Step] { def dependencies:Iterable[Step] } @@ -12,15 +13,15 @@ abstract class CompilationStep(val name:String, val pathConfig:PathConfig, logge def this(name:String, layout:PathLayout,logger:Logger) = this(name, layout / name, logger) // Utility methods (for quick access, ...) - def srcDir = pathConfig.sources + final def srcDir = pathConfig.sources // Methods required for the compilation def log: Logger = logger - def sourceRoots : PathFinder = pathConfig.sources + final def sourceRoots : PathFinder = pathConfig.sources def sources: PathFinder = sourceRoots.descendentsExcept("*.java" | "*.scala", ".svn") - def projectPath: Path = pathConfig.projectRoot - def analysisPath: Path = pathConfig.analysis - def outputDirectory: Path = pathConfig.output + final def projectPath: Path = pathConfig.projectRoot + final def analysisPath: Path = pathConfig.analysis + final def outputDirectory: Path = pathConfig.output def classpath = { def addDependenciesOutputTo(list:List[Step],acc:PathFinder):PathFinder = list match{ case Nil => acc diff --git a/project/build/Packer.scala b/project/build/Packer.scala index 8e3be9d9a3..8450f212fb 100644 --- a/project/build/Packer.scala +++ b/project/build/Packer.scala @@ -4,22 +4,30 @@ import java.util.jar.Manifest import BasicLayer._ import FileUtilities._ -/** - * Create the jars of pack - * @author Grégory Moix - */ -trait Packer { - self: BasicLayer => - def libraryToCopy:List[Path] = Nil - protected def jarPattern(path:PathFinder) = path.descendentsExcept(AllPassFilter, defaultExcludes || new ExactFilter("MANIFEST.MF")).get +object Packer { + + /** + * A filter that exclude files that musn't be in a jar file. + */ + // We must exclude the manifest because we generate it automatically, and when we add multiples other jars, they could have + // also a manifest files each, resulting in conflicts for the FileUtilities.jar(..) method + def jarPattern(path:PathFinder) = path.descendentsExcept(AllPassFilter, (".*" - ".") || HiddenFileFilter || new ExactFilter("MANIFEST.MF")).get + + def createJar(j:Packaging,log:Logger):Option[String]=createJar(j.packagingConfig,log,jarPattern _,true) + def createJar(j:PackagingConfiguration,log:Logger):Option[String]=createJar(j,log,jarPattern _,true) + + + /** + * Create a jar from the packaging trait. Is able to add directly others jars to it + */ + def createJar(j:PackagingConfiguration,log:Logger,filter:(PathFinder)=>Iterable[Path],addIncludedLibs:Boolean):Option[String] = { + def pack0(content:Iterable[Path])=jar(content.flatMap(filter(_)),j.jarDestination, j.manifest, false, log) - def createJar(j:Packaging):Option[String] = { - def pack0(content:Iterable[Path])=jar(content.flatMap(jarPattern(_)),j.jarDestination, j.manifest, false, log) j.jarsToInclude match { - case Nil => pack0(j.jarContent) - case list => { + case Nil => pack0(j.content) + case list if addIncludedLibs => { withTemporaryDirectory(log) { tmp: File => val tmpPath = Path.fromFile(tmp) log.debug("List of jars to be added : " +list) @@ -29,18 +37,34 @@ trait Packer { } unzip0(list) log.debug("Content of temp folder"+ tmpPath.##.**( GlobFilter("*"))) - pack0(j.jarContent ++ Set(tmpPath ##)) + pack0(j.content ++ Set(tmpPath ##)) } } + case _ => pack0(j.content) + } } - lazy val pack= task { +} + +/** + * Create the jars of pack + * @author Grégory Moix + */ +trait Packer { + self: BasicLayer => + + def libraryToCopy:List[Path] = Nil + /** + * The actual pack task. + */ + def packF= { + import Packer._ def iterate(steps:List[Step]):Option[String]= steps match{ case x::xs => x match{ case c:Packaging => { - createJar(c) orElse iterate(xs) + createJar(c,log) orElse iterate(xs) } case _ => iterate(xs) } @@ -56,19 +80,28 @@ trait Packer { } } iterate(allSteps.topologicalSort) orElse copy0 - }.dependsOn(finishLayer) - - - + } + lazy val pack=task{packF}.dependsOn(finishLayer) +} +class PackagingConfiguration(val jarDestination:Path, val content:Iterable[Path],val manifest:Manifest,val jarsToInclude:List[Path]){ + def this(jarDestination:Path,content:Iterable[Path])=this(jarDestination,content, new Manifest,Nil) + def this(jarDestination:Path,content:Iterable[Path],jarsToInclude:List[Path])=this(jarDestination,content,new Manifest, jarsToInclude) + //def this(jarName:String,destinationFunction:(String)=>Path,content:Iterable[Path],manifest:Manifest,jarsToInclude:List[Path]) = + // this(destinationFunction(jarName),content,manifest,jarsToInclude) + //def this(jarName:String,destinationFunction:(String)=>Path,content:Iterable[Path]) = + // this(jarName,destinationFunction,content, new Manifest, Nil) } trait Packaging extends Step{ - def manifest = new Manifest - def jarDestination:Path = packagingDestination /"lib" / jarName - def packagingDestination:Path - def jarName:String - def jarsToInclude:List[Path] = Nil - def jarContent:Iterable[Path] + //def manifest = new Manifest + //final def simplePath = packagingDestination / jarName + //final def libPath = packagingDestination /"lib" / jarName + //def jarDestination:Path = libPath + //def packagingDestination:Path + //def jarName:String + //def jarsToInclude:List[Path] = Nil + //def jarContent:Iterable[Path] + def packagingConfig:PackagingConfiguration } @@ -85,5 +118,16 @@ trait WrapperPackaging extends Packaging { } getContent(dependencies.toList,Nil) } +} +/** + * This trait is here to add the possiblity to have a different packing destination that is used right after the + * compilation of the step has finished. It permits to have use libraries that are build using a plugin. (The plugin must + * be a jar in order to be recognised by the compiler. + */ +trait EarlyPackaging extends Packaging{ + self:CompilationStep => + //def earlyPackagingDestination:Path + //def earlyJarDestination = earlyPackagingDestination / jarName + def earlyPackagingConfig:PackagingConfiguration } diff --git a/project/build/PathConfig.scala b/project/build/PathConfig.scala index 4dc91772e1..b5cce66a2c 100644 --- a/project/build/PathConfig.scala +++ b/project/build/PathConfig.scala @@ -12,15 +12,20 @@ abstract class PathConfig { def output:Path } -/** - * - */ +object PathConfig { + val classes = "classes" + val analysis = "analysis" +} -class PathLayout(val projectRoot:Path, val outputDir:Path) { - lazy val srcDir = projectRoot / "src" - lazy val classesOutput = outputDir / "classes" - lazy val analysisOutput = outputDir / "analysis" +trait SimpleOutputLayout{ + def outputDir:Path + lazy val classesOutput = outputDir / PathConfig.classes + lazy val analysisOutput = outputDir / PathConfig.analysis + +} +class PathLayout(val projectRoot:Path, val outputDir:Path) extends SimpleOutputLayout { + lazy val srcDir = projectRoot / "src" /** * An utility method to easily create StandardPathConfig from a given path layout */ diff --git a/project/build/ScalaBuildProject.scala b/project/build/ScalaBuildProject.scala new file mode 100644 index 0000000000..e31b3a8d4a --- /dev/null +++ b/project/build/ScalaBuildProject.scala @@ -0,0 +1,37 @@ +import sbt._ +import ScalaBuildProject._ + + +abstract class ScalaBuildProject extends Project{ + lazy val projectRoot = info.projectPath + lazy val layerOutput = outputRootPath / name + lazy val pathLayout = new PathLayout(projectRoot, layerOutput) + + lazy val manifestPath = projectRoot/"META-INF"/"MANIFEST.MF" + + 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 + + + +} + +object ScalaBuildProject { + // 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" + + +} diff --git a/project/build/ScalaSBTBuilder.scala b/project/build/ScalaSBTBuilder.scala index 10b90247bb..2720e82c82 100644 --- a/project/build/ScalaSBTBuilder.scala +++ b/project/build/ScalaSBTBuilder.scala @@ -1,19 +1,30 @@ import sbt._ -import BasicLayer._ +import ScalaBuildProject._ /** * This class is the entry point for building scala with SBT. * @author Grégory Moix */ class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectiveProject { - override def dependencies: Iterable[Project] = info.dependencies ++ locker.dependencies ++ quick.dependencies ++ strap.dependencies + override def dependencies: Iterable[Project] = info.dependencies ++ locker.dependencies ++ quick.dependencies ++ strap.dependencies ++ libs.dependencies override def shouldCheckOutputDirectories = false - // Main Tasks - - lazy val replaceLocker=task{None}.dependsOn(locker.unlock) + // Top Level Tasks lazy val build = task{None}.dependsOn(quick.binPack,quick.binQuick) + lazy val clean = locker.clean lazy val docs = quick.scaladoc + lazy val palo = locker.pack + lazy val pasta = quick.pasta + lazy val newStarr = quick.newStarr + lazy val newLocker=locker.newLocker + lazy val buildForkjoin=libs.buildForkjoin + lazy val newForkjoin = libs.newForkjoin + lazy val buildFjbg = libs.buildFjbg + lazy val newFjbg = libs.newFjbg + lazy val buildMsil = libs.buildMsil + lazy val newMsil = libs.newMsil + + // Top level variables @@ -56,6 +67,8 @@ class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectivePro lazy val locker=project(info.projectPath,"locker", new LockerLayer(_)) lazy val quick=project(info.projectPath,"quick",new QuickLayer(_,locker)) lazy val strap=project(info.projectPath,"strap", new StrapLayer(_, quick)) + lazy val libs=project(info.projectPath,"libs", new LibsBuilder(_)) + /** * Definition of what is specific to the locker layer. It implements SimplePacker in order to @@ -63,8 +76,8 @@ class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectivePro */ class LockerLayer(info:ProjectInfo) extends BasicLayer(info,versionNumber,None) with Packer{ - import BasicLayer._ + override lazy val nextLayer=Some(quick) lazy val instantiationCompilerJar = lib / compilerJarName lazy val instantiationLibraryJar = lib / libraryJarName lazy val lockFile = layerOutput / "locker.lock" @@ -83,26 +96,43 @@ class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectivePro else action } + def deleteLock = FileUtilities.clean(lockFile,log) + def createLock = { + log.info("locking "+name) + FileUtilities.touch(lockFile,log) + } + /** * Task for locking locker */ lazy val lock = super.task{ - log.info("locking "+name) - FileUtilities.touch(lockFile,log) + createLock } /** * Task for unlocking locker */ lazy val unlock = super.task{ - FileUtilities.clean(lockFile,log) + deleteLock } + lazy val newLocker = super.task{ + createNewLocker + } + def createNewLocker = { + deleteLock orElse + buildLayer orElse + createLock + } + + /** * Making locker being locked when it has finished building */ override lazy val finishLayer = lock.dependsOn(build) + override lazy val pack = super.task{packF}.dependsOn(finishLayer) + override lazy val packingDestination:Path = outputRootPath /"palo" @@ -112,11 +142,11 @@ class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectivePro */ override lazy val libraryWS = { new WrapperStep(libraryConfig::Nil) with WrapperPackaging{ - def jarName = libraryJarName - def packagingDestination = packingDestination + lazy val packagingConfig = new PackagingConfiguration(libsDestination/libraryJarName, jarContent) } } override val minimalCompilation = true + override lazy val pluginsWS:WrapperStep = new WrapperStep(Nil) override lazy val toolsWS = new WrapperStep(Nil) } @@ -128,24 +158,61 @@ class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectivePro class QuickLayer(info:ProjectInfo, previous:BasicLayer) extends BasicLayer(info,versionNumber,Some(previous)) with Packer with ScalaTools with Scaladoc{ + override lazy val nextLayer=Some(strap) + + lazy val instantiationCompilerJar = previous.compilerOutput lazy val instantiationLibraryJar = previous.libraryOutput override lazy val packingDestination:Path = outputRootPath/ "pack" + override def libraryToCopy = jlineJar::Nil override def compilerAdditionalJars = msilJar::fjbgJar::Nil override def libraryAdditionalJars = forkJoinJar::Nil + override lazy val libraryWS = new WrapperStep(libraryConfig::actorsConfig::dbcConfig::swingConfig::Nil)with Packaging{ - def jarName = libraryJarName - def packagingDestination = packingDestination - def jarContent = List(libraryConfig.outputDirectory ## , actorsConfig.outputDirectory ## ) - override def jarsToInclude = libraryAdditionalJars - } + def jarContent = List(libraryConfig , actorsConfig, continuationLibraryConfig).map(_.outputDirectory ##) + lazy val starrJarContent=List(libraryConfig , actorsConfig,dbcConfig,swingConfig, continuationLibraryConfig).map(_.outputDirectory ##) + lazy val packagingConfig = new PackagingConfiguration(libsDestination/libraryJarName,jarContent,libraryAdditionalJars) + lazy val starrPackagingConfig = new PackagingConfiguration(packedStarrOutput/libraryJarName,starrJarContent) + + } + override lazy val toolsWS = new WrapperStep(scalapConfig::partestConfig::Nil) + // An additional task for building only the library of quick + // Used for compiling msil + lazy val compileLibraryOnly = task{ + compile(libraryConfig, cleanCompilation _) + } + lazy val externalCompileLibraryOnly = task{ + val runner = new ExternalTaskRunner(projectRoot,this.name,compileLibraryOnly.name, log) + runner.runTask + }.dependsOn(startLayer) + + + def createNewStarrJar:Option[String]={ + import Packer._ + createJar(libraryWS.starrPackagingConfig,log) orElse + createJar(compilerConfig.starrPackagingConfig,log) + } + lazy val pasta = task{ + createNewStarrJar + }.dependsOn(build) + + lazy val newStarr = task{ + val files = (packedStarrOutput ##) * "*.jar" + FileUtilities.copy(files.get,lib,true,log) match{ + case Right(_) =>None + case Left(_) =>Some("Error occured when copying the new starr to its destination") + } + + }.dependsOn(pasta) + + /* @@ -169,11 +236,84 @@ class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectivePro lazy val instantiationLibraryJar = previous.libraryOutput override lazy val libraryWS = new WrapperStep(libraryConfig::actorsConfig::dbcConfig::swingConfig::Nil) with WrapperPackaging{ - def jarName = libraryJarName - def packagingDestination = packingDestination + lazy val packagingConfig = new PackagingConfiguration(libsDestination/libraryJarName,Set()) + } override lazy val toolsWS= new WrapperStep(scalapConfig::partestConfig::Nil) } -} + + + + /** + * An additional subproject used to build new version of forkjoin,fjbg and msil + */ + class LibsBuilder(val info:ProjectInfo) extends ScalaBuildProject with ReflectiveProject with Compilation with BuildInfoEnvironment { + override def dependencies = info.dependencies + + def buildInfoEnvironmentLocation:Path=outputRootPath / ("build-"+name+".properties") + + def instantiationCompilerJar:Path=locker.compilerOutput + def instantiationLibraryJar:Path=locker.libraryOutput + + def libsDestination = layerOutput + + lazy val checkJavaVersion = task{ + val version = System.getProperty("java.specification.version") + log.debug("java.specification.version="+version) + val required = "1.6" + if (version.startsWith(required)) None else Some("Incompatible java version : required "+required) + } + + + private def simpleBuild(step:CompilationStep with Packaging)=task{ + import Packer._ + compile(step) orElse createJar(step,log) + }.dependsOn(locker.finishLayer) + + private def copyJar(step:CompilationStep with Packaging, name:String) = task { + FileUtilities.copyFile(step.packagingConfig.jarDestination,lib/name,log) + } + + lazy val newForkjoin = copyJar(forkJoinConfig,forkjoinJarName).dependsOn(buildForkjoin) + lazy val buildForkjoin= simpleBuild(forkJoinConfig).dependsOn(checkJavaVersion) + lazy val newFjbg = copyJar(fjbgConfig, fjbgJarName).dependsOn(buildFjbg) + lazy val buildFjbg = simpleBuild(fjbgConfig) + lazy val newMsil = copyJar(msilConfig,msilJarName).dependsOn(buildMsil) + // TODO As msil contains scala files, maybe needed compile it with an ExternalSBTRunner + lazy val buildMsil = simpleBuild(msilConfig).dependsOn(quick.externalCompileLibraryOnly) + + lazy val forkJoinConfig = new CompilationStep("forkjoin",pathLayout,log) with Packaging{ + def label = "new forkjoin library" + override def sources: PathFinder = sourceRoots.descendentsExcept("*.java", ".svn") + def dependencies = Seq() + def options = Seq() + override def javaOptions = Seq("-target","1.5","-source","1.5","-g") + lazy val packagingConfig = new PackagingConfiguration(libsDestination/forkjoinJarName,List(outputDirectory ##)) + + // TODO Verify java options + } + + lazy val fjbgConfig = new CompilationStep("fjbg",pathLayout,log) with Packaging{ + def label = "new fjbg library" + override def sources: PathFinder = sourceRoots.descendentsExcept("*.java", ".svn") + def dependencies = Seq() + def options = Seq() + override def javaOptions = Seq("-target","1.5","-source","1.4","-g") + lazy val packagingConfig = new PackagingConfiguration(libsDestination/fjbgJarName,List(outputDirectory ##)) + + } + + lazy val msilConfig = new CompilationStep("msil",pathLayout,log) with Packaging{ + def label = "new msil library" + override def sources: PathFinder = sourceRoots.descendentsExcept("*.java"|"*.scala", ".svn"|"tests") + def dependencies = Seq() + override def classpath = super.classpath +++ quick.libraryOutput + def options = Seq() + override def javaOptions = Seq("-target","1.5","-source","1.4","-g") + lazy val packagingConfig = new PackagingConfiguration(libsDestination/msilJarName,List(outputDirectory ##)) + + } + } + } |