mirror of https://github.com/sbt/sbt.git
147 lines
4.7 KiB
ReStructuredText
147 lines
4.7 KiB
ReStructuredText
==============
|
|
Cross-building
|
|
==============
|
|
|
|
Introduction
|
|
============
|
|
|
|
Different versions of Scala can be binary incompatible, despite
|
|
maintaining source compatibility. This page describes how to use `sbt`
|
|
to build and publish your project against multiple versions of Scala and
|
|
how to use libraries that have done the same.
|
|
|
|
Publishing Conventions
|
|
======================
|
|
|
|
The underlying mechanism used to indicate which version of Scala a
|
|
library was compiled against is to append `_<scala-version>` to the
|
|
library's name. For Scala 2.10.0 and later, the binary version is used.
|
|
For example, `dispatch` becomes `dispatch_2.8.1` for the variant
|
|
compiled against Scala 2.8.1 and `dispatch_2.10` when compiled against
|
|
2.10.0, 2.10.0-M1 or any 2.10.x version. This fairly simple approach
|
|
allows interoperability with users of Maven, Ant and other build tools.
|
|
|
|
The rest of this page describes how `sbt` handles this for you as part
|
|
of cross-building.
|
|
|
|
Using Cross-Built Libraries
|
|
===========================
|
|
|
|
To use a library built against multiple versions of Scala, double the
|
|
first `%` in an inline dependency to be `%%`. This tells `sbt`
|
|
that it should append the current version of Scala being used to build
|
|
the library to the dependency's name. For example:
|
|
|
|
::
|
|
|
|
libraryDependencies += "net.databinder" %% "dispatch" % "0.8.0"
|
|
|
|
A nearly equivalent, manual alternative for a fixed version of Scala is:
|
|
|
|
::
|
|
|
|
libraryDependencies += "net.databinder" % "dispatch_2.10" % "0.8.0"
|
|
|
|
or for Scala versions before 2.10:
|
|
|
|
::
|
|
|
|
libraryDependencies += "net.databinder" % "dispatch_2.8.1" % "0.8.0"
|
|
|
|
Cross-Building a Project
|
|
========================
|
|
|
|
Define the versions of Scala to build against in the
|
|
:key:`crossScalaVersions` setting. Versions of Scala 2.8.0 or later are
|
|
allowed. For example, in a `.sbt` build definition:
|
|
|
|
::
|
|
|
|
crossScalaVersions := Seq("2.8.2", "2.9.2", "2.10.0")
|
|
|
|
To build against all versions listed in `build.scala.versions`, prefix
|
|
the action to run with `+`. For example:
|
|
|
|
::
|
|
|
|
> + package
|
|
|
|
A typical way to use this feature is to do development on a single Scala
|
|
version (no `+` prefix) and then cross-build (using `+`)
|
|
occasionally and when releasing. The ultimate purpose of `+` is to
|
|
cross-publish your project. That is, by doing:
|
|
|
|
.. code-block:: console
|
|
|
|
> + publish
|
|
|
|
you make your project available to users for different versions of
|
|
Scala. See :doc:`Publishing` for more details on publishing your project.
|
|
|
|
In order to make this process as quick as possible, different output and
|
|
managed dependency directories are used for different versions of Scala.
|
|
For example, when building against Scala 2.10.0,
|
|
|
|
- `./target/` becomes `./target/scala_2.1.0/`
|
|
- `./lib_managed/` becomes `./lib_managed/scala_2.10/`
|
|
|
|
Packaged jars, wars, and other artifacts have `_<scala-version>`
|
|
appended to the normal artifact ID as mentioned in the Publishing
|
|
Conventions section above.
|
|
|
|
This means that the outputs of each build against each version of Scala
|
|
are independent of the others. `sbt` will resolve your dependencies
|
|
for each version separately. This way, for example, you get the version
|
|
of Dispatch compiled against 2.8.1 for your 2.8.1 build, the version
|
|
compiled against 2.10 for your 2.10.x builds, and so on. You can have
|
|
fine-grained control over the behavior for for different Scala versions
|
|
by using the `cross` method on `ModuleID` These are equivalent:
|
|
|
|
::
|
|
|
|
"a" % "b" % "1.0"
|
|
"a" % "b" % "1.0" cross CrossVersion.Disabled
|
|
|
|
These are equivalent:
|
|
|
|
::
|
|
|
|
"a" %% "b" % "1.0"
|
|
"a" % "b" % "1.0" cross CrossVersion.binary
|
|
|
|
This overrides the defaults to always use the full Scala version instead
|
|
of the binary Scala version:
|
|
|
|
::
|
|
|
|
"a" % "b" % "1.0" cross CrossVersion.full
|
|
|
|
This uses a custom function to determine the Scala version to use based
|
|
on the binary Scala version:
|
|
|
|
::
|
|
|
|
"a" % "b" % "1.0" cross CrossVersion.binaryMapped {
|
|
case "2.9.1" => "2.9.0" // remember that pre-2.10, binary=full
|
|
case "2.10" => "2.10.0" // useful if a%b was released with the old style
|
|
case x => x
|
|
}
|
|
|
|
This uses a custom function to determine the Scala version to use based
|
|
on the full Scala version:
|
|
|
|
::
|
|
|
|
"a" % "b" % "1.0" cross CrossVersion.fullMapped {
|
|
case "2.9.1" => "2.9.0"
|
|
case x => x
|
|
}
|
|
|
|
A custom function is mainly used when cross-building and a dependency
|
|
isn't available for all Scala versions or it uses a different convention
|
|
than the default.
|
|
|
|
As a final note, you can use `++ <version>` to temporarily switch the
|
|
Scala version currently being used to build. `<version>` should be either a version for Scala published to a repository, as in `++ 2.10.0` or the path to a Scala home directory, as in `++ /path/to/scala/home`. See
|
|
:doc:`/Detailed-Topics/Command-Line-Reference` for details.
|