Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Build libimobiledevice stack for macOS with ease
#!/bin/bash
# If you like this script and my work on libimobiledevice, please
# consider becoming a patron at https://patreon.com/nikias - Thanks <3
REV=1.0.10
if test -x "`which tput`"; then
ncolors=`tput colors`
if test -n "$ncolors" && test $ncolors -ge 8; then
BOLD="$(tput bold)"
UNDERLINE="$(tput smul)"
STANDOUT="$(tput smso)"
NORMAL="$(tput sgr0)"
BLACK="$(tput setaf 0)"
RED="$(tput setaf 1)"
GREEN="$(tput setaf 2)"
YELLOW="$(tput setaf 3)"
BLUE="$(tput setaf 4)"
MAGENTA="$(tput setaf 5)"
CYAN="$(tput setaf 6)"
WHITE="$(tput setaf 7)"
fi
fi
echo -e "${BOLD}**** libimobiledevice stack build script for macOS, revision $REV ****${NORMAL}"
INSTALL_STUFF=1
while getopts hyn flag
do
case "${flag}" in
h)
echo "
This script will build the ${BOLD}libimobiledevice${NORMAL} stack for macOS consisting of
${YELLOW}libplist${NORMAL}, ${YELLOW}libusbmuxd${NORMAL}, ${YELLOW}libimobiledevice${NORMAL}, ${YELLOW}libimobiledevice-glue${NORMAL}, ${YELLOW}libirecovery${NORMAL},
${YELLOW}idevicerestore${NORMAL}, ${YELLOW}libideviceactivation${NORMAL}, ${YELLOW}ideviceinstaller${NORMAL}, and ${YELLOW}ifuse${NORMAL} (requires
macFUSE) with the least amount of external dependencies. Besides command line
tools and the compiler for the build process (and optionally macFUSE)
currently the only external dependency is libzip which will be statically
linked.
Everything needed for the build process will be automatically downloaded,
built, and installed. The built libraries and tools will be installed in
the default prefix /usr/local. This can be changed by setting the PREFIX
environment variable. This script will run sudo if the install prefix is
not writeable for the current user, so it might ask for your password.
NOTE: It is *not* recommended to run this script as root. Instead you should
set the DESTDIR environment variable to specify a writeable install location.
Available options:
-h Print this help text.
-y Assume yes for steps that require user confirmation.
-n Do not ask for confirmation and do not attempt to install third party
software (like macFUSE) during the process. This will still allow
installation of required tools within the source tree.
"
exit 0
;;
y)
DONTASK=1
;;
n)
unset DONTASK
unset INSTALL_STUFF
;;
esac
done
echo -e "Run $0 -h for help."
if test $UID -eq 0; then
if test -z $RUN_AS_ROOT; then
echo -e "${RED}WARNING: It is *NOT* recommended to run this script as root. See -h for help.${NORMAL}"
echo -e "If you still want to run it as root, set environment variable RUN_AS_ROOT=1"
exit 1
else
echo -e "${RED}WARNING: Running as root (enforced via env RUN_AS_ROOT)${NORMAL}"
fi
fi
TESTCOMMANDS="xcrun clang"
for TESTCMD in ${TESTCOMMANDS}; do
if ! test -x "`which $TESTCMD`"; then
echo -e "${RED}FATAL: Xcode with command line tools is required. Please install and run again.${NORMAL}"
exit 1
fi
done
if test -z "$CFLAGS"; then
SDKDIR=`xcrun --sdk macosx --show-sdk-path 2>/dev/null`
TESTARCHS="arm64 x86_64"
USEARCHS=
for ARCH in $TESTARCHS; do
if echo "int main(int argc, char **argv) { return 0; }" |clang -arch $ARCH -o /dev/null -isysroot $SDKDIR -x c - 2>/dev/null; then
USEARCHS="$USEARCHS -arch $ARCH"
fi
done
export CFLAGS="$USEARCHS -isysroot $SDKDIR"
else
echo -e "${YELLOW}NOTE: Using externally defined CFLAGS. If that's not what you want, run: unset CFLAGS${NORMAL}"
fi
if test -z "$PREFIX"; then
PREFIX="/usr/local"
else
echo -e "${YELLOW}NOTE: Using externally defined PREFIX. If that's not what you want, run: unset PREFIX${NORMAL}"
fi
echo -e "${BOLD}PREFIX:${NORMAL} ${GREEN}$PREFIX${NORMAL}"
INSTALL_DIR=$PREFIX
if test -n "$DESTDIR"; then
case "$DESTDIR" in
/*) export DESTDIR="$DESTDIR" ;;
*) export DESTDIR="`pwd`/$DESTDIR" ;;
esac
mkdir -p "$DESTDIR"
echo -e "${BOLD}DESTDIR:${NORMAL} ${GREEN}$DESTDIR${NORMAL}"
INSTALL_DIR=$DESTDIR
fi
if ! test -w "$INSTALL_DIR"; then
echo -e "${YELLOW}NOTE: During the process you will be asked for your password, this is to allow installation of the built libraries and tools via ${MAGENTA}sudo${YELLOW}.${NORMAL}"
fi
###########################################################
VERS=`sw_vers -productVersion`
VMAJ=`echo $VERS |cut -d "." -f 1`
VMIN=`echo $VERS |cut -d "." -f 2`
############# DEPENDENCY URLS AND FILE DATA ###############
# autoconf
AUTOCONF_URL=https://ftpmirror.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
AUTOCONF_HASH=562471cbcb0dd0fa42a76665acf0dbb68479b78a
# automake
AUTOMAKE_URL=https://ftpmirror.gnu.org/gnu/automake/automake-1.16.3.tar.gz
AUTOMAKE_HASH=b36e3877d961c1344351cc97b35b683a4dfadc0c
# libtool
LIBTOOL_URL=https://ftpmirror.gnu.org/gnu/libtool/libtool-2.4.6.tar.gz
LIBTOOL_HASH=25b6931265230a06f0fc2146df64c04e5ae6ec33
# cmake
if [ $VMAJ -le 10 ] && [ $VMIN -lt 13 ]; then
if [ $VMIN -lt 10 ]; then
# < macOS 10.10
CMAKE_URL=https://github.com/Kitware/CMake/releases/download/v3.18.6/cmake-3.18.6-Darwin-x86_64.tar.gz
CMAKE_HASH=fe09f28c2bfe26a7b7daf0ff9444175f410bae36
else
# >= macOS 10.10
CMAKE_URL=https://github.com/Kitware/CMake/releases/download/v3.20.1/cmake-3.20.1-macos10.10-universal.tar.gz
CMAKE_HASH=668e554a7fa7ad57eaf73d374774afd7fd25f98f
fi
else
# >= macOS 10.13
CMAKE_URL=https://github.com/Kitware/CMake/releases/download/v3.20.1/cmake-3.20.1-macos-universal.tar.gz
CMAKE_HASH=43cc6b91ca2ec711f3a1a3eafb970f9389e795e2
fi
# libzip
LIBZIP_URL=https://github.com/nih-at/libzip/releases/download/v1.7.1/libzip-1.7.1.tar.gz
LIBZIP_VERSION=1.7.1
LIBZIP_HASH=22a7a9b13357015275d017d0ca1b75e69abe1db9
# macFUSE
if [ $VMAJ -le 10 ] && [ $VMIN -lt 12 ]; then
# <= macOS 10.11
MFUSE_URL=https://github.com/osxfuse/osxfuse/releases/download/macfuse-4.0.5/macfuse-4.0.5.dmg
MFUSE_HASH=2056c833aa8996d03748687bc938ba9805cc77a5
else
# macOS >= 10.12
MFUSE_URL=https://github.com/osxfuse/osxfuse/releases/download/macfuse-4.1.2/macfuse-4.1.2.dmg
MFUSE_HASH=a12e1f8d5e33baaa075e1a59986922eaa45162a2
fi
############# CHECK REQUIRED COMMANDS #####################
if test -x "`which shasum`"; then
SHA1SUM="`which shasum`"
SHA256SUM="$SHA1SUM -a 256"
elif test -x "`which sha1sum`"; then
SHA1SUM="`which sha1sum`"
fi
if test -z "$SHA1SUM"; then
echo -e "${RED}FATAL: no shasum or sha1sum found.${NORMAL}"
exit 1
fi
if test -z "$SHA256SUM"; then
if test -x "`which sha256sum`"; then
SHA256SUM="`which sha256sum`"
fi
fi
if test -z "$SHA256SUM"; then
echo -e "${RED}FATAL: no sha256sum found.${NORMAL}"
exit 1
fi
TESTCOMMANDS="strings dirname cut grep find curl tar gunzip git make sudo"
for TESTCMD in ${TESTCOMMANDS}; do
if ! test -x "`which $TESTCMD`"; then
echo -e "${RED}FATAL: Required command '$TESTCMD' is not available.${NORMAL}"
exit 1
fi
done
CURL="`which curl`"
if test -x "/usr/bin/curl" && test "$CURL" != "/usr/bin/curl"; then
CURL=/usr/bin/curl
fi
if test -f "/usr/local/include/openssl/opensslv.h"; then
echo -e "${RED}ERROR: You have OpenSSL headers installed in /usr/local/include/openssl
and compiling libimobiledevice will fail.${NORMAL}
You can either uninstall the OpenSSL package or just temporarily rename it
like this:
${YELLOW}sudo mv /usr/local/include/openssl /usr/local/include/openssl.bak${NORMAL}
and once this script completes, just rename it back:
${YELLOW}sudo mv /usr/local/include/openssl.bak /usr/local/include/openssl${NORMAL}
Aborting.
"
exit 1
fi
BREW_OR_PORTS_INSTALL=
BREW_OR_PORTS_UNINSTALL=
if test -x "`which brew`"; then
BREW_OR_PORTS_INSTALL="brew install"
BREW_OR_PORTS_UNINSTALL="brew uninstall"
elif test -x "`which port`"; then
BREW_OR_PORTS_INSTALL="sudo port install"
BREW_OR_PORTS_UNINSTALL="sudo port uninstall"
fi
CHECKPKGS="idevicerestore ideviceinstaller libimobiledevice libusbmuxd libplist libimobiledevice-glue libirecovery libideviceactivation ifuse"
for PKG in $CHECKPKGS; do
PKG_INSTALLED=
if test -x "`which brew`"; then
if brew list $PKG >/dev/null 2>/dev/null; then
PKG_INSTALLED="brew"
fi
fi
if test -x "`which port`"; then
if test -n "`port installed $PKG 2>/dev/null |grep active`"; then
PKG_INSTALLED="macports"
fi
fi
if test -n "$PKG_INSTALLED"; then
echo -e "${RED}WARNING: ${YELLOW}$PKG${RED} is already installed through ${PKG_INSTALLED}!${NORMAL}
Unless you know exactly what you are doing it is recommended to uninstall the
package first by running: ${YELLOW}${BREW_OR_PORTS_UNINSTALL} $PKG${NORMAL}"
echo
echo -e "Choose one of these options:"
echo -e " [a] Abort now and do nothing"
echo -e " [r] Run the uninstall command, then continue"
echo -e " [c] Continue without doing anything"
read -r -p "${BOLD}Your choice? [A/r/c]${NORMAL} " response
case "$response" in
[rR])
echo -e "Running ${YELLOW}$BREW_OR_PORTS_UNINSTALL $PKG${NORMAL}..."
$BREW_OR_PORTS_UNINSTALL $PKG 2>/dev/null || exit 1
;;
[cC])
;;
""|*)
echo "Aborting."
exit 0
;;
esac
fi
done
if test -z "$INSTALL_STUFF"; then
unset BREW_OR_PORTS_INSTALL
fi
BASEDIR=`pwd`
DEPSDIR="$BASEDIR/deps"
mkdir -p "$DEPSDIR"
cd "$DEPSDIR"
rm -f "*.log"
export PATH="$PATH:$DEPSDIR/bin"
echo -e "${CYAN}######## INSTALLING REQUIRED TOOLS AND DEPENDENCIES ########${NORMAL}"
#################### autoconf ####################
if ! test -x "`which autoconf`"; then
echo -e "${BOLD}*** Installing autoconf (in-tree)${NORMAL}"
if test -z "$BREW_OR_PORTS_INSTALL"; then
AUTOCONF_TGZ=`basename $AUTOCONF_URL`
HASH=`$SHA1SUM "$AUTOCONF_TGZ" 2>/dev/null |cut -d " " -f 1`
if test -z "$HASH" || test "$HASH" != "$AUTOCONF_HASH"; then
echo "-- downloading autoconf"
$CURL -LfsS -o $AUTOCONF_TGZ $AUTOCONF_URL || exit 1
HASH=`$SHA1SUM "$AUTOCONF_TGZ" 2>/dev/null |cut -d " " -f 1`
if test -z "$HASH" || test "$HASH" != "$AUTOCONF_HASH"; then
echo -e "${RED}FATAL: hash mismatch for $AUTOCONF_TGZ${NORMAL}"
exit 1
fi
fi
tar xzf $AUTOCONF_TGZ
cd `basename $AUTOCONF_TGZ .tar.gz`
echo "-- configuring autoconf"
./configure --prefix="$DEPSDIR" >> ../autoconf-configure.log || exit 1
echo "-- building autoconf"
make clean > /dev/null
make >> ../autoconf-make.log|| exit 1
echo "-- installing autoconf (in-tree)"
make install >> ../autoconf-make_install.log || exit 1
cd $DEPSDIR
else
$BREW_OR_PORTS_INSTALL autoconf || exit 1
fi
echo -e "${BOLD}* autoconf: ${GREEN}done${NORMAL}"
else
echo -e "${BOLD}* autoconf: ${GREEN}found${NORMAL}"
fi
#################### automake ####################
if ! test -x "`which automake`"; then
echo -e "${BOLD}*** Installing automake (in-tree)${NORMAL}"
if test -z "$BREW_OR_PORTS_INSTALL"; then
AUTOMAKE_TGZ=`basename $AUTOMAKE_URL`
HASH=`$SHA1SUM "$AUTOMAKE_TGZ" 2>/dev/null |cut -d " " -f 1`
if test -z "$HASH" || test "$HASH" != "$AUTOMAKE_HASH"; then
echo "-- Downloading automake"
$CURL -LfsS -o $AUTOMAKE_TGZ $AUTOMAKE_URL || exit 1
HASH=`$SHA1SUM "$AUTOMAKE_TGZ" 2>/dev/null |cut -d " " -f 1`
if test -z "$HASH" || test "$HASH" != "$AUTOMAKE_HASH"; then
echo -e "${RED}FATAL: hash mismatch for $AUTOMAKE_TGZ${NORMAL}"
exit 1
fi
fi
tar xzf $AUTOMAKE_TGZ
cd `basename $AUTOMAKE_TGZ .tar.gz`
echo "-- Configuring automake"
./configure --prefix="$DEPSDIR" >> ../automake-configure.log || exit 1
echo "-- Building automake"
make clean > /dev/null
make >> ../automake-make.log || exit 1
echo "-- Installing automake (in-tree)"
make install >> ../automake-make_install.log || exit 1
cd $DEPSDIR
else
$BREW_OR_PORTS_INSTALL automake || exit 1
fi
echo -e "${BOLD}* automake: ${GREEN}done${NORMAL}"
else
echo -e "${BOLD}* automake: ${GREEN}found${NORMAL}"
fi
#################### libtool ####################
if ! test -x "`which libtool`" || ! test -x "`which libtoolize`" -o -x "`which glibtoolize`"; then
echo -e "${BOLD}*** Installing libtool (in-tree)${NORMAL}"
if test -z "$BREW_OR_PORTS_INSTALL"; then
LIBTOOL_TGZ=`basename $LIBTOOL_URL`
HASH=`$SHA1SUM "$LIBTOOL_TGZ" 2>/dev/null |cut -d " " -f 1`
if test -z "$HASH" || test "$HASH" != "$LIBTOOL_HASH"; then
echo "-- Downloading libtool"
$CURL -LfsS -o $LIBTOOL_TGZ $LIBTOOL_URL || exit 1
HASH=`$SHA1SUM "$LIBTOOL_TGZ" 2>/dev/null |cut -d " " -f 1`
if test -z "$HASH" || test "$HASH" != "$LIBTOOL_HASH"; then
echo -e "${RED}FATAL: hash mismatch for $LIBTOOL_TGZ${NORMAL}"
exit 1
fi
fi
tar xzf $LIBTOOL_TGZ
cd `basename $LIBTOOL_TGZ .tar.gz`
echo "-- Configuring libtool"
./configure --prefix="$DEPSDIR" >> ../libtool-configure.log || exit 1
echo "-- Building libtool"
make clean > /dev/null
make >> ../libtool-make.log|| exit 1
echo "-- Installing libtool (in-tree)"
make install >> ../libtool-make_install.log || exit 1
cd $DEPSDIR
else
$BREW_OR_PORTS_INSTALL libtool || exit 1
fi
echo -e "${BOLD}* libtool: ${GREEN}done${NORMAL}"
else
echo -e "${BOLD}* libtool: ${GREEN}found${NORMAL}"
fi
TESTCOMMANDS="autoconf automake libtool" # pkg-config"
for TESTCMD in ${TESTCOMMANDS}; do
if ! test -x "`which $TESTCMD`"; then
echo -e "${RED}FATAL: required ${BOLD}$TESTCMD${RED} not found. Please install manually.${NORMAL}"
err_cmd="$err_cmd $TESTCMD"
fi
done
if test -n "$err_cmd"; then
exit 1
fi
INSTALL_SUDO=
POSTINSTALL=
if test -z $DESTDIR; then
if ! test -w $PREFIX; then
INSTALL_SUDO="sudo"
fi
fi
ACLOCALDIR=$(dirname `automake --print-libdir`)/aclocal
if ! test -f ${ACLOCALDIR}/pkg.m4; then
$CURL -LfsS -o "$DEPSDIR/pkg.m4" https://raw.githubusercontent.com/pkgconf/pkgconf/master/pkg.m4 || exit 1
if test -w ${ACLOCALDIR}; then
cp "$DEPSDIR/pkg.m4" "${ACLOCALDIR}/pkg.m4"
else
$INSTALL_SUDO cp "$DEPSDIR/pkg.m4" "${ACLOCALDIR}/pkg.m4"
fi
rm -f "$DEPSDIR/pkg.m4"
fi
############## CMAKE for building libzip ####################
if ! test -x "`which cmake`"; then
echo -e "${BOLD}*** Installing cmake (in-tree)${NORMAL}"
CMAKE_TGZ=`basename $CMAKE_URL`
HASH=`$SHA1SUM "$CMAKE_TGZ" 2>/dev/null |cut -d " " -f 1`
if test -z "$HASH" || test "$HASH" != "$CMAKE_HASH"; then
echo "-- Downloading cmake"
$CURL -LfsS -o "$CMAKE_TGZ" "$CMAKE_URL" || exit 1
fi
CMAKE_PATH="$DEPSDIR/`basename $CMAKE_TGZ .tar.gz`/CMake.app/Contents/bin"
CMAKE_BIN="$CMAKE_PATH/cmake"
if ! test -x "$CMAKE_BIN"; then
echo "-- Extracting cmake (in tree)"
tar xzf "$CMAKE_TGZ"
fi
echo "-- Updating \$PATH"
export PATH="$PATH:$CMAKE_PATH"
if ! test -x "`which cmake`"; then
echo -e "${RED}FATAL: cmake not found in \$PATH after trying to install it locally?!${NORMAL}"
exit 1
fi
echo -e "${BOLD}* cmake: ${GREEN}done${NORMAL}"
else
echo -e "${BOLD}* cmake: ${GREEN}found${NORMAL}"
fi
############ lzma headers for libzip #############
if ! test -f "$DEPSDIR/xz-5.0.5/src/liblzma/api/lzma.h"; then
echo -e "${BOLD}*** Installing lzma headers (in-tree)${NORMAL}"
XZ_URL=https://sourceforge.net/projects/lzmautils/files/xz-5.0.5.tar.gz/download
XZ_HASH=26fec2c1e409f736e77a85e4ab314dc74987def0
XZ_TGZ="xz-5.0.5.tar.gz"
HASH=`$SHA1SUM "$XZ_TGZ" 2>/dev/null |cut -d " " -f 1`
if test -z "$HASH" || test "$HASH" != "$XZ_HASH"; then
echo "-- Downloading xz"
$CURL -LfsS -o "$XZ_TGZ" "$XZ_URL" || exit 1
fi
echo "-- Extracting xz"
tar xzf "$XZ_TGZ"
LZMA_INCLUDES="$DEPSDIR/xz-5.0.5/src/liblzma/api"
if ! test -f "$LZMA_INCLUDES/lzma.h"; then
echo -e "${RED}FATAL: lzma.h not found${NORMAL}"
exit 1
fi
echo -e "${BOLD}* lzma headers: ${GREEN}done${NORMAL}"
else
LZMA_INCLUDES="$DEPSDIR/xz-5.0.5/src/liblzma/api"
echo -e "${BOLD}* lzma headers: ${GREEN}found${NORMAL}"
fi
############ libzip ###################
LIBZIP_FILENAME=`basename $LIBZIP_URL`
LIBZIP_DIR=`basename $LIBZIP_FILENAME .tar.gz`
if ! test -f $DEPSDIR/$LIBZIP_DIR/build/lib/libzip.a; then
echo -e "${BOLD}*** Installing libzip (static, in-tree)${NORMAL}"
HASH=`$SHA1SUM "LIBZIP_FILENAME" 2>/dev/null |cut -d " " -f 1`
if test -z "$HASH" || test "$HASH" != "$LIBZIP_HASH"; then
echo "-- Downloading libzip"
$CURL -LfsS -o "$LIBZIP_FILENAME" "$LIBZIP_URL" || exit 1
fi
echo "-- Extracting libzip"
tar xzf "$LIBZIP_FILENAME"
if test -z "$SDKDIR"; then
SDKDIR=`xcrun --sdk macosx --show-sdk-path 2>/dev/null`
fi
CURDIR=`pwd`
cd "$LIBZIP_DIR"
rm -rf build
mkdir build
cd build
echo "-- Configuring libzip (cmake)"
cmake -DCMAKE_OSX_SYSROOT="${SDKDIR}" -DBUILD_SHARED_LIBS=OFF -DBUILD_DOC=OFF -DBUILD_EXAMPLES=OFF -DBUILD_REGRESS=OFF -DBUILD_TOOLS=OFF -DENABLE_GNUTLS=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF -DCMAKE_POLICY_DEFAULT_CMP0063=NEW -DCMAKE_LIBRARY_PATH="$SDKDIR/usr/lib" -DLIBLZMA_INCLUDE_DIR="$LZMA_INCLUDES" .. >> ../../libzip-cmake.log || exit 1
echo "-- Bulding libzip"
make clean > /dev/null
make >> ../../libzip-make.log || exit 1
cd "$CURDIR"
echo -e "${BOLD}* libzip: ${GREEN}done${NORMAL}"
else
echo -e "${BOLD}* libzip: ${GREEN}found${NORMAL}"
fi
LIBZIP_CFLAGS="-I$DEPSDIR/$LIBZIP_DIR/lib -I$DEPSDIR/$LIBZIP_DIR/build"
LIBZIP_LIBS="$DEPSDIR/$LIBZIP_DIR/build/lib/libzip.a -Xlinker /usr/lib/libbz2.dylib -Xlinker /usr/lib/liblzma.dylib -lz"
############ LibreSSL ##############
if ! test -f "$LIBCRYPTO" || ! test -f "$LIBSSL"; then
mkdir -p lib
if ! test -f "lib/libssl.35.tbd"; then
$CURL -o "lib/libssl.35.tbd" -LfsS \
https://gist.github.com/nikias/94c99fd145a75a5104415e5117b0cafa/raw/5209dfbff5a871a14272afe4794e76eb4cf6f062/libssl.35.tbd || exit 1
fi
if ! test -f "lib/libcrypto.35.tbd"; then
$CURL -o "lib/libcrypto.35.tbd" -LfsS \
https://gist.github.com/nikias/94c99fd145a75a5104415e5117b0cafa/raw/5209dfbff5a871a14272afe4794e76eb4cf6f062/libcrypto.35.tbd || exit 1
fi
LIBSSL=$DEPSDIR/lib/libssl.35.tbd
LIBCRYPTO=$DEPSDIR/lib/libcrypto.35.tbd
LIBRESSL_VER=2.2.7
fi
if ! test -f "$LIBCRYPTO"; then
echo -e "${RED}ERROR: Could not find $LIBCRYPTO. Cannot continue.${NORMAL}"
exit 1
else
echo -e "${BOLD}* LibreSSL `basename $LIBSSL`: ${GREEN}found${NORMAL}"
fi
if ! test -f "$LIBSSL"; then
echo -e "${RED}ERROR: Could not find $LIBSSL. Cannot continue.${NORMAL}"
exit 1
else
echo -e "${BOLD}* LibreSSL `basename $LIBCRYPTO`: ${GREEN}found${NORMAL}"
fi
if test -z "$LIBRESSL_VER"; then
if LIBRESSL_VER_TMP=`strings "$LIBCRYPTO" |grep "^LibreSSL .\..\.."`; then
LIBRESSL_VER=`echo $LIBRESSL_VER_TMP |cut -d " " -f 2`
fi
fi
echo " ${YELLOW}LibreSSL version requirment: $LIBRESSL_VER${NORMAL}"
if ! test -f "$DEPSDIR/libressl-$LIBRESSL_VER/include/openssl/opensslv.h"; then
echo -e "${BOLD}*** Installing LibreSSL headers (in-tree)${NORMAL}"
rm -rf libressl-$LIBRESSL_VER
FILENAME="libressl-$LIBRESSL_VER.tar.gz"
$CURL -LfsS -o "libressl.sha256.txt" "https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/SHA256" || exit 1
CHKSUM=`cat "libressl.sha256.txt" |grep "($FILENAME)" |cut -d " " -f 4`
rm -f "libressl.sha256.txt"
if test -z "$CHKSUM"; then
echo -e "${RED}ERROR: Failed to get checksum from server for $FILENAME${NORMAL}"
exit 1
fi
if test -f "$FILENAME"; then
CALCSUM=`$SHA256SUM "$FILENAME" |cut -d " " -f 1`
fi
if test -z "$CALCSUM" -o "$CALCSUM" != "$CHKSUM"; then
echo "-- Downloading $FILENAME${NORMAL}"
$CURL -LfsS -o "$FILENAME" "https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/$FILENAME" || exit 1
CALCSUM=`$SHA256SUM "$FILENAME" |cut -d " " -f 1`
if test "$CALCSUM" != "$CHKSUM"; then
echo -e "${RED}ERROR: Failed to verify $FILENAME (checksum mismatch).${NORMAL}"
exit 1
fi
else
echo "-- Using cached $FILENAME"
fi
echo "-- Extracting $FILENAME"
tar xzf "$FILENAME" || exit 1
echo -e "${BOLD}* LibreSSL headers: ${GREEN}done${NORMAL}"
else
echo -e "${BOLD}* LibreSSL headers: ${GREEN}found${NORMAL}"
fi
cd "$BASEDIR"
############ macFUSE ##############
HAVE_MACFUSE=no
if ! test -f "/usr/local/lib/libfuse.dylib" || ! test -f "/usr/local/include/fuse/fuse.h"; then
INSTALL_MACFUSE=no
if test -n "$DONTASK" && test -n "$INSTALL_STUFF"; then
INSTALL_MACFUSE=yes
elif test -z "$INSTALL_STUFF"; then
INSTALL_MACFUSE=no
else
echo -e "${BOLD}The package ifuse requires macFUSE in order to work."
if [ $VMAJ -ge 11 ]; then
echo -e "${YELLOW}NOTE: Your Mac's startup security needs to be set to ${MAGENTA}reduced security${YELLOW} in recovery mode, and also the kernel extension cache has to be regenerated for macFUSE to work. Without perfoming these steps after the installation of macFUSE, ifuse will not be able to run.${NORMAL}"
fi
echo
read -r -p "${BOLD}Install macFUSE? [Y/n]${NORMAL} " response
case "$response" in
[yY][eE][sS]|[yY]|"")
INSTALL_MACFUSE=yes
;;
*)
INSTALL_MACFUSE=no
;;
esac
fi
if test "$INSTALL_MACFUSE" == "yes"; then
echo -e "${BOLD}*** Installing macFUSE${NORMAL}"
MFUSE_DMG=$DEPSDIR/`basename $MFUSE_URL`
HASH=`$SHA1SUM "$MFUSE_DMG" 2>/dev/null |cut -d " " -f 1`
if test -z "$HASH" || test "$HASH" != "$MFUSE_HASH"; then
echo "-- Downloading macFUSE"
$CURL -LfsS -o "$MFUSE_DMG" "$MFUSE_URL" || exit 1
fi
hdiutil attach "$MFUSE_DMG" -quiet || exit 1
MOUNTP="/Volumes/macFUSE"
INSTPKG="$MOUNTP/Install macFUSE.pkg"
echo "-- Installing macFUSE (runs with sudo, enter your password when asked for it)"
sudo /usr/sbin/installer -pkg "$INSTPKG" -target /
INSTRES=$?
hdiutil detach "$MOUNTP" -quiet
if test $INSTRES != 0; then exit 1; fi
echo -e "${BOLD}* macFUSE: ${GREEN}done${NORMAL}"
HAVE_MACFUSE=yes
else
echo "Skipping installation of macFUSE."
fi
else
echo -e "${BOLD}* macFUSE: ${GREEN}found${NORMAL}"
HAVE_MACFUSE=yes
fi
CURDIR=`pwd`
#############################################################################
COMPONENTS="
libplist:master \
libimobiledevice-glue:master \
libusbmuxd:master \
libimobiledevice:master \
libirecovery:master \
idevicerestore:master \
libideviceactivation:master \
ideviceinstaller:master \
"
# error helper function
function error_exit {
echo "$1"
exit 1
}
if test "$HAVE_MACFUSE" == "yes"; then
COMPONENTS="$COMPONENTS ifuse:master"
fi
if test -z "$NO_CLONE"; then
echo
echo -e "${CYAN}######## UPDATING SOURCES ########${NORMAL}"
echo
for I in $COMPONENTS; do
COMP=`echo $I |cut -d ":" -f 1`;
CVER=`echo $I |cut -d ":" -f 2`;
if test -d "$COMP/.git" && ! test -f "$COMP/.git/shallow"; then
cd $COMP
if test -z "`git branch |grep '$CVER'`"; then
git checkout $CVER --quiet || error_exit "Failed to check out $CVER"
fi
if test "$CVER" != "master"; then
echo "Updating $COMP (release $CVER)";
else
echo "Updating $COMP";
fi
git reset --hard --quiet
git pull --quiet || error_exit "Failed to pull from git $COMP"
cd "$CURDIR"
else
rm -rf $COMP
if test "$CVER" != "master"; then
echo "Cloning $COMP (release $CVER)";
git clone -b $CVER https://github.com/libimobiledevice/$COMP 2>/dev/null || error_exit "Failed to clone $COMP"
else
echo "Cloning $COMP (master)";
git clone https://github.com/libimobiledevice/$COMP 2>/dev/null || error_exit "Failed to clone $COMP"
fi
fi
done
fi
#############################################################################
echo
echo -e "${CYAN}######## STARTING BUILD ########${NORMAL}"
echo
#############################################################################
export PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig"
function error_out {
echo -e "${RED}ERROR: ${STEP} failed for ${COMP}, check ${YELLOW}${LOGF}${RED} for details.${NORMAL}"
exit 1
}
LIBCURL_VERSION=`/usr/bin/curl-config --version |cut -d " " -f 2`
LIBXML2_VERSION=`/usr/bin/xml2-config --version |cut -d " " -f 2`
#############################################################################
COMP=libplist
echo -e "${BOLD}#### Building libplist ####${NORMAL}"
cd libplist
echo -e "[*] Configuring..."
STEP=configure
LOGF=$CURDIR/${COMP}_${STEP}.log
./autogen.sh --prefix="$PREFIX" --without-cython > "$LOGF" 2>&1 || error_out
echo -e "[*] Building..."
STEP=build
LOGF=$CURDIR/${COMP}_${STEP}.log
make > "$LOGF" 2>&1 || error_out
echo -e "[*] Installing..."
STEP=install
LOGF=$CURDIR/${COMP}_${STEP}.log
$INSTALL_SUDO make install > "$LOGF" 2>&1 || error_out
LIBPLIST_CFLAGS="-I$PREFIX/include"
LIBPLIST_LIBS="-L$PREFIX/lib -lplist-2.0"
LIBPLIST_VERSION=`cat src/libplist-2.0.pc |grep Version: |cut -d " " -f 2`
cd "$CURDIR"
#############################################################################
COMP=libimobiledevice-glue
echo -e "${BOLD}#### Building libimobiledevice-glue ####${NORMAL}"
cd libimobiledevice-glue
echo -e "[*] Configuring..."
STEP=configure
LOGF=$CURDIR/${COMP}_${STEP}.log
./autogen.sh --prefix="$PREFIX" libplist_CFLAGS="$LIBPLIST_CFLAGS" libplist_LIBS="$LIBPLIST_LIBS" libplist_VERSION="$LIBPLIST_VERSION" > "$LOGF" 2>&1 || error_out
echo -e "[*] Building..."
STEP=build
LOGF=$CURDIR/${COMP}_${STEP}.log
make > "$LOGF" 2>&1 || error_out
echo -e "[*] Installing..."
STEP=install
LOGF=$CURDIR/${COMP}_${STEP}.log
$INSTALL_SUDO make install > "$LOGF" 2>&1 || error_out
LIMD_GLUE_CFLAGS="-I$PREFIX/include"
LIMD_GLUE_LIBS="-L$PREFIX/lib -limobiledevice-glue-1.0"
LIMD_GLUE_VERSION=`cat src/libimobiledevice-glue-1.0.pc |grep Version: |cut -d " " -f 2`
cd "$CURDIR"
#############################################################################
COMP=libusbmuxd
echo -e "${BOLD}#### Building libusbmuxd ####${NORMAL}"
cd libusbmuxd
echo -e "[*] Configuring..."
STEP=configure
LOGF=$CURDIR/${COMP}_${STEP}.log
./autogen.sh --prefix="$PREFIX" libplist_CFLAGS="$LIBPLIST_CFLAGS" libplist_LIBS="$LIBPLIST_LIBS" libplist_VERSION="$LIBPLIST_VERSION" limd_glue_CFLAGS="$LIMD_GLUE_CFLAGS" limd_glue_LIBS="$LIMD_GLUE_LIBS" limd_glue_VERSION="$LIMD_GLUE_VERSION" > "$LOGF" 2>&1 || error_out
echo -e "[*] Building..."
STEP=build
LOGF=$CURDIR/${COMP}_${STEP}.log
make > "$LOGF" 2>&1 || error_out
echo -e "[*] Installing..."
STEP=install
LOGF=$CURDIR/${COMP}_${STEP}.log
$INSTALL_SUDO make install > "$LOGF" 2>&1 || error_out
LIBUSBMUXD_CFLAGS="-I$PREFIX/include"
LIBUSBMUXD_LIBS="-L$PREFIX/lib -lusbmuxd-2.0"
LIBUSBMUXD_VERSION=`cat src/libusbmuxd-2.0.pc |grep Version: |cut -d " " -f 2`
cd "$CURDIR"
#############################################################################
COMP=libimobiledevice
echo -e "${BOLD}#### Building libimobiledevice ####${NORMAL}"
cd libimobiledevice
echo -e "[*] Configuring..."
STEP=configure
LOGF=$CURDIR/${COMP}_${STEP}.log
./autogen.sh --prefix="$PREFIX" --enable-debug --without-cython \
openssl_CFLAGS="-I$DEPSDIR/libressl-$LIBRESSL_VER/include" openssl_LIBS="-Xlinker $LIBSSL -Xlinker $LIBCRYPTO" openssl_VERSION="$LIBRESSL_VER" \
libplist_CFLAGS="$LIBPLIST_CFLAGS" libplist_LIBS="$LIBPLIST_LIBS" libplist_VERSION="$LIBPLIST_VERSION" \
libusbmuxd_CFLAGS="$LIBUSBMUXD_CFLAGS" libusbmuxd_LIBS="$LIBUSBMUXD_LIBS" libusbmuxd_VERSION="$LIBUSBMUXD_VERSION" \
limd_glue_CFLAGS="$LIMD_GLUE_CFLAGS" limd_glue_LIBS="$LIMD_GLUE_LIBS" limd_glue_VERSION="$LIMD_GLUE_VERSION" \
> "$LOGF" 2>&1 || error_out
echo -e "[*] Building..."
STEP=build
LOGF=$CURDIR/${COMP}_${STEP}.log
make > "$LOGF" 2>&1 || error_out
echo -e "[*] Installing..."
STEP=install
LOGF=$CURDIR/${COMP}_${STEP}.log
$INSTALL_SUDO make install > "$LOGF" 2>&1 || error_out
LIMD_CFLAGS="-I$PREFIX/include"
LIMD_LIBS="-L$PREFIX/lib -limobiledevice-1.0 -lplist-2.0"
LIMD_VERSION=`cat src/libimobiledevice-1.0.pc |grep Version: |cut -d " " -f 2`
cd "$CURDIR"
#############################################################################
COMP=libirecovery
echo -e "${BOLD}#### Building libirecovery ####${NORMAL}"
cd libirecovery
echo -e "[*] Configuring..."
STEP=configure
LOGF=$CURDIR/${COMP}_${STEP}.log
./autogen.sh --prefix="$PREFIX" limd_glue_CFLAGS="$LIMD_GLUE_CFLAGS" limd_glue_LIBS="$LIMD_GLUE_LIBS" limd_glue_VERSION="$LIMD_GLUE_VERSION" > "$LOGF" 2>&1 || error_out
echo -e "[*] Building..."
STEP=build
LOGF=$CURDIR/${COMP}_${STEP}.log
make > "$LOGF" 2>&1 || error_out
echo -e "[*] Installing..."
STEP=install
LOGF=$CURDIR/${COMP}_${STEP}.log
$INSTALL_SUDO make install > "$LOGF" 2>&1 || error_out
IRECV_CFLAGS="-I$PREFIX/include"
IRECV_LIBS="-L$PREFIX/lib -lirecovery-1.0"
IRECV_VERSION=`cat src/libirecovery-1.0.pc |grep Version: |cut -d " " -f 2`
cd "$CURDIR"
#############################################################################
COMP=idevicerestore
echo -e "${BOLD}#### Building idevicerestore ####${NORMAL}"
cd idevicerestore
echo -e "[*] Configuring..."
STEP=configure
LOGF=$CURDIR/${COMP}_${STEP}.log
./autogen.sh --prefix="$PREFIX" \
openssl_CFLAGS="-I$DEPSDIR/libressl-$LIBRESSL_VER/include" openssl_LIBS="-Xlinker $LIBSSL -Xlinker $LIBCRYPTO" openssl_VERSION="$LIBRESSL_VER" \
libcurl_CFLAGS="-I$SDKDIR/usr/include" libcurl_LIBS="-lcurl" libcurl_VERSION="$LIBCURL_VERSION" \
libzip_CFLAGS="$LIBZIP_CFLAGS" libzip_LIBS="$LIBZIP_LIBS" libzip_VERSION="$LIBZIP_VERSION" \
zlib_CFLAGS="-I$SDKDIR/usr/include" zlib_LIBS="-lz" zlib_VERSION="1.2" \
libimobiledevice_CFLAGS="$LIMD_CFLAGS" libimobiledevice_LIBS="$LIMD_LIBS" libimobiledevice_VERSION="$LIMD_VERSION" \
libirecovery_CFLAGS="$IRECV_CFLAGS" libirecovery_LIBS="$IRECV_LIBS" libirecovery_VERSION="$IRECV_VERSION" \
libplist_CFLAGS="$LIBPLIST_CFLAGS" libplist_LIBS="$LIBPLIST_LIBS" libplist_VERSION="$LIBPLIST_VERSION" \
limd_glue_CFLAGS="$LIMD_GLUE_CFLAGS" limd_glue_LIBS="$LIMD_GLUE_LIBS" limd_glue_VERSION="$LIMD_GLUE_VERSION" \
> "$LOGF" 2>&1 || error_out
echo -e "[*] Building..."
STEP=build
LOGF=$CURDIR/${COMP}_${STEP}.log
make > "$LOGF" 2>&1 || error_out
echo -e "[*] Installing..."
STEP=install
LOGF=$CURDIR/${COMP}_${STEP}.log
$INSTALL_SUDO make install > "$LOGF" 2>&1 || error_out
cd "$CURDIR"
#############################################################################
COMP=libideviceactivation
echo -e "${BOLD}#### Building libideviceactivation ####${NORMAL}"
cd libideviceactivation
echo -e "[*] Configuring..."
STEP=configure
LOGF=$CURDIR/${COMP}_${STEP}.log
./autogen.sh --prefix="$PREFIX" \
libcurl_CFLAGS="-I$SDKDIR/usr/include" libcurl_LIBS="-lcurl" libcurl_VERSION="$LIBCURL_VERSION" \
libxml2_CFLAGS="-I$SDKDIR/usr/include/libxml2" libxml2_LIBS="-lxml2" libxml2_VERSION="$LIBXML2_VERSION" \
libimobiledevice_CFLAGS="$LIMD_CFLAGS" libimobiledevice_LIBS="$LIMD_LIBS" libimobiledevice_VERSION="$LIMD_VERSION" \
libplist_CFLAGS="$LIBPLIST_CFLAGS" libplist_LIBS="$LIBPLIST_LIBS" libplist_VERSION="$LIBPLIST_VERSION" \
> "$LOGF" 2>&1 || error_out
echo -e "[*] Building..."
STEP=build
LOGF=$CURDIR/${COMP}_${STEP}.log
make > "$LOGF" 2>&1 || error_out
echo -e "[*] Installing..."
STEP=install
LOGF=$CURDIR/${COMP}_${STEP}.log
$INSTALL_SUDO make install > "$LOGF" 2>&1 || error_out
cd "$CURDIR"
#############################################################################
COMP=ideviceinstaller
echo -e "${BOLD}#### Building ideviceinstaller ####${NORMAL}"
cd ideviceinstaller
echo -e "[*] Configuring..."
STEP=configure
LOGF=$CURDIR/${COMP}_${STEP}.log
./autogen.sh --prefix="$PREFIX" \
libzip_CFLAGS="$LIBZIP_CFLAGS" libzip_LIBS="$LIBZIP_LIBS" libzip_VERSION="$LIBZIP_VERSION" \
libimobiledevice_CFLAGS="$LIMD_CFLAGS" libimobiledevice_LIBS="$LIMD_LIBS" libimobiledevice_VERSION="$LIMD_VERSION" \
libplist_CFLAGS="$LIBPLIST_CFLAGS" libplist_LIBS="$LIBPLIST_LIBS" libplist_VERSION="$LIBPLIST_VERSION" \
> "$LOGF" 2>&1 || error_out
echo -e "[*] Building..."
STEP=build
LOGF=$CURDIR/${COMP}_${STEP}.log
make > "$LOGF" 2>&1 || error_out
echo -e "[*] Installing..."
STEP=install
LOGF=$CURDIR/${COMP}_${STEP}.log
$INSTALL_SUDO make install > "$LOGF" 2>&1 || error_out
cd "$CURDIR"
#############################################################################
if test "$HAVE_MACFUSE" == "yes"; then
COMP=ifuse
echo -e "${BOLD}#### Building ifuse ####${NORMAL}"
cd ifuse
echo -e "[*] Configuring..."
STEP=configure
LOGF=$CURDIR/${COMP}_${STEP}.log
./autogen.sh --prefix="$PREFIX" \
libfuse_CFLAGS="-I/usr/local/include/fuse -D_FILE_OFFSET_BITS=64" libfuse_LIBS="-L/usr/local/lib -lfuse -pthread" libfuse_VERSION="12.0.0" \
libimobiledevice_CFLAGS="$LIMD_CFLAGS" libimobiledevice_LIBS="$LIMD_LIBS" libimobiledevice_VERSION="$LIMD_VERSION" \
libplist_CFLAGS="$LIBPLIST_CFLAGS" libplist_LIBS="$LIBPLIST_LIBS" libplist_VERSION="$LIBPLIST_VERSION" \
> "$LOGF" 2>&1 || error_out
echo -e "[*] Building..."
STEP=build
LOGF=$CURDIR/${COMP}_${STEP}.log
make > "$LOGF" 2>&1 || error_out
echo -e "[*] Installing..."
STEP=install
LOGF=$CURDIR/${COMP}_${STEP}.log
$INSTALL_SUDO make install > "$LOGF" 2>&1 || error_out
cd "$CURDIR"
fi
#############################################################################
echo
echo -e "${CYAN}######## BUILD COMPLETE ########${NORMAL}"
echo
echo -e "${BOLD}If you like this script and my work on libimobiledevice, please
consider becoming a patron at ${YELLOW}https://patreon.com/nikias${NORMAL}${BOLD} - Thanks ${RED}<3${NORMAL}"
echo
#############################################################################
@felikcat
Copy link

This script seems broken for macOS Monterey (version 12.1).

  1. libzip fails to download due to curl's * error:06FFF089:digital envelope routines:CRYPTO_internal:bad key length, and seems specific to macOS Monterey.
    Using the latest LibreSSL from brew (defined the exports listed by brew info libressl in .zshrc, so it was used correctly) didn't fix this, neither did the latest OpenSSL from brew.
  2. libimobiledevice fails compiling due to no detected SSL library; here's my configure.log: https://gist.github.com/Iazos/2d7ceeb7b33e3bf466e87b05bbf3273a
    I've tried using different versions of LibreSSL and OpenSSL for openssl_CFLAGS and openssl_LIBS, with no success.

@nikias
Copy link
Author

nikias commented Jan 15, 2022

@nermur should be fixed now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment