bazel icon indicating copy to clipboard operation
bazel copied to clipboard

[4/5] support C++20 Modules, support one phase compilation

Open PikachuHyA opened this issue 1 year ago • 43 comments

I split the XXL PR https://github.com/bazelbuild/bazel/pull/19940 into several small patches. This is the fourth patch of Support C++20 Modules, which supports one phase compilation.

Changes of build graph

First, files are scanned, resulting in the creation of .ddi files. If the compiler being used is Clang, the tool clang-scan-deps is employed.

Next, the generated .ddi files are aggregated into a .CXXModules.json file using the aggregate-ddi tool.

Following this, the .CXXModules.json file, along with the .ddi files, is used to generate .modmap files through the generate-modmap tool.

Finally, the source files are compiled into object files. If a file is a module interface, a corresponding module file is produced as a byproduct.

The following diagram illustrates the scanning process.

              ┌────────┐                  ┌────────┐                  ┌────────┐
              │foo.cppm│                  │bar.cppm│                  │main.cc │
              └────┬───┘                  └────┬───┘                  └────┬───┘
                   │  c++-module-deps-scanning │                           │
                   │                           │                           │
              ┌────▼───┐                  ┌────▼───┐                  ┌────▼───┐
              │foo.ddi │                  │bar.ddi │                  │main.ddi│
              └────┬───┘                  └────┬───┘                  └────┬───┘
                   │                           │                           │
                   └───────────────────────────┼───────────────────────────┘
                                               │aggregate-ddi
                                      ┌────────▼───────────┐
                                      │demo.CXXModules.json│
                                      └────────────────────┘

The following diagram illustrates the compile process of foo.cppm.

                                                    ┌────────────────────┐
                                                    │demo.CXXModules.json│
                                                    └─────┬──────────────┘
                                                          │
                                                          │
                                        ┌───────┐         │          ┌───────────┐
                                     ┌─►│foo.ddi├─────────┤          │ bar.cppm  │
                                     │  └───────┘         │          └─────┬─────┘
                                     │                    │                │
                                     │                    │                │
                                     │                    │                │
            c++-module-deps-scanning │                    │                │
      ┌────────┐                     │  ┌───────┐   ┌─────▼────┐      ┌────▼─────┐
      │foo.cppm├─────────────────────┴─►│foo.d  │   │foo.modmap│      │ bar.pcm  │
      └───┬────┘                        └──┬────┘   └────┬─────┘      └────┬─────┘
          │                                │             │                 │
          │                                │             │                 │
          │◄───────────────────────────────┴─────────────┴─────────────────┘
          │ c++20-module-compile
 ┌────────▼─────────┐
 │ foo.pcm && foo.o │
 └──────────────────┘

Changes of compile

I modified the CppCompileAction to include the relevant context, inputs, and outputs.

Context: Module files and .CXXModules.json files Inputs: Module files, .modmap file, and .modmap.input file Outputs: Module files and .CXXModules.json files The primary difference in CppCompileAction is the addition of the computeUsedCpp20Modules function.

The restart mechanism is utilized; if the necessary C++20 Modules files are not ready during compilation, the current compilation will exit and wait for an appropriate time to recompile.

PikachuHyA avatar May 27 '24 09:05 PikachuHyA

@katre @lberki I'm not sure if you got the notification, but ping... If this PR [4/5] can be merged, we can start using C++ modules with bazel... in eager anticipation :-)

peakschris avatar Sep 05 '24 18:09 peakschris

Sorry, I didn't notice this because I don't know anything about C++ modules. Re-assigning to @comius, apologies for not noticing this earlier.

katre avatar Sep 05 '24 19:09 katre

I'm testing this patch. If this patch ready, I will remove the [WIP] prefix.

PikachuHyA avatar Sep 06 '24 01:09 PikachuHyA

@comius @trybka please review this patch.

PikachuHyA avatar Sep 12 '24 12:09 PikachuHyA

@comius @trybka, friendly ping!

peakschris avatar Sep 17 '24 23:09 peakschris

Hey, this is quite a large PR and will take me some time to review it completely. Thanks for your patience.

comius avatar Sep 23 '24 12:09 comius

Hey, this is quite a large PR and will take me some time to review it completely.

Please also review https://github.com/bazelbuild/bazel/pull/22744, which contains a small patch split from this one.

PikachuHyA avatar Sep 26 '24 02:09 PikachuHyA

@comius kind ping

PikachuHyA avatar Oct 09 '24 08:10 PikachuHyA

Hi @comius @trybka, is there any chance this feature could make it in soon? We are keenly awaiting it in one of the bazel 8 releases

peakschris avatar Nov 01 '24 01:11 peakschris

@comius ping

PikachuHyA avatar Nov 14 '24 10:11 PikachuHyA

@comius @trybka can we expect to see this before 2025?

ChuanqiXu9 avatar Nov 21 '24 05:11 ChuanqiXu9

@comius @trybka can we expect to see this before 2025?

Hey, yes. I was under a very heavy load for Bazel 8 release (removal of all the ruleset except C++). It's just winding down, so expect more going on in the following weeks.

comius avatar Nov 21 '24 08:11 comius

@comius @trybka ping

PikachuHyA avatar Dec 16 '24 11:12 PikachuHyA

@comius @trybka can we expect to see this before 2025?

Hey, yes. I was under a very heavy load for Bazel 8 release (removal of all the ruleset except C++). It's just winding down, so expect more going on in the following weeks.

Not a push, but it's Dec 20.

ChuanqiXu9 avatar Dec 20 '24 06:12 ChuanqiXu9

@comius @trybka It is January 2025. Many people are waiting for this PR to land.

