Code

Enhanced comments related to python modules
[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" 
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/"
179 mkdir -p "$pkgexec"
180 mkdir -p "$pkgbin"
181 mkdir -p "$pkglib"
182 mkdir -p "$pkglocale"
183 mkdir -p "$pkgpython"
186 # Build and add the launcher
187 #----------------------------------------------------------
189         # Build fails if CC happens to be set (to anything other than CompileC)
190         unset CC
191         
192         cd "$resdir/ScriptExec"
193         echo -e "\033[1mBuilding launcher...\033[0m\n"
194         xcodebuild $XCODEFLAGS clean build
196 cp "$resdir/$SCRIPTEXECDIR/ScriptExec" "$pkgexec/Inkscape"
199 # Copy all files into the bundle
200 #----------------------------------------------------------
201 echo -e "\n\033[1mFilling app bundle...\033[0m\n"
203 binary_name=`basename "$binary"`
204 binary_dir=`dirname "$binary"`
206 # Inkscape's binary
207 binpath="$pkgbin/inkscape-bin"
208 cp -v "$binary" "$binpath"
209 # TODO Add a "$verbose" variable and command line switch, which sets wether these commands are verbose or not
211 # Share files
212 rsync -av "$binary_dir/../share/$binary_name"/* "$package/Contents/Resources/"
213 cp "$plist" "$package/Contents/Info.plist"
214 rsync -av "$binary_dir/../share/locale"/* "$package/Contents/Resources/locale"
216 # Icons and the rest of the script framework
217 rsync -av --exclude ".svn" "$resdir"/Resources/* "$package"/Contents/Resources/
219 # Add python modules if requested
220 if [ ${add_python} = "true" ]; then
221         # 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
222         cp -rvf "$python_dir"/* "$pkgpython"
223 fi
225 # PkgInfo must match bundle type and creator code from Info.plist
226 echo "APPLInks" > $package/Contents/PkgInfo
228 # Pull in extra requirements for Pango and GTK
229 pkgetc="$package/Contents/Resources/etc"
230 mkdir -p $pkgetc/pango
231 cp $LIBPREFIX/etc/pango/pangox.aliases $pkgetc/pango/
232 # Need to adjust path and quote in case of spaces in path.
233 sed -e "s,$LIBPREFIX,\"\${CWD},g" -e 's,\.so ,.so" ,g' $LIBPREFIX/etc/pango/pango.modules > $pkgetc/pango/pango.modules
234 cat > $pkgetc/pango/pangorc <<END_PANGO
235 [Pango]
236 ModuleFiles=\${HOME}/.inkscape-etc/pango.modules
237 [PangoX]
238 AliasFiles=\${HOME}/.inkscape-etc/pangox.aliases
239 END_PANGO
241 # We use a modified fonts.conf file so only need the dtd
242 mkdir -p $pkgetc/fonts
243 cp $LIBPREFIX/etc/fonts/fonts.dtd $pkgetc/fonts/
244 cp -r $LIBPREFIX/etc/fonts/conf.avail $pkgetc/fonts/
245 cp -r $LIBPREFIX/etc/fonts/conf.d $pkgetc/fonts/
247 mkdir -p $pkgetc/gtk-2.0
248 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/etc/gtk-2.0/gdk-pixbuf.loaders > $pkgetc/gtk-2.0/gdk-pixbuf.loaders
249 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/etc/gtk-2.0/gtk.immodules > $pkgetc/gtk-2.0/gtk.immodules
251 for item in gnome-vfs-mime-magic gnome-vfs-2.0
252 do
253         cp -r $LIBPREFIX/etc/$item $pkgetc/
254 done
256 pango_version=`pkg-config --variable=pango_module_version pango`
257 mkdir -p $pkglib/pango/$pango_version/modules
258 cp $LIBPREFIX/lib/pango/$pango_version/modules/*.so $pkglib/pango/$pango_version/modules/
260 gtk_version=`pkg-config --variable=gtk_binary_version gtk+-2.0`
261 mkdir -p $pkglib/gtk-2.0/$gtk_version/{engines,immodules,loaders}
262 cp -r $LIBPREFIX/lib/gtk-2.0/$gtk_version/engines/* $pkglib/gtk-2.0/$gtk_version/engines/
263 cp $LIBPREFIX/lib/gtk-2.0/$gtk_version/immodules/*.so $pkglib/gtk-2.0/$gtk_version/immodules/
264 cp $LIBPREFIX/lib/gtk-2.0/$gtk_version/loaders/*.so $pkglib/gtk-2.0/$gtk_version/loaders/
266 mkdir -p $pkglib/gnome-vfs-2.0/modules
267 cp $LIBPREFIX/lib/gnome-vfs-2.0/modules/*.so $pkglib/gnome-vfs-2.0/modules/
269 # Find out libs we need from fink, darwinports, or from a custom install
270 # (i.e. $LIBPREFIX), then loop until no changes.
271 a=1
272 nfiles=0
273 endl=true
274 while $endl; do
275         echo -e "\033[1mLooking for dependencies.\033[0m Round" $a
276         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`"
277         cp -f $libs $package/Contents/Resources/lib
278         let "a+=1"      
279         nnfiles=`ls $package/Contents/Resources/lib | wc -l`
280         if [ $nnfiles = $nfiles ]; then
281                 endl=false
282         else
283                 nfiles=$nnfiles
284         fi
285 done
287 # Add extra libraries of necessary
288 for libfile in $EXTRALIBS
289 do
290         cp -f $libfile $package/Contents/Resources/lib
291 done
294 # Strip libraries and executables if requested
295 #----------------------------------------------------------
296 if [ "$strip" = "true" ]; then
297         echo -e "\n\033[1mStripping debugging symbols...\033[0m\n"
298         chmod +w "$pkglib"/*.dylib
299         strip -x "$pkglib"/*.dylib
300         strip -ur "$binpath"
301 fi
303 # NOTE: This works for all the dylibs but causes GTK to crash at startup.
304 #                               Instead we leave them with their original install_names and set
305 #                               DYLD_LIBRARY_PATH within the app bundle before running Inkscape.
307 # fixlib () {
308 #               # Fix a given executable or library to be relocatable
309 #               if [ ! -d "$1" ]; then
310 #                       echo $1
311 #                       libs="`otool -L $1 | fgrep compatibility | cut -d\( -f1`"
312 #                       for lib in $libs; do
313 #                               echo "  $lib"
314 #                               base=`echo $lib | awk -F/ '{print $NF}'`
315 #                               first=`echo $lib | cut -d/ -f1-3`
316 #                               to=@executable_path/../lib/$base
317 #                               if [ $first != /usr/lib -a $first != /usr/X11R6 ]; then
318 #                                       /usr/bin/install_name_tool -change $lib $to $1
319 #                                       if [ "`echo $lib | fgrep libcrypto`" = "" ]; then
320 #                                               /usr/bin/install_name_tool -id $to ../lib/$base
321 #                                               for ll in $libs; do
322 #                                                       base=`echo $ll | awk -F/ '{print $NF}'`
323 #                                                       first=`echo $ll | cut -d/ -f1-3`
324 #                                                       to=@executable_path/../lib/$base
325 #                                                       if [ $first != /usr/lib -a $first != /usr/X11R6 -a "`echo $ll | fgrep libcrypto`" = "" ]; then
326 #                                                               /usr/bin/install_name_tool -change $ll $to ../lib/$base
327 #                                                       fi
328 #                                               done
329 #                                       fi
330 #                               fi
331 #                       done
332 #               fi
333 # }
334
335 # Fix package deps
336 #(cd "$package/Contents/MacOS/bin"
337 # for file in *; do
338 #                fixlib "$file"
339 # done
340 # cd ../lib
341 # for file in *; do
342 #                fixlib "$file"
343 # done)
345 exit 0