windows: fix native MSVC/Vulkan build portability - #640
Conversation
a5e31c8 to
45550dc
Compare
localai-org-maint-bot
left a comment
There was a problem hiding this comment.
This portability PR is not reviewable as a merge candidate while its own portability and build gates are red. The current head fails windows-msvc-cpu, windows-msvc-vulkan, both Linux build-test jobs, Vulkan verification, both sanitizer jobs, commit-protocol-tag, agent-record, device-leakage, and documentation-checkpoint. Please rebase onto current main, add the required FOLLOWING_AGENTS_PROTOCOL trailer to every PR commit, and push a head where the intended MSVC/Vulkan fixes pass their target jobs. After that, the large mechanical compatibility diff can be reviewed against a meaningful green signal.
|
Thanks for tackling this, and welcome — the Windows arm being red on every PR is a real problem and the centralising instinct here is the right one. Four hand-rolled I have to be straight with you though: as it stands this PR does not turn the Windows jobs green, and it breaks the Linux build in two places. Details below so you can judge what to keep. The Windows jobs go redder, not greenerBoth die in The current baseline red is three errors, all The two new ones are your Important, and not your fault: the reason your native Windows validation passed while CI fails is that your host build never runs this gate. And separately — even a perfect version of this PR could not have turned Two Linux breaks, both reproduced locally1. 2. Missing include. Three hunks I'd drop
Also inert: the What I'd keepThe SequencingThere are four other Windows PRs in flight and this collides with them. #524 hard-conflicts — you both edit My suggestion: let #677 and #584 land, then bring this back split into (a) the shared One housekeeping note, and a normal thing for a first contribution: commits need a bare |
42f0434 to
15aa963
Compare
…the C++ compile (#774) (#795) Closes #774. `check-windows-portability.py:1710` asserted the MSVC warning policy with a SUBSTRING test: `if not all(token in warnings for token in ("/W4", "/WX"))`. `"/WX" in "/WX-"` is True, and `/WX-` is MSVC's spelling for DISABLE warnings-as-errors -- so the gate was blind to its own inversion. Measured against PR #640 commit 74ba382, which shipped exactly that: `/WX-` on the CXX arm, with the only bare `/WX` left on $<COMPILE_LANGUAGE:OBJCXX> -- Objective-C++, the Metal backend, which never compiles under MSVC. The checker passed it. Two further blindnesses fell out of the same `in`, both found while scoping and neither in the issue: `/W44996` answers for `/W4`, and CMakeLists.txt:30's `#` comment contains the literal `/W4 /WX`, satisfying the entire policy on its own -- deleting every real flag would still have passed. The repair is a token-boundary match evaluated over flags reduced to what can reach an MSVC C/C++ TU (comments stripped, genexes naming only non-C/C++ languages blanked in place), plus refusal of the negating spellings `/WX-`, `/W0`, `/w`. Sibling evasions argued OUT in the spec rather than silently swept in: COMPILE_WARNING_AS_ERROR OFF (CMake only uses it to decide whether IT adds a flag; it does not remove a literal /WX from target_compile_options) and blanket /wd#### (narrows what /W4 reports, does not invert it; "how many is too many" is an undecided threshold). `/W0` and `/w` are IN because they are the disable spellings of /W4 itself. RED before, same test file against base and head checkers: 6 failed, 1 passed E AssertionError: 0 == 0 : Windows portability contract OK That message is the finding -- the gate reporting "contract OK" on a tree whose C++ arm says /WX-. The single base pass is the inverse pin, so the fix is not merely stricter about everything. GREEN after: 7 passed, 9 subtests. Also carries a repair it did not cause: tests/scripts/test_check_windows_ portability.py has been RED on main since e8a9e74 (#680's stale mutation anchor -- the mutation targets the first `$calls.Add(` in the file, which since #512/#583 lives in a different function). check-pr-size's evidence contract runs the whole recognized module and requires it green at HEAD, so nothing could land in that file until this was fixed. The mutation is now anchored to the governed occurrence with uniqueness asserted; #680 stays open for its other half. Full tests/scripts: 8 failed / 1368 passed, all eight reproduced BY NAME on a pristine origin/main worktree. CI: merged with checks still queued -- the runner pool has been saturated for hours and no job started on this head. Every gate runnable locally is green, including check-pr-size's own re-execution of the base-red/head-green evidence in an isolated worktree, which is the authoritative form of that proof.
|
Re-reviewed against current
Two things are left, and they are packaging rather than code. 1.
|
bbd858d to
cf44751
Compare
|
Thank you for this, and sorry it has sat so long — the delay is on us, and it What changed underneath it. Verified on
So the portability value this PR was carrying has largely been paid elsewhere, The blocking findings, in order of weight
What is genuinely good and worth keeping. Your commit trailers are the only What we would merge today. Roughly a 15-file PR: the CMake packaging/link Also worth knowing: five test cases here become |
cf44751 to
bcf1df0
Compare
|
Rebased onto current What changed since the earlier review:
The branch now locally passes the targeted gates:
Would appreciate a re-review when convenient. |
Keep the reviewed Windows/MSVC portability work and drop the now-obsolete branch bulk. Preserve the shared-library packaging/link repair, the header-free shared-library smoke test, the portable temp-path and sparse file helpers used by the MiniMax-H3 / KV-offload / C API tests, and the internal platform_compat shim under src/vllm/support. Route tests through the existing internal src include path, keep the env seam on the existing tests/support/test_env.h path, and update laguna-gen to use the minimal internal helper for the native Windows env override. Issue: mudler#503 Identity: ENG-RELEASE-WINDOWS FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:GPT-5 [Codex]
…f every test target
Three review repairs on top of the reviewed MSVC subset. No behavior change on any
path that runs today.
`examples/laguna_gen` is reverted to `setenv(..., 0)` and loses the private
`-I ${CMAKE_SOURCE_DIR}/src`. The explicit `getenv(...) == nullptr` guard it
replaced that with was semantically identical, but reaching
`src/vllm/support/platform_compat.h` made laguna_gen the first example to include
a header that exists ONLY under `src/` — every prior breach on its
`scripts/example-abi-allowlist.txt` row is an `include/` header, and the allowlist
calls a private `-I` into `src/` "the deepest breach" where it records one for
`quant_gemm_bench`. `scripts/check-surface-coverage.py` parses `#include` lines and
is blind to `-I` flags, so no gate would have caught it. `laguna-gen` is not among
the seven targets `scripts/build-windows-release.ps1:372-382` builds, so this
bought nothing on Windows.
`vllm_cpp_add_test` no longer grants `${CMAKE_SOURCE_DIR}/src` to every test.
`tests/CMakeLists.txt` already carries 123 explicit per-target grants; a blanket
one in the helper converts that deliberate opt-in into a repo-wide default. The
five suites that actually reach `platform_compat.h` get it by name instead
(`test_capi` already had one). No header name under `tests/` collides with one
under `src/`, so this was not breaking anything — it was simply wider than the
change needs.
`SetEnvVar`'s empty-value divergence is documented rather than silently carried:
`_putenv_s(name, "")` REMOVES the variable where POSIX `setenv(name, "", 1)`
defines it empty. No caller passes an empty value, so normalising would be
unexercised code; the comment records the contract and points at the same rule
`tests/support/test_env.h` already states for the test-side seam.
EXCEPTION, argued rather than waived: `documentation-checkpoint` refuses this
commit because `examples/CMakeLists.txt` is in `USER_USAGE_FILES`, so any edit to
it owes `docs/USAGE.md`. This commit REVERTS an example back to what `main`
already has -- the net diff under `examples/` against `origin/main` is empty --
so there is no user-facing fact for `docs/USAGE.md` to gain, and writing one
would make the page describe a change that no longer exists. This is the shape
recorded as mudler#515: "check-doc-checkpoint treats every root CMakeLists.txt edit as
a usage change, so adding a source file demands a docs/USAGE.md edit that has
nothing true to say". mudler#1086 narrowed the sibling `feature_surface` trigger from a
path to a registration-set change; `USER_USAGE_FILES` still keys off the path.
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: ClaudeCode:claude-opus-5 [ClaudeCode]
bcf1df0 to
eb5ab03
Compare
Removes POSIX-only constructs from the test and loader paths that MSVC cannot
compile, behind one small internal shim, so the Windows target list can widen
past the seven binaries
scripts/build-windows-release.ps1:372-382builds today.src/vllm/support/platform_compat.h(63 lines) carries five inline helpers withWindows and POSIX arms:
HostPageSize,CurrentProcessId,FileDescriptorFromFile,TruncateFileandSetEnvVar.HostPageSizeis theone with a production caller —
safetensors_reader.cpp:285now delegates to it,byte-for-byte behaviour-preserving inside the pre-existing
#if !defined(_WIN32).The other four are reached from tests only; they are recorded as such rather than
claimed as shipped capability.
SetEnvVaris deliberately NOT normalised on an empty value:_putenv_s(name, "")removes the variable where POSIX
setenv(name, "", 1)defines it empty. No callerpasses an empty value, so normalising would be unexercised code. The header records
the contract, matching the rule
tests/support/test_env.halready states for thetest-side seam.
Seven test suites lose their POSIX-isms:
::mkdirbecomesstd::filesystem::create_directories,::rmdirbecomesfs::remove,::getpidbecomes
CurrentProcessId, andtest_minimax_h3_video_fold.cppreplaces astd::system("rm -rf '" + root + "'")— a shell-injection-shaped construct on apath — with
fs::remove_all.tests/capi/test_capi.cpproutes its::unsetenvthrough the existing
tests/support/test_env.hseam rather than a new one.tests/capi/test_dlopen.cppgains aLoadLibraryA/GetProcAddressabstractionalongside
dlopen/dlsym, and fixes a latent bug on the path we run every day:the old
INFO("dlopen error: ", (dlerror() != nullptr ? dlerror() : ""))calleddlerror()twice, and the first call consumes and clears the error, so on a realfailure the ternary streamed the second call's
nullptras aconst char*.LastSharedLibraryError()reads it once.CMakeLists.txtgivesvllm_sharedanARCHIVE_OUTPUT_NAME. Without it,install(TARGETS vllm vllm_shared ARCHIVE DESTINATION ...)installs the sharedtarget's MSVC import library and the static archive both as
vllm.lib, and oneoverwrites the other. No-op on ELF and Mach-O, where a SHARED target has no
ARCHIVE artifact. This is the one piece here that fixes a defect rather than
preparing for one.
Scope, stated plainly
None of these files is built by either Windows CI lane today, so this does not
move #584 and does not turn
windows-msvc-*green — that lane now compiles,links
vllm-server.exeand runs its tests, and dies at #584's0xC0000409runtime crash. What lands here is the prerequisite removal of POSIX-isms, plus
the
vllm.libcollision fix and thedlerror()repair.Maintainer changes on top
Three, applied while landing, none altering behaviour:
examples/laguna_genis reverted tomain's version and loses a private-I ${CMAKE_SOURCE_DIR}/src. Reachingplatform_compat.hwould have made itthe first example to include a header existing only under
src/; every priorentry on its
scripts/example-abi-allowlist.txtrow is aninclude/header,and
check-surface-coverage.pyparses#includelines and is blind to-Iflags, so no gate would have caught it.
laguna-genis not built on Windows,so it bought nothing there.
vllm_cpp_add_testno longer grants${CMAKE_SOURCE_DIR}/srcto every test.The file already carries 123 explicit per-target grants; the five suites that
actually reach the shim get it by name.
SetEnvVar's empty-value divergence is documented in the header.Issue: #503
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: ClaudeCode:claude-opus-5 [ClaudeCode]