现象
对象/扫描产物路径仅由「目标名 + 源文件父目录名 + 文件名」构成,不同目录下的同名源文件(且父目录同名)发生 ninja 规则冲突,构建直接失败:
ninja: error: build.ninja:58: multiple rules generate obj/repro_src/util.cpp.ddi
最小复现(mcpp 0.0.95 / 0.0.96,linux-x86_64)
repro/
├── mcpp.toml
├── a/src/util.cpp # int fa(){return 1;}
├── b/src/util.cpp # int fb(){return 2;}
└── src/main.cpp # int fa(); int fb(); int main(){return fa()+fb()-3;}
[package]
name = "repro"
version = "0.1.0"
[build]
sources = ["a/src/util.cpp", "b/src/util.cpp"]
[targets.repro]
kind = "bin"
main = "src/main.cpp"
mcpp build →
ninja: error: build.ninja:58: multiple rules generate obj/repro_src/util.cpp.ddi
build.ninja 中两条 cxx_scan 规则输出同一路径:obj/repro_src/util.cpp.ddi(a/src 与 b/src 的父目录都叫 src,被折叠)。
影响
modules/<mod>/src/*.cpp 是 C/C++ 大型项目的标准布局(OpenCV、LLVM 等)。OpenCV 5.0 的 modules/imgproc/src/utils.cpp 与 modules/imgcodecs/src/utils.cpp 即刻冲突——这是把 OpenCV 5.0 以全源码直编形态引入 mcpp-index(compat.ffmpeg 同款形态)时撞上的。FFmpeg 侥幸不受影响只因它是 per-lib 扁平目录(libavcodec/utils.c 的父目录名互不相同)。
当前 workaround:为每个 TU 生成唯一名转发 stub(gen/tu/<group>/<path__mangled>.cpp #include 原文件)——457 个 stub 文件,纯噪音。
期望
对象路径镜像源文件相对路径(或加入路径 hash),如 obj/<target>/a/src/util.cpp.o 与 obj/<target>/b/src/util.cpp.o。
现象
对象/扫描产物路径仅由「目标名 + 源文件父目录名 + 文件名」构成,不同目录下的同名源文件(且父目录同名)发生 ninja 规则冲突,构建直接失败:
最小复现(mcpp 0.0.95 / 0.0.96,linux-x86_64)
mcpp build→build.ninja 中两条 cxx_scan 规则输出同一路径:
obj/repro_src/util.cpp.ddi(a/src 与 b/src 的父目录都叫src,被折叠)。影响
modules/<mod>/src/*.cpp是 C/C++ 大型项目的标准布局(OpenCV、LLVM 等)。OpenCV 5.0 的modules/imgproc/src/utils.cpp与modules/imgcodecs/src/utils.cpp即刻冲突——这是把 OpenCV 5.0 以全源码直编形态引入 mcpp-index(compat.ffmpeg 同款形态)时撞上的。FFmpeg 侥幸不受影响只因它是 per-lib 扁平目录(libavcodec/utils.c的父目录名互不相同)。当前 workaround:为每个 TU 生成唯一名转发 stub(
gen/tu/<group>/<path__mangled>.cpp#include原文件)——457 个 stub 文件,纯噪音。期望
对象路径镜像源文件相对路径(或加入路径 hash),如
obj/<target>/a/src/util.cpp.o与obj/<target>/b/src/util.cpp.o。