I have a simple file stlTest2.cpp
like this:
#include <jni.h>
#include <cmath>
bool isnan (void);
There is something more complicated in some code I am porting. My question is this. Why would this work when building using GCC outside of the NDK, but not with using the NDK? There error it gives is this:
jni/stlTest2.cpp:6: error: expected unqualified-id before 'sizeof'
jni/stlTest2.cpp:6: error: expected ')' before 'sizeof'
The immediate reason for this is that math.h
(included via <cmath>
) defines isnan
as a macro. Why is the build outside of the ndk not including the #define
from math.h
, but this is? If I comment out the includes in the code, all is fine, but that is not acceptable as this problem repeats itself.... a lot.
The Android Native Development Kit (NDK): a set of tools that allows you to use C and C++ code with Android. CMake: an external build tool that works alongside Gradle to build your native library. You do not need this component if you only plan to use ndk-build.
To have the ndk-build script build an application, first create a project folder. In the folder, create a folder named jni. In the jni folder, place the Android.mk file, Application.mk file, and source files. Then navigate to the project folder in a terminal and execute ndk-build.
The CMake toolchain file The toolchain file used for the NDK is located in the NDK at <NDK>/build/cmake/android.
The isnan
macro was added in C99. In C++11 it was added as a function in the std
namespace, overloaded for float
and double
and long double
(so a typical <cmath>
header, such as your non-NDK GCC is probably using, might have something like this:
#undef isnan
inline bool isnan(float ...) { ... }
inline bool isnan(double ...) { ... }
inline bool isnan(long double ...) { ... }
), but apparently the NDK hasn't gotten the memo, and is still providing the C99 macro as a convenience. (isnan
was never a macro in C++, but before TR1 added std::tr1::isnan
, there wasn't really a C++ alternative, so multiple C++ compilers provided the C99 macro.)
Do you need to be able to use the compiler-provided isnan
or std::isnan
? If not, then you can just change this:
#include <cmath>
to this:
#include <cmath>
#undef isnan
(and similarly for any other problematic macros, provided you don't need them).
In $ndk\sources\cxx-stl\gnu-libstdc++\libs\armeabi\include\bits\c++config.h (change armeabi to whatever is appropriate) change this:
/* #undef _GLIBCXX_USE_C99_MATH */
to
#define _GLIBCXX_USE_C99_MATH 1
Then clean and build your project again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With