From 6104cc7478fbe58d982a2056f720097292a1823a Mon Sep 17 00:00:00 2001 From: bulk88 Date: Mon, 27 May 2024 09:48:34 -0400 Subject: [PATCH 2/2] Win32 fix build for compat with mid 2000s Mingw GCCs src/config.h.W32: - add better #ifdef feature detection for CC's included headers for struct stat {} ->d_type src/remake.c: - not all Win OS CCs, use identical tokens for fn statX() and struct statX {} and Mingw 3.4.5 headers does not make the tokens identical dos2unix.js: - old gcc.exe es will not read from disk, a "@linker_options.txt" file passed on command line, if the file has CRLF, instead of POSIXy LF, fix that with a small WSH Jscript tool, using WSH during the gnumake win32 build, removes dep for any other tools/packages/downloads, vs a bare Win32 C compiler on a bare clean install OS, and avoids adding any other FOSS program deps to gnumake on Win32 current build requirements, beyond the current very very small requirements (a C compiler+whatever Win OS comes with on the CD/ISO) src/w32/utf8.manifest: -was added in 2019, Win 7 either has relaxed PE (.exe) Manifest XML parsing rules vs Win XP or Win 7 supports the newer schema, but Win XP OS won't execute or load into memory, a GCC Win32 gnumake.exe binary, with the previous manifest file, tag was the specific token that prevent Win XP from execing the .exe fix it by adding proper schema/ns labels to the file, Win XP now ignores the XML tags intended for Win 10 32 bit OS details see: https://www.medo64.com/2013/10/xp-compatible-manifest/ http://archive.today/2017.09.04-215057/https://www.medo64.com/2013/10/xp-compatible-manifest/ --- build_w32.bat | 13 +++++++- scripts/dos2unix.js | 36 ++++++++++++++++++++++ src/config.h.W32 | 69 +++++++++++++++++++++++++++++++++++++++++-- src/remake.c | 6 +++- src/w32/utf8.manifest | 4 +-- 5 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 scripts/dos2unix.js diff --git a/build_w32.bat b/build_w32.bat index a227111c..c19ae243 100644 --- a/build_w32.bat +++ b/build_w32.bat @@ -363,7 +363,7 @@ goto CompileDone :GccResourceCompile :: GCC Resource Compile if "%VERBOSE%" == "Y" echo on -call %RC% -o %OUTDIR%/%1.%O% -i %1.rc +call %RC% -I src/w32 -o %OUTDIR%/%1.%O% -i %1.rc @echo off goto CompileDone @@ -392,6 +392,17 @@ goto :EOF :: GCC Link if "%VERBOSE%" == "Y" echo on echo %GUILELIBS% -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 >>%OUTDIR%\link.sc +:: Mingw.org 3.4.5 released 2006, gcc.exe's "stdio" falsly errors out if +::a "@file" has CRLF, even though MS procmon (think strace) shows +::gcc.exe 3.4.5 block by block, read the file, modern Mingws are fine +::example error msg from mingw.org 3.4.5 +::- Linking ./GccRel/gnumake.exe gcc: @./GccRel/link.sc: No such file or directory + +::test if cscript.exe exists, might be missing, on WinOS >= 2020s, +::MS global OS design choice or user's choice, no harm if WSH missing, modern +::Mingw GCCs dont have linker bug +call cscript.exe /nologo >nul 2>&1 +if ERRORLEVEL 1 cscript.exe /nologo scripts\dos2unix.js %LNKOUT%/link.sc call %COMPILER% -mthreads -gdwarf-2 -g3 %OPTS% -o %LNKOUT%/%MAKE%.exe @%LNKOUT%/link.sc -Wl,--out-implib=%LNKOUT%/libgnumake-1.dll.a @echo off goto :EOF diff --git a/scripts/dos2unix.js b/scripts/dos2unix.js new file mode 100644 index 00000000..d01a9736 --- /dev/null +++ b/scripts/dos2unix.js @@ -0,0 +1,36 @@ +/* + used by gmake win32 for GCC for very old Mingw GCCs that can't read + "link.sc" as in "gcc @link.sc -o gmake.exe" if link.sc has CRLF. + By using WSH, which comes with all Win OSes for decades, gmake has no + outside dependencies beyond a "bare minimum" GCC package. Thus avoiding deps + on perl, sed, awk, python and larger software like "cygwin", + "git for windows", "msys", "Windows Subsystem for Linux", etc + + note, this tool is not needed for 2010s or 2020s Mingw GCCes, so if MS + removes WSH or particular user specifically uninstalled/disabled WSH, just + don't run dos2unix.js at all. The user probably has a modern CC. Note this + script might need to be rewriten in PowerShell one day, keeping WSH and PS + versions for very wide back compat. + + run as + + cscript.exe /nologo dos2unix.js [filename.txt] +*/ +try { + var shell = WScript.CreateObject("WScript.Shell"); + var args = WScript.Arguments; + var fname = args.Item(0); + var fso = WScript.CreateObject("Scripting.FileSystemObject"); + var f = fso.OpenTextFile(fname, /*ForReading*/ 1, false, /*TristateFalse*/ 0); + var fstr = f.readAll(); + f.Close(); + fstr = fstr.replace(/\x0d\x0a/g, "\x0a"); + f = fso.OpenTextFile(fname, /*ForWriting*/ 2, false, /*TristateFalse*/ 0); + f.Write(fstr); + f.Close(); + WScript.Stdout.WriteLine("dos2unix.js: converted "+fname+" successfully"); + WScript.Quit(0); +} catch (e) { + WScript.Stderr.WriteLine("dos2unix.js: JScript runtime error: " + e.message); + WScript.Quit(1); +} \ No newline at end of file diff --git a/src/config.h.W32 b/src/config.h.W32 index b2747cbe..2d7d2fce 100644 --- a/src/config.h.W32 +++ b/src/config.h.W32 @@ -355,9 +355,74 @@ this program. If not, see . */ /* Define to 1 if `d_type' is a member of `struct dirent'. */ /* SV 57152: MinGW64 version of dirent doesn't support d_type. */ -#ifndef __MINGW64__ -# define HAVE_STRUCT_DIRENT_D_TYPE 1 + +/* not all Mingw.org from day 1, releases have struct dirent->d_type + the old 2006 released mingw "3.4.5 mingw-vista special r3" doesnt have + member d_type. + + Always be very careful when using macros styled as __MINGW_WHATEVER__ + to separate less popular, very low maintence,"mingw.org" toolchain/code fork + from mainstream larger newer mingw-w64 project and its code base and NOT + introduce by accident 32b vs 64b target BINARY differences + + Both Ming groups define __MINGW32__ 32b and 64b, .org and w64. + macro __MINGW64__ is automatic proof of w64 toolchain + but only proof -w64 toolchain is used, if target x86-32 is belw + __MINGW64__ is missing if -w64 toolchain target Win32 (well supported) + + online various sources recommend + +#ifdef __MINGW64_VERSION_MAJOR + + to ID -W64 Toolchain + + commit: from ".org" adding d_type feature, see commit below + + Make dirent implementation namespace and time_t clean. + wsl-5.4.2-release wsl-5.3.4-release + keithmarshall committed on Nov 3, 2014 + + https://github.com/stahta01/mingw-org-wsl/commit/11dde2656497d4bd446689867710e1bc62e4016e + archive of above page https://archive.is/sdcr8 +*/ + +/* catch mingw.org CC family, using feature test from above commit*/ +#ifdef __MINGW32__ +/* macro tests feature flag in .org's headers */ +# ifdef _DIRENT_HAVE_D_TYPE +# define HAVE_STRUCT_DIRENT_D_TYPE 1 +# elif defined(__MINGW64__) +/* mingw-w64, in 2024 no support for d_type */ +# endif + +# ifndef __MINGW64_VERSION_MAJOR +/*mingw.org 3.4.5 default is 0x0600, boost it to get _stat64() + 6.01 supposedly released on Win2000 CD and WinME CD, I verified manually, + 2K and ME, with OS CD, that msvcrt.dll has _stat64() +*/ +# undef __MSVCRT_VERSION__ +# define __MSVCRT_VERSION__ 0x0601 +# endif + +#else +/* MSVC, all others if any*/ +# define HAVE_STRUCT_DIRENT_D_TYPE 1 #endif +/* + + Todo research/verify in future + + 2021 relead mingw.org, YES for d_type + gcc version 9.2.0 (MinGW.org GCC Build-2) + + 2021-ish mingw-w64 build, NO for D_TYPE + gcc version 8.3.0 (i686-posix-dwarf, Built by strawberryperl.com project) NO DTYPE + + 2006 approx NO for D_TYPE + gcc version 3.4.5 (mingw-vista special r3) + + */ + /* Define to 1 if 'n_un.n_name' is a member of 'struct nlist'. */ /* #undef HAVE_STRUCT_NLIST_N_UN_N_NAME */ diff --git a/src/remake.c b/src/remake.c index 6385e86c..2161d1a5 100644 --- a/src/remake.c +++ b/src/remake.c @@ -42,10 +42,12 @@ this program. If not, see . */ # if MSC_VER > 1200 /* VC7 or later supports _stat64 to access 64-bit file size. */ # define STAT _stat64 +# define STAT_T _stat64 # define U64_TO_DBL_VC(u64) ((double)(u64)) # else /* is VC 6*/ # define STAT stat +# define STAT_T stat /* Old MS compilers do not implement the double->uint64 conversion and * silently do a double->int64 conversion instead. See * http://connect.microsoft.com/VisualStudio/feedback/details/270762/error-in-converting-double-to-unsigned-long-long */ @@ -66,6 +68,8 @@ this program. If not, see . */ # endif /* Win32 but not VC */ # else +# define STAT _stat64 +# define STAT_T __stat64 # define U64_TO_DBL_VC(u64) ((double)(u64)) # endif #endif @@ -1613,7 +1617,7 @@ name_mtime (const char *name) { FILE_TIMESTAMP mtime; #if MK_OS_W32 - struct STAT st; + struct STAT_T st; #else struct stat st; #endif diff --git a/src/w32/utf8.manifest b/src/w32/utf8.manifest index dab929e1..3d8c1930 100644 --- a/src/w32/utf8.manifest +++ b/src/w32/utf8.manifest @@ -1,7 +1,7 @@ - - + + UTF-8 -- 2.35.1.windows.2