Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define another compilation scope in SBT?

Tags:

sbt

By default, SBT compiles source under src/main and src/tests to target/scala-[version]/classes and target/scala-[version]/test-classes, respectively. I'd like to define another group called core that I can put in src/core/java or src/core/scala and have that compiled to a separate class path. How do I do this?

My motive: I want to have separate groups of class files, because I want to recompile and reload new application code during development, without restarting the JVM process for the running application. So the core classes will load when the application starts, and they will use a custom classloader to load everything else from src/main. Those latter classes will be reloadable. I need to do this because I'm writing a music program that loads a software instrument through JNI, which takes a long time to load. Rebooting the app during development wastes too much time.

I mainly need to separate the class files. If I were producing jars, I'd want myapp-core.jar and myapp-main.jar, but that's not as important, since this is for development more than the final product.

A first attempt:

val Core = config("core")
...
classDirectory in Core <<= crossTarget(t => file(t.getAbsolutePath + "core-classes"))

gives this error:

Reference to undefined setting: 
{.}/*:cross-target from {.}/core:class-directory
    Did you mean *:cross-target ?

I'll go read about scopes now...

like image 579
Rob N Avatar asked Feb 01 '13 23:02

Rob N


1 Answers

There is an advanced configurations example in the sbt documentation that shows many aspects of custom compilation configurations.

A basic example is:

object MyBuild extends Build {

  lazy val root = Project(...,
    settings = Defaults.defaultSettings ++ coreSettings
  )

  // Declare the custom configuration.
  lazy val Core = config("core")

  lazy val coreSettings: Seq[Setting[_]] = 
     // Add the src/core/scala/ compilation configuration.
     // This configures sources, classpaths, output directories, REPL, scalac, ...
     inConfig(Core)(Defaults.configSettings) ++ Seq(
        // example dependency just for Core
        libraryDependencies += "org.example" % "demo" % "1.0" % Core,
        // register the custom core configuration
        ivyConfigurations += Core
     )
}

Access the compiled core classpath via the fullClasspath in Core task.

like image 93
Mark Harrah Avatar answered Sep 29 '22 06:09

Mark Harrah