build: make the tree compile on gcc 16, and add a CI lane so it stays that way - #945
Conversation
localai-org-maint-bot
left a comment
There was a problem hiding this comment.
The GCC 16 lane is useful, but the current head introduces a Windows portability regression while fixing the Linux one.
All five source changes add <unistd.h> unconditionally. MSVC does not provide that header, and these targets are part of the Windows build/test surface. Current main already fixed server_main.cpp with the portable split (<process.h> under _WIN32, POSIX handling otherwise), so rebasing the branch will also collide with or supersede that part of this diff. The four loader tests still call ::getpid() and need the same portable treatment (or a shared cross-platform process-ID helper), not an unconditional POSIX include.
The branch is currently 18 commits behind main and has no checks reported. Please rebase, preserve only the still-needed GCC 16 fixes, make the process-ID use portable on Windows, and let the new GCC lane plus the Windows lanes run on the updated head. I can re-review that result.
7389d26 to
ad01eb2
Compare
localai-org-maint-bot
left a comment
There was a problem hiding this comment.
Re-reviewing the updated head: the server include is now correctly guarded, but the original Windows blocker remains in all four loader tests. Each still includes <unistd.h> unconditionally and calls ::getpid(), so both Windows lanes fail. The new GCC 16 lane also fails, along with the documentation and commit-protocol gates.
Please apply the same portable process-ID treatment to the four tests (or use a shared helper), then resolve the actual GCC 16 compiler error from the failed log and update the required repository records/protocol metadata. The branch is mergeable now, but it is not ready while these real gates remain red.
…it that way Six files used a POSIX symbol without including its header and compiled only because an older libstdc++ pulled the header in transitively. gcc 16 does not, so they fail. One is src/vllm/entrypoints/openai/server_main.cpp, i.e. a SHIPPED binary that does not build on a current distro. This is the second time this exact break has landed. Three files were fixed after a gfx1151 report on mudler#41; the pattern came back in five more, because every Linux CI lane installs the distro g++ (gcc 13 on ubuntu-latest) and no lane uses anything newer. A point fix does not hold, so this adds the missing coverage rather than only the includes: * build-newest-gcc: a COMPILE-ONLY lane in the gcc:16 container, tests configured ON so the test tree is compiled too. It deliberately does not run ctest -- build-test-cpu already owns execution, and this lane exists to catch compile-time portability for roughly one extra build per PR. * tests/support/process_id.h: ONE portable process id, next to the existing test_env.h that exists for the same reason (mudler#603). The tests name temporary directories after the process; ::getpid() is POSIX and MSVC ships no <unistd.h>, so the naive include fixes gcc 16 and breaks both windows-msvc lanes. A per-file #ifdef would be copied into the next loader test exactly as the broken idiom was, so the portable spelling lands once. * cmake/CompilerWarnings.cmake: on gcc >= 16 only, -Warray-bounds is reported but no longer fatal. gcc 16 emits it inside libstdc++ and vendored nlohmann for correct code, and no change to the calling code avoids it: after inlining, _Sp_counted_base::_M_release() is identical for every shared_ptr type, so GCC attributes one instantiation's destructor to another's allocation size. libstdc++ carries its own #pragma suppressions around that destructor; upstream is GCC PR tree-optimization/122197. gcc <= 15 is unchanged and still fails the build on a real out-of-bounds. * examples/ltx2_gen/main.cpp: the retake knobs become a NAMED array instead of a braced-init-list iterated in place, which is the second thing the lane found. Both forms are correct -- that backing array IS lifetime-extended for the loop -- but the in-place form draws -Wdangling-reference on gcc 16. The named array has automatic storage, so no reference binds to a temporary and the false positive cannot arise; nothing is suppressed. Noted because it cost a build to learn: making the LOOP VARIABLE a copy does not help, the diagnostic is about the range reference rather than the element. * src/vllm/entrypoints/openai/server_main.cpp: the include sits inside the file's existing non-Windows block rather than at the top, because MSVC ships no <unistd.h>. That hunk is Ettore Di Giacinto's, from the review of this pull request, folded into this commit rather than left standing alone: check-doc-checkpoint requires every commit touching src/vllm/entrypoints/ to update docs/USAGE.md, and it was repairing a regression this commit had introduced in the first place. * docs/USAGE.md: a Host compilers section stating which compilers build the tree and what the gcc 16 warning policy is. Required by check-doc-checkpoint, which classifies src/vllm/entrypoints/ as a user-facing surface and has no bypass by design. Verified on gcc 16.1.1 (Arch): full CPU configure + build with tests ON, no command-line workaround, 0 errors. The workflow file itself is NOT verified locally -- a GitHub Actions lane cannot be executed off the forge -- but its first run on this pull request already earned its keep: it found a sixth file (::sysconf in qwen3_5.cpp) that no other lane can see. Windows is NOT verified here either: there is no MSVC on this machine, so the two windows-msvc lanes on this pull request are the first execution of the portable header. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: Claude-Code:claude-opus-5 [Claude Code] Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
`build-newest-gcc` failed on the very pull request that adds it, which is the
lane working rather than the lane breaking:
src/vllm/model_executor/models/qwen3_5.cpp:5296:27: error: '::sysconf' has
not been declared; did you mean 'swscanf'?
src/vllm/model_executor/models/qwen3_5.cpp:5296:35: error: '_SC_PAGESIZE'
was not declared in this scope
`g++ (GCC) 16.2.0`, container `gcc:16`. This is the class the lane exists for,
one file further than the five this PR already repairs, and a different symbol
pair from the same header — so a `::getpid` sweep would not have found it.
`<sys/mman.h>` was already included for the same block and carried the file this
far on gcc 13 through a transitive declaration.
The include goes inside the `#if defined(__unix__)` guard the file already has at
the top, which is the same condition guarding the `::sysconf` call at `:5294`.
`qwen3_5.cpp` is not in `REQUIRED_CPP` in `scripts/check-windows-portability.py`
and is not built by `scripts/build-windows-release.ps1`, so no Windows arm sees
it either way; `check-windows-portability.py` returns
`Windows portability contract OK`.
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: ClaudeCode:claude-opus-5 [ClaudeCode]
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
f023e21 to
316389d
Compare
::getpid()without<unistd.h>compiles on the distrog++every Linux laneinstalls (gcc 13 on
ubuntu-latest) because a transitive include supplies thedeclaration. On gcc 16 it does not, and five files in this tree rely on it —
one of them
src/vllm/entrypoints/openai/server_main.cpp, a shipped binary.Each gains the include it actually needs.
build-newest-gccis a compile-only lane oncontainer: gcc:16, so the classcannot come back silently. It deliberately does not run ctest —
build-test-cpuowns execution — which keeps it to roughly one extra compile per pull request.
The image was confirmed to exist (
library/gcc:16, pushed 2026-08-12), so thelane will not fail on a missing tag.
cmake/CompilerWarnings.cmakestops treating-Warray-boundsas fatal onGNU >= 16 only. That diagnostic fires inside libstdc++ and the vendored nlohmann
json for code that is correct; making the vendored headers SYSTEM does not
suppress it, because the reported location lands in our own translation unit
after inlining. The warning stays VISIBLE, and every compiler at 15 or below is
unchanged and still fails the build on a genuine out-of-bounds.
Maintainer change on top
The
server_main.cppinclude was added unguarded, among the plain includes.That file is one of five in
REQUIRED_CPPinscripts/check-windows-portability.py, whosePOSIX_PATTERNS[0]matches a bare#include <unistd.h>on any line reachable from a Windows build — so as writtenit would newly red both
windows-msvc-*lanes, the opposite of this PR's intent.Dropping it would also have been wrong: the
::getpid()that needs it (:158)is guarded by
#if defined(VT_BENCH_PROFILE_CONTROL) && !defined(_WIN32), andthat macro is set under
VLLM_CPP_CUDAplus the opt-inVLLM_CPP_BENCH_PROFILE_CONTROL. A CUDA build with the profiler enabled, ongcc 16, genuinely needs the declaration — and this PR's own lane is CPU-only, so
it would not have caught that.
The include therefore moves into the
VT_BENCH_PROFILE_CONTROL && !_WIN32blockthat already carries
<cerrno>,<chrono>,<fcntl.h>and<sys/stat.h>forthe same feature. It is now guarded by exactly the condition that guards its only
user.
check-windows-portability.pyreturnsWindows portability contract OK.The four test-file includes are untouched: none is in
REQUIRED_CPP, none isbuilt on Windows, and each has an unguarded
::getpid()that needs the header.The lane earned its keep immediately
build-newest-gccfailed on this very pull request, on a SIXTH file the fiveinclude repairs above do not cover:
g++ (GCC) 16.2.0. A different symbol pair from the same header, so a::getpidsweep would never have found it;
<sys/mman.h>was already included for the sameblock and carried the file this far on gcc 13 through a transitive declaration.
Fixed in this branch, inside the
#if defined(__unix__)guard the file alreadyhas, which is the same condition guarding the call site.
Owed, not done here
build-newest-gccis not wired intobaseline-summaryorscripts/main-baseline.py'sEXPECTED_JOBS, so the published baseline verdictdoes not yet cover gcc 16. That is deliberate: #1155 is editing the same list to
address the structural half of #503, and two branches rewriting it would conflict. Wire it in after
whichever lands second.
Issue: #503
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: ClaudeCode:claude-opus-5 [ClaudeCode]
Signed-off-by: Dimitris Karakasilis dimitris@karakasilis.me