bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Building sharutils 4.13.4 with MinGW


From: Eli Zaretskii
Subject: Re: Building sharutils 4.13.4 with MinGW
Date: Sun, 07 Apr 2013 20:35:50 +0300

Here are the MinGW-specific problems with building and testing this
release (copy to gnulib list, because many issues are related to
gnulib modules).

1. Compilation fails in lib/:

     gcc -DHAVE_CONFIG_H -I. -I..  -I../intl -Id:/usr/include  -g3 -O2 
-Wno-format-contains-nul -MT idcache.o -MD -MP -MF .deps/idcache.Tpo -c -o 
idcache.o idcache.c

     In file included from idcache.c:21:0:
     idcache.h:6:23: error: unknown type name 'uid_t'
     idcache.h:7:24: error: unknown type name 'gid_t'
     idcache.h:8:1: error: unknown type name 'uid_t'
     idcache.h:9:1: error: unknown type name 'gid_t'
     idcache.c:25:17: fatal error: pwd.h: No such file or directory
     compilation terminated.
     make[4]: *** [idcache.o] Error 1

   This is because idcache.h includes sys/types.h, but gnulib's
   sys/types.h does not define uid_t and gid_t, and also there are no
   pwd.h and grp.h in lib/.

   My solution was to add private pwd.h and grp.h to lib/, and modify
   idcache.h to include them.  But I guess a better solution would be
   to import more from gnulib, or perhaps enhance the corresponding
   gnulib modules.

2. Compilation warning in lib/:

     gcc -DHAVE_CONFIG_H -I. -I..  -I../intl -Id:/usr/include  -g3 -O2 
-Wno-format-contains-nul -MT idcache.o -MD -MP -MF .deps/idcache.Tpo -c -o 
idcache.o idcache.c

     idcache.c: In function 'getuser':
     idcache.c:85:30: warning: initialization makes pointer from integer 
without a cast [enabled by default]
     idcache.c: In function 'getgroup':
     idcache.c:167:29: warning: initialization makes pointer from integer 
without a cast [enabled by default]

   This is because functions getpwuid and getgrgid are unavailable and
   there are no replacements for them in gnulib.

   To solve this, I added the missing functions to idcache.c:

--- sharutils-4.13.4.orig/lib/idcache.c 2013-03-31 21:03:14.000000000 +0300
+++ sharutils-4.13.4/lib/idcache.c      2013-04-03 12:51:30.807618000 +0300
@@ -62,6 +62,70 @@ static struct userid *group_alist;
 /* Each entry on list is a group name for which the first lookup failed.  */
 static struct userid *nogroup_alist;
 
+#ifdef __MINGW32__
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <lmcons.h>
+uid_t
+getuid (void)
+{
+  return 42;
+}
+
+struct passwd *
+getpwuid (uid_t uid)
+{
+  static char uname[UNLEN+1];
+  static char homedir[FILENAME_MAX];
+  DWORD unsz = sizeof (uname);
+  static struct passwd user_rec;
+
+  if (uname[0] == '\0')
+    GetUserName (uname, &unsz);
+  if (homedir[0] == '\0')
+    {
+      char *home = getenv ("HOME");
+
+      if (home)
+       strcpy (homedir, home);
+      else
+       {
+         home = getenv ("HOMEDRIVE");
+         if (home)
+           strcpy (homedir, home);
+         home = getenv ("HOMEPATH");
+         if (home)
+           strcat (homedir, home);
+       }
+    }
+  user_rec.pw_uid = uid;
+  user_rec.pw_name = uname;
+  user_rec.pw_dir = homedir;
+
+  return &user_rec;
+}
+
+struct passwd *
+getpwnam (const char *user)
+{
+  return getpwuid (1004);
+}
+
+struct group *
+getgrgid (gid_t gid)
+{
+  static struct group grp_rec = { 42, "Users" };
+
+  return &grp_rec;
+}
+
+struct group *
+getgrnam (const char *group)
+{
+  return getgrgid (42);
+}
+#endif
+
 /* Translate UID to a login name, with cache, or NULL if unresolved.  */
 
 char *


3. Compilation warnings in src/shar.c:

     gcc -DLOCALEDIR=\"d:/usr/share/locale\" -DHAVE_CONFIG_H -I. -I..  
-I../libopts -I. -I.. -I../lib -I../intl -Id:/usr/include 
-Wno-format-contains-nul -g3 -O2 -Wno-format-contains-nul -MT shar.o -MD -MP 
-MF .deps/shar.Tpo -c -o shar.o shar.c
     shar.c: In function 'walktree':
     shar.c:595:18: warning: assignment makes pointer from integer without a 
cast [enabled by default]
     shar.c: In function 'set_submitter':
     shar.c:1943:18: warning: initialization makes pointer from integer without 
a cast [enabled by default]
     make[2]: *** [shar.o] Error 1

   The problem here is with basename and dirname, whose declarations
   are absent.  My solution was to add "#include <libgen.h>" to
   lib/system.h (libgen.h in MinGW declares basename and dirname).
   However, I wonder if gnulib has a better solution.

