Paul Eggert wrote:
> I don't use MS-Windows and won't be of much help on that platform.
> ...
> A few minutes ago I also installed a patch that causes diff -r to use 
> readlinkat instead of readlink

I took a stab at it and attempted to compile diffutils with mingw 10.0.0
and with MSVC 14.30. Here are the compilation errors and link errors that
I encountered. I'm attaching a fix for all issues. With it, the build
succeeds, and there are
  - 13 test failures on mingw,
  - 14 test failures on MSVC.

1) A compilation error (both mingw and MSVC):

../../lib/cmpbuf.c: In function 'block_read':
../../lib/cmpbuf.c:87:17: error: 'SA_RESTART' undeclared (first use in this 
function)
   87 |           if (! SA_RESTART && errno == EINTR)
      |                 ^~~~~~~~~~

This is fixed by adding 'sigaction' to the list of gnulib modules.

2) A compilation error (both mingw and MSVC):

../../src/util.c: In function 'process_signals':
../../src/util.c:277:17: error: 'SIGSTOP' undeclared (first use in this 
function)
  277 |           sig = SIGSTOP;
      |                 ^~~~~~~

This is fixed by adding the same '#ifdef SIGTSTP' in the stop signal processing
as elsewhere in the file.

3) A compilation error (both mingw and MSVC):

../../src/util.c:308:5: error: 'SIGHUP' undeclared here (not in a function)
  308 |     SIGHUP, SIGINT, SIGPIPE,
      |     ^~~~~~
../../src/util.c:308:21: error: 'SIGPIPE' undeclared here (not in a function); 
did you mean 'SIGFPE'?
  308 |     SIGHUP, SIGINT, SIGPIPE,
      |                     ^~~~~~~
      |                     SIGFPE

This is fixed by adding #ifdefs for the use of these signal names.
For SIGPIPE, an alternative would be to use the gnulib module 'signal-h',
but that feels like overkill here.

4) A compilation error (mingw) or link error (MSVC):

../../src/diff.c: In function 'compare_files':
../../src/diff.c:1412:58: error: 'readlinkat' undeclared (first use in this 
function); did you mean 'careadlinkat'?
 1412 |                                                 nullptr, readlinkat);
      |                                                          ^~~~~~~~~~
      |                                                          careadlinkat

This is fixed by adding 'readlinkat' to the list of gnulib modules.

5) Link errors (on MSVC):

diff3.obj : error LNK2019: unresolved external symbol popen referenced in 
function read_diff
diff3.obj : error LNK2019: unresolved external symbol pclose referenced in 
function read_diff
sdiff.obj : error LNK2019: unresolved external symbol popen referenced in 
function main
sdiff.obj : error LNK2019: unresolved external symbol pclose referenced in 
function main

This is fixed by adding 'popen' and 'pclose' to the list of gnulib modules.

6) A link error (on MSVC) regarding readdir.

This is fixed by adding 'readdir' to the list of gnulib modules.

7) A link error (on mingw):

/usr/lib/gcc/x86_64-w64-mingw32/11/../../../../x86_64-w64-mingw32/bin/ld: 
../lib/libdiffutils.a(libdiffutils_a-strerror.o): in function `memcpy':
/usr/x86_64-w64-mingw32/sys-root/mingw/include/string.h:202: undefined 
reference to `__memcpy_chk'
/usr/lib/gcc/x86_64-w64-mingw32/11/../../../../x86_64-w64-mingw32/bin/ld: 
../lib/libdiffutils.a(libdiffutils_a-strerror.o): in function `sprintf':
/usr/x86_64-w64-mingw32/sys-root/mingw/include/stdio.h:386: undefined reference 
to `__chk_fail'
/usr/lib/gcc/x86_64-w64-mingw32/11/../../../../x86_64-w64-mingw32/bin/ld: 
../lib/libdiffutils.a(libdiffutils_a-localcharset.o): in function `strcpy':
/usr/x86_64-w64-mingw32/sys-root/mingw/include/string.h:228: undefined 
reference to `__strcpy_chk'
/usr/lib/gcc/x86_64-w64-mingw32/11/../../../../x86_64-w64-mingw32/bin/ld: 
../lib/libdiffutils.a(libdiffutils_a-localcharset.o): in function `sprintf':
/usr/x86_64-w64-mingw32/sys-root/mingw/include/stdio.h:386: undefined reference 
to `__chk_fail'
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:2013: cmp.exe] Error 1

