【问题标题】:Android NDK r9b and compiling C++11Android NDK r9b 和编译 C++11
【发布时间】:2013-11-16 17:36:35
【问题描述】:

我正在尝试使用 NDK r9b 编译一些 C++11 代码,但是无论我尝试什么它都不起作用。不使用 C++11 功能进行编译也可以正常工作。

这是我的 Application.mk:

NDK_TOOLCHAIN_VERSION := 4.8
APP_STL := gnustl_static

这是我的 Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

FILE_LIST := $(wildcard $(LOCAL_PATH)/*.cpp)

LOCAL_CPPFLAGS := -std=c++11 -pthread -frtti -fexceptions
LOCAL_MODULE    := RAGEAndroid
LOCAL_SRC_FILES := jni.c $(FILE_LIST:$(LOCAL_PATH)/%=%)
LOCAL_LDLIBS    := -llog -lm -landroid -lGLESv3

include $(BUILD_SHARED_LIBRARY)

我也尝试过设置以下内容,但没有运气:

LOCAL_CFLAGS := -D__GXX_EXPERIMENTAL_CXX0X__
LOCAL_CPPFLAGS := -std=gnu++11 -pthread -frtti -fexceptions

我已确保 Eclipse 在 C++ general->Paths and Symbols 中具有以下路径

(ndk path)/sources/cxx-stl/gnu-libstdc++/4.8/include
(ndk path)/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi/include

我有一个 C 文件 (jni.c) 和几个测试 cpp/hpp。在没有任何 C++11 功能的情况下,一切都可以正常编译,并且包括 之类的东西不会引起任何抱怨,但是在实际创建 std::thread 对象时,我得到“Type 'std::thread' could不能解决”。我尝试使用的其他功能(std::unique_ptr、std::shared_ptr、std::move() 等)也会发生这种情况。

我已经阅读了很多关于让 C++11 编译的主题,但似乎没有任何效果,我相信我错过了一些东西,但无法弄清楚它是什么。任何帮助将不胜感激!

编辑:如果我打印 __cplusplus,它会显示 201103L,所以看起来它使用的是正确的版本。

编辑 2:std::atomic 似乎工作正常。

【问题讨论】:

    标签: android c++11 android-ndk


    【解决方案1】:

    很抱歉,以下应该是评论,而不是回答 - 因为我不知道您的代码有什么问题,但您可以通过以下方式弄清楚自己:


    这是我的最小 Android.mk

    LOCAL_PATH      := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE    := hello-jni
    LOCAL_SRC_FILES := HelloJni.cpp
    LOCAL_LDLIBS    := -llog
    include $(BUILD_SHARED_LIBRARY)
    

    Application.mk

    APP_CPPFLAGS := -std=c++11
    NDK_TOOLCHAIN_VERSION=4.8
    APP_STL=gnustl_static
    

    这是最小的 HelloJni.cpp

    #include <jni.h>
    #include <thread>
    
    void doSomeWork( void )
    {
        __android_log_print(ANDROID_LOG_DEBUG, "HelloJni", "hello from thread...");
        return;
    }
    
    extern "C" 
    jstring 
    Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
    {
        std::thread t( doSomeWork );
        t.join();
        return env->NewStringUTF("Hello from JNI !");
    }
    

    它在我的 Mac 上的 r9b 中构建干净。要检查的一件事:运行ndk-build V=1 并确保链接步骤类似于

    ~/android-ndk-r9b/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-g++ -Wl,-soname,libhello-jni.so -shared --sysroot=~/android-ndk-r9b/platforms/android-17/arch-arm ./obj/local/armeabi/objs-debug/hello-jni/HelloJni.o ~/android-ndk-r9b/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi/libgnustl_static.a -lgcc -no-canonical-prefixes  -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now  -L~/android-ndk-r9b/platforms/android-17/arch-arm/usr/lib -llog -lc -lm -o ./obj/local/armeabi/libhello-jni.so
    

    并检查命令的输出

    ~/android-ndk-r9b/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86/bin/arm-linux-androideabi-nm -C ~/android-ndk-r9b/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi/libgnustl_static.a  | grep std::thread
    

    这是我得到的:

    00000000 T std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>)
    00000000 T std::thread::hardware_concurrency()
    00000000 T std::thread::join()
    00000000 T std::thread::detach()
    

    【讨论】:

    • 您好,感谢您的详细回复!链接阶段看起来一样,我在 Windows 上运行,所以没有 grep,但通过在 Notepad++ 中打开 libgnustl_static.a,我能够找到其他 std:: 对象的实例,但与 std::thread 没有任何关系。这使我相信该库是在关闭支持的情况下编译的?我根据您的示例构建了另一个最小项目,该项目也无法使用线程进行编译。这是它的链接,如果您不介意,您能看看它是否在您的设置中构建吗? dropbox.com/s/16bcbuokc1echo7/JNITest.rar
    • 我在 OSX 上下载了 SDK 和 NDK 并尝试编译,但最终遇到了同样的问题,所以这绝对是我正在做的事情。在 OSX 中,grep 命令给出了与您相同的输出。最后,我将 ndk-build V=1 结果放入此文件以防万一(这是来自 Windows):dropbox.com/s/who4cqkogoqph9b/ndk-build%20verbose.txt
    • 我在ndk-build V=1 result 中看不到问题。也许,我误解了你的抱怨?
    【解决方案2】:

    可能你需要反转这条线:

    LOCAL_MODULE    := RAGEAndroid
    

    用线:

    LOCAL_CPPFLAGS := -std=c++11 -pthread -frtti -fexceptions
    

    要说这些标志需要在当前模块(RageAndroid)上使用,而不是以前的模块。

    顺便说一句,在我的项目中,我需要用上面的行 (c++0xc++11) 指示 c++11(否则它在这里不起作用)。

    LOCAL_CPPFLAGS  := -std=c++0x
    

    【讨论】:

    • 这两种方法都试过了,都没有用。最后我不知道出了什么问题,所以我使用了 Jak 从here 制作的 ThreadingProblem 项目,然后把所有东西都去掉了。我做了一个差异,但仍然看不出有什么不同:/
    猜你喜欢
    • 2013-12-10
    • 1970-01-01
    • 2013-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    相关资源
    最近更新 更多