Frequently Asked Questions

Project Information

What does the name “sbt” stand for, and why shouldn’t it be written “SBT”?

TL;DR the name sbt doesn’t stand for anything, it’s just “sbt”, and it should be written that way.

When Mark Harrah (@harrah) first created the project he called it “Simple Build Tool”, but in his
first public announcement of it he already referred to it as just “sbt”.
Over time some have re-defined sbt to stand for “Scala Build Tool”, but we believe that isn’t accurate either
given it can be used to build Java-only projects.

Nowadays we just call sbt “sbt”, and to reinforce that the name is no longer an initialism we
always write it in all lowercase letters. However, we are cool with 酢豚 (subuta) as a nickname.

How do I get help?

How do I report a bug?

How can I help?

Usage

My last command didn’t work but I can’t see an explanation. Why?

sbt 1.1.1 by default suppresses most stack traces and debugging
information. It has the nice side effect of giving you less noise on
screen, but as a newcomer it can leave you lost for explanation. To see
the previous output of a command at a higher verbosity, type
last <task> where <task> is the task that failed or that you want to
view detailed output for. For example, if you find that your update
fails to load all the dependencies as you expect you can enter:

> last update

and it will display the full output from the last run of the update
command.

How do I disable ansi codes in the output?

Sometimes sbt doesn’t detect that ansi codes aren’t supported and you
get output that looks like:

[0m[ [0minfo [0m] [0mSet current project to root

or ansi codes are supported but you want to disable colored output. To
completely disable ansi codes, pass -no-colors option:

$ sbt -no-colors

How can I start a Scala interpreter (REPL) with sbt project configuration (dependencies, etc.)?

How do I add files to a jar package?

The files included in an artifact are configured by default by a task
mappings that is scoped by the relevant package task. The mappings
task returns a sequence Seq[(File,String)] of mappings from the file
to include to the path within the jar. See
mapping files for details on creating these mappings.

For example, to add generated sources to the packaged source artifact:

This takes sources from the managedSources task and relativizes them
against the managedSource base directory, falling back to a flattened
mapping. If a source generation task doesn’t write the sources to the
managedSource directory, the mapping function would have to be
adjusted to try relativizing against additional directories or something
more appropriate for the generator.

There are two additional arguments for the first parameter list that
allow the file tracking style to be explicitly specified. By default,
the input tracking style is FilesInfo.lastModified, based on a file’s
last modified time, and the output tracking style is FilesInfo.exists,
based only on whether the file exists. The other available style is
FilesInfo.hash, which tracks a file based on a hash of its contents.
See the FilesInfo API for details.

A more advanced version of FileFunction.cached passes a data structure
of type ChangeReport describing the
changes to input and output files since the last evaluation. This
version of cached also expects the set of files generated as output to
be the result of the evaluated function.

Extending sbt

How can I add a new configuration?

The following example demonstrates adding a new set of compilation
settings and tasks to a new configuration called samples. The sources
for this configuration go in src/samples/scala/. Unspecified settings
delegate to those defined for the compile configuration. For example,
if scalacOptions are not overridden for samples, the options for the
main sources are used.

Options specific to samples may be declared like:

scalacOptions in Samples += "-deprecation"

This uses the main options as base options because of +=. Use := to
ignore the main options:

scalacOptions in Samples := "-deprecation" :: Nil

The example adds all of the usual compilation related settings and tasks
to samples:

How can I create a custom run task, in addition to run?

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")

If you want to be able to supply arguments on the command line, replace
TaskKey with InputKey and fullRunTask with fullRunInputTask. The
Test part can be replaced with another configuration, such as
Compile, to use that configuration’s classpath.

This run task can be configured individually by specifying the task key
in the scope. For example:

fork in myRunTask := true
javaOptions in myRunTask += "-Xmx6144m"

How should I express a dependency on an outside tool such as proguard?

Tool dependencies are used to implement a task and are not needed by
project source code. These dependencies can be declared in their own
configuration and classpaths. These are the steps:

// 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.
managedClasspath in proguard := {
// these are the types of artifacts to include
val artifactTypes: Set[String] = (classpathTypes in proguard).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] = (managedClasspath in proguard).value
// ... do something with , which includes proguard ...
}

Defining the intermediate classpath is optional, but it can be useful
for debugging or if it needs to be used by multiple tasks. It is also
possible to specify artifact types inline. This alternative proguard
task would look like:

How would I change sbt’s classpath dynamically?

It is possible to register additional jars that will be placed on sbt’s
classpath (since version 0.10.1). Through
State, it is possible to obtain a
xsbti.ComponentProvider, which
manages application components. Components are groups of files in the
~/.sbt/boot/ directory and, in this case, the application is sbt. In
addition to the base classpath, components in the “extra” component are
included on sbt’s classpath.

(Note: the additional components on an application’s classpath are
declared by the components property in the [main] section of the
launcher configuration file boot.properties.)

Because these components are added to the ~/.sbt/boot/ directory and
~/.sbt/boot/ may be read-only, this can fail. In this case, the user
has generally intentionally set sbt up this way, so error recovery is
not typically necessary (just a short error message explaining the
situation.)

Example of dynamic classpath augmentation

The following code can be used where a State => State is required,
such as in the onLoad setting (described below) or in a
command. It adds some files to the “extra”
component and reloads sbt if they were not already added. Note that
reloading will drop the user’s session state.

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
}

I’ve added a plugin, and now my cross-compilations fail!

This problem crops up frequently. Plugins are only published for the
Scala version that sbt uses (currently, 2.12). You can still use
plugins during cross-compilation, because sbt only looks for a 2.12
version of the plugin.

… unless you specify the plugin in the wrong place!

A typical mistake is to put global plugin definitions in
~/.sbt/plugins.sbt. THIS IS WRONG..sbt files in ~/.sbt are
loaded for each build—that is, for each cross-compilation. So, if
you build for Scala 2.9.0, sbt will try to find a version of the plugin
that’s compiled for 2.9.0—and it usually won’t. That’s because it
doesn’t know the dependency is a plugin.

To tell sbt that the dependency is an sbt plugin, make sure you define
your global plugins in a .sbt file in ~/.sbt/plugins/. sbt knows
that files in ~/.sbt/plugins are only to be used by sbt itself, not as
part of the general build definition. If you define your plugins in a
file under that directory, they won’t foul up your cross-compilations.
Any file name ending in .sbt will do, but most people use
~/.sbt/plugins/build.sbt or ~/.sbt/plugins/plugins.sbt.