Difference between CMake and NDK-build in android studio project
Asked Answered
C

4

71

What is the actual difference between CMake and NDK build in android studio project. I already went through google documentation but the concept is not clear yet. As per google documentation:

The Android Native Development Kit (NDK): a toolset that allows you to use C and C++ code with Android, and provides platform libraries that allow you to manage native activities and access the physical device components, such as sensors and touch input.

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.

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

Chaplet answered 20/9, 2016 at 8:41 Comment(4)
You can use CMake together with the NDK, not as a replacement for the NDK.Alexandrina
CMake is a new way, using NDK, to build your native code into shared lib and used by your app's java code ( or pure android native code project ); it is the build tool that uses other tools bundled in your NDK package. NDK and CMake are in different domain, it is not fair to compare them I think; inside your downloaded NDK package, there is another tool to uses NDK to build native source code, called ndk-build: ndk-build tool and cmake are comparable: they solve the same problem.Swinish
I can see the future: ndk-build will be deprecated and CMake shall rule (untl they decide to break things again and move to something even shinier). :-)Giorgione
cmake is clearly the superior choice here. cmake is a complete programming language it has for-loops, if-else, functions, variables, list, etc all waiting to be used for your most demanding dependency-related compilation needs.Phyllode
I
81

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.

Ichthyosis answered 20/9, 2016 at 18:19 Comment(8)
I think that if your new to both the NDK and cmake toolchains, the NDK might be a good choice if your project is complex. I found that the docs, guides and overall knowledge about the cmake toolchain when used with Android is little to none. Things like Crashlytics etc. only have guides for the old NDK tools etc. I went for the cmake toolchain for a complex product, getting it to build well with Gradle has been cumbersome.Premeditate
That's a good point. In contrast, most of the new samples we create are in CMake only.Ichthyosis
I am using new AS 2.3.3 and found that with CMAKE my native libs are not building correctly.How can I force AS to use NDK Build system and not cmake?I cant even find Android.mk in new JNI sample project improted from 2.3.3 ASMicrometeorite
Follow developer.android.com/studio/projects/…Ichthyosis
I'd like to point out that almost all the documentation still assumes you're using an Android.mk with no equivalents for CMake. This is really frustrating when CMake is pushed as the default and then you find out you have no support for it.Jerold
(I've been fixing the NDK side of the documentation recently, so that's getting much better now. Sorry it took so long to get there.)Ichthyosis
ndk-build and cmake uses the NDK? Isn't it the other way around?Phyllode
No. Build systems use toolchains.Ichthyosis
C
26

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.

Chaplet answered 27/4, 2017 at 9:14 Comment(4)
THis is pretty much the official doc verbatum. No extra info provided and OP's question was not answered.Falcate
Can we use both cmake and ndkBuild blocks in externalNativeBuild?Dorindadorine
Can i use both cmake and ndkbuild block for two modules with different build systems?Pronunciamento
@DeclanNnadozie yes you can use different native build systems in different modules of the same project. The catch is that you cannot easily connect the native parts of different modules together, even if both use same build system. The new Prefab tool (available since AS 4.0) answers this need partially.Lindquist
P
1

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

Parnas answered 13/11, 2016 at 8:2 Comment(2)
"ndk-build is for legacy projects, try to migrate to cmake or new plugin". That is not stated anywhere in that blog post. If you're successfully using ndk-build, there is no reason to switch.Ichthyosis
Also, the order you've given those options is not how I read it. The way I read it, cmake is the preferred option over gradle experimental.Ichthyosis
I
0

Android.mk is a file that contains NDK-build, if you use Cmake build you app you don’t need Android.mk instead its CmakeList.txt

Ianthe answered 7/11, 2017 at 6:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.