【问题标题】:Android NDK CMake uses C++17Android NDK CMake 使用 C++17
【发布时间】:2018-11-04 15:01:12
【问题描述】:

问题

我想在我的 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 from 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")

这行得通。我摆脱了所有的警告。然而,它似乎有点老套,我仍然不知道究竟是什么将此变量附加到构建命令中。因此,我不会将此作为答案发布,因为我仍在寻找实际的解决方案。但是,如果有人遇到同样的问题并且只是在寻找快速解决方案,那么,你去吧!

【问题讨论】:

  • 您是否尝试检查${CMAKE_CXX_FLAGS}?现在你正在附加set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1z -Wall")。尝试在之前和之后扩展标志以查看它是如何添加的。 stackoverflow.com/questions/9298278/…
  • @JamesPoag 对不起,我刚刚看到你的评论。我检查了 CMAKE_CXX_FLAGS ,它包含构建日志中的前两个标志。我还尝试使用string(REPLACE ...) 将它们替换为std=c++17。尽管我成功更改了第一个构建标志,但最后一个仍然保持原样。不幸的是,最后一个标志决定了所使用的标准。但是它似乎是在我的CMakeLists.txt 被执行后附加的。

标签: android cmake android-ndk c++17 clang++


【解决方案1】:

NDK 的工具链文件应遵循-std 设置。这两个标志都会出现,但它们会按照用户设置覆盖工具链的顺序出现。

听起来您的构建中某处有类似 target_compile_features(foobar PRIVATE cxx_range_for)set_property(TARGET foobar PROPERTY CXX_STANDARD 11) 的东西。

【讨论】:

    【解决方案2】:

    将参数传递给 cmake 应该作为一个列表来完成,而不是作为一个简单的字符串。我在我的一个项目中使用它来构建本机库:

        cmake {
              // Passes optional arguments to CMake. Make sure it is a list, not just a string :-) .
              arguments "-DANDROID_NATIVE_API_LEVEL=21", "-DANDROID_STL=c++_shared", "-DANDROID=true"
              cppFlags "-fexceptions", "-frtti"
              ...
        }
    

    您的构建脚本使用简单的字符串,而不是列表。

    【讨论】:

      猜你喜欢
      • 2017-09-16
      • 2013-04-17
      • 1970-01-01
      • 2021-07-09
      • 2013-10-13
      • 1970-01-01
      • 1970-01-01
      • 2020-12-15
      • 2018-01-23
      相关资源
      最近更新 更多