Click here to Skip to main content
15,886,823 members
Articles / Programming Languages / Scala
Technical Blog

Scala : multi project sbt setup

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
19 Jan 2016CPOL2 min read 8K  
Scala : multi project sbt setup

A while ago I wrote a post about how to use SBT (Scala Build Tool):

https://sachabarbs.wordpress.com/2015/10/13/sbt-wheres-my-nuget/

In that post I showed simple usages of SBT. Thing is that was not really that realistic, so I wanted to have a go at a more real world example of this. One where we might have multiple projects, say like this:

SachasSBTDemo-App which depends on 2 sub projects

  • SachasSBTDemo-Server
  • SachasSBTDemo-Common

So how do we go about doing this with SBT?

There are 5 main steps to do this. Which we look at in turn.

SBT Directory Structure

The first that we need to do is create a new project folder (if you are from Visual Studio / .NET background think of this as the solution folder) called “project”

In here we will create 2 files

build.properties which just lists the version of SBT we will use. It looks like this

sbt.version=0.13.8 

SachaSBTDemo.scala is what I have called the other file, but you can call it what you like. Here is the contents of that file, this is the main SBT file that governs how it all hangs together. I will be explaining each of these parts as we go.

  import sbt._
  import Keys._
 
object BuildSettings {
 
 
  val buildOrganization = "sas"
  val buildVersion      = "1.0"
  val buildScalaVersion = "2.11.5"
 
  val buildSettings = Defaults.defaultSettings ++ Seq (
    organization := buildOrganization,
    version      := buildVersion,
    scalaVersion := buildScalaVersion
  )
}
 
 
object Dependencies {
  val jacksonjson = "org.codehaus.jackson" % "jackson-core-lgpl" % "1.7.2"
  val scalatest = "org.scalatest" % "scalatest_2.9.0" % "1.4.1" % "test"
}
 
 
object SachasSBTDemo extends Build {
 
  import Dependencies._
  import BuildSettings._
 
  // Sub-project specific dependencies
  val commonDeps = Seq (
     jacksonjson,
     scalatest
  )
 
  val serverDeps = Seq (
     scalatest
  )
 
 
  lazy val demoApp = Project (
    "SachasSBTDemo-App",
    file ("SachasSBTDemo-App"),
    settings = buildSettings
  )
  //build these projects when main App project gets built
  .aggregate(common, server)
  .dependsOn(common, server)
 
  lazy val common = Project (
    "common",
    file ("SachasSBTDemo-Common"),
    settings = buildSettings ++ Seq (libraryDependencies ++= commonDeps)
  )
 
  lazy val server = Project (
    "server",
    file ("SachasSBTDemo-Server"),
    settings = buildSettings ++ Seq (libraryDependencies ++= serverDeps)
  ) dependsOn (common)
   
}

Projects

In order to have separate project we need to use the Project item from the SBT library JARs. A minimal Project setup will tell SBT where to create the new Project. Here is an example of a Project, where the folder we expect SBT to create will be called “SachasSBTDemo-App”.

lazy val demoApp = Project (
    "SachasSBTDemo-App",
    file ("SachasSBTDemo-App"),
    settings = buildSettings
  )

Project Dependencies

We can also specify Project dependencies using “dependsOn” which takes a Seq of other projects that this Project depends on.

That means that when we apply an action to the Project that is depended on, the Project that has the dependency will also have the action applied.

lazy val demoApp = Project (
    "SachasSBTDemo-App",
    file ("SachasSBTDemo-App"),
    settings = buildSettings
  )
  //build these projects when main App project gets built
  .aggregate(common, server)
  .dependsOn(common, server)

Project Aggregation

We can also specify Project aggregates results from other projects, using “aggregate” which takes a Seq of other projects that this Project aggregates.

What “aggregate” means is that whenever we apply an action on the aggregating Project we should also see the same action applied to the aggregated Projects.

lazy val demoApp = Project (
    "SachasSBTDemo-App",
    file ("SachasSBTDemo-App"),
    settings = buildSettings
  )
  //build these projects when main App project gets built
  .aggregate(common, server)
  .dependsOn(common, server)

Library Dependencies

Just like the simple post I did before, we still need to bring in our JAR files using SBT. But this time we come up with a nicer way to manage them. We simply wrap them all up in a simple object, and then use the object to satisfy the various dependencies of the Projects. Much neater.

import sbt._
import Keys._
 
 
object Dependencies {
  val jacksonjson = "org.codehaus.jackson" % "jackson-core-lgpl" % "1.7.2"
  val scalatest = "org.scalatest" % "scalatest_2.9.0" % "1.4.1" % "test"
}
 
  // Sub-project specific dependencies
  val serverDeps = Seq (
     scalatest
  )
 
  .....
  .....
  lazy val server = Project (
    "server",
    file ("SachasSBTDemo-Server"),
    //bring in the library dependencies
    settings = buildSettings ++ Seq (libraryDependencies ++= serverDeps)
  ) dependsOn (common)

The Finished Product

The final product once run through SBT should be something like this if viewed in IntelliJ IDEA:

image

Or like on the file system

image

If you want to grab my source files, they are available here at GitHub : https://github.com/sachabarber/SBT_MultiProject_Demo

This article is part of the series 'Scala View All

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United Kingdom United Kingdom
I currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)

- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence

Both of these at Sussex University UK.

Award(s)

I am lucky enough to have won a few awards for Zany Crazy code articles over the years

  • Microsoft C# MVP 2016
  • Codeproject MVP 2016
  • Microsoft C# MVP 2015
  • Codeproject MVP 2015
  • Microsoft C# MVP 2014
  • Codeproject MVP 2014
  • Microsoft C# MVP 2013
  • Codeproject MVP 2013
  • Microsoft C# MVP 2012
  • Codeproject MVP 2012
  • Microsoft C# MVP 2011
  • Codeproject MVP 2011
  • Microsoft C# MVP 2010
  • Codeproject MVP 2010
  • Microsoft C# MVP 2009
  • Codeproject MVP 2009
  • Microsoft C# MVP 2008
  • Codeproject MVP 2008
  • And numerous codeproject awards which you can see over at my blog

Comments and Discussions

 
-- There are no messages in this forum --