Subject: bug#10474: Building guile 2.x under mingw + msys

From: Eli Zaretskii <[email-masked]>
Date: Tue, 24 Jan 2012 07:27:52 -0500

> Date: Sat, 21 Jan 2012 13:09:08 +0200
> From: Eli Zaretskii <[email-masked]>
> Cc: [email-masked], [email-masked]
> 
> This completes the description of problems I needed to overcome for
> building Guile with MinGW+MSYS.

Well, it turns out there's more to tell:

1. First, I forgot to tell before that I needed to configure with

     CPPFLAGS='-D_WIN32_WINNT=0x0501' ./configure ...

because if I don't use CPPFLAGS='-D_WIN32_WINNT=0x0501, the configure
script claims various network-related functions, like getaddrinfo and
getnameinfo) are not available, which is a lie.

2. Warning messages from guile-snarf-docs:

     ./guile-snarf-docs -o memoize.doc memoize.c -- -DHAVE_CONFIG_H -DBUILDING_LIBGUILE=1 -I.. -I.. -I../lib -I../lib -Id:/usr/include   -D_WIN32_WINNT=0x0501 -I/d/usr/include -Id:/usr/include   -g -O2
     memoize.c:479:***Mismatching FUNC_NAME.  Should be: `#define FUNC_NAME s_"@prompt"'
     ./guile-snarf-docs -o pairs.doc pairs.c -- -DHAVE_CONFIG_H -DBUILDING_LIBGUILE=1 -I.. -I.. -I../lib -I../lib -Id:/usr/include   -D_WIN32_WINNT=0x0501 -I/d/usr/include -Id:/usr/include   -g -O2
     pairs.c:147:***Missing or erroneous `#define FUNC_NAME s_scm_cdr'
     pairs.c:150:***Missing or erroneous #undef for scm_car:
     pairs.c:155:***Missing or erroneous `#define FUNC_NAME s_scm_cddr'
     pairs.c:158:***Missing or erroneous #undef for scm_cdar:
     pairs.c:163:***Missing or erroneous `#define FUNC_NAME s_scm_cadr'
     pairs.c:166:***Missing or erroneous #undef for scm_caar:
     pairs.c:171:***Missing or erroneous `#define FUNC_NAME s_scm_cdddr'
     pairs.c:174:***Missing or erroneous #undef for scm_cddar:
     pairs.c:179:***Missing or erroneous `#define FUNC_NAME s_scm_cdadr'
     pairs.c:182:***Missing or erroneous #undef for scm_cdaar:
     pairs.c:187:***Missing or erroneous `#define FUNC_NAME s_scm_caddr'
     pairs.c:190:***Missing or erroneous #undef for scm_cadar:
     pairs.c:195:***Missing or erroneous `#define FUNC_NAME s_scm_caadr'
     pairs.c:198:***Missing or erroneous #undef for scm_caaar:
     pairs.c:203:***Missing or erroneous `#define FUNC_NAME s_scm_cddddr'
     pairs.c:206:***Missing or erroneous #undef for scm_cdddar:
     pairs.c:211:***Missing or erroneous `#define FUNC_NAME s_scm_cddadr'
     pairs.c:214:***Missing or erroneous #undef for scm_cddaar:
     pairs.c:219:***Missing or erroneous `#define FUNC_NAME s_scm_cdaddr'
     pairs.c:222:***Missing or erroneous #undef for scm_cdadar:
     pairs.c:227:***Missing or erroneous `#define FUNC_NAME s_scm_cdaadr'
     pairs.c:230:***Missing or erroneous #undef for scm_cdaaar:
     pairs.c:235:***Missing or erroneous `#define FUNC_NAME s_scm_cadddr'
     pairs.c:238:***Missing or erroneous #undef for scm_caddar:
     pairs.c:243:***Missing or erroneous `#define FUNC_NAME s_scm_cadadr'
     pairs.c:246:***Missing or erroneous #undef for scm_cadaar:
     pairs.c:251:***Missing or erroneous `#define FUNC_NAME s_scm_caaddr'
     pairs.c:254:***Missing or erroneous #undef for scm_caadar:
     pairs.c:259:***Missing or erroneous `#define FUNC_NAME s_scm_caaadr'
     pairs.c:262:***Missing or erroneous #undef for scm_caaaar:

These come from the guile-func-name-check Awk script, because the
offending functions indeed lack the usual "#define FUNC_NAME" and
"#undef FUNC_NAME" directives.

Are these problems real?  If not, I'd suggest to modify the Awk script
to not emit them: people might get alarmed without a good reason.

3. Error messages from makeinfo:

     rm -f guile-procedures.txt
     makeinfo --force -o guile-procedures.txt guile-procedures.texi || test -f guile-procedures.txt
     d:\usr\eli\utils\guile-2.0.3\libguile//guile-procedures.texi:10720: Cross reference to nonexistent node `Backslash Escapes' (perhaps incorrect sectioning?).
     d:\usr\eli\utils\guile-2.0.3\libguile//guile-procedures.texi:10415: Cross reference to nonexistent node `Network Address Conversion' (perhaps incorrect sectioning?).

