From: Po Lu Date: Sat, 4 Mar 2023 03:19:25 +0000 (+0800) Subject: Improve support for building Android C++ dependencies X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=0e995d06a8df4660a4eca63673087d2df63bf8b0;p=emacs.git Improve support for building Android C++ dependencies * configure.ac: Call ndk_LATE after gl_EARLY. * cross/ndk-build/Makefile.in (NDK_BUILD_CXX): New variable. * cross/ndk-build/ndk-build-shared-library.mk: * cross/ndk-build/ndk-build-static-library.mk: Use it. * java/INSTALL: Describe how to build C++ dependencies. * m4/ndk-build.m4 (ndk_LATE): New macro. (ndk_INIT): Try to find a suitable C++ compiler. (ndk_CHECK_MODULES): Make sure the C++ compiler works before allowing C++ dependencies. --- diff --git a/configure.ac b/configure.ac index 0eb7db1cb29..e15d0c7ef39 100644 --- a/configure.ac +++ b/configure.ac @@ -173,6 +173,7 @@ if test "$XCONFIGURE" = "android"; then # NDK require them to be able to find system includes. with_ndk_path="$android_ndk_path" with_ndk_cxx_shared="$android_ndk_cxx_shared" + with_ndk_cxx="$android_ndk_cxx" ndk_INIT([$android_abi], [$ANDROID_SDK], [cross/ndk-build],\ [$ANDROID_CFLAGS]) fi @@ -1155,6 +1156,7 @@ package will likely install on older systems but crash on startup.]) ANDROID_SDK="$android_sdk" android_abi=$android_abi \ android_ndk_path="$with_ndk_path" \ android_ndk_cxx_shared="$with_ndk_cxx_shared" \ + android_ndk_cxx="$android_ndk_cxx" \ $0 $passthrough], [], [AC_MSG_ERROR([Failed to cross-configure Emacs for android.])]) @@ -1472,6 +1474,7 @@ AC_DEFUN([gt_TYPE_WINT_T], # Initialize gnulib right after choosing the compiler. dnl Amongst other things, this sets AR and ARFLAGS. gl_EARLY +ndk_LATE if test "$ac_test_CFLAGS" != set; then # It's helpful to have C macros available to GDB, so prefer -g3 to -g diff --git a/cross/ndk-build/Makefile.in b/cross/ndk-build/Makefile.in index b546c5b6231..cdf18471ff3 100644 --- a/cross/ndk-build/Makefile.in +++ b/cross/ndk-build/Makefile.in @@ -29,6 +29,7 @@ NDK_BUILD_ANDROID_MK = @NDK_BUILD_ANDROID_MK@ NDK_BUILD_ABI = @NDK_BUILD_ABI@ NDK_BUILD_SDK = @NDK_BUILD_SDK@ NDK_BUILD_CC = @NDK_BUILD_CC@ + NDK_BUILD_CXX = @NDK_BUILD_CXX@ NDK_BUILD_AR = @NDK_BUILD_AR@ NDK_BUILD_NASM = @NDK_BUILD_NASM@ NDK_BUILD_CFLAGS = @NDK_BUILD_CFLAGS@ diff --git a/cross/ndk-build/ndk-build-shared-library.mk b/cross/ndk-build/ndk-build-shared-library.mk index 12712265de2..3a400644070 100644 --- a/cross/ndk-build/ndk-build-shared-library.mk +++ b/cross/ndk-build/ndk-build-shared-library.mk @@ -46,7 +46,7 @@ else ifeq (x$(suffix $(1)),x.$(or $(LOCAL_CPP_EXTENSION),cpp)) $(call objname,$(LOCAL_MODULE),$(basename $(1))): $(call maybe-absolute,$(1)) - $(NDK_BUILD_CC) -c $$< -o $$@ $(NDK_CFLAGS_$(LOCAL_MODULE)) $(NDK_BUILD_CFLAGS_CXX) $(NDK_CXXFLAGS_$(LOCAL_MODULE)) + $(NDK_BUILD_CXX) -c $$< -o $$@ $(NDK_CFLAGS_$(LOCAL_MODULE)) $(NDK_BUILD_CFLAGS_CXX) $(NDK_CXXFLAGS_$(LOCAL_MODULE)) else ifneq ($(or $(call eq,x$(suffix $(1)),x.s),$(call eq,x$(suffix $(1)),x.S)),) @@ -59,7 +59,7 @@ ifneq (x$(suffix $(1)),x.asm) ifeq (x$(suffix $(1)),x.cc) $(call objname,$(LOCAL_MODULE),$(basename $(1))): $(call maybe-absolute,$(1),$(2)) - $(NDK_BUILD_CC) -c $$< -o $$@ $(NDK_CFLAGS_$(LOCAL_MODULE)) $(NDK_BUILD_CFLAGS_CXX) $(NDK_CXXFLAGS_$(LOCAL_MODULE)) + $(NDK_BUILD_CXX) -c $$< -o $$@ $(NDK_CFLAGS_$(LOCAL_MODULE)) $(NDK_BUILD_CFLAGS_CXX) $(NDK_CXXFLAGS_$(LOCAL_MODULE)) else $$(error Unsupported suffix: $(suffix $(1))) diff --git a/cross/ndk-build/ndk-build-static-library.mk b/cross/ndk-build/ndk-build-static-library.mk index 163a4487e5f..3566ee2c65e 100644 --- a/cross/ndk-build/ndk-build-static-library.mk +++ b/cross/ndk-build/ndk-build-static-library.mk @@ -34,7 +34,7 @@ else ifeq (x$(suffix $(1)),x.$(or $(LOCAL_CPP_EXTENSION),cpp)) $(call objname,$(LOCAL_MODULE),$(basename $(1))): $(call maybe-absolute,$(1),$(2)) - $(NDK_BUILD_CC) -c $$< -o $$@ $(NDK_BUILD_CFLAGS_CXX) $(NDK_CFLAGS_$(LOCAL_MODULE)) $(NDK_CXXFLAGS_$(LOCAL_MODULE)) + $(NDK_BUILD_CXX) -c $$< -o $$@ $(NDK_BUILD_CFLAGS_CXX) $(NDK_CFLAGS_$(LOCAL_MODULE)) $(NDK_CXXFLAGS_$(LOCAL_MODULE)) else ifneq ($(or $(call eq,x$(suffix $(1)),x.s),$(call eq,x$(suffix $(1)),x.S)),) @@ -47,7 +47,7 @@ ifneq (x$(suffix $(1)),x.asm) ifeq (x$(suffix $(1)),x.cc) $(call objname,$(LOCAL_MODULE),$(basename $(1))): $(call maybe-absolute,$(1),$(2)) - $(NDK_BUILD_CC) -c $$< -o $$@ $(NDK_BUILD_CFLAGS_CXX) $(NDK_CFLAGS_$(LOCAL_MODULE)) $(NDK_CXXFLAGS_$(LOCAL_MODULE)) + $(NDK_BUILD_CXX) -c $$< -o $$@ $(NDK_BUILD_CFLAGS_CXX) $(NDK_CFLAGS_$(LOCAL_MODULE)) $(NDK_CXXFLAGS_$(LOCAL_MODULE)) else $$(error Unsupported suffix: $(suffix $(1))) diff --git a/java/INSTALL b/java/INSTALL index bc5f4a70cd0..b331d09d9ff 100644 --- a/java/INSTALL +++ b/java/INSTALL @@ -111,6 +111,24 @@ 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. + +BUILDING C++ DEPENDENCIES + +With a new version of the NDK, dependencies containing C++ code should +build without any futher configuration. However, older versions +require that you use the ``make_standalone_toolchain.py'' script in +the NDK distribution to create a ``standalone toolchain'', and use +that instead, in order for C++ headers to be found. + +See https://developer.android.com/ndk/guides/standalone_toolchain for +more details; when a ``standalone toolchain'' is specified, the +configure script will try to determine the location of the C++ +compiler based on the C compiler specified. If that automatic +detection does not work, you can specify a C++ compiler yourself, like +so: + + ./configure --with-ndk-cxx=/path/to/toolchain/bin/i686-linux-android-g++ + DEBUG AND RELEASE BUILDS diff --git a/m4/ndk-build.m4 b/m4/ndk-build.m4 index d635b8d1a6b..0ade91da230 100644 --- a/m4/ndk-build.m4 +++ b/m4/ndk-build.m4 @@ -25,6 +25,10 @@ AC_ARG_WITH([ndk_cxx_shared], [AS_HELP_STRING([--with-ndk-cxx-shared], [name of the C++ standard library included with the NDK])]) +AC_ARG_WITH([ndk_cxx], + [AS_HELP_STRING([--with-ndk-cxx], + [name of the C++ compiler included with the NDK])]) + # ndk_INIT(ABI, API, DIR, CFLAGS) # ------------------------------- # Initialize the Android NDK. ABI is the ABI being built for. @@ -54,6 +58,7 @@ ndk_API=$2 ndk_DIR=$3 ndk_ANY_CXX= ndk_BUILD_CFLAGS="$4" +ndk_working_cxx=no AS_CASE(["$ndk_ABI"], [*arm64*], [ndk_ARCH=arm64], @@ -169,6 +174,10 @@ that could not be found in the list of directories specified in \ [AC_MSG_ERROR([The module [$]1 requires the C++ standard library \ (libc++_shared.so), but it was not found.])]) + AS_IF([test "$ndk_ANY_CXX" = "yes" && test "$ndk_working_cxx" != "yes"], + [AC_MSG_ERROR([The module [$]1 requires the C++ standard library \ +(libc++_shared.so), but a working C++ compiler was not found.])]) + AC_MSG_RESULT([yes]) # Make sure the module is prepended. @@ -181,6 +190,44 @@ that could not be found in the list of directories specified in \ done } +# ndk_filter_cc_for_cxx +# --------------------- +# Run through $CC, removing any options that are not suitable for +# use in a C++ compiler. + +ndk_filter_cc_for_cxx () { + for ndk_word in $CC; do + AS_CASE([$ndk_word], [*-std=*], [], + [AS_ECHO_N(["$ndk_word "])]) + done +} + +# ndk_subst_cc_onto_cxx +# --------------------- +# Print the value of $CXX, followed by any innocent looking options +# in $CC. + +ndk_subst_cc_onto_cxx () { + AS_ECHO_N(["$CXX "]) + ndk_flag= + for ndk_word in `AS_ECHO_N(["$CC"]) | cut -s -f2- -d' '`; do + AS_IF([test "$ndk_flag" = "yes"], + [AS_ECHO_N(["$ndk_word "])], + [AS_CASE([$ndk_word], + [*-sysroot=*], + [AS_ECHO_N(["$ndk_word "])], + [*-isystem*], + [AS_ECHO_N(["$ndk_word "]) + ndk_flag=yes], + [*-sysroot*], + [AS_ECHO_N(["$ndk_word "]) + ndk_flag=yes], + [-D__ANDROID_API__*], + [AS_ECHO_N(["$ndk_word "])])]) + ndk_flag=no + done +} + # Look for a suitable ar in the same directory as the C compiler. ndk_cc_firstword=`AS_ECHO(["$CC"]) | cut -d' ' -f1` ndk_where_cc=`which $ndk_cc_firstword` @@ -209,7 +256,7 @@ ndk_where_toolchain= AS_IF([test -z "$with_ndk_cxx_shared" && test -n "$ndk_where_cc"],[ # Find the NDK root directory. Go to $ndk_where_cc. SAVE_PWD=`pwd` - cd `dirname "$ndk_where_cc"` + cd `AS_DIRNAME(["$ndk_where_cc"])` # Now, keep moving backwards until pwd ends with ``toolchains''. while :; do @@ -264,7 +311,37 @@ name of an appropriate ``libc++_shared.so'' binary.])], ndk_CXX_SHARED=$with_ndk_cxx_shared -# These variables have now been found. +# These variables have now been found. Now look for a C++ compiler. +# Upon failure, pretend the C compiler is a C++ compiler and use that +# instead. + +ndk_cc_name=`AS_BASENAME(["${ndk_cc_firstword}"])` +ndk_cxx_name= + +AS_CASE([$ndk_cc_name], [*-gcc], + [ndk_cxx_name=`AS_ECHO([$ndk_cc_name]) | sed 's/gcc/g++/'`], + [ndk_cxx_name="${ndk_cc_name}++"]) + +AS_IF([test -n "$with_ndk_cxx"], [CXX=$with_ndk_cxx], + [AC_PATH_PROGS([CXX], [$ndk_cxx_name], + [], [`AS_DIRNAME(["$ndk_where_cc"])`:$PATH]) + AS_IF([test -z "$CXX"], [CXX=`ndk_filter_cc_for_cxx`], + [CXX=`ndk_subst_cc_onto_cxx`])]) +]) + +# ndk_LATE +# -------- +# Perform late initialization of the ndk-build system by checking for +# required C and C++ headers. + +AC_DEFUN([ndk_LATE], +[ +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 set up, and\ + the standard library headers could not be found.])]) + AC_LANG_POP([C++])])]) ]) # ndk_SEARCH_MODULE(MODULE, NAME, ACTION-IF-FOUND, [ACTION-IF-NOT-FOUND]) @@ -303,10 +380,13 @@ else ndk_ANY_CXX=yes fi - if test "$ndk_ANY_CXX" = "yes" && test -z "$with_ndk_cxx_shared"; then - AC_MSG_ERROR([The module $1 requires the C++ standard library \ -(libc++_shared.so), but it was not found.]) - fi + AS_IF([test "$ndk_ANY_CXX" = "yes" && test -z "$with_ndk_cxx_shared"], + [AC_MSG_ERROR([The module $1 requires the C++ standard library \ +(libc++_shared.so), but it was not found.])]) + + AS_IF([test "$ndk_ANY_CXX" = "yes" && test "$ndk_working_cxx" != "yes"], + [AC_MSG_ERROR([The module [$]1 requires the C++ standard library \ +(libc++_shared.so), but a working C++ compiler was not found.])]) $2[]_CFLAGS="[$]$2[]_CFLAGS $module_cflags $module_includes" $2[]_LIBS="[$]$2[]_LIBS $module_ldflags" @@ -357,6 +437,7 @@ AC_DEFUN_ONCE([ndk_CONFIG_FILES], NDK_BUILD_ABI=$ndk_ABI NDK_BUILD_SDK=$ndk_API NDK_BUILD_CC=$CC + NDK_BUILD_CXX=$CXX NDK_BUILD_AR=$AR NDK_BUILD_MODULES="$ndk_MODULES" NDK_BUILD_CXX_SHARED="$ndk_CXX_SHARED" @@ -368,6 +449,7 @@ AC_DEFUN_ONCE([ndk_CONFIG_FILES], AC_SUBST([NDK_BUILD_ABI]) AC_SUBST([NDK_BUILD_SDK]) AC_SUBST([NDK_BUILD_CC]) + AC_SUBST([NDK_BUILD_CXX]) AC_SUBST([NDK_BUILD_AR]) AC_SUBST([NDK_BUILD_NASM]) AC_SUBST([NDK_BUILD_MODULES])