Scalaのビルドツールsbtを使ってみる

昼間、Twitterのタイムラインを眺めていたら、今日はScala会議という勉強会が開かれていたみたいだ。

partake.in

http://www.ustream.tv/channel/scala-kaigi
Ustreamでも流れていたので、ちらっと見た。なんだか、おもしろそうな話題がたくさんだった。

scala-kaigi1-sbt
発表者のかたが準備されたこちらの資料とsbtのページを参考にさせてもらって、自分もsbtをつかってみよう。ちょうど、Mavenを勉強しなおしたところで、ビルドツールにちょっと興味がでている。

Home · harrah/xsbt Wiki · GitHub
sbtはScalaのビルドツール。こいつもGithubなのか。Githubよくみかけるなあ。

sbtのインストール

sbt 0.12 インストール 2012-11-04 追記

sbtもすこしずつ使い勝手がよくなっているようだ。インストールも楽になっている。詳細は以下。

sbt 0.12 インストール

sbt 0.10 インストール

sbt-launch.jarこいつをダウンロードして、どこかクラスパスのとおったところに置くようにと。

さらに、sbtのスクリプトファイルを自分で作ると。
sbt.cmd

@echo off
set PROJECT_HOME=.
rem java -Xmx512m -Dfile.encoding=UTF-8 -jar "%PROJECT_HOME%\sbt-launch.jar" %*
rem デフォルトのエンコーディングにしないとコンソールの日本語が文字化けるようだ。
java -Xmx512m -jar "%PROJECT_HOME%\sbt-launch.jar" %*

sbtの起動

プロジェクトのディレクトリをつくって、そこで移動して、sbtコマンドを実行する。

プロジェクトのルートディレクトリは手作業で作るみたいだ。ほんとにそうなのか?、、、、

  • helloworld
    • sbt.cmd
    • sbt-launch.jar

ここでコマンドプロンプトからsbt.cmdを実行

Mavenの依存ライブラリのダウンロードのような、長いダウンロードがはじまった。。。。

F:\Data\Scala\sbtprojects\helloworld>sbt
Getting net.java.dev.jna jna 3.2.3 ...
downloading http://repo1.maven.org/maven2/net/java/dev/jna/jna/3.2.3/jna-3.2.3.jar ...
        [SUCCESSFUL ] net.java.dev.jna#jna;3.2.3!jna.jar (3464ms)
:: retrieving :: org.scala-tools.sbt#boot-app
        confs: [default]

....


:: retrieving :: org.scala-tools.sbt#boot-app
        confs: [default]
        36 artifacts copied, 0 already retrieved (6414kB/406ms)
[info] Set current project to default-fa8b09 (in build file:/F:/Data/Scala/sbtprojects/helloworld/)
>

5分ぐらいで、ダウンロードが終わった。

コンソールに表示された動作ログ?を見る限り、Home | Apache Ivy ™で依存ライブラリをダウンロードしているようだ。

sbtのリポジトリがあるわけでなくて、Mavenリポジトリをそのまま利用しているのか。なるほど。jarになってれば、Scalaからでも利用できるんだもんな。

sbtのコマンド実行

上のダウンロードが終わって、sbtのコンソールが起動しっぱなしの状態なのだろうか?

とりあえず、helpしてみる。

> help

  help command*               Displays this help message or prints detailed help on requested commands.
  reboot [full]               Reboots sbt and then executes the remaining commands.

....


  last-grep <pattern> <key>   Shows lines from the last output for 'key' that match 'pattern'.
  session ...                 Manipulates session settings.  For details, run 'help session'..

>

なんかいっぱいでた。終了するには、

> exit

F:\Data\Scala\sbtprojects\helloworld>

ディレクトリ構成は、

  • helloworld
    • project
      • なにかいろいろできている。
    • target
      • なにかいろいろできている。
    • sbt.cmd
    • sbt-launch.jar

Home · harrah/xsbt Wiki · GitHubを読むと、「ビルドの定義がなければ、デフォルト設定を想定する」と書いてある。

自分のhelloworldディレクトリ配下には、このページの説明にある、下の3つのディレクトリが作成されてないな。そういうものなのなんだろうか。手作業で足しておこう。

  • helloworld
    • src/main/scala
      • 作成されてない!しかたないのでじぶんでつくる。
    • src/test/scala
      • 作成されてない!しかたないのでじぶんでつくる。
    • lib
      • sbtが管理しないjarをおく
      • 作成されてない!しかたないのでじぶんでつくる。

ついでに、mainアプリもつくっておこう。

HelloWorld.scala

object HelloWorld {
    def main(args: Array[String]) {
        println("Hello, World!")
    }
}
  • helloworld
    • lib
    • project
    • src/main/scala
    • test/main/scala
    • target
    • sbt.cmd
    • sbt-launch.jar

もう一回起動だ。

F:\Data\Scala\sbtprojects\helloworld>sbt
[info] Set current project to default-fa8b09 (in build file:/F:/Data/Scala/sbtprojects/helloworld/)
> projects
[info] In file:/F:/Data/Scala/sbtprojects/helloworld/
[info]   * default-fa8b09
>

helloworldはともかく、default-fa8b09がわからないな。まあいいか。
mainアプリを実行するには、runするのか。

