Skip to content

build.c++.modules.tryreuse does not create job-level ordering for .cpp files that import modules from dependency targets #7530

@mmihira

Description

@mmihira

Is your feature request related to a problem? Please describe.

When build.c++.modules.tryreuse is set on a consumer target, cross-target BMI job edges are only created inside build_modules_for_jobgraph (rules/c++/modules/builder.lua), which processes module interface files (.cppm). Regular .cpp implementation files that contain import statements are compiled by the standard object.lua pipeline via on_build_files, which has no connection to those edges.

Describe the solution you'd like

Building of regular c++ files in a c++20 modules project should also be included in job ordering with tryreuse is active so that the compilation job only starts when all its required modules have been compiled.


Claude suggested the following fix, not sure if valid:

When tryreuse is active on a consumer target, the before_build_files phase already accumulates cross-target BMI job edges for .cppm files via _get_jobdeps / the deferred dependent_jobs mechanism. The on_build_files phase (regular .cpp compilation) waits for before_build_files to complete — but only for the current target's own before_build_files group, not for the cross-target BMI jobs that group depends on.

The fix: at the end of build_modules_for_jobgraph, after all reuse edges are resolved, insert a synthetic barrier job (e.g. /modules/reused_bmis_ready) that depends on every cross-target BMI job that was added via is_reused. Then order /begin_build (the start of on_build_files) after this barrier. This ensures all reused BMIs — from any dep target — exist before any regular .cpp object file in the consumer starts compiling, without requiring changes to object.lua.

Describe alternatives you've considered

build.fence on provider targets. The current workaround. Correct, but it fully serializes the provider target before any consumer job can start (including linking), eliminating the fine-grained parallelism that tryreuse is designed to provide.

Additional context

No response

Metadata

Metadata

Assignees

Type

No type

Projects

Status

Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions