Support C++20 modules in the rules-based toolchain API#750
Draft
fmeum wants to merge 4 commits into
Draft
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
4165318 to
1855ab6
Compare
The rules-based cc/toolchains toolchain API was missing several pieces needed to drive Bazel's C++20 modules pipeline (clang-scan-deps -> .ddi -> aggregate-ddi -> generate-modmap -> module compile): - Add a cpp20_module_actions action type set grouping the module interface compile, codegen and dependency scanning actions. These are deliberately kept out of compile_actions/source_compile_actions so that flags incompatible with C++20 modules can keep targeting only the non-module compiles. - Register the cpp_module_output_file and cpp_module_modmap_file build variables and make dependency_file, output_file, source_file and user_compile_flags available to the C++20 module actions. - Include the C++20 module actions in the compiler_files legacy file group so their tools (e.g. the dependency scanner) are available to the compile actions. - Fix _create_scan_deps_action to pass needs_include_validation and to not request a .d dotd file (the scanner emits a P1689 .ddi file), and let _create_compile_action forward the C++20 module output/modmap arguments to the underlying action. The C++20 modules pipeline lives only in rules_cc's compile.bzl (Bazel's native rules do not implement it), and was previously untested here: Bazel's CppModulesConfiguredTargetTest only checks the --experimental_cpp_modules / cpp_modules gating, and the shell integration test self-skips unless a host clang >= 17 is present. Add an analysis test that drives the module interface compile + dependency scanning actions with a mock toolchain (no real compiler needed) and asserts the scanning action emits a .ddi and not a .d file. This test fails without the fixes above.
1855ab6 to
2642dab
Compare
fmeum
commented
Jun 18, 2026
fmeum
commented
Jun 18, 2026
fmeum
commented
Jun 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Support C++20 modules in the rules-based toolchain API
The rules-based
cc/toolchainstoolchain API is currently missing severalpieces needed to drive Bazel's C++20 modules pipeline (
clang-scan-deps→.ddi→aggregate-ddi→generate-modmap→ module compile). The legacycc_toolchain_config-basedunix_cc_toolchain_config.bzlalready wires theseup, but the equivalents do not exist for the rules-based form, so toolchains
built with
cc/toolchainscannot compile C++20 module interfaces.This change adds the missing building blocks:
cpp20_module_actionsaction type set (cc/toolchains/actions/BUILD)grouping the module interface compile, codegen and dependency scanning
actions. These are deliberately kept out of
compile_actions/source_compile_actionsso that flags that areincompatible with C++20 modules (e.g.
-fno-cxx-modules) can keep targetingonly the non-module compiles. Toolchains combine this set with
compile_actions/source_compile_actionson the relevantcc_args.Build variables (
cc/toolchains/variables/BUILD): registercpp_module_output_fileandcpp_module_modmap_file(already passed bycompile.bzlviaadditional_build_variables), and makedependency_file,output_file,source_fileanduser_compile_flagsavailable to the C++20module actions so toolchains can reference them.
compiler_fileslegacy file group (cc/toolchains/legacy_file_group.bzl):include the C++20 module actions so their tools (most importantly the
dependency scanner) end up in the toolchain's
compiler_files/all_filesand are therefore available to the compile actions. Without this the scanner
binary is not staged and the scanning action fails with a missing-executable
error.
compile.bzlfixes:_create_scan_deps_actionnow passesneeds_include_validation(theunderlying action requires a
bool) and no longer requests a.ddotdfile — the scanner emits a P1689
.ddifile, not a Make-style dependencyfile, so the declared
.doutput was never produced._create_compile_actionnow accepts and forwards the C++20 moduleoutput/modmap arguments (
additional_outputs,module_files,modmap_file,modmap_input_file) that_create_compile_source_actionalready passes to it.
Validated end to end by wiring a rules-based LLVM/Clang toolchain to use these
and successfully scanning, compiling and linking a
cc_librarywithmodule_interfacesthat is imported by acc_binary/cc_test.Test coverage
The C++20 modules pipeline lives only in rules_cc's
compile.bzl(Bazel'snative rules don't implement it) and was previously untested here:
CppModulesConfiguredTargetTestonly checks the--experimental_cpp_modules/cpp_modulesgating, and Bazel's shellintegration test self-skips unless a host
clang >= 17is present. This addstests/cc/common/cc_module_compile_configured_target_tests.bzl, an analysistest that drives the module interface compile + dependency scanning actions with
the mock toolchain (no real compiler needed) and asserts the scanning action
emits a
.ddiand not a.dfile. It fails without the fixes in this PR (e.g.needs_include_validation got value of type 'NoneType', want 'bool').