SBT的构建配置

2 篇文章 0 订阅

构建配置

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:slickcom.typesafe.akka:akka-actor包中的根路径下均包含reference.conf配置文件,
该配置记录了模块运行时必要的默认配置。
若打包时同时依赖这两个包,则生成的jar包中reference.conf文件只会保留一份。
运行时akka-actorslick可能会因为缺少默认配置异常退出。

使用sbt-assembly插件可处理构建流程中的文件冲突。
build.sbt中添加:

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

若使用IDEA提供的打包工具,则sbt-assembly插件不会生效。
解决冲突文件的方案是在项目resource路径下手动创建冲突文件,手动合并来自不同包的冲突文件内容。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值