Difference between CMake and NDK-build in android studio project

To clear up some confusion here: ndk-build is a build system included in the NDK. It uses Android.mk files. The NDK itself is a collection of compilers and libraries that are needed to build C/C++ code for Android. ndk-build and cmake both use the NDK.

What is the actual difference between CMake and NDK build in android studio project.

They use a different language (custom makefiles vs cmake) to describe builds. Ideally there is no difference in output for identically described builds, but that doesn't mean there aren't any bugs.

Can anyone has a better explanation with an example when we need to use what?

In general, use whichever system you prefer.

CMake's main advantage is that you can use one set of build files for all your targets (Android, Linux, Windows, iOS, etc). If your project is cross platform, CMake should make that easiest on you. It also is widely known outside Android developers, so people new to Android will have a better chance of understanding it.

ndk-build should be preferred if you're building a project that already uses Android.mk files for its build system (legacy projects).

If you're writing new code, use whatever you're comfortable with. If you're not familiar with either, cmake is probably the better choice because it will make cross-platform work easier in the future if you choose to do so.


I have tried to give some explanation to identify the different between CMake and NDK-Build and setup:

Some initial notes:

  • Android Studio's default build tool for native libraries is CMake.
  • Android Studio also supports ndk-build due to the large number of existing projects that use the build toolkit to compile their native code.
  • If you are creating a new native library, you should use CMake.
  • Support for ndk-build is included due to the large number of legacy projects.

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. CMake require a build script to know how to build your native library. For new projects, Android Studio creates a CMake build script, CMakeLists.txt, and places it in your module’s root directory.

If your native sources don’t already have a CMake build script, you need to create one yourself and include the appropriate CMake commands. A CMake build script is a plain text file that you must name CMakeLists.txt.

# Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build.

cmake_minimum_required(VERSION 3.4.1)

# Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add.library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.

add_library( # Specifies the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/file_name.cpp )

NDK-Build:

Android Studio also supports ndk-build due to the large number of existing/legacy projects that use the build toolkit to compile their native code. You need to create one yourself and include the appropriate Android.mk file for ndk-build and then need to configure gradle file for ndk-build same as CMake.

Configure Gradle both for CMake and ndk-build:

To manually configure Gradle to link to your native library, you need to add the externalNativeBuild block to your module-level build.gradle file and configure it with either the cmake or ndkBuild block:

android {
    ...
    defaultConfig {
        ...
        // This block is different from the one you use to link Gradle
        // to your CMake or ndk-build script.
        externalNativeBuild {

            // For ndk-build, instead use the ndkBuild block.
            cmake/ndkBuild {

                // Passes optional arguments to CMake.
                arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"

                    // Sets optional flags for the C compiler.
                    cFlags "-fexceptions", "-frtti"

                    // Sets a flag to enable format macro constants for the C++ compiler.
                    cppFlags "-D__STDC_FORMAT_MACROS"
            }
        }
        ndk {
            // Specifies the ABI configurations of your native
            // libraries Gradle should build and package with your APK.
            abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a'
        }
    }

    buildTypes {...}

    // Encapsulates your external native build configurations.
    externalNativeBuild {

        // Encapsulates your CMake build configurations.
        cmake {

            // Provides a relative path to your CMake build script.
            path "src/main/cpp/CMakeLists.txt"
        }

        // Encapsulates your ndkBuild build configurations.
        ndkBuild {

            // Provides a relative path to your ndkBuild Android.mk file.
            path "src/main/cpp/Android.mk"
        }
    }
}

If you want to link Gradle to an existing ndk-build project, use the ndkBuild block instead of the cmake block, and provide a relative path to your Android.mk file.


Clear answer is here https://android-developers.blogspot.ru/2016/11/make-and-ndk-build-support-in-android.html. Sum up - choose in order:

  • use gradle experimental plugin for projects with limited C++

  • cmake for more stability is new projects

  • ndk-build is for legacy projects, try to migrate to cmake or new plugin