News
June 25, 2026 · View on GitHub
Unreleased
This is the first entry in the resumed changelog. Changes below are listed relative to 0.15.1 (released 2025-06-24); releases between the historical notes below and 0.15.1 were not tracked here.
Breaking changes
- Bazel 8 is now required for
bzlmod. The primary tested Bazel version moved to 8.6.0. Bazel 7 is still supported, but only inWORKSPACEmode; if you usebzlmodyou must be on Bazel 8 or newer (#1514). - Built toolchains now ship only the latest patch of each minor series. You
can request a
<major>.<minor>.xwildcard (e.g.cmake_version = "3.19.x") which resolves to the newest known patch of that series. The exact-latest version string still works, but other previously-valid exact patch versions now fail (#1559). - Several default built-tool versions changed, so unpinned users get the
newer version automatically. The default built
mesonjumped from 1.5.1 to 1.10.1 (a five-minor jump that can change meson behavior; fixes builds under apple-clang 17 / Xcode 26) (#1473), and the defaultcmake(3.31.8 → 3.31.12) andninja(1.13.0 → 1.13.2) moved with the latest-patch-per-minor change above (#1559). Pin the relevant*_versionargument ofrules_foreign_cc_dependenciesif you need the previous version. - Unrecognized platforms now fail the build instead of warning. An unknown target/host OS or CPU (or an unmapped processor/target-OS parameter) now errors out rather than silently falling back to a native compile. Builds that previously limped along on an unrecognized platform will need a platform-data update (#1490, building on #1438).
- Prebuilt
ninja1.8/1.9binaries were dropped. The supported prebuilt ninja range is now1.10to1.13, matching the build-from-source range. The exact1.8.2/1.9.0versions and the1.8.x/1.9.xwildcards no longer resolve. If you were requesting a prebuilt1.8/1.9(vianinja_versionortools.ninja(version = ...)), move up to1.10or newer (#1565). - The bzlmod
toolsextension is now hub-and-spoke. Register the single@rules_foreign_cc_toolchains//:alltarget instead of individual spoke targets. The version-suffixed source-archive repos (e.g.@cmake_src_3.31.12) replace the previous singleton names (@cmake_src); there is no zero-edit migration path. See Migrating to the bzlmod hub for the rename table and the two supported migration patterns (#1567). - The per-platform binary spoke repos were renamed to one scheme,
@<tool>-<version>-<os>-<arch>(e.g.@ninja_1.13.2_linuxbecame@ninja-1.13.2-linux-x86_64, and cmake's upstream platform tokens were normalized to Bazel spellings such aswindows-x86_64). These are implementation repo names; the hub and the@<tool>_<version>_toolchainsaggregators are unchanged, so this only affects code that referenced a binary spoke by its literal name. See Migrating to the bzlmod hub (#1567). - The public
@rules_foreign_cc//toolchains:built_*_toolchainlabels were removed (built_cmake_toolchain,built_ninja_toolchain,built_make_toolchain,built_meson_toolchain,built_pkgconfig_toolchain). The build-from-source toolchains are now per-version spokes registered through the hub. Consumers that registered these labels directly should declare the matchingtools.<tool>(mode = "source", version = "...")tag (an explicit version is required), or register the spoke-provided toolchain. See Migrating to the bzlmod hub (#1567). - The autogenerated
@rules_foreign_cc//toolchains:cmake_versions.bzldata file was removed. ItsCMAKE_SRCStable moved to//toolchains/private:cmake_versions.bzlasCMAKE_SRC_SRCSand is no longer publicly loadable. It was a "DO NOT MODIFY" generated data file; out-of-tree loads of it (always unsupported in spirit) must drop the dependency (#1567).
New features
- New
msbuildrule for building MSBuild (.vcxproj/.sln) projects withMSBuild.exefrom MSVC. Only the pre-installed toolchain is supported (#1443). - New
resource_sizeattribute on all build rules (default/tiny/small/medium/large/enormous, plus a fixed single-CPUserial). It declares the action's CPU/RAM footprint to the Bazel scheduler and forwards parallelism env vars (CMAKE_BUILD_PARALLEL_LEVEL,GNUMAKEFLAGS,MESON_NUM_PROCESSES,NINJA_JOBS) to the underlying build system. Defaults can be overridden viabazel run @rules_foreign_cc//foreign_cc/settings(#1465, #1511). For sized targets, the build tool may use the reserved CPU count plus 2 (tunable via--@rules_foreign_cc//foreign_cc/settings:parallelism_overcommit);serialis exempt and always runs-j1(#1533). - Output validation in-action via the new
experimental_validate_outputs_in_actionattribute (default on). When an expected installed output is missing, the build now fails with a clear message that lists nearby/similarly-named files and preserves the temp tree, instead of Bazel's opaque "output was not created" error. Disable per-target withexperimental_validate_outputs_in_action = False(#1517). - Opt-in short build paths on Windows via the
--@rules_foreign_cc//foreign_cc/settings:allow_building_in_tmpflag (default off), which relocates the build tree under$TMPto stay below the 260-charMAX_PATHlimit (#1527). set_file_prefix_mapis now available on the built-tool rules (in addition to the main rules), and a new--@rules_foreign_cc//foreign_cc/settings:set_file_prefix_map_defaultflag turns it on globally; the per-rule attribute still wins. This strips sandbox paths via-ffile-prefix-mapto improve build reproducibility (skipped on MSVC) (#1545, groundwork in #1553).boost_buildand the builtninjatool now honor toolchaincopts/linkopts(previously advertised but ignored) (#1554).ninjanow wires up the cc toolchain's C build variables (compilers, flags, pkg-config, and dependency env) the same waymakedoes, instead of relying on tools found onPATH. Existingninja()targets now build with the configured toolchain (#1477).mesongains ashared_ldflags_optionattribute that routes shared-library linker flags into a named meson build option, fixingshared_library()link failures when executable-only flags such as-pieare present;optionsvalues are now location/make-variable expanded (#1401).makeandconfigure_makegaindynamic_module_ldflags_varsfor loadable-module (plugin) linker flags, kept separate from shared-library flags. This is primarily for Darwin, where module links use-bundle(#1542).configure_makenow stubs autotools regen tools (ACLOCAL,AUTOCONF,AUTOMAKE, etc.) so builds don't spuriously trigger regen recipes that break on RBE or hosts lacking those tools. The newunstubbed_regen_toolsattribute lets a target opt specific tools back in (#1544).out_data_dirsandout_data_filescontents are now exposed as output groups, so you can reference them directly instead of going throughgen_diror a genrule (#1451, #1464).cmakecross-compilation gains more targets:armv7andx86_32CPUs with OS-awareCMAKE_SYSTEM_PROCESSORvalues (fixing Android armeabi-v7a/x86 builds) (#1555), iOS/tvOS/watchOSCMAKE_SYSTEM_NAMEmappings (#1495), and macOS as a cross-compile target (#1438).cmakesetsCMAKE_OSX_SYSROOTautomatically on macOS from the hermetic sysroot, so cmake honors it instead of searching for Xcode (#1361).- New
noop_<tool>_toolchaintargets under//toolchains(one per noop-capable build tool: cmake, ninja, make, meson, pkgconfig, autoconf, automake, m4, msbuild). nmake has no noop toolchain: it shares make's toolchain type, sotools.make(mode = "noop")no-ops the make family. Each is a tool-implementation target pointing the tool at a failing path. This is for builds that resolve a tool but treat it as optional and never invoke it (e.g. pkgconfig set to noop to disable package searches): resolution succeeds and that step is skipped. If a build does invoke a noop tool it fails loudly rather than silently falling back to a host binary. These are implementation targets (they go in thetoolchain = ...field of atoolchain()rule), not directly registerable toolchains; wrap one in your owntoolchain()to use it (#1567). - Per-tool bzlmod tag classes with mode selection. Each tool takes a
mode(some subset ofbinary,source,system,noop, depending on the tool) plus an optional pinnedversion.mode = "noop"selects the built-innoop_<tool>_toolchain(above), sotools.<tool>(mode = "noop")satisfies resolution without invoking the tool. Root modules can opt out of the rfcc-default registrations withtools.explicit(), or fetch a spoke without registering it viaregister_toolchain = False(#1567). - cmake and ninja now register a host-PATH
systemtoolchain in addition to their prebuilt binary. The binary toolchain still wins on the platforms rules_foreign_cc ships prebuilts for; on any other host, resolution now falls back to acmake/ninjafound onPATHinstead of failing. This restores the WORKSPACE default behavior. If you relied on resolution failing on an unsupported platform, usetools.explicit()and declare only the cmake/ninja modes you want (#1567).
Bug fixes
cmake
- Default
CMAKE_MSVC_DEBUG_INFORMATION_FORMATtoEmbedded(/Z7) and replace/Zi, fixing intermittent "PDB API call failed" (C1090) errors when building multiple cmake targets in parallel on Windows. This changes the default debug-info format for anyone who hasn't set the cache variable explicitly (embedded in.objrather than a separate.pdb) (#1483).
meson
- Fix the CMake-based dependency fallback by restoring the
ninjawrapper name and addingmakeas a dependency, so meson/cmake dependency lookups resolve correctly (#1506). - Export
ARandSTRIPfrom the cc toolchain so meson uses the hermetic archiver/stripper (#1302). - Fix
meson_with_requirementsso Python modules declared as requirements are found when meson re-invokes python directly (#1487). - A value set via
target_args["setup"]is no longer clobbered by the empty deprecatedsetup_args, and the deprecation only fails when the deprecated arg is actually set (#1444).
Framework (applies across rules)
$$EXT_BUILD_DEPS$$references in user attributes are now properly escaped so they survive make-variable expansion into the generated build scripts (#1496).- Honor
--force_pic: objects are now built position-independent when the toolchain requires PIC for dynamic libraries, fixing shared-library link errors (#1440). - Fix directory symlinks in subdirectories that produced dangling links (#1469).
- Resolve the Apple SDK root via
xcrun --sdkwithout the deprecatedAPPLE_SDK_VERSION_OVERRIDEsuffix, fixing builds with non-standard SDK names (#1467). - Populate
RANLIBfrom the toolchain when available instead of always using a no-op (:), fixing parallel builds (e.g. openssl) that need a real ranlib (#1509). - Variant toolchain attributes (
toolchain/extra_toolchain) acceptselect()again andextra_toolchainis now optional (#1466, fixing a regression from #1459).
Built pkg-config / make tools
- Fix building the from-source
pkg-configtool on Windows (#1459), compile it with-std=gnu90to fix failures on newer compilers (e.g. glib) (#1458), and prefer the fastmirror.bazel.builddownload mirror (#1445). - Append toolchain
-isysteminclude flags toCC/LD(not justCFLAGS) when bootstrapping the builtmakeandpkg-configtools, fixing configure scripts that need toolchain-provided system headers (#1470). - Symlink a tool's
.runfilesalongside it when symlinking tools into the build'sbindirectory, so hermetic autotools can find their runfiles data (#1434).
Dependencies and toolchains
- Bazel 9 compatibility: load
CcSharedLibraryInfodirectly fromrules_ccand upgraderules_ccto 0.2.18, so the rules are consumable under Bazel 9 (#1493, #1552). - The built
maketool (4.4 and 4.4.1) is now reproducible across machines, improving cache hit rates (#1543). - Updated bundled dependency versions, including a new
bazel_libdependency and bumps torules_python1.9.0,bazel_skylib,platforms,rules_cc,rules_shell,rules_perl, andrules_rust, mainly to resolve bzlmod version-mismatch warnings and keep lockfiles reproducible (#1462, #1486, #1489, #1482, #1492). Therules_pythondownload URL also moved to thebazel-contribGitHub org (#1500).
Internal
- Faster builds:
copy_dir_contents_to_dirbatches itstouch -rcalls (~22% lower wall-time on darwin/windows example jobs) (#1549). - Refactors with no behavior change: extracted common framework attributes
(#1553),
bazelrc-shim plumbing
(#1546),
data-driven prebuilt-toolchain generation
(#1561), and
use of rules_cc's
msvc-clconfig_setting (#1562). - Removed the legacy Bazel-4-era platform config_settings in favor of
@platforms//os:...(#1474). - Removed the
cmake_androidexample (core Android support is unchanged) (#1471). - Extensive CI, test-harness, formatting, example, and download-mirror work
across many PRs, including the move to a single
bazel testphase (#1548), porting examples to bzlmod (#1498), and enabling many third-party examples on Windows.
March 2021:
These rules are now maintained by the community.
Note: After this release we will be bumping the minimum tested version to 4.0.0.
-
Added repository rules for downloading prebuilt versions of cmake and ninja rather than relying on system installed tools.
-
Added native ninja build rule
-
Now builds under the Bazel sandbox rather than in
/tmp -
Tidied up the structure of the examples directory
-
Deprecated the old rules
install_ws_dependencyandcc_configure_make -
Autogenerated documentation was added
March 2019:
-
Support for versions earlier than 0.22 was removed.
-
Tests on Bazel CI are running in the nested workspace
January 2019:
-
Bazel 0.22.0 is released, no flags are needed for this version, but it does not work on Windows (Bazel C++ API is broken).
-
Support for versions earlier than 0.20 was removed.
-
rules_foreign_cc take-aways describing the recent work has been published.
-
Examples package became the separate workspace. This also allows to illustrate how to initialize rules_foreign_cc.
-
Native tools (cmake, ninja) toolchains were introduced. Though the user code does not have to be changed (default toolchains are registered, they call the preinstalled binaries by name.), you may simplify usage of ninja with the cmake_external rule and call it just by name. Please see examples/cmake_nghttp2 for ninja usage, and WORKSPACE and BUILD files in examples for the native tools toolchains usage (the locally preinstalled tools are registered by default, the build as part of the build tools are used in examples). Also, in examples/with_prebuilt_ninja_artefact you can see how to download and use prebuilt artifact.
-
Shell script parts were extracted into a separate toolchain. Shell script inside framework.bzl is first created with special notations:
export var_name=var_valuefor defining the environment variable$$var_name$$for referencing environment variable`shell_command <space-separated-maybe-quoted-arguments>`for calling shell fragment
The created script is further processed to get the real shell script with shell parts either replaced with actual fragments or with shell function calls (functions are added into the beginning of the script). Extracted shell fragments are described in commands.bzl.
Further planned steps in this direction: testing with RBE, shell script fragments for running on Windows without msys/mingw, tests for shell fragments.