Improve C++ standard library detection on Android

* configure.ac: Stop relaying --with-ndk-cxx-shared to the
nested invocation of configure.

* build-aux/ndk-build-helper-1.mk (SYSTEM_LIBRARIES):

* build-aux/ndk-build-helper-2.mk (SYSTEM_LIBRARIES): Insert all
of the C++ libraries available on Android.

* configure.ac: Call ndk_LATE and ndk_LATE_EARLY within if
statement at toplevel, averting needless calls to AC_PROG_CXX.

* cross/ndk-build/Makefile.in (NDK_BUILD_CXX_STL)
(NDK_BUILD_CXX_LDFLAGS):

* cross/ndk-build/ndk-build.mk.in (NDK_BUILD_CXX_STL)
(NDK_BUILD_CXX_LDFLAGS): New variables.

* cross/ndk-build/ndk-resolve.mk (NDK_SYSTEM_LIBRARIES):
Introduce several other C++ libraries sometimes present on
Android.
(NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE)): Insert NDK_BUILD_CXX_STL
when any of these new C++ libraries are requested.

* m4/ndk-build.m4: Completely rewrite C++ compiler and library
detection.

* java/org/gnu/emacs/EmacsNative.java (EmacsNative): Attempt to
load more libraries from static initializer.

* java/INSTALL: Remove obsolete information.
This commit is contained in:
Po Lu 2024-03-17 19:32:15 +08:00
parent 445e2499ba
commit 7a0f4de3c1
9 changed files with 335 additions and 131 deletions

View file

@ -94,7 +94,7 @@ endef
# dependencies can be ignored while building a shared library, as they
# will be linked in to the resulting shared object file later.
SYSTEM_LIBRARIES = z libz libc c libdl dl stdc++ libstdc++ log liblog android libandroid
SYSTEM_LIBRARIES = z libz libc c libdl dl stdc++ libstdc++ stlport libstlport gnustl libgnustl c++ libc++ log liblog android libandroid
$(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_SHARED_LIBRARIES)),$(eval $(call add-so-name,$(module))))
$(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_SHARED_LIBRARIES) $(LOCAL_STATIC_LIBRARIES) $(LOCAL_WHOLE_STATIC_LIBRARIES)),$(eval $(call add-includes,$(module))))

View file

@ -87,7 +87,7 @@ endef
# Resolve additional dependencies based on LOCAL_STATIC_LIBRARIES and
# LOCAL_SHARED_LIBRARIES.
SYSTEM_LIBRARIES = z libz libc c libdl dl libstdc++ stdc++ log liblog android libandroid
SYSTEM_LIBRARIES = z libz libc c libdl dl libstdc++ stdc++ stlport libstlport gnustl libgnustl c++ libc++ log liblog android libandroid
$(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_STATIC_LIBRARIES) $(LOCAL_WHOLE_STATIC_LIBRARIES)),$(eval $(call add-a-name,$(module))))
$(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_SHARED_LIBRARIES)),$(eval $(call add-so-name,$(module))))

View file

