Port to Android 35

* 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.
This commit is contained in:
Po Lu 2024-09-04 17:24:34 +08:00
parent d277123f4b
commit 2847106f3b
9 changed files with 105 additions and 26 deletions

View 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

View 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@

View 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.

View 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"

View 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.
BUILDING WITH OLD NDK VERSIONS
@ -189,6 +190,23 @@ toolchain. To work around this problem, add:
to ANDROID_CFLAGS.
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.
DEBUG AND RELEASE BUILDS

View 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);

View 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);
/* 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),

View 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])

View 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 */