Scala 的插件繼承自 Java 插件并添加了對 Scala 項(xiàng)目的支持。它可以處理 Scala 代碼,以及混合的 Scala 和 Java 代碼,甚至是純 Java 代碼(盡管我們不一定推薦使用)。該插件支持聯(lián)合編譯,聯(lián)合編譯可以通過 Scala 及 Java 的各自的依賴任意地混合及匹配它們的代碼。例如,一個 Scala 類可以繼承自一個 Java 類,而這個 Java 類也可以繼承自一個 Scala 類。這樣一來,我們就能夠在項(xiàng)目中使用最適合的語言,并且在有需要的情況下用其他的語言重寫其中的任何類。
要使用 Scala 插件,請?jiān)跇?gòu)建腳本中包含以下語句:
使用 Scala 插件
build.gradle
apply plugin: 'scala'
Scala 的插件向 project 中添加了以下任務(wù)。
表 25.1. Scala 插件 - 任務(wù)
任務(wù)名稱 | 依賴于 | 類型 | 描述 |
compileScala
|
compileJava
|
ScalaCompile | 編譯production 的 Scala 源文件。 |
compileTestScala
|
compileTestJava
|
ScalaCompile | 編譯test 的 Scala 的源文件。 |
SourceSet Scala |
SourceSet Java |
ScalaCompile | 編譯給定的source set 里的 Scala 源文件。 |
scaladoc
|
- | scaladoc | 為production 里的 Scala 源文件生成 API 文檔。 |
Scala 插件向 Java 插件所加入的 tasks 添加了以下的依賴。
表 24.2. Scala 感覺 插件 - 額外的 task 依賴
任務(wù)名稱 | 依賴于 |
classes
|
compileScala
|
testClasses
|
compileTestScala
|
sourceSet Classes |
SourceSet Scala |
圖 25.1. Scala 插件-任務(wù)
Scala 插件會假定如下所示的項(xiàng)目布局。所有 Scala 的源目錄都可以包含 Scala和Java 代碼。Java 源目錄只能包含 Java 源代碼。這些目錄不一定是存在的,或是里面包含有什么內(nèi)容;Scala 插件只會進(jìn)行編譯,而不管它發(fā)現(xiàn)什么。
表 25.3. Scala 插件 - 項(xiàng)目布局
目錄 | 意義 |
src/main/java
|
產(chǎn)品的Java源代碼 |
src/main/resources
|
產(chǎn)品的資源 |
src/main/scala
|
Production Scala 源代碼。此外可能包含聯(lián)合編譯的 Java 源代碼。 |
src/test/java
|
Java 測試源代碼 |
src/test/resources
|
測試資源 |
src/test/scala
|
Test Scala 源代碼。此外可能包含聯(lián)合編譯的 Java 源代碼。 |
sourceSet /java |
給定的源集的Java源代碼 |
sourceSet /resources |
給定的源集的資源 |
sourceSet /scala |
給定的source set 的 Scala 源代碼。此外可能包含聯(lián)合編譯的 Java 源代碼。 |
和 Java 插件一樣,Scala 插件允許把 Scala 的 production 和 test 的源文件配置為自定義的位置。
自定義 Scala 源文件布局
build.gradle
sourceSets {
main {
scala
srcDirs = ['src/scala']
}
}
test {
scala
srcDirs = ['test/scala']
}
}
}
Scala 項(xiàng)目需要聲明一個 scala-library 依賴項(xiàng)。這個依賴會在編譯和運(yùn)行的類路徑時用到。它還將用于分別獲取 Scala 編譯器及 Scaladoc 工具。
如果 Scala 用于 production 代碼, scala-library 依賴應(yīng)該添加到 compile 的配置中:
為production 代碼定義一個Scala 依賴
build.gradle
repositories {
mavenCentral()
}
dependencies {
compile 'org.scala-lang:scala-library:2.9.1'
}
如果 Scala 僅用于測試代碼, scala-library 依賴應(yīng)被添加到 testCompile 配置中:
為 test 代碼定義一個Scala 依賴
build.gradle
dependencies {
testCompile "org.scala-lang:scala-library:2.9.2"
}
ScalaCompile 和 ScalaDoc tasks 會以兩種方式使用 Scala: 在它們的 classpath 以及scalaClasspath 上。前者用于在源代碼中查找類的引用,通常會包含 scala-library 和其他庫。后者用來分別加載和執(zhí)行 Scala 編譯器和 Scala 工具,并且應(yīng)該只包含 scala-library及其依賴項(xiàng)。
除非顯式配置了一個 task 的 scalaClasspath ,否則 Scala(基礎(chǔ))插件會嘗試推斷該 task 的 classpath。以如下方式進(jìn)行:
Scala 插件沒有向 project 添加任何的公約屬性。
Scala 的插件向 project 的每一個 source set 添加了下列的公約屬性。你可以在你的構(gòu)建腳本中,把這些屬性當(dāng)成是 source set 對象中的屬性一樣使用。
表 25.4. Scala 插件 - source set 屬性
屬性名稱 | 類型 | 默認(rèn)值 | 描述 |
scala
|
SourceDirectorySet (read-only) | 非空 | 該source set 中的 Scala 源文件。包含在 Scala 源目錄中找到的所有的.java 文件,并排除所有其他類型的文件。 |
scala.srcDirs
|
Set<File> . |
name /scala] |
源目錄包含該 source set 中的 Scala 源文件。此外可能還包含用于聯(lián)合編譯的 Java 源文件。 |
allScala
|
FileTree (read-only) | 非空 | 該source set 中的所有 Scala 源文件。包含在 Scala 源目錄中找到的所有的.scala 文件。 |
這些屬性由一個 ScalaSourceSet 的約定對象提供。
Scala 的插件還修改了一些 source set 的屬性:
表 25.5. Scala 插件 - source set 屬性
屬性名稱 | 修改的內(nèi)容 |
allJava
|
添加在 Scala 源目錄中找到的所有.java 文件。 |
allSource
|
添加在 Scala 的源目錄中找到的所有源文件。 |
Scala 插件包含了對 fsc,即 Fast Scala Compiler 的支持。fsc 運(yùn)行在一個單獨(dú)的進(jìn)程中,并且可以顯著地提高編譯速度。
啟用 Fast Scala Compiler
build.gradle
compileScala
scalaCompileOptions.useCompileDaemon = true
// optionally specify host and port of the daemon:
scalaCompileOptions.daemonServer = "localhost:4243"
}
注意,每當(dāng) fsc 的編譯類路徑的內(nèi)容發(fā)生變化時,它都需要重新啟動。(它本身不會去檢測編譯類路徑的更改。)這使得它不太適合于多項(xiàng)目的構(gòu)建。
當(dāng) scalaCompileOptions.fork 設(shè)置為 true 時,編譯會在外部進(jìn)程中進(jìn)行。fork 的詳細(xì)情況依賴于所使用的編譯器。基于 Ant 的編譯器 (scalaCompileOptions.useAnt = true) 將為每個 ScalaCompile 任務(wù) fork 一個新進(jìn)程,而默認(rèn)情況下它不進(jìn)行 fork?;?Zinc 的編譯器 (scalaCompileOptions.useAnt = false) 將利用 Gradle 編譯器守護(hù)進(jìn)程,且默認(rèn)情況下也是這樣。
外部過程默認(rèn)使用JVM 的的默認(rèn)內(nèi)存設(shè)置。如果要調(diào)整內(nèi)存設(shè)置,請根據(jù)需要配置scalaCompileOptions.forkOptions :
調(diào)整內(nèi)存設(shè)置
build.gradle
tasks.withType(ScalaCompile) {
configure(scalaCompileOptions.forkOptions) {
memoryMaximumSize = '1g'
jvmArgs = ['-XX:MaxPermSize=512m']
}
}
增量編譯是只編譯那些源代碼在上一次編譯之后有修改的類,及那些受這些修改影響到的類,它可以大大減少 Scala 的編譯時間。頻繁編譯代碼的增量部分是非常有用的,因?yàn)樵陂_發(fā)時我們經(jīng)常要這樣做。
Scala 插件現(xiàn)在通過集成 Zinc 來支持增量編譯, 它是 sbt 增量 Scala 編譯器的一個單機(jī)版本。若要把 ScalaCompile 任務(wù)從默認(rèn)的基于 Ant 的編譯器切換為新的基于 Zinc 的編譯器,需要將 scalaCompileOptions.useAnt 設(shè)置為 false:
激活基于 Zinc 編譯器
build.gradlev
tasks.withType(ScalaCompile) {
scalaCompileOptions.useAnt = false
}
除非在 API 文檔中另有說明,否則基于 Zinc 的據(jù)編譯器支持與基于 Ant 的編譯器完全相同的配置選項(xiàng)。但是,要注意的是,Zinc 編譯器需要 Java 6 或其以上版本來運(yùn)行。這意味著 Gradle 本身要使用 Java 6 或其以上版本。
Scala 插件添加了一個名為 zinc 的配置,以解析 Zinc 庫及其依賴。如果要重寫 Gradle 默認(rèn)情況下使用的 Zinc 版本,請?zhí)砑右粋€顯式的 Zinc 依賴項(xiàng) (例如zinc "com.typesafe.zinc:zinc:0.1.4")。無論使用哪一個 Zinc 版本,Zinc 都是使用在scalaTools配置上找到的 Scala 編譯器。
就像 Gradle 上基于Ant 的編譯器一樣,基于 Zinc 的編譯器支持 Java 和 Scala 代碼的聯(lián)合編譯。默認(rèn)情況下,在 src/main/scala 下的所有 Java 和 Scala 代碼都會進(jìn)行聯(lián)合編譯。使用基于 Zinc 的編譯器時,即使是 Java 代碼也將會進(jìn)行增量編譯。
增量編譯需要源代碼的相關(guān)性分析。解析結(jié)果進(jìn)入由 scalaCompileOptions.incrementalOptions.analysisFile 所指定的文件(它有一個合理的默認(rèn)值)。在多項(xiàng)目構(gòu)建中,分析文件被傳遞給下游的 ScalaCompile 任務(wù),以啟用跨項(xiàng)目的增量編譯。對于由 Scala 插件添加的 ScalaCompile 任務(wù),無需對這一點(diǎn)進(jìn)行配置。對于其他的 ScalaCompile 任務(wù),需要根據(jù)類文件夾或 Jar archive 的代碼中,是哪一個的代碼被傳遞給 ScalaCompile 任務(wù)的下游類路徑,把ScalaCompileOptions.incrementalOptions.publishedCode 配置為指向它們。注意,如果publishedCode 設(shè)置不正確,上游代碼發(fā)生變化時下游任務(wù)可能不會重新編譯代碼,導(dǎo)致編譯結(jié)果不正確。
由于依賴分析的系統(tǒng)開銷,一次干凈的編譯或在代碼有了較大的更改之后的編譯,可能花費(fèi)的時間要長于使用基于 Ant 的編譯器。對于 CI 構(gòu)建和版本的構(gòu)建中,我們目前推薦使用基于 Ant 的編譯器。
注意現(xiàn)在 Zinc 基于守護(hù)進(jìn)程模式的 Nailgun 還不支持。相反,我們打算加強(qiáng) Gradle 自己的編譯器守護(hù)進(jìn)程,使得在跨 Gradle 調(diào)用時繼續(xù)存活,利用同一個 Scala 編譯器。這將會為 Scala 編譯帶來另一個方面上的明顯加速。
當(dāng) Eclipse 插件遇到 Scala 項(xiàng)目時,它將添加額外的配置,使得項(xiàng)目能夠在使用 Scala IDE 時開箱即用。具體而言,該插件添加一個 Scala 性質(zhì)和依賴的容器。
當(dāng) IDEA 插件遇到 Scala 項(xiàng)目時,它將添加額外的配置,使得項(xiàng)目能夠在使用 IDEA 時開箱即用。具體而言,該插件添加了一個 Scala facet 和一個匹配項(xiàng)目的類路徑上的 Scala 版本的 Scala 編譯器類庫。
更多建議: