Skip to content

fix(build): keep POSIX-only build parts off Windows and refuse unguarded POSIX headers in msvcism - #2611

Merged
lusoris merged 1 commit into
masterfrom
fix/msvcism-posix-headers
Oct 8, 2026
Merged

lusoris merged 1 commit into
masterfrom
fix/msvcism-posix-headers

Conversation

@lusoris

@lusoris lusoris commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Summary

The msvcism preflight stage now refuses a POSIX-only header (<unistd.h>, <dlfcn.h>, <poll.h>, <sys/socket.h>, ...) outside a platform conditional in a source the Windows MSVC builds compile, and the three build parts that are POSIX-only by design (embedded MCP server, libFuzzer harnesses, vmaf_vpl) are gated off Windows, so a Windows configure that asks for MCP or fuzzing fails with the reason instead of in the compiler (ADR-2646, ledger Q-266 and Q-269).

Every Linux and macOS lane accepts an unguarded POSIX include; only the required Windows MSVC+CUDA / Windows MSVC+SYCL lanes refuse it (C1083), and neither the local gates nor the merge train build them. While landing the RC4 Vulkan frame import (#2375), core/src/cuda/import_vulkan.c had added <unistd.h> for dup() / close() (fixed in that lane with VMAF_DUP / VMAF_CLOSE), and nothing local caught it.

What changes:

  • Scanner. scripts/dev/find-posix-only-headers.py reports path:line: <header> for a POSIX-only include outside every preprocessor conditional that names a platform (_WIN32, _MSC_VER, __linux__, __unix__, __APPLE__, __has_include, a HAVE_* feature macro other than the backend switches), in a file the Windows build compiles. Which files those are comes from the meson.build files: a source named only inside a block kept off Windows (host_machine.system() != 'windows', == 'linux', the else / elif of == 'windows', the subdir() that reads its directory, a foreach over a list filled only off Windows, a list kept empty off Linux) is not built there; a header counts through the sources that include it; a source no meson.build names counts as built. It exits non-zero when git cannot list the build files.
  • Stage. scripts/dev/preflight.sh --stage msvcism runs it over the changed sources (C, C++ and CUDA), after lint_exceptions.py filter msvcism-posix-headers, and fails on a finding and when either step cannot run (no result is never a pass). It resolves both scripts next to itself (PREFLIGHT_DIR), so it also checks another checkout correctly.
  • Gates. core/src/meson.build: enable_mcp=true on Windows is a configure error() naming <sys/socket.h> and <unistd.h>; subdir('mcp') and compat/libvmaf/mcp.c carry the gate. core/test/meson.build: the MCP tests carry it; subdir('fuzz') runs off Windows only, and fuzz=true on Windows is an error(). core/tools/meson.build: vmaf_vpl (no option requests it) is not looked for on Windows, and configure prints vmaf_vpl tool: disabled (Linux only: VA-API, libva-drm and <unistd.h>). Nothing is skipped silently.
  • Exceptions. Two files, each POSIX-only by design and built by no meson.build: the vendored MATLAB MEX source compat/python-vmaf/matlab/strred/matlabPyrTools/MEX/innerProd.c and the LD_PRELOAD fault-injection shim ffmpeg-patches/test/fault_inject_libvmaf.c, in .config/lint-exceptions.d/msvcism-posix-headers.toml with a reason and expiry 2027-06-30 (lint_exceptions.py check: 85 exceptions, 0 findings).
  • Test. scripts/ci/tests/test-preflight-msvcism.sh (now run by make lint-sh) plants an unguarded <unistd.h> and requires the stage to fail and name it; a <unistd.h> under #ifndef _WIN32 passes; a source whose only meson.build target is gated off Windows passes and fails once the gate is removed; a scanner that cannot run (a python3 that exits 3 first on PATH) fails the stage.

Failing first: the extended test run against master's stage (f225754c2): the planted unguarded <unistd.h> passes there (FAIL unguarded <unistd.h>: expected rc=1, got 0 ... PASS msvcism), which is the gap. On this branch all seven cases pass. Whole tree: before the gates, the scan found 32 includes in 9 groups (MCP server, fuzz harnesses, vmaf_vpl, the two excepted files, and files no meson.build builds); with them, scripts/dev/preflight.sh --full --stage msvcism passes with 0 findings, and the scan of a21d20ce1 reports core/src/cuda/import_vulkan.c:41: <unistd.h>, the defect that started this.

Configure (Meson 1.12.1, MinGW-w64 cross file with host_machine.system = 'windows', the closest local stand-in for the MSVC lanes): -Denable_mcp=true stops at core/src/meson.build:274 with enable_mcp=true: the embedded MCP server is POSIX-only (Unix-domain and TCP sockets through <sys/socket.h> and <unistd.h>) and cannot be built for Windows; -Dfuzz=true stops at the error() in core/test/meson.build (line 8959 on the head) with the fuzz message; the default configure succeeds. Master's meson files accept -Denable_mcp=true for that target (configure rc 0; the compiler fails later). Linux -Denable_mcp=true configures as before.

Type

  • fix — bug fix
  • build / ci — tooling / infra

Checklist

  • Commits follow Conventional Commits (the commit-msg hook enforces this).
  • Every commit is signed off (git commit -s; fix a branch with git rebase --signoff origin/master). See DCO sign-off.
  • make format && make lint is green locally. — the commit hooks (black, ruff, shfmt, shellcheck, markdownlint, semgrep, HISS audit) pass; ruff check on the scanner: clean; shellcheck on the stage and the test: clean.
  • Unit tests pass: python3 scripts/ci/run_meson_test.py -- -C build. — local gate on 560119f73, the same change before the rebase onto 4dad09e3e (which brought feat(api): import CUDA device frames with event fences and GL textures (RC4 WP3, ADR-2023) #2277 and feat(api): generate the custom resources, their CRDs and the operator role from the platform definition (ADR-2350) #2605, no conflict; on 853e5ccd4 the msvcism test, the full-tree stage, the configure checks and the train gates were repeated, same results) (CPU, -Db_lto=false, -j4, warnings as errors): build 0 warnings; --suite=fast 411 OK, 0 failed (test_gpu_picture_pool_uaf with MALLOC_PERTURB_=0, fix(test): run the GPU pool UAF test without MALLOC_PERTURB_ so it cannot fill the host's memory #2547: 1 OK); codegen tests 151 passed; preflight.sh --stage msvcism pass; affected suites: tooling 2537 passed, 6 skipped, 0 failed; bash scripts/ci/tests/test-preflight-msvcism.sh: 7 of 7.
  • If I touched any SIMD/GPU code path, I ran /cross-backend-diff and the worst ULP is ≤ 2. — not applicable: no GPU or SIMD code changed.
  • If I touched a feature extractor with SIMD/GPU twins, I either updated every twin or listed the gap under "Known follow-ups" below. — not applicable.
  • If I added a new .c / .cpp / .cu / .h / .hpp, it has the appropriate license header (see CONTRIBUTING.md). — no new C source; the new Python scanner carries the EUPL-1.2 header.
  • If this is a breaking change, the commit message uses ! or BREAKING CHANGE: and the migration path is documented below. — not breaking: a Windows build with enable_mcp=true or fuzz=true never compiled; it now stops at configure.
  • If this PR adds an ADR, the ADR row lives in docs/adr/_index_fragments/<NNNN-slug>.md and nothing else is touched for the index: do not edit docs/adr/README.md, docs/adr/by-tag/, docs/adr/titles.md or _order.txt — ADR-2646 (claimed with scripts/adr/next-free.sh --claim), fragment added; the index, by-tag and title pages are rendered at landing (ADR-2197).

Bug-status hygiene (ADR-0165)

  • docs/state.md updated in this PR — T-MSVCISM-POSIX-HEADER-UNCHECKED-2026-10-08 under Recently closed (found and fixed here).

Netflix golden-data gate (ADR-0024)

  • I did not modify any assertAlmostEqual(...) score in the Netflix golden Python tests, except by porting Netflix's own updated assertion verbatim from upstream (value and places as upstream has them, measured against the fork's CPU build first; ADR-1828).
  • If I believe a golden value must change, I have explained why below AND pinged @lusoris for a CODEOWNERS exception. — not applicable.

Golden gate (GOLDEN_NINJA_JOBS=4 make test-netflix-golden, core/build-golden built with gcc): 280 passed, 3 skipped. The Linux build compiles the same sources as before; only Windows configures change.

Cross-backend numerical results

Not applicable: no extractor, kernel or score path changed.

Deep-dive deliverables (ADR-0108)

  • Research digest — no digest needed: trivial (the evidence is the scan and the planted test above).
  • Decision matrix — ADR-2646 ## Alternatives considered (gate the three parts with two exceptions, one exception per file, scope the check to core/src/, port to Windows).
  • AGENTS.md invariant note — scripts/dev/AGENTS.md (the scan, its fail-closed exit, the exception file, the Meson gates; caveman check: pass).
  • Reproducer / smoke-test command — pasted below under "Reproducer".
  • CHANGELOG fragment — changelog.d/changed/msvcism-posix-headers.md.
  • Rebase note — docs/rebase-notes.d/msvcism-posix-headers.md (the Meson gates an upstream sync keeps, the stage's fail-closed scan, the exceptions).

Reproducer

bash scripts/ci/tests/test-preflight-msvcism.sh
scripts/dev/preflight.sh --full --stage msvcism
git ls-files '*.c' '*.cpp' '*.h' '*.hpp' '*.cu' '*.cuh' | xargs python3 scripts/dev/find-posix-only-headers.py
meson setup /tmp/win core --cross-file <mingw-w64 cross file> -Denable_mcp=true   # stops with the POSIX-only error

Known follow-ups

  • The scan models if / elif / else, foreach, subdir() and the empty-list ternary of Meson. A new way of keeping a source off Windows may need the scanner extended or a named exception.
  • No Windows configure or build ran here; the hosted Windows MSVC+* jobs on this PR are the confirmation.

@github-actions github-actions Bot added the type:bug Something isn't working label Oct 8, 2026
…ded POSIX headers in msvcism (#2611)

* fix(build): keep POSIX-only build parts off Windows and refuse unguarded POSIX headers in msvcism

MSVC ships no <unistd.h>, <dlfcn.h>, <sys/socket.h> or the other POSIX-only
headers, and only the required Windows MSVC lanes, which neither the local
gates nor the merge train build, see an unguarded include of one. The RC4
Vulkan frame import added <unistd.h> to core/src/cuda/import_vulkan.c, a
CUDA-backend source the Windows build compiles, and nothing local caught it.

The msvcism stage of scripts/dev/preflight.sh now runs
scripts/dev/find-posix-only-headers.py over the changed sources: a
POSIX-only include outside every platform conditional, in a source the
Windows build compiles (read from the meson.build gates, a header through
its includers), fails the stage, and so does a scan that cannot run. The
planted case in scripts/ci/tests/test-preflight-msvcism.sh passed master's
stage and fails this one; make lint-sh runs the test.

The MCP server, the libFuzzer harnesses and vmaf_vpl are POSIX-only and
gated off Windows: enable_mcp=true and fuzz=true stop a Windows configure
with an error that names the dependency, vmaf_vpl is not looked for and
configure says so. The vendored MATLAB MEX source and the LD_PRELOAD
fault-injection shim, which no meson.build builds, are named exceptions
with an expiry (ADR-2646, Q-266, Q-269).

Signed-off-by: Lusoris <lusoris@proton.me>
@lusoris
lusoris force-pushed the fix/msvcism-posix-headers branch from 8f34bd2 to 583a30b Compare October 8, 2026 13:32
@lusoris
lusoris merged commit 583a30b into master Oct 8, 2026
53 of 78 checks passed
@lusoris
lusoris deleted the fix/msvcism-posix-headers branch October 8, 2026 13:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant