Add APP_STL to select the C++ STL automatically.
This patch allows developers to define APP_STL in their
Application.mk in order to select the C++ STL they want to
use automatically.
Valid values are "system", "stlport_static" and "stlport_shared".
See the new document docs/STL-SUPPORT.html for more details.
Note that the patch also contains changes that will make room
for other C++ STL implementations (GNU libstdc++ and maybe uSTL)
Change-Id: Ica3fbad90d31deb9699e6cfb4a1cff3cd2e6c890
diff --git a/build/core/add-application.mk b/build/core/add-application.mk
index 5c6870c..70c133e 100644
--- a/build/core/add-application.mk
+++ b/build/core/add-application.mk
@@ -193,6 +193,17 @@
APP_CFLAGS := -O2 -DNDEBUG -g $(APP_CFLAGS)
endif
+# Check that APP_STL is defined. If not, use the default value (system)
+# otherwise, check that the name is correct.
+APP_STL := $(strip $(APP_STL))
+ifndef APP_STL
+ APP_STL := system
+else
+ $(call ndk-stl-check,$(APP_STL))
+endif
+
+
+
$(if $(call get,$(_map),defined),\
$(call __ndk_info,Weird, the application $(_app) is already defined by $(call get,$(_map),defined))\
$(call __ndk_error,Aborting)\
diff --git a/build/core/definitions.mk b/build/core/definitions.mk
index b2b3e0d..0b3893b 100644
--- a/build/core/definitions.mk
+++ b/build/core/definitions.mk
@@ -853,7 +853,7 @@
# the list of variables that *may* be defined in Application.mk files
NDK_APP_VARS_OPTIONAL := APP_OPTIM APP_CPPFLAGS APP_CFLAGS APP_CXXFLAGS \
APP_PLATFORM APP_BUILD_SCRIPT APP_ABI APP_MODULES \
- APP_PROJECT_PATH
+ APP_PROJECT_PATH APP_STL
# the list of all variables that may appear in an Application.mk file
# or defined by the build scripts.
@@ -1254,3 +1254,76 @@
$(call module-class-register,PREBUILT_STATIC_LIBRARY,,)
$(call module-class-set-prebuilt,PREBUILT_STATIC_LIBRARY)
+#
+# C++ STL support
+#
+
+# The list of registered STL implementations we support
+NDK_STL_LIST :=
+
+# Used internally to register a given STL implementation, see below.
+#
+# $1: STL name as it appears in APP_STL (e.g. system)
+# $2: STL module name (e.g. cxx-stl/system)
+# $3: list of static libraries all modules will depend on
+# $4: list of shared libraries all modules will depend on
+#
+ndk-stl-register = \
+ $(eval __ndk_stl := $(strip $1)) \
+ $(eval NDK_STL_LIST += $(__ndk_stl)) \
+ $(eval NDK_STL.$(__ndk_stl).IMPORT_MODULE := $(strip $2)) \
+ $(eval NDK_STL.$(__ndk_stl).STATIC_LIBS := $(strip $3)) \
+ $(eval NDK_STL.$(__ndk_stl).SHARED_LIBS := $(strip $4))
+
+# Called to check that the value of APP_STL is a valid one.
+# $1: STL name as it apperas in APP_STL (e.g. 'system')
+#
+ndk-stl-check = \
+ $(if $(call set_is_member,$(NDK_STL_LIST),$1),,\
+ $(call __ndk_info,Invalid APP_STL value: $1)\
+ $(call __ndk_info,Please use one of the following instead: $(NDK_STL_LIST))\
+ $(call __ndk_error,Aborting))
+
+# Called before the top-level Android.mk is parsed to
+# select the STL implementation.
+# $1: STL name as it appears in APP_STL (e.g. system)
+#
+ndk-stl-select = \
+ $(call import-module,$(NDK_STL.$1.IMPORT_MODULE))
+
+# Called after all Android.mk files are parsed to add
+# proper STL dependencies to every C++ module.
+# $1: STL name as it appears in APP_STL (e.g. system)
+#
+ndk-stl-add-dependencies = \
+ $(call modules-add-c++-dependencies,\
+ $(NDK_STL.$1.STATIC_LIBS),\
+ $(NDK_STL.$1.SHARED_LIBS))
+
+#
+#
+
+# Register the 'system' STL implementation
+#
+$(call ndk-stl-register,\
+ system,\
+ cxx-stl/system,\
+ libstdc++,\
+ )
+
+# Register the 'stlport_static' STL implementation
+#
+$(call ndk-stl-register,\
+ stlport_static,\
+ android/stlport,\
+ stlport_static,\
+ )
+
+# Register the 'stlport_shared' STL implementation
+#
+$(call ndk-stl-register,\
+ stlport_shared,\
+ android/stlport,\
+ ,\
+ stlport_shared\
+ )
diff --git a/build/core/setup-toolchain.mk b/build/core/setup-toolchain.mk
index 1a120f0..301aab2 100644
--- a/build/core/setup-toolchain.mk
+++ b/build/core/setup-toolchain.mk
@@ -18,7 +18,7 @@
#
$(call assert-defined,TARGET_PLATFORM TARGET_ARCH TARGET_ARCH_ABI)
-$(call assert-defined,NDK_APPS)
+$(call assert-defined,NDK_APPS NDK_APP_STL)
# Check that we have a toolchain that supports the current ABI.
# NOTE: If NDK_TOOLCHAIN is defined, we're going to use it.
@@ -138,16 +138,13 @@
# free the dictionary of LOCAL_MODULE definitions
$(call modules-clear)
+$(call ndk-stl-select,$(NDK_APP_STL))
+
# now parse the Android.mk for the application, this records all
# module declarations, but does not populate the dependency graph yet.
include $(NDK_APP_BUILD_SCRIPT)
-# special case of C++ runtime support: If any module has C++ sources,
-# we need to parse the Android.mk for our selected C++ runtime and
-# add it as an automatic dependency to the corresponding modules.
-#
-include $(NDK_ROOT)/sources/cxx-stl/system/setup.mk
-$(call modules-add-c++-dependencies,$(NDK_APP_CXX_STATIC_LIBRARIES),$(NDK_APP_CXX_SHARED_LIBRARIES))
+$(call ndk-stl-add-dependencies,$(NDK_APP_STL))
# recompute all dependencies between modules
$(call modules-compute-dependencies)
diff --git a/docs/APPLICATION-MK.html b/docs/APPLICATION-MK.html
index 96d9241..31a12a1 100644
--- a/docs/APPLICATION-MK.html
+++ b/docs/APPLICATION-MK.html
@@ -149,6 +149,20 @@
For the list of all supported ABIs and details about their usage and
limitations, please read docs/CPU-ARCH-ABIS.html
+APP_STL
+ By default, the NDK build system provides C++ headers for the minimal
+ C++ runtime library (/system/lib/libstdc++.so) provided by the Android
+ system.
+
+ However, the NDK comes with alternative C++ implementations that you can
+ use or link to in your own applications. Define APP_STL to select one of
+ them. Examples are:
+
+ APP_STL := stlport_static --> static STLport library
+ APP_STL := stlport_shared --> shared STLport library
+ APP_STL := system --> default C++ runtime library
+
+ For more information on the subject, please read docs/STL-SUPPORT.html
A trivial Application.mk file would be:
diff --git a/docs/CHANGES.html b/docs/CHANGES.html
index 1ea6a63..cb09431 100644
--- a/docs/CHANGES.html
+++ b/docs/CHANGES.html
@@ -80,6 +80,11 @@
Note that they still correspond to our minimal C++ runtime, no new feature
was introduced here.
+- Add sources and prebuilt binaries for a port of the STLport C++ Standard
+ Library (www.stlport.org), and an easy way to use it at build time by
+ defining APP_STL in your Application.mk. See docs/APPLICATION-MK.html and
+ docs/STL-SUPPORT.html for all details.
+
- Add support for prebuilt libraries with the PREBUILT_SHARED_LIBRARY and
PREBUILT_STATIC_LIBRARIES build scripts. See the new documentation
file named docs/PREBUILTS.html for explanations and usage examples.
diff --git a/docs/STL-SUPPORT.html b/docs/STL-SUPPORT.html
new file mode 100644
index 0000000..8335883
--- /dev/null
+++ b/docs/STL-SUPPORT.html
@@ -0,0 +1,93 @@
+<html><body><pre>
+C++ STL support with the Android NDK
+====================================
+
+
+The Android platform provides a very minimal C++ runtime support library
+(/system/lib/libstdc++) and corresponding headers for it in the NDK.
+
+If your C++ code needs a real Standard C++ Library, the NDK provides you
+with a port of the STLport library (www.stlport.org) and a way to use it
+easily in your applications.
+
+I. Usage:
+---------
+
+ Define APP_STL to name the C++ STL implementation you would want to use.
+ This instructs the NDK build system to automatically provide for the correct
+ headers and library dependencies for your C++ sources and modules.
+
+ Valid values are:
+
+ "system": The default minimal C++ runtime support library
+ "stlport_static": STLport built as a static library.
+ "stlport_shared": STLport built as a shared library.
+
+ "stlport_shared" is preferred if you have several shared libraries in your
+ project that use the C++ STL, because it avoids duplication of functions
+ and more importantly of global variables (e.g. std::cout) in each one of
+ them, which can have surprising results.
+
+ On the other hand, you will have to load it explicitely when starting your
+ application, as in the following example:
+
+ static {
+ System.loadLibrary("stlport_shared");
+ System.loadLibrary("foo");
+ System.loadLibrary("bar");
+ }
+
+ Where both "libfoo.so" and "libbar.so" depend on "libstlport_shared.so".
+
+ Note that the shared library's name if "libstlport_shared.so" to avoid
+ naming conflicts with certain Android system images which include a
+ system-level libstlport.so (which happens to not be ABI-stable and
+ cannot be used from NDK-generated machine code).
+
+ "stlport_static" is preferred if you have only one shared library in your
+ project: only the STL functions and variables you actually need will be
+ linked to your machine code, reducing its code size, and you won't need
+ to load the dynamic stlport_shared at startup.
+
+ 2/ Rebuild
+
+ After defining APP_STL, just rebuild your native code with $NDK/ndk-build
+ as usual.
+
+
+ 3/ Debugging
+
+ The NDK provides prebuilt binaries of STLport to speed up development.
+ It can be however useful to rebuild the library from sources in order
+ to make native debugging easier. To do so, define the following in your
+ environment or your Application.mk before building:
+
+ STLPORT_FORCE_REBUILD := true
+
+
+II. Licensing:
+--------------
+
+ See sources/android/stlport/README for more information about the
+ STLport sources distributed with this SDK.
+
+ STLport is under a BSD-style open-source license.
+
+II. Known Issues:
+-----------------
+
+ - The STLport version provided with this NDK does not support C++ exceptions
+ and RTTI.
+
+ - No support for STLport in "standalone toolchain" mode.
+ (See docs/STANDALONE-TOOLCHAIN.html)
+
+
+III. Future Plans:
+------------------
+
+ - GNU libstdc++ support
+ - Exceptions and RTTI support
+ - uSTL support?
+
+</pre></body></html>
diff --git a/sources/android/stlport/Android.mk b/sources/android/stlport/Android.mk
index 96fc9d1..b0a6769 100644
--- a/sources/android/stlport/Android.mk
+++ b/sources/android/stlport/Android.mk
@@ -54,6 +54,11 @@
libstlport_cppflags := -fuse-cxa-atexit
libstlport_c_includes := $(libstlport_path)/stlport
+# Note: For now, this implementation depends on the system libstdc++
+# We may want to avoid that in the future, i.e. in order to
+# properly support exceptions and RTTI.
+libstlport_static_libs := libstdc++
+
ifneq ($(STLPORT_FORCE_REBUILD),true)
$(call ndk_log,Using prebuilt STLport libraries)
@@ -61,12 +66,14 @@
include $(CLEAR_VARS)
LOCAL_MODULE := stlport_static
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE).a
+LOCAL_STATIC_LIBRARIES := $(libstlport_static_libs)
LOCAL_EXPORT_C_INCLUDES := $(libstlport_c_includes)
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := stlport_shared
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE).so
+LOCAL_STATIC_LIBRARIES := $(libstlport_static_libs)
LOCAL_EXPORT_C_INCLUDES := $(libstlport_c_includes)
include $(PREBUILT_SHARED_LIBRARY)
@@ -80,6 +87,7 @@
LOCAL_CFLAGS := $(libstlport_cflags)
LOCAL_CPPFLAGS := $(libstlport_cppflags)
LOCAL_C_INCLUDES := $(libstlport_c_includes)
+LOCAL_STATIC_LIBRARIES := $(libstlport_static_libs)
LOCAL_EXPORT_C_INCLUDES := $(libstlport_c_includes)
include $(BUILD_STATIC_LIBRARY)
@@ -89,7 +97,11 @@
LOCAL_CFLAGS := $(libstlport_cflags)
LOCAL_CPPFLAGS := $(libstlport_cppflags)
LOCAL_C_INCLUDES := $(libstlport_c_includes)
+LOCAL_STATIC_LIBRARIES := $(libstlport_static_libs)
LOCAL_EXPORT_C_INCLUDES := $(libstlport_c_includes)
include $(BUILD_SHARED_LIBRARY)
endif # STLPORT_FORCE_REBUILD == true
+
+# See above not above libstdc++ dependency.
+$(call import-module,cxx-stl/system)
diff --git a/tests/device/test-stlport/jni/Android.mk b/tests/device/test-stlport/jni/Android.mk
index f8f5cb3..1acf6f7 100644
--- a/tests/device/test-stlport/jni/Android.mk
+++ b/tests/device/test-stlport/jni/Android.mk
@@ -20,8 +20,4 @@
LOCAL_SRC_FILES := $(sources)
LOCAL_SRC_FILES += unit/cppunit/test_main.cpp
-LOCAL_STATIC_LIBRARIES := stlport_static
include $(BUILD_EXECUTABLE)
-
-$(call import-module,android/stlport)
-
diff --git a/tests/device/test-stlport/jni/Application.mk b/tests/device/test-stlport/jni/Application.mk
new file mode 100644
index 0000000..caf3b26
--- /dev/null
+++ b/tests/device/test-stlport/jni/Application.mk
@@ -0,0 +1 @@
+APP_STL := stlport_static