如何使用SBT和IntelliJ IDEA管理多个相互依赖的模块?


82

我正在开发几个相互依赖的模块,并希望在一个IDEA项目中一起使用它们。我正在使用sbt-idea从sbt构建定义中生成IDEA项目,这对于单个项目非常有用。但是,在多模块的情况下,到目前为止,我已经尝试了一些事情:

使用sbt-idea分别为每个模块生成一个IDEA .iml文件;然后从头开始创建一个主IDEA项目,并向其中添加这些模块。这使得模块来源所有可编辑在同一窗口,但它们之间的依赖关系是不被跟踪(因此从内某些源试图导航FOO项目,在一些酒吧带我到的进口库版本吧,而不是本地资源)。

使用sbt多项目构建(又称子项目),其中父项目的Build.scala包含以下内容:

lazy val foo = Project(id = "foo", base = file("foo"))
lazy val bar = Project(id = "bar", base = file("bar")) dependsOn(foo)

这几乎可以正常工作,因为sbt-idea生成一个主IDEA项目,并跟踪子项目之间的依赖关系。但是,有两个警告:

  1. 子项目必须位于主项目的子目录中(即file("../foo")不允许)是sbt的限制。这不是我真正想要的(如果在两个不同的主项目中使用模块(例如“ utils”或“ commons”包),该怎么办?)但我可以接受。
  2. 我的一个子项目有自己的子项目。我不确定sbt本身是否正确处理了这些嵌套项目,但是无论如何它们都被sbt-idea忽略。显然,我需要将嵌套子项目递归地包含在主项目中。

总结一下:我想将可能已经有子项目的模块收集到一个具有跟踪依赖项的大型IDEA项目中,以方便进行编辑。我该怎么做?谢谢!


2
尝试建立一个将其他项目链接为外部项目引用的元项目(github.com/harrah/xsbt/wiki/Full-Configuration)。我自己没有使用sbt-idea尝试过此操作,因此这是评论而不是答案。
— retronym 2012年

感谢您的想法-但可悲的是sbt-idea完全忽略了外部引用。
— David Soergel


太酷了,所以我从最新的git来源安装了svn-idea来进行这些更改,然后清理项目并再次运行sbt-idea。有一些我不完全理解的怪异的依赖关系解决问题,但是最终我以一个可行的项目结束了!我确实必须在IDEA中为子子项目手动设置源目录。回想起来,我不确定我最初使用股票sbt-idea 11.1不能做到这一点。无论如何,谢谢-我想暂时不要再stop牛了。
— David Soergel

在写完最后一条评论后,我发现我根本没有一个有效的项目(同样,子子项目很麻烦)。因此,我只是将它们分为一流的项目,所以我的主项目现在只有一个子项目级别。当然,我只能这样做,因为这是我自己所有的代码。
— David Soergel 2012年

Answers:


7

多项目构建的方法是正确的。您可以具有任意长度的子项目的嵌套树,但是不能拥有属于多个父项目的模块。这绝对有道理,并且在Maven中也是如此。

原因是很难将相同的模块放入多个项目中并使源保持同步。正常的工作流程如下:

  • 您有一个模块所属的项目,您可以在其中修改模块源。
  • 您将模块发布到本地存储库中
  • 在需要模块的其他项目中,将其声明为libraryDependency

如果要在Idea中加载不属于当前项目的模块,那么这是可行的,因为您可以将其作为外部模块添加到工作空间中:

  • SBT-IDEA为您的项目生成.iml文件,然后将它们导入工作区中
  • 您可以将其他项目的other.iml添加到工作区
  • 如果修改手动添加到工作区的外部SBT模块,则应重新发布它们,以在“主”项目上看到更改,该更改将看到这些外部模块是“ libraryDependency”

感谢您的输入。但是,问题在于不是“您可以拥有任意长度的子项目的嵌套树”。我同意这应该与sbt一起使用,但是sbt-idea显然不在生成的IDEA项目文件中包括子子项目。
— 大卫·索格尔

此限制是否来自想法?
— Edmondo1984年

不,我当然已经将IDEA项目层次结构深了几个层次。
— David Soergel

7

子项目必须位于主项目的子目录中似乎是一个sbt限制(即,不允许file(“ ../ foo”))。这不是我真正想要的(如果在两个不同的主项目中使用模块(例如“ utils”或“ commons”包),该怎么办?)但我可以接受。

使用sbt 13.5和intellij 13.x,您可以使用Build.scala使用相对路径指定项目间的依赖关系。假设您有两个项目,一个核心项目Commons和另一个项目foo,它们都位于一个公共目录代码/中

  1. 在代码/ foo / project /下创建Build.scala
  2. 将此代码段放入Build.scala中

    object ProjectDependencies {
        val commons = RootProject(file("../commons"))
    }
    
    object ProjectBuild extends Build {
        import ProjectDependencies._
    
        lazy val root = Project(id = "foo", base = file(".")).dependsOn(commons)
    }
    
  3. 通过sbt生成您的IntelliJ项目 sbt gen-idea


这将允许通过从“ foo”链接来编辑“ commons”源吗?
— Tjunkie 2015年

是的,它允许。它适用于我的sbt 0.13.7和intellij 14.0.3安装
— user2829759
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.