This is an excerpt from the Scala Cookbook (partially modified for the internet). This is a short recipe, Recipe 18.6, “How to create an SBT project with subprojects.”
Problem
You want to configure SBT to work with a main Scala project that depends on other subprojects you’re developing.
Solution
Create your subproject as a regular SBT project, but without a project subdirectory. Then, in your main project, define a project/Build.scala file that defines the dependencies between the main project and subprojects.
This is demonstrated in the following example, which I created based on the SBT Multi-Project documentation:
import sbt._ import Keys._ /** * based on http://www.scala-sbt.org/release/docs/Getting-Started/Multi-Project */ object HelloBuild extends Build { // aggregate: running a task on the aggregate project will also run it // on the aggregated projects. // dependsOn: a project depends on code in another project. // without dependsOn, you'll get a compiler error: "object bar is not a // member of package com.alvinalexander". lazy val root = Project(id = "hello", base = file(".")) aggregate(foo, bar) dependsOn(foo, bar) // sub-project in the Foo subdirectory lazy val foo = Project(id = "hello-foo", base = file("Foo")) // sub-project in the Bar subdirectory lazy val bar = Project(id = "hello-bar", base = file("Bar")) }
To create your own example, you can either follow the instructions in the SBT Multi-Project documentation to create a main project with subprojects, or clone my SBT Subproject Example on GitHub, which I created to help you get started quickly.
Discussion
Creating a main project with subprojects is well documented on the SBT website, and the primary glue that defines the relationships between projects is the project/Build.scala file you create in your main project.
In the example shown, my main project depends on two subprojects, which are in directories named Foo and Bar beneath my project’s main directory. I reference these projects in the following code in my main project, so it’s necessary to tell SBT about the relationship between the projects:
package com.alvinalexander.subprojecttests import com.alvinalexander.bar._ import com.alvinalexander.foo._ object Hello extends App { println(Bar("I'm a Bar")) println(Bar("I'm a Foo")) }
The following output from the Unix tree
command shows what the directory structure for my project looks like, including the files and directories for the main project, and the two subprojects:
|-- Bar | |-- build.sbt | +-- src | |-- main | | |-- java | | |-- resources | | +-- scala | | +-- Bar.scala | +-- test | |-- java | +-- resources |-- Foo | |-- build.sbt | +-- src | |-- main | | |-- java | | |-- resources | | +-- scala | | +-- Foo.scala | +-- test | |-- java | +-- resources |-- build.sbt |-- project | |-- Build.scala | +-- src |-- main | |-- java | |-- resources | +-- scala | +-- Hello.scala +-- test |-- java |-- resources +-- scala +-- HelloTest.scala
To experiment with this yourself, I encourage you to clone my GitHub project.
See Also
The Scala Cookbook
This tutorial is sponsored by the Scala Cookbook, which I wrote for O’Reilly:
You can find the Scala Cookbook at these locations: