openvinotoolkit / openvinotoolkit/npu_compiler

[Build] Windows/MSVC: CMakePresets builds fail with C2855 - shared PCH built without its consumers' conformance flags

Open Beginner friendly
#344 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
MLIR
Stars
100
Forks
50
Avg merge
3h 57m
Merged PRs (30d)
1

Description

Summary

On Windows/MSVC, building develop with the presets in CMakePresets.json fails with
error C2855: command-line option '...' inconsistent with precompiled header, followed by
fatal error C1903. The failure appears once the first add_npu_library target that consumes the
shared PCH is reached.

The cause is a flag-consistency gap introduced when the per-target PCHs were consolidated into a
single shared one.

Environment
  • develop @ 6761af885b8ff54ddf0da5bf8ad44e30746b2f62
  • OpenVINO @ 4089686065a245d648cdd2b99c31884f53cb7a5e (the commit pinned by validation/openvino_config.json)
  • Windows 11, MSVC 19.44.35222 (Build Tools 14.44.35207), CMake 4.2.3, Ninja 1.13.2
  • RelWithDebInfo, ENABLE_FASTER_BUILD=ON
  • ccache is configured as the compiler launcher (the presets set it). The divergence below is in the
    CMake-generated compile commands, so it is present before any launcher runs.
Steps to reproduce
cmake --preset developer-build-relwithdebinfo .
cmake --build build-x86_64/RelWithDebInfo

