Bazel Blog

Bazel 0.10

We're proud to announce the release of Bazel 0.10. The 400+ commits since last release include performance optimizations, bug fixes, and various improvements.

There is a new android test rule. android_local_test tests android_library code using Robolectric, a unit test framework designed for test-driven development without the need for an emulator or device. See the documentation for setup instructions and examples.

The depset type has evolved. To merge multiple depsets or add new elements, do not use the operators +, +=, |, or the .union method. They are deprecated and will be removed in the future. Instead use the new depset constructor, which has a better performance. For example, instead of d1 + d2 + d3, use depset(transitive = [d1, d2, d3]). See the documentation for more information and examples.

In addition to this new release, the Bazel community has been very active. See below what happened recently.

Languages & Rules


  • Spotify released a collection of tools for working with Bazel workspaces, mostly tailored towards writing JVM backend services.
  • Ever wanted to save a file and have your tests automatically run? How about restart your webserver when one of the source files change? Take a look at the Bazel watcher.


Did you know?

  • The heart of Bazel is a parallel evaluation and incrementality model called Skyframe.
  • Bazel is more than 10 years old, even though it was just open-sourced 3 years ago. John Field goes into the prehistory of Bazel in the opening remarks of Bazel Conference 2017 here.

Did we miss anything? Fill the form to suggest content for a next blog post.

Discuss on Hacker News or Reddit.

By Laurent Le Brun

Migration Help: --config parsing order

--config expansion order is changing, in order to make it better align with user expectations, and to make layering of configs work as intended. To prepare for the change, please test your build with startup option --expand_configs_in_place.

Please test this change with Bazel 0.10, triggered by the startup option --expand_configs_in_place. The change is mostly live with Bazel 0.9, but the newest release adds an additional warning if explicit flags are overriden, which should be helpful when debugging differences. The new expansion order will become the default behavior soon, probably in Bazel 0.11 or 0.12, and will no longer be configurable after another release.

Background: bazelrc & --config

The Bazel User Manual contains the official documentation for bazelrcs and will not be repeated here.
A Bazel build command line generally looks something like this:

bazel <startup options> build <command options> //some/targets

For the rest of the doc, command options are the focus. Startup options can affect which bazelrc's are loaded, and the new behavior is gated by a startup option, but the config mechanisms are only relevant to command options.

The bazelrcs allow users to set command options by default. These options can either be provided unconditionally or through a config expansion:

  • Unconditionally, they are defined for a command, and all commands that inherit from it,
    build --foo # applies "--foo" to build, test, etc.
  • As a config expansion # applies "--foo" to build, test, etc. when --config=foobar is set. build:foobar --foo

What is changing

The current order: fixed-point --config expansion

The current semantics of --config expansions breaks last-flag-wins expectations. In broad strokes, the current option order is

  1. Unconditional rc options (options set by a command without a config, "build --opt")
  2. All --config expansions are expanded in a "fixed-point" expansions.
    This does not check where the --config option initially was (rc, command line, or another --config), and will parse a single --config value at most once. Use `--announcerc` to see the order used!_
  3. Command-line specified options

Bazel claims to have a last-flag-wins command line, and this is usually true, but the fixed-point expansion of configs makes it difficult to rely on ordering where --config options are concerned.

See the Boolean option example below.

The new order: Last-Flag-Wins

Everywhere else, the last mention of a single-valued option has "priority" and overrides a previous value. The same will now be true of --config expansion. Like other expansion options, --config will now expand to its rc-defined expansion "in-place," so that the options it expands to have the same precedence.

Since this is no longer a fixed-point expansion, there are a few other changes:

  • --config=foo --config=foo will be expanded twice. If this is undesirable, more care will need to be taken to avoid redundancy. Double occurrences will cause a warning.
  • cycles are no longer implicitly ignored, but will error out.