> run
[info] Updating {file:/F:/Data/Scala/sbtprojects/helloworld/}default-fa8b09...
[info] Done updating.
[info] Compiling 1 Scala source to F:\Data\Scala\sbtprojects\helloworld\target\scala-2.8.1.final\classes...
[info] Running HelloWorld
Hello, World!
[success] Total time: 5 s, completed 2011/08/29 0:04:07
>

おおー、Hello, Worldとでた。
、、、、Scala 2.8.1じゃなくて2.9.0で動かすにはどうするんだろう。

Home · harrah/xsbt Wiki · GitHubBasic Configuration · harrah/xsbt Wiki · GitHubを読むと、自分のつくったプロジェクトの直下にbuild.sbtを置けばよいようだ。
ほかにproject/Build.scalaをつくる方法もあるのね。とりあえず、build.sbtにしよう。

build.sbt

name := "helloworld"

version := "1.0"

scalaVersion := "2.9.0-1"
  • helloworld
    • lib
    • project
    • src/main/scala
    • test/main/scala
    • target
    • build.sbt
    • sbt.cmd
    • sbt-launch.jar
> run
[info] Running HelloWorld
Hello, World!
[success] Total time: 0 s, completed 2011/08/29 0:10:13

あれ?この手ごたえのなさは、もしかして、compileされてない?変更されているファイルだけビルドなんだろうか。
helpを見て、、、、cleanとcompileでどうよ?

> clean
[success] Total time: 0 s, completed 2011/08/29 0:11:20
> compile
[info] Updating {file:/F:/Data/Scala/sbtprojects/helloworld/}default-fa8b09...
[info] Done updating.
[info] Compiling 1 Scala source to F:\Data\Scala\sbtprojects\helloworld\target\scala-2.8.1.final\classes...
[success] Total time: 2 s, completed 2011/08/29 0:11:28

あれ?compileされなおしたみたいだけど、2.8.1のままじゃん!helpを見て、、、、
build.sbtが効いてないっぽいので、reloadでどうよ?rebootもあるけど、再起動よりはリロードのほうがお手軽だろう。

> reload
Getting Scala 2.9.0-1 ...

....

        4 artifacts copied, 0 already retrieved (20447kB/912ms)
[info] Set current project to default-fa8b09 (in build file:/F:/Data/Scala/sbtprojects/helloworld/)

2.9.0-1をダウンロードしたようだ。build.sbtを読み込みなおして、新たに必要となったライブラリをダウンロードしたということにちがいない!

今度こそ!

> run
[info] Updating {file:/F:/Data/Scala/sbtprojects/helloworld/}default-fa8b09...
[info] Done updating.
[info] Compiling 1 Scala source to F:\Data\Scala\sbtprojects\helloworld\target\scala-2.9.0.1\classes...
[info] Running HelloWorld
Hello, World!
[success] Total time: 5 s, completed 2011/08/29 0:15:19

よし!2.9.0.1で動作したようだ。

HelloWorld.scala(このファイルの文字コードUTF-8)

object HelloWorld {
    def main(args: Array[String]) {
        println("Hello, World!")
        println("こんにちは、世界!")
    }
}

日本語を混ぜてみる。
build.sbtでコンパイル時のファイルエンコーディングを指定する。
パラメータは、あらかじめscalac --helpで確認した。

build.sbt

name := "helloworld"

version := "1.0"

scalaVersion := "2.9.0-1"

scalacOptions ++= Seq("-encoding", "UTF-8")
> reload
[info] Set current project to default-fa8b09 (in build file:/F:/Data/Scala/sbtprojects/helloworld/)
> clean
[success] Total time: 0 s, completed 2011/08/29 23:32:13
> run
[info] Updating {file:/F:/Data/Scala/sbtprojects/helloworld/}default-fa8b09...
[info] Done updating.
[info] Compiling 1 Scala source to F:\Data\Scala\sbtprojects\helloworld\target\scala-2.9.0.1\classes...
[info] Running HelloWorld
Hello, World!
こんにちは、世界!
[success] Total time: 2 s, completed 2011/08/29 23:32:17
>

実は、
build.sbt

scalacOptions ++= Seq("-encoding", "UTF-8")

はなくても、文字化けやコンパイルエラーがでなかった。

scalacOptions ++= Seq("-encoding", "Windows-31J")

としたら、コンソールに表示された文字が、文字化けた。
scalacまたはscalacOptionsファイルエンコーディングのデフォルトはUTF-8なんだろうか?

helpを見ると、evalでScalaを実行できるらしい。

> eval System.getProperty("file.encoding")
[info] ans: java.lang.String = MS932

あら?すくなくとも、file.encodingはふつうにMS932だし。

sbt 0.12 インストール 2012-11-04 追記

sbt 0.12では、インストールは、OSごとに簡単にできるようになっている。

Getting Started Setup · harrah/xsbt Wiki · GitHubにあるとおり、いろいろなOSごとのインストール方法が紹介されている。

Windowsインストーラは以下にある。
http://scalasbt.artifactoryonline.com/scalasbt/sbt-native-packages/org/scala-sbt/sbt/0.12.0/
ここから、zipやtgzファイルをダウンロードして、展開するというシンプルな方法もある。展開したらあとは、bin/sbtを実行するだけ

約1年前に書いた以下のやりかたでも、たぶんインストールはできるけど、新しい、上のやりかたにしたがったほうが良さそう