[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
- Re: Building sharutils 4.13.4 with MinGW,
Eli Zaretskii <=