Skip to content

Instantly share code, notes, and snippets.

@philip-lamb
Last active August 28, 2021 22:34
Show Gist options
  • Select an option

  • Save philip-lamb/9454ccfe4d7ba59a9c40acfddaf99c0a to your computer and use it in GitHub Desktop.

Select an option

Save philip-lamb/9454ccfe4d7ba59a9c40acfddaf99c0a to your computer and use it in GitHub Desktop.
Bash script to merge static libraries together, useable for macOS, iOS, Android and Linux libraries.
#! /bin/bash
#
# Usage ./merge_static_libs.sh [--prefix <prefix>] [--ext <ext>] [--indir <indir>] [--target_platform macos|ios|android|linux] [--android_toolchain <toolchain> outlib inlib1 [inlib2] [inlib3] [...]
# <prefix> defaults to 'lib', <ext> defaults to '.a', <indir> defaults to '.'
# <toolchain> defaults to "arm-linux-androideabi". Other options: "aarch64-linux-android", "x86", "x86_64", "mipsel-linux-android", "mips64el-linux-android".
#
#
TMPFILE=/tmp/$$
trap "rm -f $TMPFILE; exit 0" 0 1 2 3 15
OS=`uname -s`
ARCH=`uname -m`
# Defaults.
if [ "$OS" = "Linux" ]
then
HOST="linux-${ARCH}"
TARGET='linux'
elif [ "$OS" = "Darwin" ]
then
HOST="darwin-${ARCH}"
TARGET='macos'
elif [ "$OS" = "CYGWIN_NT-6.1" ]
then
HOST="windows-${ARCH}"
TARGET='windows'
else
echo "Unsupported host platform." && exit 1
fi
INPATH=${PWD}
LIBPREFIX="lib"
LIBEXT=".a"
TOOLCHAIN="arm-linux-androideabi"
# Parse command line.
while test $# -gt 0
do
case "$1" in
--prefix) LIBPREFIX="$2" ; shift
;;
--ext) LIBEXT="$2" ; shift
;;
--indir) INPATH="$2" ; shift
;;
--target_platform) TARGET="$2" ; shift
;;
--android_toolchain) TOOLCHAIN="$2" ; shift
;;
--*) echo "bad option $1"
;;
*)
if [ -z "${OUT}" ]; then
OUT="$1"
else
LIBS+=("$1")
fi
;;
esac
shift
done
if [ -z "${OUT}" ]; then
echo "No output library specified." && exit 1
fi
if [ ${#LIBS[@]} -eq 0 ]; then
echo "No input library/libraries specified." && exit 1
fi
# For debugging input.
#echo --prefix ${LIBPREFIX} --ext ${LIBEXT} --indir ${INPATH} --target_platform ${TARGET} ${OUT} ${LIBS[@]} && exit
if [ "${TARGET}" = "android" ] ; then
if [ -z "${ANDROID_NDK_ROOT}" ]; then
echo "ANDROID_NDK_ROOT is not set." && exit 1
fi
TOOLCHAIN_VERSION="4.9"
TOOLSBIN=$ANDROID_NDK_ROOT/toolchains/$TOOLCHAIN-$TOOLCHAIN_VERSION/prebuilt/$HOST/$TOOLCHAIN/bin
echo "CREATE $LIBPREFIX$OUT$LIBEXT" >$TMPFILE
for lib in ${LIBS[@]}
do
echo "ADDLIB $INPATH/$LIBPREFIX$lib$LIBEXT" >>$TMPFILE
done
echo "SAVE" >>$TMPFILE
echo "END" >>$TMPFILE
$TOOLSBIN/ar -M <$TMPFILE
$TOOLSBIN/ranlib $LIBPREFIX$OUT$LIBEXT
elif [ "${TARGET}" = "macos" ] || [ "${TARGET}" = "ios" ] ; then
ARCHS=`lipo -info $INPATH/$LIBPREFIX${LIBS[0]}$LIBEXT | sed -En -e 's/^(Non-|Architectures in the )fat file: .+( is architecture| are): (.*)$/\3/p'`
if (( $(wc -w <<<"$ARCHS") > 1 )) ; then
for arch in $ARCHS
do
for lib in ${LIBS[@]}
do
lipo -extract $arch $INPATH/$LIBPREFIX$lib$LIBEXT -o $LIBPREFIX$lib-$arch$LIBEXT
done
INLIBS="${LIBS[*]}"
INLIBS=`eval echo $LIBPREFIX\{${INLIBS// /,}\}-$arch$LIBEXT`
libtool -static -o $LIBPREFIX$OUT-$arch$LIBEXT $INLIBS
rm $INLIBS
done
OUTLIBS=`eval echo $LIBPREFIX$OUT-\{${ARCHS// /,}\}$LIBEXT`
lipo -create $OUTLIBS -o $LIBPREFIX$OUT$LIBEXT
rm $OUTLIBS
else
INLIBS="${LIBS[*]}"
INLIBS=`eval echo $INPATH/$LIBPREFIX\{${INLIBS// /,}\}$LIBEXT`
libtool -static -o $LIBPREFIX$OUT$LIBEXT $INLIBS
fi
elif [ "${TARGET}" = "linux" ] ; then
echo "CREATE $LIBPREFIX$OUT$LIBEXT" >$TMPFILE
for lib in ${LIBS[@]}
do
echo "ADDLIB $INPATH/$LIBPREFIX$lib$LIBEXT" >>$TMPFILE
done
echo "SAVE" >>$TMPFILE
echo "END" >>$TMPFILE
ar -M <$TMPFILE
ranlib $LIBPREFIX$OUT$LIBEXT
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment