22//
33// Layout (per docs/26-bmi-cache.md):
44// $MCPP_HOME/bmi/<fingerprint>/deps/<indexName>/<pkgName>@<version>/
5- // gcm.cache/<module>.gcm
5+ // { gcm,pcm} .cache/<module>.{ gcm,pcm}
66// obj/<file>.m.o + <file>.o
77// manifest.txt (sentinel + file list)
88//
@@ -31,20 +31,22 @@ struct CacheKey {
3131 std::string indexName; // "mcpplibs" / "xim" / ...
3232 std::string packageName; // "mcpplibs.cmdline"
3333 std::string version; // "0.0.1"
34+ std::string bmiDirName = " gcm.cache" ; // "gcm.cache" | "pcm.cache"
35+ std::string manifestTag = " gcm" ; // "gcm" | "pcm"
3436
3537 std::filesystem::path dir () const {
3638 return mcppHome / " bmi" / fingerprint / " deps"
3739 / indexName / std::format (" {}@{}" , packageName, version);
3840 }
3941
4042 std::filesystem::path manifestFile () const { return dir () / " manifest.txt" ; }
41- std::filesystem::path gcmDir () const { return dir () / " gcm.cache " ; }
43+ std::filesystem::path bmiDir () const { return dir () / bmiDirName ; }
4244 std::filesystem::path objDir () const { return dir () / " obj" ; }
4345};
4446
4547// File names (basename only) that belong to one dep package's cache entry.
4648struct DepArtifacts {
47- std::vector<std::string> gcmFiles ; // basenames in gcm.cache /
49+ std::vector<std::string> bmiFiles ; // basenames in bmiDir /
4850 std::vector<std::string> objFiles; // basenames in obj/
4951};
5052
@@ -55,14 +57,14 @@ bool is_cached(const CacheKey& key);
5557std::expected<DepArtifacts, std::string>
5658read_manifest (const CacheKey& key);
5759
58- // Copy missing cached files into projectTarget/{gcm.cache ,obj}. Existing
59- // project outputs are left untouched: GCC BMIs may differ byte-for-byte between
60+ // Copy missing cached files into projectTarget/{bmiDirName ,obj}. Existing
61+ // project outputs are left untouched: BMIs may differ byte-for-byte between
6062// equivalent builds, and overwriting them would dirty downstream modules.
6163std::expected<DepArtifacts, std::string>
6264stage_into (const CacheKey& key,
6365 const std::filesystem::path& projectTargetDir);
6466
65- // Copy fresh build outputs from projectTarget/{gcm.cache ,obj} → cache dir
67+ // Copy fresh build outputs from projectTarget/{bmiDirName ,obj} → cache dir
6668// and write manifest.txt last (atomic-ish sentinel).
6769std::expected<void , std::string>
6870populate_from (const CacheKey& key,
@@ -91,9 +93,9 @@ bool copy_one(const std::filesystem::path& from,
9193 return !ec;
9294}
9395
94- std::string serialize_manifest (const DepArtifacts& a) {
96+ std::string serialize_manifest (std::string_view tag, const DepArtifacts& a) {
9597 std::string out = " # Auto-generated by mcpp bmi_cache. Do not edit.\n " ;
96- for (auto & g : a.gcmFiles ) out += std::format (" gcm : {}\n " , g);
98+ for (auto & g : a.bmiFiles ) out += std::format (" {} : {}\n " , tag , g);
9799 for (auto & o : a.objFiles ) out += std::format (" obj: {}\n " , o);
98100 return out;
99101}
@@ -107,7 +109,8 @@ parse_manifest(const std::filesystem::path& p) {
107109 while (std::getline (is, line)) {
108110 while (!line.empty () && (line.back () == ' \r ' || line.back () == ' ' )) line.pop_back ();
109111 if (line.empty () || line[0 ] == ' #' ) continue ;
110- if (line.starts_with (" gcm: " )) a.gcmFiles .push_back (line.substr (5 ));
112+ if (line.starts_with (" gcm: " )) a.bmiFiles .push_back (line.substr (5 ));
113+ else if (line.starts_with (" pcm: " )) a.bmiFiles .push_back (line.substr (5 ));
111114 else if (line.starts_with (" obj: " )) a.objFiles .push_back (line.substr (5 ));
112115 }
113116 return a;
@@ -121,8 +124,8 @@ bool is_cached(const CacheKey& key) {
121124 auto arts = parse_manifest (mf);
122125 if (!arts) return false ;
123126 // Verify every listed file actually exists on disk.
124- for (auto & g : arts->gcmFiles ) {
125- if (!std::filesystem::exists (key.gcmDir () / g)) return false ;
127+ for (auto & g : arts->bmiFiles ) {
128+ if (!std::filesystem::exists (key.bmiDir () / g)) return false ;
126129 }
127130 for (auto & o : arts->objFiles ) {
128131 if (!std::filesystem::exists (key.objDir () / o)) return false ;
@@ -142,23 +145,23 @@ stage_into(const CacheKey& key,
142145 auto arts = parse_manifest (key.manifestFile ());
143146 if (!arts) return std::unexpected (arts.error ());
144147
145- auto projectGcm = projectTargetDir / " gcm.cache " ;
148+ auto projectBmi = projectTargetDir / key. bmiDirName ;
146149 auto projectObj = projectTargetDir / " obj" ;
147150 std::error_code ec;
148- std::filesystem::create_directories (projectGcm , ec);
151+ std::filesystem::create_directories (projectBmi , ec);
149152 std::filesystem::create_directories (projectObj, ec);
150153
151- for (auto & g : arts->gcmFiles ) {
152- auto from = key.gcmDir () / g;
153- auto to = projectGcm / g;
154+ for (auto & g : arts->bmiFiles ) {
155+ auto from = key.bmiDir () / g;
156+ auto to = projectBmi / g;
154157 if (std::filesystem::exists (to, ec)) {
155158 ec.clear ();
156159 continue ;
157160 }
158161 ec.clear ();
159162 if (!copy_one (from, to, ec)) {
160163 return std::unexpected (std::format (
161- " stage gcm '{}': {}" , g, ec.message ()));
164+ " stage bmi '{}': {}" , g, ec.message ()));
162165 }
163166 touch_now (to);
164167 }
@@ -221,25 +224,25 @@ populate_from(const CacheKey& key,
221224 ~LockGuard () { release_lock (fd); }
222225 } guard{ lockFd };
223226
224- auto cacheGcm = key.gcmDir ();
227+ auto cacheBmi = key.bmiDir ();
225228 auto cacheObj = key.objDir ();
226229 std::error_code ec;
227- std::filesystem::create_directories (cacheGcm , ec);
230+ std::filesystem::create_directories (cacheBmi , ec);
228231 std::filesystem::create_directories (cacheObj, ec);
229232
230- auto projectGcm = projectTargetDir / " gcm.cache " ;
233+ auto projectBmi = projectTargetDir / key. bmiDirName ;
231234 auto projectObj = projectTargetDir / " obj" ;
232235
233- for (auto & g : arts.gcmFiles ) {
234- auto from = projectGcm / g;
235- auto to = cacheGcm / g;
236+ for (auto & g : arts.bmiFiles ) {
237+ auto from = projectBmi / g;
238+ auto to = cacheBmi / g;
236239 if (!std::filesystem::exists (from)) {
237240 return std::unexpected (std::format (
238241 " expected build output missing: {}" , from.string ()));
239242 }
240243 if (!copy_one (from, to, ec)) {
241244 return std::unexpected (std::format (
242- " populate gcm '{}': {}" , g, ec.message ()));
245+ " populate bmi '{}': {}" , g, ec.message ()));
243246 }
244247 }
245248 for (auto & o : arts.objFiles ) {
@@ -260,7 +263,7 @@ populate_from(const CacheKey& key,
260263 tmp += " .tmp" ;
261264 {
262265 std::ofstream os (tmp);
263- os << serialize_manifest (arts);
266+ os << serialize_manifest (key. manifestTag , arts);
264267 }
265268 std::filesystem::rename (tmp, key.manifestFile (), ec);
266269 if (ec) {
0 commit comments