【问题标题】:How to specify that to build project A another project B has to be built first?如何指定要构建项目 A 必须先构建另一个项目 B?
【发布时间】:2011-11-30 17:19:18
【问题描述】:

假设我公司的一个人有一个名为 commons 的 sbt 项目,它非常通用。该项目以传统的 sbt 方式定义:在主文件夹中,构建定义在 project/Build.scala 文件中。

现在其他人正在开发一个名为 databinding 的项目,该项目依赖于 commons。我们想以同样的方式定义这个项目,使用project/Build.scala

我们有以下目录布局:

dev/
  commons/
    src/
      *.scala files here...
    project/
      Build.scala
  databinding/
    src/
      *.scala files here...
    project/
      Build.scala

如何指定databinding 需要先构建commons 并使用输出类文件?

我阅读了Multi-project builds,并为databinding 的构建定义提出了以下内容:

object MyBuild extends Build {

  lazy val root = Project(id = "databinding", base = file(".")) settings (
    // ... omitted
  ) dependsOn (commons)

  lazy val common = Project(id = "commons",
    base = file("../commons")
  )

}

除非它不起作用:sbt 不喜欢 .. 并抛出 AssertionError。显然,commons 应该是databinding 中的一个文件夹。但是这两个项目保存在不同的 git 存储库中,我们不能嵌套。

如何正确指定这种依赖关系?

【问题讨论】:

    标签: scala sbt


    【解决方案1】:

    您需要在将在dev/project/Build.scala 中定义的根项目(或任何名称,但这个名称很合适)中定义多项目。

    object RootBuild extends Build {
      lazy val root = Project(id = "root", base = file("."))
        .settings(...)
        .aggregate(commons, databinding)
    
      lazy val commons = Project(id = "commons", base = file("commons"))
        .settings(...)
    
      lazy val databinding = Project(id = "databinding", base = file("databinding"))
        .settings(...)
        .dependsOn(commons)
    }
    

    还有一点,SBT 不支持子项目中的*.scala 配置文件。这意味着您必须将在commons/project/Build.scaladatabinding/project/Build.scala 上所做的配置分别迁移到commons/build.sbtdatabinding/build.sbt

    如果您的某些配置不适合.sbt 定义文件,则必须将它们添加到根project/Build.scala 中。显然,根Build.scala 中定义的设置在*.sbt 文件中可用。

    【讨论】:

    • 非常感谢您的解释,大卫。这看起来很奇怪,是不是因为其他项目使用了我的项目commons,它就不能在.scala文件中有完整的定义?
    • 还有,是否有替代方案——例如,添加一个解析器来查找它所依赖的项目生成的 jar?
    • 关于您的第一个问题,这是一个 SBT 限制,阻止您使用 *.scala 文件来定义子项目。由于 SBT 合并项目定义文件的方式,我认为这是一个限制。幸运的是,*.sbt 文件将能够从您的根项目Build.scala 访问 vals、设置...。您还可以考虑在第二条评论中提到它,例如在本地(发布-本地)中发布您的 common,解析器应该检索它。如果要使用 SNAPSHOT 系统,请小心将 isChanging() 添加到依赖项定义中。希望这会有所帮助。
    • 再次感谢大卫,这很有帮助。
    【解决方案2】:

    您应该使用RootProject(如果引用另一个项目的根项目)或ProjectRef(如果引用另一个项目的子项目)。

    这里是一个使用 RootProject 的示例:

           lazy val commons = RootProject(file("../commons"))
           lazy val root = Project(id = "databinding", base = file(".")) settings (...) dependsOn (commons)
    

    这里是使用 ProjectRef 的示例

           lazy val commons = ProjectRef(file("../commons"), "sub-project")
           lazy val root = Project(id = "databinding", base = file(".")) settings (...) dependsOn (commons)
    

    【讨论】:

    • 这是RootProject 新的吗?这个新 API 是否会使 David 推荐的解决方案失效?
    • 看来是这样。不,但我会说它更简单一些
    • 我自己无法理解批准的答案如何在没有违背两个项目独立目的的迁移的情况下对 OP 起作用。由于根项目,他们不会在迁移后。
    【解决方案3】:

    您可以有两个独立的项目,只需在本地发布其中一个,将其作为普通库依赖项添加到另一个。

    【讨论】:

      猜你喜欢
      • 2014-06-05
      • 2015-08-11
      • 2017-10-19
      • 1970-01-01
      • 2020-10-10
      • 2018-03-31
      • 2013-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多