Code

Extensions. Compressed+media export improvements (see Bug #386664, Gather Resources...
[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 ! pkg-config --exists gtk-engines-2; then
157         echo "Missing gtk-engines2 -- please install gtk-engines2 and try again." >&2
158         exit 1
159 fi
161 if ! pkg-config --exists gnome-vfs-2.0; then
162         echo "Missing gnome-vfs2 -- please install gnome-vfs2 and try again." >&2
163         exit 1
164 fi
166 if ! pkg-config --exists poppler; then
167         echo "Missing poppler -- please install poppler and try again." >&2
168         exit 1
169 fi
171 if ! pkg-config --modversion ImageMagick >/dev/null 2>&1; then
172         echo "Missing ImageMagick -- please install ImageMagick and try again." >&2
173         exit 1
174 fi
176 if [ ! -e "$LIBPREFIX/lib/aspell-0.60/en.dat" ]; then
177         echo "Missing aspell en dictionary -- please install at least 'aspell-dict-en', but" >&2
178         echo "preferably all dictionaries ('aspell-dict-*') and try again." >&2
179         exit 1
180 fi
183 # Handle some version specific details.
184 VERSION=`/usr/bin/sw_vers | grep ProductVersion | cut -f2 -d'.'`
185 if [ "$VERSION" -ge "4" ]; then
186         # We're on Tiger (10.4) or later.
187         # XCode behaves a little differently in Tiger and later.
188         XCODEFLAGS="-configuration Deployment"
189         SCRIPTEXECDIR="ScriptExec/build/Deployment/ScriptExec.app/Contents/MacOS"
190         EXTRALIBS=""
191 else
192         # Panther (10.3) or earlier.
193         XCODEFLAGS="-buildstyle Deployment"
194         SCRIPTEXECDIR="ScriptExec/build/ScriptExec.app/Contents/MacOS"
195         EXTRALIBS=""
196 fi
199 # Package always has the same name. Version information is stored in
200 # the Info.plist file which is filled in by the configure script.
201 package="Inkscape.app"
203 # Remove a previously existing package if necessary
204 if [ -d $package ]; then
205         echo "Removing previous Inkscape.app"
206         rm -Rf $package
207 fi
210 # Set the 'macosx' directory, usually the current directory.
211 resdir=`pwd`
214 # Prepare Package
215 #----------------------------------------------------------
216 pkgexec="$package/Contents/MacOS"
217 pkgbin="$package/Contents/Resources/bin"
218 pkglib="$package/Contents/Resources/lib"
219 pkglocale="$package/Contents/Resources/locale"
220 pkgpython="$package/Contents/Resources/python/site-packages/"
221 pkgresources="$package/Contents/Resources"
223 mkdir -p "$pkgexec"
224 mkdir -p "$pkgbin"
225 mkdir -p "$pkglib"
226 mkdir -p "$pkglocale"
227 mkdir -p "$pkgpython"
229 mkdir -p "$pkgresources/Dutch.lprj"
230 mkdir -p "$pkgresources/English.lprj"
231 mkdir -p "$pkgresources/French.lprj"
232 mkdir -p "$pkgresources/German.lprj"
233 mkdir -p "$pkgresources/Italian.lprj"
234 mkdir -p "$pkgresources/Spanish.lprj"
235 mkdir -p "$pkgresources/fi.lprj"
236 mkdir -p "$pkgresources/no.lprj"
237 mkdir -p "$pkgresources/sv.lprj"
239 # Build and add the launcher
240 #----------------------------------------------------------
242         # Build fails if CC happens to be set (to anything other than CompileC)
243         unset CC
244         
245         cd "$resdir/ScriptExec"
246         echo -e "\033[1mBuilding launcher...\033[0m\n"
247         xcodebuild $XCODEFLAGS clean build
249 cp "$resdir/$SCRIPTEXECDIR/ScriptExec" "$pkgexec/Inkscape"
252 # Copy all files into the bundle
253 #----------------------------------------------------------
254 echo -e "\n\033[1mFilling app bundle...\033[0m\n"
256 binary_name=`basename "$binary"`
257 binary_dir=`dirname "$binary"`
259 # Inkscape's binary
260 binpath="$pkgbin/inkscape-bin"
261 cp -v "$binary" "$binpath"
262 # TODO Add a "$verbose" variable and command line switch, which sets wether these commands are verbose or not
264 # Share files
265 rsync -av "$binary_dir/../share/$binary_name"/* "$pkgresources/"
266 cp "$plist" "$package/Contents/Info.plist"
267 rsync -av "$binary_dir/../share/locale"/* "$pkgresources/locale"
269 # Copy GTK shared mime information
270 mkdir -p "$pkgresources/share"
271 cp -rp "$LIBPREFIX/share/mime" "$pkgresources/share/"
273 # Icons and the rest of the script framework
274 rsync -av --exclude ".svn" "$resdir"/Resources/* "$pkgresources/"
276 # Update the ImageMagick path in startup script.
277 IMAGEMAGICKVER=`pkg-config --modversion ImageMagick`
278 sed -e "s,IMAGEMAGICKVER,$IMAGEMAGICKVER,g" -i "" $pkgbin/inkscape
280 # Add python modules if requested
281 if [ ${add_python} = "true" ]; then
282         # 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
283         cp -rvf "$python_dir"/* "$pkgpython"
284 fi
286 # PkgInfo must match bundle type and creator code from Info.plist
287 echo "APPLInks" > $package/Contents/PkgInfo
289 # Pull in extra requirements for Pango and GTK
290 pkgetc="$package/Contents/Resources/etc"
291 mkdir -p $pkgetc/pango
292 cp $LIBPREFIX/etc/pango/pangox.aliases $pkgetc/pango/
293 # Need to adjust path and quote in case of spaces in path.
294 sed -e "s,$LIBPREFIX,\"\${CWD},g" -e 's,\.so ,.so" ,g' $LIBPREFIX/etc/pango/pango.modules > $pkgetc/pango/pango.modules
295 cat > $pkgetc/pango/pangorc <<END_PANGO
296 [Pango]
297 ModuleFiles=\${HOME}/.inkscape-etc/pango.modules
298 [PangoX]
299 AliasFiles=\${HOME}/.inkscape-etc/pangox.aliases
300 END_PANGO
302 # We use a modified fonts.conf file so only need the dtd
303 mkdir -p $pkgetc/fonts
304 cp $LIBPREFIX/etc/fonts/fonts.dtd $pkgetc/fonts/
305 cp -r $LIBPREFIX/etc/fonts/conf.avail $pkgetc/fonts/
306 cp -r $LIBPREFIX/etc/fonts/conf.d $pkgetc/fonts/
308 mkdir -p $pkgetc/gtk-2.0
309 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/etc/gtk-2.0/gdk-pixbuf.loaders > $pkgetc/gtk-2.0/gdk-pixbuf.loaders
310 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/etc/gtk-2.0/gtk.immodules > $pkgetc/gtk-2.0/gtk.immodules
312 for item in gnome-vfs-mime-magic gnome-vfs-2.0
313 do
314         cp -r $LIBPREFIX/etc/$item $pkgetc/
315 done
317 pango_version=`pkg-config --variable=pango_module_version pango`
318 mkdir -p $pkglib/pango/$pango_version/modules
319 cp $LIBPREFIX/lib/pango/$pango_version/modules/*.so $pkglib/pango/$pango_version/modules/
321 gtk_version=`pkg-config --variable=gtk_binary_version gtk+-2.0`
322 mkdir -p $pkglib/gtk-2.0/$gtk_version/{engines,immodules,loaders,printbackends}
323 cp -r $LIBPREFIX/lib/gtk-2.0/$gtk_version/* $pkglib/gtk-2.0/$gtk_version/
325 mkdir -p $pkglib/gnome-vfs-2.0/modules
326 cp $LIBPREFIX/lib/gnome-vfs-2.0/modules/*.so $pkglib/gnome-vfs-2.0/modules/
328 cp -r "$LIBPREFIX/lib/ImageMagick-$IMAGEMAGICKVER" "$pkglib/"
329 cp -r "$LIBPREFIX/share/ImageMagick-$IMAGEMAGICKVER" "$pkgresources/share/"
331 # Copy aspell dictionary files:
332 cp -r "$LIBPREFIX/lib/aspell-0.60" "$pkglib/"
333 cp -r "$LIBPREFIX/share/aspell" "$pkgresources/share/"
335 # Find out libs we need from fink, darwinports, or from a custom install
336 # (i.e. $LIBPREFIX), then loop until no changes.
337 a=1
338 nfiles=0
339 endl=true
340 while $endl; do
341         echo -e "\033[1mLooking for dependencies.\033[0m Round" $a
342         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/* $pkglib/ImageMagick-$IMAGEMAGICKVER/modules-Q16/{filters,coders}/*.so $binary 2>/dev/null | fgrep compatibility | cut -d\( -f1 | grep $LIBPREFIX | sort | uniq`"
343         cp -f $libs $package/Contents/Resources/lib
344         let "a+=1"      
345         nnfiles=`ls $package/Contents/Resources/lib | wc -l`
346         if [ $nnfiles = $nfiles ]; then
347                 endl=false
348         else
349                 nfiles=$nnfiles
350         fi
351 done
353 # Add extra libraries of necessary
354 for libfile in $EXTRALIBS
355 do
356         cp -f $libfile $package/Contents/Resources/lib
357 done
359 # Some libraries don't seem to have write permission, fix this.
360 chmod -R u+w $package/Contents/Resources/lib
362 # Strip libraries and executables if requested
363 #----------------------------------------------------------
364 if [ "$strip" = "true" ]; then
365         echo -e "\n\033[1mStripping debugging symbols...\033[0m\n"
366         chmod +w "$pkglib"/*.dylib
367         strip -x "$pkglib"/*.dylib
368         strip -ur "$binpath"
369 fi
371 # NOTE: This works for all the dylibs but causes GTK to crash at startup.
372 #                               Instead we leave them with their original install_names and set
373 #                               DYLD_LIBRARY_PATH within the app bundle before running Inkscape.
375 fixlib () {
376         libPath="`echo $2 | sed 's/.*Resources//'`"
377         pkgPath="`echo $2 | sed 's/Resources\/.*/Resources/'`"
378         # Fix a given executable or library to be relocatable
379         if [ ! -d "$1" ]; then
380                 libs="`otool -L $1 | fgrep compatibility | cut -d\( -f1`"
381                 for lib in $libs; do
382                         echo "  $lib"
383                         base=`echo $lib | awk -F/ '{print $NF}'`
384                         first=`echo $lib | cut -d/ -f1-3`
385                         relative=`echo $lib | cut -d/ -f4-`
386                         to=@executable_path/../$relative
387                         if [ $first != /usr/lib -a $first != /usr/X11 -a $first != /System/Library ]; then
388                                 /usr/bin/install_name_tool -change $lib $to $1
389                                 if [ "`echo $lib | fgrep libcrypto`" = "" ]; then
390                                         /usr/bin/install_name_tool -id $to $1
391                                         for ll in $libs; do
392                                                 base=`echo $ll | awk -F/ '{print $NF}'`
393                                                 first=`echo $ll | cut -d/ -f1-3`
394                                                 relative=`echo $ll | cut -d/ -f4-`
395                                                 to=@executable_path/../$relative
396                                                 if [ $first != /usr/lib -a $first != /usr/X11 -a $first != /System/Library -a "`echo $ll | fgrep libcrypto`" = "" ]; then
397                                                         /usr/bin/install_name_tool -change $ll $to $pkgPath/$relative
398                                                 fi
399                                         done
400                                 fi
401                         fi
402                 done
403         fi
406 rewritelibpaths () {
407         # 
408         # Fix package deps
409         (cd "$package/Contents/Resources/lib/gtk-2.0/2.10.0/loaders"
410         for file in *.so; do
411                 echo "Rewriting dylib paths for $file..."
412                 fixlib "$file" "`pwd`"
413         done
414         )
415         (cd "$package/Contents/Resources/lib/gtk-2.0/2.10.0/engines"
416         for file in *.so; do
417                 echo "Rewriting dylib paths for $file..."
418                 fixlib "$file" "`pwd`"
419         done
420         )
421         (cd "$package/Contents/Resources/lib/gtk-2.0/2.10.0/immodules"
422         for file in *.so; do
423                 echo "Rewriting dylib paths for $file..."
424                 fixlib "$file" "`pwd`"
425         done
426         )
427         (cd "$package/Contents/Resources/lib/gtk-2.0/2.10.0/printbackends"
428         for file in *.so; do
429                 echo "Rewriting dylib paths for $file..."
430                 fixlib "$file" "`pwd`"
431         done
432         )
433         (cd "$package/Contents/Resources/lib/gnome-vfs-2.0/modules"
434         for file in *.so; do
435                 echo "Rewriting dylib paths for $file..."
436                 fixlib "$file" "`pwd`"
437         done
438         )
439         (cd "$package/Contents/Resources/lib/pango/1.6.0/modules"
440         for file in *.so; do
441                 echo "Rewriting dylib paths for $file..."
442                 fixlib "$file" "`pwd`"
443         done
444         )
445         (cd "$package/Contents/Resources/lib/ImageMagick-$IMAGEMAGICKVER/modules-Q16/filters"
446         for file in *.so; do
447                 echo "Rewriting dylib paths for $file..."
448                 fixlib "$file" "`pwd`"
449         done
450         )
451         (cd "$package/Contents/Resources/lib/ImageMagick-$IMAGEMAGICKVER/modules-Q16/coders"
452         for file in *.so; do
453                 echo "Rewriting dylib paths for $file..."
454                 fixlib "$file" "`pwd`"
455         done
456         )
457         (cd "$package/Contents/Resources/bin"
458         for file in *; do
459                 echo "Rewriting dylib paths for $file..."
460                 fixlib "$file" "`pwd`"
461         done
462         cd ../lib
463         for file in *.dylib; do
464                 echo "Rewriting dylib paths for $file..."
465                 fixlib "$file" "`pwd`"
466         done
467         )
470 PATHLENGTH=`echo $LIBPREFIX | wc -c`
471 if [ "$PATHLENGTH" -ge "50" ]; then
472         # If the LIBPREFIX path is long enough to allow 
473         # path rewriting, then do this.
474         rewritelibpaths
475 else
476         echo "Could not rewrite dylb paths for bundled libraries.  This requires" >&2
477         echo "Macports to be installed in a PREFIX of at least 50 characters in length." >&2
478         echo "" >&2
479         echo "The package will still work if the following line is uncommented in" >&2
480         echo "Inkscape.app/Contents/Resources/bin/inkscape:" >&2
481         echo '        export DYLD_LIBRARY_PATH="$TOP/lib"' >&2
482         exit 1
484 fi
486 exit 0