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
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