Please find attached the latest patch with everything done so far,
including the inconsistency I mentioned in my previous email.

This now has all 3 build approaches, namely:

1) configure
2) Basic.mk
3) build_w32.bat

treating the resource compiler optionally, and building and
embedding the UTF-8 resource if it is found.    This applies
for all supported compilers.

I think this has everything discussed and agreed so far.

Please let me know what you think.

On Thu, 18 May 2023 at 12:38, Costas Argyris <costas.argy...@gmail.com>
wrote:

> I think this should be added to README.git.  Without these
> explanations, the purpose of Basic.mk and its auxiliary files, and of
> their intended usage, is completely unclear.
>
> I believe this was going to Paul.    From my side, these explanations
> were really helpful.
>
> On to the Basic.mk patch, please see the latest one attached in this email.
>
> After regenerating Basic.mk from .\bootstrap.bat, I tried running it with
> both msvc and gcc values for TOOLCHAIN and they both worked fine.
>
> I also tried the 'no resource compiler' case by temporarily renaming
> 'rc.exe' (msvc) and 'windres.exe' (gcc) to something else so they are
> not found on the Windows path, and the build just went through with
> no errors and produced non-utf8 GNU Make binaries.
>
> As you will see, in mk/Windows32.mk I used:
>
> ifneq (, $(shell where $(RC) 2>nul))
>
> to tell if a program is on the Windows path.    It seems to be working fine
> in both cases of 'found' and 'not-found', but I am no GNU Make expert so
> please let me know if this is correct.
>
> A little inconsistency is that in build_w32.bat I didn't implement a check
> for 'rc.exe' because I assumed it's always going to be in the Windows
> path if the compiler 'cl.exe' is, but in mk/Windows32.mk I did implement
> the check even for 'rc.exe' - I can add the check in build_w32.bat to be
> consistent in a next update, it should be easy.
>
> Also just checking - the configury approach, when building for Windows
> host, can't be used with msvc or tcc, right?    It needs to find gcc
> targeting Windows, and therefore checking for windres (already
> implemented) should be sufficient, right?
>
> On Thu, 18 May 2023 at 06:31, Eli Zaretskii <e...@gnu.org> wrote:
>
>> > From: Paul Smith <psm...@gnu.org>
>> > Cc: bug-make@gnu.org
>> > Date: Wed, 17 May 2023 18:04:55 -0400
>> >
>> > To remind: the purpose of these is to provide a makefile-based way to
>> > _develop_ GNU Make itself, on platforms where we can't run ./configure
>> > to get an automake-generated makefile.
>> >
>> > If you need to build GNU Make from scratch there's not much benefit
>> > from using Basic.mk, because it will just rebuild everything every time
>> > just like the build_w32.bat etc. files.  You don't save anything.
>> >
>> > But if you're doing ongoing development (edit/build/test cycle) and you
>> > don't want to have to recompile all files every time you change
>> > something, and you can't run ./configure, then you can use an already-
>> > built GNU Make and these makefiles to shorten your development cycle.
>>
>> I think this should be added to README.git.  Without these
>> explanations, the purpose of Basic.mk and its auxiliary files, and of
>> their intended usage, is completely unclear.
>>
>
From f7d5cf83e5ceaa0d008f9b6b0e57d05ec541ef9a Mon Sep 17 00:00:00 2001
From: Costas Argyris <costas.argy...@gmail.com>
Date: Sat, 25 Mar 2023 21:51:41 +0000
Subject: [PATCH] Add UTF-8 resource when building for Windows host, if a
 resource compiler is available. As a result, the produced GNU Make Windows
 executable will use UTF-8 as its ANSI code page, enabling it to work with
 UTF-8 encoded Makefiles, understand UTF-8 paths passed to it, etc.

These build process changes apply to all 3 ways
that GNU Make can be built for Windows:

1) configure
2) Basic.mk
3) build_w32.bat

When building with VS the resource compiler should
always be available.

When building with GCC or TCC, it depends on the
availability of 'windres'.

If a resource compiler is not available, don't
fail the build but just proceed without the UTF-8
resource, effectively ignoring this feature.

The UTF-8 resource only has an effect when GNU Make
is running on a minimum target version of:

Windows Version 1903 (May 2019 Update).

When the built GNU Make is running on an earlier
version of Windows, the embedded UTF-8 resource
has no effect at all.

Code page information gets added to --version output
to tell users what code pages are being used by any
combination of GNU Make build (with or without the
UTF-8 resource) and Windows version that GNU Make is
running on (earlier than 1903 or not).

Signed-off-by: Costas Argyris <costas.argy...@gmail.com>
---
 .gitignore            |  2 ++
 Basic.mk.template     |  6 ++++--
 Makefile.am           | 11 +++++++++++
 README.git            |  2 +-
 build_w32.bat         | 46 ++++++++++++++++++++++++++++++++++++++++---
 configure.ac          |  5 +++++
 mk/Windows32.mk       | 17 ++++++++++++++++
 src/main.c            |  5 +++++
 src/w32/utf8.manifest |  8 ++++++++
 src/w32/utf8.rc       |  3 +++
 10 files changed, 99 insertions(+), 6 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/Basic.mk.template b/Basic.mk.template
index e3a83a20..ce273a1f 100644
--- a/Basic.mk.template
+++ b/Basic.mk.template
@@ -59,6 +59,8 @@ BUILT_SOURCES =
 
 OBJECTS = $(patsubst %.c,$(OUTDIR)%.$(OBJEXT),$(prog_SOURCES))
 
+RESOURCE_OBJECTS =
+
 OBJDIRS = $(addsuffix .,$(sort $(dir $(OBJECTS))))
 
 # Use the default value of CC
@@ -99,7 +101,7 @@ RM.cmd = rm -f $1
 # $(call CP.cmd,<from>,<to>)
 CP.cmd = cp $1 $2
 
-CLEANSPACE = $(call RM.cmd,$(OBJECTS) $(PROG) $(BUILT_SOURCES))
+CLEANSPACE = $(call RM.cmd,$(OBJECTS) $(RESOURCE_OBJECTS) $(PROG) $(BUILT_SOURCES))
 
 # Load overrides for the above variables.
 include $(firstword $(wildcard $(SRCDIR)/mk/$(lastword $(subst -, ,$(MAKE_HOST)).mk)))
@@ -108,7 +110,7 @@ VPATH = $(SRCDIR)
 
 all: $(PROG)
 
-$(PROG): $(OBJECTS)
+$(PROG): $(OBJECTS) $(RESOURCE_OBJECTS)
 	$(call LINK.cmd,$^)
 
 $(OBJECTS): $(OUTDIR)%.$(OBJEXT): %.c
diff --git a/Makefile.am b/Makefile.am
index 23a48e47..dc519bf2 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
 
@@ -88,6 +90,15 @@ else
   make_SOURCES += src/posixos.c
 endif
 
+UTF8OBJ = src/w32/utf8.$(OBJEXT)
+
+if HAVE_WINDRES
+  make_LDADD += $(UTF8OBJ)
+endif
+
+$(UTF8OBJ) : $(w32_utf8_SRCS)
+	$(WINDRES) -o $@ -i $<
+
 if USE_CUSTOMS
   make_SOURCES += src/remote-cstms.c
 else
diff --git a/README.git b/README.git
index 03125fa9..0e0c327e 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 3abc43ed..049c7e41 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
@@ -183,7 +186,7 @@ if "%MAINT%" == "Y" set "OPTS=%OPTS% /D MAKE_MAINTAINER_MODE"
 :: Unfortunately this also shows a "usage" note; I can't find anything better.
 echo.
 call %COMPILER%
-goto Build
+goto FindRC
 
 :FindGcc
 set OUTDIR=.\GccRel
@@ -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 FindRC
 echo No %COMPILER% found.
 exit 1
 
@@ -212,11 +215,21 @@ 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 FindRC
 echo No %COMPILER% found.
 exit 1
 
+:FindRC
+set HAVE_RC=Y
+call where %RC% >nul 2>nul
+if not ERRORLEVEL 1 goto Build
+echo.
+echo %RC% was not found. Building without UTF-8 resource.
+set HAVE_RC=N
+goto Build
+
 :Build
+echo.
 :: Clean the directory if it exists
 if exist %OUTDIR%\nul rmdir /S /Q %OUTDIR%
 
@@ -285,6 +298,9 @@ call :Compile lib/getloadavg
 :: Compile dirent unless it is supported by compiler library (like with gcc).
 if "%DIRENT%" == "Y" call :Compile src\w32\compat\dirent
 
+:: Compile UTF-8 resource if a resource compiler is available.
+if "%HAVE_RC%" == "Y" call :ResourceCompile src/w32/utf8
+
 call :Link
 
 echo.
