Skip to content

Native Windows (MinGW) CPU build via dependency-free POSIX shim#344

Open
jamesburton wants to merge 1 commit into
antirez:rocmfrom
jamesburton:windows-native-cpu
Open

Native Windows (MinGW) CPU build via dependency-free POSIX shim#344
jamesburton wants to merge 1 commit into
antirez:rocmfrom
jamesburton:windows-native-cpu

Conversation

@jamesburton
Copy link
Copy Markdown

Summary

Adds native Windows CPU build support for ds4-bench using MinGW-w64 GCC — no WSL, Cygwin, or MSVC required. The portability surface is provided by a single small, header-only POSIX shim (ds4_win.h), wired in-tree behind #ifdef _WIN32.

ds4_win.h supplies exactly the POSIX surface that MinGW/UCRT lacks:

  • mmap / munmap / madvise (read-only file mappings via CreateFileMappingA/MapViewOfFile)
  • sysconf(_SC_NPROCESSORS_ONLN / _SC_PAGESIZE)
  • flock / fcntl(F_SETFD) / pread / dprintf (used by the instance lock)
  • a temp-file-backed fmemopen (fixed buffer, copy-back on close)

MinGW already provides pthread, clock_gettime, and ftruncate, so those are used as-is.

How it's wired

ds4.c now includes ds4_win.h in place of <sys/mman.h> (and the other POSIX-only headers) on Windows:

#ifdef _WIN32
#include "ds4_win.h"
...
#else
#include <sys/file.h>
#include <sys/mman.h>
...
#endif

The entire body of ds4_win.h is guarded by _WIN32, so POSIX builds (Linux / macOS / CUDA / ROCm) are unchanged — all new code is inert off Windows. No extra include or search-path flags are needed.

Build

uname -s on MinGW/MSYS reports MINGW64_NT* / MSYS_NT*; the Makefile detects this, defaults CC to gcc, and exposes a windows-cpu target. Darwin / Linux / cuda / rocm paths are untouched.

make windows-cpu

Direct-gcc fallback (no make):

CF="-O3 -ffast-math -march=native -std=c99 -D_GNU_SOURCE -fno-finite-math-only \
    -DDS4_NO_GPU -D_CRT_SECURE_NO_WARNINGS"
gcc $CF -c ds4.c       -o ds4_cpu.o
gcc $CF -c ds4_bench.c -o ds4_bench_cpu.o
gcc $CF -o ds4-bench.exe ds4_bench_cpu.o ds4_cpu.o -lm

Toolchain: x86_64-w64-mingw32 GCC 15.2.0.

Verification

$ ./ds4-bench.exe
ds4-bench: specify exactly one of --prompt-file or --chat-prompt-file   (exit 2)

$ ./ds4-bench.exe --help
Usage: ds4-bench --prompt-file FILE [options]
...

The binary executes and its argument validation fires, confirming a working native Windows executable.

Runtime note: set DS4_LOCK_FILE to a Windows path before running (default is /tmp/ds4.lock, which does not exist on Windows), e.g. export DS4_LOCK_FILE="$TEMP/ds4.lock".

What's in scope / deferred

Target Native Windows CPU Notes
ds4-bench builds & runs no terminal/socket deps
ds4 (CLI) deferred linenoise.c uses POSIX termios; ds4_cli.c uses sigaction — needs a Windows console raw-mode port
ds4-server deferred BSD sockets / poll / arpa/inet.h — needs a Winsock port

This PR is intentionally scoped to the CPU bench + POSIX compat layer. The CLI and server need their own portability passes (console raw-mode and Winsock respectively), documented in win/README.md and tracked as follow-ups.

Base branch

Opened against rocm since that's the branch the work was based on, but the diff is self-contained (new ds4_win.h, a guarded include in ds4.c, an additive Makefile target) and applies cleanly to main too if you prefer that base.

🤖 Generated with Claude Code

Adds native Windows CPU build support for ds4-bench using MinGW-w64 GCC
(no WSL, Cygwin or MSVC). A small header-only POSIX shim, ds4_win.h,
supplies the surface MinGW/UCRT lacks: mmap/munmap/madvise, sysconf,
flock/fcntl/pread/dprintf, and a temp-file-backed fmemopen. MinGW already
provides pthread, clock_gettime and ftruncate.

The shim is wired in-tree behind #ifdef _WIN32: ds4.c includes ds4_win.h
in place of <sys/mman.h> on Windows. The header's whole body is guarded by
_WIN32, so POSIX (Linux/macOS/CUDA/ROCm) builds are unchanged.

