Files
mtgodot-poc/tools/py_embed_android/build-and-run.sh
T
shenleiandClaude Opus 5 b02c49bb2f spike(python): CPython 2.7.18 runs the 40250 root scripts on Android arm64
libpython2.7.a cross-builds with NDK 27.2 (API 24) after disabling
HAVE_LANGINFO_H; 30 C modules built in. On a OnePlus 13 (API 36) the
harness runs system.py -> prototype.RunApp() and imports the root modules
with results identical to macOS (66/74; the 8 failures are stub values or
dev-only scripts). py_embed_spike.py now isolates __main__ like
CPythonLauncher and reports stdlib usage.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 18:16:44 +09:00

53 lines
3.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Embedded CPython 2.7.18 on Android: build libpython2.7.a with the NDK, link a harness that runs
# py_embed_spike.py on a connected device. See docs/PYTHON-EMBED-EVAL.md ("Android 验证").
# tools/py_embed_android/build-and-run.sh [WORKDIR] (default: build/py_embed_android)
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
REPO="$(cd "$HERE/../.." && pwd)"
W="${1:-$REPO/build/py_embed_android}"
NDK="${ANDROID_NDK_HOME:-$(ls -d "$HOME/Library/Android/sdk/ndk/"* | sort -V | head -1)}"
TC="$NDK/toolchains/llvm/prebuilt/$(ls "$NDK/toolchains/llvm/prebuilt" | head -1)/bin"
API=24
ADB="${ADB:-adb}"
REF="${MT_40250_SOURCE:-$REPO/$(python3 -c 'import json;print(json.load(open("'"$REPO"'/audit/manifest.json"))["reference_root"])')}"
E="$REF/../../Client/Eternexus"
DEV=/data/local/tmp/pyspike
mkdir -p "$W" && cd "$W"
[ -f Python-2.7.18.tar.xz ] || curl -sSLO https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tar.xz
echo "b62c0e7937551d0cc02b8fd5cb0f544f9405bafc9a54d3808ed4594812edef43 Python-2.7.18.tar.xz" | shasum -a 256 -c -
[ -d Python-2.7.18 ] || tar xf Python-2.7.18.tar.xz
touch Python-2.7.18/Include/graminit.h Python-2.7.18/Python/graminit.c \
Python-2.7.18/Include/Python-ast.h Python-2.7.18/Python/Python-ast.c # no host pgen needed
mkdir -p cfg && cd cfg
if [ ! -f pyconfig.h ]; then
env -u CPPFLAGS -u LDFLAGS -u CFLAGS -u LIBS CONFIG_SITE=/dev/null \
CC="$TC/aarch64-linux-android$API-clang" AR="$TC/llvm-ar" RANLIB="$TC/llvm-ranlib" READELF="$TC/llvm-readelf" \
../Python-2.7.18/configure --host=aarch64-linux-android --build=aarch64-apple-darwin \
--disable-ipv6 --without-ensurepip --disable-shared ac_cv_file__dev_ptmx=yes ac_cv_file__dev_ptc=no > configure.log
# bionic declares nl_langinfo only from API 26
sed -i '' 's|^#define HAVE_LANGINFO_H 1|/* #undef HAVE_LANGINFO_H (nl_langinfo needs API 26) */|' pyconfig.h
# compile the C modules the 40250 scripts and their stdlib imports need into libpython
for m in array math _struct time operator _random _collections _heapq itertools strop _functools datetime \
_bisect _locale binascii cStringIO cPickle select fcntl; do
sed -i '' -E "s/^#($m )/\1/" Modules/Setup
done
sed -i '' -E 's/^(math mathmodule.c _math.c) # -lm/\1/; s/^(time timemodule.c) # -lm/\1/; s/^(_locale _localemodule.c) # -lintl/\1/' Modules/Setup
rm -f Modules/config.c
fi
env -u CPPFLAGS -u LDFLAGS -u CFLAGS make -j8 libpython2.7.a > make.log
cd ..
"$TC/aarch64-linux-android$API-clang" -O2 -fPIE -pie -Icfg -IPython-2.7.18/Include "$HERE/main.c" \
cfg/libpython2.7.a -lm -ldl -o pyspike
(cd Python-2.7.18/Lib && rm -f "$W/python27.zip" && zip -q -0 -r "$W/python27.zip" . -i '*.py' \
-x 'test/*' 'lib-tk/*' 'idlelib/*' 'lib2to3/*' 'bsddb/*' 'ensurepip/*' '*/test/*' '*/tests/*' 'plat-*')
rm -rf stage && mkdir -p stage/Eternexus/locale_en
cp -R "$E/root" "$E/uiscript" stage/Eternexus/ && cp -R "$E/locale_en/locale" stage/Eternexus/locale_en/
cp pyspike python27.zip "$REPO/.agents/skills/metin2-40250-parity-audit/scripts/py_embed_spike.py" stage/
"$ADB" shell rm -rf "$DEV" && "$ADB" push stage "$DEV" >/dev/null && "$ADB" shell chmod 755 "$DEV/pyspike"
"$ADB" shell "cd $DEV && MT_ETERNEXUS=$DEV/Eternexus ./pyspike $DEV 2>&1 | grep -v 'ignored\$' | head -3; sed -n '/modules loaded/,/native functions/p' result.txt"