58

This is more of an answer than a question, because I've figured it out, at least as far as cleanly compiling the library. The main issue for me was to get shared_ptr working.

Ingredients:

Boost v. 1.45.0

The version of STLport at http://www.anddev.org/viewtopic.php?p=29939.

Version r4b of the NDK.

Directions:

In your Android.mk file add:

LOCAL_CFLAGS += -DBOOST_EXCEPTION_DISABLE -D_STLP_NO_EXCEPTIONS -DOS_ANDROID -D_STLP_USE_SIMPLE_NODE_ALLOC

Remove the call to __stl_throw_length_error at line 613 of stlport/stl/_string.h. You can use _STLP_NO_EXCEPTIONS if you like.

Edit boost/boost/smart_ptr/shared_ptr.hpp after line 261 to get rid of the call to boost::throw_exception in the shared_ptr constructor. I used #ifndef BOOST_EXCEPTION_DISABLE around the entire body of the method. (But see the answer below.)

Next you need to supply some missing pieces. Create a header file with the following:

#ifdef OS_ANDROID

#include <exception>

namespace std
{
    struct bad_alloc : public exception { bad_alloc operator()(){}};
}

#endif

and a source file with a stripped-down exception class to support bad_alloc:

#ifdef OS_ANDROID

#include <exception>

namespace std
{
    exception::exception() {}
    exception::~exception() {}
    const char* exception::what() const {}
}

#endif

Include the header wherever you're including boost/shared_ptr.hpp. Compile the source and add it to your library.

Gamma Draconis
  • 1,166
  • 1
  • 9
  • 11
  • 9
    To keep this question from being open forever, it would be very cool if you could rephrase this post as a question and then answer it yourself, as suggested by the [FAQ](http://stackoverflow.com/faq#ask). – dennycrane Dec 03 '10 at 15:49
  • 1
    Thanks for sharing what you've learnt! I'm sure this is helpful for many. – Daniel Lidström Dec 03 '10 at 16:08
  • Dennycrane, I'm still experimenting with this approach, so I want to leave it open a bit in case there is more to add. When I get a cleanly running library, I'll report that and close the question with an answer. – Gamma Draconis Dec 05 '10 at 20:16
  • 1
    I agree with @dennycrane at what would be better in the future, but far more important is the fact that you took the time to post this helpful guide on SO in whatever format you post it in. I have already found it helpful, and I haven't even had the chance to read it; simply knowing this is possible will greatly help me with designing my current project. Thank you for saving me, and many other people, the time of finding the answer the same way you did, without a question to prompt you. – Daniel H May 02 '12 at 09:59

4 Answers4

39

It turned out that this approach does not entirely work when compiling a debuggable library. The release library is compiled with -O2 which optimizes out some infelicities, but the debug library is done with -O0 which reveals some additional problems. Furthermore, I wasn't too happy about having to edit the boost files. So with some additional study, I've come up with the following solution.

First, don't edit any of the boost files. Instead add the following to the header within the std namespace:

struct bad_cast : public exception {bad_cast operator()(){}};

Next add the following to the source file:

namespace boost
{
    void throw_exception(std::exception const&) {}
}

This now compiles and links into the application even with android:debuggable="true" in AndroidManifest.xml. It doesn't run in the emulator, but then it wasn't doing that before I included this library either.

Gamma Draconis
  • 1,166
  • 1
  • 9
  • 11
  • 2
    Gave you as many upvotes as I could. Spent about 1 full day working on figuring this out, and finding this helped immensely. –  Sep 16 '11 at 12:22
  • 1
    And since you have in fact answered your own question as suggested above, you deserve another upvote. I wish more people (including, unfortunately, myself) thought of posting their hard-found solutions here without somebody else asking them to. – Daniel H May 02 '12 at 10:04
3

Notably, NDK r5 comes with STLport, and the GNU STL, and so the hacks here are no longer going to be necessary now that there is a) STL support b) exception support in the NDK C++ compiler.

grrussel
  • 7,209
  • 8
  • 51
  • 71
  • Your points a and b are true individually, but not in combination (see the WARNING in section III of CPLUSPLUS-SUPPORT.html in the nkd documentation.) Consequently, you'll still need the std::bad_alloc, std::bad_cast and boost::throw_exception hacks I discussed. – Gamma Draconis Dec 09 '10 at 05:03
  • It's odd. The documentation I quoted above does not refer to the GNU STL at all, except to say that "full GNU libstdc++ support" is a future plan. But there it is in the NDK under sources/cxx-stl along with their minimal system and stlport. Have you managed to get it to work? I note an ongoing discussion on the issue at http://groups.google.com/group/android-ndk/browse_thread/thread/da175a5d6b8b7956. – Gamma Draconis Dec 09 '10 at 06:26
  • It seems to be mentioned on the NDK page at http://developer.android.com/sdk/ndk/index.html and not in the docs. quote "Provides a default C++ STL implementation (based on STLport) as a helper module. It can be used either as a static or shared library (details and usage examples are in sources/android/stlport/README). Prebuilt binaries for STLport (static or shared) and GNU libstdc++ (static only)" Seems like libstdc++ works with exceptions and RTTI. – grrussel Dec 09 '10 at 14:13
  • I can compile with it, but the library link stage goes badly with lots of undefined reference errors. I tried an explicit LOCAL_LDLIBS += -lstdc++ but it didn't help. Have you gotten APP_STL := gnustl_static to work? – Gamma Draconis Dec 09 '10 at 16:45
  • Yes, it works for me (tm). I didn't need explicit additions to the ld arguments for the STL; for every other library I build and use, but not the STL itself. You can verify with a hello world using std::vector or the like. – grrussel Dec 09 '10 at 17:09
1

The current version of Android NDK (r9) now supports exceptions.

The capabilities of the various runtimes vary. See this table:

          C++       C++   Standard
          Exceptions  RTTI  Library
system    no           no        no
gabi++   yes          yes        no
stlport  yes          yes       yes
gnustl   yes          yes       yes

stlport can get used in non-GPL binarys. It's still flagged as experimantal, but you can use it with clang and gcc.

See http://developer.android.com/tools/sdk/ndk/

sweisgerber.dev
  • 1,726
  • 17
  • 36
1

Another workaround for shared_ptr in particular is to use boost::intrusive_ptr instead. This is not always possible, but worked for my situation.

Martin Stone
  • 12,682
  • 2
  • 39
  • 53
  • 1
    You can also use extract shared_ptr from shared_ptr_nmt.hpp pretty easily, it's a simplified version. – Chris Jan 31 '12 at 02:36