Domanda

After C++11, various cmath functions previously in the global namespace are moved to the std namespace, when including the <cmath> header.

However the android NDK build has issues with this, with both gcc-4.8 and clang-3.4 toolchains.

The C++11 flag is correctly specified, as other c++11 particulars like unique_ptr work fine.

If i attempt to use std::round, or std::cbrt, the compiler says these don't exist in std:: namespace, which they should [1]. They exist in the global namespace, but I don't want to use those.

Is this a known issue? Have I overlooked something? Are there workarounds?

[1] http://en.cppreference.com/w/cpp/header/cmath


  • The desktop build does not have this problem using gcc-4.8.1, and I use gcc warnings to its fullest with -Wall -Wextra -Wcast-align -Wcast-qual -fpermissive -Wconversion -Wdisabled-optimization -Weffc++ -Wfloat-equal -Wformat=2 -Wimport -Winit-self -Winline -Winvalid-pch -Wlong-long -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wshadow -Wstack-protector -Wstrict-aliasing=2 -Wunreachable-code -Wunsafe-loop-optimizations -Wunused -Wvariadic-macros -Wwrite-strings -pedantic -pedantic-errors -Woverloaded-virtual -Wswitch-enum -Werror

  • Relevant build command, in all its glory: /opt/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++ -MMD -MP -MF ./obj/local/armeabi/objs/main/__/android/jni/src/main.o.d -fpic -ffunction-sections -funwind-tables -fstack-protector -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -fno-rtti -mthumb -Os -g -DNDEBUG -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Ijni/src/../android/jni/SDL/include -Ijni/src/../android/jni/SDL_image -Ijni/src/../android/jni/SDL_mixer -I/opt/bullet/bullet-2.82/include/bullet -I/opt/glm/glm-0.9.5.2 -I/opt/android-ndk-r9d/sources/android/cpufeatures -Ijni/SDL/include -Ijni/SDL_image -Ijni/SDL_image/external/jpeg-9 -Ijni/SDL_image/external/libpng-1.6.2 -Ijni/SDL_mixer -Ijni/SDL_mixer/external/libmodplug-0.8.8.4/src -Ijni/SDL_mixer/external/libmodplug-0.8.8.4/src/libmodplug -Ijni/SDL_mixer/external/smpeg2-2.0.0 -Ijni/SDL_mixer/external/libogg-1.3.1/include -Ijni/SDL_mixer/external/libvorbisidec-1.2.1 -I/opt/android-ndk-r9d/sources/cxx-stl/gnu-libstdc++/4.8/include -I/opt/android-ndk-r9d/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi/include -I/opt/android-ndk-r9d/sources/cxx-stl/gnu-libstdc++/4.8/include/backward -Ijni/src -DANDROID -fno-strict-aliasing -D_REENTRANT -DGLM_FORCE_RADIANS -isystem /opt/glm/glm-0.9.5.2 -Wa,--noexecstack -Wformat -Werror=format-security -std=c++11 -fexceptions -frtti -I/opt/android-ndk-r9d/platforms/android-19/arch-arm/usr/include -c jni/src/../android/jni/src/main.cpp -o ./obj/local/armeabi/objs/main/__/android/jni/src/main.o

È stato utile?

Soluzione

This seems to be a known issue with C++11 support on android. There is a known issue that indicates that a lot of the routines are missing:

When compiling c++ code with -std=c++11 and using gnustl_shared, many C99 math functions are not provided by the <cmath> header as they should.

You're probably better off assuming that only a limited subset of the c++ library is available for android - this seems to be indicated in the CPLUSPLUS-SUPPORT.html file in the docs/ for the ndk.

Mind you when I have:

APP_STL := c++_static

in my Application.mk and

LOCAL_CPPFLAGS  := -std=c++11

in my Android.mk, then files making use of std::cbrt and std::round compile cleanly; but it is against the static LLVM libc++, rather than against the gnu standard library.

Altri suggerimenti

If functions are really missing, you have to write them yourself (or copy them from some other implementation).

In the Android NDK, some functions seem to be there, but just outside of namespace std. I have worked around the same issue for the round function by adding a function round to namespace std, which just falls back on the round function from the global scope.

namespace std
{
    inline int round(float x)
    {
        return ::round(x);
    }
}

If you want to use this in a portable way, you would have to protect this with preprocessor macros.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top