From 1892ae07e2c3592850826737f457bb642c98b033 Mon Sep 17 00:00:00 2001
From: Costas Argyris <costas.argyris@gmail.com>
Date: Sat, 25 Mar 2023 21:51:41 +0000
Subject: [PATCH] Use UTF-8 active code page when building for Windows.

---
 .gitignore            |  2 ++
 Makefile.am           | 10 ++++++++++
 README.git            |  2 +-
 build_w32.bat         | 41 +++++++++++++++++++++++++++++++++++++++--
 configure.ac          |  5 +++++
 src/w32/utf8.manifest |  8 ++++++++
 src/w32/utf8.rc       |  3 +++
 7 files changed, 68 insertions(+), 3 deletions(-)
 create mode 100644 src/w32/utf8.manifest
 create mode 100644 src/w32/utf8.rc

diff --git a/.gitignore b/.gitignore
index 1ea8c55c..cf4109d5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,6 +59,8 @@ WinDebug/
 WinRel/
 GccDebug/
 GccRel/
+TccDebug/
+TccRel/
 
 # Test artifacts
 makeerror-*
diff --git a/Makefile.am b/Makefile.am
index c29c2357..60a4e5b3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -46,6 +46,8 @@ w32_SRCS =	src/w32/pathstuff.c src/w32/w32os.c src/w32/compat/dirent.c \
 		src/w32/subproc/misc.c src/w32/subproc/proc.h \
 		src/w32/subproc/sub_proc.c src/w32/subproc/w32err.c
 
+w32_utf8_SRCS = src/w32/utf8.rc src/w32/utf8.manifest
+
 vms_SRCS =	src/vms_exit.c src/vms_export_symbol.c src/vms_progname.c \
 		src/vmsdir.h src/vmsfunctions.c src/vmsify.c
 
@@ -90,6 +92,14 @@ else
   make_SOURCES += src/posixos.c
 endif
 
+if HAVE_WINDRES
+  UTF8OBJ     = src/w32/utf8.$(OBJEXT)
+  make_LDADD += $(UTF8OBJ)
+endif
+
+$(UTF8OBJ) : $(w32_utf8_SRCS)
+	$(WINDRES) $< -o $@
+
 if USE_CUSTOMS
   make_SOURCES += src/remote-cstms.c
 else
diff --git a/README.git b/README.git
index dc445236..9a8c39aa 100644
--- a/README.git
+++ b/README.git
@@ -147,7 +147,7 @@ That is, you can just run:
 to build and test GNU Make.
 
 NOTE! This method builds GNU Make in "maintainer mode".  Make programs built
-      in this mode it will be slower, possibly MUCH slower: there are various
+      in this mode will be slower, possibly MUCH slower: there are various
       sanity checks enabled.  Further this mode assumes a modern GCC, GNU
       libc, and well-formed system headers and enables a high level of
       warnings AND enables -Werror to turn warnings into failures.
diff --git a/build_w32.bat b/build_w32.bat
index 3e023002..7b1c556a 100644
--- a/build_w32.bat
+++ b/build_w32.bat
@@ -34,6 +34,7 @@ echo.
 set MAKE=gnumake
 set GUILE=Y
 set COMPILER=cl.exe
+set RC=rc.exe
 set O=obj
 set ARCH=x64
 set DEBUG=N
@@ -81,6 +82,7 @@ goto ParseSW
 
 :SetCC
 set COMPILER=gcc
+set RC=windres
 set O=o
 echo - Building with GCC
 shift
@@ -88,6 +90,7 @@ goto ParseSW
 
 :SetTCC
 set COMPILER=tcc
+set RC=windres
 set O=o
 echo - Building with TinyC
 shift
@@ -197,7 +200,7 @@ if "%MAINT%" == "Y" set "OPTS=%OPTS% -DMAKE_MAINTAINER_MODE"
 :: Show the compiler version that we found
 echo.
 call %COMPILER% --version
-if not ERRORLEVEL 1 goto Build
+if not ERRORLEVEL 1 goto FindWindres
 echo No %COMPILER% found.
 exit 1
 
