Difference between revisions of "MacOS/Quartz"

From GnuCash
Jump to: navigation, search
(Replacing the "Running from the commandline" section which I somehow lost.)
(gnucash-help is gnucash-manual as of GnuCash 5.0)
 
(223 intermediate revisions by 18 users not shown)
Line 1: Line 1:
 +
{{Lowercase title}}
 +
[[Category: MacOS]]
 +
==Downloads==
 +
{{Macos_Downloads}}
 +
 
==Overview==
 
==Overview==
GnuCash can be built to run more or less natively on OSX -- meaning without X11. Better yet, the build is almost automatic.
+
GnuCash can be built to run more or less natively on macOS -- meaning without X11. Better yet, the build is almost automatic.
  
To pull this off, you'll need Developer Tools installed. The instructions which follow assume that you're comfortable building programs from the command line and editing text files.
+
This page describes the procedure to build GnuCash with the Quartz environment. You can also use MacPorts: The details are described at [[MacOS/MacPortsDetail]]. If you already have MacPorts installed, you should use that procedure, as gtk-osx doesn't work well with a MacPorts installation.  
  
I've succeeded in building this under various incarnations of Leopard while perfecting the modulesets, always on a Mac Pro... but it ought to work on any Mac running Tiger or Leopard.
+
If you want to have a clickable GnuCash.app to put in your Applications folder, this is the solution to use. If you want to be able to easily customize your installation, this is also the solution for you. Don't want all of the extra stuff that MacPorts drags in? Well, this might be a bit better... but GnuCash is notorious for its huge list of dependencies. Want to keep up with the latest work from the Gnome developers? You can set up this solution to get many of its packages directly from source-code-control. That's a double-edged sword, of course, because if a build gets broken, you're pretty well stuck until the developers for that package fix it.  
  
The default configuration builds in your home folder. On my system, I build in /usr/local/src/gnome and install to /usr/local/gtk. If you want to do that, uncomment the checkoutroot and prefix lines in .jhbuildrc-custom, then create the folders up front and give yourself ownership. If you don't know how to do that, then you should probably leave it the way it is.
+
A build will consume about 5 gigabytes of disk space and typically take several hours to run. The initial build, which includes pulling down sources from all dependencies, can take days, depending on how often network errors interrupt the process, and how quickly they are noticed.
  
