emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/android 0e995d06a8d 1/2: Improve support for building Android C+


From: Po Lu
Subject: feature/android 0e995d06a8d 1/2: Improve support for building Android C++ dependencies
Date: Fri, 3 Mar 2023 22:26:02 -0500 (EST)

branch: feature/android
commit 0e995d06a8df4660a4eca63673087d2df63bf8b0
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    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.
---
 configure.ac                                |  3 +
 cross/ndk-build/Makefile.in                 |  1 +
 cross/ndk-build/ndk-build-shared-library.mk |  4 +-
 cross/ndk-build/ndk-build-static-library.mk |  4 +-
 java/INSTALL                                | 18 ++++++
 m4/ndk-build.m4                             | 94 +++++++++++++++++++++++++++--
 6 files changed, 114 insertions(+), 10 deletions(-)

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
@@ -112,6 +112,24 @@ 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
 
 Android makes a distinction between ``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])



reply via email to

[Prev in Thread] Current Thread [Next in Thread]