From 0124825ffba11a0efa70201470d6b7080dffeb90 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 12 Jun 2024 13:52:33 +0800 Subject: [PATCH] Improve compression of Emacs packages on Android 2.2 * configure.ac (ZIP): Search for a `zip' executable and substitute the same if targeting SDK 8. * java/INSTALL: Document new requirement. * java/Makefile.in (GZIP_PROG, ZIP): New substitutions. (.PHONY): Delete references to directory-tree. (install_temp): On SDK 8 and earlier, compress large *.el and Info files with gzip, and divide install_temp into three separate directories, with one for large files, another for gzipped files, and one more for the remainder. (install_temp/assets/directory-tree, install_temp/assets/version) (install_temp/assets/build_info): Merge these rules into install_tmp, that they may execute before the assets directory is split. (emacs.apk-in): Package each directory separately, accounting for their varied compression requirements. * lisp/term/android-win.el (input-decode-map): Define select to return in input-decode-map. (cherry picked from commit 5fc75b051fc623a4f614a7abe09f08d127ed9ccd) --- configure.ac | 6 ++ java/INSTALL | 11 ++-- java/Makefile.in | 120 ++++++++++++++++++++++++++++++--------- lisp/term/android-win.el | 3 + 4 files changed, 109 insertions(+), 31 deletions(-) diff --git a/configure.ac b/configure.ac index 2e0797f822c..6a77e5cede0 100644 --- a/configure.ac +++ b/configure.ac @@ -877,6 +877,7 @@ AC_ARG_VAR([JAVAC], [Java compiler path. Used for Android.]) AC_ARG_VAR([JARSIGNER], [Java package signer path. Used for Android.]) AC_ARG_VAR([APKSIGNER], [Android package signer path. Used for Android.]) AC_ARG_VAR([SDK_BUILD_TOOLS], [Path to the Android SDK build tools.]) +AC_ARG_VAR([ZIP], [Path to the `zip' utility.]) if test "$with_android" = "yes"; then AC_MSG_ERROR([Please specify the path to the Android.jar file, like so: @@ -1222,8 +1223,13 @@ package will likely install on older systems but crash on startup.]) ANDROID_SDK_8_OR_EARLIER= if test "$android_sdk" -le "8"; then ANDROID_SDK_8_OR_EARLIER=yes + AC_CHECK_PROGS([ZIP], [zip]) + AS_IF([test -z "$ZIP"], + [AC_MSG_ERROR([The `zip' utility is required for generating \ +packages targeting Android 2.2.])]) fi AC_SUBST([ANDROID_SDK_8_OR_EARLIER]) + AC_SUBST([ZIP]) # Save confdefs.h and config.log for now. mv -f confdefs.h _confdefs.h diff --git a/java/INSTALL b/java/INSTALL index 1d6f1535647..91916c6586c 100644 --- a/java/INSTALL +++ b/java/INSTALL @@ -158,10 +158,13 @@ the NDK r10b or later. We wanted to make Emacs work on even older versions of Android, but they are missing the required JNI graphics library that allows Emacs to display text from C code. -Due to an extremely nasty bug in the Android 2.2 system, the generated -Emacs package cannot be compressed in builds for Android 2.2. As a -result, the Emacs package will be approximately 100 megabytes larger -than a compressed package for a newer version of Android. +There is an extremely nasty bug in the Android 2.2 system, the upshot of +which is that large files within the generated Emacs package cannot be +compressed in builds for Android 2.2, so that the Emacs package will be +approximately 15 megabytes larger than a compressed package for a newer +version of Android. For such systems the `zip' utility is also required +to produce packages that will not be misinterpreted by the package +manager. BUILDING C++ DEPENDENCIES diff --git a/java/Makefile.in b/java/Makefile.in index 83df6384650..9e0fb10eba7 100644 --- a/java/Makefile.in +++ b/java/Makefile.in @@ -44,10 +44,20 @@ ANDROID_JAR = @ANDROID_JAR@ ANDROID_ABI = @ANDROID_ABI@ ANDROID_SDK_18_OR_EARLIER = @ANDROID_SDK_18_OR_EARLIER@ ANDROID_SDK_8_OR_EARLIER = @ANDROID_SDK_8_OR_EARLIER@ +ZIP = @ZIP@ WARN_JAVAFLAGS = @WARN_JAVAFLAGS@ JAVAFLAGS = $(WARN_JAVAFLAGS) -classpath "$(ANDROID_JAR):$(srcdir)" FIND_DELETE = @FIND_DELETE@ +ifneq (,$(ANDROID_SDK_8_OR_EARLIER)) +# gzip is invoked to compress installed .el and some .txt files, on SDK +# 8 and earlier, where ZIP compression is unavailable. +GZIP_PROG = @GZIP_PROG@ +else +GZIP_PROG = +endif + + # Android 4.3 and earlier require Emacs to be signed with a different # digital signature algorithm. @@ -187,7 +197,7 @@ $(libsrc)/asset-directory-tool: # There is no need to depend on NDK_BUILD_SHARED as libemacs.so # does already. -.PHONY: install_temp install_temp/assets/directory-tree +.PHONY: install_temp install_temp: $(CROSS_BINS) $(CROSS_LIBS) $(RESOURCE_FILES) $(AM_V_GEN) # Make the working directory for this stuff @@ -222,6 +232,54 @@ install_temp: $(CROSS_BINS) $(CROSS_LIBS) $(RESOURCE_FILES) rm -rf $${subdir}/[mM]akefile*[.-]in ; \ rm -rf $${subdir}/Makefile; \ done +# Compress files if AAPT otherwise will not. + $(AM_V_SILENT) \ + [ -z "${GZIP_PROG}" ] || { \ + echo "Compressing large *.el *.info etc. ..." && \ + cd "install_temp/assets/lisp" && \ + for f in `find . -name "*.elc" \( -size +1536 -o \ + -size 1536 \) -print \ + | sed 's/.elc$$/.el/'`; do \ + ${GZIP_PROG} -9n "$$f"; \ + done; \ + ${GZIP_PROG} -9n "../etc/publicsuffix.txt"; \ + find ../info -name "*.elc" -size 1536 -o -size +1536 \ + | xargs ${GZIP_PROG} -9n ; \ + } +# Produce metadata files providing build information and suchlike. + $(AM_V_SILENT) \ + { (cd $(top_srcdir) \ + && git rev-parse HEAD || echo "Unknown") \ + && (git rev-parse --abbrev-ref HEAD \ + || echo "Unknown") } 2> /dev/null > \ + install_temp/assets/version + $(AM_V_SILENT) \ + { hostname; date +%s; } > install_temp/assets/build_info +# Produce the file index. + $(AM_V_SILENT) $(libsrc)/asset-directory-tool \ + install_temp/assets install_temp/assets/directory-tree +# If the package targets Android 2.2, move compressable and +# non-compressable assets to separate directories. + $(AM_V_SILENT) \ + if [ -z "${ANDROID_SDK_8_OR_EARLIER}" ]; then :; else \ + echo "Moving large and gzipped files to separate directories...">&2;\ + mkdir -p install_temp/assets_raw; \ + cd install_temp/assets; \ + find . \( -size +1536 -o -size 1536 \) \ + \( \! -name '*.gz' \) -type f > files.txt; \ + tar cf ../assets_raw/largefiles.tar -T files.txt; \ + cat files.txt | xargs rm; \ + cd ../assets_raw && tar xf largefiles.tar \ + && rm largefiles.tar; \ + cd ..; \ + mkdir -p assets_gz; \ + find assets -name '*.gz' -type f > files.txt; \ + tar cf assets_gz/gzfiles.tar -T files.txt; \ + cat files.txt | xargs rm; \ + cd assets_gz && tar xf gzfiles.tar \ + && rm gzfiles.tar; \ + rm ../assets/files.txt; \ + fi # Generate the directory tree for those directories. # Install architecture dependents to lib/$(ANDROID_ABI). This # perculiar naming scheme is required to make Android preserve these @@ -251,35 +309,43 @@ ifneq ($(NDK_BUILD_SHARED),) install_temp/lib/$(ANDROID_ABI) endif -install_temp/assets/directory-tree: $(libsrc)/asset-directory-tool \ - install_temp install_temp/assets/version \ - install_temp/assets/build_info - $(AM_V_GEN) $(libsrc)/asset-directory-tool install_temp/assets \ - install_temp/assets/directory-tree - -install_temp/assets/version: install_temp - $(AM_V_GEN) { (cd $(top_srcdir) \ - && git rev-parse HEAD || echo "Unknown") \ - && (git rev-parse --abbrev-ref HEAD \ - || echo "Unknown") } 2> /dev/null > $@ - -install_temp/assets/build_info: install_temp - $(AM_V_GEN) { hostname; date +%s; } > $@ - -emacs.apk-in: install_temp install_temp/assets/directory-tree \ - AndroidManifest.xml install_temp/assets/version \ - install_temp/assets/build_info classes.dex +emacs.apk-in: install_temp AndroidManifest.xml classes.dex # Package everything. Redirect the generated R.java to install_temp, as # it must already have been generated as a prerequisite of -# classes.dex's. - $(AM_V_AAPT) $(AAPT) p -I "$(ANDROID_JAR)" -F $@ \ - -f -M AndroidManifest.xml $(AAPT_ASSET_ARGS) \ - -A install_temp/assets \ - -S $(top_srcdir)/java/res -J install_temp +# classes.dex's. If ANDROID_SDK_8_OR_EARLIER, compress those files +# which are smaller than 1536 blocks (i.e. 768 kib), the maximum the +# asset manager on such old systems can decompress. +# +# The elaborate dance with zip serves to disable the automatic +# decompression of *.gz files in aapt. +# +# One more consideration is that timestamps should be preserved in +# packaged libraries, as on Android 2.2 the package manager retains +# existing libraries from previous installations if a new package's +# libraries are not more recent. + $(AM_V_AAPT) \ + if [ -z "$(ANDROID_SDK_8_OR_EARLIER)" ]; then \ + $(AAPT) p -I "$(ANDROID_JAR)" -F $@ \ + -f -M AndroidManifest.xml $(AAPT_ASSET_ARGS) \ + -A install_temp/assets \ + -S $(top_srcdir)/java/res -J install_temp; \ + cd install_temp; \ + $(AAPT) add ../$@ `find lib -type f`; \ + else \ + echo "Packaging files not eligible for compression...">&2;\ + $(AAPT) p -I "$(ANDROID_JAR)" -F $@ \ + -f -M AndroidManifest.xml -A install_temp/assets_raw\ + -S $(top_srcdir)/java/res -J install_temp -0 ""; \ + echo "Packaging files eligible for compression...">&2;\ + cd install_temp; find assets -type f \ + | xargs $(ZIP) ../$@ &> /dev/null; \ + echo "Packagging files already compressed...">&2; \ + cd assets_gz; find assets -type f \ + | xargs $(ZIP) ../../$@ &> /dev/null; \ + echo "Packaging shared libraries and code..." >&2; \ + cd ..; $(ZIP) ../$@ `find lib -type f`; \ + fi $(AM_V_SILENT) $(AAPT) a $@ classes.dex - $(AM_V_SILENT) pushd install_temp &> /dev/null; \ - $(AAPT) add ../$@ `find lib -type f`; \ - popd &> /dev/null $(AM_V_SILENT) rm -rf install_temp # Makefile itself. diff --git a/lisp/term/android-win.el b/lisp/term/android-win.el index 3e0f71abf91..0d2d0299282 100644 --- a/lisp/term/android-win.el +++ b/lisp/term/android-win.el @@ -627,6 +627,9 @@ accessible to other programs." (global-set-key [\83] #'ignore) ; KEYCODE_NOTIFICATION on pre-Honeycomb ; releases. +;; `select' key, which I suppose amounts to return. +(define-key input-decode-map [select] [return]) + (provide 'android-win) ;; android-win.el ends here. -- 2.39.2