corner stamp here.

Android SDK & NDK Part 2: Android talks C++

The Android NDK works in conjunction with JNI (Java Native Interface) which allows connecting Java programs to C/C++. With the NDK, you can compile dynamic and static libraries using the provided cross compilation chain (i.e. a way to create program on a foreign platform or processor).

Although not all Android APIs can be accessed yet from the NDK, the most important one is provided: OpenGL ES, the famous 3D API for handheld devices! In today’s article, I am going to show you how to get a basic NDK project up and running with OpenGL ES 2 and STL support. I am going to explain how to prepare the development environment and how the project files can be personalized.

Go to Android SDK & NDK Part 1: Setting-up your environment

Chapter 1: The Exodus: from Java to C++
Chapter 2: STL & Boost on Android
Chapter 3: Compiling C/C++ libraries with the NDK
Chapter 4: Android talks C++
Chapter 5: Time to run!
References

Special notice:

Please also note that Android currently supports Open GL ES 1.0, 1.1 partially & 2.0 since the Eclair release. I however don’t know if all devices will be compatible with GLES 2.0 eventually. Sadly, this also the case for the Android emulator :( which works only in GLES 1.x mode currently… So if no development phone is available, then consider using GL ES 1.1 only.

The Exodus: from Java to C++

Native libraries can be loaded dynamically when the Java application is launched with a static constructor in the main Java file:

public class VirtualXperiments extends Activity
{
    static
    {
        // Loads the libcubic.so library.
        System.loadLibrary("stlport");
        System.loadLibrary("virtualxp");
    }
}

Dynamic libraries are a piece of executable loaded on demand. They are the only one saved into the final application archive (i.e. the APK file) and loaded from an Android program. Dynamic libraries can be linked together so that a library A can makes use of a library B. And if a third library requires B, then it detects that the library is already loaded and use it (this is why they are also called shared libraries). On the other hand, static libraries are embedded in a dynamic library during compilation: the binary code (is copied into the final library, without regards to duplication. They make dynamic libraries bigger but “all-included”, without dependencies (you may remember the “DLL not found” syndrome on Windows).

And now, to use a native library, well guess what? You need native functions :D:

public class VirtualXperiments extends Activity
{
    ...
    public static native void virtualXpInit (int width, int height);

    public static native void virtualXpStep ();
}

Then just call these functions like classic Java methods! In VirtualXperiments, these methods will handle the Open GL ES calls to render 3D objects (setting the mesh, textures, sending them to the device, etc.). But the screen initialization (e.g. allocating a GL context) and display (e.g. swapping display buffers) has to be performed in Java.

Android provides a Java component named GLSurfaceView to allow easy integration of Open GL ES in Android apps. As our app is going to use Open GL 2 only, we need to use a specialized version of GLSurfaceView which selects a compatible rendering context. Hopefully, Googles’ engineers have included some examples in the NDK (see the hello-gl2 example). I made some trivial modifications to create a GL2SurfaceView component which takes a rendering context (i.e. the application) and a renderer (the rendering logic) as parameters. The corresponding file can be found in the sample project attached to this article and needs to be copied in the com.codexperiments.virtual package.

To integrate this new component, VirtualXperiments.java needs to be updated:

public class VirtualXperiments extends Activity
{
    public void onCreate(Bundle savedInstanceState) {
        ...
        // We remove setContentView(R.layout.main); which loads the GUI defined
        // in the resource files. Instead, we ask the application to use our own
        // Open GL component as GUI.
        setContentView(new GL2SurfaceView(new VirtualXpRenderer(), getApplication()));
    }

    // The GL component uses a renderer to define the rendering logic (what is
    // rendered, where, etc.). It can of course define the application logic too
    // but that is a matter of design.
    // The present renderer delegates computation to the native libraries, which
    // performs itself the application (almost nothing) and rendering operations.
    private static class VirtualXpRenderer implements GLSurfaceView.Renderer {
        public void onDrawFrame(GL10 gl) {
            virtualXpStep();
        }

        public void onSurfaceChanged(GL10 gl, int width, int height) {
            virtualXpInit(width, height);
        }

        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            // Do nothing.
        }
    }
}

The Java side is now ready. Let’s see how to create a native library.

STL & Boost on Android

C++ is a language and not a framework, whereas as Java comes with a full-featured framework (for collections, GUI, etc.). This is why the C++ Standard Template Library has been created. The STL provides lots of useful piece of code such as containers, strings, algorithms, etc… It is now the standard in almost all C/C++ program but several implementation exists with compatibility issues. More particularly, Android NDK causes some trouble with STL because it does not handle exceptions. As stated by Google’s engineer David Turner in the NDK Google Group, exceptions (and RTTI) were deliberately discarded from the official implementation mainly because of the poorly generated code. I do not know if that still stands nowadays, but it has an immediate effect on existing code reusability. Hence the “minimal C++ support” stated by the NDK documentation.

That is why you may find some custom NDK with exceptions ability on the Web. I myself prefer to use the official NDK to avoid any dependency on third party modifications. But if compatibility or code reuse matters to you, then definitely give it a try. Hopefully for me, a few C++ coders patched the popular open source STL implementation named STLport to handle the Android platform (many thanks to Emmanuel in the NDK Google groups). STLport is quite portable (and more lightweight compared to the GNU implementation) and thus provides an option to deactivate exceptions. The patch to fully support Android is currently not included in the official release, so the code must be taken from the repository (you need GIT versioning system client installed on your system):

> git clone git://stlport.git.sourceforge.net/gitroot/stlport/stlport stlport

Put the downloaded directory in the folder “[VIRTUALXP_HOME]/cots”. The COTS directory, which means Component On The Shelf (a popular denomination), contains all external libraries. Although this can overload a bit the versioning system, I prefer having my COTS in my project to save and integrate new versions more easily, avoid version conflicts and have a ready to work project after Checkout. That is a matter of taste!

Anyway, another very popular framework for C++ projects is Boost (can be downloaded from here). Boost is a really huge library, in terms of size as well as functionalities! Hopefully most of it is only templates, which means that only include files (and no C++ implementation files) are provided for most of it. So no need to compile a library here: just include what you need and use it. Boost is particularly famous for its smart pointer implementation, a low-cost C++ wrappers to standard pointers offering additional capabilities like automatic garbage collection. This helps a lot in the prevention of the most common C++ diseases: memory leaks and destroyed object access. See the official documentation for more information on Boost features.

However, I warn you that there are some annoying incompatibilities between StlPort and Boost. One small example: when disabling exception support, boost stops throwing exceptions (that is supported) and passes an exception bad_alloc to the function boost::throw_exception which has to be redefined by users (I didn’t try this yet). Sadly, STLPort does not declare bad_alloc when exception mode is disabled. This looks more like a STLPort bug to me. Anyway, to take care of that, STLPort needs to be modified. Look for _new.h in STLPort (if you are in Eclipse, use Ctrl+Shift+R to quickly find a file by its name. When I was telling you that Eclipse is great!) and create a new optional directive to force bad_alloc declaration by replacing:

...
#if defined (_STLP_USE_EXCEPTIONS) && defined (_STLP_NEW_DONT_THROW_BAD_ALLOC)

#  ifndef _STLP_INTERNAL_EXCEPTION
#    include <stl/_exception.h>
#  endif
...

with the following

...
#if (defined (_STLP_USE_EXCEPTIONS) || defined(_STLP_DEFINE_BAD_ALLOC)) && defined (_STLP_NEW_DONT_THROW_BAD_ALLOC)

#  ifndef _STLP_INTERNAL_EXCEPTION
#    include <stl/_exception.h>
#  endif
...

Don’t forget to redefine throw_exception or you may get an undefined compilation error (especially when using boost smart pointer):

namespace boost
{
    void throw_exception(std::exception const & e)
    {
        Your exception handling here...
    }
}

Now, when compiling STLPort for Android, just define _STLP_DEFINE_BAD_ALLOC directive (-D_STLP_DEFINE_BAD_ALLOC in VIRTUALXP_CFLAGS, see next chapter) or add it (#define _STLP_DEFINE_BAD_ALLOC 1) to _android.h in STLPort config directory. You should also define BOOST_EXCEPTION_DISABLE and BOOST_NO_EXCEPTIONS for Boost. Note that as the sample project at the end of the article is very simple and doesn’t need Boost, these are not defined in the provided files.

Compiling C/C++ libraries with the NDK

The building system has changed with the new NDK R4. Prior to that version, a project descriptor Application.mk located in the “[ANDROID_NDK]/app” directory was required. That file, which was built using make, had to point to your home project containing an Android.mk file which was the real makefile. And to build native libraries, being in the NDK directory when launching the make command was a necessary condition.

The NDK R4 building system is now a bit simpler: the only thing required is to have an Android.mk file under a “jni” directory within your own project (e.g. in [VIRTUALXP_HOME]/jni). The new ndk-build command, located in [ANDROID_NDK], can then be launched from your project directory (or using the -C parameter to specifiy your project directory).

Because I like to personalize my project directories, I am still going to use an Application.mk file. This file is a prerequisite for people who do not want to use the “jni” directory. In my case, I like to name it “cpp”. Let’s create a [VIRTUALXP_HOME]/Application.mk file which defines the C/C++ projects to compile and the main options:

# Defines where your project folder is. It can be an absolute path to your Java
# project or a path relative to the current dir (where ndk-build is launched)
# defined by my-dir (NDK project file location, e.g. [NDK_HOME]/app/cubic/project).
APP_PROJECT_PATH := $(call my-dir)
# Defines the name and path of the makefile
APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/Android.mk
$(info $(APP_BUILD_SCRIPT))
# Defines the native projects that must be compiled. These names point to the libs
# defined in the Android.mk file.
APP_MODULES      := stlport virtualxp
# Can be set to release or debug. For optimization purpose.
APP_OPTIM        := debug

Edit 11/06/2010: I just discovered that in the NDK R4, APP_MODULES is not required any more. If it’s not specified, by default, all modules will be compiled. So it’s fine not to define it.

Then, we need to create in [VIRTUALXP_HOME] the Android.mk file, which is the C/C++ makefile handling cross compilation. Its location is defined by the APP_BUILD_SCRIPT variable defined in the Application.mk. As previously said, by convention, it should be located in [VIRTUALXP_HOME]/jni. But why doing simple when we can do pretty :D:

# Stores the project directory. Useful when you compile several libraries to restore
# the build location.
VIRTUALXP_HOME := $(call my-dir)

# Defines common options (android release, here the 5th which is bundled with
# Android Java API 5, 6 and 7). Also defines some preprocessor variables for
# Open GL ES (for extensions beware that it may not be compatible with all
# devices), STLport, ...
VIRTUALXP_CFLAGS     := \
-isystem $(SYSROOT)/usr/include --sysroot=build/platforms/android-5/arch-arm \
-mandroid -Wno-psabi \
-DGL_GLEXT_PROTOTYPES -D_STLP_NO_CWCHAR -D__ANDROID__ -DDEBUG

# This is a C++ optimization, nothing specific to Android. It avoids (when applicable)
# copying objects initialized inside a function when they are returned. They get
# initialized directly at their final location.
VIRTUALXP_CPPFLAGS   := -felide-constructors

# STLport compilation
# Clear options from previous compiled projects if appliable.
include $(CLEAR_VARS)

# Name of the project, used in the Application.mk project file.
LOCAL_MODULE    := stlport
# C Compiler options. "-I" adds C/C++ include files from the specified directory.
LOCAL_CFLAGS    := $(VIRTUALXP_CFLAGS) -I$(VIRTUAL_HOME)/cots/stlport/stlport
# C++ compiler options
LOCAL_CPPFLAGS  := $(VIRTUALXP_CPPFLAGS)
# Project source directory.
LOCAL_PATH      := $(VIRTUALXP_HOME)/cots/stlport/src
# I only compile the files I need to make compilation faster and more important
# the final stl library smaller (40Kb instead of 750Kb).
#LOCAL_SRC_FILES := strstream.cpp messages.cpp iostream.cpp ctype.cpp dll_main.cpp complex_trig.cpp locale_catalog.cpp complex_io.cpp allocators.cpp string.cpp ostream.cpp locale_impl.cpp libstlport.so locale.cpp istream.cpp time_facets.cpp fstream.cpp bitset.cpp codecvt.cpp stdio_streambuf.cpp complex.cpp ios.cpp sstream.cpp num_put.cpp num_put_float.cpp cxa.c facets_byname.cpp numpunct.cpp monetary.cpp num_get_float.cpp num_get.cpp c_locale.c collate.cpp
LOCAL_SRC_FILES := allocators.cpp dll_main.cpp

include $(BUILD_SHARED_LIBRARY)

# VirtualXperiments compilation
include $(CLEAR_VARS)

LOCAL_MODULE    := virtualxp
# The source code will be located in a cpp folder
LOCAL_PATH      := $(VIRTUALXP_HOME)/cpp
LOCAL_CFLAGS    := $(VIRTUALXP_CFLAGS)
LOCAL_CPPFLAGS  := $(VIRTUALXP_CPPFLAGS) -I$(VIRTUALXP_HOME)/cots/stlport/stlport
LOCAL_SRC_FILES := VirtualXpJNI.cpp
LOCAL_SHARED_LIBRARIES := stlport
# Do not forget to indicates the required dynamic libraries. They will not be
# embedded in the present library but rather loaded at the same time.
# Library names must appear undecorated (GLESv2 instead of libGLESv2.so).
# If you want to use static libraries, then the LOCAL_STATIC_LIBRARIES
# variable has to be used instead.
LOCAL_LDLIBS    := -llog -lGLESv2

include $(BUILD_SHARED_LIBRARY)

Edit 12/03/2010: After digging a bit (thank you G.D.) -DTARGET_OS=android, -DANDROID and -D__SGI_STL_INTERNAL_PAIR_H were reminiscences of some past code and are not necessary any more. -Dandroid was used by my own engine (so not required here). On the other hand__ANDROID__ is used by stlport. But although it looks like it can compile without it, I’d rather set it! -D__NEW__ is used to bypass new included in arch-arm and avoid a conflict with operators provided by STLPort. However it’s already defined in STLPort _android.h config file and therefore is not essential. The Android.mk above is now updated with these modifications.

Moreover, I don’t know if some of you got the problem, but when deploying an application with STLPort on a recent device, I kept running into an unexpected crash until I realized there was already a  “stlport” system library. I don’t know if that was specific to this device or if it is systematically deployed on Android 2.2. Anyway, a simple solution to that problem is to rename LOCAL_MODULE stlport into something different (like mystlport) and any references in LOCAL_SHARED_LIBRARIES option.

The NDK project is now configured. We only miss one minor thing now: the source code!

Android talks C++

I have created two source files: VirtualXpJNI.cpp and VirtualXp.cpp. No need for includes files in this very simple project. Below is VirtualXpJNI.cpp. This file is the entry point for the native library. It defines and implements the native methods found earlier in the Java part. These JNI methods are just calling an internal function. This indirection avoids coupling between JNI interface and C/C++ code and thus improves reusability. And finally, notice the keyword extern “C” which forbids name mangling when C++ compiler is used (to ensure functions names are unique). Indeed, Java expects the C convention when looking for native methods.

#include <jni.h>
#include "VirtualXp.cpp"

extern "C" {
    JNIEXPORT void JNICALL Java_com_codexperiments_virtual_VirtualXperiments_virtualXpInit(JNIEnv * env, jobject obj,  jint width, jint height);
    JNIEXPORT void JNICALL Java_com_codexperiments_virtual_VirtualXperiments_virtualXpStep(JNIEnv * env, jobject obj);
};

JNIEXPORT void JNICALL Java_com_codexperiments_virtual_VirtualXperiments_virtualXpInit(JNIEnv * env, jobject obj,  jint width, jint height)
{
    setupGraphics(width, height);
}

JNIEXPORT void JNICALL Java_com_codexperiments_virtual_VirtualXperiments_virtualXpStep(JNIEnv * env, jobject obj)
{
    renderFrame();
}

Native methods names are constituted of:

  • a concatenation of the “Java_” prefix, the Java package path, the class name and finally the native method name. Underscores are used as separators.
  • a return type surrounded by the JNIEXPORT and JNICALL macros which respectively publishes the method (to make it available to the outside world) and describes the calling convention (parameter order, stack or registered based, etc.).
  • a JNIEnv parameter, which is a handle to JVM functions (more information on Chapter 4 of the official Sun JNI documentation, see references), like creating Java arrays, calling java method (in a way similar to the Reflection API), etc… JNIEnv is specific to each thread and thus, can not be shared.
  • effective parameters. Basic types are redefined by JNI to be compatible with the JVM: jint for integer, jstring for strings, jobject for Java objects, etc.

The second file is VirtualXp.cpp. This is the file which contains the effective OpenGL code which is going to render a simple green triangle. This code is the one that can be found in the Android NDK example hello-gl2. I am not going to explain it here as this is practically pure Open GL code: renderFrame() is called by Java at each iteration through the JNI interface.

#include <android/log.h>
...
#define  LOG_TAG    "libclubic"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
...
LOGI("after %s() glError (0x%x)\n", op, error);
...
void renderFrame() {
    ...
    glClearColor(grey, grey, grey, 1.0f);
    ...
}
...

The only point I want to notice is the Android specific code which logs message the way a classic printf would. Although many of the Java features are not provided (in which case it should probably be implemented in Java anyway), it is always good idea to look for what is available (e.g. zlib) in your “[Android_NDK]/build/platforms/[your platform]/arch-arm/usr/include” folder.

Time to run!

We are almost done! To compile the project, go to the $ANDROID_NDK directory and run the following command:

[Android_NDK]/ndk-build -C [VirtualXperiments] NDK_APPLICATION_MK=[VirtualXperiments]/Application.mk

And if you want to erase what has been previously compiled, just add the clean parameter

[Android_NDK]/ndk-build -C [VirtualXperiments] NDK_APPLICATION_MK=[VirtualXperiments]/Application.mk clean

Just check that the libraries have been generated and copied into the “[VIRTUALXP_HOME]/libs” directory. And voilà! Your first hybrid app is compiled! Just a little trick to compile automatically with eclipse:

  • Right click on your Project and click on the “Properties” item,
  • Select the Builders tab
  • Create a new builder of type Program
  • Click on the first “Variables…” button.
  • Select “Edit Variables…” and add a new ANDROID_NDK environment variable pointing to your own [ANDROID_NDK] directory. It is always a good idea to make use of Eclipse variables to keep a environment independent project configuration.
  • Fill-in the form like in the screenshot below. If you use a different project name, then just replace VirtualXperiments by your own project name.
  • Now, when you click on the build button, ndk-build will be automatically run and native libraries built. Much easier!

Automatically launch the NDK build command using Eclipse

Now run it using Eclipse (click on the Run or Debug button) after making sure your phone is connected. I remind you that Open GL ES 2 does not work on the Android emulator, so no need to try to run VirtualXperiments on it. The final project can be downloaded here.

The final result

I will try to explain in a future post how to set-up a Open GL ES environment on your Linux system with the PowerVR SDK. This is a really practical way to debug applications directly on your computer and to analyse them with tools such as Valgrind (for memory leaks, etc.).

References

  1. Sandeep

    Hi,

    I downloaded your code and trying to compile the application and getting the following error.

    Problems occurred building the selected resources.
    Errors running builder ‘Integrated External Tool Builder’ on project ‘VirtualXperiments’.
    Exception occurred executing command line.
    Cannot run program “C:\Program Files\Android\android-ndk-r5\ndk-build” (in directory “E:\Projects\Std\Learning\10.Learning_android\sample\VirtualXperiments”): CreateProcess error=193, %1 is not a valid Win32 application
    Exception occurred executing command line.
    Cannot run program “C:\Program Files\Android\android-ndk-r5\ndk-build” (in directory “E:\Projects\Std\Learning\10.Learning_android\sample\VirtualXperiments”): CreateProcess error=193, %1 is not a valid Win32 application

  2. www-admin

    Hi Sandeep,

    I suppose there is an error because I use an External Builder (see Eclipse Project properties) to launch NDK compiler from Eclipse and the process launched (i.e. ndk-build) is not valid or does not exist on your system. You should check that you have downloaded the proper NDK for windows and that ndk-build is working (for example by trying to launch ndk-build in command line).

    Hope that helps.

  3. alexander

    Hi.
    i’m working with ndk and have the logic for my apps in C/C++, starting some experiments with opengl es too.
    i’m very interested in the tools to debug and profile, whats your experience with valgrind, how can you set a good working environment. right now i’m debugging with gdb but i dont have any tool to see how the memory of my app is going.
    can you tell me something about this. thanks

  4. www-admin

    Well as far as I know, Valgrind doesn’t have an ARM implementation. So it’s not possible to run Valgrind directly on Android. The only way I found is to use PowerVR SDK to emulate OpenGL ES on a X86 PC (see part 3 of the series). And it works quite well! I found some memory management mistakes in my code which were making it crashing and was able to fix them on my PC. It then worked perfectly after recompiling my code on Android.

    The big drawback is that more code is necessary to develop X86 specific code to emulate Android features (mainly GL ES window creation, input handling, etc.).

  5. Ekko

    Hi,

    I have everything setup and running like you presented here. GL2JNIActivity works fine on my Samsung Galaxy S.
    However, when i’m trying to link to another module it doesn’t work, it just crashes at start.
    All i did was use the simplest shared library (which is also a sample in the Android NDK – called Module-Exports)

    LOCAL_PATH:= $(call my-dir)

    include $(CLEAR_VARS)
    LOCAL_MODULE := foo
    LOCAL_SRC_FILES := Libraries/FooStaticLib/foo.c
    LOCAL_CFLAGS := -DFOO=2
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/Libraries/FooStaticLib
    LOCAL_EXPORT_CFLAGS := -DFOO=1
    LOCAL_EXPORT_LDLIBS := -llog
    include $(BUILD_STATIC_LIBRARY)

    include $(CLEAR_VARS)
    LOCAL_MODULE := bar
    LOCAL_SRC_FILES := Libraries/BarSharedLib/bar.c
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/Libraries/BarSharedLib
    LOCAL_STATIC_LIBRARIES := foo
    include $(BUILD_SHARED_LIBRARY)

    include $(CLEAR_VARS)

    LOCAL_MODULE := libgl2jni
    LOCAL_CFLAGS := -Werror
    LOCAL_SRC_FILES := gl_code.cpp

    LOCAL_STATIC_LIBRARIES := foo #works with the static library
    #LOCAL_SHARED_LIBRARIES := bar #crashs if i use this
    LOCAL_LDLIBS := -llog -lGLESv2 -ldl -lz

    include $(BUILD_SHARED_LIBRARY)

    Everything is in order in terms of files being in the right directories i.e. Libraries/FooStaticLib and Libraries/BarSharedLib

    Can you try to reproduce this? Any ideeas?

    Thanks,
    Ekko

  6. www-admin

    Hi Ekko,

    Check your final APK that is deployed on your phone to see if it contains your all the .so libraries (it’s just a zip file).
    Also, and more importantly, look at the Eclipse Logcat (or download a tool on your phone) to detect what is exactly happening. My bet is that it is an “unsatisfied linked library error” or something like that. That happens often for example when forgetting to build native libs with ndk-build while building the final Java application.

    It is not the cause of your problem but I am surprised to see you need LOCAL_EXPORT_C_INCLUDES as I think it is reserved to prebuilt libraries (I am not absolutely sure however) built with “include $(PREBUILT_SHARED_LIBRARY)”. Are you sure these directive works?

    Good luck.

  7. Rohit Krishnan » Setting Up Android NDK

    [...] C++ and Android development. Before you continue to the next part, you should probably check out this page for more information on the structure of a C++ Android program (not really the same format as [...]

  8. KennethMcKnight

    Thanks for your great Blog!
    Very helpful for a newby to Android coming from WinMobile.

    I found one error, drives me crazy while reading, before I understand that it is an typing eror!!
    - This sentences:
    >> I am still going to use an ANDROID.MK file.
    - should be:
    >> I am still going to use an APPLICATION.MK file.

    Regards Kenneth

  9. android | Pearltrees

    [...] The Android NDK works in conjunction with JNI (Java Native Interface) which allows connecting Java programs to C/C++. Android SDK & NDK Part 2: Android talks C++ – Code Xperiments [...]

  10. Nathan Glenn

    @Sandeep: point Eclipse to the file called “ndk-build.cmd”.

  11. montreux

    I set up the system very closely to what you mentioned, but I’m having difficulty with the following error: “error: ‘invalid_argument’ is not a member of ‘std’”. Here is my Application.mk file:
    ###################################################
    APP_PROJECT_BUILD := $(shell pwd)
    APP_ABI := armeabi-v7a
    APP_STL := gnustl_static
    APP_PROJECT_PATH := $(shell pwd)
    APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/Android.mk
    ###################################################

    And here is my Android.mk file that is located inside the appropriate directory:
    ###################################################

    LOCAL_PATH := $(call my-dir)

    local_src_files := gmp-utils.cpp gmp-ntl-conv.cpp redc_1.s

    local_c_includes := \
    /prod/android-ndk-r8/workspace/verifiable/gmp-precompiled/armeabi-v7a/include \
    /prod/android-ndk-r8/workspace/verifiable/openssl-android/include/openssl \
    /prod/android-ndk-r8/workspace/verifiable/ntl-6.0.0/include/NTL

    local_c_flags := -O \
    -I/prod/android-ndk-r8/workspace/verifiable/gmp-precompiled/armeabi-v7a/include \
    -I/prod/android-ndk-r8/workspace/verifiable/openssl-android/include/openssl \
    -I/prod/android-ndk-r8/workspace/verifiable/ntl-6.0.0/include

    # INCLUDE GMP SHARED LIBRARY
    include $(CLEAR_VARS)
    LOCAL_MODULE := gmp
    LOCAL_SRC_FILES :=/prod/android-ndk-r8/workspace/verifiable/verifiable-delegation/jni/libprebuild/libgmp.so
    LOCAL_C_INCLUDES :=/prod/android-ndk-r8/workspace/verifiable/gmp-precompiled/armeabi-v7a/include
    include $(PREBUILT_SHARED_LIBRARY)

    # INCLUDE GMPXX (DIDN’T WE GET RID OF THIS?)
    include $(CLEAR_VARS)
    LOCAL_MODULE := gmpxx
    LOCAL_SRC_FILES :=/prod/android-ndk-r8/workspace/verifiable/verifiable-delegation/jni/libprebuild/libgmpxx.so
    LOCAL_C_INCLUDES :=/prod/android-ndk-r8/workspace/verifiable/gmp-precompiled/armeabi-v7a/include
    include $(PREBUILT_SHARED_LIBRARY)

    # INCLUDE OPENSSL LIBCRYPTO
    include $(CLEAR_VARS)
    LOCAL_MODULE := crypto
    LOCAL_SRC_FILES :=/prod/android-ndk-r8/workspace/verifiable/verifiable-delegation/jni/libprebuild/libcrypto.so
    LOCAL_C_INCLUDES :=/prod/android-ndk-r8/workspace/verifiable/openssl-android/include/openssl
    include $(PREBUILT_SHARED_LIBRARY)

    # INCLUDE OPENSSL LIBSSL
    include $(CLEAR_VARS)
    LOCAL_MODULE := ssl
    LOCAL_SRC_FILES :=/prod/android-ndk-r8/workspace/verifiable/verifiable-delegation/jni/libprebuild/libssl.so
    LOCAL_C_INCLUDES :=/prod/android-ndk-r8/workspace/verifiable/openssl-android/include/openssl
    include $(PREBUILT_SHARED_LIBRARY)

    # INCLUDE NTL
    include $(CLEAR_VARS)
    LOCAL_MODULE := ntl
    LOCAL_SRC_FILES :=/prod/android-ndk-r8/workspace/verifiable/verifiable-delegation/jni/libprebuild/libntl.so
    LOCAL_C_INCLUDES :=/prod/android-ndk-r8/workspace/verifiable/ntl-6.0.0/include/NTL
    include $(PREBUILT_SHARED_LIBRARY)

    # BUILD GMP-UTILS
    include $(CLEAR_VARS)
    LOCAL_CPP_EXTENSION := .c .cxx .cpp .cc
    LOCAL_SRC_FILES += $(local_src_files)
    LOCAL_C_INCLUDES += $(local_c_includes)
    LOCAL_C_INCLUDES +=/prod/android-ndk-r8e/sources/cxx-stl/stlport/stlport
    LOCAL_CFLAGS += $(local_c_flags)
    LOCAL_MODULE_TAGS := optional
    LOCAL_MODULE := gmp-utils
    LOCAL_SHARED_LIBRARIES := libcrypto libssl libgmp libgmpxx libntl
    include $(BUILD_SHARED_LIBRARY)
    #######################################################

    I tried changing the APP_STL variable, but to no success. The headers are also all included, so no error there in particular.

  12. www-admin

    Hi,

    First, make sure you have enabled exceptions (and rtti if you need it) because I don’t see any flag in your makefile:
    LOCAL_CPPFLAGS += -fexceptions -frtti
    or to enable exceptions everywhere:
    APP_CPPFLAGS += -fexceptions -frtti

    I see that you use at the same time gnustl_static (APP_STL := gnustl_static) and STLport (LOCAL_C_INCLUDES +=/prod/android-ndk-r8e/sources/cxx-stl/stlport/stlport). You should make sure there is no “conflict” between both (and probably use one of them only).

    Also check you have properly included all the necessary header files in your sources (if your problem is there).
    You doesn’t seem to use it but there also seems to be many problems related to C++11 support. Here are a few pointers:
    http://stackoverflow.com/questions/14532057/smart-pointers-not-working-with-android-ndk-r8
    http://stackoverflow.com/questions/11730111/how-to-use-c0x-thread-in-android-ndk
    http://stackoverflow.com/questions/15269496/how-to-compile-c11-code-with-android-ndk-and-eclipse

    One way to see if this is an isolated bug or a real setup problem is to define yourself an std::invalid_argument exception (maybe in gnulstl source in your NDK or in your own source depending on where the problem comes from problem).

    Also, there are often some breaking changes or bugs in the NDK. Don’t hesitate to try a previous version if necessary.

    Hope that helps!

Leave a Reply