Bazel is a tool for building and testing software and can handle large, multi-language projects at scale.
This project defines core build rules for Scala that can be used to build, test, and package Scala projects.
- scala_library
- scala_macro_library
- scala_binary
- scala_test
- scala_repl
- scala_library_suite
- scala_test_suite
- thrift_library
- scala_proto_library
- scala_toolchain
- scala_import
- scala_doc
Install Bazel, preferably using the Bazelisk wrapper. See the compatible Bazel versions section to select a suitable Bazel version.
Add the following configuration snippet to your WORKSPACE
file and update the
release <VERSION>
and its <SHA256>
as specified on the rules_scala releases
page. This snippet is designed to ensure that users pick up the
correct order of dependencies for rules_scala
. If you want to override any of
the following dependency versions, make sure to load()
them before calling
rules_scala_dependencies()
.
# WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# See https://github.com/bazelbuild/rules_scala/releases for up to date version
# information, including `<VERSION>` and `<SHA256>` values.
http_archive(
name = "rules_scala", # Can be "io_bazel_rules_scala" if you still need it.
sha256 = "<SHA256>",
strip_prefix = "rules_scala-<VERSION>",
url = "https://github.com/bazelbuild/rules_scala/releases/download/<VERSION>/rules_scala-<VERSION>.tar.gz",
)
load("@rules_scala//scala:deps.bzl", "rules_scala_dependencies")
rules_scala_dependencies()
# Only include the next two statements if using
# `--incompatible_enable_proto_toolchain_resolution`.
# See the "Using a precompiled protocol compiler" section below.
load("@platforms//host:extension.bzl", "host_platform_repo")
# Instantiates the `@host_platform` repo to work around:
# - https://github.com/bazelbuild/bazel/issues/22558
host_platform_repo(name = "host_platform")
# This is optional, but register this toolchain before any others. Requires
# invoking the `scala_protoc_toolchains` repo rule, but is safe to include even
# `--incompatible_enable_proto_toolchain_resolution` is `False`.
# See the "Using a precompiled protocol compiler" section below.
register_toolchains("@rules_scala_protoc_toolchains//...:all")
load("@rules_java//java:rules_java_deps.bzl", "rules_java_dependencies")
rules_java_dependencies()
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()
# If you need a specific `rules_python` version, specify it here.
# Otherwise you may get the version defined in the `com_google_protobuf` repo.
http_archive(
name = "rules_python",
sha256 = "2ef40fdcd797e07f0b6abda446d1d84e2d9570d234fddf8fcd2aa262da852d1c",
strip_prefix = "rules_python-1.2.0",
url = "https://github.com/bazelbuild/rules_python/releases/download/1.2.0/rules_python-1.2.0.tar.gz",
)
load("@rules_python//python:repositories.bzl", "py_repositories")
py_repositories()
# Note that `rules_java` 8.x suggests loading `protobuf_deps()` after
# `rules_java_dependencies` and before `rules_java_toolchains()`:
# - https://github.com/bazelbuild/rules_java/releases/tag/8.9.0
#
# `rules_java` 7.x also works with this ordering.
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
protobuf_deps()
load("@rules_java//java:repositories.bzl", "rules_java_toolchains")
rules_java_toolchains()
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies")
rules_proto_dependencies()
load("@rules_proto//proto:setup.bzl", "rules_proto_setup")
rules_proto_setup()
load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
rules_proto_toolchains()
# Include this after loading `platforms`, `com_google_protobuf`, and
# `rules_proto` to enable the `//protoc` precompiled protocol compiler
# toolchains. See the "Using a precompiled protocol compiler" section below.
load("@rules_scala//protoc:toolchains.bzl", "scala_protoc_toolchains")
# This name can be anything, but we recommend `rules_scala_protoc_toolchains`.
scala_protoc_toolchains(name = "rules_scala_protoc_toolchains")
load("@rules_scala//:scala_config.bzl", "scala_config")
# Stores the selected Scala version and other configuration parameters.
#
# 2.12 is the default version. Use other versions by passing them explicitly:
#
# scala_config(scala_version = "2.13.16")
#
# You may define your own custom toolchain using Maven artifact dependencies
# configured by your `WORKSPACE` file, imported using an external loader like
# https://github.com/bazelbuild/rules_jvm_external. See docs/scala_toolchain.md.
scala_config()
load(
"@rules_scala//scala:toolchains.bzl",
"scala_register_toolchains",
"scala_toolchains",
)
# Defines a default toolchain repo for the configured Scala version that loads
# Maven deps like the Scala compiler and standard libs. Enable other builtin
# toolchains by setting their corresponding parameters to `True`. See the
# `scala_toolchains()` docstring for all builtin toolchain configuration
# options.
#
# On production projects, you may consider defining a custom toolchain to use
# your project's required dependencies instead. In that case, you can omit
# `scala_toolchains()` or explicitly set `scala = False` if you use it to
# instantiate other builtin toolchains.
scala_toolchains()
scala_register_toolchains()
The above configuration snippet reflects important changes since rules_scala
v6.x:
-
rules_scala
no longer requires theio_bazel_rules_scala
repository name unless yourBUILD
files or those of your dependencies require it (#1696).Update your project's
@io_bazel_rules_scala
references to@rules_scala
if possible. Otherwise, userepo_name = "io_bazel_rules_scala"
inbazel_dep()
orname = "io_bazel_rules_scala"
inhttp_archive
.You can use the
repo_mapping
attribute ofhttp_archive
or equivalent Bzlmod mechanisms to translate@rules_scala
to@io_bazel_rules_scala
for dependencies. See the Translating repo names for dependencies section below for details. (That section is about@rules_scala_config
, but the same mechanisms apply.) -
rules_scala
v7.0.0 introduces a newscala_toolchains()
API that is very different fromrules_scala
6. For details on what's changed, see the New 'scala_toolchains()' API for 'WORKSPACE' section below.
Add the following to your BUILD
files to make the scala_*
rules available:
load(
"@rules_scala//scala:scala.bzl",
"scala_binary",
"scala_library",
"scala_test",
)
rules_scala
now supports the
--incompatible_enable_proto_toolchain_resolution
flag when using
protobuf v29 or later. When using this flag with the
MODULE.bazel
or WORKSPACE
configurations below, rules_scala
will use a
precompiled protocol compiler binary by default.
Windows builds now require using protobuf
v29 or later with the precompiled
protocol compiler toolchain. See the Windows MSVC builds of protobuf broken
by default section below for details.
To set the flag in your .bazelrc
file:
common --incompatible_enable_proto_toolchain_resolution
In both MODULE.bazel
and WORKSPACE
, you must register the protocol compiler
toolchains before any other toolchains. It's safe to use even when
--incompatible_enable_proto_toolchain_resolution
is False
.
It is OK to call register_toolchains
before using the scala_protoc
extension
under Bzlmod, and before the scala_protoc_toolchains()
repo rule under
WORKSPACE
.
# MODULE.bazel
register_toolchains(
"@rules_scala_protoc_toolchains//...:all",
dev_dependency = True,
)
# WORKSPACE
register_toolchains("@rules_scala_protoc_toolchains//...:all")
The scala_protoc
module extension instantiates the protocol compiler
toolchain under Bzlmod. It must be marked as a dev_dependency
.
# MODULE.bazel
scala_protoc = use_extension(
"@rules_scala//scala/extensions:protoc.bzl",
"scala_protoc",
dev_dependency = True,
)
use_repo(scala_protoc, "rules_scala_protoc_toolchains")
The scala_protoc_toolchains
repo rule instantiates the protocol compiler
toolchain. The repo name can be anything, but we recommend
rules_scala_protoc_toolchains
.
# WORKSPACE
# Include this after loading `platforms`, `com_google_protobuf`, and
# `rules_proto`.
load("@rules_scala//protoc:toolchains.bzl", "scala_protoc_toolchains")
scala_protoc_toolchains(name = "rules_scala_protoc_toolchains")
Use the platforms
parameter to specify additional platforms if the
execution platform may differ from the host platform, as when building with
remote execution. Valid values come from the file name suffixes of
protocolbuffers/protobuf releases. It's also safe to explicitly include the
host platform.
For example, imagine the host platform is macOS running on Apple Silicon, but
the remote execution platform is Linux running on an x86 processor.
rules_scala
configures the "osx-aarch_64"
platform automatically. Then in
MODULE.bazel
you would include:
# MODULE.bazel
scala_protoc_toolchains(
name = "rules_scala_protoc_toolchains",
platforms = ["linux-x86_64"],
dev_dependency = True,
)
In WORKSPACE
you would include:
# WORKSPACE
scala_protoc_toolchains(
name = "rules_scala_protoc_toolchains",
platforms = ["linux-x86_64"],
)
At the moment, enabling protocol compiler toolchainization requires applying
protoc/0001-protobuf-19679-rm-protoc-dep.patch. It is the git diff
output
from the branch used to create protocolbuffers/protobuf#19679. Without it, a
transitive dependency on @com_google_protobuf//:protoc
remains, causing
protoc
to recompile even with the precompiled toolchain registered first.
If and when protobuf
merges that pull request, or applies an equivalent fix,
this patch will no longer be necessary.
Applying the protobuf
patch requires using single_version_override
,
which also requires that the patch be a regular file in your own repo. In other
words, neither @rules_scala//protoc:0001-protobuf-19679-rm-protoc-dep.patch
nor an alias
to it will work.
Assuming you've copied the patch to a file called protobuf.patch
in the root
package of your repository, add the following to your MODULE.bazel
:
# MODULE.bazel
# Required for protocol compiler toolchainization until resolution of
# protocolbuffers/protobuf#19679.
bazel_dep(
name = "protobuf",
version = "30.1",
repo_name = "com_google_protobuf",
)
single_version_override(
module_name = "protobuf",
patch_strip = 1,
patches = ["//:protobuf.patch"],
version = "30.1",
)
scala/deps.bzl
currently applies the protobuf
patch to protobuf
v30.1.
If you need to apply the patch to a different version of protobuf
, copy it to
your repo as described in the Bzlmod setup above. Then apply it in your own
http_archive
call:
http_archive(
name = "com_google_protobuf",
sha256 = "1451b03faec83aed17cdc71671d1bbdfd72e54086b827f5f6fd02bf7a4041b68",
strip_prefix = "protobuf-30.1",
url = "https://github.com/protocolbuffers/protobuf/archive/refs/tags/v30.1.tar.gz",
repo_mapping = {"@com_google_absl": "@abseil-cpp"},
patches = ["//protobuf.patch"],
patch_args = ["-p1"],
)
WORKSPACE
must include the host_platform_repo
snippet from
Getting started to work around bazelbuild/bazel#22558:
# WORKSPACE
load("@platforms//host:extension.bzl", "host_platform_repo")
# Instantiates the `@host_platform` repo to work around:
# - https://github.com/bazelbuild/bazel/issues/22558
host_platform_repo(name = "host_platform")
Using --incompatible_enable_proto_toolchain_resolution
with versions of
protobuf
before v29 causes build failures due to a missing internal Bazel
dependency.
Bazel's builtin bazel_java_proto_aspect
transitively depends on a toolchain
with a toolchain_type
of @rules_java//java/proto:toolchain_type
.
Experimentation with protobuf
v28.2 using both Bazel 6.5.0 and 7.5.0 led to
the following error:
ERROR: .../external/bazel_tools/src/main/protobuf/BUILD:28:15:
in @@_builtins//:common/java/proto/java_proto_library.bzl%bazel_java_proto_aspect
aspect on proto_library rule
@@bazel_tools//src/main/protobuf:worker_protocol_proto:
Traceback (most recent call last):
File "/virtual_builtins_bzl/common/java/proto/java_proto_library.bzl",
line 53, column 53, in _bazel_java_proto_aspect_impl
File "/virtual_builtins_bzl/common/proto/proto_common.bzl",
line 364, column 17, in _find_toolchain
Error in fail: No toolchains registered for
'@rules_java//java/proto:toolchain_type'.
ERROR: Analysis of target
'@@bazel_tools//src/main/protobuf:worker_protocol_proto' failed
See #1710 for details of the experiment.
For protobuf
v29.0, protocolbuffers/protobuf#18308 added the
@protobuf//bazel/private/toolchains
package and updated
protobuf_deps()
from @protobuf//:protobuf_deps.bzl
to register it:
native.register_toolchains("//bazel/private/toolchains:all")
protocolbuffers/protobuf#18435 then introduced
java_source_toolchain_bazel7
with the required
toolchain_type
.
-
bazelbuild/bazel#7095: Protobuf repo recompilation sensitivity
-
bazelbuild/rules_proto#179: Implement proto toolchainisation
-
rules_proto 6.0.0 release notes mentioning Protobuf Toolchainization
To run with a persistent worker (much faster), add the following to
your .bazelrc
file:
build --strategy=Scalac=worker
build --worker_sandboxing
To produce a combined coverage report:
bazel coverage \
--combined_report=lcov \
--coverage_report_generator="@bazel_tools//tools/test/CoverageOutputGenerator/java/com/google/devtools/coverageoutputgenerator:Main" \
//...
This should produce a single bazel-out/_coverage/_coverage_report.dat
from all coverage files that are generated.
You can extract information from your coverage reports with
lcov
:
# For a summary:
lcov --summary your-coverage-report.dat
# For details:
lcov --list your-coverage-report.dat
If you prefer an HTML report, then you can use genhtml
provided also by the lcov
package.
Coverage support has been only tested with ScalaTest.
Please check coverage.md for more details on coverage support.
rules_scala
supports the last two released minor versions for each of Scala 2.11, 2.12, 2.13.
Previous minor versions may work but are supported only on a best effort basis.
The Getting started section illustrates how to select the default Scala version and configure its dependencies.
You can define your own custom scala_toolchain by
calling setup_scala_toolchain()
with dependencies that you specify.
Note: Toolchains are a more flexible way to configure dependencies, so you should prefer that way.
Please also note, that the overriden_artifacts
parameter is likely to be removed in the future.
rules_scala
supports configuring multiple Scala versions and offers target-level control of which one to use.
Please check cross-compilation.md for more details on cross-compilation support.
Bazel compatibility is tied directly to the versions of protobuf
required by
Bazel and rules_java
, and their compatibility with scalapb/ScalaPB Maven artifacts. For extensive analysis,
see #1647.
The Bazel versions and dependency versions in the table below represent the maximum available at the time of writing.
-
For the actual versions used by
rules_scala
, see scala/deps.bzl. -
See .bazelci/presubmit.yml for the exact Bazel versions verified by the continuous integration builds.
Bazel/Dependency | rules_scala 7.x |
---|---|
Bazel versions using Bzlmod (Coming soon! See #1482.) |
7.6.0, 8.x,rolling , last_green |
Bazel versions using WORKSPACE |
6.5.0, 7.6.0, 8.x (see the notes on 6.5.0 compatibility) |
protobuf |
v30.1 |
rules_proto |
7.1.0 |
abseil-cpp |
20250127.1 |
rules_java |
8.11.0 |
ScalaPB |
1.0.0-alpha.1 |
The next major release will likely drop support for protobuf
versions before
v29 and remove rules_proto
completely. This is to comply with the guidance in
Protobuf News: News Announcements for Version 29.x. For more details, see this comment from #1710
explaining why rules_proto remains for now.
Newer versions of abseil-cpp
, required by newer versions of
@com_google_protobuf//:protoc
, fail to compile under Bazel 6.5.0 and 7.6.0 by
default. protoc will also fail to build on Windows when using
MSVC. You will have to choose one of the following approaches to
resolve this problem.
You may use protocol compiler toolchainization with protobuf
v29 or later to
avoid recompiling protoc
. You may want to enable this even if your build
doesn't break, as it saves time by avoiding frequent protoc
recompilation. See
the Using a precompiled protocol compiler section for details.
Otherwise, if migrating to Bazel 8 isn't an immediate option, you will need to
set the following compiler flags in .bazelrc
per #1647:
common --enable_platform_specific_config
common:linux --cxxopt=-std=c++17
common:linux --host_cxxopt=-std=c++17
common:macos --cxxopt=-std=c++17
common:macos --host_cxxopt=-std=c++17
common:windows --cxxopt=/std=c++17
common:windows --host_cxxopt=/std=c++17
Note that this example uses common:
config settings instead of build:
. This
seems to prevent invalidating the action cache between bazel
runs, which
improves performance.
Usage with bazel-deps
Bazel-deps allows you to generate bazel dependencies transitively for maven artifacts. Generally we don't want bazel-deps to fetch
scala artifacts from maven but instead use the ones we get from calling scala_repositories
. The artifacts can be overridden in the
dependencies file used by bazel-deps:
replacements:
org.scala-lang:
scala-library:
lang: scala/unmangled
target: "@io_bazel_rules_scala_scala_library//:io_bazel_rules_scala_scala_library"
scala-reflect:
lang: scala/unmangled
target: "@io_bazel_rules_scala_scala_reflect//:io_bazel_rules_scala_scala_reflect"
scala-compiler:
lang: scala/unmangled
target: "@io_bazel_rules_scala_scala_compiler//:io_bazel_rules_scala_scala_compiler"
org.scala-lang.modules:
scala-parser-combinators:
lang: scala
target:
"@io_bazel_rules_scala_scala_parser_combinators//:io_bazel_rules_scala_scala_parser_combinators"
scala-xml:
lang: scala
target:
"@io_bazel_rules_scala_scala_xml//:io_bazel_rules_scala_scala_xml"
See Publish your Scala Libraries to a Maven Repository.
rules_scala
supports multiple dependency modes including strict and unused dependency tracking. See
Dependency Tracking for more info.
To make the ruleset more flexible and configurable, we introduce a phase architecture. By using a phase architecture, where rule implementations are defined as a list of phases that are executed sequentially, functionality can easily be added (or modified) by adding (or swapping) phases.
Phases provide 3 major benefits:
- Consumers are able to configure the rules to their specific use cases by defining new phases within their workspace without impacting other consumers.
- Contributors are able to implement new functionalities by creating additional default phases.
- Phases give us more clear idea what steps are shared across rules.
See Customizable Phase for more info.
Build main sources only:
bazel build //src/...
Run all smaller tests:
bazel test //test/...
To run the full test suite:
bash test_all.sh
Note: bazel test //...
will not work since we have a sub-folder on the
root folder which is meant to be used in a failure scenario in the integration
tests. Similarly, to only build you should use bazel build //src/...
due to
that folder.
The main objective of rules_scala
7.x is to enable existing users to migrate
to Bazel 8 and Bzlmod. To facilitate a gradual migration, it is compatible
with both Bazel 7 and Bazel 8, and both WORKSPACE
and Bzlmod. It remains
compatible with Bazel 6.5.0 builds using WORKSPACE
for the time being, but
Bazel 6 is no longer officially supported.
rules_java
7.x contains the following breaking changes when upgrading from
rules_scala
6.x.
rules_scala
7.0.0 replaces existing *_repositories()
and *_toolchains()
macros with the combination of rules_scala_dependencies()
,
scala_toolchains()
, and scala_register_toolchains()
.
These macros no longer exist:
jmh_repositories()
junit_repositories()
junit_toolchain()
rules_scala_setup()
rules_scala_toolchain_deps_repositories()
scala_proto_default_repositories()
scala_proto_register_enable_all_options_toolchain()
scala_proto_register_toolchains()
scala_proto_repositories()
scala_register_unused_deps_toolchains()
scala_repositories()
scalafmt_default_config()
scalafmt_repositories()
scalatest_repositories()
scalatest_toolchain()
specs2_junit_repositories()
specs2_repositories()
specs2_version()
twitter_scrooge()
Replace toolchain configurations like the following:
load(
"@rules_scala//scala:scala.bzl",
"rules_scala_setup",
"rules_scala_toolchain_deps_repositories",
)
rules_scala_setup()
rules_scala_toolchain_deps_repositories(fetch_sources = True)
# Other dependency declarations...
load("@rules_scala//:scala_config.bzl", "scala_config")
scala_config(scala_version = "2.13.16")
load(
"//testing:scalatest.bzl",
"scalatest_repositories",
"scalatest_toolchain",
)
scalatest_repositories()
scalatest_toolchain()
load(
"//scala/scalafmt:scalafmt_repositories.bzl",
"scalafmt_default_config",
"scalafmt_repositories",
)
scalafmt_default_config()
scalafmt_repositories()
with calls to rules_scala_dependencies()
, scala_toolchains()
(with the
appropriate parameters set), and scala_register_toolchains()
:
load("@rules_scala//scala:deps.bzl", "rules_scala_dependencies")
rules_scala_dependencies()
# See the `WORKSPACE` configuration snippet from the "Getting started" section
# above for other dependency declarations.
load("@rules_scala//:scala_config.bzl", "scala_config")
scala_config(scala_version = "2.13.16")
load(
"@rules_scala//scala:toolchains.bzl",
"scala_register_toolchains",
"scala_toolchains",
)
scala_toolchains(
scalafmt = True,
scalatest = True,
)
scala_register_toolchains()
See the scala_toolchains()
docstring for the
parameter list, which is almost in complete correspondence with parameters from
the previous macros. The WORKSPACE
files in this repository also provide many
examples.
Almost all rules_scala
toolchains configured using scala_toolchains()
are
automatically registered by scala_register_toolchains()
. There are two
toolchain macro replacements that require special handling.
The first is replacing scala_proto_register_enable_all_options_toolchain()
with the following scala_toolchains()
parameters:
scala_toolchains(
scala_proto = True,
scala_proto_options = [],
)
The other is replacing scala_register_unused_deps_toolchains()
with an
explicit register_toolchains()
call:
register_toolchains(
"@rules_scala//scala:unused_dependency_checker_error_toolchain",
)
In WORKSPACE
, this register_toolchains()
call must come before calling
scala_register_toolchains()
to ensure this toolchain takes precedence. The
same exact call will also work in MODULE.bazel
.
When using 'setup_scala_toolchain()' with custom compiler JARs, don't use
scala_toolchains()
if you don't need any other builtin toolchains.
If you do need other builtin toolchains, then set scala = False
:
# WORKSPACE
scala_toolchains(
scala = False,
# ...other toolchain parameters...
)
This avoids instantiating the default Scala toolchain and compiler JAR repositories, and disables the corresponding Scala version check, which may otherwise fail. This is equivalent to two ways in which the previous API avoided the same default behavior:
-
Calling
scala_repositories(load_jar_deps = False)
would instantiate only otherrules_scala
dependency repos (rules_java
,protobuf
, etc.) and compiler source JAR repos. -
Calling
rules_scala_setup()
directly, instead of indirectly viascala_repositories()
, instantiated the other dependency repositories only.
See "Defining your own scala_toolchain > Step 3 (optional)" from docs/scala_toolchain.md for futher details.
The upcoming Bzlmod implementation will funnel through the scala_toolchains()
macro as well, ensuring maximum compatibility with WORKSPACE
configurations.
The equivalent Bzlmod configuration for the scala_toolchains()
configuration
above would be:
bazel_dep(name = "rules_scala", version = "7.0.0")
scala_config = use_extension(
"@rules_scala//scala/extensions:config.bzl",
"scala_config",
)
scala_config.settings(scala_version = "2.13.16")
scala_deps = use_extension(
"@rules_scala//scala/extensions:deps.bzl",
"scala_deps",
)
scala_deps.toolchains(
scalafmt = True,
scalatest = True,
)
The module extensions will call scala_config()
and scala_toolchains()
respectively. The MODULE.bazel
file for rules_scala
declares its own
dependencies via bazel_dep()
, allowing Bazel to resolve versions according to
the main repository/root module configuration. It also calls
register_toolchains()
, so you don't have to (unless you want to
register a specific toolchain to resolve first).
The MODULE.bazel
files in this repository will also provide many examples
(when they land per #1482).
The MODULE.bazel
file from rules_scala
will automatically call
register_toolchains()
for toolchains configured via its scala_deps
module
extension. However, you must register explicitly in your MODULE.bazel
file any
toolchains that you want to take precedence over the toolchains configured by
scala_deps
. This includes any scala_toolchain
targets defined in your project, or optional rules_scala
toolchains like the
dependency checker error toolchain from above:
register_toolchains(
"@rules_scala//scala:unused_dependency_checker_error_toolchain",
)
Since @io_bazel_rules_scala
is no longer hardcoded in rules_scala
internals,
we've shortened @io_bazel_rules_scala_config
to @rules_scala_config
. This
shouldn't affect most users, but it may break some builds using
@io_bazel_rules_scala_config
to define custom cross-compilation targets.
If your project uses Bzlmod, you can remap @io_bazel_rules_scala_config
to
@rules_scala_config
for your own project via use_repo()
. Use this only if
updating your project's own @io_bazel_rules_scala_config
references isn't
immediately feasible.
scala_config = use_extension(
"@rules_scala//scala/extensions:config.bzl",
"scala_config",
)
use_repo(scala_config, io_bazel_rules_scala_config = "rules_scala_config")
If your project uses WORKSPACE
you must update all
@io_bazel_rules_scala_config
references to @rules_scala_config
. There is no
use_repo()
equivalent.
For any dependencies referencing @io_bazel_rules_scala_config
, use the workarounds
below. The same workarounds for your project's dependencies also apply to
translating @rules_scala
to @io_bazel_rules_scala
.
For module extensions, use override_repo()
to override
@io_bazel_rules_scala_config
with @rules_scala_config
:
bazel_dep(name = "foo", version = "1.0.0")
foo_ext = use_extension("@foo//:ext.bzl", "foo_ext")
override_repo(foo_ext, io_bazel_rules_scala_config = "rules_scala_config")
bazel_dep()
dependencies may still require @io_bazel_rules_scala_config
(or @io_bazel_rules_scala
) outside of a module extension. In this case, to
avoid using the old name in your own project, use archive_override()
or
git_override()
with the repo_mapping
attribute. These overrides pass the
repo_mapping
through to the underlying http_archive()
and
git_repository()
rules:
archive_override(
...
repo_mapping = {
"@io_bazel_rules_scala_config": "@rules_scala_config",
}
...
)
For dependencies, use the repo_mapping
attribute of http_archive()
or
git_repository()
:
http_archive(
...
repo_mapping = {
"@io_bazel_rules_scala_config": "@rules_scala_config",
}
...
)
MSVC builds of recent protobuf
versions started failing, as first noted in
#1710. On top of that, protobuf
is planning to stop
supporting Bazel + MSVC builds per:
-
protocolbuffers/protobuf#12947: src build on windows not working
-
protobuf.dev News Announcements for Version 30.x:Poison MSVC + Bazel
-
protocolbuffers/protobuf#20085: Breaking Change: Dropping support for Bazel+MSVC
Enable protocol compiler toolchainization to fix broken Windows
builds by avoiding @com_google_protobuf//:protoc
recompilation.
rules_scala
requires at least protobuf
v28, and at least v29 for protocol
compiler toolchain support. No ScalaPB
release supports protobuf
v25.6, v26, or v27.
If you can't update to protobuf
v28 or later right now, build using Bazel 7
and the following maximum versions of key dependencies. This is not officially
supported, but should work for some time.
Dependency | Max compatible version | Reason |
---|---|---|
protobuf |
v25.5 | Maximum version supported by ScalaPB 0.11.17. |
rules_proto |
6.0.2 | Maximum version supporting protobuf v25.5 |
rules_java |
7.12.4 | 8.x requires protobuf v27 and later. |
rules_cc |
0.0.9 | 0.0.10 requires Bazel 7 to define CcSharedLibraryHintInfo .0.0.13 requires at least protobuf v27.0. |
ScalaPB |
0.11.17 (0.9.8 for Scala 2.11) |
Later versions only support protobuf >= v28. |
Any program compiled with an external repo asset in its 'resources' attribute
will need to strip the 'external/' and repo name components from its
path. For example, the path for resources = ["@some_external_repo//:resource.txt"]
would change thus:
- Before:
external/some_external_repo/resource.txt
- After:
resource.txt
This avoids encoding repo names or any other Bazel system knowledge in the compiled artifacts. This is especially important under Bzlmod, because the generated path would otherwise contain the canonical repo name, upon which users should never depend.
Per #1660, rules_java
7.10.0 and later precipitate the
need to replace @bazel_tools//tools/jdk
targets with corresponding
@rules_java//toolchains
targets. Fix any targets broken by this rules_java
upgrade by doing a global search and replace.
However, @bazel_tools//tools/jdk:toolchain_type
dependencies must remain for
now, as there's not yet a corresponding toolchain_type()
target
in @rules_java
.
Under Bzlmod, repos are only visible to the module extension that creates them,
unless the MODULE.bazel
file brings them into scope with
use_repo()
. This can
lead to errors like those from the following example, which originally called
'setup_scala_toolchain()' under Bzlmod:
load("@rules_scala//scala:scala.bzl", "setup_scala_toolchain")
setup_scala_toolchain(
name = "custom_scala_toolchain",
scalacopts = [
"-Wunused:all",
],
strict_deps_mode = "error",
unused_dependency_checker_mode = "warn",
)
setup_scala_toolchains
is a macro that can take user specified classpath
targets as described in docs/scala_toolchain.md.
Without explicit *_classpath
or *_deps
arguments, setup_scala_toolchain()
defaults to using dependency repositories generated by rules_scala
itself.
This worked under WORKSPACE
, but breaks under Bzlmod, because the builtin
toolchain dependency repos are no longer in the project's scope by default:
ERROR: no such package
'@@[unknown repo 'org_scala_sbt_compiler_interface_3_3_5'
requested from @@]//':
The repository '@@[unknown repo 'org_scala_sbt_compiler_interface_3_3_5'
requested from @@]' could not be resolved:
No repository visible as '@org_scala_sbt_compiler_interface_3_3_5'
In this case, where the toolchain only sets different compiler options, the best
fix is to use the 'scala_toolchain' rule directly instead.
Its underlying BUILD
rule uses builtin toolchain dependencies via existing
targets visible within rules_scala
, without forcing users to import them:
load("@rules_scala//scala:scala_toolchain.bzl", "scala_toolchain")
scala_toolchain(
name = "custom_scala_toolchain_impl",
scalacopts = [
"-Ywarn-unused",
],
strict_deps_mode = "error",
unused_dependency_checker_mode = "warn",
)
toolchain(
name = "custom_scala_toolchain",
toolchain = ":custom_scala_toolchain_impl",
toolchain_type = "@rules_scala//scala:toolchain_type",
visibility = ["//visibility:public"],
)
A big part of the Bzlmodification work involved enabling rules_scala
to
generate and register toolchains without forcing users to bring their
dependencies into scope. However, another way to fix this specific problem is to
call use_repo
for every builtin repository needed by the
setup_scala_toolchain()
call.
This isn't actually a rules_scala
breakage, but a Bazel 8 breakage encountered
while preparing rules_scala
for Bazel 8 in #1652.
bazelbuild/bazel#25198 describes how the semantics of some instances of
$(location)
changed, and how changing these particular instances to
$(rootpath)
fixed them.
The good news is that replacing such instances $(location)
with $(rootpath)
is backwards compatible to Bazel 6.5.0 and 7.6.0. Updating them now will ensure
future compatibility.
rules_scala
7.x officially drops support for Bazel 6.5.0. Bzlmod builds
with Bazel 6.5.0 won't work at all because Bazel 6.5.0 doesn't support
'use_repo_rule', which
'rules_jvm_external' >= 6.3 requires.
At the moment, WORKSPACE
builds mostly continue to work with Bazel 6.5.0, but
not out of the box, and may break at any time.
You must use protobuf
v29 or earlier. rules_scala
now uses v30 by default,
which removes py_proto_library
and other symbols that Bazel 6.5.0 requires:
ERROR: Traceback (most recent call last):
File ".../external/bazel_tools/src/main/protobuf/BUILD",
line 1, column 46, in <toplevel>
load("@com_google_protobuf//:protobuf.bzl", "py_proto_library")
Error: file '@com_google_protobuf//:protobuf.bzl'
does not contain symbol 'py_proto_library'
ERROR: .../src/java/io/bazel/rulesscala/worker/BUILD:3:13:
no such target '@bazel_tools//src/main/protobuf:worker_protocol_java_proto':
target 'worker_protocol_java_proto'
not declared in package 'src/main/protobuf'
defined by .../external/bazel_tools/src/main/protobuf/BUILD
(Tip: use `query "@bazel_tools//src/main/protobuf:*"`
to see all the targets in that package)
and referenced by '//src/java/io/bazel/rulesscala/worker:worker'
See Using a prebuilt @com_google_protobuf//:protoc or C++ compiler flags for protocol compiler configuration requirements.
See Using earlier protobuf versions for details on using older versions of protobuf if necessary.
ScalaPB 0.9.8, the
last version compatible with Scala 2.11, doesn't support protobuf
v25.6 or
later. See #1712 for an example of what happens to Scala
2.11 test cases when using protobuf
v25.6. Since rules_scala
now supports
more recent protobuf
versions via ScalaPB 1.0.0-alpha1, we had to
remove the Scala 2.11 test cases.
Building scala_proto
for Scala 2.11 requires building with Bazel 6.5.0
under WORKSPACE, with the maximum dependency versions specified in
that section. While this may continue to work for some time, it is not
officially supported.
scala_proto_toolchain
has a more flexible plugin configuration schema. The
new generators
and generators_opts
attributes replace the following
attributes:
with_grpc
with_flat_package
with_single_line_to_string
main_generator
named_generators
Now each generator (plugin) will get a corresponding name that can be used for further plugin options setup:
scala_proto_toolchain(
name = "example",
generators = {
"scala": "scripts.ScalaPbCodeGenerator",
"jvm_extra_protobuf_generator": "scalarules.test.extra_protobuf_generator.ExtraProtobufGenerator",
},
generators_opts = {
"scala": [
"grpc",
"single_line_to_proto_string",
],
"jvm_extra_protobuf_generator": [
"grpc",
"single_line_to_proto_string",
],
},
)
scalapb_grpc_deps
no longer exists since it's now the user's responsibility
to configure dependencies based on the provided generators and their options.
The new scalapb_toolchain
convenience macro wraps scala_proto_toolchain
to provide the default ScalaPB implementation:
load("//scala_proto:scala_proto_toolchain.bzl", "scalapb_toolchain")
scalapb_toolchain(
name = "my_toolchain",
opts = [
"grpc",
"single_line_to_proto_string",
],
visibility = ["//visibility:public"],
)
Similarly, setup_scala_proto_toolchains()
now uses a default_gen_opts
parameter to replace the previous boolean enable_all_options
parameter.
rules_scala
7.x removes all of the obsolete bind()
aliases under
//external:io_bazel_rules_scala/dependency/
created for twitter_scrooge
toolchain dependencies. If your project happens to depend on these aliases, you
can replace them with the following repository references:
bind() alias under //external:io_bazel_rules_scala/dependency/ |
Repository reference |
---|---|
scala/guava |
@io_bazel_rules_scala_guava |
thrift/javax_annotation_api |
@io_bazel_rules_scala_javax_annotation_api |
thrift/libthrift |
@libthrift |
thrift/mustache |
@io_bazel_rules_scala_mustache |
thrift/scopt |
@io_bazel_rules_scala_scopt |
thrift/scrooge_core |
@io_bazel_rules_scala_scrooge_core |
thrift/scrooge_generator |
@io_bazel_rules_scala_scrooge_generator |
thrift/util_core |
@io_bazel_rules_scala_util_core |
thrift/util_logging |
@io_bazel_rules_scala_util_logging |
To access these repositories under Bzlmod, you'll need to add the following to
your MODULE.bazel
file:
scala_deps.toolchains(
twitter_scrooge = True,
)
use_repo(
scala_deps,
"io_bazel_rules_scala_guava",
"io_bazel_rules_scala_javax_annotation_api",
"io_bazel_rules_scala_mustache",
"io_bazel_rules_scala_scopt",
"io_bazel_rules_scala_scrooge_core",
"io_bazel_rules_scala_scrooge_generator",
"io_bazel_rules_scala_util_core",
"io_bazel_rules_scala_util_logging",
"libthrift",
)
rules_scala
7.0.0 will set the
compatibility_level
value for its module()
directive. The compatibility_level
for rules_scala
will track major version
numbers (per semantic versioning), and this README
will
clearly document the reason for the level bump. compatibility_level
mismatches
in the module graph will cause module resolution to fail, signaling the presence
of known breaking changes.
The concept of proper compatibility_level
usage is still up for discussion in
bazelbuild/bazel#24302. However, the policy above favors forcing module
resolution to fail, rather than allowing a later execution step to fail with a
potentially confusing error message. If a version bump may break builds for any
known reason, we will explain why up front instead of waiting for users to be
surprised.
A comment from #1647 illustrates how 'rules_erlang' fails due to 'compatibility_level' conflicts. The 'rules_erlang' 3.0.0 release notes describe the breaking changes. This seems like a reasonable model to follow.
See CONTRIBUTING.md for more info.
Here's a (non-exhaustive) list of companies that use rules_scala
in production. Don't see yours? You can add it in a PR!