Other rc ordering semantics remain. "common" options are expanded first, followed by the command hierarchy. This means that for an option added on the line "build:foo --buildopt", it will get added to --config=foo's expansion for bazel build, test, coverage, etc. "test:foo --testopt" will add --testopt after the (less specific and therefore lower priority) build expansion of --config=foo. If this is confusing, avoid alternating command types in the rc file, and group them in order, general options at the top. This way, the order of the file is close to the interpretation order.

How to start using new behavior

  1. Check your usual --config values' expansions by running your usual bazel command line with --announce_rc. The order that the configs are listed, with the options they expand to, is the order in which they are interpreted.

  2. Spend some time understanding the applicable configs, and check if any configs expand to the same option. If they do, you may need to move rc lines around to make sure the same value has priority with the new ordering. See "Suggestions for config definers."

  3. Flip on the startup option --expand_configs_in_place and debug any differences using --announce_rc

If you have a shared bazelrc for your project, note that changing it will propagate to other users who might be importing this bazelrc into a personal rc. Proceed with caution as needed

  1. Add the startup option to your bazelrc to continue using this new expansion order.

Suggestions for config definers

You might be in a situation where you own some --config definitions that are shared between different people, even different teams, so it might be that the users of your config are using both --expand_configs_in_place behavior and the old, default behavior.

In order to minimize differences between old and new behavior, here are some tips.

  1. Avoid internal conflicts within a config expansion (redefinitions of the same option)
  2. Define recursive --config at the END of the config expansion
    • Only critical if #1 can't be followed.

Suggestion #1 is especially important if the config expands to another config. The behavior will be more predictable with --expand_configs_in_place, but without it, the expansion of a single --config depends on previous --configs.

Suggestion #2 helps mitigate differences if #1 is violated, since the fixed-point expansion will expand all explicit options, and then expand any newly-found config values that were mentioned in the original config expansions. This is equivalent to expanding it at the end of the list, so use this order if you wish to preserve old behavior.

Motivating examples

The following example violates both #1 and #2, to help motivate why #2 makes things slightly better when #1 is impossible. bazelrc contents: build:foo --cpu=x86 build:misalteredfoo --config=foo # Violation of #2! build:misalteredfoo --cpu=arm64 # Violation of #1!

  • bazel build --config=misalteredfoo

effectively x86 in fixed-point expansion, and arm64 with in-place expansion

The following example still violates #1, but follows suggestion #2: bazelrc contents: build:foo --cpu=x86 build:misalteredfoo --cpu=arm64 # Violation of #1! build:misalteredfoo --config=foo

  • bazel build --config=misalteredfoo

