bazelbuild / bazelbuild/bazel

Support C++20 modules , GCC part

Open
#30,023 0 comments 0 reactions 0 assignees View on GitHub
P3 team-Core team-Rules-CPP type: feature request
Dominant language
Java
Stars
25.8k
Forks
4.6k
Avg merge
2d 20h
Merged PRs (30d)
72

Description

### Description of the feature request:

After [#19940](https://github.com/bazelbuild/bazel/pull/19940) (split into smaller patches and merged, e.g. [#22553](https://github.com/bazelbuild/bazel/pull/22553)), Bazel gained **basic C++20 modules support** with Clang, but the **GCC path was not fully brought up to the same level**.

This issue tracks the remaining **GCC-specific work** needed to make C++20 modules usable with GCC toolchains.

### Which category does this issue belong to?

Core

### What underlying problem are you trying to solve with this feature?

I have identified **two problems**:

### Problem 1: GCC dependency scanner wrapper is incorrect (`rules_cc`)

The `gcc_deps_scanner_wrapper` used for the `c++-module-deps-scanning` action does not match current GCC module scanning requirements.

**Impact:** dependency scanning for module interface units fails or produces incorrect `.ddi` files when using GCC, blocking the rest of the module build graph.

**Likely area:** `rules_cc` toolchain (`gcc_deps_scanner_wrapper.sh.tpl`, related action config / compile flags).

### Problem 2: Bazel cannot parse GCC module `.d` dependency files (`bazel` core)

Even when compilation succeeds, Bazel fails during **header/include validation** while parsing GCC-generated `.d` files.

GCC emits **Makefile-style** module dependency files. Besides normal `#include` paths, the `.d` file also lists paths that are **not compile-time inputs**:

- The action's own outputs (`.o`, `.gcm`)
- Module mapper files (`.modmap`)
- Makefile metadata: `.PHONY`, order-only `|`, and GCC pseudo-targets such as `foo.c++-module`

Bazel's `HeaderDiscovery` treats every path in the `.d` file as a discovered include and reports undeclared inputs, even though compilation already succeeded.

**Impact:** builds fail after compile with errors such as:

```
ERROR: ... undeclared inclusion(s) in rule '//:demo':
this rule is missing dependency declarations for the following files included by 'foo.cppm':
'bazel-out/k8-fastbuild/bin/_objs/demo/foo.pic.gcm'
```

This is **GCC-specific**. Clang module depfiles do not contain this Makefile metadata.

**Likely area:** `CppCompileAction` / `HeaderDiscovery` in Bazel core.

**Example GCC `.d` file** (`bazel-bin/_objs/demo/foo.pic.d`):

```
bazel-out/k8-fastbuild/bin/_objs/demo/foo.pic.o \
bazel-out/k8-fastbuild/bin/_objs/demo/foo.pic.gcm: foo.cppm \
/usr/include/stdc-predef.h \
bazel-out/k8-fastbuild/bin/_objs/demo/foo.pic.modmap
foo.c++-module: bazel-out/k8-fastbuild/bin/_objs/demo/foo.pic.gcm
.PHONY: foo.c++-module
bazel-out/k8-fastbuild/bin/_objs/demo/foo.pic.gcm:| \
bazel-out/k8-fastbuild/bin/_objs/demo/foo.pic.o
```

### Which operating system are you running Bazel on?

linux

### What is the output of `bazel info release`?

_No response_

### If `bazel info release` returns `development version` or `(@non-git)`, tell us how you built Bazel.

_No response_

### What's the output of `git remote get-url origin; git rev-parse HEAD` ?

```text

```

### Have you found anything relevant by searching the web?

**Bazel / modules**

- [#19940](https://github.com/bazelbuild/bazel/pull/19940) — original C++20 modules support PR
- [#4005](https://github.com/bazelbuild/bazel/issues/4005) — Support C++20 modules (tracking issue)
- [#22553](https://github.com/bazelbuild/bazel/pull/22553) — one-phase compilation patch (merged)
- [bazelbuild/proposals#354](https://github.com/bazelbuild/proposals/pull/354) — design doc

**GCC / module dependency files**

- [GCC preprocessor/120103](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120103) — Generation of Make Dependencies for C++ Modules
- [GCC patch: change `.c++m` to `.c++-module`](https://gcc.gnu.org/pipermail/gcc-patches/2024-May/653041.html) — mkdeps pseudo-target suffix used in `.d` files
- [GCC C++ Module Preprocessing docs](https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Module-Preprocessing.html) — `-fdeps-format=p1689r5`, `-fdeps-file=`, etc.
- [P1689R5](https://wg21.link/p1689r5) — Format for describing dependencies of source files (`.ddi` format)

### Any other information, logs, or outputs that you want to share?

**Minimal repro**

ubuntu 24.04 with gcc 16

`BUILD.bazel`:

```python
load("@rules_cc//cc:cc_binary.bzl", "cc_binary")

cc_binary(
name = "demo",
srcs = ["main.cc"],
features = ["cpp_modules"],
module_interfaces = ["foo.cppm"],
)
```

`foo.cppm`:

```cpp
export module foo;
export int foo() { return 1; }
```

`main.cc`:

```cpp
import foo;
int main() { return foo(); }
```

```bash
bazel build //:demo --repo_env=CC=gcc-16 --cxxopt=-fmodules
```

Contributor guide

Open the contributing guide

Research direction

Reproduce the minimal example with GCC 16 using the provided bazel build command. Inspect rules_cc's gcc_deps_scanner_wrapper.sh.tpl and the Bazel CppCompileAction/HeaderDiscovery areas, then trace how GCC .ddi and .d files are handled. Done means the GCC module build completes without incorrect scanning or undeclared-input errors.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
build-system, compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.