Windows

From GnuCash
Revision as of 15:21, 19 July 2006 by Cstim (talk | contribs) (Gnucash: add environment for tests)
Jump to: navigation, search

GnuCash on Microsoft Windows

This page collects various notes about potentially compiling GnuCash on Microsoft Windows.

FAQ: Is it possible to compile GnuCash on Windows? A: Well, compiling is possible, but it doesn't run so far.

With the 2.x series now being released, gnucash is fully based on gtk2. This means it will probably be rather easy to finish a full windows port. "The other big application" Gnumeric already showed how to do it. Their UI code relies solely on gtk-2.x, i.e. they replaced every dependency on libgnomeui by its gtk equivalent. And gtk-2.x is fully available on windows. Obviously they managed to do this somehow, so I suspect it shouldn't be too difficult to do the same with gnucash. Also, one of our smaller competitors, Grisbi http://sourceforge.net/projects/grisbi , is offering a windows port by this very same strategy.

Some old gnucash-devel discussion:

Status: It is possible to compile, but it doesn't run so far. --Cstim 07:55, 3 March 2006 (EST)

Prerequisites

Mingw32

See http://www.mingw.org . All available as pre-compiled binaries.

Many other pre-compiled binaries are also available from http://gnuwin32.sf.net/ . (All gtk-related packages like pkgconfig and libxml2, however, are already included in the large glade package, see below.)

SVN

There are multiple SVN clients for windows. The command-line program is in the http://subversion.tigris.org package. A GUI client that installs as a plugin to the Windows Explorer is on http://tortoisesvn.tigris.org .

guile

In guile-1.6.7 several tweaks were necessary to get it to compile.

  • File libguile/fports.c line 479: replace "#elif defined(FIONREAD)" by "#elif 0"
  • File libguile-ltdl/raw-ltdl.c lines 220, 222, 224: remove the LT_GLOBAL_DATA macro on each line. You might need to touch libguile-ltdl/upstream/ltdl.c.diff afterwards
  • Files srfi/Makefile, libguile-ltdl/Makefile, libguile/Makefile: Add "-no-undefined" argument to libxyz_LDFLAGS variables, see also [1]
  • Remove every occurence of fileblocks.* in config.status and run config.status.
  • Set the env variable GUILE_LOAD_PATH to the actual load path, which is different from the one that was stored during compile due to mingw's path translation. Make e.g. export GUILE_LOAD_PATH='\msys\1.0\local\share\guile\1.6'
  • For some srfi's, shared libraries are installed in $prefix/bin, e. g. libguile-srfi-srfi-13-14-v-1-1.dll. You need to copy these DLLs at the same location to a filename that does not have the last trailing "-1", which in this case is libguile-srfi-srfi-13-14-v-1.dll. On Linux, this would have been done by symlinks, but on windows due to the missing symlinks you have to do this copying yourself.

One possible set of configure arguments looked like this:

./configure --disable-elisp --disable-networking --disable-dependency-tracking --disable-libtool-lock --disable-linuxthreads -C --prefix=/usr/local LDFLAGS="-L/lib -L/mingw/lib -L/C/WINNT/system32 -lwsock32 -lregex"

For testing, first try to make sure "guile -v" will run and give you the version number. Then try a simple expression, like "guile -c '(display %load-path)'". However, so far I was unable to actually start the interactive interpreter (by simple "guile") because the readline library is unavailable. So running "guile" will give "ERROR: In procedure quasiquote: ERROR: Unbound variable: SIGBUS".

With the above DLL copying of srfi-13-14, code generation in g-wrap will actually work. It will will always show the error message "command 'indent' not found", though, but this can simply be ignored.

g-wrap

See http://savannah.nongnu.org/bugs/index.php?func=detailitem&item_id=15972 and the LDFLAGS=-no-undefined has to be added also to guile/g-wrap/gw/Makefile.

Status: Compile is possible.

Frequent error: If you get the following linker error:

C:/msys/1.0/mingw/bin/../lib/gcc/mingw32/3.4.4/libgcc.a(w32-shared-ptr.o):: 
undefined reference to `_imp__GetAtomNameA@12'
undefined reference to `_imp__FindAtomA@4'
undefined reference to `_imp__AddAtomA@4'
undefined reference to `_imp__FindAtomA@4'

then it means that your windows DLL directory showed up first before your mingw DLL directory, i. e. the gcc linker command has -Lc:\WINNT\system32 before -L/mingw/lib. This wrong order might be caused from other, linked-in libraries, like from the libguile.la file in guile's library installation. To fix this: Edit the libguile.la file, remove -Lc:\WINNT\system32 so that you can correctly enfore that /mingw/lib comes first in the library search path.