Two deviations in my own run, neither affecting the flags involved: the binary directory was placed
outside the source tree, and I added -DLLVM_ENABLE_DIA_SDK:BOOL=OFF (not part of the preset — the
Build Tools install here lacks the ATL headers LLVM's DIA support needs). The cache variables were
otherwise the preset's, ENABLE_FASTER_BUILD included.

Actual result

Building npu_compiler_pipelines on a clean develop worktree, 4 translation units fail with 20
C2855 and 4 C1903:

FAILED: [code=2] src/vpux_compiler/src/pipelines/CMakeFiles/npu_compiler_pipelines.dir/compilation_options.cpp.obj
...\src\vpux_compiler\src\pipelines\compilation_options.cpp: error C2855: command-line option '/Zc:referenceBinding' inconsistent with precompiled header
...\src\vpux_compiler\src\pipelines\compilation_options.cpp: error C2855: command-line option '/Zc:hiddenFriend' inconsistent with precompiled header
...\src\vpux_compiler\src\pipelines\compilation_options.cpp: error C2855: command-line option '/Zc:externC' inconsistent with precompiled header
...\src\vpux_compiler\src\pipelines\compilation_options.cpp: error C2855: command-line option '/Zc:externConstexpr' inconsistent with precompiled header
...\src\vpux_compiler\src\pipelines\compilation_options.cpp: error C2855: command-line option '/permissive-' inconsistent with precompiled header
...\src\vpux_compiler\src\pipelines\compilation_options.cpp: fatal error C1903: unable to recover from previous error(s); stopping compilation

Same for developer_config.cpp, options_mapper.cpp and function_statistics_instrumentation.cpp.
In a full build this stops the build partway, once that target is reached.

Root cause

add_npu_library (src/vpux_compiler/cmake/add_npu_library.cmake) applies the strict conformance
options and then attaches the shared PCH:

enable_warnings_as_errors(${name} WIN_STRICT)
if(ENABLE_FASTER_BUILD)
    target_precompile_headers(${name} REUSE_FROM npu_compiler_pch_base)
endif()

enable_warnings_as_errors(... WIN_STRICT) adds /permissive- (plus /WX /W3 /wd4244 /wd4267 and
the /external: set). The anchor target npu_compiler_pch_base
(src/vpux_compiler/src/CMakeLists.txt) is a plain add_library and never calls
enable_warnings_as_errors, so the PCH itself is compiled without them.

MSVC requires a PCH and its consumers to agree on conformance options. Neither command line sets any
/Zc: option explicitly except /Zc:inline, so the four /Zc: options MSVC names are implied by
/permissive- — which the consumers have and the PCH does not.

Comparing the conformance and warning options in the generated compile_commands.json on a clean
develop configure (1 /Yc creator, 1,967 /Yu consumers):

consumer-only : /permissive-  /WX  /wd4244  /wd4267
                /experimental:external  /external:anglebrackets  /external:W0  /GR
creator-only  : none

(The remaining textual differences are only /Yc vs /Yu, /Fo, /Fd and two -I paths.)

Before UD2026.28 (#309), add_npu_library ended with
ov_build_target_faster(${name} PCH_HEADER ${VPU_COMPILER_PCH_FILE}) — a per-target PCH built by the
consuming target with that target's own options, across 53 call sites. Consolidating to one shared
anchor made the anchor's own option set matter, and it does not currently match its consumers'.

Why CI doesn't catch it

ENABLE_FASTER_BUILD appears once in .github: job_build_cid.yml configures with
-D ENABLE_FASTER_BUILD=OFF. The Windows pipeline is windows_2022.ymljob_windows.yml
job_build_cid.yml, and no workflow invokes --preset, so no workflow exercises the PCH path.

The presets go the other way: _npu-default_variables (build-release, build-relwithdebinfo,
build-debug) and _npu-developer_variables (the developer-build-* family) both set
ENABLE_FASTER_BUILD=true. Only _cid-base sets it false. guides/how_to_build.md documents
developer-build-relwithdebinfo for Windows.

Candidate fix
# src/vpux_compiler/src/CMakeLists.txt, inside if(ENABLE_FASTER_BUILD)
ov_build_target_faster(npu_compiler_pch_base PCH_HEADER ${VPU_COMPILER_PCH_FILE})

enable_warnings_as_errors(npu_compiler_pch_base WIN_STRICT)

Verified, applied to a clean develop as the only source change, ENABLE_FASTER_BUILD=ON,
default target, cold build directory, -j 4:

  • 7,466 of 7,515 ninja steps in ~2h53m, zero C2855 anywhere in the log
  • every PCH consumer compiled, including npu_compiler_pipelines — the target that previously
    failed — and openvino_intel_npu_compiler.dll linked
  • the run then stopped on one unrelated target, copy_NPU_tests:
    CMake Error: failed to create symbolic link ...: A required privilege is not held by the client.
    cmake -E create_symlink needs Developer Mode or an elevated shell on Windows, and
    LIT_TESTS_USE_LINKS=ON is also a preset default.
  • reconfiguring that same build directory with LIT_TESTS_USE_LINKS=OFF and resuming completed the
    remaining 119 steps, still with zero C2855

So on Windows the preset currently needs both changes for a clean build; only the first is a PCH
issue.

After the fix the only remaining textual difference is /GR: consumers pass it explicitly, while the
PCH passes neither /GR nor /GR- and so takes the MSVC default, which is /GR. The effective
setting matches.

The fix above is the smallest change. Excluding the PCH from the strict options, or having
add_npu_library and the anchor share a single options helper, may fit the codebase better.

Offer

Would a PR be useful? The change above is ready and the build is confirmed. If this is already known
or being handled internally, let me know and I'll drop it.

I've worked in this repo before (#265, #266, #302). I build on Windows with Lunar Lake / NPU 4000
hardware and can test Windows-side changes.

AI assistance

Drafted with Claude Code — the flag diffing, the root-cause analysis, and this text. I reviewed and
approved it before posting. The build output, the compile_commands.json comparisons, the
reproduction above and the post-fix full build all come from real builds on the machine described.

Not verified: the failure with ccache removed from the compiler launcher, and with the preset invoked
directly rather than via its cache variables. The divergence is in the CMake-generated compile
commands, so it does not depend on the launcher.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/vpux_compiler/src/CMakeLists.txt and compare the shared PCH anchor with src/vpux_compiler/cmake/add_npu_library.cmake, where consumer options are applied. Configure with the developer-build-relwithdebinfo preset and ENABLE_FASTER_BUILD enabled, then build the default target on Windows. Done means the PCH consumers build without C2855 errors; LIT_TESTS_USE_LINKS may need to be disabled for the unrelated symlink issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
cmake
Domain
build-system
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
82/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.