在这里将配置build.sbt
来支持多个项目
我们的项目目录是multi
,然后在里面创建了两个子目录core
和util
,表示将有两个子项目。
这样我们的项目中实际上有三个项目:multi
, core
, util
.
为了方便演示,我分别在这三个项目的根目录下,各创建了一个会打出Hello
的scala程序。
multi
├── build.sbt
├── HelloMulti.scala
├── core
│ └── HelloCore.scala
└── util
└── HelloUtil.scala
object HelloMulti {
def main(args: Array[String]) {
println("Hello, multi!")
}
}
object HelloCore {
def main(args: Array[String]) {
println("Hello, core!")
}
}
object HelloUtil {
def main(args: Array[String]) {
println("Hello, util!")
}
}
name := "Multi Demo"
version := "1.0"
scalaVersion := "2.11.0"
sbtVersion := "0.13.5"
lazy val util = project
lazy val core = project
通过project
就可以声明一个新的子项目。在默认情况下,它会在项目根目录下寻找与变量名同名的目录,比如core
和util
我们可以通过projects
任务,查看该项目有多少个子项目:
$ sbt
> projects
[info] In file:/sbttest/multi/
[info] core
[info] * multi
[info] util
这里列出了三个项目,其中有*
的表示“当前项目”。
通过project
可以查看当前哪个项目被设为“当前项目”。有一些任务默认对当前任务起作用,比如run
$ sbt
> project
[info] multi (in build file:/sbttest/multi/)
运行run
:
$ sbt
> run
[info] Running HelloMulti
Hello, multi!
通过给project
任务一个参数,改变“当前项目”
$ sbt
> project
[info] multi (in build file:/sbttest/multi/)
> project core
[info] Set current project to core (in build file:/sbttest/multi/)
> run
[info] Running HelloCore
Hello, core!
可以看到已经更改了当前项目,并且在run
的时候,将会执行另一个scala文件
在前面,如果我们没有指明项目目录,它会默认使用与变量名同名的目录,如:
lazy val util = project
如果我们想使用另一个目录,如my-powerful-util
来表示项目util
,可以写成这样:
lazy val util = project in file("my-powerful-util")
这样,util
实际指向的就是my-powerful-util
目录了。
上面定义的core
和util
项目之间,实际上是没有任何关系的。比如我想compile
这两个项目,就必须分别把这两个项目设为当前项目,再依次运行compile
。
我们可以新建一个项目root
,把它们两个组合起来:
lazy val root = (project in file(".")).aggregate(util, core)
lazy val util = project
lazy val core = project
由于我们显式地给了根项目一个名字root
,原来以目录名命名的multi
就不见了:
$ sbt
> projects
[info] In file:/sbttest/multi/
[info] core
[info] * root
[info] util
如果在root
下执行compile
,则会看到core
和util
也会跟着一起编译:
$ sbt
> clean
[success] Total time: 0 s, completed 2014-9-13 16:24:06
> compile
[info] Updating {file: /sbttest/multi/}root...
[info] Updating {file: /sbttest/multi/}core...
[info] Updating {file: /sbttest/multi/}util...
[info] Resolving jline#jline;2.11 ...
[info] Done updating.
[info] Resolving org.scala-lang#scala-library;2.10.2 ...
[info] Compiling 1 Scala source to /sbttest/multi/target/scala-2.11/classes...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Resolving org.scala-lang#scala-library;2.10.2 ...
[info] Compiling 1 Scala source to /sbttest/multi/util/target/scala-2.10/classes...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Compiling 1 Scala source to /sbttest/multi/core/target/scala-2.10/classes...
会在多个子项目中并行执行,并且顺序不确定
在组合项目时,我们还可以指定哪些任务不会被同时执行到子项目中:
lazy val root = (project in file(".")).aggregate(util, core)
.settings(
aggregate in compile := false
)
这样,再执行compile
任务,它就不会被应用到core
和util
上。
$ sbt
> clean
[success] Total time: 0 s, completed 2014-9-13 16:27:29
> compile
[info] Updating {file: /sbttest/multi/}root...
[info] Resolving jline#jline;2.11 ...
[info] Done updating.
[info] Compiling 1 Scala source to /sbttest/multi/target/scala-2.11/classes...
[success] Total time: 0 s, completed 2014-9-13 16:27:32
可以看到,只有root
项目中的scala文件被编译了。
除了上面的组合,我们还可以让一个项目依赖于另一个项目,这样就可以在这个项目中使用另一个项目中定义的类。
比如,我们让core
依赖于util
:
lazy val util = project
lazy val core = project.dependsOn(util)
通过.dependsOn
,我们让core
项目依赖于util
项目,这样我们就可以在core
中使用util
中定义的类了。
如果我在core
中执行compile
任务,它会自动先到util
中执行compile
.
lazy val mypro = project.dependsOn(core, util)