如何在不同配置中将SBT用于相互依赖的项目

orr*_*lla 6 scala sbt cyclic-dependency

我想有以下SBT构建设置:

object MyBuild extends Build {

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

  lazy val testkit = Project("testkit", file("testkit"))
    .dependsOn(core % "compile")
}
Run Code Online (Sandbox Code Playgroud)

什么core是主模块,包括域对象,并且testkit是一个模块,用于测试依赖于域对象和其他类/工具的支持代码(构建器,匹配器,测试驱动程序等; 而不是测试本身)core.

对于此设置SBT给出了一个Cyclic reference错误,虽然不是一个真正的循环依赖,因为使用不同配置(core编译,然后testkit根据汇总core,然后core test根据这两个编译).

我找到了一种通过替换其中一个dependsOn用途来解决这个问题的肮脏方法unmanagedClasspath,例如:

.settings(unmanagedClasspath in Compile <+= (packageBin in (LocalProject("core"), Compile)))
Run Code Online (Sandbox Code Playgroud)

这感觉就像一个黑客,并且还会sbt-idea生成不正确的IntelliJ项目(除其他外).

想要更好的解决方案吗?SBT是否支持这样的结构?

EEC*_*LOR 2

Sbt 仅在查找循环依赖项时检查项目。它不考虑配置。依赖性检查在多个地方执行。最重要的之一是在 的构造函数中LoadedBuild

这需要在一些地方进行更改,并且可能需要进行一些广泛的测试。如果你真的想要这个功能,我认为理论上可以添加它。

最接近 sbt 本身添加依赖项的方式:

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")
)
Run Code Online (Sandbox Code Playgroud)