@@ -212,10 +215,18 @@ if "%MAINT%" == "Y" set "OPTS=%OPTS% -DMAKE_MAINTAINER_MODE"
 :: Show the compiler version that we found
 echo.
 call %COMPILER% -v
-if not ERRORLEVEL 1 goto Build
+if not ERRORLEVEL 1 goto FindWindres
 echo No %COMPILER% found.
 exit 1
 
+:FindWindres
+:: Show the resource compiler version that we found
+echo.
+call %RC% --version
+if not ERRORLEVEL 1 goto Build
+echo No %RC% found.
+exit 1
+
 :Build
 :: Clean the directory if it exists
 if exist %OUTDIR%\nul rmdir /S /Q %OUTDIR%
@@ -281,6 +292,8 @@ call :Compile lib/fnmatch
 call :Compile lib/glob
 call :Compile lib/getloadavg
 
+call :ResourceCompile src/w32/utf8
+
 :: Compile dirent unless it is supported by compiler library (like with gcc).
 if "%DIRENT%" == "Y" call :Compile src\w32\compat\dirent
 
@@ -331,6 +344,30 @@ call %COMPILER% -mthreads -Wall -std=c11 %OPTS% -I%OUTDIR%/src -I./src -I%OUTDIR
 @echo off
 goto CompileDone
 
+:ResourceCompile
+if "%VERBOSE%" == "N" echo - Compiling %1.rc
+echo %LNKOUT%/%1.%O% >>%OUTDIR%\link.sc
+if exist "%OUTDIR%\%1.%O%" del "%OUTDIR%\%1.%O%"
+if "%COMPILER%" == "gcc" goto GccResourceCompile
+if "%COMPILER%" == "tcc" goto TccResourceCompile
+
+:: MSVC Resource Compile
+if "%VERBOSE%" == "Y" echo on
+call %RC% /fo %OUTDIR%\%1.%O% %1.rc
+@echo off
+goto CompileDone
+
+:GccResourceCompile
+:: GCC Resource Compile
+if "%VERBOSE%" == "Y" echo on
+call %RC% -o %OUTDIR%/%1.%O% -i %1.rc
+@echo off
+goto CompileDone
+
+:TccResourceCompile
+:: TCC Resource Compile
+goto GccResourceCompile
+
 :CompileDone
 if not exist "%OUTDIR%\%1.%O%" exit 1
 goto :EOF
diff --git a/configure.ac b/configure.ac
index cd785754..8cbf9864 100644
--- a/configure.ac
+++ b/configure.ac
@@ -444,6 +444,7 @@ AC_SUBST([MAKE_HOST])
 
 w32_target_env=no
 AM_CONDITIONAL([WINDOWSENV], [false])
+AM_CONDITIONAL([HAVE_WINDRES], [false])
 
 AS_CASE([$host],
   [*-*-mingw32],
@@ -451,6 +452,10 @@ AS_CASE([$host],
     w32_target_env=yes
     AC_DEFINE([WINDOWS32], [1], [Build for the WINDOWS32 API.])
     AC_DEFINE([HAVE_DOS_PATHS], [1], [Support DOS-style pathnames.])
+    # Windows host tools.
+    # If windres is available, make will use UTF-8.
+    AC_CHECK_TOOL([WINDRES], [windres], [:])
+    AM_CONDITIONAL([HAVE_WINDRES], [test "$WINDRES" != ':'])
   ])
 
 AC_DEFINE_UNQUOTED([PATH_SEPARATOR_CHAR],['$PATH_SEPARATOR'],
diff --git a/src/w32/utf8.manifest b/src/w32/utf8.manifest
new file mode 100644
index 00000000..dab929e1
--- /dev/null
+++ b/src/w32/utf8.manifest
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
+  <application>
+    <windowsSettings>
+      <activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
+    </windowsSettings>
+  </application>
+</assembly>
diff --git a/src/w32/utf8.rc b/src/w32/utf8.rc
new file mode 100644
index 00000000..62bdbdc3
--- /dev/null
+++ b/src/w32/utf8.rc
@@ -0,0 +1,3 @@
+#include <winuser.h>
+
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "utf8.manifest"
-- 
2.40.0

