]> git.eshelyaron.com Git - emacs.git/commitdiff
Port to Android 35
authorPo Lu <luangruo@yahoo.com>
Wed, 4 Sep 2024 09:24:34 +0000 (17:24 +0800)
committerEshel Yaron <me@eshelyaron.com>
Thu, 5 Sep 2024 05:42:19 +0000 (07:42 +0200)
* configure.ac: Temporary workaround for Gnulib bug.  Verify
that the provided android.jar corresponds to Android 35, or any
later version.

* cross/ndk-build/Makefile.in (NDK_BUILD_SO_LDFLAGS): New
variable.

* cross/ndk-build/ndk-resolve.mk
(NDK_LOCAL_A_NAMES_$(LOCAL_MODULE)): Define to
NDK_BUILD_SO_LDFLAGS by default to enable building binaries
with support for 16 kb page sizes.

* java/AndroidManifest.xml.in: Target SDK 35.

* java/INSTALL (16KB PAGE SIZES): New section.  Replace
references to Android 34 with 35.

* java/org/gnu/emacs/EmacsActivity.java (onCreate): Restore
pre-SDK 35 inset-relative placement.

* java/org/gnu/emacs/EmacsFillPolygon.java (perform): Suppress
deprecation warnings, and document why.

* m4/ndk-build.m4 (ndk_INIT, ndk_LATE): Check for and enable
toolchain support for 16 KB page sizes, if available.
(ndk_CONFIG_FILES): Export linker options so derived.

* src/conf_post.h [__ANDROID_API__ < 35]: Include system time.h
and redefine timezone_t to rpl_timezone_t, so that the Gnulib
replacement may not conflict with the useless OS type.

(cherry picked from commit 2847106f3b6174f25ab43551f96612209fe951c8)

configure.ac
cross/ndk-build/Makefile.in
cross/ndk-build/ndk-resolve.mk
java/AndroidManifest.xml.in
java/INSTALL
java/org/gnu/emacs/EmacsActivity.java
java/org/gnu/emacs/EmacsFillPolygon.java
m4/ndk-build.m4
src/conf_post.h

index ffed1900f617e16428488a4ebb44176247b3f6b9..0463c63b2c8fab912314f061e43cb75254383208 100644 (file)
@@ -49,6 +49,10 @@ if test "$XCONFIGURE" = "android"; then
     CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=32"
     enable_largefile=no
     enable_year2038=no])
+  # Prevent Gnulib from enabling time_rz.c on old Android releases, till
+  # Gnulib itself is fixed.
+  AS_IF([test "$ANDROID_SDK" -lt "35"],
+    [ac_cv_type_timezone_t=no])
 fi
 
 dnl Set emacs_config_options to the options of 'configure', quoted for the shell,
@@ -953,7 +957,7 @@ a valid path to android.jar.  See config.log for more details.])
   fi
 
   AC_CACHE_CHECK([whether android.jar is new enough],
-    [emacs_cv_android_u_or_later],
+    [emacs_cv_android_v_or_later],
     AS_IF([rm -f conftest.class
 cat << EOF > conftest.java
 
@@ -961,18 +965,18 @@ import android.os.Build;
 
 class conftest
 {
-  private static int test = Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
+  private static int test = Build.VERSION_CODES.VANILLA_ICE_CREAM;
 }
 
 EOF
 ("$JAVAC" -classpath "$with_android" -target 1.7 -source 1.7 conftest.java \
   -d . >&AS_MESSAGE_LOG_FD 2>&1) && test -s conftest.class && rm -f conftest.class],
-          [emacs_cv_android_u_or_later=yes],
-          [emacs_cv_android_u_or_later=no]))
+          [emacs_cv_android_v_or_later=yes],
+          [emacs_cv_android_v_or_later=no]))
 
-  if test "$emacs_cv_android_u_or_later" = "no"; then
+  if test "$emacs_cv_android_v_or_later" = "no"; then
     AC_MSG_ERROR([Emacs must be built with an android.jar file produced for \
-Android 14 (Upside Down Cake) or later.])
+Android 15 (Vanilla Ice Cream) or later.])
   fi
 
   dnl See if the Java compiler supports the `--release' option which
@@ -1181,6 +1185,8 @@ main (void)
    foo = "emacs_api_33";
 #elif __ANDROID_API__ < 35
    foo = "emacs_api_34";
+#elif __ANDROID_API__ < 36
+   foo = "emacs_api_35";
 #else
    foo = "emacs_api_future";
 #endif
index b5eac9bd089a03ab090dbe1efa64fdb97e1be5b7..7f52f1784fb58021151488eb5ee114c0ca061315 100644 (file)
@@ -35,6 +35,7 @@ NDK_BUILD_CXX_LDFLAGS = @NDK_BUILD_CXX_LDFLAGS@
         NDK_BUILD_AR = @NDK_BUILD_AR@
        NDK_BUILD_NASM = @NDK_BUILD_NASM@
      NDK_BUILD_CFLAGS = @NDK_BUILD_CFLAGS@
+ NDK_BUILD_SO_LDFLAGS = @NDK_BUILD_SO_LDFLAGS@
 
 # This is a list of targets to build.
    NDK_BUILD_MODULES = @NDK_BUILD_MODULES@
index 289e3a8a00365152e753fd82f052877354d9f6b8..86a62d80a30b241be1d7ff564e1d318f8d6b0574 100644 (file)
@@ -32,7 +32,9 @@ NDK_LOCAL_EXPORT_C_INCLUDES_$(LOCAL_MODULE) := $(LOCAL_EXPORT_C_INCLUDES) $(LOCA
 NDK_LOCAL_A_NAMES_$(LOCAL_MODULE) :=
 NDK_WHOLE_A_NAMES_$(LOCAL_MODULE) :=
 NDK_LOCAL_SO_NAMES_$(LOCAL_MODULE) :=
-NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) :=
+
+# Linker options enabling 16k page sizes.
+NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) := $(NDK_BUILD_SO_LDFLAGS)
 
 # List of all dependencies resolved for this module thus far.
 # Used to avoid infinite recursion.
index df00e497f8f018f7771e2d0c195af36a5cb92c06..5c9714efab812c0953879a84c32006aba0735de2 100644 (file)
@@ -207,7 +207,7 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>. -->
   <uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"/>
 
   <uses-sdk android:minSdkVersion="@ANDROID_MIN_SDK@"
-           android:targetSdkVersion="34"/>
+           android:targetSdkVersion="35"/>
 
   <application android:name="org.gnu.emacs.EmacsApplication"
               android:label="Emacs"
index 91916c6586cae59f2785cddb71262e6be4721c09..fa13a4d107dd59d36b2fe55d1e9f94f09d00f4c7 100644 (file)
@@ -39,7 +39,7 @@ script like so:
 Replacing the paths in the command line above with:
 
   - the path to the `android.jar' headers which come with the Android
-    SDK.  They must correspond to Android version 14 (API level 34).
+    SDK.  They must correspond to Android version 15 (API level 35).
 
   - the path to the C compiler in the Android NDK, for the kind of CPU
     you are building Emacs to run on.
@@ -48,8 +48,8 @@ Replacing the paths in the command line above with:
     such as `aapt', `apksigner', and `d8'.  These are used to build
     the application package.
 
-Where the type of CPU can either be `armeabi', `armv7*', `i686',
-`x86_64', `mips', or `mips64'.
+Where the type of CPU can either be `aarch64', `armeabi', `armv7*',
+`i686', `x86_64', `mips', or `mips64'.
 
 After the configuration process completes, you may run:
 
@@ -87,13 +87,13 @@ necessary for compiling Emacs.
 
 It is imperative that Emacs is compiled using the headers for the
 exact API level that it is written for.  This is currently API level
-34, so the correct android.jar archive is located within a directory
-whose name begins with `android-34'.  Minor revisions to the headers
+35, so the correct android.jar archive is located within a directory
+whose name begins with `android-35'.  Minor revisions to the headers
 are inconsequential towards the Emacs compilation process; if there is
-a directory named `android-34-extN' (where N represents a revision to
+a directory named `android-35-extN' (where N represents a revision to
 the Android SDK), whether you provide `configure' with that
 directory's android.jar or the android.jar contained within the
-directory named `android-34' is of no special importance.
+directory named `android-35' is of no special importance.
 
 The ndk directory contains one subdirectory for each version of the
 Android NDK installed.  This directory in turn contains the C and C++
@@ -111,12 +111,13 @@ supplied by the NDK.  The C compiler is then positioned within
 `prebuilt/*/bin' inside that directory.
 
 The build-tools directory holds subdirectories containing the utility
-programs used to convert class files output by the Java compiler to
-the DEX format employed by Android.  There is one subdirectory for
-each version of the build tools, but the version you opt for is not of
+programs used to convert class files output by the Java compiler to the
+DEX format employed by Android.  There is one subdirectory for each
+version of the build tools, but the version you opt for is not of
 paramount significance: if your version does not work, configure will
 protest, so install a newer one.  We anticipate that most recent
-releases will work, such as those from the 33.0.x and 34.0.x series.
+releases will work, such as those from the 33.0.x, 34.0.x, and 35.0.x
+series.
 
 \f
 BUILDING WITH OLD NDK VERSIONS
@@ -189,6 +190,23 @@ toolchain.  To work around this problem, add:
 
 to ANDROID_CFLAGS.
 
+\f
+16 KB PAGE SIZES
+
+New Android devices might be configured with kernels that only support
+16 KB page sizes, rendering them liable not to run Emacs binaries, and
+those of other programs, that are not properly compiled for such an
+environment.  Ideally, `configure' will automatically detect toolchain
+and compiler support for this configuration, and diagnose its absence by
+a warning message, but Emacs cannot diagnose the mismatch if the NDK
+toolchain supports 16 KB page sizes while the shared object implementing
+the C++ standard library does not, and Emacs binaries generated by such
+a combination will crash at startup on those devices.
+
+As such, you are advised to build Emacs with the NDK r27 or better, if
+producing binaries to run on aarch64 or x86_64 devices and Android 15 or
+future releases.
+
 \f
 DEBUG AND RELEASE BUILDS
 
index 0c9e8312b90b9936eba4f21c2ced7872719ce401..6e8330e3092aec78a089045dd300b63f0ddf0e15 100644 (file)
@@ -271,6 +271,12 @@ public class EmacsActivity extends Activity
     /* Set it as the content view.  */
     setContentView (layout);
 
+    /* Android 15 also realigns activity contents to originate beneath
+       system windows, e.g. the navigation bar, so request the original
+       behavior.  */
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM)
+      layout.setFitsSystemWindows (true);
+
     /* Maybe start the Emacs service if necessary.  */
     EmacsService.startEmacsService (this);
 
index 6bc8333984a7d15027b65247dff867bea2a10f52..d99fdd97782e88a2c225de6da1ec6478327eae85 100644 (file)
@@ -26,8 +26,11 @@ import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.RectF;
 
+import android.os.Build;
+
 public final class EmacsFillPolygon
 {
+  @SuppressWarnings ("deprecation") /* computeBounds (IZ) */
   public static void
   perform (EmacsDrawable drawable, EmacsGC gc, Point points[])
   {
@@ -60,7 +63,15 @@ public final class EmacsFillPolygon
 
     /* Compute the damage rectangle.  */
     rectF = new RectF (0, 0, 0, 0);
-    path.computeBounds (rectF, true);
+
+    /* computeBounds (IZ) is deprecated but the incompetence of
+       Android's release management has caused its replacement to be
+       omitted from published header files.  */
+
+    /* if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) */
+      path.computeBounds (rectF, true);
+    /* else
+       path.computeBounds (rectF); */
 
     rect = new Rect ((int) Math.floor (rectF.left),
                     (int) Math.floor (rectF.top),
index a561c7c849d445f19035d77fc0eab3fc4f276b36..64468f6fc96d567f4ecdc0ba5f8af214b79ebebd 100644 (file)
@@ -56,11 +56,13 @@ ndk_ANY_CXX=
 ndk_BUILD_CFLAGS="$4"
 ndk_working_cxx=no
 ndk_CXX_SHARED=
+ndk_BUILD_SO_LDFLAGS=
+ndk_want_16k_page_sizes=no
 
 AS_CASE(["$ndk_ABI"],
-  [*arm64*], [ndk_ARCH=arm64],
+  [*arm64*], [ndk_ARCH=arm64; ndk_want_16k_page_sizes=yes],
   [*arm*], [ndk_ARCH=arm],
-  [*x86_64*], [ndk_ARCH=x86_64],
+  [*x86_64*], [ndk_ARCH=x86_64; ndk_want_16k_page_sizes=yes],
   [*x86*], [ndk_ARCH=x86],
   [*mips64*], [ndk_ARCH=mips64],
   [*mips*], [ndk_ARCH=mips],
@@ -519,8 +521,7 @@ AS_ECHO([])
 AS_ECHO(["Library includes        : $ndk_CXX_STL"])
 AS_ECHO(["Linker options          : $ndk_CXX_LDFLAGS"])
 AS_ECHO(["Library file (if any)   : $ndk_CXX_SHARED"])
-AS_ECHO([])
-])
+AS_ECHO([])])
 
 # ndk_LATE_EARLY
 # --------------
