Android编译应用的 C 和 C++ 代码主要可以使用NDK-Build和CMake两种方式来进行,NDK-Build是基于Make构建系统来构建项目的,个人比较倾向于使用CMake的方式来构建,下面主要从CMake的方式进行说明

CMake可以和Gradle配合使用,也可以单独使用命令行的方式进行构建,我们这边主要研究Gradle是如何给我们设置这些版本信息的

NDK版本

NDK版本默认是根据你配置的Android Gradle插件版本(AGP)来选择的,

buildscript {
    ext.kotlin_version = "1.5.0"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.2.1"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

比如这个边配置的是4.2.1

classpath “com.android.tools.build:gradle:4.2.1”

下表说明了各个版本使用的NDK默认版本情况

Android Studio/Gradle 插件版本

为 AGP 版本指定的默认 NDK 版本

4.2

21.4.7075529

4.1

21.1.6352462

4.0

21.0.6113669

3.6

20.0.5594570

3.5以前

未指定默认版本,会选择最新下载的NDK版本

如果你需要修改默认的NDK版本,可以在模块的 build.gradle 文件中使用 android.ndkVersion 属性指定相应的版本,如下所示

android {
    ndkVersion "major.minor.build" // e.g.,  ndkVersion "21.1.6352462"
}

或者可以通过在 Android Studio 项目根目录下的 local.properties 文件中,使用 ndk.dir 属性:

ndk.dir = /Users/ndkPath/ndk21 // Point to your own NDK

注意,该设置在不同AGP的版本下,还有着不同的一些设置方法,大家可以参考:
https://developer.android.google.cn/studio/projects/configure-agp-ndk?language=agp3-6#agp-version

CMake版本

AndroidStudio的SDK Manager中管理了3个版本的CMake,分别是

NDK版本r15 Android ndk版本与cmake版本对应_android


默认情况下,如果不进行设定CMake的版本,那么使用的是3.10.2的版本进行的构建,如果想要使用其他的CMake版本,则在模块的 build.gradle 文件中添加以下内容

android {
    ...
    externalNativeBuild {
        cmake {
            ...
            version "cmake-version"
        }
    }
}

cmake-version 可以定义为3.18.1或是3.6.0,那么如果我们想要设置除了SDK Manager管理的这三个版本以外的版本行不行呢?
答案是可行的,我们来尝试一下,随便写一个版本号,注意,这边我们使用的AGP的版本先使用4.2

android {
    ...
    externalNativeBuild {
        cmake {
            ...
            version "3.12.0"
        }
    }
}

同步一下Gradle,发现报错了,我们看一下错误信息

> Configure project :app
CMake '3.12.0' was not found in SDK, PATH, or by cmake.dir property.
- CMake '3.20.3' found in PATH did not satisfy requested version.
- CMake '3.10.2' found in SDK did not satisfy requested version.
- CMake '3.18.1' found in SDK did not satisfy requested version.
- CMake '3.6.0' found in SDK did not satisfy requested version.
CMake '3.12.0' was not found in SDK, PATH, or by cmake.dir property.
- CMake '3.20.3' found in PATH did not satisfy requested version.
- CMake '3.10.2' found in SDK did not satisfy requested version.
- CMake '3.18.1' found in SDK did not satisfy requested version.
- CMake '3.6.0' found in SDK did not satisfy requested version.
No valid CMake executable was found.
No valid CMake executable was found.

BUILD SUCCESSFUL in 3s

这边可以很明显的发现,Gradle会从SDK, PATH以及cmake.dir里去找你配置的版本,只要有一个地方找到了,就会使用,都没找到就会报错,我们分别来看看这几个地方

SDK

查找Android SDK路径下的cmake文件夹下对应的版本,如下

NDK版本r15 Android ndk版本与cmake版本对应_NDK版本r15 Android_02


这边的文件夹名称对应的就是版本名称,这边的3.6.4111459,3.18.1,3.10.2.4988404就是sdkmanager管理的cmake版本

如需使用3.6.4111459,则在version中填写3.6.0即可

这边其他的一些版本是从cmake官网下载的https://cmake.org/download/,这边的版本也是可以让Gradle找到的,
如我这边cmake-3.14.7-win64-x64,如果我需要使用该版本,我只需要在version中填写3.14.7即可找到这个版本,
并且,你可以自己修改文件夹名称,
如3.14.0,我可以修改成3.14.1,相应的version中也填写3.14.1,也是可以找到的,当然其实他还是使用的3.14.0的版本进行的构建

PATH

查找环境变量中PATH中的value配置的cmake版本,如下,PATH中配置了CMake环境变量,我这边配置的是3.20.3的,所以在version中填写3.20.3,能够正确找到

NDK版本r15 Android ndk版本与cmake版本对应_sqlite_03

cmake.dir

将其添加到项目的 local.properties 文件中,如下所示

# If you set this property, Gradle no longer uses PATH to find CMake.
cmake.dir=E\:\\ndk\\3.15.0
AGP版本的不同行为

上面提到的都是在AGP版本4.2的行为,在4.1,会有所不同,如下

dependencies {
        classpath "com.android.tools.build:gradle:4.1.0"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
CMake '3.14.7' was not found in PATH or by cmake.dir property.
- CMake '3.15.0' found from cmake.dir did not match requested version '3.14.7'.
- CMake '3.10.2' found in SDK did not match requested version '3.14.7'.
- CMake '3.18.1' found in SDK did not match requested version '3.14.7'.
- CMake '3.6.0' found in SDK did not match requested version '3.14.7'.
- CMake '3.20.3' found in PATH did not match requested version '3.14.7'.

可以看到,如果将Gradle版本修改为4.1.0,则其是不会找到我们自己放在SDK.cmake目录下的版本的

Ninja版本

默认情况下,如果是使用SDK Manager管理的那三个CMake版本,则不需要配置任何Ninja相关的配置,默认的Cmake已经包含了ninja的可执行程序

NDK版本r15 Android ndk版本与cmake版本对应_NDK版本r15 Android_04


而如果是使用我们自行下载的CMake,则需要进行手动配置,有以下方式配置

手动放入ninja可执行程序

把ninja的可执行程序放入你使用的cmake的bin目录下即可,就和上面的默认情况一样的位置就行

通过环境变量配置

在PATH里面配置ninja可执行文件的路径即可,如果配置了cmake的环境变量在PATH中,可以直接将可执行文件丢到该配置中即可

通过Gradle配置进行配置

可以在模块的build.gradle中添加如下配置

defaultConfig {
        ........
        externalNativeBuild {
            cmake {
                  arguments("-DCMAKE_MAKE_PROGRAM=C:/Program Files/CMake/bin/ninja.exe")
            }
        }
    }

这样就指定了ninja的版本了

另外,如果手动放入了ninja可执行程序,则会优先使用该ninja的版本进行构建,没有的话,会使用环境变量里面配置的ninja,再没有那就会报错了,

CMake Error: CMake was unable to find a build program corresponding to "Ninja".  CMAKE_MAKE_PROGRAM is not set.  You probably need to select a different build tool.
Configuring incomplete, errors occurred!
See also "C:/Users/Administrator/AndroidStudioProjects/NativeEvalDemo/app/.cxx/cmake/debug/x86/CMakeFiles/CMakeOutput.log".

当然,如果是进行了gradle配置,则会使用你配置的版本