Add a --enable-osx-deploy-target option to set the deployment target
[metze/wireshark/wip.git] / packaging / macosx / osx-app.sh
1 #!/bin/bash
2 #
3 # $Id$
4 #
5 # USAGE
6 # osx-app [-s] [-l /path/to/libraries] -bp /path/to/wireshark/bin -p /path/to/Info.plist
7 #
8 # This script attempts to build an Wireshark.app package for OS X, resolving
9 # dynamic libraries, etc.
10 # It strips the executable and libraries if '-s' is given.
11 # It adds python modules if the '-py option' is given
12 # The Info.plist file can be found in the base wireshark directory once
13 # configure has been run.
14 #
15 # AUTHORS
16 #                Kees Cook <kees@outflux.net>
17 #                Michael Wybrow <mjwybrow@users.sourceforge.net>
18 #                Jean-Olivier Irisson <jo.irisson@gmail.com>
19 #
20 # Copyright (C) 2005 Kees Cook
21 # Copyright (C) 2005-2007 Michael Wybrow
22 # Copyright (C) 2007 Jean-Olivier Irisson
23 #
24 # Released under GNU GPL, read the file 'COPYING' for more information
25 #
26 # Thanks to GNUnet's "build_app" script for help with library dep resolution.
27 #               https://gnunet.org/svn/GNUnet/contrib/OSX/build_app
28 #
29 # NB:
30 # This originally came from Inkscape; Inkscape's configure script has an
31 # "--enable-osxapp", which causes some of Inkscape's installation data
32 # files to have OS X-ish paths under Contents/Resources of the package
33 # or under /Library/Application Support.  We don't have such an option;
34 # we just put them in "bin", "etc", "lib", and "share" directories
35 # under Contents/Resources, rather than in the "bin", "etc", "lib",
36 # and "share" directories under the installation directory.
37 #
38
39 # Defaults
40 strip=false
41 binary_path="/tmp/inst/bin"
42 plist="./Info.plist"
43 util_dir="./Utilities"
44 cli_dir="$util_dir/Command Line"
45 chmodbpf_dir="$util_dir/ChmodBPF"
46
47 binary_list="
48         capinfos
49         dftest
50         dumpcap
51         editcap
52         mergecap
53         randpkt
54         rawshark
55         text2pcap
56         tshark
57         wireshark
58 "
59
60 # Location for libraries (macosx-setup.sh defaults to whatever the
61 # various support libraries use as their standard installation location,
62 # which is /usr/local)
63 if [ -z $LIBPREFIX ]; then
64         LIBPREFIX="/usr/local"
65 fi
66
67
68 # Help message
69 #----------------------------------------------------------
70 help()
71 {
72 echo -e "
73 Create an app bundle for OS X
74
75 USAGE
76         $0 [-s] [-l /path/to/libraries] -bp /path/to/wireshark/binaries -p /path/to/Info.plist
77
78 OPTIONS
79         -h,--help
80                 display this help message
81         -s
82                 strip the libraries and executables from debugging symbols
83         -l,--libraries
84                 specify the path to the libraries Wireshark depends on
85                 (typically /sw or /opt/local).  By default it is
86                 /usr/local.
87         -bp,--binary-path
88                 specify the path to the Wireshark binaries. By default it
89                 is /tmp/inst/bin.
90         -p,--plist
91                 specify the path to Info.plist. Info.plist can be found
92                 in the base directory of the source code once configure
93                 has been run.
94         -sdkroot
95                 specify the root of the SDK to use
96
97 EXAMPLE
98         $0 -s -l /opt/local -bp ../../Build/bin -p Info.plist -sdkroot /Developer/SDKs/MacOSX10.5.sdk
99 "
100 }
101
102
103 # Parse command line arguments
104 #----------------------------------------------------------
105 while [ "$1" != "" ]
106 do
107         case $1 in
108                 -s)
109                         strip=true ;;
110                 -l|--libraries)
111                         LIBPREFIX="$2"
112                         shift 1 ;;
113                 -bp|--binary-path)
114                         binary_path="$2"
115                         shift 1 ;;
116                 -p|--plist)
117                         plist="$2"
118                         shift 1 ;;
119                 -h|--help)
120                         help
121                         exit 0 ;;
122                 -sdkroot)
123                         sdkroot="$2"
124                         shift 1 ;;
125                 *)
126                         echo "Invalid command line option: $1"
127                         exit 2 ;;
128         esac
129         shift 1
130 done
131
132 echo -e "\nCREATE WIRESHARK APP BUNDLE\n"
133
134 # Safety tests
135 if [ ! -e "$LIBPREFIX" ]; then
136         echo "Cannot find the directory containing the libraries: $LIBPREFIX" >&2
137         exit 1
138 fi
139
140 for binary in wireshark $binary_list ; do
141         if [ ! -x "$binary_path/$binary" ]; then
142                 echo "Couldn't find $binary (or it's not executable)" >&2
143                 exit 1
144         fi
145 done
146
147 if [ ! -f "$plist" ]; then
148         echo "Need plist file" >&2
149         exit 1
150 fi
151
152
153 # Handle some version specific details.
154 VERSION=`/usr/bin/sw_vers | grep ProductVersion | cut -f2 -d'.'`
155 if [ "$VERSION" -ge "4" ]; then
156         # We're on Tiger (10.4) or later.
157         # XCode behaves a little differently in Tiger and later.
158         XCODEFLAGS="-configuration Deployment"
159         SCRIPTEXECDIR="ScriptExec/build/Deployment/ScriptExec.app/Contents/MacOS"
160         EXTRALIBS=""
161 else
162         # Panther (10.3) or earlier.
163         XCODEFLAGS="-buildstyle Deployment"
164         SCRIPTEXECDIR="ScriptExec/build/ScriptExec.app/Contents/MacOS"
165         EXTRALIBS=""
166 fi
167
168 # Set the SDK root, if an SDK was specified.
169 # (-sdk is only supported by the xcodebuild in the version of the
170 # developer tools that came with Snow Leopard and later versions)
171 if [ ! -z "$sdkroot" ]
172 then
173         XCODEFLAGS="$XCODEFLAGS SDKROOT=$sdkroot"
174 fi
175
176 # Package always has the same name. Version information is stored in
177 # the Info.plist file which is filled in by the configure script.
178 package="Wireshark.app"
179
180 # Remove a previously existing package if necessary
181 if [ -d $package ]; then
182         echo "Removing previous Wireshark.app"
183         rm -Rf $package
184 fi
185
186 # Remove a previously existing utility directory if necessary
187 if [ -d "$util_dir" ]; then
188         echo "Removing $util_dir directory"
189         rm -Rf "$util_dir"
190 fi
191
192 # Set the 'macosx' directory, usually the current directory.
193 resdir=`pwd`
194
195
196 # Prepare Package
197 #----------------------------------------------------------
198 pkgexec="$package/Contents/MacOS"
199 pkgres="$package/Contents/Resources"
200 pkgbin="$pkgres/bin"
201 pkglib="$pkgres/lib"
202 pkgplugin="$pkglib/wireshark/plugins"
203 pkgpython="$pkglib/wireshark/python"
204
205 mkdir -p "$pkgexec"
206 mkdir -p "$pkgbin"
207 mkdir -p "$pkgplugin"
208 mkdir -p "$pkgpython"
209
210 mkdir -p "$cli_dir"
211
212 # Build and add the launcher
213 #----------------------------------------------------------
214 (
215         # Build fails if CC happens to be set (to anything other than CompileC)
216         unset CC
217
218         cd "$resdir/ScriptExec"
219         echo -e "Building launcher...\n"
220         xcodebuild $XCODEFLAGS clean build
221 )
222 cp "$resdir/$SCRIPTEXECDIR/ScriptExec" "$pkgexec/Wireshark"
223
224
225 # Copy all files into the bundle
226 #----------------------------------------------------------
227 echo -e "\nFilling app bundle and utility directory...\n"
228
229 # Wireshark executables
230 for binary in $binary_list ; do
231         # Copy the binary to its destination
232         dest_path="$pkgbin/$binary-bin"
233         cp -v "$binary_path/$binary" "$dest_path"
234         # TODO Add a "$verbose" variable and command line switch, which sets wether these commands are verbose or not
235
236         case $binary in
237         wireshark)
238                 cp -v utility-launcher "$cli_dir/$binary"
239                 ;;
240         *)
241                 ln -sv ./wireshark "$pkgbin/$binary"
242                 ln -sv ./wireshark "$cli_dir/$binary"
243                 ;;
244         esac
245 done
246
247 # ChmodBPF
248 mkdir -p "$chmodbpf_dir"
249 cp -v ChmodBPF/* "$chmodbpf_dir"
250 chmod -R g-w "$chmodbpf_dir"
251
252 # The rest of the Wireshark installation (we handled bin above)
253 rsync -av \
254         --exclude bin/ \
255         --exclude lib/wireshark/plugins/ \
256         --exclude lib/wireshark/python/ \
257         "$binary_path/.."/* "$pkgres"
258
259 # Remove the version number from the plugin path
260 find "$binary_path/../lib/wireshark/plugins" -type f \
261         -exec cp -fv "{}" "$pkgplugin/" \;
262
263 # Remove the version number from the python path
264 find "$binary_path/../lib/wireshark/python" -type f \
265         -exec cp -fv "{}" "$pkgpython/" \;
266
267 cp "$plist" "$package/Contents/Info.plist"
268
269 # Icons and the rest of the script framework
270 rsync -av --exclude ".svn" "$resdir"/Resources/* "$package"/Contents/Resources/
271
272 # PkgInfo must match bundle type and creator code from Info.plist
273 echo "APPLWshk" > $package/Contents/PkgInfo
274
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}/.wireshark-etc/pango.modules
284 [PangoX]
285 AliasFiles=\${HOME}/.wireshark-etc/pangox.aliases
286 END_PANGO
287
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/
293
294 mkdir -p $pkgetc/gtk-2.0
295 #
296 # In newer versions of GTK+, the gdk-pixbuf library was split off from
297 # GTK+, and the gdk-pixbuf.loaders file moved, so we check for its
298 # existence here.
299 #
300 # The file is ultimately copied to the user's home directory, with
301 # the pathnames adjusted to refer to the installed package, so we
302 # always put it in the same location in the installed package,
303 # regardless of where it lives in the machine on which it's built.
304 #
305 if [ -e $LIBPREFIX/etc/gtk-2.0/gdk-pixbuf.loaders ]
306 then
307         sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/etc/gtk-2.0/gdk-pixbuf.loaders > $pkgetc/gtk-2.0/gdk-pixbuf.loaders
308 fi
309 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/etc/gtk-2.0/gtk.immodules > $pkgetc/gtk-2.0/gtk.immodules
310
311 pango_version=`pkg-config --variable=pango_module_version pango`
312 mkdir -p $pkglib/pango/$pango_version/modules
313 cp $LIBPREFIX/lib/pango/$pango_version/modules/*.so $pkglib/pango/$pango_version/modules/
314
315 gtk_version=`pkg-config --variable=gtk_binary_version gtk+-2.0`
316 mkdir -p $pkglib/gtk-2.0/$gtk_version/{engines,immodules,loaders}
317 cp -r $LIBPREFIX/lib/gtk-2.0/$gtk_version/* $pkglib/gtk-2.0/$gtk_version/
318
319 gdk_pixbuf_version=`pkg-config --variable=gdk_pixbuf_binary_version gdk-pixbuf-2.0`
320 if [ ! -z $gdk_pixbuf_version ]; then
321         mkdir -p $pkglib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders
322         #
323         # As per the above, check whether we have a loaders.cache file
324         # in $LIBPREFIX/lib/gdk-pixbuf-2.0/$gdk_pixbuf_version, as
325         # that's where the output of gdk-pixbuf-query-loaders gets
326         # put if gdk-pixbuf and GTK+ are separated.
327         #
328         # The file is ultimately copied to the user's home directory,
329         # with the pathnames adjusted to refer to the installed package,
330         # so we always put it in the same location in the installed
331         # package, regardless of where it lives in the machine on which
332         # it's built.
333         #
334         if [ -e $LIBPREFIX/lib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders.cache ]
335         then
336                 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/lib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders.cache > $pkgetc/gtk-2.0/gdk-pixbuf.loaders
337         fi
338         cp -r $LIBPREFIX/lib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders/* $pkglib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders
339 fi
340
341 # Find out libs we need from Fink, MacPorts, or from a custom install
342 # (i.e. $LIBPREFIX), then loop until no changes.
343 a=1
344 nfiles=0
345 endl=true
346 lib_dep_search_list="
347         $pkglib/gtk-2.0/$gtk_version/loaders/*
348         $pkglib/gtk-2.0/$gtk_version/immodules/*
349         $pkglib/gtk-2.0/$gtk_version/engines/*.so
350         $pkglib/pango/$pango_version/modules/*
351         $pkglib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders/*
352         $package/Contents/Resources/lib/*
353         $pkgbin/*-bin
354         "
355 while $endl; do
356         echo -e "Looking for dependencies. Round" $a
357         libs="`otool -L $lib_dep_search_list 2>/dev/null | fgrep compatibility | cut -d\( -f1 | grep $LIBPREFIX | sort | uniq`"
358         cp -vn $libs "$pkglib"
359         let "a+=1"
360         nnfiles=`ls "$pkglib" | wc -l`
361         if [ $nnfiles = $nfiles ]; then
362                 endl=false
363         else
364                 nfiles=$nnfiles
365         fi
366 done
367
368 # Add extra libraries of necessary
369 for libfile in $EXTRALIBS
370 do
371         cp -f $libfile "$pkglib"
372 done
373
374 # Strip libraries and executables if requested
375 #----------------------------------------------------------
376 if [ "$strip" = "true" ]; then
377         echo -e "\nStripping debugging symbols...\n"
378         chmod +w "$pkglib"/*.dylib
379         strip -x "$pkglib"/*.dylib
380         strip -ur "$binpath"
381 fi
382
383 # NOTE: This works for all the dylibs but causes GTK to crash at startup.
384 #                               Instead we leave them with their original install_names and set
385 #                               DYLD_LIBRARY_PATH within the app bundle before running Wireshark.
386 #
387 # fixlib () {
388 #               # Fix a given executable or library to be relocatable
389 #               if [ ! -d "$1" ]; then
390 #                       echo $1
391 #                       libs="`otool -L $1 | fgrep compatibility | cut -d\( -f1`"
392 #                       for lib in $libs; do
393 #                               echo "  $lib"
394 #                               base=`echo $lib | awk -F/ '{print $NF}'`
395 #                               first=`echo $lib | cut -d/ -f1-3`
396 #                               to=@executable_path/../lib/$base
397 #                               if [ $first != /usr/lib -a $first != /usr/X11R6 ]; then
398 #                                       /usr/bin/install_name_tool -change $lib $to $1
399 #                                       if [ "`echo $lib | fgrep libcrypto`" = "" ]; then
400 #                                               /usr/bin/install_name_tool -id $to ../lib/$base
401 #                                               for ll in $libs; do
402 #                                                       base=`echo $ll | awk -F/ '{print $NF}'`
403 #                                                       first=`echo $ll | cut -d/ -f1-3`
404 #                                                       to=@executable_path/../lib/$base
405 #                                                       if [ $first != /usr/lib -a $first != /usr/X11R6 -a "`echo $ll | fgrep libcrypto`" = "" ]; then
406 #                                                               /usr/bin/install_name_tool -change $ll $to ../lib/$base
407 #                                                       fi
408 #                                               done
409 #                                       fi
410 #                               fi
411 #                       done
412 #               fi
413 # }
414 #
415 # Fix package deps
416 #(cd "$package/Contents/MacOS/bin"
417 # for file in *; do
418 #                fixlib "$file"
419 # done
420 # cd ../lib
421 # for file in *; do
422 #                fixlib "$file"
423 # done)
424
425 exit 0