==Preliminaries==
+
This build integrates Gnucash menus with the Mac menubar at the top of the screen. About, Preferences, and Quit are in the "GnuCash" menu (it's named "gnucash-bin" when you run from the command line) in standard Mac style. Standard accelerator keys like Command-Q (quit), Command-S (save), and Command-O (Open) work as well. A patch to Gtk+ allows copy and paste in the register pages.
  
Go to http://developer.imendio.com/projects/gtk-macosx/build-instructions and follow the instructions. '''''Don't run jhbuild build yet!'''''
+
==Support==
 +
This procedure depends on the [https://wiki.gnome.org/action/show/Projects/GTK+/OSX Gnome Gtk-OSX project]. Support for that is provided via the [https://mail.gnome.org/mailman/listinfo/gtk-osx-users-list gtk-osx-users-list@gnome.org] mailing list. Questions, comments, or suggestions about Gnucash should be directed to the appropriate Gnucash mailing list ([https://lists.gnucash.org/mailman/listinfo/gnucash-devel gnucash-devel] for development versions (git master) or [https://lists.gnucash.org/mailman/listinfo/gnucash-user gnucash-user] for release (3.x, git maint).)
  
If you have set <tt>$MACOSX_DEPLOYMENT_TARGET</tt> to something other than your running version of OSX, you may get an error during jhbuld bootstrap.
+
==Preliminaries==
 +
Read [https://wiki.gnome.org/Projects/GTK%2B/OSX/Building Building Gtk-OSX] and scan the [https://wiki.gnome.org/Projects/Jhbuild jhbuild docs].
 +
This procedure is based on both. '''Note well the [https://wiki.gnome.org/action/show/Projects/GTK/OSX/Building#Prerequisites warnings about Homebrew, MacPorts, and Fink!]''' Creating a separate user for building and packaging GnuCash is the easiest work-around if you've used any of those systems in your regular userid.
  
You may get an error about <tt>$PREFIX/inst/man/man1/cjpeg.1</tt> not existing. What this really means is that install wasn't set to make the directory, so select '[4] start shell" and mkdir -p $PREFIX/inst/man/man1, quit the shell, and select '[1] rerun stage install'.
+
First download [https://gitlab.gnome.org/GNOME/gtk-osx/raw/master/gtk-osx-setup.sh gtk-osx-setup.sh] by clicking the link or from the command line:
 +
<syntaxhighlight lang="sh">
 +
curl -O -L https://gitlab.gnome.org/GNOME/gtk-osx/raw/master/gtk-osx-setup.sh
 +
</syntaxhighlight>
 +
and run it from the command line. Gtk now requires Python3 to build and Apple provides Python3 only on MacOS 10.15 Catalina, so it will first set up a Python3 virtual environment, then install jhbuild and configure what it needs to run. It will ask if you want to install CPython. You do.
  
Paste the code from [[#Customize jhbuildrc]] into a file named ".jhbuildrc-custom" in your home folder.
+
It defaults to installing everything in <tt>$HOME/.new_local</tt>. If you prefer to install somewhere else, set the environment variables <tt>DEVPREFIX</tt> and <tt>PYTHONUSERBASE</tt> to that directory before running <tt>gtk-osx-setup.sh</tt>. One way to do that is inline with the command, e.g.
Do likewise for [[#Gnucash Moduleset]], with a filename "gnucash.modules", also in your home directory.
+
<syntaxhighlight lang="sh">
 +
DEVPREFIX=$HOME/.jhbuild_root PYTHONUSERBASE=$HOME/.jhbuild_root ./gtk-osx-setup.sh
 +
</syntaxhighlight>
 +
There are some other directory customizing environment variables, see the list in <tt>gtk-osx-setup.sh</tt>
 +
Default or not, you'll want to add the install location's <tt>bin</tt> directory to <tt>$PATH</tt>.
  
==Building==
+
JHBuild is configured to build GnuCash via [http://github.com/gnucash/gnucash-on-osx/raw/master/jhbuildrc-custom <code>jhbuildrc-custom</code>]. Download this file to your home directory either by clicking the link and moving the downloaded file or from the command line:
 +
<syntaxhighlight lang="sh">
 +
curl -O -L https://github.com/gnucash/gnucash-on-osx/raw/master/jhbuildrc-custom
 +
</syntaxhighlight>
 +
and place it in <tt>$HOME/.config</tt>--unless you've set something different in <tt>$XDG_CONFIG_HOME</tt>, in which case put it there.
  
Once all of the preliminaries are complete, do:
+
OS X 10.11 added a security feature called [https://developer.apple.com/library/prerelease/mac/documentation/Security/Conceptual/System_Integrity_Protection_Guide/  System Integrity Protection] or SIP. One "feature" is that it strips linker environment variables (the ones starting with LD_ and DYLD_) from the environment when a "system" program does a fork/exec. For our purposes "system program" means one installed in <tt>/bin</tt> or <tt>/usr/bin</tt>, in particular <tt>/bin/sh</tt>.
<tt>
 
$> jhbuild build
 
</tt>
 
  
You'll get a few errors:
+
The Guile compiler, '''guiled''', is a shell script that as written uses '''/bin/sh''' to set the prefix then execs guile to run a compilation script. That fails in the presence of SIP.
  
'''libgnomeprint''' has a defective configure.ac which fails when libm isn't found. I've filed a bug report (Bug 540837) with a patch, but a similar bug report (Bug 471730) has been sitting for a year, so there's no telling when the developers will get around to fixing this (and libgnomeprint is deprecated anyway). Here's the patch:
+
One can get around this by disabling SIP, but that's a whole-system change that requires a reboot, and SIP clearly has significant security benefits. Don't do that.
  
<pre>
+
The other workaround is to use a shell that isn't in <tt>/bin</tt> or <tt>/usr/bin</tt>. One can just copy <tt>/bin/bash</tt> to one's user-level bin directory. <tt>gtk-osx-setup.sh</tt> does that for you, putting it in the install location's <tt>bin</tt> directory.
--- configure.in        2008-07-03 14:18:44.000000000 -0700
 
+++ configure.in.mod    2008-07-03 14:17:11.000000000 -0700
 
@@ -148,9 +148,17 @@
 
dnl Checking for libm
 
dnl =================================
 
AC_CHECK_LIBM
 
-if test "x$LIBM" = "x"; then
 
-      AC_MSG_ERROR(You need -lm(mathematic library) for this version of libgnomeprint.)
 
-fi
 
+case $host in
 
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
 
+  # These system don't have libm, or don't need it
 
+  ;;
 
+*)
 
+  if test "x$LIBM" = "x"; then
 
+      AC_MSG_ERROR(You need -lm(mathematic library) for this version of
 
+libgnomeprint.)
 
+  fi
 
+  ;;
 
+esac
 
LDFLAGS="$LDFLAGS $LIBM"
 
 
dnl =================================
 
</pre>
 
  
Select '[4] start shell', apply the patch (you probably will need to use <tt>patch -l</tt>) , quit the shell, and select "[6] go to stage configure"
+
The default build location is <tt>$HOME/gnucash</tt> with subdirectories <tt>src</tt>, <tt>build</tt>, and <tt>inst</tt> for unpacking the sources, building, and installation respectively. You can change that by setting the environment variable <tt>PREFIX</tt>, e.g. <SyntaxHighlight lang="sh">
 +
PREFIX=/opt/gnucash jhbuild bootstrap-gtk-osx
 +
PREFIX=/opt/gnucash jhbuild build
 +
</SyntaxHighlight> You can make finer-grained changes by editing <tt>jhbuildrc-custom</tt>.
  
'''libtasn1''' the download has been moved to a new location.  You will need to download and unpack the tarball manually in order to continue.  Select '[4] start shell' and:
+
==== setup_sdk ====
<pre>
+
With no arguments (the default) <code>setup_sdk()</code> will configure the build for your system. Unless you're building for distribution we recommend that you do this.
$> curl -L ftp://ftp.gnu.org/pub/gnu/gnutls/libtasn1-1.4.tar.gz -o /usr/local/src/gnome/pkgs/libtasn1-1.4.tar.gz
 
$> gunzip -dc "/usr/local/src/gnome/pkgs/libtasn1-1.4.tar.gz" | tar xf -
 
</pre>
 
  
'''goffice''' will complain about a misconfiguration of gtk-doc. It doesn't matter, so select "[2] ignore error".
+
If you have Xcode 7 (shipped with OS X 10.9 (Mavericks)) or later you can build for any version from 10.6 on with the included SDK by calling (e.g.)<SyntaxHighlight lang="sh">
 +
setup_sdk("10.6", native, ["i386"])
 +
</SyntaxHighlight> Note, however, that some users have noted linkage problems when doing this.
 +
It is safest to build GnuCash on the earliest macOS version you intend to support.
 +
The GnuCash 2.6.x application bundles were built for Mac OS X 10.5 and later. To do likewise, please see [https://wiki.gnome.org/Projects/GTK+/OSX/Building#Building_for_Older_Versions_of_Mac_OS_X Building for Older Versions of Mac OS X]. You'll use <syntaxhighlight lang="sh">
 +
setup_sdk("10.5", "10.5"["i386"])
 +
</syntaxhighlight>
 +
;Notes:
 +
:* GnuCash v2.7.x and later use the CMake buildsystem.
 +
:* GnuCash v2.7.x and later requires MacOS X 10.9 ("Mavericks") or later.
 +
:* GnuCash v3.900 and later requires MacOS 10.13 ("High Sierra") or later because it uses C++17 and the attendant standard library.
 +
:* Apple has removed 32-bit runtime support from macOS 10.15, so you'll need to build on an older version of macOS if you want <tt>arch='i386'</tt>.
 +
:* Apple Silicon is first supported in macOS 11. We have never successfully cross-compiled the Gtk stack so you'll probably need an Apple Silicon Mac to build an Apple Silicon native GnuCash. Note that as of October 2022 WebKitGtk isn't able to find its loadable modules so that reports don't render in GnuCash.
 +
:* PowerPC similarly requires building on a PowerPC machine.  
  
'''libgnomeui''' Another configure.in bug (Bug 535958). The patch:
+
Make any changes by editing <tt>jhbuildrc-custom</tt>
<pre>
 
Index: configure.in
 
==Running from the commandline==
 
There's a few more things to fix before we can run GnuCash. GnuCash uses dbus to find its configuration data. First we need to fix up dbus's config file. Open $PREFIX/etc/dbus-1/session.conf in your editor. Quite near the top you'll see a line that looks something like
 
<pre>
 
<listen>unix:tmpdir=/var/folders/8Z/8ZMrxptP2RW3+U+8ZNMZY++++TI/-Tmp-/</listen>
 
</pre>
 
That's a perfectly valid temp directory... but dbus itself can't handle those +s, so change the spec to <code>unix:tmpdir=$PREFIX/tmp</code> and save the file.
 
:Make sure that $PREFIX/tmp/ exists
 
  
:Run <tt>$PREFIX/bin/dbus-uuidgen --ensure=$PREFIX/var/lib/dbus/machine-id</tt>
+
==Building==
  
:Rename <code>$PREFIX/lib/libjpeg.dylib, $PREFIX/lib/libtiff.dylib</code>, and <code>$PREFIX/lib/libpng.dylib</code> to something else (I use names like <code>$PREFIX/lib/libjpeg.dylib.hidden</code>).
+
Once all of the preliminaries are complete, run:
 +
<syntaxhighlight lang="sh">
 +
jhbuild bootstrap-gtk-osx
 +
jhbuild build
 +
</syntaxhighlight>
  
:Replace <code>$PREFIX/bin/gnucash</code> with the code from [[#GnuCash Start Script (commandline)]].
+
===Building for Development===
  
Now you're ready to try it out:
+
Please see [[Development]] for general guidelines and lots of helpful links.
<tt>
 
$> $PREFIX/bin/gnucash
 
</tt>
 
  
==Making a Bundle==
+
If you intend to contribute your work to the GnuCash project please subscribe to [https://wiki.gnucash.org/wiki/Mailing_Lists#Mailing_Lists_for_Development_Topics the gnucash-devel list] and coordinate your work with the core developers '''before''' starting.
So far so good, but you don't really want to have to open a Terminal window every time you want to use GnuCash, now do you? Of course not. You want a nice icon in your Applications folder (and maybe in the Dock) to click on when you run GnuCash. Here's how to do this:
 
  
:Install the bundler from http://developer.imendio.com/projects/gtk-macosx/creating-app-bundles.
+
You'll need to work with the appropriate source code repository rather than the release tarball from the procedure so far. [[Git]] provides details on our repository and has some help for developers who aren't yet familiar with the [http://git-scm.com/ git] version control system. Open <tt>jhbuildrc-custom</tt> in your text editor and find the section
:I like to create a subfolder called gnucash-bundler and keep everything in there, but you don't have to.
+
<syntaxhighlight lang="Python">
:Paste the contents of [[#GnuCash Bundle Description]] into a file called "gnucash.bundle", [[#Gnucash Info.Plist]] into "Info.Plist", and [[#Gnucash Start Script (Bundler)]] into "gnucash-launcher", all in the same folder.
+
#Select which modules to build. The only difference is which gnucash
:Edit all three files to adjust the paths so that they match your installation.
+
#module (and all of the dependencies, see above) get built. "
:You'll need to create gnucash.icns using IconComposer (it's in /Developer/Applications) and the gnucash icons in gnucash's src/pixmaps directory and save it into $PREFIX/share/gnucash/pixmaps/.
+
modules = ["meta-gtk-osx-bootstrap", "meta-gnucash-stable"]
:make gnucash-launcher executable (<tt>chmod +x gnucash-launcher</tt>)
+
#modules = ["meta-gtk-osx-bootstrap", "gnucash-unstable"]
:make gnucash-launcher executable (<tt>chmod +x gnucash-launcher</tt>)
+
#modules = ["meta-gtk-osx-bootstrap", "gnucash-git"]
:execute <tt>jhbuild shell</tt> to set up the environment for the bundler
+
#branches["gnucash-git"] = (None, "maint")
:while in the shell, execute <tt> ige-mac-bundler gnucash.bundle</tt>.
+
</syntaxhighlight>
 +
and change it to
 +
<syntaxhighlight lang="Python">
 +
#Select which modules to build. The only difference is which gnucash
 +
#module (and all of the dependencies, see above) get built. "
 +
#modules = ["meta-gtk-osx-bootstrap", "meta-gnucash-stable"]
 +
#modules = ["meta-gtk-osx-bootstrap", "gnucash-unstable"]
 +
modules = ["meta-gtk-osx-bootstrap", "gnucash-git"]
 +
branches["gnucash-git"] = (None, "maint")
 +
</syntaxhighlight>
 +
:;Note the <tt>branches</tt> line: It will build the current ''stable'' branch; to build the ''development'' branch, the one leading to the next major release, change <tt>maint</tt> to <tt>master</tt>. You may also want to change the prefix directory in the line above that block.
  
And your bundle should be ready to go.
+
====Command-line builds====
Try <tt>GnuCash.app/Contents/MacOSX/GnuCash</tt> from the command-line so that you can see any error messages. If that works, try <tt>open GnuCash.app</tt>. If that works, then you can move GnuCash.app to your Applications folder and it's ready to use. '''''Don't move or remove the installation directory (~/gtk/inst by default): Both dbus and GnuCash have links pointing into it which can't at present be changed.'''''
+
Once you have your initial build finished you'll start editing sources (they'll be in <tt>$HOME/gnucash-stable/src/gnucash-git</tt> unless you changed the <tt>prefix</tt> in <tt>jhbuilrc-custom</tt>) and you'll want to build and run the unit tests. Start a <tt>jhbuild</tt> shell and change directory to the build directory:
 +
<syntaxhighlight lang="sh">
 +
jhbuild shell
 +
cd %PREFIX/../build/gnucash-git
 +
</syntaxhighlight>
 +
From there you can run the usual shell commands like <tt>cmake</tt> and <tt>ninja</tt>.
  
==Making a Bundle==
+
===Building with Xcode===
So far so good, but you don't really want to have to open a Terminal window every time you want to use GnuCash, now do you? Of course not. You want a nice icon in your Applications folder (and maybe in the Dock) to click on when you run GnuCash. Here's how to do this:
+
It's possible to build GnuCash using Apple's Xcode IDE. To make it work first do a regular build as above to get all of the dependencies set up.
  
:Install the bundler from http://developer.imendio.com/projects/gtk-macosx/creating-app-bundles.
+
Now create a new build directory and ```cd``` to it but do *not* start a jhbuild shell, just export the following environment variables to simplify the cmake invocation:
:I like to create a subfolder called gnucash-bundler and keep everything in there, but you don't have to.
+
<syntaxhighlight lang="sh">
:Paste the contents of [[#GnuCash Bundle Description]] into a file called "gnucash.bundle", [[#Gnucash Info.Plist]] into "Info.Plist", and [[#Gnucash Start Script (Bundler)]] into "gnucash-launcher", all in the same folder.
+
export PREFIX=/full/path/to/prefix
:Edit all three files to adjust the paths so that they match your installation.
+
export PATH=$PATH:$PREFIX/bin
:You'll need to create gnucash.icns using IconComposer (it's in /Developer/Applications) and the gnucash icons in gnucash's src/pixmaps directory and save it into $PREFIX/share/gnucash/pixmaps/.
+
export SRCROOT=$PREFIX/../src
:make gnucash-launcher executable (<tt>chmod +x gnucash-launcher</tt>)
+
</syntaxhighlight>
:make gnucash-launcher executable (<tt>chmod +x gnucash-launcher</tt>)
+
making any required changes. '''Be sure to make different build directories for the maint and the master branches'''.
:execute <tt>jhbuild shell</tt> to set up the environment for the bundler
 
:while in the shell, execute <tt> ige-mac-bundler gnucash.bundle</tt>.
 
  
And your bundle should be ready to go.
+
Now create the xcodeproject with cmake:
Try <tt>GnuCash.app/Contents/MacOSX/GnuCash</tt> from the command-line so that you can see any error messages. If that works, try <tt>open GnuCash.app</tt>. If that works, then you can move GnuCash.app to your Applications folder and it's ready to use. '''''Don't move or remove the installation directory (~/gtk/inst by default): Both dbus and GnuCash have links pointing into it which can't at present be changed.'''''
 
  
==Files==
+
<syntaxhighlight lang="sh">
===Customize jhbuildrc===
+
cmake -G Xcode -D CMAKE_INSTALL_PREFIX=$PREFIX -D GTEST_ROOT=$SRCROOT/googletest $SRCROOT/gnucash-git
Paste this into .jhbuildrc-custom in your home folder:
+
</syntaxhighlight>
<pre>
 
# -*- mode: python -*-
 
  
#You can override the build and install directories by uncommenting
+
If you're building from a tarball you'll need to change the source directory at the end of the line.
#and editing the next two lines. Be sure to create these directories
 
#and change their ownership to you before you try to build!
 
#checkoutroot = '/usr/local/src/gnome'
 
#prefix = '/usr/local/gtk'
 
  
autogenargs='--disable-static --enable-shared --disable-gtk-doc --disable-docs --disable-scrollkeeper --disable-xlib'
+
For some newer versions of Xcode cmake seems unable to determine the C compiler and tries to use ```ld```. If you encounter errors during Cmake or building saying that `ld` doesn't accept some option try adding
 +
<syntaxhighlight lang="sh">
 +
  -D CMAKE_C_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/Xcodetoolchain.default/usr/bin/clang
 +
</syntaxhighlight>
 +
to the cmake command line. Adjust the path as needed if the Xcode you're using isn't <code>/Applications/Xcode.app</code>.
  
module_autogenargs={}
+
;Notes:
module_autogenargs["gconf"]="--enable-static --enable-shared --disable-scrollkeeper --disable-xlib"
+
:* Because all current branches of GnuCash use C++ features that don't compile on or for earlier versions, GnuCash requires MacOS 10.13 (High Sierra) or later.
module_autogenargs["libofx"]="--with-opensp-includes=" + prefix + "/include/OpenSP --with-opensp-libs=" + prefix + "/lib"
+
:* The dependencies for GnuCash have changed from the 2.x releases. The most significant are that major Linux distributions have dropped support for WebKit1Gtk, so we had to enable support for WebKit2Gtk and that in turn requires that GnuCash switch to Gtk3. We've rewritten several modules in C++ and are using [https://github.com/google/googletest/ GoogleTest] for new unit tests and the [https://www.boost.org Boost Libraries] for several language extensions. The register has been fixed to no longer use the obsolete <code>libgnomecanvas</code> and the small part of <code>libgoffice</code> that the CSV importer required has been copied into GnuCash sources.
module_autogenargs["libgnomeui"]="--disable-static --enable-shared --disable-scrollkeeper --disable-xlib --without-x"
 
  
module_makeargs = {}
+
===Documentation===
module_makeargs["perl-xml-parser"]="EXPATLIBPATH=" + prefix + "/lib EXPATINCPATH=${prefix}/include "
+
The gnucash documentation is [http://www.gnucash.org/docs.phtml online], of course, but if you want a local copy, you can build the modules <tt>gnucash-docs</tt> or <tt>gnucash-docs-git</tt>. Just add whichever one you want to your "modules" argument. If you're using <tt>gnucash-docs-git</tt> you might also want to select the branch by adding a line
 +
<syntaxhighlight lang="Python">
 +
branches["gnucash-docs-git"] = (None, "maint")
 +
</syntaxhighlight>
 +
setting <tt>"maint"</tt> or <tt>"master"</tt> as you prefer.
  
 +
===Debugging===
 +
To get a debugging build, add the line
 +
<tt>setup_debug()</tt>
 +
to jhbuildrc-custom. Beware, though, that WebKit doesn't build with debugging enabled. I usually build everything first without debugging enabled, then enable it and rebuild <SyntaxHighlight lang="sh">
 +
jhbuild buildone --force --clean
 +
</SyntaxHighlight> the packages you want to debug. Most of the time you can get by with just glib and gnucash, but depending on what you're working on, you might also want gtk+, gwenhywfar, aqbanking, or libdbi.
  
path = prefix + '/bin/install-check'
+
==Running from the commandline==
if os.path.exists(path):
 
    os.environ['INSTALL'] = path
 
#Comment this out if you want to build with your default sdk; make a
 
#similar function (it's in .jhbuildrc) if you want to set a different
 
#sdk altogether.
 
#setup_sdk_10_4()
 
  
 +
Now you're ready to try it out: <syntaxhighlight lang="sh">
 +
$PREFIX/bin/gnucash
 +
</syntaxhighlight>
 +
$PREFIX is the path to where you've built gtk; you can fill it in yourself or use <tt>jhbuild shell</tt> to set it for you.
  
moduleset = os.path.expanduser("~/gnucash.modules")
+
==Making a Bundle==
 +
So far so good, but you don't really want to have to open a Terminal window every time you want to use GnuCash, now do you? Of course not. You want a nice icon in your Applications folder (and maybe in the Dock) to click on when you run GnuCash. Here's how to do this:
  
modules = ['meta-gtk-osx-bootstrap', 'meta-gtk-osx-core', 'meta-gtk-osx-freetype', 'gnucash']
+
'''N.B.''' This procedure works ''only'' with GnuCash built according to the above instructions.
  
build_policy = "updated-deps"
+
:Clone [https://gitlab.gnome.org/GNOME/gtk-mac-bundler.git the bundler], cd into the cloned gtk-mac-bundler directory, and <tt>make install</tt>
</pre>
+
:Create a directory somewhere convienient (we'll call it <tt>gnucash-bundler</tt> from now on), cd to it, and download [https://raw.github.com/Gnucash/gnucash-on-osx/master/gnucash-bundler/gnucash.bundle gnucash.bundle], [https://raw.github.com/Gnucash/gnucash-on-osx/master/gnucash-bundler/Info.plist Info.plist], and [https://raw.github.com/Gnucash/gnucash-on-osx/master/gnucash-bundler/gnucash.icns gnucash.icns] into it.
  
===Gnucash Moduleset===
+
Look through gnucash.bundle and adjust the paths to match your installation.
Paste the following into a file named gnucash.modules in your home folder:
 
<pre>
 
<?xml version="1.0" encoding="utf-8"?>
 
<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
 
<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
 
<moduleset>
 
  <repository type="svn" name="svn.gnome.org" default="yes"
 
      href="http://svn.gnome.org/svn/"/>
 
  <repository type="tarball" name="kernel.org"
 
      href="http://www.kernel.org/pub/linux/"/>
 
  <repository type='tarball' name='ftp.gnu.org'
 
      href="ftp://ftp.gnu.org/gnu/"/>
 
  <repository type='tarball' name='sourceforge'
 
      href="http://downloads.sourceforge.net/"/>
 
  <repository type="cvs" name="slib.savannah.gnu.org"
 
      cvsroot=":pserver:anonymous@cvs.savannah.gnu.org:/sources/slib"
 
      password=""/>
 
  <repository type="tarball" name="gnucash.org"
 
      href="http://www.gnucash.org/pub/gnucash/sources/stable/"/>
 
  
 +
;Documentation: The bundle includes documentation. If you've built it, great, no problem. You need to have it installed for the Help menu items to work. If you didn't build it and you don't want to, then comment out or remove the lines <syntaxhighlight lang="xml">
 +
  <data dest="${bundle}/Contents/Resources/en.lproj/GnuCash Help/">
 +
    ${prefix}/share/gnome/help/gnucash/C/gnucash-manual
 +
  </data>
  
 +
  <data dest="${bundle}/Contents/Resources/en.lproj/GnuCash Guide/">
 +
    ${prefix}/share/gnome/help/gnucash/C/gnucash-guide/
 +
  </data>
  
  <include
+
  <data dest="${bundle}/Contents/Resources/de.lproj/GnuCash Help/">
      href="http://people.imendio.com/richard/gtk-osx-build/modulesets/gtk-osx.modules"/>
+
    ${prefix}/share/gnome/help/gnucash/de_DE/gnucash-manual
 +
  </data>
  
 +
  <data dest="${bundle}/Contents/Resources/de.lproj/GnuCash Guide/">
 +
    ${prefix}/share/gnome/help/gnucash/de_DE/gnucash-guide/
 +
  </data>
  
   <tarball id='readline' autogen-sh='configure'>
+
   <data dest="${bundle}/Contents/Resources/it.lproj/GnuCash Help/">
    <source href='ftp://ftp.gnu.org/gnu/readline/readline-5.2.tar.gz'/>
+
    ${prefix}/share/gnome/help/gnucash/it_IT/gnucash-manual
      <patches>
+
   </data>
<patch file='ftp://ftp.gnu.org/gnu/readline/readline-5.2-patches/readline52-001' strip='2' />
 
<patch file='ftp://ftp.gnu.org/gnu/readline/readline-5.2-patches/readline52-002' strip='2' />
 
<patch file='ftp://ftp.gnu.org/gnu/readline/readline-5.2-patches/readline52-003' strip='2' />
 
<patch file='ftp://ftp.gnu.org/gnu/readline/readline-5.2-patches/readline52-004' strip='2' />
 
<patch file='ftp://ftp.gnu.org/gnu/readline/readline-5.2-patches/readline52-005' strip='2' />
 
<patch file='ftp://ftp.gnu.org/gnu/readline/readline-5.2-patches/readline52-006' strip='2' />
 
<patch file='ftp://ftp.gnu.org/gnu/readline/readline-5.2-patches/readline52-007' strip='2' />
 
<patch file='ftp://ftp.gnu.org/gnu/readline/readline-5.2-patches/readline52-008' strip='2' />
 
<patch file='ftp://ftp.gnu.org/gnu/readline/readline-5.2-patches/readline52-009' strip='2' />
 
<patch file='ftp://ftp.gnu.org/gnu/readline/readline-5.2-patches/readline52-010' strip='2' />
 
<patch file='ftp://ftp.gnu.org/gnu/readline/readline-5.2-patches/readline52-011' strip='2' />
 
<patch file='ftp://ftp.gnu.org/gnu/readline/readline-5.2-patches/readline52-012' strip='2' />
 
      </patches>
 
   </tarball>
 
  
   <autotools id="OpenSP" autogen-sh='configure'
+
   <data dest="${bundle}/Contents/Resources/it.lproj/GnuCash Guide/">
    autogenargs="--disable-static --enable-shared --disable-doc-build">
+
     ${prefix}/share/gnome/help/gnucash/it_IT/gnucash-guide/
     <branch repo="sourceforge" module="openjade/OpenSP-1.5.2.tar.gz"
+
   </data>
    version='1.5.2'/>>
 
   </autotools>
 
  
   <autotools id="libofx" autogen-sh='configure'>
+
   <data dest="${bundle}/Contents/Resources/ja.lproj/GnuCash Guide/">
     <branch repo="sourceforge" module="libofx/libofx-0.9.0.tar.gz"
+
     ${prefix}/share/gnome/help/gnucash/ja_JP/gnucash-guide/
    version='0.9.0'/>
+
  <data dest="${bundle}/Contents/Resources/pt.lproj/GnuCash Help/">
     <dependencies>
+
     ${prefix}/share/doc/gnucash-docs/pt/gnucash-manual/
      <dep package='guile-1.6'/>
+
   </data>
      <dep package="OpenSP"/>
 
    </dependencies>
 
   </autotools>
 
  
   <autotools id="guile-1.6" autogen-sh="configure"
+
   <data dest="${bundle}/Contents/Resources/pt.lproj/GnuCash Guide/">
    autogenargs="--disable-static --enable-shared
+
    ${prefix}/share/doc/gnucash-docs/pt/gnucash-guide/
  --disable-scrollkeeper --disable-xlib">
+
  </data>
    <branch repo="ftp.gnu.org" module="guile/guile-1.6.8.tar.gz"
+
 
    version="1.6.7" size="3114052" />
+
  <data dest="${bundle}/Contents/Resources/ru.lproj/GnuCash Guide/">
    <dependencies>
+
    ${prefix}/share/doc/gnucash-docs/ru/gnucash-guide/
      <dep package='readline'/>
+
  </data>
    </dependencies>
+
</syntaxhighlight> To comment out XML code, surround it like so: <SyntaxHighlight lang="xml">
  </autotools>
+
<!-- stuff to be commented out -->
 +
</SyntaxHighlight> Note that comments cannot contain "--".
  
  <autotools id="Slib" skip-autogen="true">
+
You're ready to make your bundle: <SyntaxHighlight lang="sh">
    <branch repo="slib.savannah.gnu.org"
+
jhbuild shell                #to set up the environment for the bundler
    module="slib"/>
+
export PATH=$PREFIX/bin:$PATH #because jhbuild shell doesn't do this for some reason
    <dependencies>
+
gtk-mac-bundler gnucash.bundle
      <dep package="guile-1.6"/>
+
exit                          #quit the jhbuild shell
    </dependencies>
+
</SyntaxHighlight>
  </autotools>
 
  
  <autotools id="gnucash" autogen-sh="configure"
+
And your bundle should be ready to go.
    autogenargs="--enable-ofx">
+
Try <tt>GnuCash.app/Contents/MacOS/GnuCash</tt> from the command-line so that you can see any error messages. If that works, try <tt>open GnuCash.app</tt>. If that works, then you can move GnuCash.app to your Applications folder and it's ready to use.  
    <branch module="gnucash-2.2.7.tar.gz" version="2.2.7"
 
    repo="gnucash.org"/>
 
 
    <dependencies>
 
      <dep package="goffice"/>
 
      <dep package="libofx"/>
 
      <dep package="gtkhtml"/>
 
      <dep package="Slib"/>
 
    </dependencies>
 
 
 
  </autotools>
 
 
 
</moduleset>
 
</pre>
 
 
 
===GnuCash Start Script (commandline)===
 
Replace $PREFIX/bin/gnucash with this:
 
<pre>
 
export PREFIX="~/gtk/inst/" #You'll have to fix this up if you changed it
 
export PATH="$PREFIX/bin:${PATH}"
 
export XDG_CONFIG_DIRS=$PREFIX/etc/xdg
 
export XDG_DATA_DIRS=$PREFIX/share
 
 
 
GUILE_WARN_DEPRECATED="no"
 
export GUILE_WARN_DEPRECATED
 
 
 
if test -z "$DBUS_SESSION_BUS_ADDRESS"; then
 
    eval `dbus-launch --sh-syntax --exit-with-session --config-file=$PREFIX/etc/dbus-1/session.conf`
 
fi
 
 
 
GNC_MODULE_PATH="$PREFIX/lib/gnucash:${GNC_MODULE_PATH}"
 
 
 
EXTRA_PATH="${EXTRA_PATH}:$PREFIX/share/gnucash/guile-modules"
 
EXTRA_PATH="${EXTRA_PATH}:$PREFIX/share/gnucash/scm"
 
GUILE_LOAD_PATH="${EXTRA_PATH}:${GUILE_LOAD_PATH}"
 
 
 
EXTRA_LIBS="${GNC_MODULE_PATH}"
 
EXTRA_LIBS="${EXTRA_LIBS}:/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/Versions/A/Resources/"
 
EXTRA_LIBS="${EXTRA_LIBS}:$PREFIX/lib"
 
EXTRA_LIBS="${EXTRA_LIBS}:$PREFIX/lib/gnucash"
 
 
 
LD_LIBRARY_PATH="${EXTRA_LIBS}:${LD_LIBRARY_PATH}"
 
DYLD_LIBRARY_PATH="${EXTRA_LIBS}:${DYLD_LIBRARY_PATH}"
 
 
 
export GNC_MODULE_PATH
 
export GUILE_LOAD_PATH
 
export LD_LIBRARY_PATH
 
export DYLD_LIBRARY_PATH
 
 
 
exec gnucash-bin "$@"
 
</pre>
 
===Gnucash Start Script (Bundler)===
 
If you're going to use the bundler, paste this file into your bundle directory named gnucash-launcher; to run from the command line, put this in $PREFIX/bin/gnucash.
 
<pre>
 
#!/bin/sh
 
#We need to point to our original install directory, so define $PREFIX.  
 
#Don't forget to fix this for your own installation!
 
 
 
export PREFIX=~/gtk/inst
 
 
 
if test "x$IGE_DEBUG_LAUNCHER" != x; then
 
    set -x
 
fi
 
 
 
if test "x$IGE_DEBUG_GDB" != x; then
 
    EXEC="gdb --args"
 
else
 
    EXEC=exec
 
fi
 
 
 
name="`basename $0`"
 
tmp="`pwd`/$0"
 
tmp=`dirname "$tmp"`
 
tmp=`dirname "$tmp"`
 
bundle=`dirname "$tmp"`
 
bundle_contents="$bundle"/Contents
 
bundle_res="$bundle_contents"/Resources
 
bundle_lib="$bundle_res"/lib
 
bundle_bin="$bundle_res"/bin
 
bundle_data="$bundle_res"/share
 
bundle_etc="$bundle_res"/etc
 
 
 
export DYLD_LIBRARY_PATH="$bundle_lib"
 
export XDG_CONFIG_DIRS="$bundle_etc"/xdg
 
#This has to point back to $PREFIX because of hard-coded paths and the fact that binreloc works only
 
#with Linux:
 
export XDG_DATA_DIRS=$PREFIX/share
 
export GTK_DATA_PREFIX="$bundle_data"
 
export GTK_EXE_PREFIX="$bundle_res"
 
export GTK_PATH="$bundle_res"
 
 
 
export GTK2_RC_FILES="$bundle_etc/gtk-2.0/gtkrc"
 
export GTK_IM_MODULE_FILE="$bundle_etc/gtk-2.0/gtk.immodules"
 
export GDK_PIXBUF_MODULE_FILE="$bundle_etc/gtk-2.0/gdk-pixbuf.loaders"
 
export PANGO_RC_FILE="$bundle_etc/pango/pangorc"
 
 
 
# We need a UTF-8 locale.
 
export LANG="`grep \`defaults read .GlobalPreferences AppleCollationOrder 2>&1\`_ /usr/share/locale/locale.alias  | tail -n1 | sed 's/\./ /' | awk '{print $2}'`.UTF-8"
 
 
 
if test -f "$bundle_lib/charset.alias"; then
 
    export CHARSETALIASDIR="$bundle_lib"
 
fi
 
 
 
# Extra arguments can be added in environment.sh.
 
EXTRA_ARGS="--config-path $bundle_etc/gnucash --share-path $bundle_data/gnucash --debug"
 
  
if test -f "$bundle_res/environment.sh"; then
+
=== Bundling Oldstable ===
  source "$bundle_res/environment.sh"
 
fi
 
  
# Strip out the argument added by the OS.
+
To bundle GnuCash version 2.6 and earlier you need [https://raw.github.com/Gnucash/gnucash-on-osx/master/gnucash-bundler/gnucash-oldstable.bundle gnucash-oldstable.bundle], [https://raw.github.com/Gnucash/gnucash-on-osx/master/gnucash-bundler/Info-oldstable.plist Info-oldstable.plist] instead of the corresponding ones listed above as well as
if [ x`echo "x$1" | sed -e "s/^x-psn_.*//"` == x ]; then
+
[https://raw.github.com/Gnucash/gnucash-on-osx/master/gnucash-bundler/gnucash.launcher gnucash.launcher]. Older versions don't have the Portuguese or Russian Guide translations. Otherwise the procedure is the same.
    shift 1
 
fi
 
  
PFX=${bundle_res}
+
=== Bundling from a Git Clone ===
export PFX
+
At present there are two active git branches, 'maint' and 'master'. Both use the primary bundling procedure above.
PATH="${PFX}/bin:${PATH}"
 
export PATH
 
  
GUILE_WARN_DEPRECATED="no"
+
=== Making a distribution ===
export GUILE_WARN_DEPRECATED
 
  
if test -z "$DBUS_SESSION_BUS_ADDRESS"; then
+
* Make a clean build including the documentation, making sure that you're not building any libraries with debugging. With all of the dependencies, the package is huge enough without it. Make sure that you're using the latest git masters for [http://gitlab.gnome.org/GNOME/gtk-mac-bundler gtk-mac-bundler] and [http://github.com/Gnucash/gnucash-on-osx  gnucash-on-osx].
    eval `dbus-launch --sh-syntax --exit-with-session --config-file=$bundle_res/etc/dbus-1/session.conf`
+
* Edit the version numbers and, if necessary, the copyright dates in Info.plist (or Info-unstable.plist).
fi
+
* make sure that $APPLICATION_CERT is set correctly with your Apple Developer Program certificate ID. gtk-mac-bundler uses the value of that environment variable to codesign the app bundle.
 +
* Make a bundle as described above. Test it.
 +
* Make a directory named for the version that you're going to distribute and move the new bundle into it.
 +
* Copy the scriptlet "FinanceQuote Update.app" from the previous version .dmg to the new distribution folder.
 +
* Copy AUTHORS, DOCUMENTORS, LICENSE, NEWS, and README from the GnuCash source directory to the distribution folder. Rename each file with a ".txt" suffix so that Finder will recognize it and enable QuickLook.
 +
* Open /Applications/Utilities/Disk Utility.app and select File>New>Disk Image from Folder in the menu. Select your installation directory in the first chooser and name it appropriately in the second (<tt>Gnucash-Intel-X.Y-Z.dmg</tt> where X.Y is the GnuCash version and Z is the serial number of dmgs for that release, beginning with 1.)
 +
* codesign the dmg with your Apple Developer Program certificate.
 +
* Get the SHA-256 hash of the .dmg with <SyntaxHighlight lang="sh">
 +
shasum -a 256 Gnucash-Intel-X.Y-Z.dmg
 +
</SyntaxHighlight> and paste the result into the SourceForge README.txt, the Github release notes, the news article in <tt>gnucash-htdocs</tt>, and the release announcement email.
 +
* Upload both the resulting .dmg  to the correct version directory of Gnucash's file manager area on Sourceforge. If this is a stable release, check the "Mac" box on the options panel so that users viewing the project page with a Mac will see the new release in the big green button.
 +
* Upload the .dmg to the release on Github.
 +
* Update the appropriate links on the Gnucash webpage.
  
GNC_MODULE_PATH="${PFX}/lib/gnucash:${GNC_MODULE_PATH}"
+
==Accessibility==
 +
Gtk has its own accessibility library, atk. It doesn't use or support the Mac's accessibility functions; in particular, one must use the [https://wiki.gnome.org/Projects/Orca Orca] screen reader. This isn't provided in the application bundle as as far as we know there is no ready-made Mac build of it.
  
EXTRA_PATH="${EXTRA_PATH}:${PFX}/share/gnucash/guile-modules"
+
==Helping Out==
EXTRA_PATH="${EXTRA_PATH}:${PFX}/share/gnucash/scm"
 
GUILE_LOAD_PATH="${EXTRA_PATH}:${GUILE_LOAD_PATH}"
 
  
EXTRA_LIBS="${GNC_MODULE_PATH}"
+
If you can work on one of these items, please pitch in! Some are Gnucash issues, some are issues with the Quartz implementation of Gtk, and some are integration issues. Join the [https://mail.gnome.org/mailman/listinfo/gtk-osx-devel-list gtk-osx-devel mailing list]  to coordinate your work with others.
EXTRA_LIBS="${EXTRA_LIBS}:/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/Versions/A/Resources/"
 
EXTRA_LIBS="${EXTRA_LIBS}:${PFX}/lib"
 
EXTRA_LIBS="${EXTRA_LIBS}:${PFX}/lib/gnucash"
 
  
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${EXTRA_LIBS}:"
+
==Example: Setting up a Development Environment==
DYLD_LIBRARY_PATH="${DYLD_LIBRARY_PATH}:${EXTRA_LIBS}"
 
  
export GNC_MODULE_PATH
+
====Platform====
export GUILE_LOAD_PATH
+
* M1 Mac running macOS Ventura 13.0.1
export LD_LIBRARY_PATH
+
* Existing user administrator account with homebrew installed
export DYLD_LIBRARY_PATH
 
 
 
$EXEC "$bundle_contents/MacOS/$name-bin" $* $EXTRA_ARGS
 
</pre>
 
 
 
===GnuCash Info.Plist===
 
This is the Info.Plist required of all App Bundles. Paste into "Info.Plist" in the bundle directory.
 
<pre>
 
<?xml version="1.0" encoding="UTF-8"?>
 
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 
<plist version="1.0">
 
<dict>
 
<key>CFBundleDevelopmentRegion</key>
 
<string>English</string>
 
<key>CFBundleExecutable</key>
 
<string>GnuCash</string>
 
<key>CFBundleGetInfoString</key>
 
<string>GnuCash version 2.2.7 © 2008 Free Software Foundation</string>
 
<key>CFBundleIconFile</key>
 
<string>gnucash.icns</string>
 
<key>CFBundleIdentifier</key>
 
<string>org.gnucash.GnuCash</string>
 
<key>CFBundleInfoDictionaryVersion</key>
 
<string>6.0</string>
 
<key>CFBundleLongVersionString</key>
 
<string>2.2.7 © 2008 Free Software Foundation</string>
 
<key>CFBundleName</key>
 
<string>GnuCash</string>
 
<key>CFBundlePackageType</key>
 
<string>APPL</string>
 
<key>CFBundleShortVersionString</key>
 
<string>2.2.7</string>
 
<key>CFBundleSignature</key>
 
<string>????</string>
 
<key>CFBundleVersion</key>
 
<string>2.2.7</string>
 
<key>CSResourcesFileMapped</key>
 
<true/>
 
<key>LSRequiresCarbon</key>
 
<true/>
 
<key>NSHumanReadableCopyright</key>
 
<string>Copyright 2008 Free Software Foundation</string>
 
</dict>
 
</plist>
 
 
 
</pre>
 
 
 
 
 
===GnuCash Bundle Description===
 
This one configures the bundler to create the app bundle. Paste it into the bundler directory and name it 'gnucash.bundle':
 
<pre>
 
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
 
<app-bundle>
 
 
 
  <meta>
 
    <!-- Where to pick up the GTK+ installation, icon themes,
 
        etc. Note that "${env:PREFIX}" is evaluated to the value of
 
        the environment variable PREFIX, and likewise with HOME. You
 
        can define additional prefixes and refer to them in paths
 
        throughout this file on the form "${prefix:name}". This is
 
        useful for installing certain libraries or even the
 
        application itself separately.
 
    -->
 
    <prefix name="default">${env:PREFIX}</prefix>
 
 
 
    <!-- The project directory is the default location of the created
 
        app. If you leave out the path, the current directory is
 
        used.
 
    -->
 
    <destination overwrite="yes">${env:HOME}/gnucash-bundler</destination>
 
 
 
    <image>
 
      <!-- Not implemented yet (DMG image). -->
 
    </image>
 
    <run-install-name-tool/>
 
 
 
    <!-- Optionally specify a launcher script to use. If the
 
        application sets up everything needed itself, like
 
        environment variable, linker paths, etc, a launcher script is
 
        not needed. If the source path is left out, the default
 
        script will be used.
 
    -->
 
    <launcher-script>${project}/gnucash-launcher</launcher-script>
 
 
 
    <!-- Not implemented: Optional runtime, could be python or mono
 
        for example.
 
    -->
 
    <!--runtime copy="yes">/usr/bin/python</runtime-->
 
  </meta>
 
 
 
  <!-- The special macro "${project}" refers to the directory where
 
      this bundle file is located. The application name and bundle
 
      identifier are taken from the plist file.
 
  -->
 
  <plist>${project}/Info.plist</plist>
 
 
 
  <main-binary>${prefix}/bin/gnucash-bin</main-binary>
 
 
 
  <!-- Copy in GTK+ and Pango modules. Note the use of the
 
      "${pkg:module:variable}" macro, which evaluates to a pkg-config
 
      variable in the specified module. Note that any libraries that
 
      binaries link to are also copied in automatically.
 
  -->
 
  <binary>
 
    ${prefix}/lib/gtk-2.0/${pkg:gtk+-2.0:gtk_binary_version}/loaders/*.so
 
  </binary>
 
  <binary>
 
    ${prefix}/lib/pango/${pkg:pango:pango_module_version}/modules/pango-basic-fc.so
 
  </binary>
 
 
 
  <binary>
 
    ${prefix}/lib/GConf/2/*.so
 
  </binary>
 
 
 
  <binary>
 
    ${prefix}/lib/gnucash
 
  </binary>
 
  <binary>
 
    ${prefix}/libexec
 
  </binary>
 
 
 
  <binary>
 
    ${prefix}/bin/dbus-launch
 
  </binary>
 
 
 
  <binary>
 
    ${prefix}/bin/dbus-daemon
 
  </binary>
 
 
 
  <binary>
 
    ${prefix}/bin/gnc-*
 
  </binary>
 
 
 
 
 
  <!-- Data to copy in, usually Glade/UI files, images, sounds files
 
      etc. The destination inside the bundle can be specified if the
 
      files should end up at a different location, by using the
 
      "dest" property. The destination must then start with the macro
 
      "${bundle}", which refers to the bundle root directory.
 
  -->
 
  <data>
 
    ${prefix}/share/gnucash
 
  </data>
 
 
 
  <data>
 
    ${prefix}/share/mime
 
  </data>
 
 
 
  <data>
 
    ${prefix}/share/guile
 
  </data>
 
 
 
  <data>
 
    ${prefix}/share/gnome
 
  </data>
 
 
 
  <!--data dest="${bundle}/Contents/Resources/slib"-->
 
  <data>
 
    ${prefix}/lib/slib
 
  </data>
 
 
 
  <data dest="${bundle}/Contents/Resources">
 
    ${prefix}/share/gnucash/pixmaps/gnucash.icns
 
  </data>
 
 
 
  <data dest='${bundle}/Contents/Resources/lib/'>
 
    ${prefix}/lib/*.la
 
  </data>
 
 
 
  <data dest='${bundle}/Contents/Resources/var/lib/dbus/machine-id'>
 
    ${prefix}/var/lib/dbus/machine-id
 
  </data>
 
 
 
  <data dest='${bundle}/Contents/Resources/etc/dbus-1/'>
 
    ${prefix}/etc/dbus-1/
 
  </data>
 
  
 +
====Goal====
 +
* Create a new macOS user '''gnucash'''
 +
* Install a GnuCash development environment in the gnucash user account
 +
* Insulated the development environment from the homebrew installation
 +
* Build GunCash from git repo
  
  <!-- Icon themes to copy. The "icons" property can be either of
+
====Steps====
      "auto", "all", or "none". All or none should be
 
      self-explanatory, while auto means that the script will try to
 
      figure out which icons are needed. This is done by getting all
 
      the strings from all copied binaries, and matching them against
 
      icon names. To be safe, you should use "all". "none" is useful
 
      if you want just the index.theme file but no icons, mostly
 
      needed for the "hicolor" base theme.
 
  -->
 
  <!-- icon-theme icons="auto"/>
 
    Tango
 
  </icon-theme -->
 
  
</app-bundle>
+
# In the existing administrator account, use '''System Settings > Users & Groups > Add Account...'' to create the '''gnucash''' administrator account. Then, changing the bash version number as appropriate. <SyntaxHighlight lang="sh">
</pre>
+
brew install bash
 +
cp /opt/homebrew/Cellar/bash/5.2.15/bin/bash /Users/gnucash/Public/Drop\ Box
 +
chmod +a "user:gnucash deny add_file,search,add_subdirectory,delete_child,readattr,writeattr,writeextattr,readsecurity" /opt/homebrew
 +
</SyntaxHighlight>
 +
#* The development environment needs its own copy of bash, but at least in macOS 13, just copying '''/bin/bash''' doesn't work
 +
#* The first two commands provide a usable copy of bash to the gnucash user
 +
#* The '''chmod''' commands prevent the gnucash user from accessing the homebrew installation
 +
# Switch to the '''gnucash''' and <SyntaxHighlight lang="sh">
 +
cd $HOME
 +
curl -O -L https://gitlab.gnome.org/GNOME/gtk-osx/raw/master/gtk-osx-setup.sh
 +
chmod 755 gtk-osx-setup.sh
 +
./gtk-osx-setup.sh
 +
export PATH="$HOME/.new_local/bin:$PATH"
 +
cp ~/Public/Drop\ Box/bash $HOME/.new_local/bin
 +
curl -O -L https://github.com/gnucash/gnucash-on-osx/raw/master/jhbuildrc-custom
 +
mv jhbuildrc-custom .config
 +
echo 'branches["gnucash-git"] = (None, "master")' >> .config/jhbuildrc-custom
 +
sed -i '' -Ee 's/= _modules_stable/= _modules_git/' .config/jhbuildrc-custom
 +
PREFIX=/Users/gnucash/opt/gnucash jhbuild bootstrap-gtk-osx
 +
PREFIX=/Users/gnucash/opt/gnucash jhbuild build
 +
</SyntaxHighlight>
 +
# As of January 2023, the build failed on xmlsec1 due to a missing dependency in gnutls. The build stopped with a menu of several options.  The following patched the issue <SyntaxHighlight lang="sh">
 +
# Open another terminal and edit the following package config file
 +
nano /Users/gnucash/opt/gnucash/inst/lib/pkgconfig/gnutls.pc  # add -lgcrypt to the Libs line & save
 +
# Back in the original build terminal, select Go to phase "configure" option
 +
</SyntaxHighlight>
 +
# Install Finance::Quote from source <SyntaxHighlight lang="sh">
 +
PREFIX=/Users/gnucash/opt/gnucash jhbuild shell
 +
PREFIX=/Users/gnucash/opt/gnucash
 +
curl -L https://cpanmin.us | perl - App::cpanminus
 +
export PATH="$PATH:$HOME/perl5/bin"
 +
cpanm --local-lib=$PREFIX/lib/perl5 local::lib && eval $(perl -I $PREFIX/lib/perl5/lib/perl5 -Mlocal::lib)
 +
git clone https://github.com/finance-quote/finance-quote.git
 +
cd finance-quote
 +
cpanm install Dist::Zilla
 +
dzil authordeps --missing | cpanm --notest
 +
dzil listdeps --missing | cpanm --notest
 +
cpanm install Data::Dumper::Perltidy Smart::Comments
 +
dzil build
 +
cpanm Finance-Quote-1.55.tar.gz
 +
cpanm install JSON::Parse
 +
</SyntaxHighlight>

Latest revision as of 17:32, 6 April 2023

Downloads

macOS 11 "Big Sur" or higher
Gnucash-Arm-5.9-1 is now available for download from the GnuCash projects at Sourceforge and Github.
macOS 10.13 "High Sierra" or higher
Gnucash-Intel-5.9-1 is now available for download from the GnuCash projects at Sourceforge and Github.
Alternatives and older versions
Release notes
are included in the disk-image.

For virtually all users it is more appropriate to download the binary rather than to use the procedure described here.

Overview

GnuCash can be built to run more or less natively on macOS -- meaning without X11. Better yet, the build is almost automatic.

This page describes the procedure to build GnuCash with the Quartz environment. You can also use MacPorts: The details are described at MacOS/MacPortsDetail. If you already have MacPorts installed, you should use that procedure, as gtk-osx doesn't work well with a MacPorts installation.

If you want to have a clickable GnuCash.app to put in your Applications folder, this is the solution to use. If you want to be able to easily customize your installation, this is also the solution for you. Don't want all of the extra stuff that MacPorts drags in? Well, this might be a bit better... but GnuCash is notorious for its huge list of dependencies. Want to keep up with the latest work from the Gnome developers? You can set up this solution to get many of its packages directly from source-code-control. That's a double-edged sword, of course, because if a build gets broken, you're pretty well stuck until the developers for that package fix it.

A build will consume about 5 gigabytes of disk space and typically take several hours to run. The initial build, which includes pulling down sources from all dependencies, can take days, depending on how often network errors interrupt the process, and how quickly they are noticed.

This build integrates Gnucash menus with the Mac menubar at the top of the screen. About, Preferences, and Quit are in the "GnuCash" menu (it's named "gnucash-bin" when you run from the command line) in standard Mac style. Standard accelerator keys like Command-Q (quit), Command-S (save), and Command-O (Open) work as well. A patch to Gtk+ allows copy and paste in the register pages.

Support

This procedure depends on the Gnome Gtk-OSX project. Support for that is provided via the gtk-osx-users-list@gnome.org mailing list. Questions, comments, or suggestions about Gnucash should be directed to the appropriate Gnucash mailing list (gnucash-devel for development versions (git master) or gnucash-user for release (3.x, git maint).)

Preliminaries

Read Building Gtk-OSX and scan the jhbuild docs. This procedure is based on both. Note well the warnings about Homebrew, MacPorts, and Fink! Creating a separate user for building and packaging GnuCash is the easiest work-around if you've used any of those systems in your regular userid.

First download gtk-osx-setup.sh by clicking the link or from the command line:

curl -O -L https://gitlab.gnome.org/GNOME/gtk-osx/raw/master/gtk-osx-setup.sh

and run it from the command line. Gtk now requires Python3 to build and Apple provides Python3 only on MacOS 10.15 Catalina, so it will first set up a Python3 virtual environment, then install jhbuild and configure what it needs to run. It will ask if you want to install CPython. You do.

It defaults to installing everything in $HOME/.new_local. If you prefer to install somewhere else, set the environment variables DEVPREFIX and PYTHONUSERBASE to that directory before running gtk-osx-setup.sh. One way to do that is inline with the command, e.g.

DEVPREFIX=$HOME/.jhbuild_root PYTHONUSERBASE=$HOME/.jhbuild_root ./gtk-osx-setup.sh

There are some other directory customizing environment variables, see the list in gtk-osx-setup.sh Default or not, you'll want to add the install location's bin directory to $PATH.

JHBuild is configured to build GnuCash via jhbuildrc-custom. Download this file to your home directory either by clicking the link and moving the downloaded file or from the command line:

curl -O -L https://github.com/gnucash/gnucash-on-osx/raw/master/jhbuildrc-custom

and place it in $HOME/.config--unless you've set something different in $XDG_CONFIG_HOME, in which case put it there.

OS X 10.11 added a security feature called System Integrity Protection or SIP. One "feature" is that it strips linker environment variables (the ones starting with LD_ and DYLD_) from the environment when a "system" program does a fork/exec. For our purposes "system program" means one installed in /bin or /usr/bin, in particular /bin/sh.

The Guile compiler, guiled, is a shell script that as written uses /bin/sh to set the prefix then execs guile to run a compilation script. That fails in the presence of SIP.

One can get around this by disabling SIP, but that's a whole-system change that requires a reboot, and SIP clearly has significant security benefits. Don't do that.

The other workaround is to use a shell that isn't in /bin or /usr/bin. One can just copy /bin/bash to one's user-level bin directory. gtk-osx-setup.sh does that for you, putting it in the install location's bin directory.

The default build location is $HOME/gnucash with subdirectories src, build, and inst for unpacking the sources, building, and installation respectively. You can change that by setting the environment variable PREFIX, e.g.
PREFIX=/opt/gnucash jhbuild bootstrap-gtk-osx
PREFIX=/opt/gnucash jhbuild build
You can make finer-grained changes by editing jhbuildrc-custom.

setup_sdk

With no arguments (the default) setup_sdk() will configure the build for your system. Unless you're building for distribution we recommend that you do this.

If you have Xcode 7 (shipped with OS X 10.9 (Mavericks)) or later you can build for any version from 10.6 on with the included SDK by calling (e.g.)
setup_sdk("10.6", native, ["i386"])
Note, however, that some users have noted linkage problems when doing this.

It is safest to build GnuCash on the earliest macOS version you intend to support.

The GnuCash 2.6.x application bundles were built for Mac OS X 10.5 and later. To do likewise, please see Building for Older Versions of Mac OS X. You'll use
setup_sdk("10.5", "10.5"["i386"])
Notes
  • GnuCash v2.7.x and later use the CMake buildsystem.
  • GnuCash v2.7.x and later requires MacOS X 10.9 ("Mavericks") or later.
  • GnuCash v3.900 and later requires MacOS 10.13 ("High Sierra") or later because it uses C++17 and the attendant standard library.
  • Apple has removed 32-bit runtime support from macOS 10.15, so you'll need to build on an older version of macOS if you want arch='i386'.
  • Apple Silicon is first supported in macOS 11. We have never successfully cross-compiled the Gtk stack so you'll probably need an Apple Silicon Mac to build an Apple Silicon native GnuCash. Note that as of October 2022 WebKitGtk isn't able to find its loadable modules so that reports don't render in GnuCash.
  • PowerPC similarly requires building on a PowerPC machine.

Make any changes by editing jhbuildrc-custom

Building

Once all of the preliminaries are complete, run:

jhbuild bootstrap-gtk-osx
jhbuild build

Building for Development

Please see Development for general guidelines and lots of helpful links.

If you intend to contribute your work to the GnuCash project please subscribe to the gnucash-devel list and coordinate your work with the core developers before starting.

You'll need to work with the appropriate source code repository rather than the release tarball from the procedure so far. Git provides details on our repository and has some help for developers who aren't yet familiar with the git version control system. Open jhbuildrc-custom in your text editor and find the section

#Select which modules to build. The only difference is which gnucash
#module (and all of the dependencies, see above) get built. "
modules = ["meta-gtk-osx-bootstrap", "meta-gnucash-stable"]
#modules = ["meta-gtk-osx-bootstrap", "gnucash-unstable"]
#modules = ["meta-gtk-osx-bootstrap", "gnucash-git"]
#branches["gnucash-git"] = (None, "maint")

and change it to

#Select which modules to build. The only difference is which gnucash
#module (and all of the dependencies, see above) get built. "
#modules = ["meta-gtk-osx-bootstrap", "meta-gnucash-stable"]
#modules = ["meta-gtk-osx-bootstrap", "gnucash-unstable"]
modules = ["meta-gtk-osx-bootstrap", "gnucash-git"]
branches["gnucash-git"] = (None, "maint")
Note the branches line
It will build the current stable branch; to build the development branch, the one leading to the next major release, change maint to master. You may also want to change the prefix directory in the line above that block.

Command-line builds

Once you have your initial build finished you'll start editing sources (they'll be in $HOME/gnucash-stable/src/gnucash-git unless you changed the prefix in jhbuilrc-custom) and you'll want to build and run the unit tests. Start a jhbuild shell and change directory to the build directory:

jhbuild shell
cd %PREFIX/../build/gnucash-git

From there you can run the usual shell commands like cmake and ninja.

Building with Xcode

It's possible to build GnuCash using Apple's Xcode IDE. To make it work first do a regular build as above to get all of the dependencies set up.

Now create a new build directory and ```cd``` to it but do *not* start a jhbuild shell, just export the following environment variables to simplify the cmake invocation:

export PREFIX=/full/path/to/prefix
export PATH=$PATH:$PREFIX/bin
export SRCROOT=$PREFIX/../src

making any required changes. Be sure to make different build directories for the maint and the master branches.

Now create the xcodeproject with cmake:

cmake -G Xcode -D CMAKE_INSTALL_PREFIX=$PREFIX -D GTEST_ROOT=$SRCROOT/googletest $SRCROOT/gnucash-git

If you're building from a tarball you'll need to change the source directory at the end of the line.

For some newer versions of Xcode cmake seems unable to determine the C compiler and tries to use ```ld```. If you encounter errors during Cmake or building saying that `ld` doesn't accept some option try adding

  -D CMAKE_C_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/Xcodetoolchain.default/usr/bin/clang

to the cmake command line. Adjust the path as needed if the Xcode you're using isn't /Applications/Xcode.app.

Notes
  • Because all current branches of GnuCash use C++ features that don't compile on or for earlier versions, GnuCash requires MacOS 10.13 (High Sierra) or later.
  • The dependencies for GnuCash have changed from the 2.x releases. The most significant are that major Linux distributions have dropped support for WebKit1Gtk, so we had to enable support for WebKit2Gtk and that in turn requires that GnuCash switch to Gtk3. We've rewritten several modules in C++ and are using GoogleTest for new unit tests and the Boost Libraries for several language extensions. The register has been fixed to no longer use the obsolete libgnomecanvas and the small part of libgoffice that the CSV importer required has been copied into GnuCash sources.

Documentation

The gnucash documentation is online, of course, but if you want a local copy, you can build the modules gnucash-docs or gnucash-docs-git. Just add whichever one you want to your "modules" argument. If you're using gnucash-docs-git you might also want to select the branch by adding a line

branches["gnucash-docs-git"] = (None, "maint")

setting "maint" or "master" as you prefer.

Debugging

To get a debugging build, add the line setup_debug()

to jhbuildrc-custom. Beware, though, that WebKit doesn't build with debugging enabled. I usually build everything first without debugging enabled, then enable it and rebuild
jhbuild buildone --force --clean
the packages you want to debug. Most of the time you can get by with just glib and gnucash, but depending on what you're working on, you might also want gtk+, gwenhywfar, aqbanking, or libdbi.

Running from the commandline

Now you're ready to try it out:
$PREFIX/bin/gnucash

$PREFIX is the path to where you've built gtk; you can fill it in yourself or use jhbuild shell to set it for you.

Making a Bundle

So far so good, but you don't really want to have to open a Terminal window every time you want to use GnuCash, now do you? Of course not. You want a nice icon in your Applications folder (and maybe in the Dock) to click on when you run GnuCash. Here's how to do this:

N.B. This procedure works only with GnuCash built according to the above instructions.

Clone the bundler, cd into the cloned gtk-mac-bundler directory, and make install
Create a directory somewhere convienient (we'll call it gnucash-bundler from now on), cd to it, and download gnucash.bundle, Info.plist, and gnucash.icns into it.

Look through gnucash.bundle and adjust the paths to match your installation.

Documentation
The bundle includes documentation. If you've built it, great, no problem. You need to have it installed for the Help menu items to work. If you didn't build it and you don't want to, then comment out or remove the lines
  <data dest="${bundle}/Contents/Resources/en.lproj/GnuCash Help/">
    ${prefix}/share/gnome/help/gnucash/C/gnucash-manual
  </data>

  <data dest="${bundle}/Contents/Resources/en.lproj/GnuCash Guide/">
    ${prefix}/share/gnome/help/gnucash/C/gnucash-guide/
  </data>

   <data dest="${bundle}/Contents/Resources/de.lproj/GnuCash Help/">
    ${prefix}/share/gnome/help/gnucash/de_DE/gnucash-manual
  </data>

  <data dest="${bundle}/Contents/Resources/de.lproj/GnuCash Guide/">
    ${prefix}/share/gnome/help/gnucash/de_DE/gnucash-guide/
  </data>

  <data dest="${bundle}/Contents/Resources/it.lproj/GnuCash Help/">
    ${prefix}/share/gnome/help/gnucash/it_IT/gnucash-manual
  </data>

  <data dest="${bundle}/Contents/Resources/it.lproj/GnuCash Guide/">
    ${prefix}/share/gnome/help/gnucash/it_IT/gnucash-guide/
  </data>

  <data dest="${bundle}/Contents/Resources/ja.lproj/GnuCash Guide/">
    ${prefix}/share/gnome/help/gnucash/ja_JP/gnucash-guide/
  <data dest="${bundle}/Contents/Resources/pt.lproj/GnuCash Help/">
    ${prefix}/share/doc/gnucash-docs/pt/gnucash-manual/
  </data>

  <data dest="${bundle}/Contents/Resources/pt.lproj/GnuCash Guide/">
    ${prefix}/share/doc/gnucash-docs/pt/gnucash-guide/
  </data>
  
  <data dest="${bundle}/Contents/Resources/ru.lproj/GnuCash Guide/">
    ${prefix}/share/doc/gnucash-docs/ru/gnucash-guide/
  </data>
To comment out XML code, surround it like so:
<!-- stuff to be commented out -->
Note that comments cannot contain "--".
You're ready to make your bundle:
jhbuild shell                 #to set up the environment for the bundler
export PATH=$PREFIX/bin:$PATH #because jhbuild shell doesn't do this for some reason
gtk-mac-bundler gnucash.bundle
exit                          #quit the jhbuild shell

And your bundle should be ready to go. Try GnuCash.app/Contents/MacOS/GnuCash from the command-line so that you can see any error messages. If that works, try open GnuCash.app. If that works, then you can move GnuCash.app to your Applications folder and it's ready to use.

Bundling Oldstable

To bundle GnuCash version 2.6 and earlier you need gnucash-oldstable.bundle, Info-oldstable.plist instead of the corresponding ones listed above as well as gnucash.launcher. Older versions don't have the Portuguese or Russian Guide translations. Otherwise the procedure is the same.

Bundling from a Git Clone

At present there are two active git branches, 'maint' and 'master'. Both use the primary bundling procedure above.

Making a distribution

  • Make a clean build including the documentation, making sure that you're not building any libraries with debugging. With all of the dependencies, the package is huge enough without it. Make sure that you're using the latest git masters for gtk-mac-bundler and gnucash-on-osx.
  • Edit the version numbers and, if necessary, the copyright dates in Info.plist (or Info-unstable.plist).
  • make sure that $APPLICATION_CERT is set correctly with your Apple Developer Program certificate ID. gtk-mac-bundler uses the value of that environment variable to codesign the app bundle.
  • Make a bundle as described above. Test it.
  • Make a directory named for the version that you're going to distribute and move the new bundle into it.
  • Copy the scriptlet "FinanceQuote Update.app" from the previous version .dmg to the new distribution folder.
  • Copy AUTHORS, DOCUMENTORS, LICENSE, NEWS, and README from the GnuCash source directory to the distribution folder. Rename each file with a ".txt" suffix so that Finder will recognize it and enable QuickLook.
  • Open /Applications/Utilities/Disk Utility.app and select File>New>Disk Image from Folder in the menu. Select your installation directory in the first chooser and name it appropriately in the second (Gnucash-Intel-X.Y-Z.dmg where X.Y is the GnuCash version and Z is the serial number of dmgs for that release, beginning with 1.)
  • codesign the dmg with your Apple Developer Program certificate.
  • Get the SHA-256 hash of the .dmg with
    shasum -a 256 Gnucash-Intel-X.Y-Z.dmg
    
    and paste the result into the SourceForge README.txt, the Github release notes, the news article in gnucash-htdocs, and the release announcement email.
  • Upload both the resulting .dmg to the correct version directory of Gnucash's file manager area on Sourceforge. If this is a stable release, check the "Mac" box on the options panel so that users viewing the project page with a Mac will see the new release in the big green button.
  • Upload the .dmg to the release on Github.
  • Update the appropriate links on the Gnucash webpage.

Accessibility

Gtk has its own accessibility library, atk. It doesn't use or support the Mac's accessibility functions; in particular, one must use the Orca screen reader. This isn't provided in the application bundle as as far as we know there is no ready-made Mac build of it.

Helping Out

If you can work on one of these items, please pitch in! Some are Gnucash issues, some are issues with the Quartz implementation of Gtk, and some are integration issues. Join the gtk-osx-devel mailing list to coordinate your work with others.

Example: Setting up a Development Environment

Platform

  • M1 Mac running macOS Ventura 13.0.1
  • Existing user administrator account with homebrew installed

Goal

  • Create a new macOS user gnucash
  • Install a GnuCash development environment in the gnucash user account
  • Insulated the development environment from the homebrew installation
  • Build GunCash from git repo

Steps

  1. In the existing administrator account, use System Settings > Users & Groups > Add Account... to create the gnucash' administrator account. Then, changing the bash version number as appropriate.
    brew install bash
    cp /opt/homebrew/Cellar/bash/5.2.15/bin/bash /Users/gnucash/Public/Drop\ Box
    chmod +a "user:gnucash deny add_file,search,add_subdirectory,delete_child,readattr,writeattr,writeextattr,readsecurity" /opt/homebrew
    
    • The development environment needs its own copy of bash, but at least in macOS 13, just copying /bin/bash doesn't work
    • The first two commands provide a usable copy of bash to the gnucash user
    • The chmod commands prevent the gnucash user from accessing the homebrew installation
  2. Switch to the gnucash and
    cd $HOME
    curl -O -L https://gitlab.gnome.org/GNOME/gtk-osx/raw/master/gtk-osx-setup.sh
    chmod 755 gtk-osx-setup.sh
    ./gtk-osx-setup.sh
    export PATH="$HOME/.new_local/bin:$PATH"
    cp ~/Public/Drop\ Box/bash $HOME/.new_local/bin
    curl -O -L https://github.com/gnucash/gnucash-on-osx/raw/master/jhbuildrc-custom
    mv jhbuildrc-custom .config
    echo 'branches["gnucash-git"] = (None, "master")' >> .config/jhbuildrc-custom
    sed -i '' -Ee 's/= _modules_stable/= _modules_git/' .config/jhbuildrc-custom
    PREFIX=/Users/gnucash/opt/gnucash jhbuild bootstrap-gtk-osx
    PREFIX=/Users/gnucash/opt/gnucash jhbuild build
    
  3. As of January 2023, the build failed on xmlsec1 due to a missing dependency in gnutls. The build stopped with a menu of several options. The following patched the issue
    # Open another terminal and edit the following package config file
    nano /Users/gnucash/opt/gnucash/inst/lib/pkgconfig/gnutls.pc  # add -lgcrypt to the Libs line & save
    # Back in the original build terminal, select Go to phase "configure" option
    
  4. Install Finance::Quote from source
    PREFIX=/Users/gnucash/opt/gnucash jhbuild shell
    PREFIX=/Users/gnucash/opt/gnucash
    curl -L https://cpanmin.us | perl - App::cpanminus
    export PATH="$PATH:$HOME/perl5/bin"
    cpanm --local-lib=$PREFIX/lib/perl5 local::lib && eval $(perl -I $PREFIX/lib/perl5/lib/perl5 -Mlocal::lib)
    git clone https://github.com/finance-quote/finance-quote.git
    cd finance-quote
    cpanm install Dist::Zilla
    dzil authordeps --missing | cpanm --notest
    dzil listdeps --missing | cpanm --notest
    cpanm install Data::Dumper::Perltidy Smart::Comments
    dzil build
    cpanm Finance-Quote-1.55.tar.gz
    cpanm install JSON::Parse