From 37201dd3cd6da6ca47f651a5b346a7706ae1e561 Mon Sep 17 00:00:00 2001 From: michelou Date: Sun, 27 Nov 2011 11:39:54 +0000 Subject: attempt to fix reopened SI-5196 --- src/compiler/scala/tools/ant/FastScalac.scala | 81 ++++++++++++++++++++------- src/compiler/scala/tools/ant/Scalac.scala | 17 ++++-- 2 files changed, 73 insertions(+), 25 deletions(-) diff --git a/src/compiler/scala/tools/ant/FastScalac.scala b/src/compiler/scala/tools/ant/FastScalac.scala index 96d242ae07..19a1526e67 100644 --- a/src/compiler/scala/tools/ant/FastScalac.scala +++ b/src/compiler/scala/tools/ant/FastScalac.scala @@ -8,10 +8,14 @@ package scala.tools.ant -import org.apache.tools.ant.Project +import org.apache.tools.ant.{AntClassLoader, Project} +import org.apache.tools.ant.taskdefs.Java +import org.apache.tools.ant.types.Path import scala.tools.nsc.Settings +import scala.tools.nsc.io.File import scala.tools.nsc.settings.FscSettings +import scala.tools.nsc.util.ScalaClassLoader /** An Ant task to compile with the fast Scala compiler (`fsc`). * @@ -92,12 +96,6 @@ class FastScalac extends Scalac { s.preferIPv4.value = useIPv4 if (!idleMinutes.isEmpty) s.idleMins.value = idleMinutes.get - val prefixSettings = - List( - /*scalac*/ - s.jvmargs, s.defines - ) flatMap (_.value) - val stringSettings = List( /*scalac*/ @@ -111,7 +109,7 @@ class FastScalac extends Scalac { List( /*scalac*/ s.debuginfo, s.target - ) map (x => "%s:%s".format(x.name, x.value)) + ) filter (x => x.value != x.default) map (x => "%s:%s".format(x.name, x.value)) val booleanSettings = List( @@ -134,20 +132,61 @@ class FastScalac extends Scalac { else List("%s:%s".format(s.name, s.value.mkString(","))) } - val cmdOptions = - prefixSettings ::: stringSettings ::: choiceSettings ::: booleanSettings ::: intSettings ::: phaseSetting - - val args = (cmdOptions ::: (sourceFiles map (_.toString))).toArray - log("FastScalac args="+args.mkString(" "), Project.MSG_DEBUG) - try { - if (!scala.tools.nsc.CompileClient.process(args) && failonerror) - buildError("Compile failed; see the compiler error output for details.") + val fscOptions = + stringSettings ::: choiceSettings ::: booleanSettings ::: intSettings ::: phaseSetting + + val java = new Java(this) + java setFork true + // use same default memory options as in fsc script + java.createJvmarg() setValue "-Xmx256M" + java.createJvmarg() setValue "-Xms32M" + val scalacPath: Path = { + val path = new Path(getProject) + if (compilerPath.isDefined) path add compilerPath.get + else getClass.getClassLoader match { + case cl: AntClassLoader => + path add new Path(getProject, cl.getClasspath) + case _ => + buildError("Compilation failed because of an internal compiler error;"+ + " see the error output for details.") + } + path } - catch { - case ex: Throwable => - ex.printStackTrace() - val msg = if (ex.getMessage == null) "no error message provided" else ex.getMessage - buildError("Compile failed because of an internal compiler error (" + msg + "); see the error output for details.") + java.createJvmarg() setValue ("-Xbootclasspath/a:"+scalacPath) + s.jvmargs.value foreach (java.createJvmarg() setValue _) + + val scalaHome: String = try { + val url = ScalaClassLoader.originOfClass(classOf[FastScalac]).get + File(url.getFile).jfile.getParentFile.getParentFile getAbsolutePath + } catch { + case _ => + buildError("Compilation failed because of an internal compiler error;"+ + " couldn't determine value for -Dscala.home=") } + java.createJvmarg() setValue "-Dscala.usejavacp=true" + java.createJvmarg() setValue ("-Dscala.home="+scalaHome) + s.defines.value foreach (java.createJvmarg() setValue _) + + java setClassname "scala.tools.nsc.MainGenericRunner" + java.createArg() setValue "scala.tools.nsc.CompileClient" + + // Encode scalac/javac args for use in a file to be read back via "@file.txt" + def encodeScalacArgsFile(t: Traversable[String]) = t map { s => + if(s.find(c => c <= ' ' || "\"'\\".contains(c)).isDefined) + "\"" + s.flatMap(c => (if(c == '"' || c == '\\') "\\" else "") + c ) + "\"" + else s + } mkString "\n" + + // dump the arguments to a file and do "java @file" + val tempArgFile = File.makeTemp("fastscalac") + val tokens = fscOptions ++ (sourceFiles map (_.getPath)) + tempArgFile writeAll encodeScalacArgsFile(tokens) + + val paths = List(Some(tempArgFile.toAbsolute.path), argfile).flatten map (_.toString) + val res = execWithArgFiles(java, paths) + + if (failonerror && res != 0) + buildError("Compilation failed because of an internal compiler error;"+ + " see the error output for details.") } } diff --git a/src/compiler/scala/tools/ant/Scalac.scala b/src/compiler/scala/tools/ant/Scalac.scala index 72330615cc..7aff4e3e8e 100644 --- a/src/compiler/scala/tools/ant/Scalac.scala +++ b/src/compiler/scala/tools/ant/Scalac.scala @@ -36,6 +36,7 @@ import scala.tools.nsc.reporters.{Reporter, ConsoleReporter} * - `bootclasspathref`, * - `extdirs`, * - `extdirsref`, + * - `argfile`, * - `dependencyfile`, * - `encoding`, * - `target`, @@ -126,8 +127,9 @@ class Scalac extends ScalaMatchingTask with ScalacShared { /** The external extensions path to use for this compilation. */ protected var extdirs: Option[Path] = None + protected var argfile: Option[File] = None /** The dependency tracking file. */ - protected var dependencyfile: Option[String] = None + protected var dependencyfile: Option[File] = None /** The character encoding of the files to compile. */ protected var encoding: Option[String] = None @@ -229,7 +231,7 @@ class Scalac extends ScalaMatchingTask with ScalacShared { } /** Sets the `compilerPath` attribute. Used by [[http://ant.apache.org Ant]]. * @param input The value of `compilerPath`. */ - def setCompilerPath(input : Path) { + def setCompilerPath(input: Path) { compilerPath = setOrAppend(compilerPath, input) } @@ -299,9 +301,15 @@ class Scalac extends ScalaMatchingTask with ScalacShared { def setExtdirsref(input: Reference) = createExtdirs().setRefid(input) + /** Sets the `argfile` attribute. Used by [[http://ant.apache.org Ant]]. + * @param input The value of `argfile`. */ + def setArgfile(input: File) { + argfile = Some(input) + } + /** Sets the `dependencyfile` attribute. Used by [[http://ant.apache.org Ant]]. * @param input The value of `dependencyfile`. */ - def setDependencyfile(input: String) { + def setDependencyfile(input: File) { dependencyfile = Some(input) } @@ -584,7 +592,8 @@ class Scalac extends ScalaMatchingTask with ScalacShared { if (!bootclasspath.isEmpty) settings.bootclasspath.value = asString(getBootclasspath) if (!extdirs.isEmpty) settings.extdirs.value = asString(getExtdirs) - if (!dependencyfile.isEmpty) settings.dependencyfile.value = dependencyfile.get + if (!dependencyfile.isEmpty) + settings.dependencyfile.value = asString(dependencyfile.get) if (!encoding.isEmpty) settings.encoding.value = encoding.get if (!backend.isEmpty) settings.target.value = backend.get if (!logging.isEmpty && logging.get == "verbose") -- cgit v1.2.3