Code

- Prevent the python packages from accidently being left out of the
[inkscape.git] / packaging / macosx / osx-app.sh
1 #!/bin/bash
2 #
3 # USAGE
4 # osx-app [-s] [-l /path/to/libraries] -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
9 # If the '-s' option is given, then the libraries and executable are stripped.
10
11 # The Info.plist file can be found in the base inkscape directory once
12 # configure has been run.
13 #
14 # AUTHORS
15 #                Kees Cook <kees@outflux.net>
16 #                Michael Wybrow <mjwybrow@users.sourceforge.net>
17 #                Jean-Olivier Irisson <jo.irisson@gmail.com>
18
19 # Copyright (C) 2005 Kees Cook
20 # Copyright (C) 2005-2009 Michael Wybrow
21 # Copyright (C) 2007-2009 Jean-Olivier Irisson
22 #
23 # Released under GNU GPL, read the file 'COPYING' for more information
24 #
25 # Thanks to GNUnet's "build_app" script for help with library dep resolution.
26 #               https://gnunet.org/svn/GNUnet/contrib/OSX/build_app
27
28 # NB:
29 # When packaging Inkscape for OS X, configure should be run with the 
30 # "--enable-osxapp" option which sets the correct paths for support
31 # files inside the app bundle.
32
34 # Defaults
35 strip=false
36 add_python=false
37 python_dir=""
39 # 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)
40 if [ -z $LIBPREFIX ]; then
41         LIBPREFIX=""
42 fi
45 # Help message
46 #----------------------------------------------------------
47 help()
48 {
49 echo -e "
50 Create an app bundle for OS X
52 \033[1mUSAGE\033[0m
53         $0 [-s] [-l /path/to/libraries] -py /path/to/python/modules -b /path/to/bin/inkscape -p /path/to/Info.plist
55 \033[1mOPTIONS\033[0m
56         \033[1m-h,--help\033[0m 
57                 display this help message
58         \033[1m-s\033[0m
59                 strip the libraries and executables from debugging symbols
60         \033[1m-py,--with-python\033[0m
61                 add python modules (numpy, lxml) from given directory
62                 inside the app bundle
63         \033[1m-l,--libraries\033[0m
64                 specify the path to the librairies Inkscape depends on
65                 (typically /sw or /opt/local)
66         \033[1m-b--binary\033[0m
67                 specify the path to Inkscape's binary. By default it is in
68                 Build/bin/ at the base of the source code directory
69         \033[1m-p,--plist\033[0m
70                 specify the path to Info.plist. Info.plist can be found
71                 in the base directory of the source code once configure
72                 has been run
74 \033[1mEXAMPLE\033[0m
75         $0 -s -py ~/python-modules -l /opt/local -b ../../Build/bin/inkscape -p ../../Info.plist
76 "
77 }
80 # Parse command line arguments
81 #----------------------------------------------------------
82 while [ "$1" != "" ]
83 do
84         case $1 in
85                 -py|--with-python)
86                         add_python=true
87                         python_dir="$2"
88                         shift 1 ;;
89                 -s)
90                         strip=true ;;
91                 -l|--libraries)
92                         LIBPREFIX="$2"
93                         shift 1 ;;
94                 -b|--binary)
95                         binary="$2"
96                         shift 1 ;;
97                 -p|--plist)
98                         plist="$2"
99                         shift 1 ;;
100                 -h|--help)
101                         help
102                         exit 0 ;;
103                 *)
104                         echo "Invalid command line option: $1" 
105                         exit 2 ;;
106         esac
107         shift 1
108 done
110 echo -e "\n\033[1mCREATE INKSCAPE APP BUNDLE\033[0m\n"
112 # Safety tests
114 if [ "x$binary" == "x" ]; then
115         echo "Inkscape binary path not specified." >&2
116         exit 1
117 fi
119 if [ ! -x "$binary" ]; then
120         echo "Inkscape executable not not found at $binary." >&2
121         exit 1
122 fi
124 if [ "x$plist" == "x" ]; then
125         echo "Info.plist file not specified." >&2
126         exit 1
127 fi
129 if [ ! -f "$plist" ]; then
130         echo "Info.plist file not found at $plist." >&2
131         exit 1
132 fi
134 PYTHONPACKURL="http://inkscape.modevia.com/macosx-snap/Python-packages.dmg"
136 if [ "x$python_dir" == "x" ]; then
137         echo "Python modules directory not specified." >&2
138         echo "Python modules can be downloaded from:" >&2
139         echo "    $PYTHONPACKURL" >&2
140         exit 1
141 fi
143 if [ ! -e "$python_dir/i386" -o ! -e "$python_dir/ppc" ]; then
144         echo "Directory does not appear to contain the i386 and ppc python modules:" >&2
145         echo "    $python_dir" >&2
146         echo "Python modules can be downloaded from:" >&2
147         echo "    $PYTHONPACKURL" >&2
148         exit 1
149 fi
151 if [ ! -e "$LIBPREFIX" ]; then
152         echo "Cannot find the directory containing the libraires: $LIBPREFIX" >&2
153         exit 1
154 fi
156 if [ ! -e "$LIBPREFIX/share/themes/Clearlooks-Quicksilver" ]; then
157         echo "Missing Clearlooks -- please install gtk2-clearlooks and try again." >&2
158         exit 1
159 fi
161 if [ ! -e "$LIBPREFIX/lib/gnome-vfs-2.0" ]; then
162         echo "Missing gnome-vfs -- please install gnome-vfs and try again." >&2
163         exit 1
164 fi
166 if [ ! -e "$LIBPREFIX/lib/aspell-0.60/en.dat" ]; then
167         echo "Missing aspell en dictionary -- please install at least 'aspell-dict-en', but" >&2
168         echo "preferably all dictionaries ('aspell-dict-*') and try again." >&2
169         exit 1
170 fi
173 # Handle some version specific details.
174 VERSION=`/usr/bin/sw_vers | grep ProductVersion | cut -f2 -d'.'`
175 if [ "$VERSION" -ge "4" ]; then
176         # We're on Tiger (10.4) or later.
177         # XCode behaves a little differently in Tiger and later.
178         XCODEFLAGS="-configuration Deployment"
179         SCRIPTEXECDIR="ScriptExec/build/Deployment/ScriptExec.app/Contents/MacOS"
180         EXTRALIBS=""
181 else
182         # Panther (10.3) or earlier.
183         XCODEFLAGS="-buildstyle Deployment"
184         SCRIPTEXECDIR="ScriptExec/build/ScriptExec.app/Contents/MacOS"
185         EXTRALIBS=""
186 fi
189 # Package always has the same name. Version information is stored in
190 # the Info.plist file which is filled in by the configure script.
191 package="Inkscape.app"
193 # Remove a previously existing package if necessary
194 if [ -d $package ]; then
195         echo "Removing previous Inkscape.app"
196         rm -Rf $package
197 fi
200 # Set the 'macosx' directory, usually the current directory.
201 resdir=`pwd`
204 # Prepare Package
205 #----------------------------------------------------------
206 pkgexec="$package/Contents/MacOS"
207 pkgbin="$package/Contents/Resources/bin"
208 pkglib="$package/Contents/Resources/lib"
209 pkglocale="$package/Contents/Resources/locale"
210 pkgpython="$package/Contents/Resources/python/site-packages/"
211 pkgresources="$package/Contents/Resources"
213 mkdir -p "$pkgexec"
214 mkdir -p "$pkgbin"
215 mkdir -p "$pkglib"
216 mkdir -p "$pkglocale"
217 mkdir -p "$pkgpython"
219 mkdir -p "$pkgresources/Dutch.lprj"
220 mkdir -p "$pkgresources/English.lprj"
221 mkdir -p "$pkgresources/French.lprj"
222 mkdir -p "$pkgresources/German.lprj"
223 mkdir -p "$pkgresources/Italian.lprj"
224 mkdir -p "$pkgresources/Spanish.lprj"
225 mkdir -p "$pkgresources/fi.lprj"
226 mkdir -p "$pkgresources/no.lprj"
227 mkdir -p "$pkgresources/sv.lprj"
229 # Build and add the launcher
230 #----------------------------------------------------------
232         # Build fails if CC happens to be set (to anything other than CompileC)
233         unset CC
234         
235         cd "$resdir/ScriptExec"
236         echo -e "\033[1mBuilding launcher...\033[0m\n"
237         xcodebuild $XCODEFLAGS clean build
239 cp "$resdir/$SCRIPTEXECDIR/ScriptExec" "$pkgexec/Inkscape"
242 # Copy all files into the bundle
243 #----------------------------------------------------------
244 echo -e "\n\033[1mFilling app bundle...\033[0m\n"
246 binary_name=`basename "$binary"`
247 binary_dir=`dirname "$binary"`
249 # Inkscape's binary
250 binpath="$pkgbin/inkscape-bin"
251 cp -v "$binary" "$binpath"
252 # TODO Add a "$verbose" variable and command line switch, which sets wether these commands are verbose or not
254 # Share files
255 rsync -av "$binary_dir/../share/$binary_name"/* "$pkgresources/"
256 cp "$plist" "$package/Contents/Info.plist"
257 rsync -av "$binary_dir/../share/locale"/* "$pkgresources/locale"
259 # Copy GTK shared mime information
260 mkdir -p "$pkgresources/share"
261 cp -rp "$LIBPREFIX/share/mime" "$pkgresources/share/"
263 # Icons and the rest of the script framework
264 rsync -av --exclude ".svn" "$resdir"/Resources/* "$pkgresources/"
266 # Add python modules if requested
267 if [ ${add_python} = "true" ]; then
268         # 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
269         cp -rvf "$python_dir"/* "$pkgpython"
270 fi
272 # PkgInfo must match bundle type and creator code from Info.plist
273 echo "APPLInks" > $package/Contents/PkgInfo
275 # Pull in extra requirements for Pango and GTK
276 pkgetc="$package/Contents/Resources/etc"
277 mkdir -p $pkgetc/pango
278 cp $LIBPREFIX/etc/pango/pangox.aliases $pkgetc/pango/
279 # Need to adjust path and quote in case of spaces in path.
280 sed -e "s,$LIBPREFIX,\"\${CWD},g" -e 's,\.so ,.so" ,g' $LIBPREFIX/etc/pango/pango.modules > $pkgetc/pango/pango.modules
281 cat > $pkgetc/pango/pangorc <<END_PANGO
282 [Pango]
283 ModuleFiles=\${HOME}/.inkscape-etc/pango.modules
284 [PangoX]
285 AliasFiles=\${HOME}/.inkscape-etc/pangox.aliases
286 END_PANGO
288 # We use a modified fonts.conf file so only need the dtd
289 mkdir -p $pkgetc/fonts
290 cp $LIBPREFIX/etc/fonts/fonts.dtd $pkgetc/fonts/
291 cp -r $LIBPREFIX/etc/fonts/conf.avail $pkgetc/fonts/
292 cp -r $LIBPREFIX/etc/fonts/conf.d $pkgetc/fonts/
294 mkdir -p $pkgetc/gtk-2.0
295 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/etc/gtk-2.0/gdk-pixbuf.loaders > $pkgetc/gtk-2.0/gdk-pixbuf.loaders
296 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/etc/gtk-2.0/gtk.immodules > $pkgetc/gtk-2.0/gtk.immodules
298 for item in gnome-vfs-mime-magic gnome-vfs-2.0
299 do
300         cp -r $LIBPREFIX/etc/$item $pkgetc/
301 done
303 pango_version=`pkg-config --variable=pango_module_version pango`
304 mkdir -p $pkglib/pango/$pango_version/modules
305 cp $LIBPREFIX/lib/pango/$pango_version/modules/*.so $pkglib/pango/$pango_version/modules/
307 gtk_version=`pkg-config --variable=gtk_binary_version gtk+-2.0`
308 mkdir -p $pkglib/gtk-2.0/$gtk_version/{engines,immodules,loaders,printbackends}
309 cp -r $LIBPREFIX/lib/gtk-2.0/$gtk_version/* $pkglib/gtk-2.0/$gtk_version/
311 mkdir -p $pkglib/gnome-vfs-2.0/modules
312 cp $LIBPREFIX/lib/gnome-vfs-2.0/modules/*.so $pkglib/gnome-vfs-2.0/modules/
314 # Copy aspell dictionary files:
315 cp -r "$LIBPREFIX/lib/aspell-0.60" "$pkglib/"
316 cp -r "$LIBPREFIX/share/aspell" "$pkgresources/share/"
318 # Find out libs we need from fink, darwinports, or from a custom install
319 # (i.e. $LIBPREFIX), then loop until no changes.
320 a=1
321 nfiles=0
322 endl=true
323 while $endl; do
324         echo -e "\033[1mLooking for dependencies.\033[0m Round" $a
325         libs="`otool -L $pkglib/gtk-2.0/$gtk_version/{engines,immodules,loaders,printbackends}/*.{dylib,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`"
326         cp -f $libs $package/Contents/Resources/lib
327         let "a+=1"      
328         nnfiles=`ls $package/Contents/Resources/lib | wc -l`
329         if [ $nnfiles = $nfiles ]; then
330                 endl=false
331         else
332                 nfiles=$nnfiles
333         fi
334 done
336 # Add extra libraries of necessary
337 for libfile in $EXTRALIBS
338 do
339         cp -f $libfile $package/Contents/Resources/lib
340 done
343 # Strip libraries and executables if requested
344 #----------------------------------------------------------
345 if [ "$strip" = "true" ]; then
346         echo -e "\n\033[1mStripping debugging symbols...\033[0m\n"
347         chmod +w "$pkglib"/*.dylib
348         strip -x "$pkglib"/*.dylib
349         strip -ur "$binpath"
350 fi
352 # NOTE: This works for all the dylibs but causes GTK to crash at startup.
353 #                               Instead we leave them with their original install_names and set
354 #                               DYLD_LIBRARY_PATH within the app bundle before running Inkscape.
356 fixlib () {
357         libPath="`echo $2 | sed 's/.*Resources//'`"
358         pkgPath="`echo $2 | sed 's/Resources\/.*/Resources/'`"
359         # Fix a given executable or library to be relocatable
360         if [ ! -d "$1" ]; then
361                 libs="`otool -L $1 | fgrep compatibility | cut -d\( -f1`"
362                 for lib in $libs; do
363                         echo "  $lib"
364                         base=`echo $lib | awk -F/ '{print $NF}'`
365                         first=`echo $lib | cut -d/ -f1-3`
366                         relative=`echo $lib | cut -d/ -f4-`
367                         to=@executable_path/../$relative
368                         if [ $first != /usr/lib -a $first != /usr/X11 -a $first != /System/Library ]; then
369                                 /usr/bin/install_name_tool -change $lib $to $1
370                                 if [ "`echo $lib | fgrep libcrypto`" = "" ]; then
371                                         /usr/bin/install_name_tool -id $to $1
372                                         for ll in $libs; do
373                                                 base=`echo $ll | awk -F/ '{print $NF}'`
374                                                 first=`echo $ll | cut -d/ -f1-3`
375                                                 relative=`echo $ll | cut -d/ -f4-`
376                                                 to=@executable_path/../$relative
377                                                 if [ $first != /usr/lib -a $first != /usr/X11 -a $first != /System/Library -a "`echo $ll | fgrep libcrypto`" = "" ]; then
378                                                         /usr/bin/install_name_tool -change $ll $to $pkgPath/$relative
379                                                 fi
380                                         done
381                                 fi
382                         fi
383                 done
384         fi
386
387 # Fix package deps
388 # (cd "$package/Contents/Resources/lib/gtk-2.0/2.10.0/loaders"
389 # for file in *.so; do
390 #       echo "Rewriting dylib paths for $file..."
391 #       fixlib "$file" "`pwd`"
392 # done
393 # )
394 # (cd "$package/Contents/Resources/lib/gtk-2.0/2.10.0/engines"
395 # for file in *.so; do
396 #       echo "Rewriting dylib paths for $file..."
397 #       fixlib "$file" "`pwd`"
398 # done
399 # )
400 # (cd "$package/Contents/Resources/lib/gtk-2.0/2.10.0/immodules"
401 # for file in *.so; do
402 #       echo "Rewriting dylib paths for $file..."
403 #       fixlib "$file" "`pwd`"
404 # done
405 # )
406 # (cd "$package/Contents/Resources/lib/gtk-2.0/2.10.0/printbackends"
407 # for file in *.so; do
408 #       echo "Rewriting dylib paths for $file..."
409 #       fixlib "$file" "`pwd`"
410 # done
411 # )
412 # (cd "$package/Contents/Resources/bin"
413 # for file in *; do
414 #       echo "Rewriting dylib paths for $file..."
415 #       fixlib "$file" "`pwd`"
416 # done
417 # cd ../lib
418 # for file in *.dylib; do
419 #       echo "Rewriting dylib paths for $file..."
420 #       fixlib "$file" "`pwd`"
421 # done
422 # )
424 exit 0