mirror of
https://github.com/sbt/sbt.git
synced 2026-10-06 18:14:04 +02:00
Ideally, we wouldn't need to construct the classpath ourselves and instead reuse the classpath construction code from a compiler (scalac or javac). However, we need to ensure that we only call the compiler when needed. Because we need to construct the classpath even when compilation might not happen, we have to duplicate classpath construction.
74 lines
3.6 KiB
Scala
74 lines
3.6 KiB
Scala
/* sbt -- Simple Build Tool
|
|
* Copyright 2009, 2010 Mark Harrah
|
|
*/
|
|
package sbt
|
|
package compiler
|
|
|
|
import xsbti.ArtifactInfo
|
|
import scala.util
|
|
import java.io.File
|
|
import CompilerArguments.{abs, absString, BootClasspathOption}
|
|
|
|
/** Forms the list of options that is passed to the compiler from the required inputs and other options.
|
|
* The directory containing scala-library.jar and scala-compiler.jar (scalaLibDirectory) is required in
|
|
* order to add these jars to the boot classpath. The 'scala.home' property must be unset because Scala
|
|
* puts jars in that directory on the bootclasspath. Because we use multiple Scala versions,
|
|
* this would lead to compiling against the wrong library jar.*/
|
|
final class CompilerArguments(scalaInstance: xsbti.compile.ScalaInstance, cp: xsbti.compile.ClasspathOptions)
|
|
{
|
|
def apply(sources: Seq[File], classpath: Seq[File], outputDirectory: File, options: Seq[String]): Seq[String] =
|
|
{
|
|
checkScalaHomeUnset()
|
|
val cpWithCompiler = finishClasspath(classpath)
|
|
// Scala compiler's treatment of empty classpath is troublesome (as of 2.9.1).
|
|
// We append a random dummy element as workaround.
|
|
val dummy = "dummy_" + Integer.toHexString(util.Random.nextInt)
|
|
val classpathOption = Seq("-classpath", if(cpWithCompiler.isEmpty) dummy else absString(cpWithCompiler))
|
|
val outputOption = Seq("-d", outputDirectory.getAbsolutePath)
|
|
options ++ outputOption ++ bootClasspathOption(hasLibrary(classpath)) ++ classpathOption ++ abs(sources)
|
|
}
|
|
def finishClasspath(classpath: Seq[File]): Seq[File] =
|
|
filterLibrary(classpath) ++ include(cp.compiler, scalaInstance.compilerJar) ++ include(cp.extra, scalaInstance.otherJars : _*)
|
|
private[this] def include(flag: Boolean, jars: File*) = if(flag) jars else Nil
|
|
private[this] def abs(files: Seq[File]) = files.map(_.getAbsolutePath).sortWith(_ < _)
|
|
private[this] def checkScalaHomeUnset()
|
|
{
|
|
val scalaHome = System.getProperty("scala.home")
|
|
assert((scalaHome eq null) || scalaHome.isEmpty, "'scala.home' should not be set (was " + scalaHome + ")")
|
|
}
|
|
def createBootClasspathFor(classpath: Seq[File]) = createBootClasspath(hasLibrary(classpath))
|
|
|
|
/** Add the correct Scala library jar to the boot classpath if `addLibrary` is true.*/
|
|
def createBootClasspath(addLibrary: Boolean) =
|
|
{
|
|
val originalBoot = System.getProperty("sun.boot.class.path", "")
|
|
if(addLibrary)
|
|
{
|
|
val newBootPrefix = if(originalBoot.isEmpty) "" else originalBoot + File.pathSeparator
|
|
newBootPrefix + scalaInstance.libraryJar.getAbsolutePath
|
|
}
|
|
else
|
|
originalBoot
|
|
}
|
|
def filterLibrary(classpath: Seq[File]) = if(cp.filterLibrary) classpath filterNot isScalaLibrary else classpath
|
|
def hasLibrary(classpath: Seq[File]) = classpath exists isScalaLibrary
|
|
private[this] val isScalaLibrary: File => Boolean = file => {
|
|
val name = file.getName
|
|
(name contains ArtifactInfo.ScalaLibraryID) || file.getName == scalaInstance.libraryJar.getName
|
|
}
|
|
def bootClasspathOption(addLibrary: Boolean) = if(cp.autoBoot) Seq(BootClasspathOption, createBootClasspath(addLibrary)) else Nil
|
|
def bootClasspath(addLibrary: Boolean) = if(cp.autoBoot) IO.parseClasspath(createBootClasspath(addLibrary)) else Nil
|
|
def bootClasspathFor(classpath: Seq[File]) = bootClasspath(hasLibrary(classpath))
|
|
|
|
import Path._
|
|
def extClasspath: Seq[File] = ( IO.parseClasspath(System.getProperty("java.ext.dirs")) * "*.jar" ).get
|
|
}
|
|
object CompilerArguments
|
|
{
|
|
val BootClasspathOption = "-bootclasspath"
|
|
def abs(files: Seq[File]): Seq[String] = files.map(_.getAbsolutePath)
|
|
def abs(files: Set[File]): Seq[String] = abs(files.toSeq)
|
|
def absString(files: Seq[File]): String = abs(files).mkString(File.pathSeparator)
|
|
def absString(files: Set[File]): String = absString(files.toSeq)
|
|
}
|