@@ -535,7 +536,7 @@ AC_DEFUN([ndk_LATE_EARLY],
 # ndk_LATE
 # --------
 # Perform late initialization of the ndk-build system by checking for
-# required C and C++ headers.
+# required C and C++ headers and 16 KB page size support.
 
 AC_DEFUN([ndk_LATE],
 [dnl
@@ -543,10 +544,30 @@ AS_IF([test "$ndk_INITIALIZED" = "yes"],[
   AS_IF([test -n "$CXX"], [
     AC_LANG_PUSH([C++])
     AC_CHECK_HEADER([string], [ndk_working_cxx=yes],
-      [AC_MSG_WARN([Your C++ compiler is not properly configured, as \
+      [AC_MSG_WARN([Your C++ compiler is not properly configured, as
 the standard library headers could not be found.])])
     AC_LANG_POP([C++])])])
 LDFLAGS="$ndk_save_LDFLAGS"
+dnl Detect whether this version of the NDK supports 16KB page sizes,
+dnl which are required on certain architectures to execute under Android
+dnl 15 (35) and later, and apply the appropriate linker options if
+dnl positive.
+AS_IF([test "$ndk_want_16k_page_sizes" = "yes"],
+  [AC_CACHE_CHECK([whether toolchain supports configurations with 16k page sizes],
+     [ndk_cv_16k_page_sizes],
+     [ndk_save_LDFLAGS="$LDFLAGS"
+      LDFLAGS="$LDFLAGS -Wl,-z,max-page-size=16384"
+      AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
+        [ndk_cv_16k_page_sizes=yes],
+       [ndk_cv_16k_page_sizes=no])
+      LDFLAGS="$ndk_save_LDFLAGS"])
+   AS_IF([test "$ndk_cv_16k_page_sizes" = "yes"],
+     [LDFLAGS="$LDFLAGS -Wl,-z,max-page-size=16384"
+      ndk_BUILD_SO_LDFLAGS="-Wl,-z,max-page-size=16384"],
+     [AC_MSG_WARN([\
+Your toolchain does not support configurations with 16KB page sizes,
+and consequently binaries it produces cannot support all devices
+running Android 15 or later.])])])
 ])
 
 # ndk_SEARCH_MODULE(MODULE, NAME, ACTION-IF-FOUND, [ACTION-IF-NOT-FOUND])
@@ -659,6 +680,7 @@ AC_DEFUN_ONCE([ndk_CONFIG_FILES],
     NDK_BUILD_CXX_STL="$ndk_CXX_STL"
     NDK_BUILD_CXX_LDFLAGS="$ndk_CXX_LDFLAGS"
     NDK_BUILD_ANY_CXX_MODULE=$ndk_ANY_CXX
+    NDK_BUILD_SO_LDFLAGS="$ndk_BUILD_SO_LDFLAGS"
     NDK_BUILD_CFLAGS="$ndk_BUILD_CFLAGS"
 
     AC_SUBST([NDK_BUILD_ANDROID_MK])
@@ -674,6 +696,7 @@ AC_DEFUN_ONCE([ndk_CONFIG_FILES],
     AC_SUBST([NDK_BUILD_CXX_STL])
     AC_SUBST([NDK_BUILD_CXX_LDFLAGS])
     AC_SUBST([NDK_BUILD_ANY_CXX_MODULE])
+    AC_SUBST([NDK_BUILD_SO_LDFLAGS])
     AC_SUBST([NDK_BUILD_CFLAGS])
     AC_SUBST([NDK_BUILD_READELF])
 
index f2353803074e7c47d8686fe365dc1c99685206fc..53e1cb56e7402bcaa8e27bdf0cecc0fdf85f4792 100644 (file)
@@ -475,3 +475,15 @@ extern int emacs_setenv_TZ (char const *);
 /* Emacs does not need glibc strftime behavior for AM and PM
    indicators.  */
 #define REQUIRE_GNUISH_STRFTIME_AM_PM false
+
+#if defined __ANDROID_API__ && __ANDROID_API__ < 35
+/* Persuade lib/time.h to include the system's time.h, then... */
+#define __need_time_t
+#include <time.h>
+#undef __need_time_t
+
+/* ... redefine timezone_t to an Emacs-specific type, so that Gnulib's
+   replacement may not conflict with the OS type uselessly defined when
+   __ANDROID_API__ < 35.  */
+#define timezone_t rpl_timezone_t
+#endif /* __ANDROID_API__ && __ANDROID_API__ < 35 */