tintor avatar Jan 03 '25 23:01 tintor

@comius @trybka we are eagerly awaiting support for modules in Bazel. If you don't have time to review (this PR has now been waiting for 4 months), is there some other way it can progress?

peakschris avatar Jan 23 '25 21:01 peakschris

I conferred with @comius and I'm going to take point. As I understand it, it doesn't merge cleanly in our repo so I anticipate some back and forth to get it working.

trybka avatar Jan 23 '25 21:01 trybka

@trybka joining others in voicing excitement in getting c++ module support into bazel. Anything we can do to help get this merged? Any rough ETA so we can plan accordingly?

Much appreciated!

sachnk avatar Jan 31 '25 15:01 sachnk

I conferred with @comius and I'm going to take point. As I understand it, it doesn't merge cleanly in our repo so I anticipate some back and forth to get it working.

ping @trybka

PikachuHyA avatar Feb 19 '25 11:02 PikachuHyA

Rebased due to windows CI failed.

PikachuHyA avatar Feb 21 '25 06:02 PikachuHyA

Internal checks mostly look good. AFAICT no adverse breakages, but I'm re-running flaky failing tests anyway.

I don't have a good solution yet for the failing test. I'm wondering if it would be possible to gate the tests that require cpp20 modules support on some other bit that signals that we have the requisite tools available? (Maybe it would be sufficient to try to configure the action once and fail gracefully).

I can imagine also wanting something in the crosstool itself (e.g. feature(name='supports_cpp20_modules')) for the non-{clang,msvc-cl,gcc} compilers or toolchains not yet willing to adopt support.

Here's the current failure:

Basically because we don't intend to support C++20 modules immediately, we had stubbed out the tools provided in semantics.bzl -- e.g. here: https://cs.opensource.google/bazel/bazel/+/master:src/main/starlark/builtins_bzl/common/cc/semantics.bzl;l=137-149;drc=f777a3c33151b5a3ae2295f1ba6ea94653840665

Ours looks like this:

semantics = struct(
   ...
   cpp_modules_tools = lambda: {},
   ...
)

With this PR, tests like CppModulesConfiguredTargetTest.testSameModuleInterfacesFileInCcLibraryTwice fail because those tools are not provided, e.g. with:

java.lang.RuntimeException: Unrecoverable error while evaluating node 'ConfiguredTargetKey{label=<somelabel>, config=BuildConfigurationKey[<somekey>]}' (requested by nodes 'ConfiguredTargetKey{label=<someotherlabel>, config=BuildConfigurationKey[<somekey>]}')
...
Caused by: net.starlark.java.eval.Starlark$UncheckedEvalException: NullPointerException thrown during Starlark evaluation (<somelabel>)
	at <starlark>.compile(<builtin>:0)
	at <starlark>._compile(/virtual_builtins_bzl/common/cc/cc_common.bzl:755)
	at <starlark>._cc_library_impl(/virtual_builtins_bzl/common/cc/cc_library.bzl:56)
Caused by: java.lang.NullPointerException: the tool 'aggregate-ddi' cannot be null
	at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:988)
	at com.google.devtools.build.lib.rules.cpp.CcCompilationHelper.createAggDdiAction(CcCompilationHelper.java:1852)
	at com.google.devtools.build.lib.rules.cpp.CcCompilationHelper.createCcCompileActionsWithCpp20ModuleHelper(CcCompilationHelper.java:1057)
	at com.google.devtools.build.lib.rules.cpp.CcCompilationHelper.createCcCompileActionsWithCpp20Module(CcCompilationHelper.java:987)
	at com.google.devtools.build.lib.rules.cpp.CcCompilationHelper.compile(CcCompilationHelper.java:835)
	at com.google.devtools.build.lib.rules.cpp.CcModule.compile(CcModule.java:2255)

trybka avatar Feb 21 '25 20:02 trybka

With this PR, tests like CppModulesConfiguredTargetTest.testSameModuleInterfacesFileInCcLibraryTwice fail because those tools are not provided

hi @trybka , thank you for sharing the detailed failure messages.

Would it be possible for us to temporarily disable the failing tests in order to quickly merge this patch?

PikachuHyA avatar Feb 24 '25 15:02 PikachuHyA

Yes that seems reasonable. If you want to do that I can merge your changes, otherwise I'll do something tomorrow.

trybka avatar Feb 24 '25 23:02 trybka

Yes that seems reasonable. If you want to do that I can merge your changes, otherwise I'll do something tomorrow.

hi @trybka , I have removed the CppModulesConfiguredTargetTest . please merge the patch.

PikachuHyA avatar Feb 25 '25 07:02 PikachuHyA

I believe the CI failure is not related to this patch.

PikachuHyA avatar Feb 25 '25 07:02 PikachuHyA

The failures are known, I retried the runs.

fmeum avatar Feb 25 '25 08:02 fmeum

Can you try rebasing? There are some non-trivial changes to input discovery here that I think you should probably take into consideration. Notably, the most recent change to CppCompileAction was to fix "old" (i.e. Clang Header) modules w.r.t. discoverInputs for the purpose of aspects.

trybka avatar Feb 25 '25 22:02 trybka

Can you try rebasing?

Rebased.

PikachuHyA avatar Feb 26 '25 11:02 PikachuHyA

Ack, thanks. I've re-imported, and re-running our Global Presubmits. I should have results tomorrow (need to run off-peak hours as it invalidates all the caches). Will post an update then.

trybka avatar Feb 27 '25 00:02 trybka

Mailed for review internally -- local presubmits all green. Global presubmit hit a snag and didn't run. Scheduled another one for this evening, will try to check it early in the AM.

trybka avatar Feb 27 '25 20:02 trybka