Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override output directory for sbt multi-project build

Tags:

sbt

I'm using sbt for a multi-project build, as described here:

http://www.scala-sbt.org/0.13/tutorial/Multi-Project.html

Here's the top-level build.scala file:

import sbt._
import Keys._

object ExampleBuild extends Build {
  lazy val scrooge = Project(
    id = "scrooge",
    base = file("messages-scrooge")
  )
  lazy val examples = Project(
    id = "examples",
    base = file("examples")
  ).dependsOn(scrooge)
}

I would like to change the target directory so that all the output goes to a separate partition.* The following seems to work but is really clunky, since I need to change it separately for every sub-project. It's only going to get worse if there are more of them:

target="$HOME/sbt-target"
sbt "project scrooge" "set target := new java.io.File(\"$target/scrooge\")" "project examples" "set target := new java.io.File(\"$target/examples\")" "project root" clean assembly

I'd prefer to do something more like the following, but it fails to compile with lots of messages about "object blah is not a member of package..." in places where the "examples" project tries to import types from the "scrooge" project. I assume that's because both projects are stomping on each others' output files.

target="$HOME/sbt-target"
sbt "set every target := new java.io.File(\"$target\")" clean assembly

Is there a better way to do this? I don't mind changing the build files, but I'd prefer not to have any hard-coded paths inside them.

* - The reason I want to change the output directory is that I'm building inside a Vagrant VM, and the source folder is shared using a Virtualbox shared folder from a Windows host to a Linux VM. The Scala compiler tries to create some really long filenames that exceed the Windows 260 character path limit. If you strongly believe I'd be better trying to work around this problem in a different way, let me know and I'll post a separate question, but I've already hit a lot of problems in that direction, hence my desire to simply change the target directory.

like image 487
Weeble Avatar asked Nov 10 '22 09:11

Weeble


1 Answers

I do this with a plugin. In my case, I try to consolidate all the target/ folders (without collision):

package sbt
package plugins

/** [[PluginOptimizedLayout]] is an [[AutoPlugin]] that consolidates `target/` folders under the root `target/`.
  * 
  * This removes noise when navigating the source folders; and enables elision of `src/`.
  */
object PluginOptimizedLayout extends AutoPlugin {    
  import Keys._

  override def requires = JvmPlugin
  override def trigger = allRequirements

  override lazy val projectSettings = Seq(
    target := {
      (ThisBuild / baseDirectory).value / "target" / thisProject.value.id
    }
  )
}
like image 132
Jeffrey Aguilera Avatar answered Jan 04 '23 03:01

Jeffrey Aguilera