Bazel 8.0 is a major LTS release. It contains new features and backwards incompatible changes.
Highlights
- Many rules that were bundled with Bazel are now split into their own repositories, as part of the Starlarkification effort. This includes:
- Android: All android_* build and repo rules have been moved to http://github.com/bazelbuild/rules_android. Android tools are no longer bundled with Bazel inside @bazel_tools//tools/android.
- C++: All C++ toolchain-related symbols have been moved http://github.com/bazelbuild/rules_cc; other symbols, including the rules themselves, will be moved in a future release.
- Java: All java_* rules and providers (like JavaInfo) have been moved to http://github.com/bazelbuild/rules_java.
- Protobuf: All *_proto_library rules (for Java, C++, Python) and providers (like ProtoInfo) have been moved to http://github.com/google/protobuf.
- Python: All py_* rules and providers (like PyInfo) have been moved to http://github.com/bazelbuild/rules_python.
- Shell: All sh_* rules have been moved to http://github.com/bazelbuild/rules_shell.
- Use load statements for all the rules and providers from the above repositories. The load statements work with Bazel 6, 7 and 8 (repositories are backwards compatible and support both bzlmod and WORKSPACE mode). Bazel 9 will make load statements mandatory.
- To facilitate migration, Bazel 8 introduces the --incompatible_autoload_externally flag, which by default loads rules and symbols that were previously hard-coded inside Bazel from corresponding rule repositories.
- The WORKSPACE mechanism is now disabled by default.
- Bzlmod, the new way to manage external dependencies, is turned on by default since Bazel 7.0.
- The WORKSPACE and WORKSPACE.bzlmod files are no longer read by Bazel, by default. To bring back this behavior, use --enable_workspace. Check the migration guide and try out the migration tool for moving your external dependencies to Bzlmod.
- We are aiming to remove WORKSPACE in Bazel 9 completely.
- Symbolic macros are introduced as a new way to write build macros, improving the experience for both macro authors and BUILD file owners.
- Symbolic macro arguments are typed like rule attributes, with similar type conversions. They also are less prone to latent bugs because they automatically promote values of configurable attributes to select() expressions.
- Symbolic macros avoid pitfalls that harm BUILD readability, such as mutating their arguments, and are compatible with lazy evaluation (not implemented yet).
- Internal targets of symbolic macros are protected from clients by the visibility system.
- Legacy macros that call native.existing_rules() can often be replaced by finalizer macros.
- See https://bazel.build/extending/macros for more detail on symbolic macros.
Migration-Ready Incompatible Flags
The following flags are flipped in 8.0:
- --enable_workspace (#23023; now defaults to false)
- --incompatible_disallow_ctx_resolve_tools (#22249; now defaults to true)
- --incompatible_disallow_empty_glob (#8195; now defaults to true)
- --incompatible_macos_set_install_name (#12370; now defaults to true)
- --incompatible_no_implicit_watch_label (#23861; now defaults to true)
- --incompatible_struct_has_no_methods (#19465; now defaults to true)
- --incompatible_use_plus_in_repo_names (#23127; now defaults to true)
- --legacy_external_runfiles (#23574; now defaults to false)
- --legacy_important_outputs (#14353; now defaults to false)
- --zip_undeclared_test_outputs (489d08b; now defaults to false)
The following flags will be flipped in a future major release:
- --incompatible_autoload_externally (#23043; will default to true)
- --incompatible_disable_native_repo_rules (#22080; will default to true)
- --incompatible_disable_non_executable_java_binary (#19687; will default to true)
- --incompatible_disallow_struct_provider_syntax (#19467; will default to true)
- --incompatible_disable_target_provider_fields (#19466; will default to true)
- --incompatible_enable_deprecated_label_apis (#23144; will default to false)
- --incompatible_stop_exporting_language_modules (#19455; will default to true)
- --incompatible_auto_exec_groups (#17134; will default to true)
- --incompatible_disable_starlark_host_transitions (#17032; will default to true)
- --incompatible_config_setting_private_default_visibility (#12933; will default to true)
General
- [Incompatible] All labels in Bazel error messages, log output, Build Event Protocol, etc. are now prefixed with double-at (@@) instead of single-at (@) where applicable, to properly denote that they contain canonical repo names.
- [Incompatible] The global applicable_licenses attribute has been renamed to package_metadata. The older name may be used for creating targets, but Starlark code must use the name package_metadata to retrieve it.
- [Incompatible] The package(distribs=[...]) attribute has been removed. It has been a no-op for several years now. distribs() at the package level is no longer legal syntax.
- [Incompatible] The --host_jvm_profile command line argument is not supported anymore.
- [Incompatible] The path attribute is removed from filegroup.
- [Incompatible] "bazel query" and "bazel print_action" can't run under the output base anymore.
- [Incompatible] --zip_undeclared_test_outputs now defaults to false, causing undeclared test outputs (i.e., files written to $TEST_UNDECLARED_OUTPUTS_DIR by a test) to be produced as a directory instead of a zip file.
- [Incompatible] On Windows, a change to the output base locking protocol might cause an older Bazel invoked immediately after a newer Bazel (on the same output base) to error out instead of blocking for the lock, even if --block_for_lock is enabled. (#24210)
- The result of canonicalize-flags now includes all Starlark flags by default. Use --noexperimental_include_default_values for the old behavior that only reports Starlark flags with non-default values.
- Bazel now supports all characters in the rlocation and target paths of runfiles and can be run from workspaces with a space in their full path (#23331).
- genquery now supports (unconfigured) cycles, but may have higher peak memory usage.
- The default value of --skyframe_high_water_mark_minor_gc_drops_per_invocation and --skyframe_high_water_mark_full_gc_drops_per_invocation has been decreased to 10, which can result in Bazel OOMing more eagerly as Skyframe state is no longer dropped an unlimited number of times in response to high memory pressure.
- Improved progress message in case there are no actions in flight, and display explicitly "no actions running" in that case.
- glob now has a more efficient implementation that uses less retained memory and CPU, while sometimes taking more wall time for recursive globs in very large directory trees.
- REPO.bazel now allows another directive, ignore_directories(). It takes a list of directories to ignore just like .bazelignore does, but with glob semantics. (#24203)
Android
- Native
mobile-install
is deleted. Please use the new Starlarkified version (“mobile-install v3”) instead. See https://github.com/bazelbuild/rules_android.
Build Event Protocol
- BEP will include correct TestResult and TargetSummary events when special test inputs like $test_runtime fail to build.
- The default size limit for a named set of files in BEP is now 5000 (was unlimited before). In the event that the limit is reached, the message will be split.
- BEP now contains data similar to dump command breakdowns for rules, aspects and skykeys.
- WorkerMetrics of killed workers are logged (max 50 based on custom prioritization and then arranged in order of worker id). WorkerMetrics also includes the number of actions executed by each worker are now logged in the BEP. The semantics of WorkerPoolStats.evicted_count to refer to the workers that are killed (destroyed) as a result of memory pressure (evicted_count <= destroyed_count).
- BEP's execution_phase_time_in_ms no longer includes the analysis-only part at the beginning of the build. Artificial downtrend in execution_phase_time_in_ms expected.
- A new experimental flag, --experimental_build_event_output_group_mode, allows users to change how a given output group's files are reported in BEP. The current behavior is NAMED_SET_OF_FILES_ONLY which populates OutputGroup.file_sets. Users may now specify INLINE_ONLY to instead report files directly in the TargetComplete/AspectComplete event under OutputGroup.inline_files. Users may also specify BOTH to populate OutputGroup.file_sets and OutputGroup.inline_files.
- Undeclared test outputs are now reported individually in the BEP, unless zipping is enabled via --zip_undeclared_test_outputs.
- Log all WorkerPoolStats for all worker pools (even though workers aren't created or destroyed). Also add unknown_destroyed_count and alive_count to the WorkerPoolStats proto.
- By default, coverage artifacts will be reported inline in the TargetComplete event. To disable this behavior, pass --experimental_build_event_output_group_mode=baseline.lcov=named_set_of_files_only.
C++ / Objective-C
- [Incompatible] apple_cc_toolchain rule was removed. Use regular cc_toolchain instead.
- [Incompatible] The Starlark methods copts, generate_linkmap, and should_strip_binary in the objc fragment have been deleted. Please use the equivalent methods objccopts, objc_generate_linkmap, and objc_should_strip_binary in the cpp fragment instead.
- [Incompatible] Removed def_file from cc_common.create_link_variables.
- [Incompatible] With the default Unix toolchain on macOS, binaries now use @rpath to find their .dylib dependencies. This is required to fix issues where tools run during the build couldn't find their dynamic dependencies. (#23090)
- [Incompatible] The deprecated fragments["apple"].bitcode_mode and fragments["cpp"].apple_bitcode_mode APIs have been removed from Bazel. Apple deprecated Bitcode in Xcode 14.
- [Incompatible] CppLinkAction returns 2 args to aspects that have the correct quoting set (before it was always 1 args object defaulting to bash escaping).
- [Incompatible] The BAZEL_CURRENT_REPOSITORY preprocessor variable, which holds the canonical name of the Bazel repository containing a cc_* target, is now only set during compilation if the target depends on the C/C++ runfiles library @rules_cc/cc//runfiles via deps or implementation_deps.
- [Incompatible] C++ toolchains configuration files have moved to rules_cc, if you are depending on anything in @bazel_tools//tools/cpp, you should use the version from @rules_cc (>=0.0.12) instead.
- Added conlyopts and cxxopts attributes to C++ rules (#23792)
- cc_toolchain now passes runfiles for its *_files attrs (e.g. data files for a tool built for linking).
- The new cc_static_library rule produces a static library that bundles given targets and all their transitive dependencies. It has to be enabled via --experimental_cc_static_library.
- New $(DUMPBIN) make variable is now available for Visual Studio toolchains.
- --incompatible_make_thinlto_command_lines_standalone is now a no-op.
- --compile_one_dependency selects header-only cc_librarys in more cases.
- Added windows_quoting_for_param_files feature for windows-style parameter file escaping.
- The local_defines attribute of cc_library() and cc_binary() supports $(location ...) expansion for additional_compiler_inputs just like for deps.
- The bazel --quiet command line option can now be used to make Bazel emit much less output. (#24024)
- [Incompatible] cc_toolchain_suite is a no op. All C++ rules use Bazel's toolchain API.
- [Incompatible] --incompatible_enable_cc_toolchain_resolution is a no op. All C++ rules use Bazel's toolchain API.
Configurability / cquery
- [Incompatible] Incoming rule() transitions can't set cfg = "exec" or cfg = config.exec(). This generally doesn't make sense. Prefer declaring dependencies as exec tools.
- Starlark rules can annotate attr() with cfg = config.none(). This is useful for pure-data dependencies that should build the same no matter their parent's configuration.
- Starlark rules can replace cfg = "target" on attribute definitions with cfg = config.target() for more consistent syntax.
- bazel cquery more accurately lists dependencies from aspects. Requires --experimental_explicit_aspects. Try this if you see confusing results. As an experimental feature this doesn't work for all output formats. Available since 7.2.0.
- bazel query includes toolchain type requirements as implicit dependencies.. This includes the toolchains parameter in rule() definitions.
Coverage
- [Incompatible] Passing a FilesToRunProvider to coverage_support_files will now result in an error as opposed to being silently ignored.
- [Incompatible] Coverage report generators no longer receive the JAVA_RUNFILES and PYTHON_RUNFILES environment variables.
External Dependencies
- [Incompatible] The format of canonical repo names has changed to use plus (+) instead of tilde (~). Effectively, this flips the flag --incompatible_use_plus_in_repo_names to true, and the flag is now a no-op (i.e. cannot be "unflipped"). See https://bazel.build/external/module#repository_names_and_strict_deps for advice on how to avoid hardcoding canonical repository names.
- --experimental_repository_downloader_retries now defaults to 5.
- Overrides in the root MODULE.bazel file are now ignored with --ignore_dev_dependency. (Overrides in non-root modules are already ignored.)
- The fetch and vendor commands now support --target_pattern_file for specifying target patterns.
- Patches to the module file in single_version_override are now effective as long as the patch file lies in the root module.
- Repository rules instantiated in the same module extensions can now refer to each other by their extension-specified names in label attributes.
- override_repo and inject_repo can be used to override and inject repos in module extensions. (#23534)
- The new --inject_repository flag can be used to add new repositories via the CLI with --enable_bzlmod. Such repositories behave as if they were declared by local_repository via use_repo_rule in the root module. (#24301)
- External repositories that are managed by Bzlmod can now contain a top-level external directory or package. (#24147)
- repository_ctx.execute can now remove an environment variable when executing a process by associating it with the value None in the environment argument. (#24245)
- bazel mod now tries to evaluate all module extensions, even when some have failed to evaluate. (#24259)
- archive_override now accepts all attributes usable with http_archive; similar for git_override and git_repository. (#24443)
Java
- The core Java rules (java_binary, java_library, java_test, java_import, java_plugin) and symbols (java_common, JavaInfo, JavaPluginInfo) are no longer available in Bazel and must be loaded from @rules_java.
- WORKSPACE builds may need to update their setup, see the release notes at https://github.com/bazelbuild/rules_java/releases for what @rules_java now requires. Relatedly, projects enabling both --enable_bzlmod and --enable_workspace that fetch @rules_java via the MODULE.bazel file, may need to explicitly re-declare some dependencies in the WORKSPACE file, as Bzlmod dependencies are not automatically visible to other WORKSPACE repositories.
- The default java language level (with rules_java 8.1.0) is now 11 (previously 8).
- java_binary and java_test no longer generate an additional target - the deploy jars are once again outputs of the primary (only) target.
- JavaInfo.compilation_info.javac_options now returns a depset. Use tokenize_javacopts from @rules_java to get the options as a correctly ordered list.
- Java compilation actions now set LC_ALL=C.UTF-8 (previously: en_US.UTF-8).
Local Execution
- [Incompatible] The mnemonic passed to --worker_extra_flag is now matched against the worker key mnemonic when one is available, instead of the action mnemonic. This makes it consistent with other worker flags taking a mnemonic. (#24251)
- Prevent linux-sandbox(ed) spawns from being able to write in the cgroups mount.
- Symlink trees are now created through direct filesystem calls by default, instead of delegated to a helper process. On Windows, this entails respecting the --windows_enable_symlinks flag, falling back to a copy when the flag is unset (the helper process always attempts to create symlinks, irrespective of the flag). Set --noexperimental_inprocess_symlink_creation to temporarily revert to the previous behavior, which will be removed in a future release.
Performance
- [Incompatible] The aquery command now reports all potential inputs of actions that support input discovery, including the input headers of C++ compilation actions and those explicitly marked as unused through the unused_inputs_list argument to ctx.actions.run. Set --noinclude_pruned_inputs to omit pruned inputs from aquery output when running it after action execution.
- [Incompatible] The --experimental_aquery_dump_after_build_format and --experimental_aquery_dump_after_build_output_file command line options are not available anymore.
- --experimental_collect_system_network_usage is flipped to true and will be removed soon.
- Introduced Skyfocus, an experimental feature aimed to reduce Bazel's retained heap usage with working sets. Use --experimental_enable_skyfocus to enable it. See documentation for more information.
- bazel query now uses 3% less memory.
- Introduce new flag --experimental_worker_use_cgroups_on_linux that uses cgroups to track memory usage for singleplex workers (on Linux).
- Added --experimental_collect_skyframe_counts_in_profiler to collect Skyframe node counts in the JSON profile over time. Currently, the following SkyFunctions are measured: BZL_LOAD, GLOB, GLOBS, PACKAGE, CONFIGURED_TARGET, ASPECT, ACTION_EXECUTION.
- Introduced a new format for the execution log, enabled by --execution_log_compact_file. This format is preferred over the preexisting --execution_log_{binary,json}_file, as it’s much cheaper to produce and smaller in size; however, it’s not human-readable. The tools in //src/tools/execlog may be used to analyze logs and convert between formats.
Remote Execution
- Added the ability to garbage collect the disk cache by setting one or both of --experimental_disk_cache_gc_max_size and --experimental_disk_cache_gc_max_age. Garbage collection occurs in the background while the Bazel server is idle; the idle timer defaults to 5 minutes, but may be overridden by --experimental_disk_cache_gc_idle_delay.
- The default value of --experimental_remote_cache_eviction_retries is changed to 5.
- Uploading local action results to a disk or remote cache now occurs in the background whenever possible, potentially unblocking the execution of followup actions. Set --noremote_cache_async to revert to the previous behavior.
- Added support for using a remote cache that evicts blobs and doesn't have AC integrity check (e.g. HTTP cache).
- --incompatible_remote_symlinks, --incompatible_remote_dangling_symlinks, --incompatible_remote_downloader_send_all_headers and --incompatible_remote_output_paths_relative_to_input_rootare deleted.
- --build_event_upload_max_threads is removed.
- The default value of --experimental_remote_cache_compression_threshold is changed to 100.
Starlark / Build Language
- Bazel can now parse .scl files, a dialect of Starlark without Bazel-specific symbols.
- Dormant dependencies and materializer functions are now available with the --experimental_dormant_deps flag.
- Aspects can now propagate to target’s toolchain dependencies by specifying the toolchain types to propagate to via toolchains_aspects.
- Aspects can now return DefaultInfo, which will then be merged with that of the configured target they are applied to. Currently, only the files field is supported.
- Output groups provided by a rule and/or multiple aspects are now merged instead of resulting in an error.
- If --proto:rule_classes flag is enabled, query proto output will contain rule class definitions in Stardoc proto format.
- Starlark min and max builtins now allow a key callback, similarly to sorted.
- [Incompatible] Non-singleton target visibility lists can now contain //visibility:public and //visibility:private elements; the result is appropriately simplified when assigned to an attribute. (#19922)
- [Incompatible] --incompatible_simplify_unconditional_selects_in_rule_attrs simplifies configurable rule attributes which contain only unconditional selects. (#19922)
- [Incompatible] The input_manifests argument of ctx.actions.{run,run_shell} is now a no-op. resolve_command and resolve_tools always return the empty list as the input manifest list.
- [Incompatible] ctx.resolve_tools is no longer available by default, in preparation for complete removal. Use --noincompatible_disallow_ctx_resolve_tools to temporarily make it available again. (#22249)
Windows
- [Incompatible] On Windows, the default msys64 root is changed to C:/msys64 from C:/tools/msys64.
Appendix
The following flags have been removed or changed to no-op:
- --android_cpu
- --android_crosstool_top
- --android_grte_top
- --android_sdk
- --crosstool_top
- --enable_fdo_profile_absolute_path
- --experimental_announce_profile_path
- --experimental_objc_include_scanning
- --experimental_proto_extra_actions
- --fat_apk_cpu
- --host_crosstool_top
- --host_swiftcopt
- --incompatible_depset_for_java_output_source_jars
- --incompatible_disallow_symlink_file_to_dir
- --incompatible_disallow_unsound_directory_outputs
- --incompatible_enable_android_toolchain_resolution
- --incompatible_enable_cc_toolchain_resolution
- --incompatible_existing_rules_immutable_view
- --incompatible_make_thinlto_command_lines_standalone
- --incompatible_objc_provider_remove_linking_info
- --incompatible_remote_build_event_upload_respect_no_cache
- --incompatible_remote_dangling_symlinks
- --incompatible_remote_downloader_send_all_headers
- --incompatible_remote_output_paths_relative_to_input_root
- --incompatible_remote_results_ignore_disk
- --incompatible_remote_symlinks
- --incompatible_struct_has_no_methods
- --incompatible_use_host_features
- --incompatible_use_plus_in_repo_names
- --python2_path
- --python3_path
- --swiftcopt
Acknowledgements:
This release contains contributions from many people at Google, as well as Adam Azarchs, Adam Singer, Alan Falloon, Alessandro Patti, Alex Eagle, Alex Sharoff, Alexander Golovlev, Alexandre Boulgakov, Artem V. Navrotskiy, Ben Lee, Benjamin Peterson, Brentley Jones, CaerusKaru, Cameron Martin, Chirag Ramani, Chris Gray, Christian Scott, Clay McClure, Cornelius Riemenschneider, Cristin Donoso, Daniel Wagner-Hall, David Ostrovsky, David Sanderson, Dennis van den Berg, detailyang, Dimi Shahbaz, DocQuantum, Douglas Thor, eantpil, Ed Schouten, Emil Waijers, Fabian Meumertzheim, FaBrand, Farid Zakaria, Fil-Den, Fredrik Medley, Fredrikhms, George Gensure, Greg Magolan, Greg Roodt, Grzegorz Lukasik, Guillaume Maudoux, Gunnar Wagenknecht, Honnix, Ikko Eltociear Ashimine, Isaac Torres, Jacob Van De Weert, James Sharpe, Jamison Lahman, Jan Keromnes, Jason Schroeder, Javier Maestro, Jay Conrod, Jiawen (Kevin) Chen, JKutscha, Joe Lencioni, John Millikin, Jonas Scharpf, Jonathan Block, jonshea, Jordan Mele, Josh Chorlton, Keith Smiley, Laurent Le Brun, Laurenz Altenmller, Letu Ren, Lior Gorelik, Luis Padron, M. Taimoor Zaeem, Marc Redemske, Maria, Mark Elliot, Matt Brown, Matt Smith, Matthieu MOREL, Michael Siegrist, Muescha, Nick Biryulin, Nikhil Kalige, Niko Wenselowski, Nils Wireklint, ouguoc2-stripe, Patrick Balestra, Paul Janzen, Peter Lobsinger, PikachuHy, Rahul Butani, Richard Smith, Richard Woodbury, Romain Chossart, Roman Salvador, Ryan Beasley, Sangita.Nalkar, Sara Adams, shingt, Siddhartha Bagaria, Simon Mavi Stewart, Son Luong Ngoc, Spencer Putt, Stefano Baghino, Sushain Cherivirala, Tanya Bouman, Ted, thesayyn, Thi Doan, Thomas Weischuh, Tianyu Geng, Timothy Gu, Tomasz Pasternak, UebelAndre, Ulf Adams, Ventzilla, Victor Hiairrassary, Viktor Kustov, Wade Carpenter, Xavier Bonaventura, xinyu.wang, and Yannic Bonenberger.
Notice: Bazel installers contain binaries licensed under the GPLv2 with Classpath exception. Those installers should always be redistributed along with the source code.
Some versions of Bazel contain a bundled version of OpenJDK. The license of the bundled OpenJDK and other open-source components can be displayed by running the command bazel license
. The vendor and version information of the bundled
OpenJDK can be displayed by running the command bazel info java-runtime
. The binaries and source-code of the bundled OpenJDK can be downloaded from our mirror server.
Security: All our binaries are signed with our public key 3D5919B448457EE0.