Later, if you encounter the error ERROR: file: "libgw-guile-standard", message: "can't open the module" then you need to locate the file libgw-guile-standard-0.dll in your g-wrap installation and copy it to the file name libgw-guile-standard.dll, i. e. without the trailing "-0". The DLL is probably located in the bin directory of your g-wrap installation. (If it's not and you still encounter this error, you might consider copying the DLL into the bin directory, too.)

glade

http://gladewin32.sourceforge.net This project offers a large (10MB) Installer which also includes all the rest of the gtk/glib platform, including pkgconfig, libxml2 and various other tools.

Note: After installation, the pkgconfig files have to be adapted to your installation path. See below in the gnome section for instructions.

glib

http://www.gtk.org/download/ has binary windows packages, but the binary is already included in the glade installer above, so no separate download is necessary.

gnome

A lot of windows binaries for gnome packages missing in the glade package can be found at ftp://ftp.gnome.org.

GConf, Orbit2, gail, gnome-{common, mime-data, vfs}, intltool, libIDL, libart_lgpl, libbonobo{,ui}, libgnome{,canvas,ui} and pango can be found at:

Libgnomeprint, libgnomeprintui and libgtkhtml can be found at:

GConf

After installation of gconf, check whether you can run the "gconftool-2.exe" program. If it doesn't show its usage message but instead fails with an error like "cannot find symbol freeaddrinfo in WS2_32.DLL", then your DLL of ORBit cannot be used on your system. In my case this error went away after upgrading ORBit to 2.13.3.

Paths in pkgconfig files

Important note: After installation of all these packages, you need to hand-edit all pkgconfig files in your $prefix/lib/pkgconfig directory. All of them will have a wrong prefix= line, because it contains the path at build time instead of your installed path at installation time. One easy way to do this is the following perl command, with your glade/gnomeui/etc installation at C:\GTK2-8-10 :

perl -pi.bak -e's!^prefix=.*$!prefix=C:/GTK2-8-10!' *.pc

which will modify all pkgconfig files in-place. After that, two additional files will still have paths from build-time, namely pangocairo.pc and pangoft2.pc, where the line with Cflags: has an include directive pointing to a build-time directory. Replace the /home/ivan/cross/build/include by ${includedir} and everything should be fine.

Gnucash

Initial notes about how to tweak ./configure so that it doesn't complain about the missing gnome packages (but eventually everything is written down in the text below):

(As gnucash uses symbolic links quite a lot, in the first build trials we used a trick to make use of symlinks: We completed a normal build on a SMB networked filesystem from a Linux computer, and then accessed that very same directory from windows. This way, the symlinks appear as normal directories from windows. However, this doesn't work with the g-wrap wrapper generator, so this simplification cannot be used. See below for instructions on the symlinks.)

Build Instructions / hints

This is for a system where all the GTK and GNOME libs are installed in c:\GTK-2-8-10\.

./configure

In order to get ./configure to run successfully, the following one change was necessary compared to SVN configure.in. Apply that by hand, then run ./autogen.sh.

--- configure.in        (Revision 14371)
+++ configure.in        (Arbeitskopie)
@@ -39,7 +39,7 @@
 # order, doesn't it? Whatever.)
 AC_PROG_CC
 AC_GNU_SOURCE
-AC_PROG_INTLTOOL
+AC_PROG_INTLTOOL([],[no-xml])
 AM_GCONF_SOURCE_2
(You can skip this patch if you install ActivePerl and export INTLTOOL_PERL=${PathToPerlBin}. This package includes XML::Parser.)

Then run ./configure. The ./configure line used was

./configure --disable-error-on-warning --with-zlib=/c/GTK2-8-10 \
  LDFLAGS="-no-undefined -mms-bitfields -L/lib -L/mingw/lib -L/C/WINNT/system32 -lwsock32 -lregex" \
  CFLAGS="-I/usr/include -I/usr/local/include -D_WIN32 -DLIBLTDL_DLL_IMPORT -mms-bitfields" \
  PKG_CONFIG=/c/GTK2-8-10/bin/pkg-config \
  LD_LIBRARY_PATH=/c/GTK2-8-10/lib PATH="/c/GTK2-8-10/bin:$PATH"

Now you need to do some changes in the file config.status. Change the line defining LN_S to read

s,@LN_S@,touch,;t t

and in the line defining G_WRAP_MODULE_DIR, replace all forward slashes by properly quoted backslashes, e. g.

s,@G_WRAP_MODULE_DIR@,c:\\\\GTK2-8-10\\\\share\\\\guile\\\\site,;t t

so that guile at runtime will use the windows-style backslash path to find the g-wrap module directory. Otherwise the commands for building the g-wrap wrapsets will fail with "no such module" errors.

(Note that the g-wrap wrapper generator didn't start up successfully when the current working directory was on the SMB share. The g-wrap wrapper generator only works when I'm on the local disc of the computer.)

Symlinks

During the build, various header files are expected to be located in subdirectories, which is simulated during normal Unix building by setting symlinks to the current working directory. This doesn't work on windows due to the missing symlinks. If you encounter such errors (e.g. for goffice/goffice-config.h or various g-wrapped/gw-foo.scm files), you need to manually create these subdirectories and copy the respective files into that newly created subdirectory. (e. g. "rm -rf goffice; mkdir goffice; cp goffice-config.h goffice-features.h goffice")

goffice

The internal goffice subdirectory of gnucash doesn't immediately compile. A few changes are necessary:

  • The headers <urlmon.h> and <htmlhelp.h> as well as the libraries urlmon and htmlhelp are unknown, at least on my windows system. Therefore the header goffice/utils/win32-stub.h needs to be edited to get rid of these headers, and goffice/utils/win32-stub.c as well. I simply removed the includes, and replaced the function calls in the c file by "return 0;".
  • The HtmlHelp seems to be unavailable but is expected in goffice/gtk/goffice-gtk.c; I replaced in line 746 the "#elif defined(G_OS_WIN32)" by "#elif 0".

All changes are included in the diff available at https://lists.gnucash.org/pipermail/gnucash-devel/2006-March/016883.html

Test environment

If everything is compiled, you should try to get the tests running, i.e. "make check" to pass. When running "make check", a lot of environment variables are set before the actual test programs are called. These env variables should set the appropriate search paths to the locations in the build directory. However, these paths are in unix-notation with '/' as a directory separator, whereas for the windows programs they need to be in windows-notation with '\' as directory separator. You therefore need to manually edit the Makefile in the test/ subdirectory and change the GNC_TEST_DEPS variable so that the unix-style variables and directories are completely replaced by windows pathnames, properly quoted. E.g. change

GNC_TEST_DEPS := \
 --gnc-module-dir ${top_builddir}/src/gnc-module \

into

GNC_TEST_DEPS := \
 --gnc-module-dir '\\working\\gnucash-trunk\\src\\gnc-module' \

if c:\working\gnucash-trunk is your directory of the gnucash source code and also the build directory.


Status

The windows port successfully compiled all C files in the standard configuration, which were 586 C files in r13657. All gnucash modules can be linked successfully. All test executables can be compiled and linked as well. It is possible to run "make install" successfully until end.

The majority of checks can be run successfully as well (in src/engine, only 3 out of 22 fail). However there are problems with the installation of the gnucash scheme modules, which might probably need some tweaking with the guile path variables (backward vs. forward slashes and the like).

However, when starting gnucash-bin.exe nothing happens so far.

Note: Due to the file system wrapper layers in mingw32, compiling and especially linking is extremely slow. A full build of the gnucash tree might take well over 6 hours on a normal PC.

Old notes

  • There was a weird linker problem in the early porting effort. The src/gnc-module/libgncmodule.la DLL doesn't export its symbols. This DLL simply won't have any exported symbols, in stark contrast to e.g. src/core-utils/libcore-utils.la, which has all symbols exported just fine. My checking for exported symbols was nm .libs/libgncmodule.dll.a | grep ' T '. Turns out the libtool header <ltdl.h> must have the macros _WIN32 and in particular LIBLTDL_DLL_IMPORT defined or otherwise the linking will fail on windows. Once I do this, these variables marked with "C" disappear in the object file, and all expected symbols correctly appear. That's why these macros are included in the above configure command now. Of course this is nowhere documented, thank you libtool.
  • In goffice, one include directory was missing and needs to be added to CFLAGS, either in config.status or manually in the Makefiles: -I/c/GTK2-8-10/include/freetype2 ; either this is fixed in gnucash, or you fix the pkgconfig file pangoft2.pc as described in the gnome section above.
  • I got DLL problems when running tests and/or starting gnucash-bin.exe. The error message is something like "cannot find symbol freeaddrinfo in WS2_32.DLL". This was fixed by upgrading ORBit to 2.13.3.
  • "make check" gave some errors related to the g-wrap installation: ERROR: file: "libgw-guile-standard", message: "can't open the module". To fix this, run "cp libgw-guile-standard-0.dll libgw-guile-standard.dll" in the bin directory of the g-wrap installation.

TODO

We collect various TODO-items that need to be solved in order to compile gnucash on Windows.

  • ln -s - The windows file systems don't have symlinks. GnuCash uses symlinks extensively all over the build system. Replacing the literal ln -s by the macro LN_S seemed a good thing, but still won't work in many cases because gnucash relies upon content that is created later in the symlinked directory, i.e. simply making a copy is IIRC not sufficient. The only long-term solution would be to have gnucash create the content and copy it afterwards, not assuming a symlinked directory.