要約: sbt という名前は何かの略ではなく、単に「sbt」です。そのように書く必要があります。
Mark Harrah (@harrah) が最初にこのプロジェクトを作成したとき、「Simple Build Tool」と呼んでいましたが、最初の公式発表では、すでに単に「sbt」と呼んでいました。時が経つにつれて、sbt を「Scala Build Tool」の略として再定義する人もいましたが、Java のみのプロジェクトをビルドするためにも使用できることを考えると、それも正確ではないと考えています。
現在では、sbt を単に「sbt」と呼んでおり、名前がもはや頭字語ではないことを強調するために、常にすべて小文字で記述しています。ただし、酢豚 (subuta) をニックネームとして使用することは問題ありません。
sbt 1.9.8 は、デフォルトでは、ほとんどのスタックトレースとデバッグ情報を抑制します。画面上のノイズを少なくするという良い副作用がありますが、初心者にとっては説明がわからなくなる可能性があります。コマンドの以前の出力をより詳細な冗長性で表示するには、「last <task>」と入力します。ここで、「<task>」は失敗したタスク、または詳細な出力を表示するタスクです。たとえば、「update」が期待どおりにすべての依存関係をロードできないことがわかった場合は、次のように入力します。
> last update
すると、「update」コマンドの最後の実行からの完全な出力が表示されます。
sbt が ANSI コードがサポートされていないことを検出しない場合があり、次のような出力が表示されることがあります。
[0m[ [0minfo [0m] [0mSet current project to root
または、ANSI コードはサポートされていますが、色付きの出力を無効にしたい場合があります。ANSI コードを完全に無効にするには、「-no-colors」オプションを渡します。
$ sbt -no-colors
sbt のシェルで「console」を実行します。
これらは、「Setting」または「Task」を構築するために使用されるキーのメソッドです。入門ガイドでは、これらのすべてのメソッドについて説明しています。たとえば、.sbt ビルド定義、タスクグラフ、値の追加を参照してください。
管理された依存関係を指定するときに、文字列から「ModuleID」を作成するために使用されます。ライブラリの依存関係に関する入門ガイドをお読みください。
`ThisBuild` は、ビルドのデフォルト値を定義するために使用できる特別なサブプロジェクト名として機能します。1 つ以上のサブプロジェクトを定義し、サブプロジェクトが `scalaVersion` キーを定義していない場合、`ThisBuild / scalaVersion` を探します。
ビルド全体の設定を参照してください。
不明な型またはメソッドを調べるには、まだの場合は入門ガイドをご覧ください。また、一般的に使用されるメソッド、値、および型の索引と、API ドキュメントも試してみてください。
アーティファクトに含まれるファイルは、デフォルトでは、関連するパッケージタスクによってスコープが設定されたタスク「mappings」によって設定されます。「mappings」タスクは、含めるファイルから jar 内のパスへのマッピングのシーケンス `Seq[(File,String)]` を返します。これらのマッピングの作成の詳細については、ファイルのマッピングを参照してください。
たとえば、生成されたソースをパッケージ化されたソースアーティファクトに追加するには、次のようにします。
Compile / packageSrc / mappings ++= {
import Path.{flat, relativeTo}
val base = (Compile / sourceManaged).value
val srcs = (Compile / managedSources).value
srcs pair (relativeTo(base) | flat)
}
これは、「managedSources」タスクからソースを取得し、「managedSource」ベースディレクトリに対して相対化し、フラット化されたマッピングにフォールバックします。ソース生成タスクが「managedSource」ディレクトリにソースを書き込まない場合、マッピング関数を調整して、追加のディレクトリに対して相対化を試みるか、ジェネレーターに適したものにする必要があります。
ファイルの生成を参照してください。
キャッシングを参照してください。
カスタム依存関係設定を定義する方法を参照してください。
この回答は、メーリングリストのディスカッションから抜粋したものです。
背景については、カスタム設定までの入門ガイドをお読みください。
基本的な実行タスクは、次のように作成されます。
lazy val myRunTask = taskKey[Unit]("A custom run task.")
// this can go either in a `build.sbt` or the settings member
// of a Project in a full configuration
fullRunTask(myRunTask, Test, "foo.Foo", "arg1", "arg2")
コマンドラインで引数を指定できるようにするには、「TaskKey」を「InputKey」に、「fullRunTask」を「fullRunInputTask」に置き換えます。「Test」部分は、「Compile」などの別の設定に置き換えて、その設定のクラスパスを使用できます。
この実行タスクは、スコープでタスクキーを指定することで、個別に設定できます。たとえば、
myRunTask / fork := true
myRunTask / javaOptions += "-Xmx6144m"
ツールの依存関係はタスクの実装に使用され、プロジェクトのソースコードでは必要ありません。これらの依存関係は、独自の構成とクラスパスで宣言できます。手順は以下のとおりです。
例として、proguard
タスクを考えてみましょう。このタスクは、ツールを実行するためにProGuard jarを必要とします。まず、新しい構成を定義して追加します。
lazy val ProguardConfig = config("proguard").hide
ivyConfigurations += ProguardConfig
次に、
// Add proguard as a dependency in the custom configuration.
// This keeps it separate from project dependencies.
libraryDependencies +=
"net.sf.proguard" % "proguard" % "4.4" % ProguardConfig.name
// Extract the dependencies from the UpdateReport.
ProguardConfig / managedClasspath := {
// these are the types of artifacts to include
val artifactTypes: Set[String] = (ProguardConfig / classpathTypes).value
Classpaths.managedJars(proguardConfig, artifactTypes, update.value)
}
// Use the dependencies in a task, typically by putting them
// in a ClassLoader and reflectively calling an appropriate
// method.
proguard := {
val cp: Seq[File] = (ProguardConfig / managedClasspath).value
// ... do something with , which includes proguard ...
}
中間クラスパスの定義はオプションですが、デバッグに役立つ場合や、複数のタスクで使用される必要がある場合に便利です。アーティファクトタイプをインラインで指定することも可能です。この代替のproguard
タスクは次のようになります。
proguard := {
val artifactTypes = Set("jar")
val cp =
Classpaths.managedJars(proguardConfig, artifactTypes, update.value)
// ... do something with , which includes proguard ...
}
sbtのクラスパスに配置される追加のjarを登録することができます。Stateを通して、アプリケーションコンポーネントを管理するxsbti.ComponentProviderを取得できます。コンポーネントは~/.sbt/boot/
ディレクトリにあるファイルのグループであり、この場合はアプリケーションはsbtです。基本クラスパスに加えて、「extra」コンポーネントのコンポーネントがsbtのクラスパスに含まれます。
(注:アプリケーションのクラスパスに追加されるコンポーネントは、ランチャー構成ファイルboot.properties
の[main]
セクションのcomponents
プロパティによって宣言されます。)
これらのコンポーネントは~/.sbt/boot/
ディレクトリに追加され、~/.sbt/boot/
は読み取り専用である可能性があるため、これは失敗する可能性があります。この場合、ユーザーは一般的に意図的にsbtをこのように設定しているため、エラー回復は通常必要ありません(状況を説明する短いエラーメッセージだけで十分です)。
以下のコードは、State => State
が必要な場合、例えば、onLoad
設定(下記参照)やコマンドなどで使用できます。これは「extra」コンポーネントにいくつかのファイルを追加し、まだ追加されていない場合はsbtをリロードします。リロードすると、ユーザーのセッション状態が失われることに注意してください。
def augment(extra: Seq[File])(s: State): State = {
// Get the component provider
val cs: xsbti.ComponentProvider = s.configuration.provider.components()
// Adds the files in 'extra' to the "extra" component
// under an exclusive machine-wide lock.
// The returned value is 'true' if files were actually copied and 'false'
// if the target files already exists (based on name only).
val copied: Boolean = s.locked(cs.lockFile, cs.addToComponent("extra", extra.toArray))
// If files were copied, reload so that we use the new classpath.
if(copied) s.reload else s
}
起動時にアクションを実行する方法を参照してください。
次の例では、プロジェクトがロードされた回数をカウントし、その数を表示します。
{
// the key for the current count
val key = AttributeKey[Int]("loadCount")
// the State transformer
val f = (s: State) => {
val previous = s get key getOrElse 0
println("Project load count: " + previous)
s.put(key, previous + 1)
}
Global / onLoad := {
val previous = (Global / onLoad).value
f compose previous
}
}
設定イニシャライザは順番に実行されます。設定の初期化が初期化されていない他の設定に依存している場合、sbtはロードを停止します。
この例では、空のシーケンスで初期化する前に、libraryDependencies
にライブラリを追加しようとしています。
libraryDependencies += "commons-io" % "commons-io" % "1.4" % "test"
disablePlugins(plugins.IvyPlugin)
これを修正するには、libraryDependencies := Seq()
を含むIvyPluginプラグイン設定を含めます。そのため、明示的な無効化を削除するだけです。
libraryDependencies += "commons-io" % "commons-io" % "1.4" % "test"
このエラーのより微妙なバリエーションは、スコープ設定を使用する場合に発生します。
// error: Reference to uninitialized setting
settings = Seq(
libraryDependencies += "commons-io" % "commons-io" % "1.2" % "test",
fullClasspath := fullClasspath.value.filterNot(_.data.name.contains("commons-io"))
)
この設定は、テストスコープとコンパイルスコープで異なります。解決策は、イニシャライザへの入力として、そして更新する設定として、スコープ設定を使用することです。
Compile / fullClasspath := (Compile / fullClasspath).value.filterNot(_.data.name.contains("commons-io"))
このエラーは、sha1やmd5ハッシュなどの公開されているチェックサムが、jarやpom.xmlなどのダウンロードされたアーティファクトに対して計算されたチェックサムと異なる場合に発生します。このようなエラーの例は次のとおりです。
[warn] problem while downloading module descriptor:
https://repo1.maven.org/maven2/commons-fileupload/commons-fileupload/1.2.2/commons-fileupload-1.2.2.pom:
invalid sha1: expected=ad3fda4adc95eb0d061341228cc94845ddb9a6fe computed=0ce5d4a03b07c8b00ab60252e5cacdc708a4e6d8 (1070ms)
無効なチェックサムは、一般的にリポジトリの所有者に報告する必要があります(上記のエラーについてはこちらで行われました)。 一時的にチェックを無効にするには、次の設定を使用します。
checksums in update := Nil
詳細は、ライブラリ管理を参照してください。
この問題は頻繁に発生します。プラグインは、sbtが使用するScalaバージョン(現在は2.12)に対してのみ公開されます。 sbtはプラグインの2.12バージョンのみを検索するため、クロスコンパイル中にプラグインを*使用*することはできます。
…間違った場所にプラグインを指定しない限り!
典型的な間違いは、グローバルプラグイン定義を~/.sbt/plugins.sbt
に配置することです。 **これは間違っています。** ~/.sbt
にある.sbt
ファイルは、*各*ビルド、つまり*各*クロスコンパイルに対してロードされます。そのため、Scala 2.11.0用にビルドする場合、sbtは2.11.0用にコンパイルされたプラグインのバージョンを見つけようとしますが、通常は見つかりません。依存関係がプラグインであることを*知ら*ないからです。
依存関係がsbtプラグインであることをsbtに伝えるには、グローバルプラグインを~/.sbt/plugins/
にある.sbt
ファイルで定義してください。 sbtは、~/.sbt/plugins
内のファイルはsbt自体によってのみ使用され、一般的なビルド定義の一部としては使用されないことを認識しています。 *その*ディレクトリの下にあるファイルでプラグインを定義すると、クロスコンパイルが混乱することはありません。 .sbt
で終わるファイル名であれば何でも構いませんが、ほとんどの人は~/.sbt/plugins/build.sbt
または~/.sbt/plugins/plugins.sbt
を使用します。
現在利用可能なプラグインのリストについては、コミュニティプラグインを参照してください。