Skip to content

Commit 960f0b2

Browse files
committed
prepare.cppm: split into the primary interface and thirteen implementation files
The physical split (design step 4-5 combined, given the time this decomposition has already taken): src/build/prepare.cppm keeps only the module preamble, the exported helper functions (with bodies -- splitting each into a bare declaration plus a definition in a separate exports.cpp was not done; at 2414 lines the file is under the 2500 hard cap without it, so this was deferred rather than risk a mechanical error for no required outcome), and prepare_build's own exported declaration with its default arguments. Everything else moved under src/build/prepare/: state.cppm implementation partition :state -- PrepareState, the five structs P4 needed hoisted, and every phase function's declaration. driver.cpp prepare_build's definition. manifest.cpp P0. toolchain.cpp P1 + P2. toolchain_decision.cpp P5 (split out of toolchain.cpp: P1+P2+P5 together were 2526 lines, over the hard cap). xlings.cpp P3. graph_load.cpp P4a (loadVersionDep). graph.cpp P4b (the worklist engine). features.cpp P6-P8. target_side.cpp P9. scan.cpp P11. plan.cpp P13. Two visibility problems, both from the same cause -- an implementation partition does not implicitly see its module's primary interface the way an implementation unit does, so it must import it explicitly: - The preamble helpers moved out of their anonymous namespace in the previous commit for exactly this reason, but ToolPurpose (a type, not a module-linkage function) still needed an explicit `export`: :state names it in PrepareState's own member list, and a partition only sees what its imports export. - state.cppm added `import mcpp.build.prepare;` for BuildOverrides, BuildContext, PlanNote, CacheMode and TcOrigin, all exported types PrepareState's declaration itself names. Every other file compiled against the split on the first attempt: the extensive state.<name> threading done in every prior commit was already correct, this just gave it its own files. All twelve source files are at or under the 2500-line hard cap; nine are at or under the 2000-line target. prepare.cppm (2414) and three implementation files (target_side.cpp 1968, features.cpp 2052, toolchain.cpp 2136, graph.cpp 2345, plan.cpp 2392) sit between the two because splitting them further was not required to satisfy the cap and each remaining cut point would have needed its own escaping- closure audit. GCC 16.1 builds this cleanly: the primary interface imports no partition, :state is an implementation partition imported only by implementation units, satisfying the constraint verified in .agents/docs/2026-09-27-mcpp-2026.9.27.1-ecosystem-plan.md §4.3. Golden fixture diff against the baseline is empty; mcpp test: 129/129 (root) plus every member with tests (versioning, platform, manifest, toolchain-model, buildmcpp) individually green.
1 parent a65a52c commit 960f0b2

13 files changed

Lines changed: 15257 additions & 14030 deletions

‎src/build/prepare.cppm‎

Lines changed: 59 additions & 14030 deletions
Large diffs are not rendered by default.

