Summary
When two workspace members each compile a module with the same name, a shared member's compile commands depend on which members the invocation selects. mcpp build --workspace gives the shared member's translation units an explicit -fmodule-file=<name>=<build>/pcm.cache/<package>/<name>.pcm. mcpp build -p <member>, whose graph holds only one of the two providers, finds the module through -fprebuilt-module-path instead. Both invocations use the same build directory, so every switch between them recompiles the shared member and relinks what depends on it. Repeating one selection is a no-op.
Reproduction (mcpp 2026.9.30.2, Linux, llvm@22.1.8)
ws/
mcpp.toml [workspace] members = ["core", "app", "tool"]
shared/m.ixx export module m; export inline int answer() { return 42; }
core/ lib; sources = ["core.cpp", "../shared/m.ixx"]; core.cpp imports m
app/ bin; depends on core
tool/ bin; sources = ["../shared/m.ixx"]; main.cpp imports m
mcpp build --workspace # builds everything
mcpp build -p app # Compiling core, Compiling app
mcpp build -p app # nothing to do
mcpp build --workspace # Compiling core, Compiling app
mcpp build -p app # Compiling core, Compiling app
The build directory is the same for both invocations (target/x86_64-linux-gnu/16872967eb4d901b). In the workspace graph, build.ninja maps the module per provider: -fmodule-file=m=…/pcm.cache/core/m.pcm for core, …/pcm.cache/tool/m.pcm for tool. In the -p app graph, core's commands carry neither mapping.
Where it shows
GalTranslPP 3.1.3: its updater now compiles 3rdParty/3rdModule/boost.ixx, which the core library also compiles. In a mcpp build --workspace compile database, 80 of the core's 82 translation units differ from the ones -p GPPCLI plans; the only difference is -fmodule-file=boost=…/pcm.cache/gpp.core/boost.pcm. On a windows-2025 runner, mcpp run -p GPPCLI after mcpp build --workspace recompiled the core for 3m22s (Sunrisepeak/GalTranslPP run 36725347783). With 3.1.2, which compiled the module in one member, the same step took 5.8 s (run 36710506562).
Expected
A member's compile commands depend on the member and its own dependencies, not on unrelated members of the graph. Then -p shares what --workspace built, as e2e 851 states. Two ways would give this:
- map a package's own modules to its own BMIs in every graph;
- decide the per-provider mapping by what one program links, not by the whole graph.
Summary
When two workspace members each compile a module with the same name, a shared member's compile commands depend on which members the invocation selects.
mcpp build --workspacegives the shared member's translation units an explicit-fmodule-file=<name>=<build>/pcm.cache/<package>/<name>.pcm.mcpp build -p <member>, whose graph holds only one of the two providers, finds the module through-fprebuilt-module-pathinstead. Both invocations use the same build directory, so every switch between them recompiles the shared member and relinks what depends on it. Repeating one selection is a no-op.Reproduction (mcpp 2026.9.30.2, Linux, llvm@22.1.8)
The build directory is the same for both invocations (
target/x86_64-linux-gnu/16872967eb4d901b). In the workspace graph,build.ninjamaps the module per provider:-fmodule-file=m=…/pcm.cache/core/m.pcmfor core,…/pcm.cache/tool/m.pcmfor tool. In the-p appgraph, core's commands carry neither mapping.Where it shows
GalTranslPP 3.1.3: its updater now compiles
3rdParty/3rdModule/boost.ixx, which the core library also compiles. In amcpp build --workspacecompile database, 80 of the core's 82 translation units differ from the ones-p GPPCLIplans; the only difference is-fmodule-file=boost=…/pcm.cache/gpp.core/boost.pcm. On awindows-2025runner,mcpp run -p GPPCLIaftermcpp build --workspacerecompiled the core for 3m22s (Sunrisepeak/GalTranslPP run 36725347783). With 3.1.2, which compiled the module in one member, the same step took 5.8 s (run 36710506562).Expected
A member's compile commands depend on the member and its own dependencies, not on unrelated members of the graph. Then
-pshares what--workspacebuilt, as e2e 851 states. Two ways would give this: