Support C++20 modules , GCC part
- 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
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