Skip to content

Support C++20 modules in the rules-based toolchain API#750

Draft
fmeum wants to merge 4 commits into
bazelbuild:mainfrom
fmeum:fmeum/cpp20-modules-rules-based
Draft

Support C++20 modules in the rules-based toolchain API#750
fmeum wants to merge 4 commits into
bazelbuild:mainfrom
fmeum:fmeum/cpp20-modules-rules-based

Conversation

@fmeum

@fmeum fmeum commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Support C++20 modules in the rules-based toolchain API

The rules-based cc/toolchains toolchain API is currently missing several
pieces needed to drive Bazel's C++20 modules pipeline (clang-scan-deps
.ddiaggregate-ddigenerate-modmap → module compile). The legacy
cc_toolchain_config-based unix_cc_toolchain_config.bzl already wires these
up, but the equivalents do not exist for the rules-based form, so toolchains
built with cc/toolchains cannot compile C++20 module interfaces.

This change adds the missing building blocks:

  • cpp20_module_actions action 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_actions so that flags that are
    incompatible with C++20 modules (e.g. -fno-cxx-modules) can keep targeting
    only the non-module compiles. Toolchains combine this set with
    compile_actions/source_compile_actions on the relevant cc_args.

  • Build variables (cc/toolchains/variables/BUILD): register
    cpp_module_output_file and cpp_module_modmap_file (already passed by
    compile.bzl via additional_build_variables), and make dependency_file,
    output_file, source_file and user_compile_flags available to the C++20
    module actions so toolchains can reference them.

  • compiler_files legacy 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_files
    and 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.bzl fixes:

    • _create_scan_deps_action now passes needs_include_validation (the
      underlying action requires a bool) and no longer requests a .d dotd
      file — the scanner emits a P1689 .ddi file, not a Make-style dependency
      file, so the declared .d output was never produced.
    • _create_compile_action now accepts and forwards the C++20 module
      output/modmap arguments (additional_outputs, module_files,
      modmap_file, modmap_input_file) that _create_compile_source_action
      already 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_library with
module_interfaces that is imported by a cc_binary/cc_test.

Test coverage

The C++20 modules pipeline lives only in rules_cc's compile.bzl (Bazel's
native rules don't implement it) and was previously untested here:
CppModulesConfiguredTargetTest only checks the
--experimental_cpp_modules/cpp_modules gating, and Bazel's shell
integration test self-skips unless a host clang >= 17 is present. This adds
tests/cc/common/cc_module_compile_configured_target_tests.bzl, an analysis
test that drives the module interface compile + dependency scanning actions with
the mock toolchain (no real compiler needed) and asserts the scanning action
emits a .ddi and not a .d file. It fails without the fixes in this PR (e.g.
needs_include_validation got value of type 'NoneType', want 'bool').

@google-cla

google-cla Bot commented Jun 14, 2026

Copy link
Copy Markdown

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.

@fmeum fmeum force-pushed the fmeum/cpp20-modules-rules-based branch from 4165318 to 1855ab6 Compare June 14, 2026 22:35
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.
@fmeum fmeum force-pushed the fmeum/cpp20-modules-rules-based branch from 1855ab6 to 2642dab Compare June 15, 2026 08:44
Comment thread cc/toolchains/actions/BUILD Outdated
Comment thread cc/private/compile/compile.bzl Outdated
Comment thread cc/toolchains/legacy_file_group.bzl Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant