Building on Windows
GnuCash Windows - Development Notes
Guile 1.8
GnuCash/Windows currently uses guile 1.6.x. Guile's development continues and the use of this old, no longer supported version of guile is blocking some improvements. Recent examples of this were:
- Guile 1.8.7 removed some deprecated functions. However, the replacement functions were not available in 1.6.x. Because of this, GnuCash has to carry a compatibility header. We were lucky to get away with that.
- Andy Wingo provided patches to make GnuCash work with the upcoming guile 2.0 and to remove our dependency on slib. These patches are incompatible with guile 1.6.x (and likely will always be), so they couldn't all be applied.
I have been attempting for some time to build a more recent version of guile but this turns out to be rather difficult. At the time of this writing, I have a working guile, save it won't load slib. There were many small things I had to do to get to this point. In order not to forget them, I've chosen to document them here.
Getting it to build
The 1.8.7 tarball you can download from guile's homepage won't build in our GnuCash mingw/MSYS environment.
- First error is that our version of automake is too old. Guile requires 1.11, GnuCash still builds with 1.10 at the time of this writing. Luckily, this can easily be fixed by updating the version in defaults.sh and rebuilding the autotools/libtool packages.
- Guile 1.8.7 no longer contains its own libltdl implementation. This is provided with libtool though. All it required to fix this was to add the proper paths to CPPFLAGS and LDFLAGS.
- Also new is that guile now requires gmp. Another addition to CPPFLAGS and LDFLAGS solves this.
- Next is libintl. GnuCash builds this as part of the Gnome packages. However, we pull in the gnome libraries after we build guile. This doesn't work. So the build script has to be modified to first do the gnome install and then build guile.
- Guile 1.8.7 still recognizes the configure time option --disable-networking, yet it won't build on Windows if this option is set. So this option should be removed from the build script.
- Next, all kinds of unresolved symbol errors pop up. To fix most of them, I looked at the source package of MSYS-guile-1.8.7. They apparently managed to build guile, so it provided a good starting point. I can't use their patches verbatim, because that would result in a guile package that depends on the MSYS environment. Their patch for config.in was very useful though. To build build with this patch, the configure script has to be rebuilt, using autoreconf. This in itself was a bit of a quest. It wouldn't work unless I redefined ACLOCAL and passed autoreconf a number of library paths.
- I also learned from the MSYS-guile project that guile should be built with "-Wl,enable-auto-import" to avoid a number of linker warnings (which are treated as errors in our build process).
ERROR: In procedure scm_i_lreadparen: #<unknown port>:1:7: end of file.
It took me quite a while to grasp this one. I found several threads on different mailing lists about the error, which where more or less helpful:
- http://www.mail-archive.com/bug-guile@gnu.org/msg04711.html, which at some point links to http://lists-archives.org/mingw-users/14268-problem-with-argc-argv-under-msys.html, which in turn refers to http://thread.gmane.org/gmane.comp.gnu.mingw.msys/3719. The solution mentioned here, didn't apply in my case, but I got to understand the problem a little better.
- Then I was lucky enough to stumble upon two thread in the mingw-devel list: Again on windows support and Again on windows support (2). These are two long threads on building guile on windows and the issues in it. I learned here that the build process uses a wrapper program around the guile executable. Confusingly, this wrapper is called guile.exe as well, yet it has issues on windows, that the actual guile.exe doesn't have. So I wrote a small patch to use that actual guile.exe instead of the wrapper during the build process.
Result: the guile build process completes, and the guile binary works - provided it can find all of its library dependencies of course.
guile -c '(use-modules (srfi srfi-39))'runs with no problems.
slib
This is still problematic at this point.
guile -c "(use-modules (ice-9 slib)) (require 'printf)"results in this error:
ERROR: In procedure open-file: ERROR: No such file or directory: "C:/GCDevel/guile/share/guile/1.8/slib/C:/GCDevel/guile/share/guile/1.8/slib/require" ABORT: (system error)</pre>
Obviously there's something wrong with the path guile uses to find the file require.scm.
I'm still investigating what happens here.