sbtについて調べた
scalaを書くにあたってsbt
を使う必要があったのでまとめておく。公式ドキュメントは以下にある。
Contents sbt Documentation http://www.scala-sbt.org/release/docs/index.html
公式ドキュメントをみつつ、sbtのセットアップ方法をまとめておく。環境は以下のとおり。
% uname -a Darwin HOST 12.4.0 Darwin Kernel Version 12.4.0: Wed May 1 17:57:12 PDT 2013; root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64 % system_profiler SPSoftwareDataType | grep "System Version" System Version: OS X 10.8.4 (12E55) % brew --version 0.9.4 % scala -version Scala code runner version 2.9.2 -- Copyright 2002-2011, LAMP/EPFL
セットアップ方法
まずインストール
% brew install sbt
とりあえず作業ディレクトリを/tmp/sbt_test
とした。バージョンをみるにはsbt about
。
% sbt about [info] Set current project to default-cf6087 (in build file:/private/tmp/sbt_test/) [info] This is sbt 0.11.3 [info] The current project is {file:/private/tmp/sbt_test/}default-cf6087 [info] The current project is built against Scala 2.9.1 [info] sbt, sbt plugins, and build definitions are using Scala 2.9.1
こんな感じのファイルをhw.scala
として配置しておく。
object Hi { def main(args: Array[String]) = println("Hi!") }
sbt
でコンソールを開き、run
するとビルドできる。Hi!と出力されているのが確認できる。
% pwd /tmp/sbt_test % ls hw.scala % sbt [info] Set current project to default-cf6087 (in build file:/private/tmp/sbt_test/) > run [info] Updating {file:/private/tmp/sbt_test/}default-cf6087... [info] Resolving org.scala-lang#scala-library;2.9.1 ... [info] Done updating. [info] Compiling 1 Scala source to /private/tmp/sbt_test/target/scala-2.9.1/classes... [info] Running Hi Hi! [success] Total time: 4 s, completed 2013/08/01 10:18:49 >
設定
設定情報はbuild.sbt
に書く。設定の書き方は以下に載っている。
.sbt Build Definition — sbt Documentation http://www.scala-sbt.org/release/docs/Getting-Started/Basic-Def.html
試しに以下のようにbuild.sbtを書いた
name := "hello" version := "1.0" scalaVersion := "2.9.1"
これを/tmp/sbt_test/build.sbt
に配置して、sbt
する。
% sbt [info] Set current project to hello (in build file:/private/tmp/sbt_test/) > run [info] Updating {file:/private/tmp/sbt_test/}default-cf6087... [info] Resolving org.scala-lang#scala-library;2.9.1 ... [info] Done updating. [info] Running Hi Hi! [success] Total time: 1 s, completed 2013/08/01 10:32:04 % ls build.sbt hw.scala project target
するとprojectディレクトリが作成される。sbt関連のランチャーっぽいものが生成されているようだ。
% tree project project └── target └── config-classes ├── $81beed32fd363d86c9c3$$anonfun$$sbtdef$1.class ├── $81beed32fd363d86c9c3$.class ├── $81beed32fd363d86c9c3.class ├── $f0b4b64e830dcd216535$$anonfun$$sbtdef$1.class ├── $f0b4b64e830dcd216535$.class ├── $f0b4b64e830dcd216535.class ├── $fc2285516a79659283ee$$anonfun$$sbtdef$1.class ├── $fc2285516a79659283ee$.class └── $fc2285516a79659283ee.class 2 directories, 9 files % javap project.target.config-classes.\$81beed32fd363d86c9c3 Warning: Binary file project.target.config-classes.$81beed32fd363d86c9c3 contains $81beed32fd363d86c9c3 Compiled from "/private/tmp/sbt_test/build.sbt" public final class $81beed32fd363d86c9c3 { public static final sbt.Init<sbt.Scope>.SettingsDefinition $sbtdef(); }
実際のディレクトリ構造
Directory structure — sbt Documentation http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html
実際にはMavenなどと同様のディレクトリ構造にする。
sbtのインタラクティブモードについて
sbt
でインタラクティブモードを起動できる。
% sbt [info] Set current project to hello (in build file:/private/tmp/sbt_test/) > help help command* Displays this help message or prints detailed help on requested commands. about Displays basic information about sbt and the build. reboot [full] Reboots sbt and then executes the remaining commands. < file* Reads command lines from the provided files. !! Execute the last command again !: Show all previous commands !:n Show the last n commands !n Execute the command with index n, as shown by the !: command !-n Execute the nth command before this one !string Execute the most recent command starting with 'string' !?string Execute the most recent command containing 'string' ~ <command> Executes the specified command whenever source files change. exit Terminates the build. reload Loads the project in the current directory projects Displays the names of available projects. project [project] Displays the current project or changes to the provided `project`. - command Registers 'command' to run if a command fails. iflast command If there are no more commands after this one, 'command' is run. ( ; command )+ Runs the provided semicolon-separated commands. shell Provides an interactive prompt from which commands can be run. set <setting-expression> Evaluates the given Setting and applies to the current project. tasks Displays the tasks defined for the current project. inspect <key> Prints the value for 'key', the defining scope, delegates, related definitions, and dependencies. eval <expression> Evaluates the given Scala expression and prints the result and type. alias Adds, removes, or prints command aliases. append command Appends `command` to list of commands to run. last <key> Prints the last output associated with 'key'. last-grep <pattern> <key> Shows lines from the last output for 'key' that match 'pattern'. session ... Manipulates session settings. For details, run 'help session'.. show <key> Displays the result of evaluating the setting or task associated with 'key'.
便利そうなのが、継続的にビルドする機能。~ compile
するだけ。これでソースの変更を見はってくれる。watchrとか使うより手軽でよい。
> ~ compile [success] Total time: 0 s, completed 2013/08/01 10:45:44 1. Waiting for source changes... (press enter to interrupt)
実行のトリガについてはここにまとめてのってる。テストだけ継続的に実行することもできる。
Triggered Execution — sbt Documentation http://www.scala-sbt.org/release/docs/Detailed-Topics/Triggered-Execution.html
外部ライブラリの読み込み
再び設定の話。せっかくだからMavenではなくてsbtに統一したいところ。.sbt Build Definitionによると、build.sbtに以下のように書けばよい。
libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3"
ライブラリの依存関係については以下に書かれている。
Library Dependencies — sbt Documentation http://www.scala-sbt.org/release/docs/Getting-Started/Library-Dependencies.html
このlibraryDependenciesの書式は以下の様なルールに基づいている。%
をつかうのはApache Ivyの流儀らしい。
libraryDependencies += groupID % artifactID % revision % configuration
まとめて書きたいなら以下のようにもできる。
libraryDependencies ++= Seq( groupID % artifactID % revision, groupID % otherID % otherRevision )
scalaのバージョンなどについては%%
表記すれば設定値から渡せるらしい。
libraryDependencies += "org.scala-tools" % "scala-stm_2.9.1" % "0.3"
とあるものを、
libraryDependencies += "org.scala-tools" %% "scala-stm" % "0.3"
書いておけば、build.sbt
内のscalaVersion
から設定値を当てはめてくれるようになっている。もし複数のScalaバージョンにまたがるリリースを行いたい場合にはCross-Buildingの設定をするといいらしい。
Cross-building — sbt Documentation http://www.scala-sbt.org/release/docs/Detailed-Topics/Cross-Build.html
また、テスト用にだけ使いたい依存ライブラリについてはtest
をconfiguration
に設定するとよい。
libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3" % "test"
こうするとTest
の時についてのみclasspathに設定されるようになっている。
Mavenを併用したい場合には、外部設定として読みこむようにもできる。
Library Management — sbt Documentation http://www.scala-sbt.org/release/docs/Detailed-Topics/Library-Management.html
以下のようにする。
externalPom() or externalPom(baseDirectory(_ / "custom-name.xml"))
これにより依存関係のみMavenで管理することもできる。ただし、sbtはIvyをベースに作られているので、IvyがサポートしていないPOMは利用できないという制限がある。