Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use SBT for interdependent projects in different configurations

I would like to have the following SBT build setup:

object MyBuild extends Build {

  lazy val core = Project("core", file("core"))
    .dependsOn(testkit % "test")

  lazy val testkit = Project("testkit", file("testkit"))
    .dependsOn(core % "compile")
}

When core is the main module, including domain objects, and testkit is a module for testing support code (builders, matchers, test drivers, etc.; not the tests themselves) that depends on the domain objects and other classes/utils in core.

For this setup SBT gives a Cyclic reference error, although there isn't really a cyclic dependency because of the use of different configurations (core compiles, then testkit compiles depending on core, then core test is compiled depending on both).

I found a dirty way to get around this problem by replacing one of the dependsOn use unmanagedClasspath, for example:

.settings(unmanagedClasspath in Compile <+= (packageBin in (LocalProject("core"), Compile)))

This feels like a hack, and also makes sbt-idea generate incorrect IntelliJ projects (among other things).

Any idea for a better solution? Does SBT support such a structure?

like image 918
orrsella Avatar asked Oct 03 '14 11:10

orrsella


People also ask

Which is the correct way to add dependencies in sbt file?

If you have JAR files (unmanaged dependencies) that you want to use in your project, simply copy them to the lib folder in the root directory of your SBT project, and SBT will find them automatically.

How do we specify library dependencies in sbt?

The libraryDependencies key Most of the time, you can simply list your dependencies in the setting libraryDependencies . It's also possible to write a Maven POM file or Ivy configuration file to externally configure your dependencies, and have sbt use those external configuration files.

What is sbt dependency management?

These tools support automatic dependency management for your project. Like in almost every build system, SBT allows you to define library dependencies which are resolved automatically, so you don't have to download and package required libraries by yourself.


1 Answers

Sbt only checks projects when it looks for cyclic dependencies. It does not take configurations into account. The dependency check is executed in multiple places. One of the most important ones is in the constructor of LoadedBuild.

It would require changes in a few places and probably some extensive testing. If you really want this feature I think it could theoretically be added.

The closest you can get to the way sbt itself adds the dependency:

lazy val core = project.in( file("core") )
  .settings(
    internalDependencyClasspath in Test <++= 
      exportedProducts in Compile in LocalProject("testkit")
  )

lazy val testkit = project.in( file("testkit") )
  .settings(
    internalDependencyClasspath in Compile <++= 
      exportedProducts in Compile in LocalProject("core")
)
like image 141
EECOLOR Avatar answered Sep 28 '22 01:09

EECOLOR