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