and many more similar errors.

This is because guile-procedures.texi is not a complete Texinfo
source.  Since this command just generates a plain-text document, I
suggest to add --no-validate to makeinfo command-line switches.

4. Error in "make install-strip":

     make  install-data-hook
     make[5]: Entering directory `/d/usr/eli/utils/guile-2.0.3/meta'
     cd /d/usr/test/bin && rm -f guile-tools.exe && \
	     cp -p guild.exe guile-tools.exe
     cp: cannot stat `guild.exe': No such file or directory
     make[5]: *** [install-data-hook] Error 1

This happens because meta/Makefile.am has this:

     # What we now call `guild' used to be known as `guile-tools'.
     install-data-hook:
	     cd $(DESTDIR)$(bindir) && rm -f guile-tools$(EXEEXT) && \
	     $(LN_S) guild$(EXEEXT) guile-tools$(EXEEXT)

The $(EXEEXT) part should be removed.

5. Invoking the installed guile.exe aborts:

     D:\usr\test>guile
     Backtrace:
     In ice-9/boot-9.scm:
      162: 7 [catch #t #<catch-closure d47380> ...]
      170: 6 [#<procedure cf4a50 ()>]
     In unknown file:
	?: 5 [catch-closure]
     In ice-9/boot-9.scm:
       62: 4 [call-with-prompt prompt0 ...]
     In ice-9/top-repl.scm:
       33: 3 [#<procedure cf84f0 at ice-9/top-repl.scm:31:6 (thunk)> #<procedure cf8370 at ice-9/top-repl.scm:66:5 ()>]
       76: 2 [#<procedure cf8370 at ice-9/top-repl.scm:66:5 ()>]
     In system/repl/repl.scm:
      135: 1 [start-repl scheme #:debug #f]
     In system/repl/common.scm:
      139: 0 [make-repl scheme #f]

     system/repl/common.scm:139:25: In procedure make-repl:
     system/repl/common.scm:139:25: In procedure module-lookup: Unbound variable: times

This happens because HAVE_TIMES is not defined, as Windows doesn't
have `times' and the corresponding gnulib module was not imported to
Guile.

Like the problems with poll.scm, it sounds unwise to call at startup
procedures that depend on optional features which may not exist on the
underlying platform.  If guile.exe depends on some of these features,
it should fail to build if they don't exist.

I solved this by copy/pasting gnulib's times.c into stime.c.

6. I noticed that changes in C sources do not trigger recompilation of
   the *.scm files.  Should they?

7. guile.exe aborts again at startup:

     D:\usr\test>guile
     GNU Guile 2.0.3
     Copyright (C) 1995-2011 Free Software Foundation, Inc.

     Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
     This program is free software, and you are welcome to redistribute it
     under certain conditions; type `,show c' for details.

     Enter `,help' for help.
     While reading expression:
     ERROR: In procedure fport_input_waiting: Not fully implemented on this platform
     Backtrace:
     In ice-9/boot-9.scm:
      162: 10 [catch #t #<catch-closure d47370> ...]
      170: 9 [#<procedure cf4a50 ()>]
     In unknown file:
	?: 8 [catch-closure]
     In ice-9/boot-9.scm:
       62: 7 [call-with-prompt prompt0 ...]
     In ice-9/top-repl.scm:
       33: 6 [#<procedure cf8510 at ice-9/top-repl.scm:31:6 (thunk)> #<procedure cf8390 at ice-9/top-repl.scm:66:5 ()>]
       76: 5 [#<procedure cf8390 at ice-9/top-repl.scm:66:5 ()>]
     In system/repl/repl.scm:
      153: 4 [run-repl #]
      158: 3 [#<procedure f94660 ()>]
      125: 2 [#<procedure f9c5d0 at system/repl/repl.scm:118:4 (key . args)> misc-error ...]
      102: 1 [flush-all-input]
     In unknown file:
	?: 0 [char-ready? #<undefined>]

     ERROR: In procedure char-ready?:
     ERROR: In procedure fport_input_waiting: Not fully implemented on this platform

This is because Windows has neither `poll' nor `select' nor FIONREAD,
which are the 3 mechanisms supported by fport_input_waiting.

I solved it by adding this to fports.c:

     #elif defined (__MINGW32__)
       DWORD input_events;

       if (!GetNumberOfConsoleInputEvents (_get_osfhandle (fdes), &input_events))
	 scm_syserror ("fport_input_waiting");
       return (int) input_events;

and also the necessary definition of struct tms needed by stime.c.
But really the gnulib `select' module should be imported into Guile,
because the above will DTRT only for keyboard input ports.

This, finally, allows to start up guile.exe and type several simple
commands.

HTH