@@ -332,6 +348,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 645b4466..c6741003 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([MK_OS_W32], [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/mk/Windows32.mk b/mk/Windows32.mk
index 57226eb1..6e357ea7 100644
--- a/mk/Windows32.mk
+++ b/mk/Windows32.mk
@@ -30,6 +30,8 @@ P2W = $(subst /,\,$1)
 
 prog_SOURCES += $(loadavg_SOURCES) $(glob_SOURCES) $(w32_SOURCES)
 
+utf8_SOURCES = $(src)w32/utf8.rc $(src)w32/utf8.manifest
+
 BUILT_SOURCES += $(lib)alloca.h $(lib)fnmatch.h $(lib)glob.h
 
 w32_LIBS = kernel32 user32 gdi32 winspool comdlg32 advapi32 shell32 ole32 \
@@ -41,6 +43,7 @@ LDFLAGS =
 
 # --- Visual Studio
 msvc_CC = cl.exe
+msvc_RC = rc.exe
 msvc_LD = link.exe
 
 msvc_CPPFLAGS = /DHAVE_CONFIG_H /DMK_OS_W32=1 /DWIN32 /D_CONSOLE
@@ -54,6 +57,7 @@ msvc_LDFLAGS = /nologo /SUBSYSTEM:console /PDB:$(BASE_PROG).pdb
 msvc_LDLIBS = $(addsuffix .lib,$(w32_LIBS))
 
 msvc_C_SOURCE = /c
+msvc_RC_SOURCE =
 msvc_OUTPUT_OPTION = /Fo$@
 msvc_LINK_OUTPUT = /OUT:$@
 
@@ -68,6 +72,7 @@ debug_msvc_LDFLAGS = /DEBUG
 
 # --- GCC
 gcc_CC = gcc
+gcc_RC = windres
 gcc_LD = $(gcc_CC)
 
 release_gcc_OUTDIR = ./GccRel/
@@ -79,6 +84,7 @@ gcc_LDFLAGS = -mthreads -gdwarf-2 -g3
 gcc_LDLIBS = $(addprefix -l,$(w32_libs))
 
 gcc_C_SOURCE = -c
+gcc_RC_SOURCE = -i
 gcc_OUTPUT_OPTION = -o $@
 gcc_LINK_OUTPUT = -o $@
 
@@ -87,6 +93,7 @@ release_gcc_CFLAGS = -O2
 
 # ---
 
+RES_COMPILE.cmd = $(RC) $(OUTPUT_OPTION) $(RC_SOURCE) $1
 LINK.cmd = $(LD) $(extra_LDFLAGS) $(LDFLAGS) $(TARGET_ARCH) $1 $(LDLIBS) $(LINK_OUTPUT)
 
 CHECK.cmd = cmd /c cd tests \& .\run_make_tests.bat -make ../$(PROG)
@@ -96,9 +103,11 @@ RM.cmd = cmd /c del /F /Q $(call P2W,$1)
 CP.cmd = cmd /c copy /Y $(call P2W,$1 $2)
 
 CC = $($(TOOLCHAIN)_CC)
+RC = $($(TOOLCHAIN)_RC)
 LD = $($(TOOLCHAIN)_LD)
 
 C_SOURCE = $($(TOOLCHAIN)_C_SOURCE)
+RC_SOURCE = $($(TOOLCHAIN)_RC_SOURCE)
 OUTPUT_OPTION = $($(TOOLCHAIN)_OUTPUT_OPTION)
 LINK_OUTPUT = $($(TOOLCHAIN)_LINK_OUTPUT)
 
@@ -120,3 +129,11 @@ LDLIBS = $(call _CUSTOM,LDLIBS)
 
 $(OUTDIR)src/config.h: $(SRCDIR)/src/config.h.W32
 	$(call CP.cmd,$<,$@)
+
+w32_UTF8OBJ = $(OUTDIR)src/w32/utf8.$(OBJEXT)
+$(w32_UTF8OBJ): $(utf8_SOURCES)
+	$(call RES_COMPILE.cmd,$<)
+
+ifneq (, $(shell where $(RC) 2>nul))
+RESOURCE_OBJECTS = $(w32_UTF8OBJ)
+endif
diff --git a/src/main.c b/src/main.c
index 6a94cfdb..da8b56c7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -3686,6 +3686,11 @@ print_version (void)
     printf (_("%sBuilt for %s (%s)\n"),
             precede, make_host, remote_description);
 
+  #if MK_OS_W32
+    printf ("%sANSI code page: %u\n", precede, GetACP());
+    printf ("%sConsole code page: %u\n", precede, GetConsoleOutputCP());
+  #endif
+
   /* Print this untranslated.  The coding standards recommend translating the
      (C) to the copyright symbol, but this string is going to change every
      year, and none of the rest of it should be translated (including the
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.1

Reply via email to