[RFC Patch] Invert the program entry point

Chris Shoemaker c.shoemaker at cox.net
Tue Jan 3 01:18:37 EST 2006


Folks,
        I'm interested in comments on the attached patch.  For anyone
unfamiliar with the details... Right now, Gnucash is basically a Guile
program which happens to link to some libraries written in C.

        When you run Gnucash, you're actually just starting the guile
interpreter and pointing it to some guile code to start running.
After some guile code runs, we dlopen the shared objects containing
some C code and pass control into that library, which enters the main
gtk event loop.  The C code then calls guile code whenever g-wrapped
functionality is needed.  It's really the gtk event loop running the
show until we quit Gnucash.  At that point the event loop returns and
we pop back into guile for long enough to exit.

        This design has several disadvantages that I don't want to get
into right now, but several of them can be avoided by a small change
in the attached patch.  Basically, we can just provide a main()
function in C, link to libguile, and build an executable that calls a
guile module.  That's what this patch does.  It installs an alternate
startup script 'gnucash-test' in the bin directory which calls the
'gnucash-bin' executable, which starts up Gnucash.  Tada! Gnucash is
now a C program that happens to link to some libraries written in
guile.

        BTW, I think that one consequence of this change would be that
it would become much easier to move the entire start-up sequence from
guile to C.

        WorksForMe(tm) but I'm especially interested to hear if I've
missed anything.  I've delayed committing on the chance that there's
some fundamental flaw in this design.  So speak up if so!

-chris
-------------- next part --------------
Index: src/bin/gnucash-bin.c
===================================================================
--- src/bin/gnucash-bin.c	(revision 0)
+++ src/bin/gnucash-bin.c	(revision 0)
@@ -0,0 +1,21 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <libguile.h>
+#include "glib.h"
+
+static void
+inner_main (void *closure, int argc, char **argv)
+{
+    /* module initializations would go here */
+    //scm_c_eval_string("(display %load-path)");
+    scm_c_eval_string("(use-modules (gnucash main))");
+    scm_c_eval_string("(gnc:main)");
+    return;
+}
+
+int main(int argc, char ** argv)
+{
+    scm_boot_guile(argc, argv, inner_main, 0);
+    exit(0); /* never reached */
+}
Index: src/bin/Makefile.am
===================================================================
--- src/bin/Makefile.am	(revision 12230)
+++ src/bin/Makefile.am	(working copy)
@@ -3,6 +3,26 @@
 
 AM_CFLAGS = -I${top_builddir} ${GLIB_CFLAGS}
 
+bin_PROGRAMS = gnucash-bin
+gnucash_bin_SOURCES = gnucash-bin.c
+gnucash_bin_LDADD = ${GUILE_LIBS} ${GLIB_LIBS}
+
+gnucash-test: gnucash-test.in ${top_builddir}/config.status
+	rm -f $@.tmp
+	sed < $< > $@.tmp \
+	    -e 's:@-BIN_DIR-@:${bindir}:g' \
+	    -e 's:@-G_WRAP_MODULE_DIR-@:${G_WRAP_MODULE_DIR}:g' \
+	    -e 's:@-G_WRAP_LIB_DIR-@:${G_WRAP_LIB_DIR}:g' \
+	    -e 's:@-GNC_GUILE_MODULE_DIR-@:${GNC_SHAREDIR}/guile-modules:g' \
+	    -e 's:@-GNC_SCM_INSTALL_DIR-@:${GNC_SCM_INSTALL_DIR}:g' \
+            -e 's:@-GNC_LIB_INSTALLDIR-@:${libdir}:' \
+            -e 's:@-GNC_PKGLIB_INSTALLDIR-@:${pkglibdir}:g' \
+	    -e 's:@-GNC_MODULE_DIR-@:${GNC_MODULE_DIR}:g' \
+            -e 's:@-GNC_SCRIPT_OVERRIDE_DIR-@:${gncoverridedir}:g'
+	mv $@.tmp $@
+	chmod u+x $@
+CLEANFILES = gnucash-test
+
 # We handle gnucash scripts in a somewhat unexpected way, but we do
 # this so that a user who doesn't necessarily have the right
 # directories in their path can still invoke these commands via their
@@ -20,7 +40,7 @@
 # by these top-level "common" scripts.
 gnc_common_scripts = gnucash gnucash-env gnucash-run-script gnucash-make-guids
 
-bin_SCRIPTS = ${gnc_common_scripts} update-gnucash-gconf
+bin_SCRIPTS = ${gnc_common_scripts} update-gnucash-gconf gnucash-test
 
 # if you change gncoverridedir, make sure you change ./overrides/Makefile.am too.
 gncoverridesdir = ${GNC_LIBEXECDIR}/overrides
@@ -31,7 +51,7 @@
 ${gnc_common_scripts}: generate-gnc-script ${top_builddir}/config.status
 	${srcdir}/generate-gnc-script $@ "${gncoverridesdir}"
 
-CLEANFILES = ${gnc_common_scripts} update-gnucash-gconf
+CLEANFILES += ${gnc_common_scripts} update-gnucash-gconf
 
 ## We borrow guile's convention and use @-...-@ as the substitution
 ## brackets here, instead of the usual @... at .  This prevents autoconf
Index: src/bin/gnucash-test.in
===================================================================
--- src/bin/gnucash-test.in	(revision 0)
+++ src/bin/gnucash-test.in	(revision 0)
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+PATH="@-BIN_DIR-@:${PATH}"
+export PATH
+
+GUILE_WARN_DEPRECATED="no"
+export GUILE_WARN_DEPRECATED
+
+GNC_MODULE_PATH="@-GNC_PKGLIB_INSTALLDIR-@:${GNC_MODULE_PATH}"
+
+EXTRA_PATH="@-G_WRAP_MODULE_DIR-@"
+EXTRA_PATH="${EXTRA_PATH}:@-GNC_GUILE_MODULE_DIR-@"
+EXTRA_PATH="${EXTRA_PATH}:@-GNC_SCM_INSTALL_DIR-@"
+GUILE_LOAD_PATH="${EXTRA_PATH}:${GUILE_LOAD_PATH}"
+
+EXTRA_LIBS="${GNC_MODULE_PATH}"
+EXTRA_LIBS="${EXTRA_LIBS}:@-GNC_LIB_INSTALLDIR-@"
+EXTRA_LIBS="${EXTRA_LIBS}:@-GNC_MODULE_DIR-@"
+EXTRA_LIBS="${EXTRA_LIBS}:@-G_WRAP_LIB_DIR-@"
+
+LD_LIBRARY_PATH="${EXTRA_LIBS}:${LD_LIBRARY_PATH}"
+LTDL_LIBRARY_PATH="${EXTRA_LIBS}:${LTDL_LIBRARY_PATH}"
+
+export GNC_MODULE_PATH
+export GUILE_LOAD_PATH
+export LD_LIBRARY_PATH
+export LTDL_LIBRARY_PATH
+
+gnucash-bin "$@"


More information about the gnucash-devel mailing list