ac7cafd3cabdf740844f290e245679c50388a8e3
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/"
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 #----------------------------------------------------------
188 (
189 # Build fails if CC happens to be set (to anything other than CompileC)
190 unset CC
192 cd "$resdir/ScriptExec"
193 echo -e "\033[1mBuilding launcher...\033[0m\n"
194 xcodebuild $XCODEFLAGS clean build
195 )
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/* $pkglib/gtk-2.0/$gtk_version/
264 mkdir -p $pkglib/gnome-vfs-2.0/modules
265 cp $LIBPREFIX/lib/gnome-vfs-2.0/modules/*.so $pkglib/gnome-vfs-2.0/modules/
267 # Find out libs we need from fink, darwinports, or from a custom install
268 # (i.e. $LIBPREFIX), then loop until no changes.
269 a=1
270 nfiles=0
271 endl=true
272 while $endl; do
273 echo -e "\033[1mLooking for dependencies.\033[0m Round" $a
274 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`"
275 cp -f $libs $package/Contents/Resources/lib
276 let "a+=1"
277 nnfiles=`ls $package/Contents/Resources/lib | wc -l`
278 if [ $nnfiles = $nfiles ]; then
279 endl=false
280 else
281 nfiles=$nnfiles
282 fi
283 done
285 # Add extra libraries of necessary
286 for libfile in $EXTRALIBS
287 do
288 cp -f $libfile $package/Contents/Resources/lib
289 done
292 # Strip libraries and executables if requested
293 #----------------------------------------------------------
294 if [ "$strip" = "true" ]; then
295 echo -e "\n\033[1mStripping debugging symbols...\033[0m\n"
296 chmod +w "$pkglib"/*.dylib
297 strip -x "$pkglib"/*.dylib
298 strip -ur "$binpath"
299 fi
301 # NOTE: This works for all the dylibs but causes GTK to crash at startup.
302 # Instead we leave them with their original install_names and set
303 # DYLD_LIBRARY_PATH within the app bundle before running Inkscape.
304 #
305 # fixlib () {
306 # # Fix a given executable or library to be relocatable
307 # if [ ! -d "$1" ]; then
308 # echo $1
309 # libs="`otool -L $1 | fgrep compatibility | cut -d\( -f1`"
310 # for lib in $libs; do
311 # echo " $lib"
312 # base=`echo $lib | awk -F/ '{print $NF}'`
313 # first=`echo $lib | cut -d/ -f1-3`
314 # to=@executable_path/../lib/$base
315 # if [ $first != /usr/lib -a $first != /usr/X11R6 ]; then
316 # /usr/bin/install_name_tool -change $lib $to $1
317 # if [ "`echo $lib | fgrep libcrypto`" = "" ]; then
318 # /usr/bin/install_name_tool -id $to ../lib/$base
319 # for ll in $libs; do
320 # base=`echo $ll | awk -F/ '{print $NF}'`
321 # first=`echo $ll | cut -d/ -f1-3`
322 # to=@executable_path/../lib/$base
323 # if [ $first != /usr/lib -a $first != /usr/X11R6 -a "`echo $ll | fgrep libcrypto`" = "" ]; then
324 # /usr/bin/install_name_tool -change $ll $to ../lib/$base
325 # fi
326 # done
327 # fi
328 # fi
329 # done
330 # fi
331 # }
332 #
333 # Fix package deps
334 #(cd "$package/Contents/MacOS/bin"
335 # for file in *; do
336 # fixlib "$file"
337 # done
338 # cd ../lib
339 # for file in *; do
340 # fixlib "$file"
341 # done)
343 exit 0