I'd like to use decomposition declarations in my Android NDK project. Therefore clang
needs to be called with -std=c++17
. Currently my code compiles without errors, but Clang prints the following warning:
warning: decomposition declarations are a C++17 extension [-Wc++17-extensions]
In the build log I spotted that -std=...
is appended to the build flags four times:
[...]/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 [...]
I know where the second and the third flag comes from (see below). I tried to change them to -std=c++17
and -std=c++1z
but with no success.
I guess that later flags override earlier ones. So I don't really care about the first one. But I can't figure out where the last one (-std=gnu++11
) comes from and how I could deactivate or modify it. Also I guess the fact that it's gnu++11
instead of c++11
activates some GNU extension that leads to the situation that I'm only getting warnings and no errors.
But I can't tell for sure. Nevertheless I want "real" C++17 support and not just some GNU extensions. Also I want to get rid of the warnings.
gradle.build
The switch cppFlags
in here is the origin of the second flag from the above excerpt from the build log. I know that some of the versions here are outdated. But I got that from the NDK sample repository and I'm new to Android programming. I'm still figuring out how things work. And so I don't care about that part yet.
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
Origin of the third flag. cmrc_add_resource_library
from assets/CMakeRC.cmake
compiles resources. I searched the code and there is nothing related to std=*
or CMAKE_*_FLAGS
. If you don't believe me have a look at the source yourself.
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)
None of the other files in my project contains code that remotely has to do with build flags. So I guess that's all.
Where could that last -std=
flag originate from? If the above problem description is not enough to deduce a solution, what further steps could I take in finding out the origin? And maybe I got it all wrong and clang++
already compiles with C++17. But why am I getting these warnings then? And how do I get rid of them?
I searched my local Android SDK folder for std=gnu++11
and tried changing all occurrences consecutively to find out which one is the one used in my build process. It turns out that in cmake/3.6.4111459/share/cmake-3.6/Modules/Compiler/Clang-CXX.cmake
the variable CMAKE_CXX11_EXTENSION_COMPILE_OPTION
is responsible to the aforementioned compiler flag. My current workaround is setting it to the desired standard in my CMakeLists.txt
:
set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=c++17")
This works. I got rid of all the warnings. However it seems a bit hacky and I still don't have a clue what actually appends this variable to the build command. So I'm not posting this as an answer as I'm still searching for an actual solution. But if anyone has the same problem and is just searching for a quick fix, well, here you go!
Code written in C/C++ can be compiled to ARM, or x86 native code (or their 64-bit variants) using the Android Native Development Kit (NDK). The NDK uses the Clang compiler to compile C/C++.
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.
The Android NDK is a toolset that lets you implement parts of your app in native code, using languages such as C and C++. For certain types of apps, this can help you reuse code libraries written in those languages.
libc++ LLVM's libc++ is the C++ standard library that has been used by the Android OS since Lollipop, and as of NDK r18 is the only STL available in the NDK.
The NDK's toolchain file obeys -std
settings as it should. Both flags will appear, but they do so in the order that has the user's setting override the toolchains.
It sounds like you have something like target_compile_features(foobar PRIVATE cxx_range_for)
or set_property(TARGET foobar PROPERTY CXX_STANDARD 11)
somewhere in your build.
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