Build 是使用';合计';后面是';德彭森';与相同模块冗余?

Build 是使用';合计';后面是';德彭森';与相同模块冗余?,build,sbt,Build,Sbt,在SBT中,如果二者都包含相同的子模块,那么使用聚合后的dependsOn是多余的吗?根据文档,似乎是这样,但我以前见过这种行为,我不明白它的好处是什么。如果一个项目是用依赖项定义的,这难道不意味着聚合对这些依赖项做了什么吗?我注意到,使用这个冗余聚合后,我的项目构建要比不使用它慢得多,我想知道是否可以安全地删除它 lazy val module = sbt.Project(...) dependsOn (foo, bar) aggregate (foo, bar) 或者只是 lazy val

在SBT中,如果二者都包含相同的子模块,那么使用聚合后的dependsOn是多余的吗?根据文档,似乎是这样,但我以前见过这种行为,我不明白它的好处是什么。如果一个项目是用依赖项定义的,这难道不意味着聚合对这些依赖项做了什么吗?我注意到,使用这个冗余聚合后,我的项目构建要比不使用它慢得多,我想知道是否可以安全地删除它

lazy val module = sbt.Project(...) dependsOn (foo, bar) aggregate (foo, bar)
或者只是

lazy val module = sbt.Project(...) dependsOn (foo, bar)

我使用的是SBT 0.13.6

tl;dr
aggregate
使任务在聚合模块中执行,所有
aggregate
d一个执行,而
dependsOn
设置类路径依赖项,以便库对
聚合模块可见(取决于示例中的
compile
aka
default
)配置)

一个示例来演示这些差异

我正在使用以下
build.sbt
(没有什么真正有趣的):

构建定义了三个模块
a
b
c
,最后一个
c
项目是
a
b
的聚合。还有第四个模块-隐式模块-聚合所有模块
a
b
c

> projects
[info] In file:/Users/jacek/sandbox/aggregate-dependsOn/
[info]     a
[info]   * aggregate-dependson
[info]     b
[info]     c
> b/run
[info] Running Hello
Hello from B
[success] Total time: 0 s, completed Oct 22, 2014 9:46:44 AM
> c/runMain Hello
[info] Running Hello
Hello from B
[success] Total time: 0 s, completed Oct 22, 2014 9:46:58 AM
当我在
aggreate
ing模块中执行任务时,该任务将在
aggregate
d模块中执行

> compile
[info] Updating {file:/Users/jacek/sandbox/aggregate-dependsOn/}b...
[info] Updating {file:/Users/jacek/sandbox/aggregate-dependsOn/}a...
[info] Updating {file:/Users/jacek/sandbox/aggregate-dependsOn/}aggregate-dependson...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Updating {file:/Users/jacek/sandbox/aggregate-dependsOn/}c...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[success] Total time: 0 s, completed Oct 22, 2014 9:33:20 AM
当我在
c
中执行一项任务时,同样的情况也会发生,而该任务将针对
a
b
执行,但不会在顶级项目中执行

> show c/clean
[info] a/*:clean
[info]  ()
[info] b/*:clean
[info]  ()
[info] c/*:clean
[info]  ()
[success] Total time: 0 s, completed Oct 22, 2014 9:34:26 AM
当任务在
a
b
中执行时,它仅在项目中运行

> show a/clean
[info] ()
[success] Total time: 0 s, completed Oct 22, 2014 9:34:43 AM
是否在
aggregate
ing项目中执行任务由
aggregate
项目和/或任务范围内的键控制

> show aggregate
[info] a/*:aggregate
[info]  true
[info] b/*:aggregate
[info]  true
[info] c/*:aggregate
[info]  true
[info] aggregate-dependson/*:aggregate
[info]  true
如中所述进行更改:

在执行聚合的项目中,即本例中的根项目中,您可以控制每个任务的聚合。(……
aggregate In
update是作用于更新任务的聚合键

下面我正在更改
c
模块和
clean
任务的键,因此
clean
不再在
aggregate
d模块
a
b
中执行:

> set aggregate in (c, clean) := false
[info] Defining c/*:clean::aggregate
[info] The new value will be used by no settings or tasks.
[info] Reapplying settings...
[info] Set current project to aggregate-dependson (in build file:/Users/jacek/sandbox/aggregate-dependsOn/)
> show c/clean
[info] ()
[success] Total time: 0 s, completed Oct 22, 2014 9:39:13 AM
c
的其他任务不受影响,仍在
c
中执行任务的任务将在
aggregate
模块中运行:

> show c/libraryDependencies
[info] a/*:libraryDependencies
[info]  List(org.scala-lang:scala-library:2.10.4)
[info] b/*:libraryDependencies
[info]  List(org.scala-lang:scala-library:2.10.4)
[info] c/*:libraryDependencies
[info]  List(org.scala-lang:scala-library:2.10.4)
aggregate
为sbt任务设置一个依赖项,以便它们在其他
aggregate
d模块中执行时,
dependsOn
设置一个类路径依赖项,即
dependsOn
ed模块中的代码在
dependsOn
ing模块中可见(很抱歉出现了“新”字)

让我们假设
b
有一个如下的主对象:

object Hello extends App {
  println("Hello from B")
}
Hello
对象保存到
b/Hello.scala
,即在
b
模块下

由于
c
被定义为
dependsOn b
(请参见上文
build.sbt
),因此
Hello
对象在
b
中可见(因为它属于模块),但在
c
中也可见

> projects
[info] In file:/Users/jacek/sandbox/aggregate-dependsOn/
[info]     a
[info]   * aggregate-dependson
[info]     b
[info]     c
> b/run
[info] Running Hello
Hello from B
[success] Total time: 0 s, completed Oct 22, 2014 9:46:44 AM
> c/runMain Hello
[info] Running Hello
Hello from B
[success] Total time: 0 s, completed Oct 22, 2014 9:46:58 AM
(我不得不在
c
中使用
runMain
,因为
run
无法单独看到我无法解释的类)

尝试在
a
中运行任务的结果是
java.lang.ClassNotFoundException:Hello
,因为该类在模块中不可见

> a/runMain Hello
[info] Updating {file:/Users/jacek/sandbox/aggregate-dependsOn/}a...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Running Hello
[error] (run-main-6) java.lang.ClassNotFoundException: Hello
java.lang.ClassNotFoundException: Hello
    at java.lang.ClassLoader.findClass(ClassLoader.java:530)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
[trace] Stack trace suppressed: run last a/compile:runMain for the full output.
java.lang.RuntimeException: Nonzero exit code: 1
    at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last a/compile:runMain for the full output.
[error] (a/compile:runMain) Nonzero exit code: 1
[error] Total time: 0 s, completed Oct 22, 2014 9:48:15 AM
build.sbt
中将
a
重新定义为
dependsOn b
,异常消失


您应该阅读官方文档。

根据“dependsOn”的文档:“这也会在编译项目时创建项目之间的顺序;必须更新并编译util,然后才能编译core。”这是否意味着dependsOn还意味着相关模块的编译和更新任务的聚合?或者这必须使用“聚合”单独表示?或者聚合和dependsOn之间的行为差异是任务执行的顺序,而不是任务执行的选择?这是一个非常有趣的观察结果de>dependsOn
确实在依赖项目上设置了一种
aggregate
,但仅用于使JAR可用的任务,以便它们可以在类路径上使用。这是
compile
的情况,而不是
test
,如果以前没有这样做,它只会执行
compile