天天看點

SBT的建構配置

建構配置

sbt

項目根目錄下的

build.sbt

定義了項目的建構配置。

project

目錄下也可以添加

*.scala

建構定義。

可以在

build.sbt

檔案中設定項目的名稱、版本資訊、建構規則、依賴等配置。

build.sbt

檔案遵循

Scala

文法。

一個簡單的

build.sbt

檔案内容如下所示:

name := "項目名稱"
version := "項目版本号"
scalaVersion := "Scala編譯器版本号"

libraryDependencies ++= Seq(
  "xx" % "xx" % "xx", //項目Java依賴
  ...
   "xx" % "xx" %% "xx", //項目Scala依賴
  ...
)

scalacOptions ++= Seq(
  "-xxx", //編譯器選項
  ...
)

enablePlugins(Xxx) //啟用插件
           

sbt shell

隻在啟動時讀取一遍建構配置。

若在

sbt shell

開啟之後

build.sbt

檔案發生了修改,則已經開啟的

sbt shell

依舊使用之前的建構配置。

若需要已開啟的

sbt shell

使用新的建構配置,則應在

sbt shell

中使用

reload

指令重新加載建構配置。

自定義源碼路徑

sbt

項目預設源碼路徑為

項目根目錄/src

,若需要管理預設路徑之外的源碼,在

build.sbt

中添加:

// 擷取源碼絕對路徑,并建構 File 執行個體
def sourceDir(dir: String) = file(s"${file(".").getAbsolutePath}/$dir")

// 自定義源碼路徑需要修改 unmanagedSourceDirectories 配置項
unmanagedSourceDirectories in Compile ++= Seq(
  sourceDir("子目錄1"),
  sourceDir("子目錄2"),
  ...
)
           

多項目建構

sbt

支援多項目建構,一個項目中可包含多個子項目。

每個子項目均可包含獨立、完整的建構配置。

使用

sbt

環境中預定義的

project

方法指定子項目的路徑:

// 子項目的根路徑為目前路徑下的 xxx 子路徑
// 子項目名稱 ChildProject (變量名稱)
lazy val ChildProject = project in file("xxx")
           

project

方法建構的執行個體類型為

sbt.Project

,代表子項目的建構定義,執行個體名稱會作為子項目的

ID

project in file("xxx")

中的路徑資訊

xxx

.

(項目目前路徑)時,擷取的執行個體代表預設項目的建構定義。

sbt.Project

類型定義了一系列控制建構配置的方法:

package sbt

sealed trait Project extends AnyRef with ProjectDefinition[ProjectReference] {
  ...
  def in(dir : java.io.File): Project = ... //設定建構定義的對應路徑
  def configs(cs: librarymanagement.Configuration*): Project = ...
  def dependsOn(deps: ClasspathDep[ProjectReference]*): Project = ...   //設定項目依賴
  def settings(ss: Def.SettingsDefinition*): Project = ...   //設定項目通用配置
  def enablePlugins(ns: Plugins*): Project = ... //啟用SBT插件
  def disablePlugins(ps: AutoPlugin*) : Project = ... //禁用SBT插件
  ...
}
           

使用

settings()

方法向項目中添加通用定義:

childProject
  .settings(
    libraryDependencies ++= Seq(
      ...
    ),
    scalacOptions ++= Seq(
      ...
    ),
    ...)
           

所有能在父級項目中設定的配置都可以添加在子項目的

settings()

方法中。

使用

enablePlugins()/disablePlugins()

方法啟用/禁用

sbt

插件。

使用

dependsOn()

方法設定依賴項目,子項目能引用依賴項目的代碼,并自動引入依賴項目的

libraryDependencies

sbt.Project

類型的主要方法均傳回自身執行個體,支援鍊式調用。

常見的配置結構,如下所示:

val root = project in file(".") //父項目配置
  .settings(
    ...
  )
  ...

val child = (project in file("xxx"))  //子項目配置
  .dependsOn(root) //設定依賴項目
  .enablePlugins(xxx) //啟用插件
  .settings( //配置相
    name := "xxx",
    version := "xxx",
    scalaVersion := "2.12.x"
    libraryDependencies ++= Seq(
      ... //jar包依賴
    ),
    scalacOptions ++= Seq(
      ... //編譯器配置
    ),
    ...
  )
           

通路建構資訊

sbt

沒有提供通路

build.sbt

中項目建構資訊的接口,使用

sbt

插件

sbt-buildinfo

可以讓項目通路

sbt

的建構資訊。

sbt

項目中的

project/plugins.sbt

檔案中引入該插件:

addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "版本号")
           

在項目建構配置檔案

build.sbt

中啟用

sbt-buildinfo

插件:

enablePlugins(BuildInfoPlugin)
           

sbt-buildinfo

插件的原理是利用

build.sbt

中的項目建構資訊在項目建構時生成額外的源碼,

并以單例對象的形式将建構資訊提供給項目源碼進行通路。

啟用

sbt-buildinfo

插件後會增加插件相關的配置項。

build.sbt

中的

name、version、scalaVersion、sbtVersion

等配置項傳入

sbt-buildinfo

插件的

buildInfoKeys

配置項,

通過

buildInfoPackage

配置項設定生成單例的包路徑。

build.sbt

檔案中配置

sbt-buildinfo

插件,執行個體如下:

// sbt項目建構資訊
name := "xxx"
version := "xxx"
scalaVersion := "2.12.3"
sbtVersion := "0.13.16"

// 啟用 sbt-buildinfo 插件
enablePlugins(BuildInfoPlugin)

// 設定建構資訊
buildInfoKeys := Seq(name, version, scalaVersion, sbtVersion)
buildInfoPackage := "xxx.yyy.zzz" //将建構資訊生成到 xxx.yyy.zzz 包路徑中
           

sbt-buildinfo

插件生成的單例對象結構如下所示:

case object BuildInfo {
  /** The value is "xxx". */
  val name: String = "xxx"
  /** The value is "xxx". */
  val version: String = "xxx"
  /** The value is "2.12.2". */
  val scalaVersion: String = "2.12.2"
  /** The value is "0.13.15". */
  val sbtVersion: String = "0.13.15"
  override val toString: String = {
    "name: %s, version: %s, scalaVersion: %s, sbtVersion: %s" format (
      name, version, scalaVersion, sbtVersion
    )
  }
}
           

處理建構沖突

jar

打包時将多個

jar

包依賴引入同一個包時,若依賴的

jar

包包含相對路徑相同的目錄、檔案,則可能産生沖突。

com.typesafe.slick:slick

com.typesafe.akka:akka-actor

包中的根路徑下均包含

reference.conf

配置檔案,

該配置記錄了子產品運作時必要的預設配置。

若打包時同時依賴這兩個包,則生成的

jar

包中

reference.conf

檔案隻會保留一份。

運作時

akka-actor

slick

可能會因為缺少預設配置異常退出。

使用

sbt-assembly

插件可處理建構流程中的檔案沖突。

build.sbt

中添加:

assemblyMergeStrategy in assembly := {
  case PathList("reference.c·onf") => MergeStrategy.concat //合并沖突檔案内容
}
           

若使用

IDEA

提供的打包工具,則

sbt-assembly

插件不會生效。

解決沖突檔案的方案是在項目

resource

路徑下手動建立沖突檔案,手動合并來自不同包的沖突檔案内容。