Code

Integrate fix from Jon Cruz regarding localization on OS X
[inkscape.git] / packaging / macosx / osx-app.sh
1 #!/bin/bash
2 #
3 # USAGE
4 # osx-app [-s] [-py /path/to/python/modules] [-l /path/to/libraries] -b /path/to/bin/inkscape -p /path/to/Info.plist
5 #
6 # This script attempts to build an Inkscape.app package for OS X, resolving
7 # dynamic libraries, etc.        
8 # It strips the executable and libraries if '-s' is given.
9 # It adds python modules if the '-py option' is given
10 # The Info.plist file can be found in the base inkscape directory once
11 # configure has been run.
12 #
13 # AUTHORS
14 #                Kees Cook <kees@outflux.net>
15 #                Michael Wybrow <mjwybrow@users.sourceforge.net>
16 #                Jean-Olivier Irisson <jo.irisson@gmail.com>
17
18 # Copyright (C) 2005 Kees Cook
19 # Copyright (C) 2005-2007 Michael Wybrow
20 # Copyright (C) 2007 Jean-Olivier Irisson
21 #
22 # Released under GNU GPL, read the file 'COPYING' for more information
23 #
24 # Thanks to GNUnet's "build_app" script for help with library dep resolution.
25 #               https://gnunet.org/svn/GNUnet/contrib/OSX/build_app
26
27 # NB:
28 # When packaging Inkscape for OS X, configure should be run with the 
29 # "--enable-osxapp" option which sets the correct paths for support
30 # files inside the app bundle.
31
33 # Defaults
34 strip=false
35 add_python=false
36 python_dir=""
38 # If LIBPREFIX is not already set (by osx-build.sh for example) set it to blank (one should use the command line argument to set it correctly)
39 if [ -z $LIBPREFIX ]; then
40         LIBPREFIX=""
41 fi
44 # Help message
45 #----------------------------------------------------------
46 help()
47 {
48 echo -e "
49 Create an app bundle for OS X
51 \033[1mUSAGE\033[0m
52         $0 [-s] [-py /path/to/python/modules] [-l /path/to/libraries] -b /path/to/bin/inkscape -p /path/to/Info.plist
54 \033[1mOPTIONS\033[0m
55         \033[1m-h,--help\033[0m 
56                 display this help message
57         \033[1m-s\033[0m
58                 strip the libraries and executables from debugging symbols
59         \033[1m-py,--with-python\033[0m
60                 add python modules (numpy, lxml) from given directory
61                 inside the app bundle
62         \033[1m-l,--libraries\033[0m
63                 specify the path to the librairies Inkscape depends on
64                 (typically /sw or /opt/local)
65         \033[1m-b--binary\033[0m
66                 specify the path to Inkscape's binary. By default it is in
67                 Build/bin/ at the base of the source code directory
68         \033[1m-p,--plist\033[0m
69                 specify the path to Info.plist. Info.plist can be found
70                 in the base directory of the source code once configure
71                 has been run
73 \033[1mEXAMPLE\033[0m
74         $0 -s -py ~/python-modules -l /opt/local -b ../../Build/bin/inkscape -p ../../Info.plist
75 "
76 }
79 # Parse command line arguments
80 #----------------------------------------------------------
81 while [ "$1" != "" ]
82 do
83         case $1 in
84                 -py|--with-python)
85                         add_python=true
86                         python_dir="$2"
87                         shift 1 ;;
88                 -s)
89                         strip=true ;;
90                 -l|--libraries)
91                         LIBPREFIX="$2"
92                         shift 1 ;;
93                 -b|--binary)
94                         binary="$2"
95                         shift 1 ;;
96                 -p|--plist)
97                         plist="$2"
98                         shift 1 ;;
99                 -h|--help)
100                         help
101                         exit 0 ;;
102                 *)
103                         echo "Invalid command line option: $1" 
104                         exit 2 ;;
105         esac
106         shift 1
107 done
109 echo -e "\n\033[1mCREATE INKSCAPE APP BUNDLE\033[0m\n"
111 # Safety tests
112 if [ ${add_python} = "true" ]; then
113         if [ ! -e "$python_dir" ]; then
114                 echo "Cannot find the directory containing python modules: $python_dir" >&2
115                 exit 1
116         fi
117 fi
119 if [ ! -e "$LIBPREFIX" ]; then
120         echo "Cannot find the directory containing the libraires: $LIBPREFIX" >&2
121         exit 1
122 fi
124 if [ ! -f "$binary" ]; then
125         echo "Need Inkscape binary" >&2
126         exit 1
127 fi
129 if [ ! -f "$plist" ]; then
130         echo "Need plist file" >&2
131         exit 1
132 fi
134 if [ ! -x "$binary" ]; then
135         echo "Not executable: $binary" >&2
136         exit 1
137 fi
140 # Handle some version specific details.
141 VERSION=`/usr/bin/sw_vers | grep ProductVersion | cut -f2 -d'.'`
142 if [ "$VERSION" -ge "4" ]; then
143         # We're on Tiger (10.4) or later.
144         # XCode behaves a little differently in Tiger and later.
145         XCODEFLAGS="-configuration Deployment"
146         SCRIPTEXECDIR="ScriptExec/build/Deployment/ScriptExec.app/Contents/MacOS"
147         EXTRALIBS=""
148 else
149         # Panther (10.3) or earlier.
150         XCODEFLAGS="-buildstyle Deployment"
151         SCRIPTEXECDIR="ScriptExec/build/ScriptExec.app/Contents/MacOS"
152         EXTRALIBS=""
153 fi
156 # Package always has the same name. Version information is stored in
157 # the Info.plist file which is filled in by the configure script.
158 package="Inkscape.app"
160 # Remove a previously existing package if necessary
161 if [ -d $package ]; then
162         echo "Removing previous Inkscape.app"
163         rm -Rf $package
164 fi
167 # Set the 'macosx' directory, usually the current directory.
168 resdir=`pwd`
171 # Prepare Package
172 #----------------------------------------------------------
173 pkgexec="$package/Contents/MacOS"
174 pkgbin="$package/Contents/Resources/bin"
175 pkglib="$package/Contents/Resources/lib"
176 pkglocale="$package/Contents/Resources/locale"
177 pkgpython="$package/Contents/Resources/python/site-packages/"
178 pkgresources="$package/Contents/Resources"
180 mkdir -p "$pkgexec"
181 mkdir -p "$pkgbin"
182 mkdir -p "$pkglib"
183 mkdir -p "$pkglocale"
184 mkdir -p "$pkgpython"
186 mkdir -p "$pkgresources/Dutch.lprj"
187 mkdir -p "$pkgresources/English.lprj"
188 mkdir -p "$pkgresources/French.lprj"
189 mkdir -p "$pkgresources/German.lprj"
190 mkdir -p "$pkgresources/Italian.lprj"
191 mkdir -p "$pkgresources/Spanish.lprj"
192 mkdir -p "$pkgresources/fi.lprj"
193 mkdir -p "$pkgresources/no.lprj"
194 mkdir -p "$pkgresources/sv.lprj"
196 # Build and add the launcher
197 #----------------------------------------------------------
199         # Build fails if CC happens to be set (to anything other than CompileC)
200         unset CC
201         
202         cd "$resdir/ScriptExec"
203         echo -e "\033[1mBuilding launcher...\033[0m\n"
204         xcodebuild $XCODEFLAGS clean build
206 cp "$resdir/$SCRIPTEXECDIR/ScriptExec" "$pkgexec/Inkscape"
209 # Copy all files into the bundle
210 #----------------------------------------------------------
211 echo -e "\n\033[1mFilling app bundle...\033[0m\n"
213 binary_name=`basename "$binary"`
214 binary_dir=`dirname "$binary"`
216 # Inkscape's binary
217 binpath="$pkgbin/inkscape-bin"
218 cp -v "$binary" "$binpath"
219 # TODO Add a "$verbose" variable and command line switch, which sets wether these commands are verbose or not
221 # Share files
222 rsync -av "$binary_dir/../share/$binary_name"/* "$package/Contents/Resources/"
223 cp "$plist" "$package/Contents/Info.plist"
224 rsync -av "$binary_dir/../share/locale"/* "$package/Contents/Resources/locale"
226 # Icons and the rest of the script framework
227 rsync -av --exclude ".svn" "$resdir"/Resources/* "$package"/Contents/Resources/
229 # Add python modules if requested
230 if [ ${add_python} = "true" ]; then
231         # copy python site-packages. They need to be organized in a hierarchical set of directories, by architecture and python major+minor version, e.g. i386/2.3/ for Ptyhon 2.3 on Intel; ppc/2.4/ for Python 2.4 on PPC
232         cp -rvf "$python_dir"/* "$pkgpython"
233 fi
235 # PkgInfo must match bundle type and creator code from Info.plist
236 echo "APPLInks" > $package/Contents/PkgInfo
238 # Pull in extra requirements for Pango and GTK
239 pkgetc="$package/Contents/Resources/etc"
240 mkdir -p $pkgetc/pango
241 cp $LIBPREFIX/etc/pango/pangox.aliases $pkgetc/pango/
242 # Need to adjust path and quote in case of spaces in path.
243 sed -e "s,$LIBPREFIX,\"\${CWD},g" -e 's,\.so ,.so" ,g' $LIBPREFIX/etc/pango/pango.modules > $pkgetc/pango/pango.modules
244 cat > $pkgetc/pango/pangorc <<END_PANGO
245 [Pango]
246 ModuleFiles=\${HOME}/.inkscape-etc/pango.modules
247 [PangoX]
248 AliasFiles=\${HOME}/.inkscape-etc/pangox.aliases
249 END_PANGO
251 # We use a modified fonts.conf file so only need the dtd
252 mkdir -p $pkgetc/fonts
253 cp $LIBPREFIX/etc/fonts/fonts.dtd $pkgetc/fonts/
254 cp -r $LIBPREFIX/etc/fonts/conf.avail $pkgetc/fonts/
255 cp -r $LIBPREFIX/etc/fonts/conf.d $pkgetc/fonts/
257 mkdir -p $pkgetc/gtk-2.0
258 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/etc/gtk-2.0/gdk-pixbuf.loaders > $pkgetc/gtk-2.0/gdk-pixbuf.loaders
259 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/etc/gtk-2.0/gtk.immodules > $pkgetc/gtk-2.0/gtk.immodules
261 for item in gnome-vfs-mime-magic gnome-vfs-2.0
262 do
263         cp -r $LIBPREFIX/etc/$item $pkgetc/
264 done
266 pango_version=`pkg-config --variable=pango_module_version pango`
267 mkdir -p $pkglib/pango/$pango_version/modules
268 cp $LIBPREFIX/lib/pango/$pango_version/modules/*.so $pkglib/pango/$pango_version/modules/
270 gtk_version=`pkg-config --variable=gtk_binary_version gtk+-2.0`
271 mkdir -p $pkglib/gtk-2.0/$gtk_version/{engines,immodules,loaders}
272 cp -r $LIBPREFIX/lib/gtk-2.0/$gtk_version/* $pkglib/gtk-2.0/$gtk_version/
274 mkdir -p $pkglib/gnome-vfs-2.0/modules
275 cp $LIBPREFIX/lib/gnome-vfs-2.0/modules/*.so $pkglib/gnome-vfs-2.0/modules/
277 # Find out libs we need from fink, darwinports, or from a custom install
278 # (i.e. $LIBPREFIX), then loop until no changes.
279 a=1
280 nfiles=0
281 endl=true
282 while $endl; do
283         echo -e "\033[1mLooking for dependencies.\033[0m Round" $a
284         libs="`otool -L $pkglib/gtk-2.0/$gtk_version/loaders/* $pkglib/gtk-2.0/$gtk_version/immodules/* $pkglib/gtk-2.0/$gtk_version/engines/*.so $pkglib/pango/$pango_version/modules/* $pkglib/gnome-vfs-2.0/modules/* $package/Contents/Resources/lib/* $binary 2>/dev/null | fgrep compatibility | cut -d\( -f1 | grep $LIBPREFIX | sort | uniq`"
285         cp -f $libs $package/Contents/Resources/lib
286         let "a+=1"      
287         nnfiles=`ls $package/Contents/Resources/lib | wc -l`
288         if [ $nnfiles = $nfiles ]; then
289                 endl=false
290         else
291                 nfiles=$nnfiles
292         fi
293 done
295 # Add extra libraries of necessary
296 for libfile in $EXTRALIBS
297 do
298         cp -f $libfile $package/Contents/Resources/lib
299 done
302 # Strip libraries and executables if requested
303 #----------------------------------------------------------
304 if [ "$strip" = "true" ]; then
305         echo -e "\n\033[1mStripping debugging symbols...\033[0m\n"
306         chmod +w "$pkglib"/*.dylib
307         strip -x "$pkglib"/*.dylib
308         strip -ur "$binpath"
309 fi
311 # NOTE: This works for all the dylibs but causes GTK to crash at startup.
312 #                               Instead we leave them with their original install_names and set
313 #                               DYLD_LIBRARY_PATH within the app bundle before running Inkscape.
315 # fixlib () {
316 #               # Fix a given executable or library to be relocatable
317 #               if [ ! -d "$1" ]; then
318 #                       echo $1
319 #                       libs="`otool -L $1 | fgrep compatibility | cut -d\( -f1`"
320 #                       for lib in $libs; do
321 #                               echo "  $lib"
322 #                               base=`echo $lib | awk -F/ '{print $NF}'`
323 #                               first=`echo $lib | cut -d/ -f1-3`
324 #                               to=@executable_path/../lib/$base
325 #                               if [ $first != /usr/lib -a $first != /usr/X11R6 ]; then
326 #                                       /usr/bin/install_name_tool -change $lib $to $1
327 #                                       if [ "`echo $lib | fgrep libcrypto`" = "" ]; then
328 #                                               /usr/bin/install_name_tool -id $to ../lib/$base
329 #                                               for ll in $libs; do
330 #                                                       base=`echo $ll | awk -F/ '{print $NF}'`
331 #                                                       first=`echo $ll | cut -d/ -f1-3`
332 #                                                       to=@executable_path/../lib/$base
333 #                                                       if [ $first != /usr/lib -a $first != /usr/X11R6 -a "`echo $ll | fgrep libcrypto`" = "" ]; then
334 #                                                               /usr/bin/install_name_tool -change $ll $to ../lib/$base
335 #                                                       fi
336 #                                               done
337 #                                       fi
338 #                               fi
339 #                       done
340 #               fi
341 # }
342
343 # Fix package deps
344 #(cd "$package/Contents/MacOS/bin"
345 # for file in *; do
346 #                fixlib "$file"
347 # done
348 # cd ../lib
349 # for file in *; do
350 #                fixlib "$file"
351 # done)
353 exit 0