Files
DroidDeck/tools/proot/build.sh

81 lines
3.8 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
OUTDIR=$(mkdir -p "$1" && cd "$1" && pwd)
: "${NDK:?set NDK to the Android NDK root}"
API=26
HERE=$(cd "$(dirname "$0")" && pwd)
. "$HERE/source.env"
case "$(uname -s):$(uname -m)" in
Darwin:*) NDK_HOST=darwin-x86_64 ;;
Linux:x86_64) NDK_HOST=linux-x86_64 ;;
Linux:aarch64|Linux:arm64) NDK_HOST=linux-aarch64 ;;
*) echo "Unsupported build host: $(uname -s) $(uname -m)" >&2; exit 1 ;;
esac
TOOLCHAIN="$NDK/toolchains/llvm/prebuilt/$NDK_HOST/bin"
if [[ ! -d "$TOOLCHAIN" && -d "$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin" ]]; then
TOOLCHAIN="$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin"
fi
CC="$TOOLCHAIN/aarch64-linux-android${API}-clang"
if [[ ! -x "$CC" ]]; then
echo "Android NDK toolchain not found at $TOOLCHAIN" >&2
exit 1
fi
WORK=$(mktemp -d)
trap 'rm -rf "$WORK"' EXIT
fetch() {
local name=$1 primary=$2 sha=$3 url fetched=0
shift 3
for url in "$primary" "$@"; do
if curl -fsSL --connect-timeout 15 --max-time 90 --retry 3 --retry-all-errors --retry-max-time 120 -o "$WORK/$name" "$url" &&
printf '%s %s\n' "$sha" "$WORK/$name" | shasum -a 256 -c -; then
fetched=1
break
fi
done
[[ $fetched == 1 ]] || return 1
mkdir -p "$WORK/${name%%.*}"
tar -xzf "$WORK/$name" -C "$WORK/${name%%.*}" --strip-components=1
}
fetch proot.tar.gz "https://github.com/termux/proot/archive/${PROOT_COMMIT}.tar.gz" "$PROOT_SHA256"
fetch talloc.tar.gz "https://www.samba.org/ftp/talloc/talloc-${TALLOC_VERSION}.tar.gz" "$TALLOC_SHA256" \
"https://distfiles.macports.org/talloc/talloc-${TALLOC_VERSION}.tar.gz"
cp "$HERE/statx_mnt_id.h" "$WORK/proot/src/tracee/statx_mnt_id.h"
cp "$HERE/profile.h" "$WORK/proot/src/syscall/profile.h"
for patch in "$HERE"/patches/*.patch; do
patch -d "$WORK/proot" -p1 --forward --quiet < "$patch"
done
mkdir -p "$WORK/talloc/config"
cp "$HERE/talloc-config.h" "$WORK/talloc/config/config.h"
"$CC" -c -O2 -fPIC -ffile-prefix-map="$WORK"=. -D__STDC_WANT_LIB_EXT1__=1 -DHAVE_CONFIG_H \
-I"$WORK/talloc/config" -I"$WORK/talloc" -I"$WORK/talloc/lib/replace" \
-o "$WORK/talloc.o" "$WORK/talloc/talloc.c"
"$TOOLCHAIN/llvm-ar" rcs "$WORK/libtalloc.a" "$WORK/talloc.o"
mkdir -p "$WORK/bin"
ln -s "$TOOLCHAIN/llvm-readelf" "$WORK/bin/readelf"
# loader-info.awk needs strtonum, which mawk (the default awk on some runners) lacks.
if command -v gawk >/dev/null; then
ln -s "$(command -v gawk)" "$WORK/bin/awk"
elif ! awk 'BEGIN { exit !(strtonum("0x10") == 16) }' 2>/dev/null; then
echo "gawk, or an awk with strtonum, is required to build the proot loader" >&2
exit 1
fi
PATH="$WORK/bin:$PATH" make -C "$WORK/proot/src" -j"$(getconf _NPROCESSORS_ONLN)" \
CC="$CC" STRIP="$TOOLCHAIN/llvm-strip" OBJCOPY="$TOOLCHAIN/llvm-objcopy" OBJDUMP="$TOOLCHAIN/llvm-objdump" \
CPPFLAGS="-D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I. -I$WORK/talloc -DARG_MAX=131072 -Wno-error=implicit-function-declaration" \
LDFLAGS="$WORK/libtalloc.a -Wl,-z,noexecstack" \
PROOT_UNBUNDLE_LOADER=/nonexistent proot loader
install -m755 "$WORK/proot/src/proot" "$OUTDIR/libproot.so"
install -m755 "$WORK/proot/src/loader/loader" "$OUTDIR/libproot-loader.so"
"$TOOLCHAIN/llvm-strip" --strip-unneeded "$OUTDIR/libproot.so"
"$TOOLCHAIN/llvm-strip" --strip-unneeded "$OUTDIR/libproot-loader.so"
grep -q '^#define HAVE_SECCOMP_FILTER' "$WORK/proot/src/build.h" || { echo "ERROR: proot was built without seccomp acceleration"; exit 1; }
grep -q '^#define HAVE_PROCESS_VM' "$WORK/proot/src/build.h" || { echo "ERROR: proot was built without process_vm"; exit 1; }
NEEDED=$("$TOOLCHAIN/llvm-readelf" -d "$OUTDIR/libproot.so" | sed -n 's/.*NEEDED.*\[\(.*\)\]/\1/p' | tr '\n' ' ')
echo "libproot.so NEEDED: $NEEDED"
for lib in $NEEDED; do
case $lib in libc.so|libdl.so|libm.so) ;;
*) echo "ERROR: unexpected dependency $lib"; exit 1 ;;
esac
done
ls -l "$OUTDIR/libproot.so" "$OUTDIR/libproot-loader.so"