effectively x86 in both expansions, so this does not diverge and appears fine at first glance. (thanks, suggestion #2!)

  • bazel build --config=foo --config=misalteredfoo

effectively arm64 in fixed-point expansion, x86 with in-place, since misalteredfoo's expansion is independent of the previous config mention.

Suggestions for users of --config

Lay users of --config might also see some surprising changes depending on usage patterns. The following suggestions are to avoid those differences. Both of the following will cause warnings if missed.

A. Avoid including to the same --config twice

B. Put --config options FIRST, so that explicit options continue to have precedence over the expansions of the configs.

Multiple mentions of a single --config, when combined with violations of #1, may cause surprising results, as shown in #1's motivating examples. In the new expansion, multiple expansions of the same config will warn. Multi-valued options will receive duplicates values, which may be surprising.

Motivating example for B

bazelrc contents:
    build:foo --cpu=x86
  • bazel build --config=foo --cpu=arm64 # Fine

effectively arm64 in both expansion cases

  • bazel build --cpu=arm64 --config=foo # Violates B

The explicit value arm64 has precedence with fixed-point expansion, but the config value x86 wins in in-place expansion. With in-place expansion, this will print a warning.

Additional Boolean Option Example

There are 2 boolean options, --foo and --bar. Each only accept one value (as opposed to accumulating multiple values).

In the following examples, the two options --foo and --bar have the same apparent order (and will have the same behavior with the new expansion logic). What changes from one example to the next is where the options are specified.

bazelrc Command Line Current final value New final value




# Config definitions 
build:all --foo
build:all --bar




# Set for every build
build --nofoo
build --config=all
build --nobar

# Config definitions build:all --foo build:all --bar



Now to make this more complicated, what if a config includes another config?

bazelrc Command Line Current final value New final value

# Config definitions 
build:combo --nofoo
build:combo --config=all
build:combo --nobar
build:all --foo
build:all --bar







Here, counterintuitively, including --config=all explicitly makes its values effectively disappear. This is why it is basically impossible to create an automatic migration script to run on your rc - there's no real way to know what the intended behavior is.

Unfortunately, it gets worse, especially if you have the same config for different commands, such as build and test, or if you defined these in different files. It frankly isn't worth going into the further detail of the ordering semantics as it's existed up until now, this should suffice to demonstrate why it needs to change.

To understand the order of your configs specifically, run Bazel as you normally would (remove targets for speed) with the option --announce_rc. The order in which the config expansions are output to the terminal is the order in which they are currently interpreted (again, between rc and command line).

By Chloe Calvarin

Introducing Bazel Code Search

We are always looking for new ways to improve the experience of contributing to Bazel and helping users understanding how Bazel works. Today, we’re excited to share a preview of Bazel Code Search, a major upgrade to Bazel’s code search site. This new site features a refreshed user interface for code browsing and cross-repository semantic search with regular expression support, and a navigable semantic index of all definitions and references for the Bazel codebase. We’ve also updated the “Contribute” page on the Bazel website with documentation for this tool.

Getting started with Bazel Code Search

You can try Bazel Code Search right now by visiting

Select the repository you want to browse from the list on the main screen, or search across all Bazel repositories on the site using the search box at the top of the page.

Main screen of Bazel Code Search

Searching the Bazel codebase

Bazel Code Search has a semantic understanding of the Bazel codebase and allows you to search for either files or code within files. This semantic understanding of the code means that the search index identifies which parts of your code are entities such as classes, functions, and fields. Since the search index has classified these entities, your queries can include filters to scope the search to classes or functions and allows for improved search relevance by ranking important parts of code like classes, functions, and fields higher. By default, all searches use RE2 regular expressions though you can escape individual special characters with a backslash, or an entire string by enclosing it in quotes.

To search, start typing in the search box at the top of the screen and you’ll see suggestions for matching results. For Java, JavaScript, and Proto, result suggestions indicate if the match is an entity such as a Class, Method, Enum or Field. Semantic understanding for more languages is on the way.

Bazel code search suggestions

If you don’t see the result you want in the suggestions, you can submit your search and find all matches on the search result page. From the results page, you can select a matching line or file to view.

Here’s a sampling of different search examples to try out on your own:

  • ccToolchain
    • search for the substring “ccToolchain”
  • class ccToolchain
    • search for files containing both “class” and “ccToolchain” substrings
  • “class ccToolchain”
    • search for files containing the phrase “class ccToolchain”
  • class:ccToolchain
    • search for classes where the name of a class contains the substring “ccToolchain”
  • file:cpp ccToolchain
    • search for files containing the substring “ccToolchain” where “cpp” is in the file path
  • file:cpp lang:java ccToolchain
    • search for Java files containing the substring “ccToolchain” where “cpp” is in the file path
  • aggre.*test
    • search for the regular expression “aggre.*test”
  • ccToolchain -test
    • search for the substring “ccToolchain” excluding any files containing the substring “test”
  • cTool case:yes
    • search for the substring “cTool” (case sensitive)

Note that all searches are case insensitive unless you specify “case:yes” in the query.

Understanding the Bazel codebase using cross references

Another way to understand the Bazel repository is through the use of cross references. If you’ve ever wondered how to properly use a method, cross references can help by displaying all references to that method so you can see how it is used in other parts of the codebase. Alternatively, if you see a method being used but don’t understand what that method actually does, cross references enables you to click the method to view the definition or see how it’s used elsewhere.

Cross refereneces pane

Cross references aren’t only available for methods, they’re also generated for classes, fields, imports, and enums. Bazel Code Search uses the Kythe open source project to generate a semantic index of cross references for the Bazel codebase. These cross references appear automatically as hyperlinks within source files. To make cross references easier to identify, click the Cross References button to underline all cross references in a file.

Cross references underlined

Once you’ve clicked on a cross reference, the cross references pane will be displayed where you can view all the definitions and references organized by file. Within the cross references pane, you can navigate into multiple levels of depth of cross references while continuing to view the original file you were viewing in the File pane allowing you to maintain context of the original task.

Navigating through levels of cross references

Browsing through Bazel repositories

Selecting a repository from the main screen will take you to a view of the chosen repository with search scoped to its contents. The breadcrumb toolbar at the top allows you to quickly navigate to other repositories, refs, or folders.

Repository view on Bazel Code Search

From the view of the repository, you can browse through folders and files in the repository while taking advantage of blame, change history, a diff view and many other features.

Bazel Code Search File View showing Blame and History

Give Feedback

We hope you’ll try Bazel Code Search and provide feedback through the “!” button in the top right of any page on the Bazel Code Search site. We would love to hear whether this tool helps you work with Bazel and what else you’d like to see Bazel Code Search offer.

Keep in mind that this project is still experimental and is subject to change.

By Russell Wolf

Thank you for BazelCon 2017

We are truly thankful to our community for making our first annual Bazel Conference a success! Check out all the videos of all the talks from BazelCon 2017 on YouTube.

Your feedback reflected high level of satisfaction, and there was something of interest for everyone:

  • Bazel usage and migration stories from TensorFlow, Kubernetes, SpaceX, Pinterest, Wix, Stripe, DataBricks, and Dropbox.
  • Talks about upcoming features and tools such as remote execution & caching, buildozer, robolectric tests, PodToBUILD, bazeltfc, rules_typescript presented by Uber, Two Sigma, Google, Pinterest, and Asana.
  • Office hours where you got your Bazel questions answered, met engineers, and debugged on the fly. One attendee used their session to configure remote execution with buildfarm!

BazelCon2017 by the Numbers:

  • 200+ attendees
  • 60 organizations
  • 30 speakers
  • 12 informative talks
  • 14 hours of hands-on debugging and Q&A during Office Hours

What we heard from you:

  • Bazel Query is great!
  • Python is used more widely than we realized, and needs better Bazel support.
  • Reproducible builds are important especially when you're flying rockets, building autonomous vehicles, delivering media, and calculating financial transactions, leading to wider Bazel adoption by these communities.
  • Documentation is often hard to find, and is either too basic or too advanced.
  • Bazel's parallelism is impressive: much faster than Maven.
  • IDE integration is important, particularly with Visual Studio, CLion, XCode.
  • Build Event Protocol enables many options for internal visualization of events.
  • Aspects are a powerful tool.

What we can do next:

  • Work on better documentation and training, particularly for intermediate-level topics.
  • Prioritize IDE integration.
  • Engage the community in building better Python support in Bazel.
  • Implement improved support for third-party dependencies.
  • Continue work on cross-platform improvements.
  • Engage the community in wider adoption and contribution to Bazel.

What you can do next:

  • Contribute to Bazel, particularly to the new community driven buildfarm effort.
  • Kick off local meet-ups (we will reach out to volunteers who responded to this in our survey).
  • Get more info on Bazel at
  • Join the discussion on

We look forward to working with you and growing our Bazel user community in 2018!

By Helen Altshuler and David Stanke

Bazel on Windows -- a year in retrospect

Bazel on Windows is no longer experimental. We think Bazel on Windows is now stable and usable enough to qualify for the Beta status we have given Bazel on other platforms.

Over the last year, we put a lot of work into improving Bazel's Windows support:

  • Bazel no longer depends on the MSYS runtime. This means Bazel is now a native Windows binary and we no longer link it to the MSYS DLLs. Bazel still needs Bash (MSYS or Git Bash) and the GNU binutils (binaries under /usr/bin) if your dependency graph includes genrule or sh_* rules (similarly to requiring python.exe to build py_* rules), but you can use any MSYS version and flavour you like, including Git Bash.
  • Bazel can now build Android applications. If you use native android_* rules, Bazel on Windows can now build and deploy Android applications.
  • Bazel is easier to set up. You now (typically) no longer need to set the following environment variables:
    • BAZEL_SH and BAZEL_PYTHON -- Bazel attempts to autodetect your Bash and Python installation paths.
    • JAVA_HOME -- we release Bazel with an embedded JDK. (We also release binaries without an embedded JDK if you want to use a different one.)
  • Visual C++ is the default C++ compiler. We no longer use GCC by default, though Bazel still supports it.
  • Bazel integrates better with the Visual C++ compiler. Bazel no longer dispatches to a helper script to run the compiler; instead Bazel now has a CROSSTOOL definition for Visual C++ and drives the compiler directly. This means Bazel creates fewer processes to run the compiler. By removing the script, we have eliminated one more point of failure.
  • Bazel creates native launchers. Bazel builds native Windows executables from java_binary, sh_binary, and py_binary rules. Unlike the .cmd files that Bazel used to build for these rules, the new .exe files no longer dispatch to a shell script to launch the xx_binaries, resulting in faster launch times. (If you see errors, you can use the --[no]windows_exe_launcher flag to fall back to the old behavior; if you do, please file a bug. We'd like to remove this flag and only support the new behavior.)

Coming soon

We are also working on bringing the following to Bazel on Windows:

  • Android Studio integration. We'll ensure Bazel works with Android Studio on Windows the same way it does on Linux and macOS. See issue #3888.
  • Dynamic C++ Linking. Bazel will support building and linking to DLLs on Windows. See issue #3311.
  • Skylark rule migration guide. We'll publish tutorials on writing Skylark rules that work not just on Linux and macOS, but also on Windows. See issue #3889.

Looking ahead, we aim to maintain feature parity between Windows and other platforms. We aim to maximize portability between host systems, so you get the same fast, correct builds on your developer OS of choice. If you run into any problems, please don't hesitate to file a bug.

By László Csomor

Bazel Conference 2017

Bazel team is pleased to announce our first annual Bazel Conference, focused on the needs of our community. The conference will feature user stories and feedback, migration talks, roadmap, hands-on and break-out tech sessions with Bazel engineers, contributors and users.

Dates: November 6 and 7, 2017 Location: Sunnyvale, California

We are inspired by our community engagement in the upcoming conference. We've received a large number of requests for talks and topics for discussion, and have scheduled tech talks by engineers at large and small companies on working with Bazel in wide variety of languages, including Scala, JavaScript and Go. We are looking forward to having 200 engineers from 35 companies across the world share their experience with Bazel.

We are humbled by the commitment to make Bazel even better, and are seeing engineers develop advanced features like Remote Execution, and sharing migration tips, tricks and tools. You will hear user stories and tips about iOS migration, and TensorFlow and Kubernetes experience with Bazel. We will also discuss as a community different tools out there that could be open sourced.

We are excited to see all of you at this first annual Bazel Conference in Sunnyvale, California on November 6 and 7, 2017!

Register by October 15, as seating is limited and we won't allow walk-ins. Detailed schedule will be published mid October, and location details will be sent out to registered attendees.

By Helen Altshuler

The New World of Bazel Releases

Bazel has been open-sourced exactly 2.5 years ago. It continues to be quite a journey, and we are very happy we have acquired some fellow travellers: many projects, organizations and companies that we all know and love rely on Bazel every day.

As our community grows, we owe to it a transparent and predictable release process. So we are taking some steps to bring more clarity and order to the world of Bazel releases:

  • We will cut (from master) a candidate for minor releases (0.7, 0.8 and so on) every month on approximately first business day of the month. The planned target dates for the cuts are published as GitHub issues with label 'release'
  • After the release candidate is cut, we will let it bake for two weeks before promoting it to the release. We will cherry-pick fixes for critical bugs, issuing new release candidates (0.7.0rc1, 0.7.0rc2 and so on), and release 0.minor.0 version at the end of baking period.
  • If critical bugs are discovered after the release, we will fix them and issue patch releases as needed (0.7.1, 0.7.2 and so on). Patch releases are always patches on top of existing minor releases - they are never cut from master.
  • No new features or backward incompatible changes ever appear in patch releases, and no new features or backward incompatible changes are added to release candidates after they have been cut.

Our website has more details on release policy.

As a result of this change, we now issue one minor release per month.

Our roadmap reflects our vision for Bazel 1.0 and beyond. We will annotate features on the roadmap with the release versions as those features get shipped.

By Dmitry Lomov

Bazel Conference 2017

Bazel team is pleased to announce our first annual Bazel Conference, focused on the needs of our community. The conference will feature user stories and feedback, migration talks, roadmap, hands-on and break-out tech sessions with Bazel engineers, contributors and users.

Dates: November 6 and 7, 2017 Location: Sunnyvale, California

We are inspired by our community engagement in the upcoming conference. We've received a large number of requests for talks and topics for discussion, and have scheduled tech talks by engineers at large and small companies on working with Bazel in wide variety of languages, including Scala, JavaScript and Go. We are looking forward to having 200 engineers from 35 companies across the world share their experience with Bazel.

We are humbled by the commitment to make Bazel even better, and are seeing engineers develop advanced features like Remote Execution, and sharing migration tips, tricks and tools. You will hear user stories and tips about iOS migration, and TensorFlow and Kubernetes experience with Bazel. We will also discuss as a community different tools out there that could be open sourced.

We are excited to see all of you at this first annual Bazel Conference in Sunnyvale, California on November 6 and 7, 2017!

Register by October 15, as seating is limited and we won't allow walk-ins. Detailed schedule will be published mid October, and location details will be sent out to registered attendees.

By Helen Altshuler

Introducing sandboxfs

sandboxfs is a new project to improve the way sandboxing works in Bazel by making it more efficient and correct. It's experimental and subject to change, but it's available now for you to check out! Read on for details.

Correct builds

As our motto claims, correctness is an integral part of Bazel. To achieve correctness, builds must be hermetic and reproducible, which means that all actions invoked by Bazel should be run in a well-defined environment. In other words: we want actions to run within a sandbox.

Let's consider an example. Think of a cc_library target that specifies as a source. This cc_library rule contains a compilation action that, for this target, turns the source file into a foo.o object file. This action will run clang, and it will need to:

  • read,
  • read all the headers required by,
  • write foo.o, and
  • possibly write some temporary files under /tmp/.

To be confident this build is correct, Bazel must ensure that the action has read-only access to the identified input files and write-only access to the output and temporary files we expect. Otherwise, Bazel cannot know if the compiler went astray and read random files from the system, making future builds inconsistent. One way to achieve these restrictions is by running each action within a sandbox.

Current sandboxing techniques

Today, Bazel uses different technologies to implement the sandboxing of actions. For example, on Linux, Bazel uses PID- and mount-namespaces, and on macOS, Bazel uses symlinks and the sandbox(7) facility. Note that sandboxing is disabled by default.

However, all these approaches have scalability and performance issues. A typical build action requires hundreds, if not thousands, of files and directories to be mapped into the sandbox. Setting these up takes time. On macOS, this approach is especially problematic because Bazel must create thousands of symlinks every time it invokes an action, and this is slow.

To make things worse, these approaches also have correctness issues. If symlinks are used, some tools (e.g. some compilers or linkers) will decide to extract the real path of such symlinks and work off that path. These tools may end up "discovering" and consuming undeclared files that are siblings of the symlink's target.

Enter sandboxfs

To resolve these issues, we came up with the idea of implementing a FUSE file system that allows us to define an arbitrary view of the host's file system under the mount point. We call this approach sandboxfs.

sandboxfs is efficient

The view sandboxfs offers is cheaply configured at mount time. With sandboxfs there is a single system call to configure the mount point versus thousands of symlink creation and deletion system calls.

The view can also be reconfigured cheaply across different actions, avoiding the need to remount the FUSE file system on each action, which would also be costly.

sandboxfs is correct

The view sandboxfs offers is fully virtual, so sandboxfs can enforce arbitrary read-only and read/write access permissions on any file or directory it exposes. Similarly, because the view is virtual, there are no symlinks involved. sandboxfs exposes real files and directories to the actions, so actions cannot reach into the original locations.

Isn't FUSE slow though?

Yes. As you may know, FUSE is slower than a real file system. This difference is because of the overhead of message-passing between the kernel and userspace, and because of all the context switches that are involved in serving a file system operation.

Our hypothesis is that, because builds are generally not I/O bound, the increased cost of I/O within the sandbox will pay for itself when compared to the cost of setting up and tearing down the sandbox for each action. No more creating thousands of symlinks or defining thousands of mount points.

But for now, that's all that it is: a hypothesis. We haven't finished stabilizing the sandboxfs code base, which means we haven't profiled nor tuned it. The integration points with Bazel are still being defined and implemented, which means it's not yet trivial to test-run Bazel's sandboxing with sandboxfs.

But it's here!

Though still in development, there is no reason to keep the code hostage any longer. We are very happy to announce that, as of today, it's now available as an open-source project under the Bazel umbrella! See:

Keep in mind that this project is still an experiment and highly subject to change. In particular, be aware that the command line and the data formats are most certainly going to mutate (for simplicity if anything). But the current code is now sufficient to experiment and play with.

As sandboxfs is now an open-source project, please take a look and report any features you would like to see, any bugs you encounter, and... if you decide to delve into the code and address any of the many TODOs in it, feel free to send us your Pull Requests!


Special credits go to Pallav Agarwal, whom we had the pleasure of hosting over a summer internship in the Google NYC office and who wrote the initial version of sandboxfs.

By Julio Merino

Backward compatibility

Bazel is in Beta and we are working hard towards Bazel 1.0 (see the roadmap). We are not there yet, and there are still many things we want to change, clean, and improve. Future releases of Bazel will not be 100% compatible with all previous Beta versions. We understand that breaking changes can be painful for users. That's why we want to make it as easy as we can to migrate to new Bazel versions.

During the Beta period, we may introduce breaking changes in each minor version (0.x). Starting with Bazel 1.0, breaking changes will cause a major version change (1.0, 2.0, etc.). This is known as Semantic Versioning. Major version changes should not be more frequent than once a year, and may be less.

For most breaking changes, we will add a flag, e.g. --incompatible_foo that is disabled by default. The flag --all_incompatible_changes will enable all of these flags at once, so you can see whether you're ready for the next major release.

The Bazel team will use the flags as follow:

  • To introduce a breaking change, we release the change along with a new flag that is unset by default, e.g. --incompatible_foo. This flag enables the new behavior, allowing you to test the future change. Flags for incompatible features are documented in the section Backward compatibility.

  • At a later release, the new flag is set by default. This change is effectively released, so it can happen only at a major version (or minor version during Beta). In the release notes, we tell you which incompatible changes are enabled. The flag for this change still exists, so if needed you can disable it.

  • Finally, the flag may be removed at any release in the future, and so you will no longer be able to disable the behaviour of the change. In the release notes, we list these removed flags.

When you migrate to a new release, we recommend the following workflow:

  • Use --all_incompatible_changes to ensure your code is forward-compatible with the next release. We are aware that you will not always be able to fix every issue, for example, there could incompatibilities with a repository you depend on.

  • When there is a new Bazel release, try your code again with the specific incompatible changes released in the new version. Check the release notes to know which flags to use. After verifying your project with the released changes, you can update to the new version. Verify your project again with the new version, as some small incompatible changes are not introduced behind flags.

  • If many users depend on your repository, please update it quickly after each Bazel release. This update will help your users test their code.

In all cases, the Bazel team will try to make version updates simple. We will try to document clearly the changes and provide good error messages. If anything is unclear, please contact us and we will help you.

To learn more about the changes we are doing, see the backward compatibility page.

By Laurent Le Brun