6

I am trying to add a strip debug symbols step for my Android library which includes native shared libraries for different ABIs, e.g. x86/native-lib.so, x86_64/native-lib.so, arm64-v8a/native-lib.so, etc.

I understand that the strip command must be respective to each ABI. So, I need to invoke the correct strip command, for which I need to know its correct path during build time.

For example, for ABI x86_64, I need to have below path setting:

set(STRIP ~/Library/Android/android-ndk-r16b/toolchains/x86_64-4.9/prebuilt/darwin-x86_64/bin/x86_64-linux-android-strip)

add_custom_command(TARGET ${SHARED_LIBRARY_NAME} POST_BUILD
                COMMAND ${STRIP}
                "${DIST_LIBS_DIR}/${LIB_BUILD_TYPE}/${ANDROID_ABI}/lib${SHARED_LIBRARY_NAME}.so"
                COMMENT "Strip debug symbols done on final binary.")

The path I need is illustrated like below: enter image description here

So, my questions are:

  • Is there an existing CMake variable to point at this path, i.e. /android-ndk-r16b/toolchains/???/prebuilt/???/bin/???-???-???-strip?

  • If not, is there a way to form this path utilising other known Android CMake variable, e.g. ANDROID_NDK, ANDROID_ABI, etc?

shizhen
  • 12,251
  • 9
  • 52
  • 88
  • Note that Android Studio (or, to be more exact, the Android Gradle plugin) will strip the shared objects for you. The trick is they perform the strip step later, not as part of CMake. – Alex Cohn Nov 21 '18 at 10:08
  • This is true for application projects, but for library projects with native shared .so, I want to ship a slimmed package rather than leave a heavy bundle to customers. – shizhen Nov 21 '18 at 10:17

2 Answers2

8

Thanks @Alex Cohn a lot for pointing out the file android.toolchain.cmake which usually exists at directory ~/Library/Android/sdk/cmake/cmake_version_xxx/android.toolchain.cmake on macOS.

There are many useful Android CMake variables already configured inside, e.g.

ANDROID_NDK
ANDROID_TOOLCHAIN
ANDROID_ABI
ANDROID_PLATFORM
ANDROID_STL
ANDROID_PIE
ANDROID_CPP_FEATURES
ANDROID_ALLOW_UNDEFINED_SYMBOLS
ANDROID_ARM_MODE
ANDROID_ARM_NEON
ANDROID_DISABLE_NO_EXECUTE
ANDROID_DISABLE_RELRO
ANDROID_DISABLE_FORMAT_STRING_CHECKS
ANDROID_CCACHE

And the one ANDROID_TOOLCHAIN_PREFIX is exactly what I looked for, so my final CMake script comes into below:

add_custom_command(TARGET ${SHARED_LIBRARY_NAME} POST_BUILD
            COMMAND "${ANDROID_TOOLCHAIN_PREFIX}strip" -g -S -d --strip-debug --verbose
            "${DIST_LIBS_DIR}/${LIB_BUILD_TYPE}/${ANDROID_ABI}/lib${SHARED_LIBRARY_NAME}.so"
            COMMENT "Strip debug symbols done on final binary.")

And I don't need to explicitly pass any additional arguments, i.e. DCMAKE_TOOLCHAIN_FILE=android.toolchain.cmake, from command line to the build process. Because, this file, i.e. android.toolchain.cmake, was already taken into account automatically by Android native build system.

shizhen
  • 12,251
  • 9
  • 52
  • 88
  • 1
    This [answer](https://stackoverflow.com/a/71236302/230825) provides a more generic way to achieve this but it may require a not too old version of CMake. I've validated it with CMake 3.16 on Ubuntu with Linux and Android. – david Mar 31 '22 at 17:15
5

You can use ${CMAKE_STRIP}. It is set appropriately when you use -DCMAKE_TOOLCHAIN_FILE=android.toolchain.cmake. I hope it is OK also if you work with 'built-in' Android support with supported NDK version.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • Thanks a lot for pointing at the file `android.toolchain.cmake`. It does be helpful with solving my real problem. – shizhen Nov 22 '18 at 01:39
  • See this [answer](https://stackoverflow.com/a/71236302/230825), it works like a charm with Linux, Android and I suppose any platform since it's fully generic – david Mar 31 '22 at 17:13