Locked History Actions

sbt/stepByStep

ステップバイステップ

ここでは、sbtを使用してひと通りのことができるまで(コンパイル、依存ライブラリの取得、テスト、リリース)までを簡単に見てみる。 なお、話が面倒になるので、IDEは使用しない。sbt、DOS窓、普通のエディタを前提にする。

インストール

0.10以降は、従来のgooglecodeからgihubにウェブサイトが変更されている。https://github.com/harrah/xsbt/wiki/Setup

ダウンロードは、http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-tools.sbt/sbt-launch/の中の最新のものにすればよい。

ダウンロードしたjarファイルは$SCALA_HOME/libやプロジェクトのlibディレクトリ、あるいはその他クラスパスの通ったところには置いてはいけないという。

次にDOS窓でsbtコマンドが使えるように、sbt.batを作成し、これをPATHの通ったところにおくか、PATHを通す。

java -Xmx512M -jar "(sbt-launch.jarをおいたパス)\sbt-launch.jar" %*

初回にsbtコマンドを実行すると、scala環境を勝手にダウンロードしてくるので、終了するまで待つ必要がある。

プロジェクトの作成

DOS窓で適当なディレクトリを作成し、そこに移り、sbt(実際には先に示したsbt.bat)を起動する。

mkdir hello
cd hello
sbt

sbtのコマンドプロンプトになる。このとき、勝手にtargetというディレクトリが作成されている。ここには、sbtの生成物が格納されるらしい。

scalaソースの作成と実行

sbt-0.7では、プロジェクト名やら何やらを聞いてきて、勝手にsrc/main/scala等のディレクトリが作成されていたが、0.10以降ではtargetしか作成されない。そこで、src/main/scalaを手で作成する(いったんexitでsbtを抜ける必要がある)。

mkdir src
mkdir src\main\
mkdir src\main\scala

src/main/scalaの中にHello.scalaを作成する。

object Hello {
  def main(args: Array[String]) {
    println("Hello, World")
  }
}

もう一度sbtコマンドを実行し、プロンプトからrunを入力すると、上記が実行される。 この状態で、「~ compile」と入力すると、なにやら「ソース変更監視モード」(?)になり、Hello.scalaをエディタで編集して保存する都度勝手にコンパイルするようになる。つまり、保存したソースに構文エラーがあれば、すぐにそれを表示してくれる。

このモードを抜けるにはEnter。抜けたときには既にコンパイルが完了しているので、runですぐに実行できる。

ちなみに、run実行のときに複数のmainメソッドがあった場合には、

> run

Multiple main classes detected, select one to run:

 [1] Hello
 [2] FooBar

Enter number:

などと、どれを実行するのか聞いてくる。

設定ファイル

sbtの対話シェルを使って、基本的なコンパイル・実行ができることがわかったが、このやり方では様々な処理を自動的に行わせることはできない。これを行うには設定ファイルを記述する必要がある。

sbt0.10以降では、この設定ファイルとしてlight configurationとfull configurationの二種類があり、これらは共存できるとのことだが、ここでは最初からfull configurationを使ってみることにする。

まずプロジェクトディレクトリにprojectというディレクトリを作成し、その中にBuild.scalaというファイルを作成する。 このファイルは拡張子からもわかるように、以前にあった(現在もサポートされているが).sbtファイルとは異なり、完全にscalaのソースファイルとして処理されるようだ。

例えばBuild.scalaを以下のようにする。

import sbt._
import Keys._

object MyBuild extends Build {
  lazy val helloProject = Project("helloProject", file(".")) settings(
      libraryDependencies += "org.slf4j" % "slf4j-api" % "1.6.2"
  )
}

そして、Hello.scalaを以下のようにする。

import org.slf4j.Logger
import org.slf4j.LoggerFactory

class Hello {
}
object Hello {
  def main(args: Array[String]) {
    val logger = LoggerFactory.getLogger(classOf[Hello])
    logger.info("Hello, World")
    println("Hello, World")
  }
}

コンパイルが成功し、実行もできる(ただし、slf4jの中身が無いので実行時エラー)。

ダウンロードされた依存jarのありか

先の設定による依存jar(実際にアプリの中で呼び出さない限り実際にダウンロードはされない)のダウンロードはsbt内部でivyを使って行われるらしい。そして実際にダウンロードされたjarファイルはivyのキャッシュに保存される。windows7の場合、c:\users\ユーザ名\.ivy2\cacheの下になる。

sbt0.7では、ダウンロードされた依存jarはlib_managedディレクトリに集められたが、0.10以降は上記のようになっている。以前のバージョンと同じようにlib_managedディレクトリに集めたい場合には、「retrieveManaged := true」を追加する。例えば、

import sbt._
import Keys._

object MyBuild extends Build {
  lazy val helloProject = Project("helloProject", file(".")) settings(
      libraryDependencies += "org.slf4j" % "slf4j-api" % "1.6.2",
      libraryDependencies += "com.borachio" % "borachio-core_2.9.1" % "1.3",
      retrieveManaged := true
  )
}

ソースファイルパスの変更

ソースファイルパスをsrc/main/scalaではなく、srcにしたい。

import sbt._
import Keys._

object MyBuild extends Build {
  lazy val helloProject = Project("helloProject", file(".")) settings(
      libraryDependencies += "org.slf4j" % "slf4j-api" % "1.6.2",
      libraryDependencies += "com.borachio" % "borachio-core_2.9.1" % "1.3",
      retrieveManaged := true,
      unmanagedSourceDirectories in Compile <+= baseDirectory{ _ / "src"}
  )
}

参考:https://groups.google.com/group/simple-build-tool/browse_thread/thread/03d22fe8cf33b94f