Skip to content

Commit 8889f3c

Browse files
committed
fix(plan): handle intra-package basename collisions + bump to 0.0.5
The 0.0.4 collision fix namespaced by package name, but two source files in the SAME package with the same basename (e.g. ftxui's dom/color.cpp vs screen/color.cpp) still collided. Fix: when basenameCount > 1, the object subdirectory now uses `<sanitized-pkg>_<parent-dir>/<file>` instead of just `<sanitized-pkg>/<file>`. This handles both cross-package (multi- version mangling) and intra-package (ftxui, etc.) collisions.
1 parent 2c72e25 commit 8889f3c

3 files changed

Lines changed: 17 additions & 12 deletions

File tree

mcpp.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mcpp"
3-
version = "0.0.4"
3+
version = "0.0.5"
44
description = "Modern C++ build & package management tool"
55
license = "Apache-2.0"
66
authors = ["mcpp-community"]

src/build/plan.cppm

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,18 +96,17 @@ BuildPlan make_plan(const mcpp::manifest::Manifest& manifest,
9696
plan.stdBmiPath = stdBmiPath;
9797
plan.stdObjectPath = stdObjectPath;
9898

99-
// 1a. Detect basename collisions across packages (multi-version mangling
100-
// stages a second copy of the same dep, so `parse.cppm` and friends
101-
// can show up twice). For colliding files we namespace the object
102-
// path by the unit's owning package so `obj/<file>.o` doesn't get
103-
// two `build` rules.
99+
// 1a. Detect basename collisions (both cross-package AND intra-package:
100+
// ftxui ships dom/color.cpp + screen/color.cpp, for instance).
101+
// For colliding files the object path gets a per-unit prefix
102+
// derived from `<pkg>/<parent-dir>` so collisions are impossible.
104103
std::map<std::string, int> basenameCount;
105104
for (auto idx : topoOrder) {
106105
basenameCount[object_filename_for(graph.units[idx].path)]++;
107106
}
108-
auto sanitize_pkg = [](const std::string& s) {
107+
auto sanitize = [](const std::string& s) {
109108
std::string out; out.reserve(s.size());
110-
for (char c : s) out += (c == '.' ? '_' : c);
109+
for (char c : s) out += (c == '.' || c == '/' ? '_' : c);
111110
return out;
112111
};
113112

@@ -117,9 +116,15 @@ BuildPlan make_plan(const mcpp::manifest::Manifest& manifest,
117116
CompileUnit cu;
118117
cu.source = u.path;
119118
const auto fname = object_filename_for(u.path);
120-
if (basenameCount[fname] > 1 && !u.packageName.empty()) {
121-
cu.object = std::filesystem::path("obj")
122-
/ sanitize_pkg(u.packageName) / fname;
119+
if (basenameCount[fname] > 1) {
120+
// Use <sanitized-pkg>/<parent-dir-name> as prefix to handle
121+
// both cross-package (multi-version mangling) and intra-package
122+
// (e.g. ftxui dom/color.cpp vs screen/color.cpp) collisions.
123+
auto parentDir = u.path.parent_path().filename().string();
124+
auto prefix = u.packageName.empty()
125+
? parentDir
126+
: sanitize(u.packageName) + "_" + parentDir;
127+
cu.object = std::filesystem::path("obj") / prefix / fname;
123128
} else {
124129
cu.object = std::filesystem::path("obj") / fname;
125130
}

src/toolchain/fingerprint.cppm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import mcpp.toolchain.detect;
1818

1919
export namespace mcpp::toolchain {
2020

21-
inline constexpr std::string_view MCPP_VERSION = "0.0.4";
21+
inline constexpr std::string_view MCPP_VERSION = "0.0.5";
2222

2323
struct FingerprintInputs {
2424
Toolchain toolchain;

0 commit comments

Comments
 (0)