Closed fh127 closed 8 years ago
For ERANGE see the PR. However, the std::strtof in the latest NDK STL looks fine to me and seems to be correctly used in this project. So I would say that there is a problem in your project setup (outdated NDK, weird defines, wrong STL?) and you rather find a solution in an Android developer forum :).
Also try to only run the preprocessor on the problematic source code and check if the included headers are actually defining strtof and are using
them in the std
namespace (e.g. by running GCC -E ...
).
I merged PR #222. @fh127, is your issue solved by this?
I came across the same problem (in my project, changing or tweaking NDK settings was not an option because of other dependancies) and ended up fixing using a workaround. I hope there would be a cleaner solution though.. What I did:
For GCC 4.9 (for example ndk r10d):
Add to_string in the beginning of json.hpp
#include <vector>
#ifdef JSON_ANDROID_WORKAROUNDS
namespace std
{
template < typename T > std::string to_string(const T& n)
{
std::ostringstream stm;
stm << n;
return stm.str();
}
}
#endif
// disable float-equal warnings on GCC/clang
Use strtod in two places (warning! this will of course lose precision and maybe other errors):
long double str_to_float_t(long double* /* type */, char** endptr) const
{
#ifdef JSON_ANDROID_WORKAROUNDS
return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
#else
return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
#endif
}
float str_to_float_t(float* /* type */, char** endptr) const
{
#ifdef JSON_ANDROID_WORKAROUNDS
return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
#else
return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
#endif
}
For GCC 4.8 this was also needed (ndk r9c):
#ifdef JSON_ANDROID_WORKAROUNDS
basic_json() {};
#else
basic_json() = default;
#endif
Hi, @nlohmann , I tested the commit PR #222, when I am compiling in Android NDK, this error was solved: error: 'ERANGE' was not declared in this scope''' But I have more errores: error: 'strtof' is not a member of 'std' error: 'strtoll' is not a member of 'std'
I am using the Android NDK configuration, and doesn't support those function c. Application.MK:
APP_STL := gnustl_static
APP_CPPFLAGS := -std=c++11 -frtti -fexceptions
APP_ABI := armeabi armeabi-v7a x86 arm64-v8a
NDK_TOOLCHAIN_VERSION := 4.9
this commit of the repository #c0bb5a5 work fine for my Android project
I use CrystaX NDK and it compiles all fine for android.
@fh127 @Dimon4eg As the code works in your cases, could you please give me a detailed version number of your NDK/GCC so that I can mention it in the README file?
@vjjjv I don't want to add these adjustments to my code, because GCC 4.8 is not supported anyway.
Instead of Google NDK I use CrystaX NDK (latest 10.3.1 from https://www.crystax.net).
How about the GCC 4.9, I posted two workarounds for that too?
Its just a bit uncomfortable that a great lib is not compatible with some common dev envs because of such a small changes.. Or am I missing some bigger issues here? Is it so that it's not recommended to use the lib with changes that I made? (I am not super familiar with c++11 "specialities")
@vjjjv Can you not use the c++-shared standard library to get the missing to_string function?
I am not sure, because I experience this problem using Unity and Qt frameworks for example - there the NDK settings come predefined and its not very clear if I can change them easily.
Can someone please provide an example project so I can try to execute the build myself? (I have no experience with Android NDK - I just want to install it in an Ubuntu VM and try it myself.)
Ok, I tried the following: I got Android NDK, Revision 11c and compiled the unit tests with the following files in a subdirectory Android
:
Android.mk
:
LOCAL_PATH := .
include $(CLEAR_VARS)
LOCAL_MODULE := jsonunit.out
LOCAL_SRC_FILES := ../test/unit.cpp
LOCAL_C_INCLUDES += ../src ../test
LOCAL_CPP_FEATURES += exceptions rtti
LOCAL_CPPFLAGS += -fexceptions -frtti -std=c++11
include $(BUILD_EXECUTABLE)
Application.mk
:
APP_ABI := x86
APP_PLATFORM := android-21
APP_STL := c++_shared
APP_BUILD_SCRIPT := Android.mk
Executing ndk-build NDK_APPLICATION_MK=./Application.mk
takes a long time, but completes without error.
I have no experience with Android NDK. Can someone please tell me:
I really want to experience the reported problems on my machine to assess whether it makes sense to adjust the code. This may also be applicable to #136.
I had another try with the configuration above and only adjusted the NDK_TOOLCHAIN_VERSION
parameter:
NDK_TOOLCHAIN_VERSION
given: GCC 4.9 20150123 (prerelease) is used; compilesNDK_TOOLCHAIN_VERSION := clang
: Clang 3.8.243773 is used; compilesNDK_TOOLCHAIN_VERSION
given: GCC 4.8 is used; does not compileNDK_TOOLCHAIN_VERSION := 4.9
: GCC 4.9 20140827 (prerelease) is used; compilesNDK_TOOLCHAIN_VERSION := clang
: clang version 3.6 is used; compilesNDK_TOOLCHAIN_VERSION
given: GCC 4.6 20120106 (prerelease) is used; does not compileNDK_TOOLCHAIN_VERSION := clang
: Clang 3.4 is used; compilesI forgot to mention: So far, I was not able to reproduce the 'to_string' is not a member of 'std'
error.
I checked another NDK:
NDK_TOOLCHAIN_VERSION
given: GCC 5.3 20151204 is used; compilesNDK_TOOLCHAIN_VERSION := clang
: Clang 3.7 is used; compilesThank you for investigating this! Can you try with this Application.mk:
APP_ABI := x86 APP_PLATFORM := android-21 APP_STL := gnustl_static APP_BUILD_SCRIPT := Android.mk
For me, this is how the issue re-produces. With "APP_STL := c++_shared" there is no issues, but as I mentioned before, in our project we cannot change the STL version.
Ok, I'll check this weekend. Which NDK version and compiler shall I try?
For us, r10d GCC 4.9 is relevant
I can reproduce the error.
Combinations that do not work:
APP_STL := gnustl_static
(using NDK_TOOLCHAIN_VERSION := clang
)APP_STL := gnustl_static
(using NDK_TOOLCHAIN_VERSION := clang
)Combinations that do work:
APP_STL := c++_static
(using NDK_TOOLCHAIN_VERSION := clang
)APP_STL := c++_static
(using NDK_TOOLCHAIN_VERSION := clang
)APP_STL := gnustl_static
(using NDK_TOOLCHAIN_VERSION := clang
)APP_STL := c++_static
(using NDK_TOOLCHAIN_VERSION := clang
)A longer explanation can be found here.
Is changing to one of the working combinations an option for you @vjjjv?
(I removed the bug label, because the error is out of scope of the library, but is a known issue for the combination of used options in Android NDK)
Interesting results on this one after all. We are using this json-lib in component that has to work with Unity and Qt frameworks - so it might be quite challenging to change the NDK options. But I could think Unity and Qt are also moving towards these better working setups in the long run.
For now we are quite happy with the workarounds I have posted here earlier. It seems that this should not be fixed in the json lib now when we know where the problem originates from.
I added a note to the README file and linked this discussion.
Does anyone have this working for the most recent NDK while using gradle? I use
ndk {
stl "c++_static"
}
externalNativeBuild {
cmake {
cppFlags "-fexceptions -frtti -std=c++11"
}
}
and I still get the 'to_string' is not a member of 'std'
I could compile the code, see https://github.com/nlohmann/json/issues/451#issuecomment-281374011.
I have no idea why but I needed this instead (this took me a few hours to figure out so hopefully it helps someone on Android using Gradle...):
externalNativeBuild {
cmake {
cppFlags "-fexceptions -frtti -std=c++11"
arguments "-DANDROID_STL=c++_shared"
}
}
@haydenkaizeta Thanks for sharing. Could you please give the exact version numbers so I can add a hint to the README?
android-ndk-r13b, buildToolsVersion "24.0.3", ANDROID_STL=c++_shared, built with clang
For me compiles ok with CrystaX NDK (but I'm not using this lib as separate cmake module, just include as header)
When using gnustl, add -D_GLIBCXX_USE_C99=1 -D_GLIBCXX_HAVE_WCSTOF=1
would fix it.
Tested with NDK r16b clang
More detail:
to_string
is not available in gnu-libstdc++ "out of the box". I searched the sources and found that std::to_string is indeed in the lib (${NDK_HOME}/sources/cxx-stl/gnu-libstdc++/4.9/include/bits/basic_string.h) but opted out by
#if ((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
&& !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
see: https://stackoverflow.com/a/34352742/2395134
for armeabi-v7a , need -D_GLIBCXX_HAVE_WCSTOF=1
for std::wcstof
hi, can you help me, this error occurs when it compile with Android NDK