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 bundle 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 bundle
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"
67 # Location for libraries (macosx-setup.sh defaults to whatever the
68 # various support libraries use as their standard installation location,
69 # which is /usr/local)
70 if [ -z $LIBPREFIX ]; then
71 LIBPREFIX
="/usr/local"
76 #----------------------------------------------------------
80 Create an app bundle for OS X
83 $0 [-s] [-l /path/to/libraries] [-qt] -bp /path/to/wireshark/binaries -p /path/to/Info.plist
87 display this help message
89 strip the libraries and executables from debugging symbols
91 specify the path to the libraries Wireshark depends on
92 (typically /sw or /opt/local). By default it is
95 specify the path to the Wireshark binaries. By default it
98 specify the path to Info.plist. Info.plist can be found
99 in the base directory of the source code once configure
102 specify the root of the SDK to use
107 $0 -s -l /opt/local -bp ../../Build/bin -p Info.plist -sdkroot /Developer/SDKs/MacOSX10.5.sdk
112 # Parse command line arguments
113 #----------------------------------------------------------
130 wireshark_bin_name
="wireshark-qt"
139 echo "Invalid command line option: $1"
145 echo -e "\nCREATE WIRESHARK APP BUNDLE\n"
148 if [ ! -e "$LIBPREFIX" ]; then
149 echo "Cannot find the directory containing the libraries: $LIBPREFIX" >&2
153 for binary
in $wireshark_bin_name $binary_list ; do
154 if [ ! -x "$binary_path/$binary" ]; then
155 echo "Couldn't find $binary (or it's not executable)" >&2
160 if [ ! -f "$plist" ]; then
161 echo "Need plist file" >&2
166 # Handle some version specific details.
167 VERSION
=`/usr/bin/sw_vers | grep ProductVersion | cut -f2 -d'.'`
168 if [ "$VERSION" -ge "4" ]; then
169 # We're on Tiger (10.4) or later.
170 # XCode behaves a little differently in Tiger and later.
171 XCODEFLAGS
="-configuration Deployment"
172 SCRIPTEXECDIR
="ScriptExec/build/Deployment/ScriptExec.app/Contents/MacOS"
175 # Panther (10.3) or earlier.
176 XCODEFLAGS
="-buildstyle Deployment"
177 SCRIPTEXECDIR
="ScriptExec/build/ScriptExec.app/Contents/MacOS"
181 # Set the SDK root, if an SDK was specified.
182 # (-sdk is only supported by the xcodebuild in the version of the
183 # developer tools that came with Snow Leopard and later versions)
184 if [ ! -z "$sdkroot" ]
186 XCODEFLAGS
="$XCODEFLAGS SDKROOT=$sdkroot"
189 # Bundle always has the same name. Version information is stored in
190 # the Info.plist file which is filled in by the configure script.
191 bundle
="Wireshark.app"
193 # Remove a previously existing bundle if necessary
194 if [ -d $bundle ]; then
195 echo "Removing previous $bundle"
199 # Remove a previously existing utility directory if necessary
200 if [ -d "$util_dir" ]; then
201 echo "Removing $util_dir directory"
205 # Set the 'macosx' directory, usually the current directory.
210 #----------------------------------------------------------
211 pkgexec
="$bundle/Contents/MacOS"
212 pkgres
="$bundle/Contents/Resources"
214 if [ "$ui_toolkit" = "gtk" ] ; then
217 # Should pkglib be Contents/Frameworks instead?
218 #pkglib="$pkgres/lib"
219 pkglib
="$bundle/Contents/Frameworks"
220 pkgqtplugin
="$bundle/Contents/PlugIns"
221 pkgplugin
="$pkglib/wireshark/plugins"
222 pkgpython
="$pkglib/wireshark/python"
226 mkdir
-p "$pkgqtplugin"
227 mkdir
-p "$pkgplugin"
228 mkdir
-p "$pkgpython"
232 if [ "$ui_toolkit" = "qt" ] ; then
233 cp "$binary_path/$wireshark_bin_name" "$pkgexec/Wireshark"
235 # Build and add the launcher
236 #----------------------------------------------------------
238 # Build fails if CC happens to be set (to anything other than CompileC)
241 cd "$resdir/ScriptExec"
242 echo -e "Building launcher...\n"
243 xcodebuild
$XCODEFLAGS clean build
245 cp "$resdir/$SCRIPTEXECDIR/ScriptExec" "$pkgexec/Wireshark"
249 # Copy all files into the bundle
250 #----------------------------------------------------------
251 echo -e "\nFilling app bundle and utility directory...\n"
254 cp -v utility-launcher
"$cli_dir/wireshark"
256 # Wireshark executables
257 if [ "$ui_toolkit" = "gtk" ] ; then
258 for binary
in $binary_list wireshark
; do
259 # Copy the binary to its destination
260 dest_path
="$pkgbin/$binary-bin"
261 cs_binary_list
="$cs_binary_list $dest_path"
262 cp -v "$binary_path/$binary" "$dest_path"
263 # TODO Add a "$verbose" variable and command line switch, which sets wether these commands are verbose or not
265 if [ "$binary" != "wireshark" ] ; then
266 ln -sv .
/wireshark
"$pkgbin/$binary"
267 ln -sv .
/wireshark
"$cli_dir/$binary"
270 elif [ "$ui_toolkit" = "qt" ] ; then
271 for binary
in $binary_list ; do
272 # Copy the binary to its destination
273 cp -v "$binary_path/$binary" "$pkgexec"
274 cs_binary_list
="$cs_binary_list $pkgexec/$binary"
279 mkdir
-p "$chmodbpf_dir"
280 cp -v ChmodBPF
/* "$chmodbpf_dir"
281 chmod -R g-w
"$chmodbpf_dir"
283 # The rest of the Wireshark installation (we handled bin above)
287 "$binary_path/.."/* "$pkgres"
289 rsync
-av $binary_path/..
/lib
/*.dylib
"$pkglib/"
291 # Remove the version number from the plugin path
292 find "$binary_path/../lib/wireshark/plugins" -type f \
293 -exec cp -fv "{}" "$pkgplugin/" \
;
295 # Remove the version number from the python path
296 find "$binary_path/../lib/wireshark/python" -type f \
297 -exec cp -fv "{}" "$pkgpython/" \
;
299 cp "$plist" "$bundle/Contents/Info.plist"
301 # Icons and the rest of the script framework
307 if [ "$ui_toolkit" = "gtk" ] ; then
320 for rl_entry
in $res_list ; do
321 rsync
-av "$resdir"/Resources
/$rl_entry "$bundle"/Contents
/Resources
/
324 # PkgInfo must match bundle type and creator code from Info.plist
325 echo "APPLWshk" > $bundle/Contents
/PkgInfo
327 if [ "$ui_toolkit" = "gtk" ] ; then
329 # Pull in extra requirements for Pango and GTK
330 pkgetc
="$bundle/Contents/Resources/etc"
331 mkdir
-p $pkgetc/pango
332 cp $LIBPREFIX/etc
/pango
/pangox.aliases
$pkgetc/pango
/
333 # Need to adjust path and quote in case of spaces in path.
334 sed -e "s,$LIBPREFIX,\"\${CWD},g" -e 's,\.so ,.so" ,g' $LIBPREFIX/etc
/pango
/pango.modules
> $pkgetc/pango
/pango.modules
335 cat > $pkgetc/pango
/pangorc
<<END_PANGO
337 ModuleFiles=\${HOME}/.wireshark-etc/pango.modules
339 AliasFiles=\${HOME}/.wireshark-etc/pangox.aliases
342 # We use a modified fonts.conf file so only need the dtd
343 mkdir
-p $pkgetc/fonts
344 cp $LIBPREFIX/etc
/fonts
/fonts.dtd
$pkgetc/fonts
/
345 cp -r $LIBPREFIX/etc
/fonts
/conf.avail
$pkgetc/fonts
/
346 cp -r $LIBPREFIX/etc
/fonts
/conf.d
$pkgetc/fonts
/
348 mkdir
-p $pkgetc/gtk-2.0
350 # In newer versions of GTK+, the gdk-pixbuf library was split off from
351 # GTK+, and the gdk-pixbuf.loaders file moved, so we check for its
354 # The file is ultimately copied to the user's home directory, with
355 # the pathnames adjusted to refer to the installed bundle, so we
356 # always put it in the same location in the installed bundle,
357 # regardless of where it lives in the machine on which it's built.
359 if [ -e $LIBPREFIX/etc
/gtk-2.0
/gdk-pixbuf.loaders
]
361 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/etc
/gtk-2.0
/gdk-pixbuf.loaders
> $pkgetc/gtk-2.0
/gdk-pixbuf.loaders
363 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/etc
/gtk-2.0
/gtk.immodules
> $pkgetc/gtk-2.0
/gtk.immodules
365 pango_version
=`pkg-config --variable=pango_module_version pango`
366 mkdir
-p $pkglib/pango
/$pango_version/modules
367 cp $LIBPREFIX/lib
/pango
/$pango_version/modules
/*.so
$pkglib/pango
/$pango_version/modules
/
369 gtk_version
=`pkg-config --variable=gtk_binary_version gtk+-2.0`
370 mkdir
-p $pkglib/gtk-2.0
/$gtk_version/{engines
,immodules
,loaders
}
371 cp -r $LIBPREFIX/lib
/gtk-2.0
/$gtk_version/* $pkglib/gtk-2.0
/$gtk_version/
373 gdk_pixbuf_version
=`pkg-config --variable=gdk_pixbuf_binary_version gdk-pixbuf-2.0`
374 if [ ! -z $gdk_pixbuf_version ]; then
375 mkdir
-p $pkglib/gdk-pixbuf-2.0
/$gdk_pixbuf_version/loaders
377 # As per the above, check whether we have a loaders.cache file
378 # in $LIBPREFIX/lib/gdk-pixbuf-2.0/$gdk_pixbuf_version, as
379 # that's where the output of gdk-pixbuf-query-loaders gets
380 # put if gdk-pixbuf and GTK+ are separated.
382 # The file is ultimately copied to the user's home directory,
383 # with the pathnames adjusted to refer to the installed bundle,
384 # so we always put it in the same location in the installed
385 # bundle, regardless of where it lives in the machine on which
388 if [ -e $LIBPREFIX/lib
/gdk-pixbuf-2.0
/$gdk_pixbuf_version/loaders.cache
]
390 sed -e "s,$LIBPREFIX,\${CWD},g" $LIBPREFIX/lib
/gdk-pixbuf-2.0
/$gdk_pixbuf_version/loaders.cache
> $pkgetc/gtk-2.0
/gdk-pixbuf.loaders
392 cp -r $LIBPREFIX/lib
/gdk-pixbuf-2.0
/$gdk_pixbuf_version/loaders
/* $pkglib/gdk-pixbuf-2.0
/$gdk_pixbuf_version/loaders
396 # Find out libs we need from Fink, MacPorts, or from a custom install
397 # (i.e. $LIBPREFIX), then loop until no changes.
401 lib_dep_search_list
="
405 if [ "$ui_toolkit" = "gtk" ] ; then
406 lib_dep_search_list
="
408 $pkglib/gtk-2.0/$gtk_version/loaders/*
409 $pkglib/gtk-2.0/$gtk_version/immodules/*
410 $pkglib/gtk-2.0/$gtk_version/engines/*.so
411 $pkglib/pango/$pango_version/modules/*
412 $pkglib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders/*
414 elif [ "$ui_toolkit" = "qt" ] ; then
415 lib_dep_search_list
="
422 echo -e "Looking for dependencies. Round" $a
424 otool -L $lib_dep_search_list 2>/dev/null \
425 | fgrep compatibility \
427 | egrep -v "$exclude_prefixes" \
431 cp -vn $libs "$pkglib"
433 nnfiles
=`ls "$pkglib" | wc -l`
434 if [ $nnfiles = $nfiles ]; then
441 # Add extra libraries of necessary
442 for libfile
in $EXTRALIBS
444 cp -f $libfile "$pkglib"
446 chmod 755 "$pkglib"/*.dylib
448 # Strip libraries and executables if requested
449 #----------------------------------------------------------
450 if [ "$strip" = "true" ]; then
451 echo -e "\nStripping debugging symbols...\n"
452 strip
-x "$pkglib"/*.dylib
456 # NOTE: we must rpathify *all* files, *including* plugins for GTK+ etc.,
457 # to keep GTK+ from crashing at startup.
460 # Fix a given executable, library, or plugin to be relocatable
461 if [ ! -d "$1" ]; then
463 # OK, what type of file is this?
465 filetype
=`otool -hv "$1" | sed -n '4p' | awk '{print $5}'`
468 EXECUTE|DYLIB|BUNDLE
)
470 # Executable, library, or plugin. (Plugins
471 # can be either DYLIB or BUNDLE; shared
472 # libraries are DYLIB.)
474 # For DYLIB and BUNDLE, fix the shared
475 # library identification.
477 if [[ "$filetype" = "DYLIB" ||
"$filetype" = "BUNDLE" ]]; then
478 echo "Changing shared library identification of $1"
479 base
=`echo $1 | awk -F/ '{print $NF}'`
481 # The library will end up in a directory in
482 # the rpath; this is what we should change its
486 /usr
/bin
/install_name_tool
-id $to $1
490 # Show the minimum supported version of Mac OS X
491 # for each executable or library
493 if [[ "$filetype" = "EXECUTE" ||
"$filetype" = "DYLIB" ]] && [[ "$VERSION" -ge "7" ]] ; then
494 echo "Minimum Mac OS X version for $1:"
495 otool
-l $1 |
grep -A3 LC_VERSION_MIN_MACOSX
499 # Get the list of dynamic libraries on which this
500 # file depends, and select only the libraries that
501 # are in $LIBPREFIX, as those are the only ones
502 # that we'll be shipping in the app bundle; the
503 # other libraries are system-supplied or supplied
504 # as part of X11, will be expected to be on the
505 # system on which the bundle will be installed,
506 # and should be referred to by their full pathnames.
510 | fgrep compatibility \
512 | egrep -v "$exclude_prefixes" \
519 # Get the file name of the library.
521 base
=`echo $lib | awk -F/ '{print $NF}'`
523 # The library will end up in a directory in
524 # the rpath; this is what we should change its
529 # Change the reference to that library.
531 echo "Changing reference to $lib to $to in $1"
532 /usr
/bin
/install_name_tool
-change $lib $to $1
541 # Make sure we *have* that directory
546 # Make sure we *have* files to fix
548 files
=`ls $2 2>/dev/null`
549 if [ ! -z "$files" ]; then
550 for file in $files; do
551 rpathify_file
"$file" "`pwd`"
562 rpathify_dir
"$pkglib" "*.dylib"
563 if [ "$ui_toolkit" = "gtk" ] ; then
564 rpathify_dir
"$pkglib/gtk-2.0/$gtk_version/loaders" "*.so"
565 rpathify_dir
"$pkglib/gtk-2.0/$gtk_version/engines" "*.so"
566 rpathify_dir
"$pkglib/gtk-2.0/$gtk_version/immodules" "*.so"
567 rpathify_dir
"$pkglib/gtk-2.0/$gtk_version/printbackends" "*.so"
568 rpathify_dir
"$pkglib/gnome-vfs-2.0/modules" "*.so"
569 rpathify_dir
"$pkglib/gdk-pixbuf-2.0/$gtk_version/loaders" "*.so"
570 rpathify_dir
"$pkglib/pango/$pango_version/modules" "*.so"
572 rpathify_dir
"$pkgbin" "*"
575 if [ "$ui_toolkit" = "qt" ] ; then
576 macdeployqt
"$bundle" -verbose=2 ||
exit 1
579 PATHLENGTH
=`echo $LIBPREFIX | wc -c`
580 if [ "$PATHLENGTH" -ge "6" ]; then
581 # If the LIBPREFIX path is long enough to allow
582 # path rewriting, then do this.
583 # 6 is the length of @rpath, which replaces LIBPREFIX.
586 echo "Could not rewrite dylib paths for bundled libraries. This requires" >&2
587 echo "the support libraries to be installed in a PREFIX of at least 6 characters in length." >&2
589 echo "The bundle will still work if the following line is uncommented in" >&2
590 echo "Wireshark.app/Contents/Resources/bin/{various scripts}:" >&2
591 echo ' export DYLD_LIBRARY_PATH="$TOP/lib"' >&2
597 codesign
--sign "Developer ID Application: $CODE_SIGN_IDENTITY" --verbose "$1"
598 codesign
--verify --verbose "$1" ||
exit 1
599 spctl
--assess --type execute
"$1" ||
exit 1
602 if [ -n "$CODE_SIGN_IDENTITY" ] ; then
603 security find-identity
-v -s "$CODE_SIGN_IDENTITY" -p codesigning
605 echo "Signing executables"
606 for binary
in $cs_binary_list ; do
607 codesign_file
"$binary"
609 echo "Signing frameworks"
610 for framework
in $pkglib/*.framework
/Versions
/*/* ; do
611 codesign_file
"$framework"
613 echo "Signing libraries"
614 for library
in $pkglib/*.dylib
; do
615 codesign_file
"$library"
617 echo "Signing plugins"
618 for plugin
in $pkgplugin/*.so
; do
619 codesign_file
"$plugin"
621 echo "Signing $bundle"
622 codesign_file
"$bundle"
624 echo "Code signing not performed (no identity)"