代码之家  ›  专栏  ›  技术社区  ›  Scindix

Android NDK CGuSE使用C++ 17

  •  5
  • Scindix  · 技术社区  · 6 年前

    问题

    我想在我的android ndk项目中使用分解声明。因此 clang 需要呼叫 -std=c++17 。当前我的代码编译没有错误,但clang会打印以下警告:

    warning: decomposition declarations are a C++17 extension [-Wc++17-extensions]
    

    我知道的和我想要的

    在构建日志中我发现了 -std=... 附加到生成标志四次:

    [...]/bin/clang++ [...] -Wformat -Werror=format-security -std=c++11 -std=c++1z\
        -fexceptions -std=c++1z -Wall -O0 -fno-limit-debug-info  -fPIC\
        -std=gnu++11 -MD -MT [...]
    

    我知道第二面和第三面旗子是从哪里来的(见下文)。我试着把它们改成 - STD=C++ 17 -std=c++1z 但是没有成功。

    我想以后的标志会覆盖以前的标志。所以我真的不在乎第一个。但我不知道最后一个在哪( -std=gnu++11 )来自以及我如何停用或修改它。我猜事实上 gnu++11 而不是 c++11 激活一些GNU扩展,导致出现以下情况:我只收到警告,没有错误。

    但我不能确定。不过,我想要“真正的”C++ 17的支持,而不仅仅是一些GNU扩展。我还想消除这些警告。

    建筑过程中涉及的文件

    我的 gradle.build

    开关 cppFlags 这里是上面构建日志中摘录的第二个标志的来源。我知道这里有些版本已经过时了。但我是从ndk示例存储库中得到的,我对Android编程还很陌生。我还在搞清楚事情是如何运作的。所以我还不在乎那部分。

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion = 25
    
        defaultConfig {
            applicationId = 'com.example.stackoverflow'
            minSdkVersion 14
            targetSdkVersion  25
            externalNativeBuild {
                cmake {
                    arguments '-DANDROID_STL=c++_static'
                    cppFlags "-std=c++1z -fexceptions"
                }
            }
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'),
                    'proguard-rules.pro'
            }
        }
        externalNativeBuild {
            cmake {
                path 'src/main/CMakeLists.txt'
            }
        }
    }
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation 'com.android.support:appcompat-v7:25.4.0'
        implementation 'com.android.support.constraint:constraint-layout:1.0.1'
    }
    

    我的 CMakeLists.txt

    第三个标志的来源。 cmrc_add_resource_library assets/CMakeRC.cmake 编译资源。我搜索了代码,没有任何相关信息 std=* CMAKE_*_FLAGS 。如果你不相信我,看看 source 你自己。

    cmake_minimum_required(VERSION 3.4.1)
    include(assets/CMakeRC.cmake)
    
    # Build native_app_glue as a static library
    set(${CMAKE_C_FLAGS}, "${CMAKE_C_FLAGS}")
    add_library(native_app_glue STATIC
        ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
    
    # Now build app's shared library
    cmrc_add_resource_library(shaderFiles assets/shader/standard.fs assets/shader/standard.vs)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1z -Wall")
    
    # Export ANativeActivity_onCreate(),
    set(CMAKE_SHARED_LINKER_FLAGS
        "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
    
    add_library(myappname SHARED
                cpp/main.cpp
                #cpp files...
    
    target_include_directories(myappname PRIVATE
        ${ANDROID_NDK}/sources/android/native_app_glue)
    
    # Add library dependencies
    target_link_libraries(myappname
        shaderFiles
        android
        native_app_glue
        EGL
        GLESv2
        log)
    

    我的项目中没有其他文件包含与生成标志远程相关的代码。所以我想就这些了。

    主要问题

    那能持续多久呢 -std= 标志来源于?如果上述问题描述不足以推断出解决方案,我可以采取哪些进一步的步骤来找出来源?也许我搞错了 clang++ 已经用C++ 17编译了。但是为什么我会收到这些警告呢?我该如何摆脱它们?

    更新

    我在本地的android sdk文件夹中搜索 std=gnu++11 并尝试连续地更改所有事件,以找出在构建过程中使用的事件。结果是在 cmake/3.6.4111459/share/cmake-3.6/Modules/Compiler/Clang-CXX.cmake 变量 CMAKE_CXX11_EXTENSION_COMPILE_OPTION 负责上述编译器标志。我目前的解决方法是在我的 cmakelists.txt文件 :

    set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=c++17")
    

    这是可行的。我消除了所有的警告。然而,它看起来有点老土,我仍然不知道到底是什么将这个变量附加到build命令中。所以我不会把这个作为答案发布,因为我还在寻找一个实际的解决方案。但是如果有人有同样的问题,只是在寻找一个快速的解决方法,那么,给你!

    1 回复  |  直到 6 年前
        1
  •  2
  •   Peter Mortensen icecrime    6 年前

    ndk的工具链文件遵循 -std 设置。这两个标志都将出现,但它们的出现顺序是让用户的设置覆盖工具链。

    听起来你有点像 target_compile_features(foobar PRIVATE cxx_range_for) set_property(TARGET foobar PROPERTY CXX_STANDARD 11) 在你的建筑中。