Apparently the _FORTIFY_SOURCE support in mingw is experimental. Other
people have noticed it as well:
https://github.com/msys2/MINGW-packages/issues/5868

The fix is to not define _FORTIFY_SOURCE on this platform. Done in
configure.ac.

Bruno

>From 9814f76b8fe272ea4d22beba71e00b8a2a5a59b4 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Tue, 25 Jul 2023 15:26:23 +0200
Subject: [PATCH] maint: Fix build failures mingw 10 and MSVC 14.30

* bootstrap.conf (gnulib_modules): Add popen, pclose, readdir,
readlinkat, sigaction.
* configure.ac: Don't enable _FORTIFY_SOURCE on mingw.
* src/util.c (process_signals): If SIGTSTP is not defined,
stop_signal_count is zero, therefore disable the stop signal processing.
(sig): If SIGHUP is not defined, don't list it. If SIGPIPE is not
defined, don't list it.
---
 bootstrap.conf |  5 +++++
 configure.ac   |  3 ++-
 src/util.c     | 13 +++++++++++--
 3 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/bootstrap.conf b/bootstrap.conf
index 55ff67b..3815596 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -79,15 +79,20 @@ mktime
 nstrftime
 nullptr
 openat
+pclose
 perl
+popen
 progname
 propername-lite
 raise
 rawmemchr
+readdir
+readlinkat
 readme-release
 regex
 same-inode
 sh-quote
+sigaction
 signal
 sigprocmask
 stat
diff --git a/configure.ac b/configure.ac
index 1804cb3..19f4c16 100644
--- a/configure.ac
+++ b/configure.ac
@@ -127,7 +127,8 @@ if test $gl_gcc_warnings != no; then
   AH_VERBATIM([FORTIFY_SOURCE],
   [/* Enable compile-time and run-time bounds-checking, and some warnings,
       without upsetting glibc 2.15+. */
-   #if !defined _FORTIFY_SOURCE && defined __OPTIMIZE__ && __OPTIMIZE__
+   #if !defined _FORTIFY_SOURCE && defined __OPTIMIZE__ && __OPTIMIZE__ \
+       && !defined __MINGW32__
    # define _FORTIFY_SOURCE 2
    #endif
   ])
diff --git a/src/util.c b/src/util.c
index 69b7831..b9a0f59 100644
--- a/src/util.c
+++ b/src/util.c
@@ -266,7 +266,9 @@ process_signals (void)
 
       /* Reload stop_signal_count and (if needed) interrupt_signal, in
 	 case a new signal was handled before sigprocmask took effect.  */
-      int stops = stop_signal_count, sig;
+      int sig;
+#ifdef SIGTSTP
+      int stops = stop_signal_count;
 
       /* SIGTSTP is special, since the application can receive that signal
          more than once.  In this case, don't set the signal handler to the
@@ -277,6 +279,7 @@ process_signals (void)
           sig = SIGSTOP;
         }
       else
+#endif
 	{
 	  sig = interrupt_signal;
 	  xsignal (sig, SIG_DFL);
@@ -305,7 +308,13 @@ static int const sig[] =
 #ifdef SIGALRM
     SIGALRM,
 #endif
-    SIGHUP, SIGINT, SIGPIPE,
+#ifdef SIGHUP
+    SIGHUP,
+#endif
+    SIGINT,
+#ifdef SIGPIPE
+    SIGPIPE,
+#endif
 #ifdef SIGQUIT
     SIGQUIT,
 #endif
-- 
2.34.1

Reply via email to