When --deduplicate collapses the multiple compile entries for a source file that is built in more than one project, MergeEntries treats the PCH switches ( /Fp , /Yu , /Yc ) as generic "other" flags and unions them. Because each project emits a distinct /Fp , the merged entry ends up carrying multiple conflicting /Fp switches. /Fp is a single-valued, last-wins cl.exe switch (it names the PCH file), so the resulting command line cannot be honored coherently by a compiler or an IntelliSense engine.
Repro
- A repo where source files are compiled in multiple projects with PCH (e.g. Windows Terminal OpenConsole.slnx ).
- Run the extractor with dedup:
dotnet run --project msbuild-extractor-sample.csproj -c Release --
--solution \OpenConsole.slnx -c Debug -a x64
--deduplicate --prefer-configuration Debug --prefer-platform x64
--msbuild-path <...> --vc-tools-install-dir <...> --cl-path <...>
-o .mscppls\compile_commands.json
- Inspect the output for entries with more than one /Fp .
Expected
Each deduplicated entry has at most one PCH identity: a single /Fp and its matching /Yu or /Yc , taken from the preferred (config/platform-winning) entry, consistent with how IsPreferred already selects the base command.
Actual
Merged entries carry multiple distinct /Fp paths. In a Windows Terminal Debug/x64 extraction (extractor msbuild-extractor-sample/1.0.0 ): 562 deduplicated entries, 53 entries with more than one /Fp , max 5 on a single entry. Worst case is a PCH-create source:
precomp.cpp (/Yc) 5 x /Fp:
/Fp...\Host.EXE\OpenConsole.pch
/Fp...\Host.FuzzWrapper\OpenConsoleFuzzer.pch
/Fp...\Host\ConhostV2Lib.pch
/Fp...\Host.Tests.Unit\Conhost.Unit.Tests.pch
/Fp...\Host.unittest\ConhostV2Lib.unittest.pch
When --deduplicate collapses the multiple compile entries for a source file that is built in more than one project, MergeEntries treats the PCH switches ( /Fp , /Yu , /Yc ) as generic "other" flags and unions them. Because each project emits a distinct /Fp , the merged entry ends up carrying multiple conflicting /Fp switches. /Fp is a single-valued, last-wins cl.exe switch (it names the PCH file), so the resulting command line cannot be honored coherently by a compiler or an IntelliSense engine.
Repro
dotnet run --project msbuild-extractor-sample.csproj -c Release --
--solution \OpenConsole.slnx -c Debug -a x64
--deduplicate --prefer-configuration Debug --prefer-platform x64
--msbuild-path <...> --vc-tools-install-dir <...> --cl-path <...>
-o .mscppls\compile_commands.json
Expected
Each deduplicated entry has at most one PCH identity: a single /Fp and its matching /Yu or /Yc , taken from the preferred (config/platform-winning) entry, consistent with how IsPreferred already selects the base command.
Actual
Merged entries carry multiple distinct /Fp paths. In a Windows Terminal Debug/x64 extraction (extractor msbuild-extractor-sample/1.0.0 ): 562 deduplicated entries, 53 entries with more than one /Fp , max 5 on a single entry. Worst case is a PCH-create source:
precomp.cpp (/Yc) 5 x /Fp:
/Fp...\Host.EXE\OpenConsole.pch
/Fp...\Host.FuzzWrapper\OpenConsoleFuzzer.pch
/Fp...\Host\ConhostV2Lib.pch
/Fp...\Host.Tests.Unit\Conhost.Unit.Tests.pch
/Fp...\Host.unittest\ConhostV2Lib.unittest.pch