@ -171,7 +171,6 @@ AS_IF([test "$XCONFIGURE" = "android"],[
# Make sure to pass through the CFLAGS, as older versions of the
# 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])
@ -1233,7 +1232,7 @@ package will likely install on older systems but crash on startup.])
passthrough="$passthrough --with-harfbuzz=$with_harfbuzz"
passthrough="$passthrough --with-threads=$with_threads"
# Now pass through some checking options.
# Now pass through some checking-related options.
emacs_val="--enable-check-lisp-object-type=$enable_check_lisp_object_type"
passthrough="$passthrough $emacs_val"
@ -1243,7 +1242,6 @@ package will likely install on older systems but crash on startup.])
AS_IF([XCONFIGURE=android ANDROID_CC="$ANDROID_CC" \
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" \
$CONFIG_SHELL $0 $passthrough], [],
[AC_MSG_ERROR([Failed to cross-configure Emacs for android.])])
@ -1570,7 +1568,13 @@ AC_DEFUN_ONCE([gl_STDLIB_H],
# Initialize gnulib right after choosing the compiler.
dnl Amongst other things, this sets AR and ARFLAGS.
gl_EARLY
ndk_LATE
# ndk_LATE must be enclosed in this conditional to prevent the
# AC_PROG_CXX it indirectly requires from being expanded at top level.
if test "$ndk_INITIALIZED" = "yes"; then
ndk_LATE_EARLY
ndk_LATE
fi
if test "$ac_test_CFLAGS" != set; then
# It's helpful to have C macros available to GDB, so prefer -g3 to -g

View file

@ -24,15 +24,17 @@
srcdir = @srcdir@
# This is a list of Android.mk files which provide targets.
NDK_BUILD_ANDROID_MK = @NDK_BUILD_ANDROID_MK@
NDK_BUILD_ARCH = @NDK_BUILD_ARCH@
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@
NDK_BUILD_ANDROID_MK = @NDK_BUILD_ANDROID_MK@
NDK_BUILD_ARCH = @NDK_BUILD_ARCH@
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_CXX_STL = @NDK_BUILD_CXX_STL@
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@
# This is a list of targets to build.
NDK_BUILD_MODULES = @NDK_BUILD_MODULES@
@ -58,8 +60,10 @@ NDK_BUILD_ANDROID_MK := $(call uniqify,$(NDK_BUILD_ANDROID_MK))
NDK_BUILD_MODULES := $(call uniqify,$(NDK_BUILD_MODULES))
# Define CFLAGS for compiling C++ code; this involves removing all
# -std=NNN options.
NDK_BUILD_CFLAGS_CXX := $(filter-out -std=%,$(NDK_BUILD_CFLAGS))
# -std=NNN options and inserting compilation options for the C++
# library.
NDK_BUILD_CFLAGS_CXX := $(filter-out -std=%,$(NDK_BUILD_CFLAGS)) \
$(NDK_BUILD_CXX_STL)
define subr-1

View file

@ -22,6 +22,8 @@
NDK_BUILD_MODULES = @NDK_BUILD_MODULES@
NDK_BUILD_CXX_SHARED = @NDK_BUILD_CXX_SHARED@
NDK_BUILD_CXX_STL = @NDK_BUILD_CXX_STL@
NDK_BUILD_CXX_LDFLAGS = @NDK_BUILD_CXX_LDFLAGS@
NDK_BUILD_ANY_CXX_MODULE = @NDK_BUILD_ANY_CXX_MODULE@
NDK_BUILD_SHARED =
NDK_BUILD_STATIC =

View file

@ -20,7 +20,7 @@
# which actually builds targets.
# List of system libraries to ignore.
NDK_SYSTEM_LIBRARIES = z libz libc c libdl dl stdc++ libstdc++ log liblog android libandroid
NDK_SYSTEM_LIBRARIES = z libz libc c libdl dl stdc++ libstdc++ stlport libstlport gnustl libgnustl c++ libc++ log liblog android libandroid
# Save information.
NDK_LOCAL_PATH_$(LOCAL_MODULE) := $(LOCAL_PATH)
@ -90,11 +90,35 @@ endif
# Likewise for libstdc++.
ifeq ($(strip $(1)),libstdc++)
NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += -lstdc++
NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += $(NDK_BUILD_CXX_LDFLAGS)
endif
ifeq ($(strip $(1)),dl)
NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += -lstdc++
ifeq ($(strip $(1)),stdc++)
NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += $(NDK_BUILD_CXX_LDFLAGS)
endif
ifeq ($(strip $(1)),libstlport)
NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += $(NDK_BUILD_CXX_LDFLAGS)
endif
ifeq ($(strip $(1)),stlport)
NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += $(NDK_BUILD_CXX_LDFLAGS)
endif
ifeq ($(strip $(1)),libgnustl)
NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += $(NDK_BUILD_CXX_LDFLAGS)
endif
ifeq ($(strip $(1)),gnustl)
NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += $(NDK_BUILD_CXX_LDFLAGS)
endif
ifeq ($(strip $(1)),libc++)
NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += $(NDK_BUILD_CXX_LDFLAGS)
endif
ifeq ($(strip $(1)),c++)
NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += $(NDK_BUILD_CXX_LDFLAGS)
endif
# Likewise for liblog.

View file

@ -166,25 +166,21 @@ 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 further 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.
In normal circumstances, Emacs should automatically detect and configure
one of the C++ standard libraries part of the NDK when such a library is
required to build a dependency specified under `--with-ndk-path'.
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:
Nevertheless, this process is not infalliable, and with certain versions
of the NDK is liable to fail to locate a C++ compiler, requiring that
you run the `make_standalone_toolchain.py' script in the NDK
distribution to create a ``standalone toolchain'' and substitute the
same for the regular compiler toolchain. See
https://developer.android.com/ndk/guides/standalone_toolchain for
further details.
./configure --with-ndk-cxx=/path/to/toolchain/bin/i686-linux-android-g++
Some versions of the NDK have a bug, where GCC fails to locate
``stddef.h'' after being copied to a standalone toolchain. To work
around this problem (which normally exhibits itself when building C++
code), add:
Some versions of the NDK that ship GCC 4.9.x exhibit a bug where the
compiler cannot locate `stddef.h' after being copied to a standalone
toolchain. To work around this problem, add:
-isystem /path/to/toolchain/include/c++/4.9.x

View file

@ -323,7 +323,9 @@ public static native void blitRect (Bitmap src, Bitmap dest, int x1,
Every time you add a new shared library dependency to Emacs,
please add it here as well. */
libraryDeps = new String[] { "png_emacs", "selinux_emacs",
libraryDeps = new String[] { "c++_shared", "gnustl_shared",
"stlport_shared", "gabi++_shared",
"png_emacs", "selinux_emacs",
"crypto_emacs", "pcre_emacs",
"packagelistparser_emacs",
"gnutls_emacs", "gmp_emacs",
@ -331,7 +333,7 @@ public static native void blitRect (Bitmap src, Bitmap dest, int x1,
"tasn1_emacs", "hogweed_emacs",
"jansson_emacs", "jpeg_emacs",
"tiff_emacs", "xml2_emacs",
"icuuc_emacs",
"icuuc_emacs", "harfbuzz_emacs",
"tree-sitter_emacs", };
for (String dependency : libraryDeps)

View file

@ -21,10 +21,6 @@ AC_ARG_WITH([ndk_path],
[AS_HELP_STRING([--with-ndk-path],
[find Android libraries in these directories])])
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])])
@ -59,6 +55,7 @@ ndk_DIR=$3
ndk_ANY_CXX=
ndk_BUILD_CFLAGS="$4"
ndk_working_cxx=no
ndk_CXX_SHARED=
AS_CASE(["$ndk_ABI"],
[*arm64*], [ndk_ARCH=arm64],
@ -149,7 +146,7 @@ ndk_resolve_import_module () {
for ndk_android_mk in $ndk_module_files; do
# Read this Android.mk file. Set NDK_ROOT to /tmp: the Android in
# tree build system sets it to a meaning value, but build files
# tree build system sets it to a meaningful value, but build files
# just use it to test whether or not the NDK is being used.
ndk_commands=`ndk_run_test`
eval "$ndk_commands"
@ -169,13 +166,14 @@ that could not be found in the list of directories specified in \
ndk_ANY_CXX=yes
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 "$module_cxx_deps" = "yes" && test -z "$ndk_CXX_STL" \
&& test -z "$ndk_CXX_LDFLAGS"],
[AC_MSG_ERROR([The module $1 requires a C++ standard library,
but none were 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.])])
AS_IF([test "$module_cxx_deps" = "yes" && test "$ndk_working_cxx" != "yes"],
[AC_MSG_ERROR([The module [$]1 requires the C++ standard library,
but a working C++ compiler was not found.])])
AC_MSG_RESULT([yes])
@ -227,6 +225,88 @@ ndk_subst_cc_onto_cxx () {
done
}
# ndk_subst_cflags_onto_cxx
# ---------------------
# Print any options in CFLAGS also suitable for a C++ compiler.
ndk_subst_cflags_onto_cxx () {
ndk_flag=
for ndk_word in $CFLAGS; do
AS_IF([test "$ndk_flag" = "yes"],
[AS_ECHO_N(["$ndk_word "])
ndk_flag=no],
[AS_CASE([$ndk_word],
[*-sysroot=*],
[AS_ECHO_N(["$ndk_word "])],
[*-isystem*],
[AS_ECHO_N(["$ndk_word "])
ndk_flag=yes],
[*-I*],
[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 "])])])
done
}
# Detect the installation directory and type of the NDK being used.
ndk_install_dir=
ndk_toolchain_type=
AC_MSG_CHECKING([for the directory where the NDK is installed])
dnl If the install directory isn't available, repeat the search over
dnl each entry in the programs directory.
ndk_programs_dirs=`$CC -print-search-dirs | sed -n "s/^programs:[[\t ]]*=\?\(.*\)/\1/p"`
ndk_save_IFS=$IFS; IFS=:
for ndk_dir in $ndk_programs_dirs; do
if test -d "$ndk_dir"; then :; else
continue
fi
ndk_dir=`cd "$ndk_dir"; pwd`
while test "$ndk_dir" != "/" && test -z "$ndk_toolchain_type"; do
ndk_dir=`AS_DIRNAME([$ndk_dir])`
AS_IF([test -d "$ndk_dir/bin" && test -d "$ndk_dir/lib"],
[dnl The directory reached is most likely either the directory
dnl holding prebuilt binaries in a combined toolchain or the
dnl directory holding a standalone toolchain itself.
dnl
dnl Distinguish between the two by verifying the name of the
dnl parent directory (and its parent).
ndk_dir1=`AS_DIRNAME(["$ndk_dir"])`
ndk_basename=`AS_BASENAME(["$ndk_dir1"])`
AS_IF([test "$ndk_basename" = "prebuilt"],
[dnl Directories named "prebuilt" are exclusively present in
dnl combined toolchains, where they are children of the
dnl base directory or, in recent releases, a directory
dnl within the base directory. Continue searching for the
dnl base directory.
ndk_toolchain_type=combined
while test "$ndk_dir1" != "/"; do
AS_IF([test -d "$ndk_dir1/toolchains" \
&& test -d "$ndk_dir1/sources"],
[ndk_install_dir=$ndk_dir1
break])
ndk_dir1=`AS_DIRNAME(["$ndk_dir1"])`
done],
[ndk_toolchain_type=standalone
ndk_install_dir=$ndk_dir])])
done
AS_IF([test -n "$ndk_toolchain_type"],
[break])
done
IFS=$ndk_save_IFS
AS_IF([test -z "$ndk_install_dir"],
[AC_MSG_RESULT([unknown])
AC_MSG_WARN([The NDK installation directory could not be \
derived from the compiler.])],
[AC_MSG_RESULT([$ndk_install_dir ($ndk_toolchain_type)])])
# Look for a suitable ar and ranlib in the same directory as the C
# compiler.
ndk_cc_firstword=`AS_ECHO(["$CC"]) | cut -d' ' -f1`
@ -259,72 +339,8 @@ NDK_BUILD_NASM=
AS_IF([test "$ndk_ARCH" = "x86" || test "$ndk_ARCH" = "x86_64"],
[AC_CHECK_PROGS([NDK_BUILD_NASM], [nasm])])
# Look for a file named ``libc++_shared.so'' in a subdirectory of
# $ndk_where_cc if it was not specified.
AC_MSG_CHECKING([for libc++_shared.so])
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 `AS_DIRNAME(["$ndk_where_cc"])`
# Now, keep moving backwards until pwd ends with ``toolchains''.
while :; do
if test "`pwd`" = "/"; then
cd "$SAVE_PWD"
break
fi
ndk_pwd=`pwd`
if test "`AS_BASENAME([$ndk_pwd])`" = "toolchains"; then
ndk_where_toolchain=$ndk_pwd
cd "$SAVE_PWD"
break
fi
cd ..
done
ndk_matching_libcxx_shared_so=
# The toolchain directory should be in "$ndk_where_toolchain".
AS_IF([test -n "$ndk_where_toolchain"],[
# Now, look in the directory behind it.
ndk_cxx_shared_so=`find "$ndk_where_toolchain" -name libc++_shared.so`
# Look for one with the correct architecture.
for ndk_candidate in $ndk_cxx_shared_so; do
AS_CASE([$ndk_candidate],
[*arm-linux-android*],
[AS_IF([test "$ndk_ARCH" = "arm"],
[ndk_matching_libcxx_shared_so=$ndk_candidate])],
[*aarch64-linux-android*],
[AS_IF([test "$ndk_ARCH" = "arm64"],
[ndk_matching_libcxx_shared_so=$ndk_candidate])],
[*i[[3-6]]86-linux-android*],
[AS_IF([test "$ndk_ARCH" = "x86"],
[ndk_matching_libcxx_shared_so=$ndk_candidate])],
[*x86_64-linux-android*],
[AS_IF([test "$ndk_ARCH" = "x86_64"],
[ndk_matching_libcxx_shared_so=$ndk_candidate])])
AS_IF([test -n "$ndk_matching_libcxx_shared_so"],
[with_ndk_cxx_shared=$ndk_matching_libcxx_shared_so])
done])])
AS_IF([test -z "$with_ndk_cxx_shared"],[AC_MSG_RESULT([no])
AC_MSG_WARN([The C++ standard library could not be found. \
If you try to build Emacs with a dependency that requires the C++ standard \
library, Emacs will not build correctly, unless you manually specify the \
name of an appropriate ``libc++_shared.so'' binary.])],
[AC_MSG_RESULT([$with_ndk_cxx_shared])])
ndk_CXX_SHARED=$with_ndk_cxx_shared
# 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.
# Search 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=
@ -338,8 +354,162 @@ AS_IF([test -n "$with_ndk_cxx"], [CXX=$with_ndk_cxx],
[], [`AS_DIRNAME(["$ndk_where_cc"])`:$PATH])
AS_IF([test -z "$CXX"], [CXX=`ndk_filter_cc_for_cxx`],
[CXX=`ndk_subst_cc_onto_cxx`])])
# None of the C++ standard libraries installed with Android are
# available to NDK programs, which are expected to select one of several
# standard libraries distributed with the NDK. This library must be
# extracted from the NDK by the program's build system and copied into
# the application directory, and the build system is also expected to
# provide the compiler with suitable options to enable it.
#
# Emacs, on recent releases of the NDK, prefers the libc++ library, the
# most complete of the libraries available, when it detects the presence
# of its headers and libraries in the compiler's search path. Next in
# line are the several libraries located in a directory named `cxx-stl'
# inside the NDK distribution, of which Emacs prefers, in this order,
# the GNU libstdc++, stlport, gabi and the system C++ library. The
# scope of the last two is confined to providing runtime support for
# basic C++ operations, and is useless for compiling most C++
# dependencies whose requirements go beyond such operations.
#
# The NDK comes in two forms. In a "combined toolchain", all C++
# libraries are present in the NDK directory and the responsibility is
# left to the build system to locate and select the best C++ library,
# whereas in a "standalone toolchain" an STL will have already been
# specified a C++ library, besides which no others will be present.
#
# Though Android.mk files are provided by the NDK for each such library,
# Emacs cannot use any of these, both for lack of prebuilt support in
# its ndk-build implementation, and since they are absent from combined
# toolchains.
ndk_CXX_SHARED=
ndk_CXX_STL=
ndk_CXX_LDFLAGS=
AS_IF([test -n "$CXX" && test -n "$ndk_install_dir"],
[ndk_library_dirs=`$CXX -print-search-dirs \
| sed -n "s/^libraries:[[\t ]]*=\?\(.*\)/\1/p"`
AS_IF([test "$ndk_toolchain_type" = "standalone"],
[dnl With a standalone toolchain, just use the first C++ library
dnl present in the compiler's library search path, that being the
dnl only C++ library that will ever be present.
ndk_save_IFS=$IFS; IFS=:
for ndk_dir in $ndk_library_dirs; do
if test -d "$ndk_dir"; then :; else
continue
fi
ndk_dir=`cd "$ndk_dir"; pwd`
if test -f "$ndk_dir/libc++_shared.so"; then
ndk_CXX_SHARED="$ndk_dir/libc++_shared.so"
ndk_CXX_LDFLAGS=-lc++_shared; break
elif test -f "$ndk_dir/libgnustl_shared.so"; then
ndk_CXX_SHARED="$ndk_dir/libgnustl_shared.so"
ndk_CXX_LDFLAGS=-lgnustl_shared; break
elif test -f "$ndk_dir/libstlport_shared.so"; then
ndk_CXX_SHARED="$ndk_dir/libstlport_shared.so"
ndk_CXX_LDFLAGS=-lstlport_shared; break
fi
done
IFS=$ndk_save_IFS],
[dnl Otherwise, search for a suitable standard library
dnl in the order stated above.
dnl
dnl Detect if this compiler is configured to link against libc++ by
dnl default.
AC_MSG_CHECKING([whether compiler defaults to libc++])
cat <<_ACEOF >conftest.cc
#include <string>
#ifndef _LIBCPP_VERSION
Not libc++!
#endif /* _LIBCPP_VERSION */
int
main (void)
{
}
_ACEOF
AS_IF([$CXX conftest.cc -o conftest.o >&AS_MESSAGE_LOG_FD 2>&1],
[dnl The compiler defaults to libc++.
AC_MSG_RESULT([yes])
ndk_save_IFS=$IFS; IFS=:
for ndk_dir in $ndk_library_dirs; do
if test -f "$ndk_dir/libc++_shared.so"; then
ndk_CXX_SHARED="$ndk_dir/libc++_shared.so"
ndk_CXX_LDFLAGS=-lc++_shared; break
fi
done
IFS=$ndk_save_IFS],
[dnl Search for gnustl, stlport, gabi, and failing that, system.
dnl The name of the gabi system root directory varies by GCC
dnl version.
AC_MSG_RESULT([no])
ndk_gcc_version=`($CXX -v 2>&1) \
| sed -n "s/^gcc version \([[0123456789]\+.[0123456789]\+]\).*/\1/p"`
cxx_stl="$ndk_install_dir/sources/cxx-stl"
ndk_cxx_stl_base="$cxx_stl/gnu-libstdc++/$ndk_gcc_version"
AS_IF([test -n "$ndk_gcc_version" \
&& test -d "$ndk_cxx_stl_base/libs/$ndk_ABI"],
[ndk_CXX_LDFLAGS="-L$ndk_cxx_stl_base/libs/$ndk_ABI -lgnustl_shared"
ndk_CXX_LDFLAGS="$ndk_CXX_LDFLAGS -lsupc++"
ndk_CXX_STL="-isystem $ndk_cxx_stl_base/include"
ndk_CXX_STL="$ndk_CXX_STL -isystem $ndk_cxx_stl_base/libs/$ndk_ABI/include"
ndk_CXX_SHARED="$ndk_cxx_stl_base/libs/$ndk_ABI/libgnustl_shared.so"])
AS_IF([test -f "$ndk_CXX_SHARED"], [],
[dnl No STL was located or the library is not reachable.
dnl Search for alternatives.
ndk_CXX_STL=
ndk_CXX_SHARED=
ndk_CXX_LDFLAGS=
ndk_cxx_stl_base="$cxx_stl/stlport"
AS_IF([test -d "$ndk_cxx_stl_base"],
[ndk_CXX_LDFLAGS="-L$ndk_cxx_stl_base/libs/$ndk_ABI -lstlport_shared"
ndk_CXX_STL="-isystem $ndk_cxx_stl_base/stlport"
ndk_CXX_SHARED="$ndk_cxx_stl_base/libs/$ndk_ABI/libstlport_shared.so"])
AS_IF([test -f "$ndk_CXX_SHARED"], [],
[ndk_CXX_STL=
ndk_CXX_SHARED=
ndk_CXX_LDFLAGS=
ndk_cxx_stl_base="$cxx_stl/gabi++"
AS_IF([test -d "$ndk_cxx_stl_base"],
[ndk_CXX_LDFLAGS="-L$ndk_cxx_stl_base/libs/$ndk_ABI -lgabi++_shared"
ndk_CXX_STL="$ndk_CXX_STL -isystem $ndk_cxx_stl_base/include"
ndk_CXX_SHARED="$ndk_cxx_stl_base/libs/$ndk_ABI/lgabi++_shared.so"])])
AS_IF([test -f "$ndk_CXX_SHARED"], [],
[ndk_CXX_STL=
ndk_CXX_SHARED=
ndk_CXX_LDFLAGS=
ndk_cxx_stl_base="$cxx_stl/system"
AS_IF([test -d "$ndk_cxx_stl_base"],
[ndk_CXX_LDFLAGS="-L$ndk_cxx_stl_base/libs/$ndk_ABI -lstdc++"
ndk_CXX_STL="-isystem $ndk_cxx_stl_base/include"
dnl The "system" library is distributed with Android and
dnl need not be present in app packages.
ndk_CXX_SHARED=
dnl Done.
])])])])
rm -f conftest.o])])
AS_ECHO([])
AS_ECHO(["C++ compiler configuration: "])
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([])
])
# ndk_LATE_EARLY
# --------------
# Call before ndk_LATE to establish certain variables in time for
# ndk_LATE's C++ compiler detection.
AC_DEFUN([ndk_LATE_EARLY],
[ndk_save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS $ndk_CXX_LDFLAGS"
CXXFLAGS="$CXXFLAGS `ndk_subst_cflags_onto_cxx` $ndk_CXX_STL"])
# ndk_LATE
# --------
# Perform late initialization of the ndk-build system by checking for
@ -347,17 +517,14 @@ AS_IF([test -n "$with_ndk_cxx"], [CXX=$with_ndk_cxx],
AC_DEFUN([ndk_LATE],
[dnl
dnl This calls AC_REQUIRE([AC_PROG_CXX]), leading to configure looking
dnl for a C++ compiler. However, the language is not restored
dnl afterwards if not `$ndk_INITIALIZED'.
AS_IF([test "$ndk_INITIALIZED" = "yes"],[
AS_IF([test -n "$CXX"], [AC_LANG_PUSH([C++])
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_MSG_WARN([Your C++ compiler is not properly configured, as \
the standard library headers could not be found.])])
AC_LANG_POP([C++])])])
dnl Thus, manually switch back to C here.
AC_LANG([C])
LDFLAGS="$ndk_save_LDFLAGS"
])
# ndk_SEARCH_MODULE(MODULE, NAME, ACTION-IF-FOUND, [ACTION-IF-NOT-FOUND])
@ -396,13 +563,14 @@ else
ndk_ANY_CXX=yes
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 "$module_cxx_deps" = "yes" && test -z "$ndk_CXX_STL" \
&& test -z "$ndk_CXX_LDFLAGS"],
[AC_MSG_ERROR([The module $1 requires a C++ standard library,
but none were 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.])])
AS_IF([test "$module_cxx_deps" = "yes" && test "$ndk_working_cxx" != "yes"],
[AC_MSG_ERROR([The module [$]1 requires the C++ standard library,
but a working C++ compiler was not found.])])
$2[]_CFLAGS="[$]$2[]_CFLAGS $module_cflags $module_includes"
$2[]_LIBS="[$]$2[]_LIBS $module_ldflags"
@ -457,6 +625,8 @@ AC_DEFUN_ONCE([ndk_CONFIG_FILES],
NDK_BUILD_AR=$AR
NDK_BUILD_MODULES="$ndk_MODULES"
NDK_BUILD_CXX_SHARED="$ndk_CXX_SHARED"
NDK_BUILD_CXX_STL="$ndk_CXX_STL"
NDK_BUILD_CXX_LDFLAGS="$ndk_CXX_LDFLAGS"
NDK_BUILD_ANY_CXX_MODULE=$ndk_ANY_CXX
NDK_BUILD_CFLAGS="$ndk_BUILD_CFLAGS"
@ -470,6 +640,8 @@ AC_DEFUN_ONCE([ndk_CONFIG_FILES],
AC_SUBST([NDK_BUILD_NASM])
AC_SUBST([NDK_BUILD_MODULES])
AC_SUBST([NDK_BUILD_CXX_SHARED])
AC_SUBST([NDK_BUILD_CXX_STL])
AC_SUBST([NDK_BUILD_CXX_LDFLAGS])
AC_SUBST([NDK_BUILD_ANY_CXX_MODULE])
AC_SUBST([NDK_BUILD_CFLAGS])