4. Link errors for shar.exe:

     gcc -Wno-format-contains-nul -g3 -O2 -Wno-format-contains-nul   -o 
shar.exe shar.o encode.o shar-opts.o -lws2_32 -lws2_32 ../libopts/libopts.a 
../lib/libgnu.a ../intl/libintl.a d:/usr/lib/libiconv.dll.a -Ld:/usr/lib 
-lpthread ../lib/libgnu.a -lregex
     shar.o: In function `shar':
     d:\usr\eli\utils\sharutils-4.13.4\src/shar.c:1760: undefined reference to 
`wait'
     shar.o: In function `open_shar_input':
     d:\usr\eli\utils\sharutils-4.13.4\src/shar.c:1308: undefined reference to 
`pipe'
     d:\usr\eli\utils\sharutils-4.13.4\src/shar.c:1312: undefined reference to 
`fork'
     shar.o: In function `set_submitter':
     d:\usr\eli\utils\sharutils-4.13.4\src/shar.c:1943: undefined reference to 
`getuid'
     ../lib/libgnu.a(idcache.o): In function `getuidbyname':
     d:\usr\eli\utils\sharutils-4.13.4\lib/idcache.c:147: undefined reference 
to `getpwnam'
     ../lib/libgnu.a(idcache.o): In function `getgidbyname':
     d:\usr\eli\utils\sharutils-4.13.4\lib/idcache.c:229: undefined reference 
to `getgrnam'
     ../lib/libgnu.a(gethostname.o): In function `rpl_gethostname':
     d:\usr\eli\utils\sharutils-4.13.4\lib/gethostname.c:97: undefined 
reference to address@hidden'
     ../lib/libgnu.a(gethostname.o): In function `set_winsock_errno':
     d:\usr\eli\utils\sharutils-4.13.4\lib/w32sock.h:37: undefined reference to 
address@hidden'
     ../lib/libgnu.a(sockets.o): In function `close_fd_maybe_socket':
     d:\usr\eli\utils\sharutils-4.13.4\lib/sockets.c:51: undefined reference to 
address@hidden'
     d:\usr\eli\utils\sharutils-4.13.4\lib/sockets.c:59: undefined reference to 
address@hidden'
     ../lib/libgnu.a(sockets.o): In function `set_winsock_errno':
     d:\usr\eli\utils\sharutils-4.13.4\lib/w32sock.h:37: undefined reference to 
address@hidden'
     ../lib/libgnu.a(sockets.o): In function `ioctl_fd_maybe_socket':
     d:\usr\eli\utils\sharutils-4.13.4\lib/sockets.c:88: undefined reference to 
address@hidden'
     d:\usr\eli\utils\sharutils-4.13.4\lib/sockets.c:92: undefined reference to 
address@hidden'
     ../lib/libgnu.a(sockets.o): In function `set_winsock_errno':
     d:\usr\eli\utils\sharutils-4.13.4\lib/w32sock.h:37: undefined reference to 
address@hidden'
     ../lib/libgnu.a(sockets.o): In function `gl_sockets_startup':
     d:\usr\eli\utils\sharutils-4.13.4\lib/sockets.c:120: undefined reference 
to address@hidden'
     ../lib/libgnu.a(sockets.o): In function `gl_sockets_cleanup':
     d:\usr\eli\utils\sharutils-4.13.4\lib/sockets.c:148: undefined reference 
to address@hidden'
     collect2.exe: error: ld returned 1 exit status
     make[2]: *** [shar.exe] Error 1
     make[2]: Leaving directory `/d/usr/eli/utils/sharutils-4.13.4/src'
     make[1]: *** [all-recursive] Error 1
     make[1]: Leaving directory `/d/usr/eli/utils/sharutils-4.13.4'
     make: *** [all] Error 2

   The winsock-related errors are because of incorrect order of
   libraries on the link command line:

     -lws2_32 -lws2_32 ../libopts/libopts.a ../lib/libgnu.a ../intl/libintl.a 
d:/usr/lib/libiconv.dll.a -Ld:/usr/lib -lpthread ../lib/libgnu.a -lregex

   Solution: reorder in src/Makefile.in:

     LDADD = $(top_builddir)/libopts/libopts.a $(top_builddir)/lib/libgnu.a \
         $(LIBINTL) $(top_builddir)/lib/libgnu.a $(GETHOSTNAME_LIB) $(LIBSOCKET)

   For the other errors: I wrote emulations for fork (always fails),
   wait (always fails) and pipe (calls _pipe), and also add getuid,
   getpwnam and getgrnam to idcache.c.  However, I think gnulib has
   replacements for at least some of these functions.

5. Link errors for unshar.exe:

     gcc -Wno-format-contains-nul -g3 -O2 -Wno-format-contains-nul   -o 
unshar.exe unshar.o encode.o unshar-opts.o ../libopts/libopts.a ../lib/libgnu.a 
../intl/libintl.a d:/usr/lib/libiconv.dll.a -Ld:/usr/lib -lpthread 
../lib/libgnu.a -lws2_32 -lws2_32 -lregex
     unshar.o: In function `load_file':
     d:\usr\eli\utils\sharutils-4.13.4\src/unshar.c:310: undefined reference to 
