mirror of
https://github.com/radareorg/radare2
synced 2026-08-22 20:23:32 -04:00
Add android-sdk script for multiabi toolchain ##build
This commit is contained in:
parent
8b81db6bb6
commit
8f7f618025
2 changed files with 284 additions and 2 deletions
280
sys/android-sdk.sh
Executable file
280
sys/android-sdk.sh
Executable file
|
|
@ -0,0 +1,280 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Android SDK builder
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
CALLER_DIR=$PWD
|
||||
cd "$(dirname "$0")/.."
|
||||
ROOT=$PWD
|
||||
SCRIPT="$ROOT/sys/android-sdk.sh"
|
||||
PREFIX=/usr/local
|
||||
DEFAULT_ARCHS="arm+arm64+x86+x86_64"
|
||||
ARCHS=$DEFAULT_ARCHS
|
||||
ANDROID_API=${ANDROID_API:-28}
|
||||
JOBS=${JOBS:-4}
|
||||
OUTPUT=""
|
||||
PLUGINS_CFG=${R2_PLUGINS_CFG:-dist/plugins-cfg/plugins.android.cfg}
|
||||
if [ -z "${SOURCE_DATE_EPOCH:-}" ]; then
|
||||
SOURCE_DATE_EPOCH=$(git log -1 --format=%ct 2>/dev/null || date +%s)
|
||||
fi
|
||||
|
||||
showHelp() {
|
||||
echo "Android SDK builder"
|
||||
echo
|
||||
echo "Usage: $0 [options]"
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " -a, --archs ARCHS Architectures separated by + or ,"
|
||||
echo " (arm, arm64, x86, x86_64; default: $DEFAULT_ARCHS)"
|
||||
echo " --api LEVEL Android API level (default: $ANDROID_API)"
|
||||
echo " -j, --jobs JOBS Parallel build jobs (default: $JOBS)"
|
||||
echo " -o, --output FILE Output zip path"
|
||||
echo " -h, --help Show this help"
|
||||
echo
|
||||
echo "Examples:"
|
||||
echo " sys/android-sdk.sh"
|
||||
echo " sys/android-sdk.sh -a arm64+x86_64 --api 28"
|
||||
}
|
||||
|
||||
fail() {
|
||||
echo "android-sdk: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
buildAbi() {
|
||||
local ndk_arch=$1
|
||||
local android_abi=$2
|
||||
local target=$3
|
||||
local install_dst=$4
|
||||
local make=make
|
||||
|
||||
if gmake --help >/dev/null 2>&1; then
|
||||
make=gmake
|
||||
fi
|
||||
|
||||
export CFLAGS="-fPIC -Oz -DNDEBUG"
|
||||
export LDFLAGS=""
|
||||
case "$ndk_arch" in
|
||||
aarch64|x86_64)
|
||||
export LDFLAGS="-Wl,-z,max-page-size=16384"
|
||||
;;
|
||||
esac
|
||||
export AR=llvm-ar
|
||||
export RANLIB=llvm-ranlib
|
||||
|
||||
echo "Building Android SDK libraries for $android_abi (API $ANDROID_API)"
|
||||
"$make" mrproper
|
||||
cp -f "$PLUGINS_CFG" plugins.cfg
|
||||
./configure --with-compiler=android --with-ostype=android \
|
||||
--target="$target" --prefix="$PREFIX" --with-libr \
|
||||
--with-bundle-prefix --without-gpl --without-sqsh \
|
||||
--with-checks-level=0
|
||||
"$make" -s -j "$JOBS"
|
||||
"$make" -s install DESTDIR="$install_dst"
|
||||
}
|
||||
|
||||
if [ "${1:-}" = "--build-abi" ]; then
|
||||
[ $# = 5 ] || fail "invalid internal build arguments"
|
||||
buildAbi "$2" "$3" "$4" "$5"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-a|--archs)
|
||||
[ $# -gt 1 ] || fail "$1 requires an argument"
|
||||
ARCHS=$2
|
||||
shift 2
|
||||
;;
|
||||
--api)
|
||||
[ $# -gt 1 ] || fail "$1 requires an argument"
|
||||
ANDROID_API=$2
|
||||
shift 2
|
||||
;;
|
||||
-j|--jobs)
|
||||
[ $# -gt 1 ] || fail "$1 requires an argument"
|
||||
JOBS=$2
|
||||
shift 2
|
||||
;;
|
||||
-o|--output)
|
||||
[ $# -gt 1 ] || fail "$1 requires an argument"
|
||||
OUTPUT=$2
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
showHelp
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
fail "unknown option: $1"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "$ANDROID_API" in
|
||||
""|*[!0-9]*)
|
||||
fail "invalid Android API level: $ANDROID_API"
|
||||
;;
|
||||
esac
|
||||
case "$JOBS" in
|
||||
""|*[!0-9]*)
|
||||
fail "invalid job count: $JOBS"
|
||||
;;
|
||||
esac
|
||||
[ "$JOBS" -gt 0 ] || fail "job count must be greater than zero"
|
||||
command -v zip >/dev/null 2>&1 || fail "zip is required"
|
||||
|
||||
VERSION=$(./configure -qV)
|
||||
SDK_NAME="radare2-$VERSION-android-sdk"
|
||||
if [ -z "$OUTPUT" ]; then
|
||||
OUTPUT="$CALLER_DIR/$SDK_NAME.zip"
|
||||
elif [ "${OUTPUT#/}" = "$OUTPUT" ]; then
|
||||
OUTPUT="$CALLER_DIR/$OUTPUT"
|
||||
fi
|
||||
|
||||
WORKDIR=$(mktemp -d "${TMPDIR:-/tmp}/r2-android-sdk.XXXXXX")
|
||||
SDK_ROOT="$WORKDIR/package/$SDK_NAME"
|
||||
mkdir -p "$SDK_ROOT/include" "$SDK_ROOT/lib"
|
||||
|
||||
cleanup() {
|
||||
rm -rf "$WORKDIR"
|
||||
}
|
||||
trap cleanup EXIT HUP INT TERM
|
||||
|
||||
copyLibraries() {
|
||||
local source_dir=$1
|
||||
local dest_dir=$2
|
||||
local source_file
|
||||
local dest_file
|
||||
|
||||
mkdir -p "$dest_dir"
|
||||
while IFS= read -r source_file; do
|
||||
dest_file="$dest_dir/$(basename "$source_file")"
|
||||
if [ -f "$dest_file" ] && ! cmp -s "$source_file" "$dest_file"; then
|
||||
fail "library name collision: $(basename "$source_file")"
|
||||
fi
|
||||
cp -Lf "$source_file" "$dest_file"
|
||||
done < <(find "$source_dir" \( -type f -o -type l \) \( -name '*.a' -o -name '*.so' \) -print)
|
||||
}
|
||||
|
||||
rewritePkgConfig() {
|
||||
local pkg_dir=$1
|
||||
local android_abi=$2
|
||||
local pc
|
||||
|
||||
[ -d "$pkg_dir" ] || return 0
|
||||
for pc in "$pkg_dir"/*.pc; do
|
||||
[ -f "$pc" ] || continue
|
||||
sed \
|
||||
-e 's|^prefix=.*|prefix=${pcfiledir}/../../..|' \
|
||||
-e 's|^exec_prefix=.*|exec_prefix=${prefix}|' \
|
||||
-e "s|^libdir=.*|libdir=\${prefix}/lib/$android_abi|" \
|
||||
-e 's|^includedir=.*|includedir=${prefix}/include|' \
|
||||
"$pc" > "$pc.tmp"
|
||||
mv -f "$pc.tmp" "$pc"
|
||||
done
|
||||
}
|
||||
|
||||
FIRST_ABI=1
|
||||
BUILT_ABIS=""
|
||||
NORMALIZED_ARCHS=$(printf '%s' "$ARCHS" | tr ',+' ' ')
|
||||
export ANDROID_API JOBS PLUGINS_CFG SOURCE_DATE_EPOCH
|
||||
|
||||
for arch in $NORMALIZED_ARCHS; do
|
||||
case "$arch" in
|
||||
arm|armeabi-v7a)
|
||||
NDK_ARCH=arm
|
||||
ANDROID_ABI=armeabi-v7a
|
||||
TARGET=arm-linux-androideabi
|
||||
;;
|
||||
arm64|aarch64|arm64-v8a)
|
||||
NDK_ARCH=aarch64
|
||||
ANDROID_ABI=arm64-v8a
|
||||
TARGET=aarch64-linux-android
|
||||
;;
|
||||
x86)
|
||||
NDK_ARCH=x86
|
||||
ANDROID_ABI=x86
|
||||
TARGET=i686-linux-android
|
||||
;;
|
||||
x64|x86_64)
|
||||
NDK_ARCH=x86_64
|
||||
ANDROID_ABI=x86_64
|
||||
TARGET=x86_64-linux-android
|
||||
;;
|
||||
*)
|
||||
fail "unsupported architecture: $arch"
|
||||
;;
|
||||
esac
|
||||
|
||||
case " $BUILT_ABIS " in
|
||||
*" $ANDROID_ABI "*)
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
BUILT_ABIS="$BUILT_ABIS $ANDROID_ABI"
|
||||
INSTALL_DST="$WORKDIR/install-$ANDROID_ABI"
|
||||
mkdir -p "$INSTALL_DST"
|
||||
sys/android-shell.sh "$NDK_ARCH" "$SCRIPT" --build-abi \
|
||||
"$NDK_ARCH" "$ANDROID_ABI" "$TARGET" "$INSTALL_DST"
|
||||
INSTALL_PREFIX="$INSTALL_DST$PREFIX"
|
||||
[ -d "$INSTALL_PREFIX/include/libr" ] || fail "missing headers for $ANDROID_ABI"
|
||||
[ -d "$INSTALL_PREFIX/lib" ] || fail "missing libraries for $ANDROID_ABI"
|
||||
|
||||
if [ "$FIRST_ABI" = 1 ]; then
|
||||
cp -R "$INSTALL_PREFIX/include/." "$SDK_ROOT/include"
|
||||
if [ -d "$INSTALL_PREFIX/share/radare2" ]; then
|
||||
mkdir -p "$SDK_ROOT/share"
|
||||
cp -R "$INSTALL_PREFIX/share/radare2" "$SDK_ROOT/share/radare2"
|
||||
fi
|
||||
FIRST_ABI=0
|
||||
elif ! diff -qr "$SDK_ROOT/include" "$INSTALL_PREFIX/include" >/dev/null; then
|
||||
diff -ru "$SDK_ROOT/include" "$INSTALL_PREFIX/include" || true
|
||||
fail "installed headers differ for $ANDROID_ABI"
|
||||
fi
|
||||
|
||||
ABI_LIBDIR="$SDK_ROOT/lib/$ANDROID_ABI"
|
||||
copyLibraries "$INSTALL_PREFIX/lib" "$ABI_LIBDIR"
|
||||
if [ -d "$INSTALL_PREFIX/lib/pkgconfig" ]; then
|
||||
mkdir -p "$ABI_LIBDIR/pkgconfig"
|
||||
cp -R "$INSTALL_PREFIX/lib/pkgconfig/." "$ABI_LIBDIR/pkgconfig"
|
||||
rewritePkgConfig "$ABI_LIBDIR/pkgconfig" "$ANDROID_ABI"
|
||||
fi
|
||||
find "$ABI_LIBDIR" -maxdepth 1 -name '*.a' -print -quit | grep -q . || \
|
||||
fail "no static libraries found for $ANDROID_ABI"
|
||||
find "$ABI_LIBDIR" -maxdepth 1 -name '*.so' -print -quit | grep -q . || \
|
||||
fail "no shared libraries found for $ANDROID_ABI"
|
||||
done
|
||||
|
||||
[ "$FIRST_ABI" = 0 ] || fail "no architectures selected"
|
||||
cp -f COPYING.md "$SDK_ROOT"
|
||||
printf '%s\n' \
|
||||
"radare2 Android SDK $VERSION" \
|
||||
"" \
|
||||
"Android API level: $ANDROID_API" \
|
||||
"ABIs:$BUILT_ABIS" \
|
||||
"" \
|
||||
"Layout:" \
|
||||
" include/libr/ Public radare2 headers" \
|
||||
" lib/<android-abi>/ Static and shared libraries" \
|
||||
" lib/<android-abi>/pkgconfig/ Relocatable pkg-config files" \
|
||||
" share/ Runtime data files" \
|
||||
"" \
|
||||
"Use include/libr as an include directory and lib/\${ANDROID_ABI} as" \
|
||||
"a library directory. Set PKG_CONFIG_PATH to the matching pkgconfig" \
|
||||
"directory when using pkg-config." > "$SDK_ROOT/README.txt"
|
||||
printf 'version=%s\napi=%s\nabis=%s\n' \
|
||||
"$VERSION" "$ANDROID_API" "${BUILT_ABIS# }" > "$SDK_ROOT/METADATA"
|
||||
|
||||
mkdir -p "$(dirname "$OUTPUT")"
|
||||
ZIP_PATH="$WORKDIR/$SDK_NAME.zip"
|
||||
(
|
||||
cd "$WORKDIR/package"
|
||||
zip -qry "$ZIP_PATH" "$SDK_NAME"
|
||||
)
|
||||
if command -v unzip >/dev/null 2>&1; then
|
||||
unzip -tq "$ZIP_PATH" >/dev/null
|
||||
fi
|
||||
mv -f "$ZIP_PATH" "$OUTPUT"
|
||||
echo "$OUTPUT"
|
||||
|
|
@ -104,15 +104,17 @@ fi
|
|||
echo ROOT=$ROOT
|
||||
echo NDK="$NDK"
|
||||
echo NDK_ARCH=$NDK_ARCH
|
||||
[ -z "${ANDROID_API}" ] && ANDROID_API=28
|
||||
echo ANDROID_API=$ANDROID_API
|
||||
|
||||
TOOLCHAIN_ID="${NDK}:${ARCH}"
|
||||
TOOLCHAIN_ID="${NDK}:${ARCH}:${ANDROID_API}"
|
||||
TOOLCHAIN_ID_FILE=/tmp/ndk/.r2-toolchain
|
||||
CURRENT_TOOLCHAIN_ID=`cat "${TOOLCHAIN_ID_FILE}" 2>/dev/null`
|
||||
if [ -x /tmp/ndk/bin/ndk-gcc ] && [ "${CURRENT_TOOLCHAIN_ID}" = "${TOOLCHAIN_ID}" ]; then
|
||||
echo "NDK toolchain already initialized."
|
||||
else
|
||||
echo "Building the standalone NDK toolchain..."
|
||||
${NDK}/build/tools/make_standalone_toolchain.py --arch=${ARCH} --install-dir=/tmp/ndk/ --api=28 --force || exit 1
|
||||
${NDK}/build/tools/make_standalone_toolchain.py --arch=${ARCH} --install-dir=/tmp/ndk/ --api=${ANDROID_API} --force || exit 1
|
||||
(
|
||||
cd /tmp/ndk/bin/ && \
|
||||
ln -fs clang ndk-gcc && \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue