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?
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.
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.
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.
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")
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With