From 9afe2079933c04459cf76086be9b5427aeca1193 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 13 Mar 2010 13:43:29 -0500 Subject: [PATCH] Use arguments file for calling javac to fix issue with long command lines --- src/main/scala/sbt/Compile.scala | 20 ++++++++++++++++++-- src/main/scala/sbt/FileUtilities.scala | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/main/scala/sbt/Compile.scala b/src/main/scala/sbt/Compile.scala index bf65dded7..dbdb7d897 100644 --- a/src/main/scala/sbt/Compile.scala +++ b/src/main/scala/sbt/Compile.scala @@ -69,7 +69,7 @@ sealed abstract class CompilerBase extends CompilerCore // Copyright 2005-2008 LAMP/EPFL // Original author: Martin Odersky -final class Compile(maximumErrors: Int, compiler: AnalyzingCompiler, analysisCallback: AnalysisCallback, baseDirectory: Path) extends CompilerBase +final class Compile(maximumErrors: Int, compiler: AnalyzingCompiler, analysisCallback: AnalysisCallback, baseDirectory: Path) extends CompilerBase with WithArgumentFile { protected def processScala(sources: Set[File], classpath: Set[File], outputDirectory: File, options: Seq[String], log: Logger) { @@ -80,10 +80,26 @@ final class Compile(maximumErrors: Int, compiler: AnalyzingCompiler, analysisCal { val arguments = (new CompilerArguments(compiler.scalaInstance))(sources, classpath, outputDirectory, options, true) log.debug("Calling 'javac' with arguments:\n\t" + arguments.mkString("\n\t")) - val code = Process("javac", arguments) ! log + def javac(argFile: File) = Process("javac", ("@" + normalizeSlash(argFile.getAbsolutePath)) :: Nil) ! log + val code = withArgumentFile(arguments)(javac) if( code != 0 ) throw new CompileFailed(arguments.toArray, "javac returned nonzero exit code") } } +trait WithArgumentFile extends NotNull +{ + def withArgumentFile[T](args: Seq[String])(f: File => T): T = + { + import xsbt.FileUtilities._ + withTemporaryDirectory { tmp => + val argFile = new File(tmp, "argfile") + write(argFile, args.map(escapeSpaces).mkString(FileUtilities.Newline)) + f(argFile) + } + } + // javac's argument file seems to allow naive space escaping with quotes. escaping a quote with a backslash does not work + def escapeSpaces(s: String): String = '\"' + normalizeSlash(s) + '\"' + def normalizeSlash(s: String) = s.replace(File.separatorChar, '/') +} final class Scaladoc(maximumErrors: Int, compiler: AnalyzingCompiler) extends CompilerCore { protected def processScala(sources: Set[File], classpath: Set[File], outputDirectory: File, options: Seq[String], log: Logger): Unit = diff --git a/src/main/scala/sbt/FileUtilities.scala b/src/main/scala/sbt/FileUtilities.scala index 0ad0d2c9b..863e8d4e5 100644 --- a/src/main/scala/sbt/FileUtilities.scala +++ b/src/main/scala/sbt/FileUtilities.scala @@ -35,7 +35,7 @@ object FileUtilities import wrap.Wrappers.readOnly /** The size of the byte or char buffer used in various methods.*/ private val BufferSize = 8192 - private val Newline = System.getProperty("line.separator") + val Newline = System.getProperty("line.separator") /** A pattern used to split a String by path separator characters.*/ private val PathSeparatorPattern = java.util.regex.Pattern.compile(File.pathSeparator)