From f5dd02255158cc34e13da961539e620de76123c5 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Mon, 21 Apr 2014 23:05:27 -0400 Subject: [PATCH] Separate location of analysis cache if we're cross compiling scala. * Add task to determine file-name of analysis cache * If crossPaths := true, then add scala binary version to the analysis cache name. This makes it possible to leverage incremental compilation with the `+` command. Fixes #1267 --- main/src/main/scala/sbt/Defaults.scala | 22 +++++++++++++++---- main/src/main/scala/sbt/Keys.scala | 1 + .../separate-analysis-per-scala/build.sbt | 12 ++++++++++ .../separate-analysis-per-scala/foo.scala | 6 +++++ .../separate-analysis-per-scala/test | 3 +++ 5 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 sbt/src/sbt-test/compiler-project/separate-analysis-per-scala/build.sbt create mode 100644 sbt/src/sbt-test/compiler-project/separate-analysis-per-scala/foo.scala create mode 100644 sbt/src/sbt-test/compiler-project/separate-analysis-per-scala/test diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index d24010467..ba0a1b87a 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -246,6 +246,14 @@ object Defaults extends BuildCommon lazy val configTasks = docTaskSettings(doc) ++ inTask(compile)(compileInputsSettings) ++ configGlobal ++ Seq( compile <<= compileTask tag(Tags.Compile, Tags.CPU), printWarnings <<= printWarningsTask, + compileAnalysisFilename := { + // Here, if the user wants cross-scala-versioning, we also append it + // to the analysis cache, so we keep the scala versions separated. + val extra = + if(crossPaths.value) s"_${scalaBinaryVersion.value}" + else "" + s"inc_compile${extra}" + }, compileIncSetup <<= compileIncSetupTask, console <<= consoleTask, consoleQuick <<= consoleQuickTask, @@ -763,10 +771,16 @@ object Defaults extends BuildCommon } finally x.close() // workaround for #937 } - def compileIncSetupTask = - (dependencyClasspath, skip in compile, definesClass, compilerCache, streams, incOptions) map { (cp, skip, definesC, cache, s, incOptions) => - Compiler.IncSetup(analysisMap(cp), definesC, skip, s.cacheDirectory / "inc_compile", cache, incOptions) - } + def compileIncSetupTask = Def.task { + Compiler.IncSetup( + analysisMap(dependencyClasspath.value), + definesClass.value, + (skip in compile).value, + // TODO - this is kind of a bad way to grab the cache directory for streams... + streams.value.cacheDirectory / compileAnalysisFilename.value, + compilerCache.value, + incOptions.value) + } def compileInputsSettings: Seq[Setting[_]] = Seq(compileInputs := { val cp = classDirectory.value +: data(dependencyClasspath.value) diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 3ea64983b..76c7bb20d 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -142,6 +142,7 @@ object Keys val consoleProject = TaskKey[Unit]("console-project", "Starts the Scala interpreter with the sbt and the build definition on the classpath and useful imports.", AMinusTask) val compile = TaskKey[Analysis]("compile", "Compiles sources.", APlusTask) val compilers = TaskKey[Compiler.Compilers]("compilers", "Defines the Scala and Java compilers to use for compilation.", DTask) + val compileAnalysisFilename = TaskKey[String]("compileAnalysisFilename", "Defines the filename used to store the incremental compiler analysis file (inside the streams cacheDirectory).", DTask) val compileIncSetup = TaskKey[Compiler.IncSetup]("inc-compile-setup", "Configures aspects of incremental compilation.", DTask) val compilerCache = TaskKey[GlobalsCache]("compiler-cache", "Cache of scala.tools.nsc.Global instances. This should typically be cached so that it isn't recreated every task run.", DTask) val stateCompilerCache = AttributeKey[GlobalsCache]("compiler-cache", "Internal use: Global cache.") diff --git a/sbt/src/sbt-test/compiler-project/separate-analysis-per-scala/build.sbt b/sbt/src/sbt-test/compiler-project/separate-analysis-per-scala/build.sbt new file mode 100644 index 000000000..090b41544 --- /dev/null +++ b/sbt/src/sbt-test/compiler-project/separate-analysis-per-scala/build.sbt @@ -0,0 +1,12 @@ +name := "foo" + +scalaVersion := "2.10.4" + +crossScalaVersions := List("2.10.4", "2.11.0") + +incOptions := incOptions.value.withNewClassfileManager( + sbt.inc.ClassfileManager.transactional( + crossTarget.value / "classes.bak", + (streams in (Compile, compile)).value.log + ) +) diff --git a/sbt/src/sbt-test/compiler-project/separate-analysis-per-scala/foo.scala b/sbt/src/sbt-test/compiler-project/separate-analysis-per-scala/foo.scala new file mode 100644 index 000000000..b6922e9ac --- /dev/null +++ b/sbt/src/sbt-test/compiler-project/separate-analysis-per-scala/foo.scala @@ -0,0 +1,6 @@ +package foo + +object Foo extends App { + println("yay") +} + diff --git a/sbt/src/sbt-test/compiler-project/separate-analysis-per-scala/test b/sbt/src/sbt-test/compiler-project/separate-analysis-per-scala/test new file mode 100644 index 000000000..e76fa4b5c --- /dev/null +++ b/sbt/src/sbt-test/compiler-project/separate-analysis-per-scala/test @@ -0,0 +1,3 @@ +> + compile +$ exists target/scala-2.10 +$ exists target/scala-2.11