#
# USAGE
# osx-app [-s] [-l /path/to/libraries] -py /path/to/python/modules [-l /path/to/libraries] -b /path/to/bin/inkscape -p /path/to/Info.plist
#
# This script attempts to build an Inkscape.app package for OS X, resolving
# dynamic libraries, etc.
#
# If the '-s' option is given, then the libraries and executable are stripped.
#
# The Info.plist file can be found in the base inkscape directory once
# configure has been run.
#
# AUTHORS
# Kees Cook <kees@outflux.net>
# Michael Wybrow <mjwybrow@users.sourceforge.net>
# Jean-Olivier Irisson <jo.irisson@gmail.com>
# Liam P. White <inkscapebrony@gmail.com>
# ~suv <suv-sf@users.sourceforge.net>
#
# Copyright (C) 2005 Kees Cook
# Copyright (C) 2005-2009 Michael Wybrow
# Copyright (C) 2007-2009 Jean-Olivier Irisson
# Copyright (C) 2014 Liam P. White
# Copyright (C) 2014 ~suv
#
# Released under GNU GPL, read the file 'COPYING' for more information
#
# Thanks to GNUnet's "build_app" script for help with library dep resolution.
#
# NB:
# When packaging Inkscape for OS X, configure should be run with the
# "--enable-osxapp" option which sets the correct paths for support
# files inside the app bundle.
#
# Defaults
strip_build=false
add_wrapper=true
add_python=true
python_dir=""
# 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)
if [ -z $LIBPREFIX ]; then
LIBPREFIX=""
fi
# Help message
#----------------------------------------------------------
{
echo -e "
Create an app bundle for OS X
\033[1mUSAGE\033[0m
$0 [-s] [-l /path/to/libraries] -py /path/to/python/modules -b /path/to/bin/inkscape -p /path/to/Info.plist
\033[1mOPTIONS\033[0m
\033[1m-h,--help\033[0m
display this help message
\033[1m-s\033[0m
strip the libraries and executables from debugging symbols
\033[1m-py,--with-python\033[0m
add python modules (numpy, lxml) from given directory
inside the app bundle
\033[1m-l,--libraries\033[0m
specify the path to the librairies Inkscape depends on
\033[1m-b,--binary\033[0m
specify the path to Inkscape's binary. By default it is in
\033[1m-p,--plist\033[0m
specify the path to Info.plist. Info.plist can be found
in the base directory of the source code once configure
has been run
\033[1m-v,--verbose\033[0m
Verbose mode.
\033[1mEXAMPLE\033[0m
"
}
# Parse command line arguments
#----------------------------------------------------------
while [ "$1" != "" ]
do
case $1 in
add_python=true
python_dir="$2"
shift 1 ;;
-s)
strip_build=true
with_dSYM=false ;;
-l|--libraries)
LIBPREFIX="$2"
shift 1 ;;
-b|--binary)
binary="$2"
shift 1 ;;
-p|--plist)
plist="$2"
shift 1 ;;
-v|--verbose)
verbose_mode=true ;;
-h|--help)
exit 0 ;;
*)
echo "Invalid command line option: $1"
exit 2 ;;
esac
shift 1
done
echo -e "\n\033[1mCREATE INKSCAPE APP BUNDLE\033[0m\n"
# Safety tests
#----------------------------------------------------------
if [ "x$binary" == "x" ]; then
echo "Inkscape binary path not specified." >&2
exit 1
fi
if [ ! -x "$binary" ]; then
echo "Inkscape executable not not found at $binary." >&2
exit 1
fi
if [ "x$plist" == "x" ]; then
echo "Info.plist file not specified." >&2
exit 1
fi
if [ ! -f "$plist" ]; then
echo "Info.plist file not found at $plist." >&2
exit 1
fi
if [ ${add_python} = "true" ]; then
if [ -z "$python_dir" ]; then
echo "Python modules will be copied from MacPorts tree." >&2
else
if [ ! -e "$python_dir" ]; then
exit 1
else
if [ -e "$python_dir/i386" -o -e "$python_dir/ppc" ]; then
echo "Outdated structure in custom python modules detected," >&2
echo "not compatible with current packaging." >&2
exit 1
else
echo "Python modules will be copied from $python_dir." >&2
fi
fi
fi
fi
if [ ! -e "$LIBPREFIX" ]; then
echo "Cannot find the directory containing the libraires: $LIBPREFIX" >&2
exit 1
fi
echo "Missing GTK+ backend -- please install gtk2 and its dependencies with variant '+quartz' and try again." >&2
exit 1
fi
_backend="quartz"
else
echo "Missing GTK+ backend -- please install gtk2 and its dependencies with variant '+x11' and try again." >&2
exit 1
fi
_backend="x11"
fi
echo "Missing gtk-engines2 -- please install gtk-engines2 and try again." >&2
exit 1
fi
if [ ! -e "$LIBPREFIX/lib/gtk-2.0/$(pkg-config --variable=gtk_binary_version gtk+-2.0)/engines/libmurrine.so" ]; then
echo "Missing gtk2-murrine -- please install gtk2-murrine and try again." >&2
exit 1
fi
if [ ! -e "$LIBPREFIX/lib/gtk-2.0/$(pkg-config --variable=gtk_binary_version gtk+-2.0)/engines/libadwaita.so" ]; then
echo "Missing gnome-themes-standard -- please install gnome-themes-standard and try again." >&2
exit 1
fi
if [ ! -e "$LIBPREFIX/share/icons/hicolor/index.theme" ]; then
echo "Missing hicolor-icon-theme -- please install hicolor-icon-theme and try again." >&2
exit 1
fi
echo "Missing icon-naming-utils -- please install icon-naming-utils and try again." >&2
exit 1
fi
# if [ "$default_theme" != "default" ] ; then
# if ! pkg-config --exists gnome-icon-theme; then
# echo "Missing gnome-icon-theme -- please install gnome-icon-theme and try again." >&2
# exit 1
# fi
#
# if ! pkg-config --exists gnome-icon-theme-symbolic; then
# echo "Missing gnome-icon-theme-symbolic -- please install gnome-icon-theme-symbolic and try again." >&2
# exit 1
# fi
# fi
unset WITH_GNOME_VFS
echo "Missing gnome-vfs2 -- some features will be disabled" >&2
else
WITH_GNOME_VFS=true
fi
# unset WITH_DBUS
# if ! pkg-config --exists dbus-1; then
# echo "Missing dbus -- some features will be disabled" >&2
# else
# WITH_DBUS=true
# fi
#
# unset WITH_GVFS
# echo "Missing gvfs -- some features will be disabled" >&2
# elif [ ! -z "$WITH_DBUS" ]; then
# WITH_GVFS=true
# else
# echo "Missing dbus for gvfs -- some features will be disabled" >&2
# fi
echo "Missing poppler -- please install poppler and try again." >&2
exit 1
fi
if [ ! -e "$LIBPREFIX/lib/libpotrace.dylib" ]; then
echo "Missing potrace -- please install potrace and try again." >&2
exit 1
fi
echo "Missing ImageMagick -- please install ImageMagick and try again." >&2
exit 1
fi
# FIXME: retrieve aspell version from installed files (no pkg-config support)
ASPELL_VERSION="0.60"
if [ ! -e "$LIBPREFIX/lib/aspell-$ASPELL_VERSION/en.dat" ]; then
echo "Missing aspell en dictionary -- please install at least 'aspell-dict-en', but" >&2
echo "preferably more dictionaries ('aspell-dict-*') and try again." >&2
exit 1
fi
# awk on Leopard fails in fixlib(), test earlier and require gawk if test fails
if [ -z "$awk_test" ]; then
if [ ! -x "$LIBPREFIX/bin/gawk" ]; then
echo "awk provided by system is too old, please install gawk and try again" >&2
exit 1
else
fi
else
awk_cmd="awk"
fi
unset awk_test
# OS X version
#----------------------------------------------------------
# guess default build_arch (MacPorts)
_build_arch="x86_64"
else
_build_arch="i386"
fi
else
if [ $ARCH = "powerpc" ]; then
_build_arch="ppc"
else
_build_arch="i386"
fi
fi
# Setup
#----------------------------------------------------------
x11)
echo "Building package with GTK+/X11." >&2
# Handle some version specific details.
echo "Note: Inkscape packaging requires Mac OS X 10.5 Leopard or later."
exit 1
else # if [ "$OSXMINORNO" -ge "5" ]; then
XCODEFLAGS="-configuration Deployment"
EXTRALIBS=""
fi
;;
# quartz backend
echo "Building package with GTK+/Quartz." >&2
;;
*)
exit 1
esac
# Package always has the same name. Version information is stored in
# the Info.plist file which is filled in by the configure script.
# Remove a previously existing package if necessary
if [ -d $package ]; then
echo "Removing previous Inkscape.app"
fi
# Set the 'macosx' directory, usually the current directory.
resdir=`pwd`
# Custom resources used to generate resources during app bundle creation.
if [ -z "$custom_res" ] ; then
custom_res="${resdir}/Resources-extras"
fi
# Prepare Package
#----------------------------------------------------------
mkdir -p "$pkglocale"
# utility
#----------------------------------------------------------
if [ $verbose_mode ] ; then
else
fi
# Build and add the launcher
#----------------------------------------------------------
x11)
(
# Build fails if CC happens to be set (to anything other than CompileC)
unset CC
cd "$resdir/ScriptExec"
echo -e "\033[1mBuilding launcher...\033[0m\n"
)
$cp_cmd "$resdir/$SCRIPTEXECDIR/ScriptExec" "$pkgexec/Inkscape"
;;
$cp_cmd "$resdir/ScriptExec/launcher-quartz-no-macintegration.sh" "$pkgexec/inkscape"
;;
*)
exit 1
esac
# Copy all files into the bundle
#----------------------------------------------------------
echo -e "\n\033[1mFilling app bundle...\033[0m\n"
# Inkscape's binary
if [ $_backend = "x11" ]; then
else
fi
# TODO Add a "$verbose" variable and command line switch, which sets wether these commands are verbose or not
if [ $_backend = "quartz" ]; then
fi
# Share files
# Copy GTK shared mime information
mkdir -p "$pkgresources/share"
# Copy GTK hicolor icon theme index file
mkdir -p "$pkgresources/share/icons/hicolor"
# GTK+ stock icons with legacy icon mapping
echo "Creating GtkStock icon theme ..."
stock_src="${custom_res}/src/icons/stock-icons" \
./create-stock-icon-theme.sh "${pkgshare}/icons/GtkStock"
# GTK+ themes
done
if [ $_backend = "quartz" ]; then
done
fi
# Icons and the rest of the script framework
# remove files not needed with GTK+/Quartz
if [ $_backend = "quartz" ]; then
rm "$pkgresources/script"
rm "$pkgresources/openDoc"
fi
# activate wrapper scripts
if [ $add_wrapper = "true" ]; then
mv "$pkgbin/gimp-wrapper.sh" "$pkgbin/gimp"
fi
# Add python modules if requested
if [ ${add_python} = "true" ]; then
{
# lxml
$cp_cmd -RL "$packages_path/lxml" "$pkgpython"
# numpy
$cp_cmd -RL "$packages_path/nose" "$pkgpython"
$cp_cmd -RL "$packages_path/numpy" "$pkgpython"
# UniConvertor
$cp_cmd -RL "$packages_path/PIL" "$pkgpython"
else # we build Pillow with +tkinter
fi
$cp_cmd -RL "$packages_path/sk1libs" "$pkgpython"
$cp_cmd -RL "$packages_path/uniconvertor" "$pkgpython"
# pySerial for HPGL plotting
$cp_cmd -RL "$packages_path/serial" "$pkgpython"
# PyGTK (optional)
$cp_cmd -RL "$packages_path/cairo" "$pkgpython"
$cp_cmd -RL "$packages_path/glib" "$pkgpython"
$cp_cmd -RL "$packages_path/gobject" "$pkgpython"
$cp_cmd -RL "$packages_path/gtk-2.0" "$pkgpython"
# cleanup python modules
# TODO: test whether to remove hard-coded paths from *.la files or to exclude them altogether
done
}
PYTHON_VERSIONS="2.5 2.6 2.7"
PYTHON_VERSIONS="2.6 2.7"
else # if [ $OSXMINORNO -ge "7" ]; then
PYTHON_VERSIONS="2.7"
fi
if [ -z "$python_dir" ]; then
packages_path="${python_dir}/lib/python${PYTHON_VER}/site-packages"
pkgpython="${pkglib}/python${PYTHON_VER}/site-packages"
mkdir -p $pkgpython
done
else
# copy custom python site-packages.
# They need to be organized in a hierarchical set of directories by python major+minor version:
# - ${python_dir}/python2.5/site-packages/lxml
# - ${python_dir}/python2.5/site-packages/nose
# - ${python_dir}/python2.5/site-packages/numpy
# - ${python_dir}/python2.6/site-packages/lxml
# - ...
fi
fi
# PkgInfo must match bundle type and creator code from Info.plist
# Pull in extra requirements for Pango and GTK
PANGOVERSION=$(pkg-config --modversion pango)
else
echo "Newer pango version found, modules are built-in"
fi
# We use a modified fonts.conf file so only need the dtd
(cd $pkgetc/fonts/conf.d && $ln_cmd ../../../share/fontconfig/conf.avail/10-autohint.conf)
(cd $pkgetc/fonts/conf.d && $ln_cmd ../../../share/fontconfig/conf.avail/70-no-bitmaps.conf)
# Pull in modules
$cp_cmd $LIBPREFIX/lib/pango/$pango_mod_version/modules/*.so $pkglib/pango/$pango_mod_version/modules/
fi
gtk_version=`pkg-config --variable=gtk_binary_version gtk+-2.0`
$cp_cmd $LIBPREFIX/lib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders/*.so $pkglib/gdk-pixbuf-2.0/$gdk_pixbuf_version/loaders/
#sed -e "s,$LIBPREFIX,@loader_path/..,g" "$LIBPREFIX/etc/pango/pango.modules" > "$pkgetc/pango/pango.modules"
#sed -e "s,$LIBPREFIX,@loader_path/..,g" "$LIBPREFIX/lib/gtk-2.0/$gtk_version/immodules.cache" > "$pkglib/gtk-2.0/$gtk_version/immodules.cache"
#sed -e "s,$LIBPREFIX,@loader_path/..,g" "$LIBPREFIX/lib/gdk-pixbuf-2.0/$gtk_version/loaders.cache" > "$pkglib/gdk-pixbuf-2.0/$gtk_version/loaders.cache"
# recreate loaders and modules caches based on actually included modules
# Pango modules
| sed -e "s,$PWD/$pkgresources,@loader_path/..,g" \
fi
# Gtk immodules
| sed -e "s,$PWD/$pkgresources,@loader_path/..,g" \
> "$pkglib/gtk-2.0/$gtk_version/"immodules.cache
# Gdk pixbuf loaders
# GIO modules
# Gnome-vfs modules (deprecated, optional in inkscape)
if [ $WITH_GNOME_VFS ] ; then
$cp_cmd -r "$LIBPREFIX/etc/$item" "$pkgetc/"
done
done
fi
# ImageMagick version
# ImageMagick data
# include *.la files for main libs too
done
# ImageMagick modules
# REQUIRED: remove hard-coded paths from *.la files
done
done
done
# Copy aspell dictionary files:
$cp_cmd -r "$LIBPREFIX/lib/aspell-$ASPELL_VERSION" "$pkglib/"
$cp_cmd -r "$LIBPREFIX/share/aspell" "$pkgshare/"
# Copy Poppler data:
$cp_cmd -r "$LIBPREFIX/share/poppler" "$pkgshare"
# GLib2 schemas
# Copy all linked libraries into the bundle
#----------------------------------------------------------
# get list of *.so modules from python modules
python_libs=""
done
[ $verbose_mode ] && echo "Python libs: $python_libs"
# get list of included binary executables
[ $verbose_mode ] && echo "Extra binaries: $extra_bin"
# Find out libs we need from MacPorts, Fink, or from a custom install
# (i.e. $LIBPREFIX), then loop until no changes.
a=1
nfiles=0
endl=true
while $endl; do
echo -e "\033[1mLooking for dependencies.\033[0m Round" $a
$pkglib/gtk-2.0/$gtk_version/{engines,immodules,printbackends}/*.{dylib,so} \
$binpath \
2>/dev/null | fgrep compatibility | cut -d\( -f1 | grep $LIBPREFIX | sort | uniq)"
let "a+=1"
endl=false
else
fi
done
# Some libraries don't seem to have write permission, fix this.
# Strip libraries and executables if requested
#----------------------------------------------------------
if [ "$strip_build" = "true" ]; then
echo -e "\n\033[1mStripping debugging symbols...\033[0m\n"
fi
# Rewrite id and paths of linked libraries
#----------------------------------------------------------
# extract level for relative path to libs
echo -e "\n\033[1mRewriting library paths ...\033[0m\n"
if [ ! -d "$1" ]; then
fileType="$3"
unset to_id
lib)
loader_to_res="$(echo $filePath | $awk_cmd -F/ '{for (i=1;i<NF;i++) sub($i,".."); sub($NF,"",$0); print $0}')"
;;
bin)
loader_to_res="../"
;;
exec)
loader_to_res="../Resources/"
;;
*)
echo "Skipping loader_to_res for $1"
;;
esac
[ $verbose_mode ] && echo ""
[ $verbose_mode ] && echo "basename: $1"
[ $verbose_mode ] && echo "dirname: $2"
[ $verbose_mode ] && echo "filePath: $filePath"
[ $verbose_mode ] && echo "to_id: $to_id"
[ $verbose_mode ] && echo "loader_to_res: $loader_to_res"
[ $to_id ] && install_name_tool -id "$to_id" "$1"
if [ $first != /usr/lib -a $first != /usr/X11 -a $first != /opt/X11 -a $first != /System/Library ]; then
unset to_path
lib)
to_path="@loader_path/$loader_to_res$res_to_lib"
;;
bin)
to_path="@executable_path/$loader_to_res$res_to_lib"
;;
exec)
to_path="@executable_path/$loader_to_res$res_to_lib"
;;
*)
echo "Skipping to_path for $lib in $1"
;;
esac
[ $verbose_mode ] && echo "lib: $lib"
[ $verbose_mode ] && echo "lib_prefix_levels: $lib_prefix_levels"
[ $verbose_mode ] && echo "res_to_lib: $res_to_lib"
[ $verbose_mode ] && echo "to_path: $to_path"
[ $verbose_mode ] && echo "install_name_tool arguments: -change $lib $to_path $1"
[ $to_path ] && install_name_tool -change "$lib" "$to_path" "$1"
fi
done
fi
}
echo -n "Rewriting dylib paths for executable ... "
echo "done"
fi
echo "Rewriting dylib paths for included binaries:"
for file in $extra_bin; do
echo -n "Rewriting dylib paths for $file ... "
echo "done"
done
echo "Rewriting dylib paths for included libraries:"
echo -n "Rewriting dylib paths for $file ... "
echo "done"
done
}
# Include debug info in app bundle
#----------------------------------------------------------
# TODO: needs more testing
if [ "$with_dSYM" = "true" ]; then
echo -e "\n\033[1mAdding debug info to app bundle ...\033[0m\n"
# package debug symbols for main binary
echo "dsymutil $binpath"
# some of the dependencies have debug symbols in MacPorts ...
#for item in libbz2.1.0.dylib libexif.12.dylib libopenraw.1.dylib; do
echo "dsymutil ${pkglib}/${item}"
dsymutil "${pkglib}/${item}"
done
# to debug issues with ImageMagick / libMagick++
# Note: install ImageMagick with local portfile which includes the 'debug 1.0' portgroup
# use 'port -n -k upgrade --enforce-variants ImageMagick +debug' to reinstall with debug symbols
# (keep work dir (port -k) to allow recreation of bundled dSYMs with dsymutil)
if [[ "$use_port" == "t" ]]; then
# if ImageMagick was installed with debug variant
echo "dsymutil $file"
done
for file in $(find $package -ipath '*ImageMagick*' -and -name '*.so' -and -not -ipath '*.dSYM*'); do
echo "dsymutil $file"
done
else
echo "Macports' ImageMagick port was not installed with +debug variant."
fi
else
echo "not using MacPorts, skipping recreation of dSYMs included in app bundle."
fi
# for debug bundle, remove translations and tutorials (download size)
echo "Removing translation files and tutorials (only for debug builds) ..."
rm -f "${pkgshare}/${binary_name}/tutorials"/*
else
# remove dSYM files if present (local port built with +debug variant from debug port group)
done
fi
# All done.
#----------------------------------------------------------
echo "Inkscape.app created successfully."
exit 0