\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[body={6.5in,9in},top=1in,left=1in,nohead]{geometry}
\usepackage{smallhds,lucidabr}
\usepackage{verbatim,fancyvrb}
\usepackage{url}

\DefineVerbatimEnvironment%
{code}{Verbatim}
{fontsize=\small, xleftmargin=1em}


\begin{document}

\setlength{\parskip}{1ex}
\setlength{\parindent}{0pt}

\begin{center}
  {\Large \textbf{Building a gretl disk image for OS X}}\\[6pt]
Allin Cottrell, September 2008
\end{center}

\textit{Note, Aril 2009. This needs to be totally re-written.  We now use the
GTK framework built by the R people, not Fink, when building
gretl for OS X.}

\section{Objective}

To build a stand-alone disk image (dmg) of gretl, including a suitably
configured version of gnuplot, for Mac OS X.  The final user should be
able to download the dmg file, double-click to mount it, and drag the
\texttt{Gretl.app} folder (found ``inside'' the image) to an
Applications folder.  You'll use Fink in the build process but the
final dmg should not be dependent on Fink in any way; it will,
however, be dependent on Apple's X11.

\section{Overview}

Here are the basic prerequisites:

\begin{itemize}
\item A fully functional installation of OS X.
\item Apple's X11 and the Xcode development package.  If these are
  not already installed, they should be found on the OS X installation
  DVDs.
\item A basic installation of Fink, including the tools
  \texttt{pkg-config} and \texttt{wget}.
\item Source code for gretl and gnuplot.
\item A skeleton for \texttt{Gretl.app} plus some auxiliary scripts.
\end{itemize}

The Fink executables directory (by default \texttt{/sw/bin}) should be
in your path, probably ahead of any other directories, for the build
process.

The method is as follows:

\begin{enumerate}
\item Install the \texttt{Gretl.app} skeleton.  This provides the
  ``space'' into which you'll install gretl and gnuplot.
\item Under Fink, install various required third-party packages
  (including the ``dev'' or developer components).  This includes
  GTK+ and friends (glib, atk, gdk, pango).  The glib package
  should be version 2.8 or later.
\item Configure and build gnuplot; install gnuplot into
  the \texttt{Gretl.app} folder.
\item Configure and build gretl; install gretl into the right place
  inside \texttt{Gretl.app}; delete some extraneous files and add some
  extras.
\item Copy various run-time files from your Fink installation into the
  appropriate place in \texttt{Gretl.app} (hence removing the
  dependency on Fink at run time).  Some configuration files have to
  be modified slightly for this putpose.  This is the trickiest part.
\item Grab the latest gretl documentation and dump it into place.
\item Create a compressed disk image containing \texttt{Gretl.app}.
\end{enumerate}

Steps 1, 2, 3 and 5 only need to be done once; thereafter you can
update the disk image with just steps 4, 6 and 7.

The following sections expand on each of the steps.

\section{The Gretl.app skeleton}

I'm making a gzipped tar file available.  This is largely an empty
directory tree, but it includes some ``generic'' files that shouldn't
depend on the particular OS X build platform (though see the final
section below).  This should be unzipped in some suitable location; on
the OS X system to which I have access I've put it under
\texttt{/Users/allin/dist}.

