Hacking Guidelines ================== This document is an introduction to hacking on GnuCash. Related Documents ----------------- In addition to this file, you should read the README file, which explains the details of getting the SVN source, building GnuCash, and creating patches for submission. The src/doc/design directory contains a preliminary design document which you should read as well. You should also feel free to hack on the design document. Coding Style Conventions ------------------------ General: * When modifying a file, the style convention in that file should be followed. * When creating a new file, the style of existing files should be followed. * When creating lots of new files in a new directory, you may use your own coding standards, but please try to stick as closely as possible to the GNU coding standards. * Do not submit patches that consist of (gratuitous) stylistic changes. C: * Use ISO C. * Use glib memory routines where possible. This means you should be using g_malloc(), g_new(), g_free(), etc., instead of malloc(), free(), etc. Do not mix glib memory calls with libc calls! * Where possible, use glib data abstractions instead of rolling your own. Glib linked lists and pointer arrays are very convenient and have been extensively used and tested. * All gnucash functions and global variables are prefixed with gnc_ * Use static functions whenever possible * Use const whenever possible Scheme: * All gnucash functions and global variables are prefixed with gnc: * All global variables are enclosed in ** (i.e. gnc:*load-path*) * All private functions are enclosed in __ (i.e. gnc:_do-not-call_) * All C functions wrapped into scheme have dashes in place of underscores. (xaccSplitGetBalance --> gnc:split-get-balance) - but FIXME: This policy seems to have been dropped in favor of having identical function names. cstim, 2006-10-30. Dave Peticolas August 22, 2000 ============== TIPS AND HINTS ============== Starting GnuCash from the build tree ------------------------------------ This is known to not work very well. Instead, `--prefix` your build into /opt/gnc/svn/ (or some such). Getting Trace Messages From GnuCash ----------------------------------- See the doxygen comments in lib/libqof/qof/qoflog.h (and .c) Starting GnuCash in GDB ----------------------- To run gdb on an installed version of gnucash (installed in /opt/gnc/unstable:) % gdb /opt/gnc/unstable/bin/gnucash OS X/Quartz developers can't run gnucash in gdb this way. They should instead use: % /opt/gnc/unstable/bin/gnucash-gdb You'll also probably want to know about these: gdb> catch fork gdb> set follow-fork-mode child ----- It may be the case that running GDB from within emacs doesn't work for you, with the following error: [C-u M-x gdb /opt/gnucash-cvs/bin/gnucash ...in buffer *gud-gdb*:] (gdb) attach jsled needed to re-define a gud.el function as such: (defun gud-gdb-massage-args (file args) (let ((l (copy-list args))) (nconc l (list "-cd" (expand-file-name default-directory) "-fullname")))) jsled does not need the above with emacs-22, thankfully. It was getting quite tiresome. Using Electric Fence with GnuCash --------------------------------- % configure --enable-efence (except this doesn't actually enable efence :-( need to hack configure.in and add $LIBS = -lefence and re-run ./autogen.sh) Don't know why, efence does not currently work with gnucash: I get a bunch of errors: warning: Cannot initialize thread debugging library: unknown thread_db error '22' If you know how to fix this, please update these instructions. Using Valgrind with GnuCash --------------------------- -- run ${prefix}/bin/gnucash-valgrind However, I did not find valgrind to be useful. It reported a bunch of guile bugs, some g_hash_table bugs, and then the program exited prematurely for no apparent reason. :-( For the moment, gnucash-valgrind uses the suppressions in src/debug/valgrind/valgrind-*.supp For valgrind-gnucash.supp, this comment was made (but is perhaps outdated by now ?): This file needs to be cleaned up in two ways: 1/ There are a bunch of duplicate suppressions in the file. * The suppressions in place were auto-generated by valgrind itself [--gen-suppressions=yes], and it makes no effort to output the suppression only once. 2/ There are a bunch of suppressions which need to not be suppressions, but instead just not be generated by valgrind. Look up exported and imported symbols ------------------------------------- These commands may be useful to find out the library that actually exported a particular symbol, and to check which import symbol one particular library depends upon and where they are imported from. Run these from the top-level of the build tree. # Create a table of all exported symbols and where they come from nm -A `find . -name '*.so'` | grep ' T ' | \ sed 's/^\([^:]*\).* \([^ ]*\)$/\1: \2/' > exportedsymbols # For a particular library, check symbol import requirements, # listing all symbols (needs the file from above) A=src/gnc-module/.libs/libgw-gnc-module.so && echo "$A requirements:" \ && nm $A | grep ' U ' | sed 's/^.* \([^ ]*\)$/\1/' | \ grep -wFf- exportedsymbols # For a particular library, check import requirements, # summarized by library A=src/gnc-module/.libs/libgw-gnc-module.so && echo "$A requirements:" \ && nm $A | grep ' U ' | sed 's/^.* \([^ ]*\)$/\1/' | \ grep -wFf- exportedsymbols | cut -d: -f1 | sort | uniq # For a particular library, check import requirements, # summarized by library, formatted for Makefile.am A=src/gnc-module/.libs/libgw-gnc-module.so && echo "$A requirements:" \ && nm $A | grep ' U ' | sed 's/^.* \([^ ]*\)$/\1/' | \ grep -wFf- exportedsymbols | cut -d: -f1 | sort | uniq | \ sed 's!.libs/!!' | sed 's/.so$/.la \\/' | sed 's!^.! \${top_builddir}!' # List all import requirements summarized by library for a full # recursive directory tree for A in `find src/business/business-core -name '*.so'`; do \ echo -e "\n##$A requirements:" && nm $A | grep ' U ' | \ sed 's/^.* \([^ ]*\)$/\1/' | grep -wFf- exportedsymbols | \ cut -d: -f1 | sort | uniq; done