Android: Add user-specified CXX flags after platform defaults
Switching from Android's "legacy toolchain file" to its "new toolchain file" changed the way CMAKE_CXX_FLAGS worked. Previously, the legacy toolchain file provided a bunch of implicit compiler flags, and CMAKE_CXX_FLAGS was appended to those flags. With the new toolchain file, setting CMAKE_CXX_FLAGS instead replaces the implicit compiler flags.
I'm not sure if this behavior was intended. It seems like a compatibility problem for the NDK.
See https://github.com/android/ndk/issues/1693.
CMake can also use the NDK without the NDK's toolchain file, and the behavior there is similarly affected: setting CMAKE_CXX_FLAGS overrides a bunch of flags that are otherwise implicitly passed to the clang driver.
The set of flags varies a bit, but it's roughly these flags (ANDROID_COMPILER_FLAGS for the legacy file or _ANDROID_NDK_INIT_CFLAGS for the new toolchain file):
-DANDROID -fdata-sections -ffunction-sections -funwind-tables \
-fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 \
-march=armv7-a -mthumb -Wformat -Werror=format-security \
-fexceptions -frtti -stdlib=libc++
I'm not sure if setting CMAKE_CXX_FLAGS is supposed to disable so many flags, but maybe this is working-as-designed?
So far, most NDK users are probably still using the legacy toolchain file because the new toolchain file requires a newer CMake version. The Android Gradle Plugin (AGP) is about to upgrade its default CMake version to 3.22.1, which would start switching users to the new toolchain file, exposing this behavior change.
One internal user at Google was bit by the change, because they were passing -DCMAKE_CXX_FLAGS=-std=c++<nn>
. When they upgraded their CMake version, they lost the -fdata-sections -ffunction-sections
flags, which bloated their app's shared objects. I suspect more NDK users may be affected.