sbt学习笔记

sbt项目目录管理sbt管理项目的目录结构如下(假设基础目录或者说项目目录为./)build.sbtsrc/ main/  scala/   <main scala source>  java/   <main java source>  resources/   <files to include in main jar here&a
摘要由CSDN通过智能技术生成

说明:参考sbt官方文档
跟着这篇官方文档学完sbt的基本使用后,深感学习的最佳途径是官方的tutorial,详细而且准确。

1. sbt项目目录管理

sbt管理项目的目录结构如下(假设基础目录或者说项目目录为./)

build.sbt
src/
 main/
  scala/
   <main scala source>
  java/
   <main java source>
  resources/
   <files to include in main jar here>
 test/
  scala/
   <test scala source>
  java/
   <test java source>
  resources/
   <files to include in test jar here>
project/
 <该文件夹下的.scala文件和build.sbt文件一起组成build support files>
target/
 <编译生成的文件,或打包的jar文件>


2. 常用sbt命令

命令含义
clean删除已经生成的文件(target/ 路径下)
compile编译源文件(src/main/scala 及 src/main/java路径下 )
test编译并运行所有测试文件(test/路径下的源文件)
console运行scala interpreter 其classpath包括所有已编译的源文件及依赖包(在build.sbt中可以指定),:quit, Ctrl+D (Unix), or Ctrl+Z (Windows)回到sbt交互界面
run运行项目中的主类
package将src/main/resources 和 从src/main/scala and src/main/java编译出来的类打包成jar文件
reload如果对构建定义文件(build.sbt, project/.scala, project/.sbt files)做过更改,需要reload这些更改使其生效
dist生成可执行的发行版本(target/universal/路径下的zip文件

3. 构建定义(build-definition)

在 project/build.properties文件中可以指定sbt的版本:

sbt.version=1.2.6

构建定义在build.sbt中指定,,由一系列的子项目(subproject)组成。如下,指定一个名为Hello的子项目,其scala版本为2.12.7,其路径在基础目录(./)下:

lazy val root = (project in file("."))
 .settings(
 name := "Hello",
 scalaVersion := "2.12.7")

其实build.sbt也遵循scala语法,这里使用的lazy关键字申明变量,使其初始化延迟,节省整个程序的初始化时间。当首次使用到该变量时才对其进行初始化:

When a val is declared as lazy, its initialization is deferred until it is accessed for the first time.

在build.sbt中利用以下语法来定义setting或者task:
build.sbt DSL
左边(name, name, version, and scalaVersion等)是key,都是SettingKey[T], TaskKey[T], or InputKey[T] 的实例,其中[T]为泛型。比如SettingKey[String] 赋值为整数就会编译不通过:name := 12

  • 有以下三种类型的key

    • SettingKey[T]: a key for a value computed once (the value is computed when loading the subproject, and kept around). 在第一次load或者利用reload命令时,对应的值才会从新计算一遍
    • TaskKey[T]: a key for a value, called a task, that has to be recomputed each time, potentially with side effects.
    • InputKey[T]: a key for a task that has command line arguments as input
  • 内置的key
    The built-in keys are just fields in an object called Keys. build.sbt隐式的import 了sbt.Keys._

  • 自定义key
    自定义key值需要利用SettingKey[T], TaskKey[T], or InputKey[T]的构造方法。每种构造方法都需要key值对应的类型以及描述,key的name即为赋值的变量名。比如利用以下语法定义一个名为hello的task key:

    lazy val hello = taskKey[Unit]("An example task")
    
  • 定义Task 和 Settings
    TaskKey[T] 是用来定义task(任务)的,task是一些操作,比如compile(编译)、package(将项目打包)等。这些task可能返回的是Unit(仅仅执行一些动作),也可能具有返回值,如果包含package的TaskKey[File],其中File为其打包好的jar文件,故返回值为File类型。
    每次执行task时,比如在sbt终端输入compile来进行编译时,所有包含compile的task都会从新执行一次。其实compile以及run等就是定义在sbt._包中的task,所以在sbt终端输入run命令就可以执行run任务了。可以自定义task,比如:

    lazy val hi = taskKey[Unit]("An example task")
    lazy val hello = (project in file("."))
      .settings( 
         hi := {println("Hello, world")
         name = "Hello"
         )
    

    reload后,在sbt终端输入hi命令后,就会执行hi task,打印Hello,world。在定义后加了description(“An example task”),在终端输入inspect hi 时,可以查看hi task的相关信息。其中name为内置的settingKey,设置subproject的name,由于是内置的,故不用像hi一样利用构造方法来创建,可直接对该变量赋值。
    利用 := 能够对setting赋值,也可以对task赋一个计算(computation)。对于setting来说,赋给setting的值会在每次load时计算一次;对与task来说,让task对应的命令执行时,其对应的computation会从新执行一次。

  • bare build definition
    settints可以直接在build.sbt中定义,不用写在.settings()中,这种定义称为bare style:

    ThisBuild / version := "1.0"
    ThisBuild / scalaVersion := "2.12.7"
    
  • 添加库依赖(library dependencies)
    有两种方法可以添加第三方库。第一种方法是将外部jar包放在lib/ 文件夹中(非托管包);第二种方法是在build.sbt中添加托管包。例如,用以下方法能够添加 Apache Derby 库, 版本是 10.4.1.3。

    val derby = "org.apache.derby" % "derby" % "10.4.1.3"
    
    ThisBuild / organization := "com.example"
    ThisBuild / scalaVersion := "2.12.7"
    ThisBuild / version      := "0.1.0-SNAPSHOT"
    
    lazy val root = (project in file("."))
     .settings(
        name := "Hello",
        libraryDependencies += derby
      )
    

4. Multi-project builds

当多个子项目相互关联时,在同一个build中管理他们会很方便。每一个子项目都有各自的源文件夹,当使用package命令时生成各自的jar文件。project在build.sbt中利用project类型的lazy val定义:

lazy val util = (project in file("util"))

lazy val core = (project in file("core"))

上述两个subProject的ID分别是 util和core,没有在.settings()中定义name时,name与ID相同。在sbt终端中利用与subProject对应的name来管理该subProject。
当文件夹名与 lazy val名相同时,在定义时其对应的文件夹可省略:

lazy val util = project

lazy val core = project

要想将common设置与每个subProject的设置区分开,可以像下面这样:

ThisBuild / organization := "com.example"
ThisBuild / version      := "0.1.0-SNAPSHOT"
ThisBuild / scalaVersion := "2.12.7"
// common settings

lazy val core = (project in file("core"))
  .settings(
    // 只与core subproject相关的settings
  )

lazy val util = (project in file("util"))
  .settings(
    // 只与util有关的settings
  )

同一个build下的不同subproject可以完全独立,也可以通过以下两种方式建立相互依赖的关系:aggregate and classpath.

  1. Aggregation(聚合)

    Aggregation means that running a task on the aggregate project will also run it on the aggregated projects

    意思就是将不同subproject(称为aggregated projects)聚合成一个Project(称为aggregate project),如:

    lazy val root = (project in file("."))
        .aggregate(util, core)
    
    lazy val util = (project in file("util"))
    
    lazy val core = (project in file("core"))
    
  2. Classpath dependencies(类路径依赖)
    当一个subproject依赖于另外一个subproject的代码时,可以调用project类的dependsOn方法实现这种依赖性。

    lazy val core = project.dependsOn(util)
    

    如此,在core中就可以使用util中的类了。不过由于core依赖util,因此必须先compile util中的类,然后才开始compile core中的代码


5. Library dependencies

库文件依赖可以分为以下两种类型:

  • 非托管库(unmanaged dependencies):放在lib/路径下的jar包
  • 托管库(managed dependencies):在构建定义中(build definition)中配置的,由sbt自动从资料库下载的库。
  1. 非托管库
    大多数人喜欢用托管库,不过实际上非托管库更方便,只需要将jar包放在lib/路径下,它们就会被加到项目类路径(classpass)中。也可以将测试包(如 ScalaCheck, Specs2, and ScalaTest)放进lib/路径下。

  2. 托管库
    sbt使用 Apache Ivy (是一种比较流行的包管理器)来实现包依赖的托管管理。

    libraryDependencies 关键字
      一般情况下只需要在project setting中将libraryDependencies 列出来即可;也可以自己另外写一个maven或者Ivy配置文件,然后利用sbt来使用这些外部文件。
      用以下方式声明包依赖:其中groupId, artifactId, and revision需要指定

    libraryDependencies += groupID % artifactID % revision
    libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3"
    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值