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