Tsvetan Bogoev
Tsvetan Bogoev

Reputation: 43

Using -Os/-Oz with Android NDK and cmake for release builds

Using: Andorid Studio 3.1.3, NDKr17b, gradle plugin 3.1.3, gradle-4.5.1-all.zip

I am not able to produce any release build of a shared library using cmake it fails with the following:

arm-linux-androideabi/bin/ld: fatal error: Optimization level must be between 0 and 3

Here is cmake release configuration I use

    release {
        externalNativeBuild {
            cmake {
                arguments "-DCMAKE_BUILD_TYPE=Release",
                        "-DANDROID_CPP_FEATURES=rtti exceptions",
                        "-DANDROID_STL=c++_static",
                        "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON"

                cppFlags "-ffunction-sections -fdata-sections -fvisibility=hidden -fvisibility-inlines-hidden -Os"
                cFlags   "-ffunction-sections -fdata-sections -fvisibility=hidden -fvisibility-inlines-hidden -Os"
            }
        }
        consumerProguardFiles 'proguard-project.txt'
    }

I found that ld is called with the following options:

-plugin /home/myhome/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/../lib64/LLVMgold.so -plugin-opt=mcpu=generic -plugin-opt=Os -plugin-opt=-function-sections -plugin-opt=-data-sections

And the problem is existence of "-plugin-opt=Os", when I run the command without this option it links, even that all source is compiled with the proper optimization level. Using the same configuration with ndk-build works fine (ld call has no such option, it just loads the LLVMgold.so plugin, with no --plugin-opt=Os).

So my question is why this option "-plugin-opt=Os" is applied and how can I remove it? Is this comes from cmake or its from ninja?

Upvotes: 2

Views: 1173

Answers (2)

Tsvetan Bogoev
Tsvetan Bogoev

Reputation: 43

Even this is a bug in Clang LTO plugin (https://reviews.llvm.org/D30920) - it can be avoided - note that ndk-build system is using the same toolchain, but this problem does not exist. The solution is to not pass Os option to Clang LTO plugin ("-plugin-opt=Os") and this can be done by removing -Os option from generic ANDROID_COMPILER_FLAGS_RELEASE, instead pass this option directly to your makefiles, this way it will not be added to Clang LTO plugin. But since ANDROID_COMPILER_FLAGS_RELEASE is not user variable, the only way to do this is to comment two lines (510, 512) in ndk-bundle/build/cmake/android.toolchain.cmake inside Android Sdk folder

Upvotes: 1

Dan Albert
Dan Albert

Reputation: 10509

I see you're also the filer of this bug, but for anyone else landing here, this is a bug in the Clang LTO plugin: https://github.com/android-ndk/ndk/issues/721.

Upvotes: 1

Related Questions