6 # osx-app [-s] [-l /path/to/libraries] -bp /path/to/wireshark/bin -p /path/to/Info.plist
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.
16 # Kees Cook <kees@outflux.net>
17 # Michael Wybrow <mjwybrow@users.sourceforge.net>
18 # Jean-Olivier Irisson <jo.irisson@gmail.com>
20 # Copyright (C) 2005 Kees Cook
21 # Copyright (C) 2005-2007 Michael Wybrow
22 # Copyright (C) 2007 Jean-Olivier Irisson
24 # Released under GNU GPL, read the file 'COPYING' for more information
26 # Thanks to GNUnet's "build_app" script for help with library dep resolution.
27 # https://gnunet.org/svn/GNUnet/contrib/OSX/build_app
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.
41 binary_path="/tmp/inst/bin"
43 util_dir="./Utilities"
44 cli_dir="$util_dir/Command Line"
45 chmodbpf_dir="$util_dir/ChmodBPF"
46 exclude_prefixes="/System/|/Library/|/usr/lib/|/usr/X11/|/opt/X11/|@rpath|@executable_path"
51 # Name of the Wireshark executable
52 wireshark_bin_name="wireshark"
66 # Location for libraries (macosx-setup.sh defaults to whatever the
67 # various support libraries use as their standard installation location,
68 # which is /usr/local)
69 if [ -z $LIBPREFIX ]; then
70 LIBPREFIX="/usr/local"
75 #----------------------------------------------------------
79 Create an app bundle for OS X
82 $0 [-s] [-l /path/to/libraries] [-qt] -bp /path/to/wireshark/binaries -p /path/to/Info.plist
86 display this help message
88 strip the libraries and executables from debugging symbols
90 specify the path to the libraries Wireshark depends on
91 (typically /sw or /opt/local). By default it is
94 specify the path to the Wireshark binaries. By default it
97 specify the path to Info.plist. Info.plist can be found
98 in the base directory of the source code once configure
101 specify the root of the SDK to use
106 $0 -s -l /opt/local -bp ../../Build/bin -p Info.plist -sdkroot /Developer/SDKs/MacOSX10.5.sdk
111 # Parse command line arguments
112 #----------------------------------------------------------
129 wireshark_bin_name="wireshark-qt"
138 echo "Invalid command line option: $1"
144 echo -e "\nCREATE WIRESHARK APP BUNDLE\n"
147 if [ ! -e "$LIBPREFIX" ]; then
148 echo "Cannot find the directory containing the libraries: $LIBPREFIX" >&2
152 for binary in $wireshark_bin_name $binary_list ; do
153 if [ ! -x "$binary_path/$binary" ]; then
154 echo "Couldn't find $binary (or it's not executable)" >&2
159 if [ ! -f "$plist" ]; then
160 echo "Need plist file" >&2
165 # Handle some version specific details.
166 VERSION=`/usr/bin/sw_vers | grep ProductVersion | cut -f2 -d'.'`
167 if [ "$VERSION" -ge "4" ]; then
168 # We're on Tiger (10.4) or later.
169 # XCode behaves a little differently in Tiger and later.
170 XCODEFLAGS="-configuration Deployment"
171 SCRIPTEXECDIR="ScriptExec/build/Deployment/ScriptExec.app/Contents/MacOS"
174 # Panther (10.3) or earlier.
175 XCODEFLAGS="-buildstyle Deployment"
176 SCRIPTEXECDIR="ScriptExec/build/ScriptExec.app/Contents/MacOS"
180 # Set the SDK root, if an SDK was specified.
181 # (-sdk is only supported by the xcodebuild in the version of the
182 # developer tools that came with Snow Leopard and later versions)
183 if [ ! -z "$sdkroot" ]
185 XCODEFLAGS="$XCODEFLAGS SDKROOT=$sdkroot"
188 # Package always has the same name. Version information is stored in
189 # the Info.plist file which is filled in by the configure script.
190 package="Wireshark.app"
192 # Remove a previously existing package if necessary
193 if [ -d $package ]; then
194 echo "Removing previous Wireshark.app"
198 # Remove a previously existing utility directory if necessary
199 if [ -d "$util_dir" ]; then
200 echo "Removing $util_dir directory"
204 # Set the 'macosx' directory, usually the current directory.
209 #----------------------------------------------------------
210 pkgexec="$package/Contents/MacOS"
211 pkgres="$package/Contents/Resources"
213 if [ "$ui_toolkit" = "gtk" ] ; then
216 # Should pkglib be Contents/Frameworks instead?
217 #pkglib="$pkgres/lib"
218 pkglib="$package/Contents/Frameworks"
219 pkgqtplugin="$package/Contents/PlugIns"
220 pkgplugin="$pkglib/wireshark/plugins"
221 pkgpython="$pkglib/wireshark/python"
225 mkdir -p "$pkgqtplugin"
226 mkdir -p "$pkgplugin"
227 mkdir -p "$pkgpython"
231 if [ "$ui_toolkit" = "qt" ] ; then
232 cp "$binary_path/$wireshark_bin_name" "$pkgexec/Wireshark"
234 # Build and add the launcher
235 #----------------------------------------------------------
237 # Build fails if CC happens to be set (to anything other than CompileC)
240 cd "$resdir/ScriptExec"
241 echo -e "Building launcher...\n"
242 xcodebuild $XCODEFLAGS clean build
244 cp "$resdir/$SCRIPTEXECDIR/ScriptExec" "$pkgexec/Wireshark"
248 # Copy all files into the bundle
249 #----------------------------------------------------------
250 echo -e "\nFilling app bundle and utility directory...\n"
252 # Wireshark executables
253 if [ "$ui_toolkit" = "gtk" ] ; then
254 cp -v utility-launcher "$cli_dir/$binary"
255 for binary in $binary_list wireshark ; do
256 # Copy the binary to its destination
257 dest_path="$pkgbin/$binary-bin"
258 cp -v "$binary_path/$binary" "$dest_path"
259 # TODO Add a "$verbose" variable and command line switch, which sets wether these commands are verbose or not
261 if [ "$binary" != "wireshark" ] ; then
262 ln -sv ./wireshark "$pkgbin/$binary"
263 ln -sv ./wireshark "$cli_dir/$binary"
266 elif [ "$ui_toolkit" = "qt" ] ; then
267 for binary in $binary_list ; do
268 # Copy the binary to its destination
269 cp -v "$binary_path/$binary" "$pkgexec"
274 mkdir -p "$chmodbpf_dir"
275 cp -v ChmodBPF/* "$chmodbpf_dir"
276 chmod -R g-w "$chmodbpf_dir"
278 # The rest of the Wireshark installation (we handled bin above)
282 "$binary_path/.."/* "$pkgres"
284 rsync -av $binary_path/../lib/*.dylib "$pkglib/"
286 # Remove the version number from the plugin path
287 find "$binary_path/../lib/wireshark/plugins" -type f \
288 -exec cp -fv "{}" "$pkgplugin/" \;
290 # Remove the version number from the python path
291 find "$binary_path/../lib/wireshark/python" -type f \
292 -exec cp -fv "{}" "$pkgpython/" \;
294 cp "$plist" "$package/Contents/Info.plist"
296 # Icons and the rest of the script framework
302 if [ "$ui_toolkit" = "gtk" ] ; then
315 for rl_entry in $res_list ; do
316 rsync -av "$resdir"/Resources/$rl_entry "$package"/Contents/Resources/
319 # PkgInfo must match bundle type and creator code from Info.plist
320 echo "APPLWshk" > $package/Contents/PkgInfo
322 if [ "$ui_toolkit" = "gtk" ] ; then
324 # Pull in extra requirements for Pango and GTK
325 pkgetc="$package/Contents/Resources/etc"
326 mkdir -p $pkgetc/pango
327 cp $LIBPREFIX/etc/pango/pangox.aliases $pkgetc/pango/
328 # Need to adjust path and quote in case of spaces in path.
329 sed -e "s,$LIBPREFIX,\"\${CWD},g" -e 's,\.so ,.so" ,g' $LIBPREFIX/etc/pango/pango.modules > $pkgetc/pango/pango.modules
330 cat > $pkgetc/pango/pangorc <<END_PANGO
332 ModuleFiles=\${HOME}/.wireshark-etc/pango.modules
334 AliasFiles=\${HOME}/.wireshark-etc/pangox.aliases
337 # We use a modified fonts.conf file so only need the dtd
338 mkdir -p $pkgetc/fonts
339 cp $LIBPREFIX/etc/fonts/fonts.dtd $pkgetc/fonts/
340 cp -r $LIBPREFIX/etc/fonts/conf.avail $pkgetc/fonts/
341 cp -r $LIBPREFIX/etc/fonts/conf.d $pkgetc/fonts/
343 mkdir -p $pkgetc/gtk-2.0
345 # In newer versions of GTK+, the gdk-pixbuf library was split off from
346 # GTK+, and the gdk-pixbuf.loaders file moved, so we check for its
349 # The file is ultimately copied to the user's home directory, with
350 # the pathnames adjusted to refer to the installed package, so we
351 # always put it in the same location in the installed package,
352 # regardless of where it lives in the machine on which it's built.
354 if [ -e $LIBPREFIX/etc/gtk-2.0/gdk-pixbuf.loaders ]
356 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/etc/gtk-2.0/gdk-pixbuf.loaders > $pkgetc/gtk-2.0/gdk-pixbuf.loaders
358 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/etc/gtk-2.0/gtk.immodules > $pkgetc/gtk-2.0/gtk.immodules
360 pango_version=`pkg-config --variable=pango_module_version pango`
361 mkdir -p $pkglib/pango/$pango_version/modules
362 cp $LIBPREFIX/lib/pango/$pango_version/modules/*.so $pkglib/pango/$pango_version/modules/
364 gtk_version=`pkg-config --variable=gtk_binary_version gtk+-2.0`
365 mkdir -p $pkglib/gtk-2.0/$gtk_version/{engines,immodules,loaders}
366 cp -r $LIBPREFIX/lib/gtk-2.0/$gtk_version/* $pkglib/gtk-2.0/$gtk_version/
368 gdk_pixbuf_version=`pkg-config --variable=gdk_pixbuf_binary_version gdk-pixbuf-2.0`
369 if [ ! -z $gdk_pixbuf_version ]; then
370 mkdir -p $pkglib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders
372 # As per the above, check whether we have a loaders.cache file
373 # in $LIBPREFIX/lib/gdk-pixbuf-2.0/$gdk_pixbuf_version, as
374 # that's where the output of gdk-pixbuf-query-loaders gets
375 # put if gdk-pixbuf and GTK+ are separated.
377 # The file is ultimately copied to the user's home directory,
378 # with the pathnames adjusted to refer to the installed package,
379 # so we always put it in the same location in the installed
380 # package, regardless of where it lives in the machine on which
383 if [ -e $LIBPREFIX/lib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders.cache ]
385 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/lib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders.cache > $pkgetc/gtk-2.0/gdk-pixbuf.loaders
387 cp -r $LIBPREFIX/lib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders/* $pkglib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders
391 # Find out libs we need from Fink, MacPorts, or from a custom install
392 # (i.e. $LIBPREFIX), then loop until no changes.
396 lib_dep_search_list="
400 if [ "$ui_toolkit" = "gtk" ] ; then
401 lib_dep_search_list="
403 $pkglib/gtk-2.0/$gtk_version/loaders/*
404 $pkglib/gtk-2.0/$gtk_version/immodules/*
405 $pkglib/gtk-2.0/$gtk_version/engines/*.so
406 $pkglib/pango/$pango_version/modules/*
407 $pkglib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders/*
409 elif [ "$ui_toolkit" = "qt" ] ; then
410 lib_dep_search_list="
417 echo -e "Looking for dependencies. Round" $a
419 otool -L $lib_dep_search_list 2>/dev/null \
420 | fgrep compatibility \
422 | egrep -v "$exclude_prefixes" \
426 cp -vn $libs "$pkglib"
428 nnfiles=`ls "$pkglib" | wc -l`
429 if [ $nnfiles = $nfiles ]; then
436 # Add extra libraries of necessary
437 for libfile in $EXTRALIBS
439 cp -f $libfile "$pkglib"
441 chmod 755 "$pkglib"/*.dylib
443 # Strip libraries and executables if requested
444 #----------------------------------------------------------
445 if [ "$strip" = "true" ]; then
446 echo -e "\nStripping debugging symbols...\n"
447 strip -x "$pkglib"/*.dylib
451 # NOTE: we must rpathify *all* files, *including* plugins for GTK+ etc.,
452 # to keep GTK+ from crashing at startup.
455 # Fix a given executable, library, or plugin to be relocatable
456 if [ ! -d "$1" ]; then
458 # OK, what type of file is this?
460 filetype=`otool -hv "$1" | sed -n '4p' | awk '{print $5}'`
463 EXECUTE|DYLIB|BUNDLE)
465 # Executable, library, or plugin. (Plugins
466 # can be either DYLIB or BUNDLE; shared
467 # libraries are DYLIB.)
469 # For DYLIB and BUNDLE, fix the shared
470 # library identification.
472 if [[ "$filetype" = "DYLIB" || "$filetype" = "BUNDLE" ]]; then
473 echo "Changing shared library identification of $1"
474 base=`echo $1 | awk -F/ '{print $NF}'`
476 # The library will end up in a directory in
477 # the rpath; this is what we should change its
481 /usr/bin/install_name_tool -id $to $1
485 # Get the list of dynamic libraries on which this
486 # file depends, and select only the libraries that
487 # are in $LIBPREFIX, as those are the only ones
488 # that we'll be shipping in the app bundle; the
489 # other libraries are system-supplied or supplied
490 # as part of X11, will be expected to be on the
491 # system on which the bundle will be installed,
492 # and should be referred to by their full pathnames.
496 | fgrep compatibility \
498 | egrep -v "$exclude_prefixes" \
505 # Get the file name of the library.
507 base=`echo $lib | awk -F/ '{print $NF}'`
509 # The library will end up in a directory in
510 # the rpath; this is what we should change its
515 # Change the reference to that library.
517 echo "Changing reference to $lib to $to in $1"
518 /usr/bin/install_name_tool -change $lib $to $1
527 # Make sure we *have* that directory
532 # Make sure we *have* files to fix
534 files=`ls $2 2>/dev/null`
535 if [ ! -z "$files" ]; then
536 for file in $files; do
537 rpathify_file "$file" "`pwd`"
548 rpathify_dir "$pkglib" "*.dylib"
549 if [ "$ui_toolkit" = "gtk" ] ; then
550 rpathify_dir "$pkglib/gtk-2.0/$gtk_version/loaders" "*.so"
551 rpathify_dir "$pkglib/gtk-2.0/$gtk_version/engines" "*.so"
552 rpathify_dir "$pkglib/gtk-2.0/$gtk_version/immodules" "*.so"
553 rpathify_dir "$pkglib/gtk-2.0/$gtk_version/printbackends" "*.so"
554 rpathify_dir "$pkglib/gnome-vfs-2.0/modules" "*.so"
555 rpathify_dir "$pkglib/gdk-pixbuf-2.0/$gtk_version/loaders" "*.so"
556 rpathify_dir "$pkglib/pango/$pango_version/modules" "*.so"
558 rpathify_dir "$pkgbin" "*"
561 if [ "$ui_toolkit" = "qt" ] ; then
562 macdeployqt "$package" -verbose=2
565 PATHLENGTH=`echo $LIBPREFIX | wc -c`
566 if [ "$PATHLENGTH" -ge "6" ]; then
567 # If the LIBPREFIX path is long enough to allow
568 # path rewriting, then do this.
569 # 6 is the length of @rpath, which replaces LIBPREFIX.
572 echo "Could not rewrite dylib paths for bundled libraries. This requires" >&2
573 echo "the support libraries to be installed in a PREFIX of at least 6 characters in length." >&2
575 echo "The package will still work if the following line is uncommented in" >&2
576 echo "Wireshark.app/Contents/Resources/bin/{various scripts}:" >&2
577 echo ' export DYLD_LIBRARY_PATH="$TOP/lib"' >&2