‎src/build/prepare/driver.cpp‎

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
module mcpp.build.prepare;
2+
import :state;
3+
4+
import mcpp.build.prepare_inputs;
5+
6+
import std;
7+
import mcpp.targetside;
8+
import mcpp.diag;
9+
import mcpp.build.refusal;
10+
import mcpp.xlings.address_set;
11+
import mcpp.build.version_floor;
12+
import mcpp.home;
13+
import mcpp.platform.axis;
14+
import mcpp.libs.json;
15+
import mcpp.log;
16+
import mcpp.manifest;
17+
import mcpp.source_kind;
18+
import mcpp.modgraph.glob;
19+
import mcpp.modgraph.graph;
20+
import mcpp.modgraph.scanner;
21+
import mcpp.modgraph.validate;
22+
import mcpp.toolchain.clang;
23+
import mcpp.toolchain.hostflags; // the compile-token producer the package std module reuses
24+
import mcpp.toolchain.cenv; // [c-abi] declaration → compiler configuration (design 2026-09-18)
25+
import mcpp.toolchain.cenv_probe; // [c-abi] declaration is checked, not trusted (design §3.2)
26+
import mcpp.toolchain.predefines; // the macros this engine defines: contract and emission in one module
27+
import mcpp.toolchain.cppfly;
28+
import mcpp.toolchain.detect;
29+
import mcpp.toolchain.dialect;
30+
import mcpp.toolchain.fingerprint;
31+
import mcpp.toolchain.msvc;
32+
import mcpp.toolchain.registry;
33+
import mcpp.toolchain.linkmodel;
34+
import mcpp.toolchain.gcc;
35+
// For `resolve_version_match` / `list_installed_versions`: a bare compiler
36+
// family named by the dependency graph resolves to a concrete version through
37+
// exactly the path `mcpp toolchain default <family>` uses.
38+
import mcpp.toolchain.lifecycle;
39+
import mcpp.toolchain.stdmod;
40+
import mcpp.freestanding.target; // the target sysroot layout (libdir)
41+
import mcpp.freestanding.linkline; // the ISA profile, for the std module command
42+
import mcpp.toolchain.post_install;
43+
import mcpp.toolchain.abi;
44+
import mcpp.toolchain.triple;
45+
import mcpp.build.linkage_form; // #519 — which form each dependency takes
46+
import mcpp.build.plan;
47+
import mcpp.build.schedule.policy;
48+
import mcpp.build.flags; // compute_flags — the per-role contracts (#418)
49+
import mcpp.build.distribution; // dist::Role / dist::Contract to_string
50+
import mcpp.platform.capacity; // the host fallback handed to schedule::decide
51+
import mcpp.build.graph_shape; // #407: the graph says which mode wrote it
52+
import mcpp.build.runtime_validation; // declared artifact -> identity verdict
53+
import mcpp.build.cache_key;
54+
import mcpp.pack.abi_tag; // the tag a prebuilt dependency is checked against
55+
import mcpp.pack.prebuilt; // …and the check itself
56+
import mcpp.pack.stage_tree; // where `${mcpp.stage_dir}` points, and its manifest
57+
import mcpp.build.build_program;
58+
import mcpp.build.directives; // directive table: mark / fold_private_tail
59+
import mcpp.build.tool_store; // #355 host tools: store layout + key + overrides
60+
import mcpp.build.dep_graph; // queries over the resolved edge graph
61+
import mcpp.build.provisions; // #359 build-time provisions: table + propagation
62+
import mcpp.build.resources; // #365 Windows resources: synthesise / scan / find rc
63+
import mcpp.build.backend; // BuildOptions for the tool sub-build
64+
import mcpp.build.ninja; // make_ninja_backend — driving that sub-build
65+
import mcpp.lockfile;
66+
import mcpp.config;
67+
import mcpp.xlings;
68+
import mcpp.xlings.subos_info;
69+
import mcpp.xlings.runtime_selection;
70+
import mcpp.runtime.binding;
71+
import mcpp.platform.runtime_search;
72+
import mcpp.toolchain.post_install;
73+
import mcpp.platform;
74+
import mcpp.platform.macos;
75+
import mcpp.build.runner_lookup;
76+
import mcpp.fetcher;
77+
import mcpp.fetcher.progress;
78+
import mcpp.pm.resolver;
79+
import mcpp.pm.index_spec;
80+
import mcpp.pm.index_contract;
81+
import mcpp.pm.index_route;
82+
import mcpp.pm.index_refresh;
83+
import mcpp.pm.mangle;
84+
import mcpp.pm.compat;
85+
import mcpp.pm.dep_spec;
86+
import mcpp.pm.dependency_selector;
87+
import mcpp.pm.lock_io;
88+
import mcpp.version_req;
89+
import mcpp.ui;
90+
import mcpp.log;
91+
import mcpp.wire; // Severity, for PlanNote (#699 item 2, E3)
92+
import mcpp.fallback.install_integrity;
93+
import mcpp.bmi_cache;
94+
import mcpp.project;
95+
96+
namespace mcpp::build {
97+
98+
std::expected<BuildContext, std::string>
99+
prepare_build(bool print_fingerprint,
100+
bool includeDevDeps,
101+
std::vector<mcpp::manifest::Target> extraTargets,
102+
BuildOverrides overrides) {
103+
PrepareState state(print_fingerprint, includeDevDeps,
104+
std::move(extraTargets), std::move(overrides));
105+
pending_flag_words_notes().clear();
106+
107+
if (auto r = phase0_manifest_and_workspace(state); !r) return std::unexpected(r.error());
108+
if (auto r = phase1_toolchain_spec_and_axes(state); !r) return std::unexpected(r.error());
109+
if (auto r = phase2_define_toolchain_resolver(state); !r) return std::unexpected(r.error());
110+
if (auto r = phase3_xlings_before_graph(state); !r) return std::unexpected(r.error());
111+
if (auto r = phase4a_graph_load(state); !r) return std::unexpected(r.error());
112+
if (auto r = phase4b_graph_worklist(state); !r) return std::unexpected(r.error());
113+
if (auto r = phase5_toolchain_after_graph(state); !r) return std::unexpected(r.error());
114+
if (auto r = phase6_features_and_host_tools(state); !r) return std::unexpected(r.error());
115+
if (auto r = phase9_target_side(state); !r) return std::unexpected(r.error());
116+
if (auto r = phase11_scan(state); !r) return std::unexpected(r.error());
117+
118+
return phase13_finish(state);
119+
}
120+
121+
122+
} // namespace mcpp::build

0 commit comments

Comments
 (0)