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 git source, building GnuCash, and creating patches for submission. Coding Style Conventions ------------------------ Please refer to https://wiki.gnucash.org/wiki/CodingStandard. ============== TIPS AND HINTS ============== Building GnuCash in-tree ------------------------ This is generally discouraged. You should always use a separate build directory, preferably outside of the source directory. If you really want a build directory inside your source directory, make it a hidden one (starting with a '.'), to keep intltool from incorrectly picking up translatable strings from the build directory. Starting GnuCash from the build tree ------------------------------------ This should mostly work, but there may be corner cases where it behaves differently from running gnucash from the target installation directory. You can tell cmake which install directory to use via the command line switch '-DCMAKE_INSTALL_PREFIX=' Don't use '/usr' or '/usr/local' unless you're a package maintainer for a distro. Instead choose /opt/gnc/git/ or even $HOME/gnc/git (or something similar). Getting Trace Messages From GnuCash ----------------------------------- See the doxygen comments in libgnucash/engine/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 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 --------------------------------- There are currently no rules in our build system to build and run gnucash or unit tests with Electric Fence. It should probably be relatively straightforward to add this as all it needs is to link with libefence.so (-lefence). Fedora 27 ships an ElectricFence package containing that library and also an executable 'ef' to run an arbitrary program with Electric Fence guarding enabled. I have given it a quick spin on gnucash but it immediately crashes. I haven't investigated whether this is because I should first have linked gnucash with -lefence or because a real problem in GnuCash code. Using Valgrind/Callgrind with GnuCash ------------------------------------- This section has been moved to https://wiki.gnucash.org/wiki/Coder_Tools 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. Note "lib64" below should be "lib" for a 32-bit build. # 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=lib64/libgnc-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=lib64/libgnc-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 a cmake TARGET_LINK_LIBRARIES command A=lib64/libgnc-gnome.so && echo "$A target link libraries:" \ && nm $A | grep ' U ' | sed 's/^.* \([^ ]*\)$/\1/' | \ grep -wFf- exportedsymbols | cut -d: -f1 | sort | uniq | \ sed 's!.*/lib! !' | sed 's/.so$//' # List all import requirements summarized by library for a full # recursive directory tree for A in `find lib64 -name '*.so'`; do \ echo -e "\n##$A requirements:" && nm $A | grep ' U ' | \ sed 's/^.* \([^ ]*\)$/\1/' | grep -wFf- exportedsymbols | \ cut -d: -f1 | sort | uniq; done