Porting to Mac/gtk-mac-bundler: Difference between revisions
No edit summary |
No edit summary |
||
| Line 1: | Line 1: | ||
[[Porting_to_Mac|&larr | [[Porting_to_Mac|← Porting to Mac]] | ||
This page contains some notes on how [http://sourceforge.net/apps/trac/gtk-osx/wiki/Bundle ige-mac-bundler] (and maybe other tools) do the job of making portable, self-contained GTK+ applications work on Mac. The notes were prepared during the course of porting [[ASCEND_overview|ASCEND]] to Mac. Please feel free to set me straight on any wrong observations, missing information, etc. | This page contains some notes on how [http://sourceforge.net/apps/trac/gtk-osx/wiki/Bundle ige-mac-bundler] (and maybe other tools) do the job of making portable, self-contained GTK+ applications work on Mac. The notes were prepared during the course of porting [[ASCEND_overview|ASCEND]] to Mac. Please feel free to set me straight on any wrong observations, missing information, etc. | ||
| Line 99: | Line 99: | ||
<pre> | <pre> | ||
$ cat gtkrc | $ cat gtkrc | ||
gtk-icon-theme-name = | gtk-icon-theme-name = "Tango" | ||
gtk-enable-mnemonics = 0 | gtk-enable-mnemonics = 0 | ||
</pre> | </pre> | ||
| Line 120: | Line 120: | ||
'''NOTE''': in the following, the "`pwd`/$0" causes problems if you invoke the <tt>ige-mac-bundler</tt>-bundled from the command line from any directory other than <tt>Contents/MacOS</tt>. I think that this is a bug. | '''NOTE''': in the following, the "`pwd`/$0" causes problems if you invoke the <tt>ige-mac-bundler</tt>-bundled from the command line from any directory other than <tt>Contents/MacOS</tt>. I think that this is a bug. | ||
<source lang="a4c">name= | <source lang="a4c">name="`basename $0`" | ||
tmp= | tmp="`pwd`/$0" | ||
tmp=`dirname | tmp=`dirname "$tmp"` | ||
tmp=`dirname | tmp=`dirname "$tmp"` | ||
bundle=`dirname | bundle=`dirname "$tmp"` | ||
bundle_contents= | bundle_contents="$bundle"/Contents | ||
bundle_res= | bundle_res="$bundle_contents"/Resources | ||
bundle_lib= | bundle_lib="$bundle_res"/lib | ||
bundle_bin= | bundle_bin="$bundle_res"/bin | ||
bundle_data= | bundle_data="$bundle_res"/share | ||
bundle_etc= | bundle_etc="$bundle_res"/etc | ||
export DYLD_LIBRARY_PATH= | export DYLD_LIBRARY_PATH="$bundle_lib" | ||
export XDG_CONFIG_DIRS= | export XDG_CONFIG_DIRS="$bundle_etc"/xdg | ||
export XDG_DATA_DIRS= | export XDG_DATA_DIRS="$bundle_data" | ||
export GTK_DATA_PREFIX= | export GTK_DATA_PREFIX="$bundle_res" | ||
export GTK_EXE_PREFIX= | export GTK_EXE_PREFIX="$bundle_res" | ||
export GTK_PATH= | export GTK_PATH="$bundle_res" | ||
export GTK2_RC_FILES= | export GTK2_RC_FILES="$bundle_etc/gtk-2.0/gtkrc" | ||
export GTK_IM_MODULE_FILE= | export GTK_IM_MODULE_FILE="$bundle_etc/gtk-2.0/gtk.immodules" | ||
export GDK_PIXBUF_MODULE_FILE= | export GDK_PIXBUF_MODULE_FILE="$bundle_etc/gtk-2.0/gdk-pixbuf.loaders" | ||
export PANGO_RC_FILE= | export PANGO_RC_FILE="$bundle_etc/pango/pangorc"</source> | ||
After the above, there is some locale-related stuff (see [http://github.com/jralls/ige-mac-bundler/blob/master/bundler/launcher.sh launcher.sh] for the details. | After the above, there is some locale-related stuff (see [http://github.com/jralls/ige-mac-bundler/blob/master/bundler/launcher.sh launcher.sh] for the details. | ||
| Line 153: | Line 153: | ||
Next the script does something with charset alias ('''FIXME''' what's this doing?): | Next the script does something with charset alias ('''FIXME''' what's this doing?): | ||
<source lang="a4c">if test -f | <source lang="a4c">if test -f "$bundle_lib/charset.alias"; then | ||
export CHARSETALIASDIR= | export CHARSETALIASDIR="$bundle_lib" | ||
fi</source> | fi</source> | ||
| Line 163: | Line 163: | ||
<source lang="a4c"># Strip out the argument added by the OS. | <source lang="a4c"># Strip out the argument added by the OS. | ||
if [ x`echo | if [ x`echo "x$1" | sed -e "s/^x-psn_.*//"` == x ]; then | ||
shift 1 | shift 1 | ||
| Line 170: | Line 170: | ||
Finally, the script launches the executable. | Finally, the script launches the executable. | ||
<source lang="a4c">$EXEC | <source lang="a4c">$EXEC "$bundle_contents/MacOS/$name-bin" $* $EXTRA_ARGS</source> | ||
[[Category:Development]] | [[Category:Development]] | ||
Revision as of 05:04, 2 November 2010
This page contains some notes on how ige-mac-bundler (and maybe other tools) do the job of making portable, self-contained GTK+ applications work on Mac. The notes were prepared during the course of porting ASCEND to Mac. Please feel free to set me straight on any wrong observations, missing information, etc.
The following observations come from bundling up GtkDemo using ige-mac-bundler.
GTK libraries
GTK libraries are copied into the Contents/Resources/lib directory in the application bundle. Their 'install names' are changed so that they look like:
$ otool -L libgtk-quartz-2.0.0.dylib libgtk-quartz-2.0.0.dylib: /Users/john/gtk/inst/lib/libgtk-quartz-2.0.0.dylib (compatibility version 1801.0.0, current version 1801.2.0) @executable_path/../Resources/lib/libgdk_pixbuf-2.0.0.dylib (compatibility version 1801.0.0, current version 1801.2.0) @executable_path/../Resources/lib/libgdk-quartz-2.0.0.dylib (compatibility version 1801.0.0, current version 1801.2.0) @executable_path/../Resources/lib/libpangocairo-1.0.0.dylib (compatibility version 2401.0.0, current version 2401.5.0)
For the GtkDemo app, the following libraries are copied:
$ ls charset.alias libfreetype.6.dylib libgobject-2.0.0.dylib libpangoft2-1.0.0.dylib gtk-2.0 libgdk-quartz-2.0.0.dylib libgtk-quartz-2.0.0.dylib libpixman-1.0.dylib libatk-1.0.0.dylib libgdk_pixbuf-2.0.0.dylib libintl.8.dylib libpng12.0.dylib libcairo.2.dylib libgio-2.0.0.dylib libjpeg.7.dylib libtiff.3.dylib libexpat.1.dylib libglib-2.0.0.dylib libpango-1.0.0.dylib libfontconfig.1.dylib libgmodule-2.0.0.dylib libpangocairo-1.0.0.dylib
Pixbuf loaders
The environment variable GDK_PIXBUF_MODULE_FILE is used to specify the path to a file usually named gdk-pixbuf.loaders. This file contains a list of shared libraries that perform the task of loading various kinds of images into GTK+.
This gdk-pixbuf.loaders file can be automatically generated by the script ~/gtk/inst/bin/gdk-pixbuf-query-loaders.
This contents of gdk-pixbuf.loaders are automatically edited by ige-mac-bundler to replace the absolute file paths with paths like @executable_path/../Resources/lib/gtk-2.0/loaders/libpixbufloader-png.so, etc.
The pixbuf loaders are copied into the locally-consistent location Contents/Resources/lib/gtk-2.0/2.xx.xx/loaders, where xx.xx is the particular GTK+ version being used.
Icons and themes
Icons and themes are copied into Contents/Resources/share. I got the following files:
$ ls -R icons themes ./icons: hicolor ./icons/hicolor: index.theme ./themes: Default Emacs Raleigh ./themes/Default: gtk-2.0-key ./themes/Default/gtk-2.0-key: gtkrc ./themes/Emacs: gtk-2.0-key ./themes/Emacs/gtk-2.0-key: gtkrc ./themes/Raleigh: gtk-2.0 ./themes/Raleigh/gtk-2.0: gtkrc
Didn't see any sign of actual image or icon files anywhere... perhaps the default ones are embedded in the shared library somehow.
Pango configuration files
In Contents/Resources/etc/pango/pangorc the following text was found:
$ cat pangorc [Pango] ModuleFiles=./pango.modules
The file pango.modules is present in the same directory, but is empty.
GTK configuration files
In Contents/Resources/etc/gtk-2.0/gtkrc the following text was found:
$ cat gtkrc gtk-icon-theme-name = "Tango" gtk-enable-mnemonics = 0
In same directory, there is another empty file called gtk.immodules.
Use of install_name_tool
In ige-mac-bundler, all DYLD paths have been set relative to the @executable_path. The executable is kept inside the bundle as Contents/MacOS/GtkDemo-bin. This means, for example, that @executable_path/../Resources/lib takes the loader to folder containing all the GTK shared libraries.
Note: for the case of PyGTK bundles, assuming Apple Python or MacPython are being used but not being included in the bundle, we can't pull this trick, because the @executable_path would then be outside the application bundle, and no help for locating GTK libraries. An alternative approach might be possible using @rpath set on the PyGTK shared libraries, and this needs to be tried out.
Environment variables
The file Contents/MacOS/GtkDemo is the entry-point for the application (as directed by Info.plist) and is a shell-script that sets various required environment variables so that GTK can find all its stuff:
NOTE: in the following, the "`pwd`/$0" causes problems if you invoke the ige-mac-bundler-bundled from the command line from any directory other than Contents/MacOS. I think that this is a bug.
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 export XDG_DATA_DIRS="$bundle_data" export GTK_DATA_PREFIX="$bundle_res" 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"
After the above, there is some locale-related stuff (see launcher.sh for the details.
Next the script does something with charset alias (FIXME what's this doing?):
if test -f "$bundle_lib/charset.alias"; then export CHARSETALIASDIR="$bundle_lib" fi
Next, a variable EXTRA_ARGS is initialised empty and an optional environment.sh is run, allowing command-line arguments to be appended to EXTRA_ARGS, or just to set additional application-specific or user-specific environment variables.
Then, the script throws out some Mac-related command-line parameters that are useless to GTK:
# Strip out the argument added by the OS. if [ x`echo "x$1" | sed -e "s/^x-psn_.*//"` == x ]; then shift 1 fi
Finally, the script launches the executable.
$EXEC "$bundle_contents/MacOS/$name-bin" $* $EXTRA_ARGS