Add a "native" Windows port (based on mingw-w64 instead of cygwin) - #6557
Add a "native" Windows port (based on mingw-w64 instead of cygwin)#6557fingolfin wants to merge 14 commits into
Conversation
|
This PR is quite large and has a bunch of non-trivial changes. Could you factor some more parts of it into their own self-contained or stacked PRs? |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #6557 +/- ##
==========================================
+ Coverage 79.01% 79.03% +0.02%
==========================================
Files 683 683
Lines 295108 295145 +37
Branches 8638 8639 +1
==========================================
+ Hits 233179 233273 +94
+ Misses 60113 60054 -59
- Partials 1816 1818 +2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
That's the plan (in fact I already got a bunch of changes for this project merged). But most of what remains now needs some understanding of the overall picture to make sense. Therefore this "master" PR, which shows the entire work as it is, and which can be referenced for context as smaller PRs extracted from it are submitted.
Indeed, and I even state that ;-)
Maybe... |
e8e0a3d to
829d9ab
Compare
|
I had a quick scan through, none of these seems upsettting. There is a lot of it (obviously), in some cases I do wonder if the AI could be convinced to write a little less, but none of it seems to fundamentally break unix GAP, it's fairly well isolated. |
829d9ab to
dfd8826
Compare
dfd8826 to
5b9fea2
Compare
mingw-w64 predefines _WIN32; Cygwin GCC does not, as Cygwin is a POSIX system to GAP. So SYS_IS_WINDOWS and SYS_IS_CYGWIN32 are mutually exclusive. Groundwork for the MinGW port (#4157). ARCH_IS_WINDOWS() also reports true for a "mingw" architecture. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Make the kernel compile with mingw-w64 (#4157, partly after #6077): termios, uname, sigaction, lstat, ttyname, mkdtemp, realpath, readlink, getrusage, sleep, environ, mkdir. Without termios the line editor falls back to syFgetsNoEdit. On Windows, SyTime and RUNTIMES use GetProcessTimes, TmpDirectory a mkdtemp built on _mktemp and mkdir, SyGetOsRelease RtlGetVersion. The fork and pty based subprocess code is compiled out, leaving the stubs of GAP_DISABLE_SUBPROCESS_CODE builds. charreadhook_rl is only defined with select, its sole user. New configure checks: sys/utsname.h, realpath, readlink, mkdtemp, lstat, ttyname. No-ops on current platforms. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Some SYS_IS_CYGWIN32 guards cover behavior any Windows needs, not Cygwin quirks: O_BINARY, CRLF stripping, the C:/WINDOWS/Temp fallback, backslash conversion in root paths, ~/_gap, and the GMP bag zeroing for #3434. Widen them to SYS_IS_WINDOWS. Genuine Cygwin quirks stay Cygwin-only. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Two testinstall diffs: - SyFseek: reject negative positions; Windows' lseek accepts them - the ExecuteProcess stub validates its arguments like the real implementation, so the documented errors come first Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
ffgen and gap-nocomp (generating c_oper1.c/c_type1.c) cannot run when cross-compiling. Fail with an explanation: seed the generated files from a native build into src/, as the s390x CI job does. Skip 'make check' for the bundled GMP and zlib, whose test programs cannot run either. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
For #4157, partly after #6077. gap.exe is a plain static executable for now; the Cygwin split into gap.exe and libgap.dll comes with kernel extensions. Stack size as on Cygwin. Multiple definitions are allowed since the PE linker rejects the duplicate EXPORT_INLINE instances ELF linkers merge. Bundled zlib uses its win32 makefile; bundled GMP and zlib drop -Wl,-rpath. HPC-GAP and non-GASMAN garbage collectors are rejected. Recipe in dev/crosscompile-mingw.md. The result links but does not run yet. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The C runtime defaults to text mode, writing "\n" as "\r\n"; this corrupted binary data, checksums and seek positions. Default to binary, as Cygwin's binmode mounts do; GAP handles CRLF itself. Size the default workspace limit from physical memory via GlobalMemoryStatusEx; without sysconf it stayed at 2 GB, which testinstall exceeds. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Use the console API where POSIX uses termios: disable line input, echo and input processing so the line editor sees every key, and enable virtual terminal input, which delivers special keys as the VT sequences the editor understands. Enable VT processing for output (colors), read the window size from GetConsoleScreenBufferInfo at each line (there is no SIGWINCH), and restore the mode when leaving raw mode. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- HOME: derive from USERPROFILE when unset, normalize backslashes; tilde expansion, ~/.gap and ~/.gap_hist then work - temporary files: use TEMP or TMP; C:/WINDOWS/Temp is not writable for users on current Windows - DirectoriesSystemPrograms: split PATH on ';', accept the spelling "Path", convert backslashes - PathSystemProgram and Filename: probe with ".exe" appended - Filename: accept ':' and '\' on Windows - GAP_getcwd: report slashes Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
SyExecuteProcess on top of CreateProcess: the argument vector becomes a command line under the MSVCRT quoting rules, the program name quoted with backslashes since cmd.exe takes forward slash paths for switches; standard input and output attach to the streams GAP passes (NUL for -1); the exit code is returned; GAP stops reading its own standard input meanwhile. Process() and Exec() work. FuncExecuteProcess is shared by all configurations, so argument validation is uniform; builds without fork or a Windows API, and GAP_DISABLE_SUBPROCESS_CODE builds, keep signalling failure. InputOutputLocalProcess stays unsupported here. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Load modules via LoadLibrary/GetProcAddress; HAVE_DYNAMIC_MODULES covers it and dlopen. As on Cygwin, GAP proper lives in libgap.dll next to a gap.exe stub. Extensions link against the import library libgap.dll.a, so the loader resolves them against the libgap.dll already in the process, by module name, without a filesystem search. libgcc is linked statically; depending on libgcc_s_seh-1.dll made the DLL unloadable outside MSYS2. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Mirror the mmap pool: reserve at the same fixed address (16 TB, else anywhere) and grow contiguously in place. Committed pages count against the commit limit even untouched, so the pool is only reserved, committed as the workspace grows into it, and decommitted after garbage collection like MADV_DONTNEED. Commit and decommit work per reservation, as one call may not span several. Sizes round up to the 64 kB granularity so the region end stays extensible. Before, one calloc with no way to grow capped the workspace at the initial pool size. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There are no pseudo terminals; connect the child's standard streams to anonymous pipes. Standard output and error get distinct handles onto one pipe: a child rearranging its standard error (ACE does) must not take its output down with it. Reads poll with PeekNamedPipe to keep GAP responsive, and squash the \r\n a native child emits, which a pty never shows. ReadAllLine for pty streams required UNIXSelect; use it when available, else let ReadLine block. A child sees a pipe, not a terminal, so it must flush its own output; anupq and ace need small patches. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Build with MSYS2's mingw-w64, fetch the required packages, run
testinstall and testmockpkg through dev/ci.sh. read.tst is removed
first: StringFile("/") expects a directory to open but not read; on
Windows the open fails.
dev/crosscompile-mingw.md gains the testing recipe and status.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
5b9fea2 to
fb8eba3
Compare
Resolves the kernel side of #4157: GAP builds and runs as a native Windows program with mingw-w64 (MSYS2/MINGW64), without Cygwin. Supersedes #6077, which was quarried for ideas.
What works
read.tst:84, which expects POSIX semantics of opening a directory.C:/...and backslashes accepted,;-separated PATH,.exeprobing, HOME from USERPROFILE.Process/Execvia CreateProcess;InputOutputLocalProcessvia anonymous pipes (there are no ptys).BuildPackages.shworks under MSYS2 unchanged.mingw64job builds with MSYS2 and runs testinstall and testmockpkg.Tested
Cross-compiled from macOS (recipe in
dev/crosscompile-mingw.md), smoke-tested under Wine, validated on Windows 11 (ARM VM running the x64 build under emulation) including interactive terminal use. Packages with kernel extensions: datastructures, json, orb (minus the IO-dependent test), edim, digraphs, ace, anupq.Note: ace, anupq, edim and digraphs need small patches, to be submitted separately. I expected further packages will need (hopefully small) patches.
Not included / follow-ups
SyGetOsReleaseis empty;TmpDirectoryis not race-free (mkdtempsubstitute).Review notes
The first build-system commit, "Support cross-compiling GAP", is not Windows-specific and can be merged on its own.
Every commit builds on all platforms; Windows-specific code is under
SYS_IS_WINDOWS, no-op elsewhere. Native and cross builds pass with--enable-Werror.Co-Authored-By: Claude Fable 5.1 noreply@anthropic.com