Makefile detects MinGW/MSYS (uname -s = MINGW*/MSYS*), defaults CC to gcc
there, and adds a `windows-cpu` target that builds ds4-bench.exe with
-DDS4_NO_GPU. Darwin/Linux/cuda/rocm paths are untouched. win/README.md
documents the build (make + direct-gcc fallback), the DS4_LOCK_FILE runtime
note, and the deferred CLI (termios/sigaction) and server (Winsock) ports.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 6, 2026 16:59
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds an experimental native Windows (MinGW-w64) build path for the CPU backend by introducing a small POSIX-compatibility shim, plus build/docs updates to support producing ds4-bench.exe.

Changes:

  • Added ds4_win.h POSIX shim for Windows (mmap/flock/pread/sysconf/dprintf/fmemopen).
  • Updated ds4.c and Makefile to enable a windows-cpu target producing ds4-bench.exe.
  • Added Windows build documentation and ignored Windows executable artifacts.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
win/README.md Documents experimental native Windows CPU build steps and known gaps.
ds4_win.h Introduces a header-only Windows shim for missing POSIX APIs used by ds4.c.
ds4.c Includes the Windows shim and adjusts includes under _WIN32.
Makefile Detects MinGW/MSYS, adds windows-cpu target and Windows-specific flags/outputs.
.gitignore Ignores ds4-bench.exe and *.exe outputs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ds4_win.h
Comment on lines +167 to +171
static inline void ds4_ms_ensure(void)
{
if (InterlockedCompareExchange(&ds4_ms_init, 1, 0) == 0)
InitializeCriticalSection(&ds4_ms_cs);
}
Comment thread ds4_win.h
Comment on lines +192 to +201
EnterCriticalSection(&ds4_ms_cs);
for (int i = 0; i < DS4_MEMSTREAM_MAX; i++) {
if (ds4_ms_tab[i].fp == NULL) {
ds4_ms_tab[i].fp = fp; ds4_ms_tab[i].buf = buf;
ds4_ms_tab[i].cap = size; ds4_ms_tab[i].writeback = writing ? 1 : 0;
break;
}
}
LeaveCriticalSection(&ds4_ms_cs);
return fp;
Comment thread ds4_win.h
Comment on lines +149 to +158
static inline int dprintf(int fd, const char *fmt, ...)
{
char buf[512];
va_list ap; va_start(ap, fmt);
int n = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
if (n < 0) return -1;
if (n > (int)sizeof(buf)) n = (int)sizeof(buf);
return _write(fd, buf, (unsigned)n);
}
Comment thread ds4_win.h
Comment on lines +131 to +144
static inline long long ds4_pread(int fd, void *buf, size_t count, long long offset)
{
HANDLE h = (HANDLE)_get_osfhandle(fd);
if (h == INVALID_HANDLE_VALUE) { errno = EBADF; return -1; }
OVERLAPPED ov; memset(&ov, 0, sizeof(ov));
ov.Offset = (DWORD)((uint64_t)offset & 0xFFFFFFFFu);
ov.OffsetHigh = (DWORD)((uint64_t)offset >> 32);
DWORD got = 0;
if (!ReadFile(h, buf, (DWORD)count, &got, &ov)) {
if (GetLastError() == ERROR_HANDLE_EOF) return 0;
errno = EIO; return -1;
}
return (long long)got;
}
Comment thread ds4_win.h
Comment on lines +125 to +129
static inline int fcntl(int fd, int cmd, ...)
{
(void)fd; (void)cmd;
return 0; /* F_SETFD/FD_CLOEXEC is a no-op: Windows handles aren't inherited by default */
}
Comment thread ds4_win.h
Comment on lines +173 to +180
static inline FILE *ds4_tmpfile(void)
{
char dir[MAX_PATH], path[MAX_PATH];
if (!GetTempPathA(sizeof(dir), dir)) return NULL;
if (!GetTempFileNameA(dir, "ds4", 0, path)) return NULL;
/* open read/write, delete on close */
return fopen(path, "wb+TD"); /* T=temporary, D=delete-on-close (MSVCRT ext) */
}
Comment thread Makefile
Comment on lines +20 to +24
# Native Windows (MinGW-w64) CPU build flags. ds4.c pulls in the dependency-free
# POSIX shim (ds4_win.h) behind #ifdef _WIN32; no extra -I/-include is needed.
WIN_CFLAGS ?= -O3 -ffast-math $(NATIVE_CPU_FLAG) -std=c99 -D_GNU_SOURCE \
-fno-finite-math-only -DDS4_NO_GPU -D_CRT_SECURE_NO_WARNINGS
WIN_LDLIBS ?= -lm
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.

2 participants