【问题标题】:SBT create sub-projects using a collectionSBT 使用集合创建子项目
【发布时间】:2014-04-19 22:30:12
【问题描述】:

我一直在寻找这是否可行,但收效甚微。

使用 SBT,您能否以编程方式创建子项目,而无需明确地将每个项目分配给它自己的 val

我当前的项目结构如下所示:

root/
    common/ <--- This is another sub-project that others dependOn
    project/
        build.scala
    src/main/scala
    apps/ <--- sub-projects live here
        Sub1/
        Sub2/

Sub1Sub2 都是他们自己的 SBT 项目。

我第一次尝试将这些项目链接在一起是这样的:

// root/project/build.scala
import sbt._
import Keys._
object build extends Build {
  lazy val common = project /* Pseudo-code */
  val names = List("Sub1", "Sub2")
  lazy val deps = names map { name =>
    Project(id = name, base = file(s"apps/$name")).dependsOn(common)
  }

  lazy val finalDeps = common :: deps
  lazy val root = project.in(file(".")).aggregate(finalDeps.map(sbt.Project.projectToRef) :_*)
                 .dependsOn(finalDeps.map(ClassPathDependency(_, None)) :_*)
}

但是,因为 SBT 使用反射来构建它的项目和子项目,所以这不起作用。

只有在明确说明每个子项目时才有效:

lazy val Sub1 = project.in(file("apps/Sub1"))

所以问题:

有没有办法在 SBT 中以编程方式构建子项目依赖项?

【问题讨论】:

    标签: scala reflection sbt subproject


    【解决方案1】:

    Sbt 允许为构建本身进行构建定义:

    http://www.scala-sbt.org/release/docs/Getting-Started/Full-Def.html

    您可以尝试创建一个包含源生成器的 project/project/build.scala 文件,如下所示:

    // project/project/build.scala
    sourceGenerators in Compile <+= sourceManaged in Compile map { out =>
        Generator.generate(out / "generated")
    }
    

    编辑:您应该自己实现 Generator 对象。

    此源生成器将依次扫描最顶层的应用程序文件夹并为包含所有子项目的对象创建源。

    // project/subprojects.scala
    // This is autogenerated from the source generator
    object Subprojects{
      lazy val Sub1 = project.in(file("apps/Sub1"))
      lazy val Sub2 = project.in(file("apps/Sub2"))
      lazy val all = Seq(Sub1,Sub2)
    }
    

    现在在你的主 bu​​ild.scala 中只写:

    // project/build.scala
    lazy val root = project.in(file("."))
      .aggregate(Subprojects.all.map(sbt.Project.projectToRef) :_*)
      .dependsOn(Subprojects.all.map(ClassPathDependency(_, None)) :_*)
    

    我没有通过编译器运行所有这些,因此可能会出现一些错误,但原理应该有效。

    编辑:我在 Github 上创建了一个存储库,并在其中实施了解决方案。去那里看看它是如何完成的。

    https://github.com/darkocerdic/sbt-auto-subprojects

    【讨论】:

    • 很好的答案,但它并不完全有效。 sourceManaged in Compile map { out => println("Before generate") ; Generator.generate(out / "generated") } 从不打印到控制台。寻找 。 -name *.scala 也没有找到该文件。
    • 根据您的回答,我设法完成了这项工作。但是,生成的 Subprojects 也需要从 sbt.Build 扩展。此外,您提供并发现 here 的 Compile 示例中的 sourceGenerators 似乎没有做任何事情。
    • 看看 repo github.com/darkocerdic/sbt-auto-subprojects 一切都在那里实现。
    猜你喜欢
    • 2018-02-09
    • 2018-03-13
    • 1970-01-01
    • 1970-01-01
    • 2020-03-29
    • 2018-04-10
    • 2011-05-14
    • 2018-03-20
    • 1970-01-01
    相关资源
    最近更新 更多