Reputation: 129
I've run into a very serious (IMO) problem. I am using the native cross platform tools in visual studio 2015.
Since several implementations of the standard library were downloaded by visual studio
C:\ProgramData\Microsoft\AndroidNDK\android-ndk-r10e\sources\cxx-stl\
I was surprised when I started finding stl classes that were not compiling.
I wrote off std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>
not being available as a quirk of gnu-libstdc++.
I tried to set the stl to others to see if they were better. This was done in the visual studio project properties window.
No combination of toolset or STL made std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>
available.
I moved on, saying "If I have to implement that one function myself it's not the end of the world."
However shortly afterward I tried to use to_wstring
. Again the function was not recognized even though wstring
was.
This was a step too far so I checked to see if gnu-libstdc++ had in fact implemented anything at all. In fact they had, see 21.5 of the standard is Y.
I was very confused now. I did some googling and found nothing more substantial than "set it to c++ 11."
Unless Visual Studio isn't doing anything with the following setting I assume GCC is being called correctly.
Eventually I opened up basic_string.h in visual studio to make sure that the function was actually there.
It was, line 3000:
inline wstring
to_wstring(int __val)
{ return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(int), L"%d", __val); }
Then I saw by the shading that it was being omitted by the preprocessor. Behold line 2847:
#if ((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
&& !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
The problem was not __cplusplus nor _GLIBCXX_HAVE_BROKEN_VSWPRINTF. _GLIBCXX_USE_C99 was not defined.
Searching for this problem yielded a couple of stack overflow questions.
Most of the comments seemed to think the problem would be fixed with a new release of GCC. For instance GCC 4.4.5. However since visual studio downloaded 4.9... I don't think this is merely a problem with versions.
I followed the link there to a three year old bug report which contained the statement:
It's not possible to fix in GCC without extraordinary effort for a single target, which is not going to happen. If a given target wants to support C++11 features then it needs to provide the necessary C99 features. This is not a GCC issue.
Well, in visual studio I had set the C standard to C99, for the record C11 didn't make any difference.
I am really not sure how to proceed from here. It seems to me that somehow Visual Studio is not communicating to GCC what is or is not available. That is just a theory though.
I am opposed to trying to manually change a distribution on the stl. That defeats the purpose of a stl. At the same time this project I am undertaking may well be impossible without the standard library (given the time constraints). I am afraid to continue lest I find more critical functionality hidden due to lack of C library functions.
I have this insane hope that there is something I could change in visual studio, some setting or command line override that would fix this.
P.S. I have looked into developing the android part in eclipse or android studio. The NDK documentation mentions eclipse often, but the android SDK has scary messages about the ADT no longer being supported. On top of that I had issues out of the box debugging the native code (but those are beyond the scope). The android studio build system (gradle) doesn't seem friendly to custom folder structures in the least. All of our source is in TFS and I can't change that at this point.
Upvotes: 1
Views: 1715
Reputation: 1259
This is known problem of Google's Android NDK - C++ Standard Library is broken there, unless you're using just small subset of C++ functionality. Macro _GLIBCXX_USE_C99
is defined (or not defined) in $NDK/sources/cxx-stl/gnu-libstdc++/4.9/libs/$ABI/include/bits/c++config.h
at the moment when GNU libstdc++ is building (i.e. on Google's side, when they build NDK). Unfortunately, it's built on top of very limited libc (Google's Bionic), so GNU libstdc++ configuration scripts detect it and disable some parts (in particular, std::to_wstring
), depending on that absent functionality in libc.
This is one of the main reason why I've started CrystaX NDK - alternative native development kit for Android. In CrystaX NDK, we pay special attention to completeness of libc, libstdc++, and conformance to standards in general. CrystaX NDK works as a drop-in replacement for Google's Android NDK, so most likely it will just work with Visual Studio too.
Upvotes: 5