\url{http://ricardo.ecn.wfu.edu/~cottrell/gretl-osx/Gretl.app.tar.gz}

\section{Required Fink packages}

The exact line-up of these packages depends somewhat on the specific
OS X variant.  If a given package is available via OS X itself, then
you don't need to, and probably don't want to, install the
corresponding Fink package.  A case in point is libxml2, which is
supplied on recent OS X (but was not supplied in earlier variants);
libpng may also be supplied by OS X.

The required packages will (likely) include

\begin{center}
{\small
\begin{tabular}{llll}
\texttt{gtk+2} & \texttt{gtk+2-dev} & \texttt{gmp} & 
\texttt{gmp-shlibs} \\
\texttt{fftw3} & \texttt{readline5} & \texttt{readline5-shlibs} 
& \texttt{libpng3} \\
 \texttt{libpng-shlibs} & \texttt{pdflib} & \texttt{pdflib-shlibs}
\end{tabular}
}
\end{center}

\textit{Warning}: Apple's development trajectory has involved, and
will no doubt continue to involve, many incompatible changes to their
X11 installation.  To some extent, Fink is forced to mirror such
changes; therefore packages are sometimes renamed or removed.  You'll
probably have to do some figuring for yourself with regard to which
packages are needed. 

You don't need to install gnuplot under Fink since we'll be building
that ourselves.  Libxml2 will hopefully be supplied by OS X; dlcompat
was required at one time, but doesn't seem to be needed any longer.  I
installed mpfr via Fink: this is not strictly required for gretl, but
if it's present it enhances the functionality of the multiple
precision plugin: as of this writing the packages seem to be
\texttt{libmpfr1} and \texttt{libmpfr1-shlibs}.


\section{Building gnuplot}
\label{sec:gpbuild}

First, why do we bother building gnuplot?  Well, briefly, gnuplot is
rather integral to gretl, and it's preferable to have a gnuplot
version that is as functional as possible.  We want good PNG support,
provided via libgd.  Unfortunately the standard libgd installation on
Fink has a problem with finding TrueType fonts; we can work around
this if we build libgd ourselves.  In addition, OS X is highly
PDF-oriented, so it's nice to be able to provide PDF graph support,
which I don't think is in a stock Fink gnuplot build.  Finally, the
gnuplot source referenced below is patched so as to provide accurate
bounding box information for PNG files; this improves the quality of
mouse-over interaction with graphs under gretl.

\textit{libgd}: Grab patched source from

\url{http://ricardo.ecn.wfu.edu/~cottrell/gretl-osx/libgd-2.0.35.tar.gz}

Untar and configure with

\begin{code}
PREFIX=/Users/allin/misc
export CFLAGS="-O2 -I/sw/include"
export CPPFLAGS=$CFLAGS
export LDFLAGS="-L/usr/X11R6/lib"
./configure --prefix=$PREFIX --disable-rpath \
--disable-static --without-jpeg 
\end{code}

%$
Then \texttt{make} and \texttt{make install}.

Note that I'm installing to a temporary location outside of Gretl.app.
When we're ready, we'll just grab the appropriate dylib file from the
lib directory in that temporary tree (here
\texttt{/Users/allin/misc}).  Note: if you don't have \texttt{gd2}
installed via Fink, you'll have to ensure that pkg-config can find the
libgd you just installed, before building gnuplot.  Use something like

\begin{code}
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/Users/allin/misc/lib/pkgconfig"
\end{code}

Now grab the patched source for CVS gnuplot,

\url{http://ricardo.ecn.wfu.edu/~cottrell/gretl-osx/gnuplot-20080105.tar.gz}

Untar and configure with

\begin{code}
TOPDIR=/Users/allin/dist
export CFLAGS="-O2 -I/sw/include"
export LDFLAGS="-L/sw/lib -L/usr/X11R6/lib"
./configure --prefix=$TOPDIR/Gretl.app/Contents/Resources
\end{code}

Again, \texttt{make} and \texttt{make install}.

\section{Configuring and building gretl}

There's a file \texttt{myconf} in the osx subdirectory of the gretl
source.  You should use this, or a variant of it, to configure gretl.
Here's what it looks like:

\begin{code}
TOPDIR=/Users/allin/dist
export CFLAGS="-O2 -I/sw/include"
export LDFLAGS=-L/sw/lib
export CPPFLAGS=$CFLAGS
export PKG_CONFIG_PATH="/usr/lib/pkgconfig:/usr/X11R6/lib/pkgconfig:/sw/lib/pkgconfig"
export PATH=$TOPDIR/Gretl.app/Contents/Resources/bin:$PATH
./configure --prefix=$TOPDIR/Gretl.app/Contents/Resources \
  --disable-rpath --enable-build-doc --without-gnome
\end{code}

The ``\texttt{export PATH}'' line is designed to ensure that the
version of gnuplot installed at the previous step is found during the
gretl configuration process.  This may not be necessary if a version
of gnuplot that supports PNG output is already in your path.

After doing \texttt{make} and \texttt{make install} we run a script
named \texttt{postinst} to clear out unnecessary files and add a few
extra things needed for OS X.  This is also in the \texttt{osx} subdir
of the source.

\begin{code}
#!/bin/sh
# postinst: run this in the gretl build directory

# The directory above Gretl.app
TOPDIR=/Users/allin/dist
PREFIX=$TOPDIR/Gretl.app/Contents/Resources

rm -f $PREFIX/bin/gretl
rm -rf $PREFIX/include
rm -rf $PREFIX/share/aclocal
rm -rf $PREFIX/share/info
rm -rf $PREFIX/info
rm -rf $PREFIX/lib/pkgconfig
rm -f $PREFIX/lib/*.la
rm -f $PREFIX/lib/gretl-gtk2/*.la
rm -rf $PREFIX/share/emacs
rm -rf $PREFIX/share/texmf-local

install -m 644 osx/README.pdf $TOPDIR
install -m 755 osx/gretl.sh $PREFIX/bin/gretl
install -m 755 osx/script $PREFIX
# uncomment for a PPC build:
# install -m 755 osx/Gretl.ppc $TOPDIR/Gretl.app/Contents/MacOS/Gretl

\end{code}

If you're making a PPC build of gretl then you need to remove the
hash-mark comment symbol from the last line above.


\section{Copying Fink run-time files}

As mentioned above, this is a bit tricky.  The general idea is that we
want to identify all the files provided by Fink that are necessary to
support gretl and/or gnuplot, and copy these into the right places
under \texttt{Gretl.app}.  To keep the disk image as compact as
possible, we want to try to ensure that we copy \textit{only} those
files that are really necessary.  This includes all shared libraries
that are not provided by OS X itself; it also includes some additional
run-time files required by GTK+.

\textit{Libraries}: You can do most of the work on the libraries by
running \texttt{libs.sh} from the osx subdirectory of the gretl
source.  This finds dependencies that live in \texttt{/sw/lib} using
\texttt{otool -L} (think ldd on Linux) and copies the files
into place. Here's \texttt{libs.sh}:

\begin{code}
TOPDIR=/Users/allin/dist
PKGDIR="$TOPDIR/Gretl.app/Contents/Resources"

cd $PKGDIR

otool -L ./bin/gretl_x11 | awk '{ print $1 }' | grep /sw/lib > liblist
otool -L ./bin/gretlcli | awk '{ print $1 }' | grep /sw/lib >> liblist
otool -L ./bin/gnuplot | awk '{ print $1 }' | grep /sw/lib >> liblist
 
for f in `cat liblist | uniq` ; do
  cp $f ./lib
done

rm liblist
\end{code}

%$
But having done this, we may need to add a few things:
\texttt{libgd.2.dylib} from the custom build of gd2 (see
section~\ref{sec:gpbuild}), \texttt{libmpfr.1.dylib} from Fink (if
available) to support the gretl plugin.  On the other hand, if
\texttt{libiconv.2.dylib} has been picked up from the Fink
installation it's possible this can be deleted: libiconv.2.dylib is
provided by OS X, so provided that the minor version is recent enough
we don't need to package it.

\textit{Other files}: 

Besides the basic dylibs, we need to borrow from Fink some module
files that live under \texttt{lib}, and configuration files under
\texttt{etc} (the installation for both sets of files will be relative
to \url{Gretl.app/Contents/Resources}).  I'll illustrate with my
current setup; filenames may differ slightly if the GTK version
differs.

Under \texttt{lib}:

\begin{code}
lib/gtk-2.0/2.4.0/immodules/
lib/gtk-2.0/2.4.0/loaders/libpixbufloader-png.so
lib/gtk-2.0/2.4.0/loaders/libpixbufloader-xpm.so
lib/pango/1.4.0/modules/pango-basic-fc.so  
lib/pango/1.4.0/modules/pango-basic-x.so
\end{code}

The \texttt{immodules} directory is empty; we don't need any input
modules.  (The directory may be redundant, I'm not sure.)  The GTK
\texttt{loaders} directory and the pango \texttt{modules} directory
contain a small subset of the full content of those directories under
Fink; this is all we need to support gretl. 

Second, config files under \texttt{etc}:

\begin{code}
etc/gtk-2.0/gtk.immodules
etc/gtk-2.0/gdk-pixbuf.loaders
etc/pangorc
etc/pango/pango.modules
etc/pango/pangox.aliases
\end{code}

The first of these is an empty file; the second is an edited
version of the corresponding Fink file.  We need to use relative
paths to the loaders, as in

\begin{code}
# GdkPixbuf Image Loader Modules file
"../lib/gtk-2.0/2.4.0/loaders/libpixbufloader-png.so"
"png" 1 "gtk20" "The PNG image format"
"image/png" ""
"png" ""
"\211PNG\r\n\032\n" "" 100

"../lib/gtk-2.0/2.4.0/loaders/libpixbufloader-xpm.so"
"xpm" 0 "gtk20" "The XPM image format"
"image/x-xpixmap" ""
"xpm" ""
"/* XPM */" "" 100
\end{code}

(Only the paths to the \texttt{.so} files need to be changed.)

The third file, \texttt{etc/pangorc}, tells pango where to find the
other files.  Its content should be as follows:

\begin{code}
[Pango]
ModuleFiles=../etc/pango/pango.modules
ModulesPath=../lib/pango/1.4.0/modules
[PangoX]
Aliasfiles=../etc/pango/pangox.aliases
\end{code}

The content of \texttt{pango.modules} is again edited
to use relative paths:

\begin{code}
# Pango Modules file
#
../lib/pango/1.4.0/modules/pango-basic-fc.so Basic...
../lib/pango/1.4.0/modules/pango-basic-x.so Basic...
\end{code}

As for \texttt{pangox.aliases}, I'm not sure it's needed, but anyway I
think it can be copied straight.

\textit{Testing}: Once you've got all this stuff in place (remember,
you only need to do it once!) you have to check that
\texttt{Gretl.app} is really self-contained.  This means running gretl
with Fink disabled.  To help with this I use two little scripts, as
follows:

\begin{code}
# disable Fink
sudo mv /sw /hidden.sw
hash -r

# enable Fink
sudo mv /hidden.sw /sw
hash -r
\end{code}

The \texttt{hash -r} command is required to ensure that common
utilities such as \texttt{cp}, which are present in both \texttt{/bin}
and \texttt{/sw/bin}, are found after the switch.

I recommend starting the test by running \texttt{./gretl} in the
\texttt{bin} directory under \url{Gretl.app/Contents/Resources}: then
if there's stuff missing you'll hear about it on stderr.  Once that's
working, try launching gretl via the \texttt{Gretl.app} icon.

\section{Documentation files}

The canonical PDF documentation for gretl is available from
\url{ricardo.ecn.wfu.edu}:

\begin{code}
TOPDIR=/Users/allin/dist
DOCDIR=$TOPDIR/Gretl.app/Contents/Resources/share/gretl/doc
rm -f gretl-guide.pdf
wget http://ricardo.ecn.wfu.edu/pub/gretl/manual/PDF/gretl-guide.pdf
cp gretl-guide.pdf $DOCDIR
rm -f gretl-ref.pdf
wget http://ricardo.ecn.wfu.edu/pub/gretl/manual/PDF/gretl-ref.pdf
cp gretl-ref.pdf $DOCDIR
\end{code}

%$
That is, you grab the current PDF files and drop them into the right
place under \texttt{Gretl.app}.

\section{Creation of dmg}

Once everything's in place, we create the final compressed .dmg file.
This is actually quite straightforward; below is a shell script to do
the job.  There's a copy in the gretl source package, in the osx
subdirectory (called \texttt{dmg.sh}).  Obviously, you'll need to edit
the line that defines \texttt{TOPDIR}; hopefully the rest should be
portable.

This script should be run from some ``neutral'' location outside of
the distribution tree; you don't want to get a recursive thing going,
whereby the dmg is included within itself.  I run \texttt{dmg.sh} from
\verb+~/bin+.

\begin{code}
#!/bin/bash

# the directory above Gretl.app
TOPDIR=/Users/allin/dist

HERE=`pwd`
KB=`du -ks $TOPDIR | awk '{ print $1 }'`
KB=$((KB+1024))
hdiutil create -size ${KB}k tmp.dmg -layout NONE
MYDEV=`hdid -nomount tmp.dmg`
sudo newfs_hfs -v gretl $MYDEV
hdiutil eject $MYDEV
hdid tmp.dmg
cd $TOPDIR && \
/sw/bin/cp -a Gretl.app /Volumes/gretl && \
/sw/bin/cp -a README.pdf /Volumes/gretl
cd $HERE
hdiutil eject $MYDEV
hdiutil convert -format UDZO tmp.dmg -o gretl.dmg && rm tmp.dmg
\end{code}

%$
This script uses the \texttt{-a} flag to the \texttt{cp} command: that
is not supported by \texttt{/bin/cp} under OS X, but it is supported by 
Fink's \texttt{/sw/bin/cp}.

\section{Extra: ScriptExec stuff}

Something else should be mentioned.  To make Gretl.app into a proper
OS X Application ``bundle'' we use the ScriptExec apparatus from
gimp.app, at \url{http://gimp-app.sourceforge.net/}.  This apparatus
allows for launching gretl from an icon, and automatic startup of X11.

The \texttt{Gretl.app} skeleton mentioned above contains all the files
generated in association with ScriptExec as built on OS X 10.4.11.
So with any luck you should not have to mess with this.  On the other
hand it's possible that the files generated on Tiger don't work
properly with Leopard (or higher), so it may be worth regenerating
them.

An account of how to do this (for gimp, but \textit{mutatis mutandis}
for gretl) is given at the gimp.app URL above.  I can't add much to
what's said there as I have no expertise in Xcode and I worked by
trial and error, but here are a few hints.

The basic idea is that you have to build ScriptExec as an
Xcode project, then copy the generated bits and pieces into place
under \texttt{Gretl.app}.

The built executable,

\begin{code}
ScriptExec/build/Deployment/ScriptExec.app/Contents/MacOS/ScriptExec
\end{code}

should be copied as

\begin{code}
Gretl.app/Contents/MacOS/Gretl
\end{code}

Two builds of this program can be found in the osx subdir of the gretl
code, namely \texttt{Gretl.ppc} (for the PPC architecture) and
\texttt{Gretl.intel}.

A copy of my gretlized version of the ScriptExec source is at

\url{http://ricardo.ecn.wfu.edu/~cottrell/gretl-osx/ScriptExec.tar.gz}

\end{document}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: t
%%% End: 