`mkstemp'
     collect2.exe: error: ld returned 1 exit status
     make[2]: *** [unshar.exe] Error 1

   Solution: add mkstemp to unshar.c.  Again, I think gnulib has a
   module for that, so importing it will solve this.

6. uutest-1 test fails because the begin line doesn't match.  This is
   because the mode bits on Windows are not real, beyond the user-read
   and user-write bits.  So it would be nice if on Windows Diff would
   be invoked like this:

     DIFF="diff -I^begin"

7. shar-4 fails because it uses cmp to compare results with expected
   ones, which fails due to line endings.  Suggest to use Diff
   instead.

8. The configure script botches the popen-binary test: the test
   program does not include stdio.h, so the compilation fails for
   reasons that have no relation to the issue being tested.

9. Using -! or --more-help triggers an error message:

     d:\usr\eli\utils\sharutils-4.13.4>uuencode -!
     uuencode: illegal option -- !
     uuencode (GNU sharutils) - encode a file into email friendly text
     Usage:  uuencode [ -<flag> | --<name> ]... [<in-file>] <output-name>
     Try 'uuencode --help' for more information.

     d:\usr\eli\utils\sharutils-4.13.4>uuencode --more-help
     uuencode: illegal option -- more-help
     uuencode (GNU sharutils) - encode a file into email friendly text
     Usage:  uuencode [ -<flag> | --<name> ]... [<in-file>] <output-name>
     Try 'uuencode --help' for more information.

   This is confusing because --help does show these options as available.

   The reason is that uuencode-options.c does this:

     #if HAVE_WORKING_FORK
     #define MORE_HELP_DESC  (uuencode_opt_strs+1045)
     #define MORE_HELP_name  (uuencode_opt_strs+1090)
     #define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT)
     #else
     #define MORE_HELP_DESC  NULL  <<<<<<<<<<<<<<<<<<<<<<<<<
     #define MORE_HELP_name  NULL  <<<<<<<<<<<<<<<<<<<<<<<<<
     #define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)
     #endif

   which is unnecessary, since the relevant libopts code already knows
   how to handle the case of !HAVE_WORKING_FORK.

   => Fixed by enabling the !HAVE_WORKING_FORK block above.

   Same in shar-opts.c and uudecode-opts.c.

10.shar fails while processing files:

     d:\usr\eli\utils\sharutils-4.13.4>src\shar src\encode.c > foo.shar
     shar: Saving src/encode.c (text)
     The system cannot find the path specified.

   This is because emit_char_ct_validation invokes 'wc' with bad
   redirection:

     set LC_ALL=C & wc -c < 'src/encode.c'

   The file from which stdin is redirected uses forward slashes and is
   quoted with '..'.

   Solution: use a slightly different command for MinGW to run 'wc'
   locally:

     set LC_ALL=C & wc -c "src/encode.c"

--- sharutils-4.13.4.orig/src/shar.c    2013-03-23 00:23:48.000000000 +0200
+++ sharutils-4.13.4/src/shar.c 2013-04-07 13:41:14.742531000 +0300
@@ -1065,14 +1097,27 @@ emit_char_ct_validation (
   /* Shell command able to count characters from its standard input.
      We have to take care for the locale setting because wc in multi-byte
      character environments gets different results.  */
+#ifdef __MINGW32__
+  /* Windows needs a slightly different format to run wc locally:
+     redirection will fail because the file uses Unix forward
+     slashes.  */
+  static char const local_cmd[] = "set LC_ALL=C & wc -c";
+#endif
   static char const cct_cmd[] = "LC_ALL=C wc -c <";
 
   FILE *pfp;
   char wc[16 /* log MAX_INT + a few extra */];
-  char *command = alloca (sizeof(cct_cmd) + strlen (quoted_name) + 2);
  
+#ifdef __MINGW32__
+  /* On Windows, disregard Unix-style shell quoting and quote by hand
+     using "..".  */
+  char *command = alloca (sizeof(local_cmd) + strlen (local_name) + 2);
+  sprintf (command, "%s \"%s\"", local_cmd, local_name);
+#else
+  char *command = alloca (sizeof(cct_cmd) + strlen (quoted_name) + 2);
   sprintf (command, "%s %s", cct_cmd, quoted_name);
-  pfp = popen (command, "r");
+#endif
+  pfp = popen (command, freadonly_mode);
   if (pfp == NULL)
     die (SHAR_EXIT_FAILED, _("Could not popen command"), command);
 

11.shar.c uses /dev/null in freopen, but does not use the gnulib
   freopen module, which makes /dev/null work on MS-Windows.

There are a few other, less important issues, like with using binary
I/O in some places.  let me know if you want me to send diffs for
those.

HTH






reply via email to

[Prev in Thread] Current Thread [Next in Thread]