{{{ #!div style="background-color: #ffc; color: #003; font: 10pt serif; padding: 9px; padding-left: 18px;" = Bundling = Once you have your application running, you'll want to create an [http://en.wikipedia.org/wiki/Application_Bundle#Application_Bundles application bundle] that you (or your users) can drag to a convenient place and launch by double-clicking on it in Finder. If you can design the application so that it doesn't need files outside of the bundle, users will be able to install it by simply dragging it from a disk image that they download to whatever folder they like. {{{ #!div class="important" style="background-color: #ffc" Almost wherever they like: Gtk+ applications typically depend heavily on environment variables, so the app bundle will have a shell script to set everything up (called a "'''launcher script'''"). The catch is that shell scripts tend to view spaces as delimiters between arguments, so paths with spaces cause trouble unless particular care is taken in writing the launcher script. }}} Gtk-OSX provides a tool, '''ige-mac-bundler''', to build the application bundle for you. You can download it as a [http://downloads.sourceforge.net/sourceforge/gtk-osx/ige-mac-bundler-0.5.4.tar.gz tarball] or clone the [http://github.com/jralls/ige-mac-bundler latest code] with git. What follows is a basic procedure for getting and using '''ige-mac-bundler'''. More details may be found in the {{{README}}} provided with the source and in the comments in the example files (found in the {{{examples}}} folder). == How to use ige-mac-bundler == Download the source code, unpack, then install it: {{{ #!sh $ cd ~ $ wget http://downloads.sourceforge.net/sourceforge/gtk-osx/ige-mac-bundler-0.5.3.tar.gz $ tar zxvf ige-mac-bundler-0.5.3.tar.gz $ cd ige-mac-bundler-0.5.3 $ make install }}} or, to use the most recent code: {{{ $ git clone git://github.com/jralls/ige-mac-bundler.git $ cd ige-mac-bundler $ make install }}} This will install ige-mac-bundler in ~/.local/bin (the same place as the [wiki:Build gtk-osx install script] puts jhbuild). '''FIXME''': when I tried the above, it did '''not''' install to ~/.local/bin, but to ~/bin, which is not the same as where jhbuild was put. Next, make a directory to hold your bundle configuration files (we'll call this the "bundle directory") and copy the contents of ~/ige-mac-bundler-0.5.3/examples to it. === Bundle File === Rename gtk-demo.bundle to something more like yourappname.bundle. We'll call this file the "'''bundle file'''". Now, edit the bundle file. This file tells ige-mac-bundler what files are required to run your application, and enables it to find all the dependencies which need to be included in your application bundle. There are a lot of comments in the file itself, and more explanation is available in ~/ige-mac-bundler-0.5.3/README. {{{ #!div class="important" style="background-color: #ffc" Ige-mac-bundler can find dependencies which are linked at build-time, using the shell command "otool -L". It cannot find dependencies which are loaded with dlopen, so you must include those explicitly in the bundle file with a tag. (Don't use a tag or ige-mac-bundler won't be able to find the shared libraries that the module depends on.) }}} === Icon file === You will need to create an '''icon''' for your application. OSX doesn't use regular image files for icons. Instead, the [http://en.wikipedia.org/wiki/Apple_Icon_Image .icns] file format is used, which contains icons of up to four (five in Snow Leopard) standard sizes. You'll want to build one of these .icns files for your app and point to it with both Info.plist and a entry in your bundle file. '''Icon Composer''' (/Developer/Applications/Utilities/Icon Composer.app) is the program to use for this. If your application already has graphics files in the appropriate resolutions you can just drag them into the appropriate boxes in Icon Composer and save. You don't need to have all of the sizes filled for the icons to work (this is particularly true of the new 512x512 icon size provided in Snow Leopard). === Info.plist === Next, edit '''Info.plist''' to refer correctly to your application and the application icon you created. This file is used by Mac OS X when actually launching your application. The basic Info.plist entries are pretty obvious, full documentation is at [http://developer.apple.com/documentation/MacOSX/Conceptual/BPRuntimeConfig/BPRuntimeConfig.html Apple Documentation]). === launcher.sh === A template launcher.sh is included in the example. Either add to this any other shell commands you need to get your application ready to run, or call other shell scripts from it. If you do use other shell scripts, be sure include them in the bundle file. === Run the bundler === Assuming that your bundle description file is called yourappname.bundle, you should now be ready to run ige-mac-bundler using the the following steps: {{{ #!sh $ jhbuild shell $ export PATH=$PREFIX/bin:~/.local/bin:$PATH $ ige-mac-bundler yourappname.bundle }}} {{{ #!div class="important" style="background-color: #ffc" Ige-mac-bundler copies all of the files you indicated in your bundle file, and also pulls in the dependencies it can find, and it adjusts the install paths to reflect the new locations. ''Note that some libraries and applications (dbus and Gconf are particularly common) hard-code paths during build and you may find that you need to keep at least some of your installation directory in place. You can finesse this problem by installing the required files (often they're text configuration files) into the bundle and having the launcher script check for and if not present or correct create a symlink from the bundle Resources directory (e.g., Yourappname.app/Contents/Resources) to the installation directory. If you do this, you probably want to set up your prefix when you build to somewhere outside of your home directory. Apple recommends /Library for application data and both /opt and /usr/local are traditional in Unix and Linux. Do be careful with both of these, as it's common for autotools-based codes to build in /usr/local by default, and MacPorts uses /opt for its own purposes. }}} Ige-mac-bundler reads the Info.plist to determine the app bundle's name, and puts it in the folder indicated by the tag; in the examples, this is ~/Desktop. For '''more details''' about what ige-mac-bundler is actually doing here, see [http://ascendwiki.cheme.cmu.edu/Porting_to_Mac/ige-mac-bundler the ASCEND wiki]. == Bundling PyGTK apps == PyGTK programs are a bit trickier to bundle, because a python program isn't a mach-o binary, so it can't go in the element. At the moment you can make libpygtk.dylib the main-binary. Add your python modules to your bundle with tags and add their location to $PYTHONPATH in your launcher script. ige-mac-bundler isn't aware of Python module dependencies (as opposed to, for example, [http://docs.python.org/library/modulefinder.html modulefinder]), so any modules which aren't provided by Apple must be manually added to your bundle file in tags. There is an example which bundles pygtk-demo. Look at {{{examples/pygtk-demo.bundle}}}, {{{examples/Info-pygtk-demo.plist}}}, {{{examples/pygtk-demo.sh}}} (the launcher script), and {{{examples/pygtk-demo}}} (a wrapper python program which does the python part of setting up and calling pygtk-demo.py). Yes, the last one could be better named. }}}