Skip to content

build: make the tree compile on gcc 16, and add a CI lane so it stays that way - #945

Merged
localai-bot merged 2 commits into
mudler:mainfrom
jimmykarily:row/BUILD-GCC16
Aug 18, 2026
Merged

build: make the tree compile on gcc 16, and add a CI lane so it stays that way#945
localai-bot merged 2 commits into
mudler:mainfrom
jimmykarily:row/BUILD-GCC16

Conversation

@jimmykarily

@jimmykarily jimmykarily commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

::getpid() without <unistd.h> compiles on the distro g++ every Linux lane
installs (gcc 13 on ubuntu-latest) because a transitive include supplies the
declaration. 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-gcc is a compile-only lane on container: gcc:16, so the class
cannot come back silently. It deliberately does not run ctest — build-test-cpu
owns 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 the
lane will not fail on a missing tag.

cmake/CompilerWarnings.cmake stops treating -Warray-bounds as fatal on
GNU >= 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.cpp include was added unguarded, among the plain includes.
That file is one of five in REQUIRED_CPP in
scripts/check-windows-portability.py, whose POSIX_PATTERNS[0] matches a bare
#include <unistd.h> on any line reachable from a Windows build — so as written
it 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), and
that macro is set under VLLM_CPP_CUDA plus the opt-in
VLLM_CPP_BENCH_PROFILE_CONTROL. A CUDA build with the profiler enabled, on
gcc 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 && !_WIN32 block
that already carries <cerrno>, <chrono>, <fcntl.h> and <sys/stat.h> for
the same feature. It is now guarded by exactly the condition that guards its only
user. check-windows-portability.py returns Windows portability contract OK.
The four test-file includes are untouched: none is in REQUIRED_CPP, none is
built on Windows, and each has an unguarded ::getpid() that needs the header.

The lane earned its keep immediately

build-newest-gcc failed on this very pull request, on a SIXTH file the five
include repairs above do not cover:

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. A different symbol pair from the same header, so a ::getpid
sweep would never 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.
Fixed in this branch, inside the #if defined(__unix__) guard the file already
has, which is the same condition guarding the call site.

Owed, not done here

build-newest-gcc is not wired into baseline-summary or
scripts/main-baseline.py's EXPECTED_JOBS, so the published baseline verdict
does 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

@localai-org-maint-bot localai-org-maint-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@localai-org-maint-bot localai-org-maint-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

jimmykarily and others added 2 commits August 18, 2026 09:07
…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>
@localai-bot
localai-bot merged commit 65d6cda into mudler:main Aug 18, 2026
16 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants